google / brax

Massively parallel rigidbody physics simulation on accelerator hardware.
Apache License 2.0
2.25k stars 249 forks source link

v2: position control's joint limit implicitly capped at 90 degrees? #341

Closed namheegordonkim closed 1 year ago

namheegordonkim commented 1 year ago

I'm using positional backend.

Suppose I have a hinge joint with range specified as -180 to 180, i.e.,

<joint armature="0" axis="1 0 0" name="my_joint" pos="0.00 0 0" range="-180 180" type="hinge"/>

A strange thing happens when I specify position control mode on this joint and pass 1 as action.

<position ctrllimited="true" ctrlrange="-1.0 1.0" joint="my_joint" gear="0"/>

The joint does not go beyond 90 degrees angle, while the desired behaviour would actuate the servo all the way to 180 degrees in the positive direction. In fact, I don't see any difference when I specify range="-90 90". Meanwhile, specifying motor control mode, i.e.,

<motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="my_joint" gear="0"/>

The joint is completely unlimited and shows infinite rotation.

As clunky as it was, v1 didn't have this issue with position control. What gives?

btaba commented 1 year ago

Hi @namheegordonkim ! Can you increase the ctrlrange to -3.14, 3.14 radians? Let us know if that works. Also, not sure how this actuator is working with gear=0?

namheegordonkim commented 1 year ago

Oh, the gear value I override in my environment definition. Sorry for the confusion. Will report back with the control range, although setting ctrllimited="False" didn't make any difference.

btaba commented 1 year ago

Ok well, in the case that it doesn't work (given that you've already tried ctrllimited=False), it would be awesome if you could send over some code that is easily reproducible. The torque in a position actuator is: gear * (act - bias), so either act is being clipped, gear is not high enough, or maybe things are being overdamped

namheegordonkim commented 1 year ago

@btaba hmm, now that you mention the values of ctrllimited, it seems that the action values passed into pipeline.step() needs to be normalized and clamped to be within angle limits in radians. That is, I set ctrllimited=false but do manual sanitization within env.step() to ensure the ranges are valid. I'm using

        # ...
        lo, hi = self.sys.dof.limit
        act = jp.clip(action * jp.pi, lo[1:], hi[1:])
        pipeline_state = self.pipeline_step(pipeline_state0, act)
        # ...

to get the PD target angles in radians.

That explains the degree limiting error I saw when using position control.

However, upon further investigation, I realized my real issue has maybe to do with positional backend's instability; with actual PD target angles in radian passed into pipeline.step(), I get the valid behaviour for generalized but not positional. I'll close this issue and open another one to continue our discussion there with a minimal example.