poppy-project / pypot

Python library for controlling dynamixel motors. Documentation available here:
https://docs.poppy-project.org/en/software-libraries/pypot.html
GNU General Public License v3.0
253 stars 137 forks source link

bug in angle_limit with INDIRECT orientation ? #304

Open tgirod opened 2 years ago

tgirod commented 2 years ago

I believe there is a problem with how angle limits are calculated when a motor is in indirect orientation. Here is a sample config

        "base_arm":{
            "id":2,
            "orientation":"indirect",
            "type":"MX-64",
            "angle_limit":[-180, 180],
            "offset":-50.0
        },

As long is my angle limits are relaxed (here, -180 to 180), everything is fine. Now, if I move the arm in compliant mode, I find my angle limits are [40, 100]. Now, if I modify my config and add those values as angle limits and turn the motors on, my base_arm joint finds itself completely outside of the angle limits and bends over to try to get back within the limits.

When checking base_arm.angle_limit, the values seems off: [10, -50]. I guess it is [-min-offset, -max-offset], but it doesn't look right. Sorry for not being more precise, I'm rather new to pypot and dynamixels, not sure if direct/indirect is pypot or dynamixel specific.

ymollard commented 2 years ago

All configurations of Poppy robots use indirect orientations with no problem. Is the offset of -50 applied on purpose in your configuration?

tgirod commented 2 years ago

Yes, the -50 offset is intentional.

ymollard commented 2 years ago

Could you test the limits with no offset to see if it is involved of your issue?

tgirod commented 2 years ago

I've just tried with offset=0, and it gets even weirder.

With no angle limits (well, -180 to 180), I can move the joint freely and the arm behaves as expected. So I move it freely to get its limits: -20 to +50.

I add the limits, turn on the motors, and this time at least it doesn't try to bend backwards. Time to move:

base_arm.goto_position(50,2)

The arm stops around angle 20. If I look at base_arm.angle_limit, I happen to have (20,-50).

tgirod commented 2 years ago

I find it very weird that when I read angle values by moving the arm in compliant mode, and then inserting those angles as limits in the config, pypot negate those values - but then the resulting values don't fit anymore.

tgirod commented 2 years ago

To be sure, I did the same procedure after setting the motor to DIRECT, and everything works as expected - reading angle values in compliant mode, entering them as limits, checking if the limits are ok, everything is fine.

tgirod commented 2 years ago

All configurations of Poppy robots use indirect orientations with no problem.

Just a hunch: in those configurations, are the limits rather symetrical, like [-50,50] ? In this case, negating the angle limits does not change anything, which would be why the problem I describe don't show up ?

ymollard commented 2 years ago

in those configurations, are the limits rather symetrical, like [-50,50] ?

No there are non-symmetrical limits. But what you observe looks an expected behaviour, see:

In [2]: p = pypot.creatures.PoppyHumanoid(simulator="dummy")                                                         

In [3]: p.r_elbow_y.direct                                                                                           
Out[3]: False

In [4]: p.r_elbow_y.angle_limit                                                                                      
Out[4]: (1.0, -148.0)

In [5]: p.config["motors"]['r_elbow_y']                                                                              
Out[5]: 
{'offset': 0.0,
 'type': 'MX-28',
 'id': 54,
 'angle_limit': [-1, 148],
 'orientation': 'indirect'}

pypot performs a sign swap for indirect motors, see : https://github.com/poppy-project/pypot/blob/9cbf189b3b7e8c7623eab237d24849d41aba3cda/pypot/dynamixel/motor.py#L46-L53