Inverse Dynamics for Articulation Bodies

Hey everyone!

We have exciting news to share! The first iteration of Inverse Dynamics is ready for experimentation! It should allow for more control over your simulations in a strictly force centered environment.

The feature consists of 4 main getters:

  • **ArticulationBody.GetDriveForces(**List forces) and the related property getter ArticulationBody.driveForce

  • ArticulationBody.GetJointGravityForces(List forces)

  • ArticulationBody.GetJointCoriolisCentrifugalForces(List forces)

  • ArticulationBody.GetJointForcesForAcceleration(ArticulationReducedSpace acceleration)

GetDriveForces and the associated property driveForce, will return the forces applied by the Articulation Drives. It can tell you how hard each drive is trying to reach the intended target. In a simple example, you could calculate the weight of objects, by how much force they exert on the scale.

GetJointGravityForces fills the supplied list of floats with the forces required to counteract gravity for each link in the chain. This tells you how much weight each link is experiencing due to gravity.

GetJointCoriolisCentrifugalForces fills the supplied list of floats with the forces required to counteract coriolis and centrifugal effects. If applied to the joints, the effects of those forces will be negated.

Otherwise, it tells you how much force is generated due to the coriolis and centrifugal forces.

GetJointForcesForAcceleration will return the forces required to reach the provided acceleration for the ArticulationBody. Applying this force to the joint will propel the body to the desired acceleration.

All of these demos can be found here: GitHub - Unity-Technologies/unity-inverse-dynamics-demo: A small project showing off the Inverse dynamics available in Unity

Inverse Dynamics is available in 2022.1.0a16 and up

We’re excited to hear any feedback you might have about this feature!

15 Likes

Hi
this is great. Will definitly try it out.
Any plans on backporting it to 2021.2?

Cheers Joerg

As it stands right now, it’s unlikely to be approved for back-porting, unfortunately. Complex feature-work. Anthony.

Absolutlly super usfull !!

Hi, is there any plan to support joint friction?

Could you elaborate a bit more on this? Isn’t joint friction supported right now?

Sorry for the confusion, I meant in the contact modeling context, a typical requirement is to do system parameter identification, which need to identify contact dampling, stiffness and friction. Friction in dynamics is very different from in static.

Here is a [recent paper](http://Validating Robotics Simulators on Real World Impacts) which compares the contact modeling between Drake, Bullet and mujoco. I could be wrong, but I think Unity has a similar way as Bullet’s to model the contact, because they both adopt PGS solver for contact/collision, which is what I see in Unity’s physics setting.

Pybullet has a useful API according to its manual: getDynamicsInfo. It returns mass, lateral_friction, rolling friction, spinning friction, contact damping/stiffness, inertia, etc.

I wonder if Unity can also expose the friction-related API if their mechanism to model the contact is similar. And it is relevant for dynamics modeling.

Thanks!

Thanks for the context, I’ll check on the linked paper shortly. With our latest robotics work we recommend to stick to TGS instead of PGS. Also, does it relate to the topic of the thread?

I was smiling until saw that 2022.1.0a16

1 Like

Hi, actually yes, it is relevant to inverse dynamics.

A typical dynamics equation is:
M(q)acc + C(q, vel) vel + G(q) = F

In current API’s context:
F: ArticulationBody.GetDriveForces
G(q): ArticulationBody.GetJointGravityForces
C(q, vel) * vel: ArticulationBody.GetJointCoriolisCentrifugalForces
M(q): ArticulationBody.GetJointForcesForAcceleration

However, the external force can be caused by many factors, dynamic joint friction is an example.

In the real world, the applied force should overcome many resistant force, so that it can control the movement as described in the Left hand of equation.

Thus it should be something like M(q)*acc + C(q, vel) * vel + G(q) + F_res = F
Joint friction is a major part of F_res.

Normally, the friction term can be modeled with respect to velocity:
F_fri = F_c*sign(vel) + F_v * vel + asys

F_c is the coulomb’s coefficient
F_v is the viscosity coefficient (internal friction)
asys is a term for symmetry

But as you may find in the paper I mentioned earlier, in simulator, they usually have some adaptation to suit the virtual world.

My point is: I think Unity is a platform of great potential, and we have invested so much on this platform for our research or other purpose. Thus I hope it can get better and better.

3 Likes

^ That’s a great overview!

Actually, PhysX does not include friction in the returned forces for Inverse Dynamics. I would assume you would need to include the calculations yourself, based on the friction/damping properties of your Articulation chain.

3 Likes

Nice tech, I am keep learning “Quadratic Programming” and “Linear Complementary Problem” of the physics engine’s contact and constraint solvers.
Once I make it I hope am gonna create that physics based character locomotion system.

So far “Toribash” did a great job regarding physics based animation like in the video.

I am pretty sure one day manual artist character animation system will be totally automated by several algorithms!

1 Like

Thanks, got it

Hi,

Another feedback here.

It seems the return values of GetDriveForces are in generalized force form. I wonder how it can be converted to torque, as in common robot arm, like UR5, franka emika panda?

Most control equations in robotics are built upon torques. I think it is a serious issue.

Looking forward to your reply.
Thanks!

P.S. We actually conduct a parallel experiment on both sim and real environments with Franka. The joint torques from real franka and the joint drive force from unity have similar trend, but very different scales.

I’m not sure how that can be. The forces returned should be in reduced space. If the joint is a revolute one, then the force returned should equate to torque? Or am I misunderstanding something?

Ok, so the unit is Nm? I will check the value of the physics properties for each joint and see if something wrong there.

1 Like

We recently updated the documentation to state the units of measurement for stuff like forces and other properties.

The doc page for driveForce will come soon, but it will pretty much state the same for the units of measurement

“Units of measurement - N (newtons) for linear and Nm (newton-meters) for angular motion.”

How has no one mentioned the cute little humanoid test-dummies in your examples? I love them!

2 Likes

Hello - Im currently stabilizing a walking biped.

        jntControl.root.maxAngularVelocity = 0f;

        var uprightAngle = Vector3.Angle(transform.up, Vector3.up) / 180;
        var balancePercent = uprightTorqueFunction.Evaluate(uprightAngle);
        var uprightTorqueVal = balancePercent * zxTorqueForces;

        var rot = Quaternion.FromToRotation(transform.up, Vector3.up);
        jntControl.root.angularVelocity = new Vector3(rot.x, rot.y, rot.z) * uprightTorqueVal;

        float dot = Vector3.Dot((moveTarget.position - jntControl.root.transform.position).normalized, jntControl.root.velocity);
        jntControl.root.velocity = Vector3.ClampMagnitude(dot * jntControl.root.velocity, targetVelocity);

        if (pelvisSpeed < targetVelocity)
            jntControl.root.AddForce((moveTarget.position - jntControl.root.transform.position).normalized * Input.GetAxis("Vertical") * 250f);

This is very naive and produce a very artificial look - even if I unlock y-axis gravity effects.

Im looking to reduce the effects of gravity acting on the rig while moving towards a target.
Looking through the examples of inverse dynamics github Im quite stumped on how to
achieve this. I basically want to negate the additional forces lifting a leg creates on the rig
but yet this have it act physically - I hope that makes sense.

Edit

In short - Its been explained to me that its possible to create a “virtual force” - for instance you have foot planted; In that case it should be “connected” to the ground.

The effect is similar to foot being held to the ground-point but can rotate freely ?

As described in the paper https://www.cs.ubc.ca/~van/papers/2010-TOG-gbwc/index.html
under : 3.4 Gravity Compensation