Dynamic attached to kinematic with FixedJoint trails a frame behind when using TGS solver #76
-
Hello! If you attach a dynamic to a kinematic with a FixedJoint, and move the kinematic with setKinematicTarget before running the simulation, the dynamic will lag behind the expected position. This only occurs with the TGS solver - if using the older solver the dynamic ends up where expected after simulation. This is an edit of the SnippetJoint sample that minimally reproduces the issue: https://gist.github.com/mfilkry/f9d0b85dce4442e4ae20686636050b9d I am not 100% certain this is a bug, since as far as I can tell:
All of which seems to imply the library would run a kinematic<->dynamic joint from the previous frame's world transform. On the other hand, the documentation states "if you want a very stiff controller that moves the object to specific position each frame, consider jointing the object to a kinematic actor and use the setKinematicTarget function to move the actor." If anyone could help me understand if this is a bug, if I'm doing something wrong, or if it's working as intended, I'd greatly appreciate it. Thank you. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hi @mfilkry , The use of a kinematic + fixed joint is definitely valid and a sensible choice in your scenario. I checked in a unit tests and setting the kinematic target, even before the first call to the solver is working as expected, there is no frame delay. I also ran your modified snippet and I think the effect you're seeing is only due to friction/damping, constraint linearization, and potentially some numerical inaccuracies, but not a frame delay. Take the following printout sequence:
The Looking even closer, I think you're hitting an issue related to constraint linearization, in particular the fact that angular velocity is solved only in the tangent space and your bodies are rotating quite quickly. If I change the following part of your snippet to only use linear velocity (abusing variable names a bit) //PxTransform rotation(PxVec3(0.0f),
// PxQuat(totaltime * vel, PxVec3(0.0f, 1.0f, 0.0f)));
PxTransform rotation(PxVec3(vel * totaltime, 0.0f, 0.0f)); the expected and actual positions actually match as desired:
=> If you can, decrease the time step so your linearization error is smaller, but otherwise you just have to accept that the solve is not 100% accurate. |
Beta Was this translation helpful? Give feedback.
-
Yes, exactly. The point was that if there were a frame delay, the dynamic body would see the target (expected pose) of the previous frame. However, it exceeds that previous target by a lot, meaning it must already have knowledge about the current target, it just doesn't converge very well to it. As to why the effect is worse for TGS than PGS -- I honestly don't really know. Probably it comes down to (one or more) relaxation factors, causing successively larger errors in the TGS iterations ("chasing a moving target") whereas PGS would use the iterations to decrease the error successively as it sees the full velocity/displacement of the kinematic from iteration 1. The linearization problem should be equal for both. So yes, either try substepping yourself or consider replacing the fixed joint with switching the dynamic to kinematic and back once you want to release the joint. |
Beta Was this translation helpful? Give feedback.
Yes, exactly. The point was that if there were a frame delay, the dynamic body would see the target (expected pose) of the previous frame. However, it exceeds that previous target by a lot, meaning it must already have knowledge about the current target, it just doesn't converge very well to it.
As to why the effect is worse for TGS than PGS -- I honestly don't really know. Probably it comes down to (one or more) relaxation factors, causing successively larger errors in the TGS iterations ("c…