rapier icon indicating copy to clipboard operation
rapier copied to clipboard

Revolute joint motor target position is broken at and beyond 90 degree angles

Open fatho opened this issue 2 years ago • 1 comments

Summary

When setting the target angle of a 2D revolute joint motor to 90 degrees, it starts spinning uncontrollably.

When setting the target angle to something larger, e.g. 135 degrees, it instead converges to 45 degrees.

Reproducer

I added the following file to the examples2d testbed.

When setting the joint motor angle to 45f32.to_radians(), it behaves as expected (after some wobbling, it converges to the 45 degree position).

However, when setting it to 90f32.to_radians() as in the example below, it just keeps spinning.

Setting it to 135f32.to_radians() behaves the same as the 45 degree case.

`motor2.rs` testbed reproducer
use rapier2d::prelude::*;
use rapier_testbed2d::Testbed;

pub fn init_world(testbed: &mut Testbed) {
    /*
     * World
     */
    let mut bodies = RigidBodySet::new();
    let mut colliders = ColliderSet::new();
    let mut impulse_joints = ImpulseJointSet::new();
    let multibody_joints = MultibodyJointSet::new();

    /*
     * The ground
     */
    let ground_size = 5.0;
    let ground_height = 0.1;

    let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
    let ground_handle = bodies.insert(rigid_body);
    let collider = ColliderBuilder::cuboid(ground_size, ground_height);
    colliders.insert_with_parent(collider, ground_handle, &mut bodies);

    /*
     * A rectangle on a motor
     */
    let rigid_body = RigidBodyBuilder::dynamic().translation(vector![0.0, 2.0]);
    let handle = bodies.insert(rigid_body);
    let collider = ColliderBuilder::cuboid(0.1, 0.5);
    colliders.insert_with_parent(collider, handle, &mut bodies);

    let joint = RevoluteJointBuilder::new()
        .local_anchor1(point![0.0, 2.0])
        .motor_position(90f32.to_radians(), 5.0, 0.5);
    impulse_joints.insert(ground_handle, handle, joint, true);

    /*
     * Set up the testbed.
     */
    testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
    testbed.look_at(point![0.0, 0.0], 40.0);
}

fatho avatar Aug 07 '22 15:08 fatho

Confirm same behavior with latest version 0.15.0. I find a workaround by changing stiffness to 100.0, and damping 40.0. However it is not possible to move outside the range [-90,90] degrees. It seems that the angles outside [-90,90] are modified angle -180 if angle is positive and +180 is angle is negative e.g setting 350 degree the body move to angle ~ 0 degrees.

pellico avatar Oct 04 '22 16:10 pellico

Also running into issues around this. Seems to also affect revolute joints using limits without motors.

Stepping through a range of limits from [0.0, 0.0] -> [180.0, 180.0] (degrees) works correctly (i.e. removing the remaining degree of freedom), but once you go beyond 180 the limit starts moving backwards in the wrong direction.

tomsmalley avatar Oct 28 '22 18:10 tomsmalley

I posted a possible fix. I reused the example of @fatho to create one example to check the issue and the fix. Thanks @fatho 🥇

pellico avatar Nov 27 '22 17:11 pellico