poppy-project/pypot

bug in angle_limit with INDIRECT orientation ?

tgirod opened this issue · 8 comments

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.

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

Yes, the -50 offset is intentional.

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

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).

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.

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.

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 ?

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 :

class DxlOrientedRegister(DxlRegister):
def __get__(self, instance, owner):
value = DxlRegister.__get__(self, instance, owner)
return (value if instance.direct else -value)
def __set__(self, instance, value):
value = value if instance.direct else -value
DxlRegister.__set__(self, instance, value)