Questions about FixDistance Joint

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Questions about FixDistance Joint

Postby JoeJ » Thu Apr 20, 2023 7:47 pm

Code: Select all
void ndJointFixDistance::JacobianDerivative(ndConstraintDescritor& desc)
{
   ndMatrix matrix0;
   ndMatrix matrix1;

   // calculate the position of the pivot point and the Jacobian direction vectors, in global space.
   CalculateGlobalMatrix(matrix0, matrix1);

   ndVector p0(matrix0.m_posit);
   ndVector p1(matrix1.m_posit);

   ndVector dir(p1 - p0);
   ndFloat32 mag2 = dir.DotProduct(dir).GetScalar();
   if (mag2 > ndFloat32(1.0e-3f))
   {
      dir = dir.Scale(1.0f / ndSqrt(mag2));
      ndFloat32 x = ndSqrt (mag2) - m_distance;

      ndMatrix matrix(dir);
      ndVector com0(m_body0->GetCentreOfMass());
      ndMatrix body0Matrix(m_body0->GetMatrix());
      ndVector veloc0(m_body0->GetVelocityAtPoint(p0));

      ndVector com1(m_body1->GetCentreOfMass());
      ndMatrix body1Matrix(m_body1->GetMatrix());
      ndVector veloc1(m_body1->GetVelocityAtPoint(p1));

      ndFloat32 v((veloc0 - veloc1).DotProduct(dir).GetScalar());
      ndFloat32 a = (x - v * desc.m_timestep) * desc.m_invTimestep * desc.m_invTimestep;

      ndVector r0 ((p0 - body0Matrix.TransformVector(com0)).CrossProduct(matrix.m_front));
      ndVector r1 ((p1 - body1Matrix.TransformVector(com1)).CrossProduct(matrix.m_front));

      AddLinearRowJacobian(desc, p0, p0, matrix0.m_right);
      ndJacobian& jacobian0 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM0;
      ndJacobian& jacobian1 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM1;

      jacobian0.m_linear = matrix[0];
      jacobian0.m_angular = r0;

      jacobian1.m_linear = matrix[0].Scale(ndFloat32 (-1.0f));
      jacobian1.m_angular = r1.Scale(ndFloat32(-1.0f));

      SetMotorAcceleration(desc, a);
   }
}

Fyi, due to the out commented code, i think you could set the joint to use just one row instead 3?
And you could remove the matrix variable and use just dir, since the other axis are not used.

But now my questions:
1. What's the purpose of r0 and r1? And what does jacobian.m_angular do?
I feel that's something i should know.

2. In this line: AddLinearRowJacobian(desc, p0, p0, matrix0.m_right);
Why do you use matrix0.m_right?
Intuitively i would have used dir, and after trying that i noticed no difference.
Maybe it does not matter here? Could we even use a zero vector?
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm

Re: Questions about FixDistance Joint

Postby Julio Jerez » Fri Apr 21, 2023 12:49 pm

there are different ways of doing the same thing, if you can see in the constructor.
you will see that it is a one dof joint.
Code: Select all
ndJointFixDistance::ndJointFixDistance(const ndVector& pivotInChildInGlobalSpace, const ndVector& pivotInParentInGlobalSpace, ndBodyKinematic* const child, ndBodyKinematic* const parent)
   :ndJointBilateralConstraint(1, child, parent, ndGetIdentityMatrix())


It does not uses the row of the matrix, it uses the distance between the two pivots.
R0 and R1 are the distance from the center of mass of the body to the pivot.

when the body is rotating that vector generate three accelerations:
a linear, a centripetal and a Coriolis.

those have to be considered. that what the Jacobian angular does.
you mention that is use matrix.m_right

if you look by the beginning, of ndJointFixDistance::JacobianDerivative
that distance between the two pivots is turn into a Gram-Schmidt normalization for dir,

ndMatrix matrix(dir);

therefore, the right vector is aligned with the direction. the other two are perpendicular.

finally:
Now that you make that observation, It is possible to make the case that using the matrix row,
can be a special case.
For example, if someone what to keep the distance between pivots very, very small.
in that case the normalization is inaccurate, but the rows can still provide for the constraint directions.

In the pass I use to do that, making the engine fool proof, but for 4.00 I am not doing that baby sister couching, if the distance is so close them the app most realize that that joint is special case of a spherical joint.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Questions about FixDistance Joint

Postby JoeJ » Fri Apr 21, 2023 1:34 pm

a linear, a centripetal and a Coriolis.

Makes sense. (although i don't know yet what those terms mean.) :)
But now i hope with considering this i might have success with a 'super joint'.
This would allow to connect a foot directly to a torso, without a need for upper / lower leg bodies.
I never got this to work previously. Would be nice for cheap or low lod characters.

The Newton code i have should be only few weeks old, from the time when i've reported the clang issues.
those have to be considered. that what the Jacobian angular does.
you mention that is use matrix.m_right

No, it's not using the Gramm Schmidt matrix, but one of the global matrices made from the bodies:
Code: Select all
      AddLinearRowJacobian(desc, p0, p0, matrix0.m_right);
      ndJacobian& jacobian0 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM0;
      ndJacobian& jacobian1 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM1;

Thus i was confused, since this direction could become the same as dir.
Will do the update at some time to see how this has changed...

But actually my plan for the distance joint has already failed.
I can't get my ragdoll to balance, and so i was desperate enough to try the old helper joint approach from my previous work. The distance joints are used to create a link from foot to hip / chest directly. This helped with the old joints. But with the new ones it shouldn't be needed. And indeed, it made no difference.
So there must be something else i do wrong...

But my stuff is not a total failure.
I already got the ragdoll swinging left and right about 4 times successfully. That's not bad. :)
But it only works if do NOT sync the physics ragdoll to the controller model.
So basically the controller calculates procedural animation, and the ragdoll tries to follow it, until it diverges too much and falls down.
Well, at least this confirms the controller works and it's properties match the ragdoll.
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm

Re: Questions about FixDistance Joint

Postby Julio Jerez » Fri Apr 21, 2023 2:26 pm

AddLinearRowJacobian(desc, p0, p0, matrix0.m_right);

what that does is that creates a slot on the joint constraiont array.

the next two lines,
ndJacobian& jacobian0 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM0;
ndJacobian& jacobian1 = desc.m_jacobian[desc.m_rowsCount - 1].m_jacobianM1;

read the slot and override the joints parameter.
when it override it the direct is no longer matrixm_right

I suppose I could used:
AddLinearRowJacobian(desc, p0, p0, dir);
but notice that dir is not normalized. so that will probably trigger asserts.

one this: "a linear, a centripetal and a Coriolis."
you can read the base and more rigoruss definitions in Wikipedia.
basically, the linear acceleration in the change R * angular velocity, time the time step because it is a time step in the future future.

centripetal is that force that you fell when you spins, when you drive your car and you make a turn you feel it all the time. it is W * W * R

Coriolis is the force when R changes in length while spinning. Tends to move the bodies sideway.
for most joint is zero, but for sliders and stuff like that is not.

you do not need to worry about that the solver does the calculation as long as the Jacobian are set correctly.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Questions about FixDistance Joint

Postby JoeJ » Fri Apr 21, 2023 3:00 pm

Ok, thanks for the explanation!
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 51 guests