Lateral movement during vertical movement
- This topic is empty.
2013-03-29 at 21:17 #5903AnonymousInactive
Finally got my bot up and working, but I’m seeing an issue that I don’t know how to resolve.
I’m using ik.ino.
When the head is centered in the XY, I can move in the Z as expected.
When the head is not centered in the XY, issuing a move command only in the Z axis will cause some shifting in the XY axis as well. In general, movement in the -Z causes XY shifting in the direction the head is already at (so if it’s to the left, moving -Z is more to the left) and movement in the +Z shifts the XY more towards the center.
I have adjusted the constants at the top of the file to match my measurements, but it doesn’t seem to have made a difference.
I also tried removing the calls to line, line_safe, etc and and calling ik() directly after updating the pos struct, and I’m seeing the same thing. This tells me that the error is probably in the math in ik(), but I honestly don’t follow it.
Ideas?2013-03-30 at 16:39 #6303AnonymousInactive
I would re-measure the dimensions of your machine and then adjust the values in ik.ino accordingly.
If they are different, please let me know. Everyone is supposed to have the same values.2013-04-02 at 05:32 #6301AnonymousInactive
Ok, I’ve triple-checked. The only different measurement is the length of the “forearm” (elbow to wrist). Probably because I screwed mine in farther than yours? Mine is a little less than 1CM less than yours.
Regardless of whether I have your original measurements or my measurements accurate to my machine, I still get the same result. The magnitude of the XY position increases when the Z position becomes more negative.
Any other ideas? It seems like others aren’t experiencing this problem, so I’m pretty stumped as to what could have went wrong here.
Thanks!2013-04-02 at 06:36 #6304AnonymousInactive
I have a theory, but I haven’t had time to test yet.
The servos you sent in my kit are not the same servos you mention in your build instructions. Could the code giving the servo the angles need to be changed? It seems like that could cause an issue like this.2013-04-02 at 15:52 #6305AnonymousInactive
No two servos are exactly the same. This was a real problem for me when I was building my crab robot, they all needed to be calibrated independently.
I’ve set aside a couple hours tomorrow to write some calibration software that should make things better for us.
I’ll post here when I get it written.2013-04-03 at 07:51 #6302AnonymousInactive
I appreciate it!
I’m happy to help with code, but I have no idea what the actual calibration process would be.2013-05-02 at 22:04 #6314AnonymousInactive
Any word on this?
After further thought, I’m convinced that the servos are off from the requested angle, and the further from 90, the farther off they are. This seems to be a calibration issue, as some looking at graphs from people who have calibrated servos look correct for the issues I’m seeing.
You made another post about practical applications…I’m working on one (well, somewhat practical anyway), but it’s not going to work if I can’t get more accurate with requested vs actual coordinates.2013-05-03 at 02:34 #6315AnonymousInactive
I really want to help you. I don’t understand your description of the issue, which is making it hard for me to be more helpful. You tell the servos to go to, say, 70 degrees and they go to 50 or 80 instead?
Also note that the heim joints (the tamiya connectors) might be limiting your range of motion and “fighting” the servos. I’m working to replace these but my part supplier is being very challenging. I need to learn mandarin. :T2013-05-03 at 16:33 #6316AnonymousInactive
Two symptoms are visible from the constructed robot. I believe they are related to each other, but I don’t have any way to verify that.
Symptom 1: As I move farther from (0,0) in the X,Y plane (holding the requested Z value constant), I also see motion of the effector towards the triangular base and servos of the robot. This is more pronounced (more Z movement) the farther from (x,y)=(0,0) I move. It’s as though instead of moving through a plane, I’m moving along the inner surface of a bowl.
Symptom 2: At (0,0,0), I can move the effector in the Z direction only (up or down) as expected. If I move the effector in the xy plane, then move in the Z direction (up or down), the effector also shifts in the xy plane. The magnitude of the change in xy is greater the farther away from (x,y)=(0,0) I am when I change the Z value.
I think that my actual angles are off from my requested angles at each servo, but I haven’t taken apart the bot and measured angles with a protractor yet. For example, the code tells the servo to turn to 45 degrees, but the servo actually goes to 40 degrees. To get an actual 45 degrees, you’d have to request some other angle. If this is the problem, it should be fixable via calibration.
As for calibration, my initial thought is to take the robot apart, request 20-30 angles and measure their actual values with a protractor. Repeat for each servo in case they’re not consistent. Then, build a table of the values and an interpolation function so requested values can be translated to a servo control value that more accurately matches the requested value. I’m sure there’s a way to calibrate in a similar way based on the cartesian motion of the finished robot, but it seems like it would be faster to take apart and reassemble than to figure out how to measure the motion, do the math, write the code, and debug the cartesian version. The cartesian calibration would have the advantage of taking into account any differences in motion from the u-joints, weight on the effector, etc.2013-05-04 at 01:02 #6313AnonymousInactive
Sounds like the measurements for the lengths of each part of the robot may not be accurate. If the expected dimensions are different from the actual dimensions then I’d get motion like you describe. If you’re already taking the machine apart you might want to measure everything. The code for each dimension is
static const float shoulder_to_elbow = 5; // cm
static const float elbow_to_wrist = 18.5f; // cm
#if NUM_ARMS == 4
static const float center_to_shoulder = 5.0f; // cm
static const float effector_to_wrist = 1.59258f+0.635f; // cm
static const float center_to_shoulder = 5.753f; // cm
static const float effector_to_wrist = 1.59258f; // cm
shoulder_to_elbow is the distance between hole centers on the horn. the 3D printed parts are correct, this value isn’t an issue.
elbow_to_wrist is the distance between hole centers on the tamiya parts. This is probably wrong.
center_to_shoulder is the distance from the center of the frame to the moving part of each servo. This is also ok.
effector_to_wrist is the distance from the center of the end effector to the center of the joint on each arm. I’m not 100% any more this number is correct. The parts are laser cut but I haven’t checked it in a long long time.
Let me know if anything is off and I will gladly fix it in the code.2013-05-10 at 16:45 #6311AnonymousInactive
I took the robot apart, then reassembled only the things attached to the servos: the bottom frame, the servos, and the biceps. I then started to measure angles using your serial program. Immediately, I could see that the servos were not rotating to nearly the range they should be. I tried one of the Arduino sample servo programs, and I could see the servo make its full sweep from 0 to 180. This indicated there was something wrong in the code.
The obvious difference between your code in the serial program and the Arduino sample code was that you were using was that you were using writemilliseconds() and the sample was using write(). I switched your code to write() (and took out the code that tried to convert the angle to the writemilliseconds() format), and then your code worked correctly. I got the full range of motion. I did the same trick on ik.ino (A little more complicated here, you were storing angles as -90 – 0 – 90 instead of the 0-180 that write() expects), put the robot back together fully, and everything works as expected. The strange behavior where the Z was changing in response to the XY is gone, and movement appears to be correctly proportional across the work envelope.
Looking at the servo library documentation, it looks like the “typical” servo goes from 1000 to 2000, but this varies from servo to servo. I think what was happening is that the servos I had were using a larger range (maybe 500 to 2500? I didn’t measure), so moving to a given value wouldn’t cause as much rotation as intended. I guess you could put constants at the top of the file to define the range for each servo, but it might be cleaner to move to the write() call for anything that doesn’t need that amount of precision. Maybe make an easy way to swap between the two with some #ifdefs to allow it to “just work” by default with write() calls (and poorer precision), but a user can measure out his individual servo values, plug them into #defines, and the system will switch to the more precise writemilliseconds() call.2013-05-13 at 01:05 #6312AnonymousInactive
Can you share your fixed code? I can include it in the github project for everyone else.2013-05-13 at 15:03 #6306AnonymousInactive
I need to clean it up a bit first, but yes. I’ll send you a pull request via github sometime this week.2013-05-17 at 16:07 #6307AnonymousInactive
I’m changing the github code now to use write(). I thought writemilliseconds() would give more precision. I guess with the quality of these servos it doesn’t make a signifigant difference. Thank you for the great work!2013-05-17 at 16:19 #6308AnonymousInactive
Updated firmware to v11b and posted about it on the blog. Thanks again!2013-05-17 at 17:15 #6309AnonymousInactive
Were you able to confirm the same thing happening on your robot?
I’m still a little confused at how the write() command knows what kind of pulses to send to get the full range of motion, when it’s clear that writemilliseconds() needs calibration to make that happen.
Thanks for the official update! I think the way I did it inverted the Z and X axis, which I didn’t bother to fix yet. Now I can just pull your code.2013-05-17 at 18:07 #6310AnonymousInactive
Please back up your copy before you test my change. it’s always good to get outside confirmation that my fix worked.2013-10-31 at 11:26 #6317AnonymousInactive
First, thanks a lot for sharing your work around the delta robot ! I made one this week following your advices. I ordered servo and balls in France so it is not exactly the same servo and balls but I could manage. It’s working pretty well and I control it from python.
But I noticed like Justin that a X translation drives to a little Z movement (almost 1 cm for a 6 cm move), especially when the tool is not close to the (X,Y)=(0,0) position. Same problem when I try a vertical move when tool is not centered on (0,0) : a little X and Y move appear.
May my question be stupid, but I did not find any advice about initial position of the servo cross. I mean that I can give arbitrary angular position when I plug the arms on the gear of the servo.
Is there a special position of the robot where arms are in vertical or horizontal position for example ?
Thanks for your advices. Best regards.
- You must be logged in to reply to this topic.