Access Joint during Simulation

In my program i use the RevoluteJoint to build a multibody. These multijoints have a motor. Everything works until here. What i would like to know is how can i access the motors and change their values during simulation. E.g. if a user is controlling a car and the wheels are connected to the mainbody of the car and he increases the velocity during simulation.
I guess there might be a way using the bodyset and maybe handles? However i can not figure it out.
Thanks in advance


You can follow that example which enables/disables a motor depending on the position of a pin-slot joint. The following snippet assumes your multibody has the handle multibody_handle and the multibody link which has the joint you want to modify is the link_id-th:

let link = body_set.multibody_mut(multibody_handle).and_then(|mb| mb.link_mut(link_id));
if let Some(revolute) = link {
    let joint = levolute
    // Do something with the joint.

Note that the velocity of the joint are not stored on the joint itself. So if you need to change the joint’s velocity directly, you can use that:

let mut joint_velocity = multibody.joint_velocity_mut(link_id);
joint_velocity[0] = 10.0;

In your case, since the revolute joint has only one degree-of-freedom, the returned vector will have only one component.

1 Like

Thanks a lot. That already was a big help and worked so far. Could you also show how you could iterate through the bodyset and manipulate all revolute motors that you can find? That would be a big help.
Thank you!

In the following, assuming bodies is a DefaultBodySet, you can do:

for (handle, body) in bodies.iter() {
    if let Some(multibody) = body.downcast_ref::<Multibody<f32>>() {
        for joint in multibody.links().filter_map(|l| l.joint().downcast_ref::<RevoluteJoint<f32>>()) {
            // Do something.

If you need mutable references, you would do:

for (handle, body) in bodies.iter_mut() {
    if let Some(multibody) = body.downcast_mut::<Multibody<f32>>() {
        for joint in multibody.links_mut().filter_map(|l| l.joint_mut().downcast_mut::<RevoluteJoint<f32>>()) {
            // Do something.

However you can’t because there is no .links_mut() method on multibodies. This is an oversight so I’ve opened a PR that adds it:

EDIT: this PR is now merged and released with nphysics2d and nphysics3d 0.12.3. So a cargo update should be enough for you to be able to use the mutable iteration mentioned above.

Thanls a lot, this is exactly what i was looking for!