rapier
rapier copied to clipboard
Revolute joint motor target position is broken at and beyond 90 degree angles
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);
}
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.
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.
I posted a possible fix. I reused the example of @fatho to create one example to check the issue and the fix. Thanks @fatho 🥇