So100 follower's 2nd motor moves the opposite direction of the leader
Hi, I'm an experienced software engineer but new to robotics. I found LeRobot project quite fascinating and am trying to get my hands dirty by building the so100 arms.
After calibration was done I found the 2nd motor of the follower moved the opposite direction of the leader during teleoperate. Because there was no room to move at that direction at resting position, it got stuck with blinking red light.
I can confirm that the motors themselves work as expected. E.g. if I directly set the follower's 2nd motor to rotate +200, and compare it with the readings from leader's 2nd motor moving the same direction, they matched: the leader's motor also increased by ~+200. So this must be a problem with the calibration.
My follower calibration file has the following: {"homing_offset": [-2145, 4, -1401, -3126, 2970, -1769], "drive_mode": [0, 1, 0, 0, 1, 0], "start_pos": [2085, 56, 1285, 3237 , 3080, 1983], "end_pos": [3169, 1020, 2425, 4150, -1946, 2793], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
And leader's: {"homing_offset": [-2062, 3126, -105, -2098, 2881, -1532], "drive_mode": [0, 1, 0, 0, 1, 0], "start_pos": [2083, 3025, 266, 2 079, 2891, 1515], "end_pos": [3086, -2102, 1129, 3122, -1857, 2556], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
I tried to manually change drive_mode of either follower or leader or both's drive_mode from [0, 1, 0, 0, 1, 0] to [0, 0, 0, 0, 1, 0]. None of the combinations worked.
As of course, I tried to calibrate many times but every time I got the same.
And here is one more interesting data point: at one time I took out the 2nd motor of both follower and leader, and re-configured them as in step C (after putting back the gear we took out for the leader.) After assembling them back the calibration worked correctly - the 2nd follower motor moved in sync with leader's! However it didn't last for long, at one point some error occurred during teleoperate and I had to re-calibrate the arms. After that, the problem re-appeared.
I'm currently stuck. Any help/advices on how to go debug this problem is appreciated.
Had this issue for the gripper rotation and fix it by just recalibrate one arm with opposite rotation:
python lerobot/scripts/control_robot.py --robot.type=so100 --control.type=calibrate --control.arms=[\"main_leader\"]
Than teleoperate again to verify:
python lerobot/scripts/control_robot.py --robot.type=so100 --control.type=teleoperate
Not sure how can I calibrate the 2nd motor (shoulder_lift) with opposite rotation? From rest position it moves only upwards.
Hi @paszea ,
It looks like you’re running into a common issue we’ve seen with the current calibration method for these arms. We’re actively working on improvements to address this.
In the meantime, here’s a tip that might help: Even if the arm moves in the wrong direction at first, try moving the leader arm through a wide range of motions. Often, after a few adjustments, the follower arm will catch on and respond correctly.
@imstevenpmwork thanks for confirming. The issue does look somewhat random. For the moment I swapped the leader's 2nd motor with the 4th and the recalibration worked fine so far. Looking forward to the improvement in case the problem happens again.
I have a similar problem with the calibration offsets. The third joint is off by 180 degrees when starting teleop. It fixes itself when I move the leader through its full range of motion. https://photos.app.goo.gl/UBitNv98t4N1JJnQ7
Hi @paszea , the way I solved this was to change the steps for calibrating from the normal 1, 2, 3 (extended, rotated, rest) positions to 3, 2, 1 (rest, rotated, extended) positions for the follower and leader arms, this causes it to start in the rest position. Let me know if this helps :)
Hi @paszea , the way I solved this was to change the steps for calibrating from the normal 1, 2, 3 (extended, rotated, rest) positions to 3, 2, 1 (rest, rotated, extended) positions for the follower and leader arms, this causes it to start in the rest position. Let me know if this helps :)
@felixboelter this approach actually worked for me. Thanks!
I solved this issue by swapping the leader's 2nd motor with the 3th moter. After a new calibration it works fine.
What is the rationale for swapping motors? Does it make any sense?
Hi @paszea and @felixboelter, When you change the calibration steps from the normal 1, 2, 3 (extended, rotated, rest) positions to 3, 2, 1 (rest, rotated, extended) positions for the follower and leader arms, do you modify any script, or do you simply place the arms in the 'rest' position when prompted to set them to 'extended'?
I simply changed the order, nothing else.
On Thu, Apr 17, 2025 at 9:40 AM Shaobo Han @.***> wrote:
Hi @paszea https://github.com/paszea and @felixboelter https://github.com/felixboelter, When you change the calibration steps from the normal 1, 2, 3 (extended, rotated, rest) positions to 3, 2, 1 (rest, rotated, extended) positions for the follower and leader arms, do you modify any script, or do you simply place the arms in the 'rest' position when prompted to set them to 'extended'?
— Reply to this email directly, view it on GitHub https://github.com/huggingface/lerobot/issues/930#issuecomment-2813515943, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2V5O3DZ4KKGI4JWXCQYFD2Z7KOZAVCNFSM6AAAAAB2KMTOLWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMJTGUYTKOJUGM . You are receiving this because you were mentioned.Message ID: @.***> shaobohan left a comment (huggingface/lerobot#930) https://github.com/huggingface/lerobot/issues/930#issuecomment-2813515943
Hi @paszea https://github.com/paszea and @felixboelter https://github.com/felixboelter, When you change the calibration steps from the normal 1, 2, 3 (extended, rotated, rest) positions to 3, 2, 1 (rest, rotated, extended) positions for the follower and leader arms, do you modify any script, or do you simply place the arms in the 'rest' position when prompted to set them to 'extended'?
— Reply to this email directly, view it on GitHub https://github.com/huggingface/lerobot/issues/930#issuecomment-2813515943, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2V5O3DZ4KKGI4JWXCQYFD2Z7KOZAVCNFSM6AAAAAB2KMTOLWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMJTGUYTKOJUGM . You are receiving this because you were mentioned.Message ID: @.***>
@shaobohan when I read the code, I saw that it defaults to the starting position, which is the extended position according to the guide. When I started the script while having the leader arm in the extended position it worked, but this was very annoying when capturing data (because it also started at the extended position in Data Collection) and if you miss the timing the robot turns backwards. So I changed the order and it worked.
Hi @paszea and @felixboelter, Thank you for the quick reply—I appreciate it!
I just tried a calibration using the suggested order of 3, 2, 1 (rest, rotated, extended) positions for both the follower and leader arms, while the script prompted for 1, 2, 3 (extended, rotated, rest). I noticed the following:
(1) At the start of teleoperation, the follower arm now stays in the rest position. Previously, it would stretch first, then rotate backward and get stuck, creating a clicking sound.
(2) However, the second motor (and sometimes the third) of the follower arm initially moves in the opposite direction of the leader. This issue disappears after moving the leader arm around for a while. May occur again randomly.
(3) When the follower-leader arm action are not matching, the follower arm vibrates and creates a clicking sound...
Not sure whether this is a bug in the current calibration code or if there's an additional procedure I should try...
My calibration files are as follows:
main_leader.json
{"homing_offset": [-1925, -4172, 3117, -1094, 2192, -1450], "drive_mode": [0, 0, 1, 0, 1, 0], "start_pos": [2064, 4025, 3119, 1963, 2234, 1482], "end_pos": [2949, 5196, -2093, 2118, -1168, 2474], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
main_follower.json
{"homing_offset": [-1979, -1107, 2206, -3037, 2157, -953], "drive_mode": [0, 0, 1, 0, 1, 0], "start_pos": [1960, 1001, 2180, 3888, 2149, 811], "end_pos": [3003, 2131, -1182, 4061, -1133, 1977], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
TLDR: I did 2 things and fixed similar problem: 1. filling the calibration file based on motor encoder reading instead of using the 3 step calibration function. 2. reassembly joint 2 with rotating the 2nd motor on both arm to avoid encoder value jumping at limit.
Had similar issue with second motor on my SO-100 model. While for me is that after running teleoperate from rest state, either 1. the second motor immediately moves backwards, hit the parent link and stuck there, or 2. the second motor immediately turn 180 degree to what would be like in the extended state, hit and stuck or 3. everything was fine in the beginning, but after moving the leader to some pose close to the extended state, the second motor immediately flip 180degrees backwards, hit, stuck.
Tried tricks in this thread, swapping motor or recalibrate only make the teleopeation goes wrong in a different way, changing the calibration order from 123 to 321 works for the teleoperation, but would mess up my kinematics module.
Finally I tried to read the calibration function. To summarize what I've learnt: 1. in the calibration file, the start pose vector is the encoder value from 6 motors at the extended state, and the end pose is the encoder value at the rotated state. 2. the homing offset vector add the start pose vector should be close to n* 4096 while n being integer. This means that the data in calibration file could be filled by reading and observation of motor encoder values.
So I tried to directly read the servo encoder to fill the calibration file, ended up with the first kind of error. After that I noticed that the second motor starts at a place near 0 or 4095 at extended state (will happen if you tried to not rotate the motor during the assembly liike me), which would make the calibration read for second motor have jumping value as it could pass the [0,4095] limit.
Then I tried to disassembly the second joint at both leader and follower to rotate the second motor a bit, for me I made the rest state value to be around 1024. Then after reassembly and handmaking of calilbration file now my SO-100 works perfect!
For the development team, I think the problem of calibration may lie in the handling of this jumping, as another weird thing I find in the calibration file is that i sometimes find values out of [0, 4095] in start pose or end pose, but they should be encoder readings which should not be out of bound?
TLDR: I did 2 things and fixed similar problem: 1. filling the calibration file based on motor encoder reading instead of using the 3 step calibration function. 2. reassembly joint 2 with rotating the 2nd motor on both arm to avoid encoder value jumping at limit.
Had similar issue with second motor on my SO-100 model. While for me is that after running teleoperate from rest state, either 1. the second motor immediately moves backwards, hit the parent link and stuck there, or 2. the second motor immediately turn 180 degree to what would be like in the extended state, hit and stuck or 3. everything was fine in the beginning, but after moving the leader to some pose close to the extended state, the second motor immediately flip 180degrees backwards, hit, stuck.
Tried tricks in this thread, swapping motor or recalibrate only make the teleopeation goes wrong in a different way, changing the calibration order from 123 to 321 works for the teleoperation, but would mess up my kinematics module.
Finally I tried to read the calibration function. To summarize what I've learnt: 1. in the calibration file, the start pose vector is the encoder value from 6 motors at the extended state, and the end pose is the encoder value at the rotated state. 2. the homing offset vector add the start pose vector should be close to n* 4096 while n being integer. This means that the data in calibration file could be filled by reading and observation of motor encoder values.
So I tried to directly read the servo encoder to fill the calibration file, ended up with the first kind of error. After that I noticed that the second motor starts at a place near 0 or 4095 at extended state (will happen if you tried to not rotate the motor during the assembly liike me), which would make the calibration read for second motor have jumping value as it could pass the [0,4095] limit.
Then I tried to disassembly the second joint at both leader and follower to rotate the second motor a bit, for me I made the rest state value to be around 1024. Then after reassembly and handmaking of calilbration file now my SO-100 works perfect!
For the development team, I think the problem of calibration may lie in the handling of this jumping, as another weird thing I find in the calibration file is that i sometimes find values out of [0, 4095] in start pose or end pose, but they should be encoder readings which should not be out of bound?
Thanks for sharing! I'm glad you got it worked out finally.
You said you did the manual filling of calibration files after setting 2nd motors' initial position to 1024 instead of 2048, did you also try the official calibration using the script? Did it not work?
I also wonder what kind of problem you were having with the "kinematics module." Is this something not concerning the lerobot repo? I've trained a couple models based on the calibration (321) and they seemed to work well. So just want to check.
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips:
(1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5.
(2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops.
(3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Hi @paszea ,
It looks like you’re running into a common issue we’ve seen with the current calibration method for these arms. We’re actively working on improvements to address this.
In the meantime, here’s a tip that might help: Even if the arm moves in the wrong direction at first, try moving the leader arm through a wide range of motions. Often, after a few adjustments, the follower arm will catch on and respond correctly.
I'm facing this issue. It was working like this until I tried to record a dataset and now my servos flash a few seconds after starting regardless of the joint positions. Sometimes if I'm lucky it'll hold our for 10 seconds or so but the second the 2nd servo gets to around 90 degrees off of rest my second servo starts flashing and freezes up if it doesn't slam the arm violently into the table.
Robot was working fine with these offsets until today when I tried to record a dataset. Now I'm getting the new behavior with the same offsets.
https://gist.github.com/odellus/82a72e6299716ddcbb6eaedfcc5bef16 https://gist.github.com/odellus/b26f2a781ca74a29b4a33c77a7b5cf70
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips:
(1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5.
(2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops.
(3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Hello @shaobohan thank you for the insights. What does middle position actually mean? And can you share your new working configuration file? Thank you :)
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips: (1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5. (2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops. (3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Hello @shaobohan thank you for the insights. What does middle position actually mean? And can you share your new working configuration file? Thank you :)
Hi @felixboelter, the "middle position" means to install the joints with the angle exactly as shown the Youtube tutorial (allow the gear to rotate both left and right later I assume). The cartoon in the video I found helpful.
Follower: {"homing_offset": [-1878, 4009, -79, -1968, 2038, -2289], "drive_mode": [0, 1, 0, 0, 1, 0], "start_pos": [1996, 4026, 89, 1973, 2117, 1891], "end_pos": [2902, -2985, 1103, 2992, -1014, 3313], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
Leader:
{"homing_offset": [-1976, 3072, -952, -1949, 2061, -1437], "drive_mode": [0, 1, 0, 0, 1, 0], "start_pos": [1994, 3073, 959, 1937, 2093, 1335], "end_pos": [3000, -2048, 1976, 2973, -1037, 2461], "calib_mode": ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], "motor_names": ["shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper"]}
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips:
(1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5.
(2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops.
(3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Thanks for those tips. What does top horn means ?
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips: (1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5. (2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops. (3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Thanks for those tips. What does top horn means ?
It is the motor horn - silver circle with the grooves and 4 holes.
I assembled a new pair, and it works perfectly in Teleops (calibration order 123). Tips: (1) The top horn should be positioned at the suggested clock locations (1:30, 4:30, 7:30, and 10:30). This can be done before assembly for motors 1, 2, 3, 4, and 6 — except for motor 5. (2) I did not remove the gears from the leader arm this time, which helped maintain the top horn alignment at the recommended clock positions when attaching the motor horn during assembly. It also helped prevent the leader arm from moving too fast during Teleops. (3) Each joint should be assembled in its middle position (as shown here: https://www.youtube.com/watch?v=FioA2oeFZ5I&t=607s). I think not sticking to this step might be why the motor move in the opposite direction.
Thanks for those tips. What does top horn means ?
It is the motor horn - silver circle with the grooves and 4 holes.
thanks
Experiencing this issue, sounds like the recommended solution is to manually adjust my horns?
This issue has been automatically marked as stale because it has not had recent activity (6 months). It will be closed if no further activity occurs. Any change, comment or update to this issue will reset this count. Thank you for your contributions.
This issue was closed because it has been stalled for 14 days with no activity. Feel free to reopen if is still relevant, or to ping a collaborator if you have any questions.