NVIDIAGameWorks/PhysX

increasing D6 Joint accuracy

amir90 opened this issue · 4 comments

I have six actors (see image, the six spheres) arranged in two rows with D6 joints between them.
image

for one row, the left the right actors are constrained to have the same orientation as the middle actor using D6 joints, with PxD6Axis::Swing1, PxD6Axis::Swing2, and PxD6Axis::Twist being locked (and eX,eY and eZ are free). all the actors on this row have there translational DOF locked.

image

I apply a force on the middle vertex on the other row, in the direction of the first row's middle actor.
The left and right actors in this row constrained to lie on its X-axis, using two more D6 joints, and constrained to lie on the X axis of the respective left and right actors in the first row.

However, when running the simulation, I am getting a drift of the middle vertex. from PVD, the reason is that the angular orientation of the actors in the first row is not the same despite the D6 joint that is supposed to enforce this.
image

The orientation values are close, but not enough, and this causes a vey noticeable drift in the actors in the second row

image

I have tried to increase the solver iterations to 32, and reduce the simulation step, and applying the force intermittently (once every 10 frames), but this still happens.

How can I get a better enforcing of the D6 joint constraint on the orientations of the left and right actors in the first row? Is there some kind of joint dominance mechanism in Physx? thanks.

If you can provide a PVD capture, I could test/verify behavior here locally.

There is a way to set dominance in joints - see PxJoint::setInvMassScale0/1 setInvInertiaScale0/1. With these parameters, you can weight the respective rigid bodies' invMasses/invInertias. Values < 1 increase the mass/inertia of the body and values > 1 decrease the mass/inertia. Values of 0 make the mass/inertia infinite for a given body.

Did you try using TGS instead of PGS solver. This should enforce the constraints more robustly.

hi,
attaching PVD capture. thanks!
PVD.zip

And changing to TGS certainly helps, but still not enough.
attached is another PVD capture with the TGS solver for reference
TGS (2).zip

Do you have a specific frame where you think the joint error is particularly bad in the capture? Jumping towards the end of the capture, I can see that there is a small amount of error like this being reported in joint relative errors. I jumped to an arbitrary frame (2053) by scrubbing the time-line. What I'm seeing reported are relative rotations in the order of:

<2.906E-06 -0.008147 -0.000955 1>
<-2.396E-05 -0.01116 0.0004458 0.9999>

Some of the reported values are exact identity, others are off by small margins like this, but I'm not seeing anything particularly far off.

I'm reading these values out from RelativeTransform in the joints. The only joints I'm focusing on are the ones with all 3 rotational DOFs locked as we know that these should be yielding an identity relative rotation.

From looking at this capture, it's also only using 8 solver iterations and 800hz simulation. It's possible more solver iterations or using TGS would drive the errors closer to 0, but I doubt it would get significantly better than this because we will be facing numerical resolution challenges. The internal implementation also leverages small angle approximations, which could lead to very small errors not being corrected (the small angle approximation for locked rotational axes is that theta = sin(theta/2)).

Ok, TGS with 32 position iterations seems to work well. thanks!