Stiff Joint

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Stiff Joint

Postby JoeJ » Tue May 29, 2012 3:31 pm

Julio Jerez wrote:His method will work, however it will not recover from any deformation.


Just to clear out: I didn't suggest the angular method here, it's something Carli came up with.
With "rotational distortion" i mean the same as you with "...the joint will never recover and will drift apart over time".

carli2 wrote:The relative position matrix already contains the information about the rotation, so I have to * it out.

I think you discovered the same problem too :)
Note: You use the body orienation for the linear rows, but only to define a space to solve the positional problem.
You could use any orthonrmal space for that as well, like an identity matrix.
That does not handle any orientational stuff, it's only a 3D point to point constraint.

Julios example constrains the relative orientation by constructing points at a distance from the bodies centers.
That's like aligning levers to link their orientations, and works fine.

Julio Jerez wrote:when I get back to the Joints, I will make the power Ragdoll use this method.

I have high hope for that. I should take some time to make a video from my powered ragdoll.
While i still havo no AI, i could show good animation matching works, and where the limits are.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Stiff Joint

Postby carli2 » Tue May 29, 2012 3:35 pm

I solved it with the old method now:
Code: Select all
procedure callback(const userJoint: PNewtonJoint; timestep : Float; threadIndex : int); cdecl;
var m0, m1: TMatrix4;
    p0, p1: TVec3;
begin
  NewtonBodyGetMatrix(NewtonJointGetBody0(userJoint), @m0[0][0]);
  NewtonBodyGetMatrix(NewtonJointGetBody1(userJoint), @m1[0][0]);
  m1:=TJoint(NewtonJointGetUserData(userJoint)).matrix*m1; // Target matrix

  // Position
  p0:=MatrixGetTransform(m0); // Is-Matrix
  p1:=MatrixGetTransform(m1); // Should-be-Matrix
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[0][0]);
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[1][0]);
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[2][0]);

  // Rotation of two axis
  p0:=ApplyMatrixToVec3(m0, SetVector(100,0,0));
  p1:=ApplyMatrixToVec3(m1, SetVector(100,0,0));
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[1][0]);
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[2][0]);

  // Last Axis
  p0:=ApplyMatrixToVec3(m0, SetVector(0,100,0));
  p1:=ApplyMatrixToVec3(m1, SetVector(0,100,0));
  NewtonUserJointAddLinearRow(userJoint, p0, p1, @m1[2][0]);
end;


Yes, it's exactly the same solution as I find in all other code for rigid joints. But now I understood why I need these rows and I know which matrices I need.
carli2
 
Posts: 157
Joined: Thu Nov 10, 2011 1:53 pm

Re: Stiff Joint

Postby Julio Jerez » Tue May 29, 2012 6:11 pm

Here is the demonstration that ‘if you apply a series of rotation by decomposing the angle into a sequence of small rotations, what you get is a series of rotation than can be applied in any order"
let us say the desired angles are P ( pitch) and Y (yaw)
Let us say we take:
Code: Select all
P =  n * dp
Y =  n * dy
This extends to three angles but for simplicity let just use two.
where n in a numbe is smal delta angle and the desire product matrix is
Code: Select all
M = Pitch(P) * Yaw (Y)
Whet Pitch an dYaw are matrix function that calculate a rotation around X and Y axis
Substituting P and Y we get
Code: Select all
M = Pitch[dp(0) + dp(1) + … dp(n)] * Yaw [dY(0) + dy(1) + … dy(n)]
M = Pitch(dp(0)) * Pitch(dp(1)) * … Pitch(dp(n))) * Yaw (dY(0)) * Pitch(dy(1)) * … Pitch(dy(n)))


This if not what we want, what need an serirus of angle like this
Code: Select all
M = Pitch(dp(0)) * Yaw (dY(0)) *  Pitch(dp(1)) * Yaw (dY(1)) *  … Pitch(dp(n)) * Yaw (dY(n));

But this apperas to breaks the commutative laws of linear algebra of matrix mutiplication.

Let us see what the general turn Pitch(dp(n)) * Yaw (dY(n)) look like
Code: Select all
            1    0     0
Pich(dp) =  0  cos(dp) sin(dp)
            0 -sin(dp) cos(dp)

           cos (dy)  0  -sin(dy)
Yaw(dy) =   0        1    0         
          sin (dy)  0   cos(dy)

product of these matrix is given by

Code: Select all
                      cos (dy)                 0        -sin(dy)
Pich(dp) * Yaw(dy) =  sin (dp) * sin (dy)     cos(dp)    sin (dp) * cos(dy)
                      cos (dp) * sin (dy)    -sin(dp)    cos (dp) * cos(dy)

                      cos (dy)   sin (dy) * sin (dp)   -sin(dy) * cos(dp)
Yaw(dy) * Pich(dp)  =   0        cos(dp)                sin(dp)     
                      sin (dy)  -cos (dy) * sin (dp)    cos(dy) * cos(dp)


we can see that simbolically they are very different, but we know that if we select dy and dp not to be larger than some small value,
then we can make these approximations
Code: Select all
cos (dp) ~=  cos(dy) ~= 1.0;
sin (dp) ~=  sin(dy) ~= dy ~= dp;

for example of dp = 2 degress of less (a large value)
Code: Select all
cos (3.1416/180) = cos (0.0393) = 0.999 ~= 1.0
sin (3.1416/180) = sin (0.0393) = 0.035 ~= 0.0393


now if we make these substitutions, we get
Code: Select all
                      1.0f     0.0     -dy
Pich(dp) * Yaw(dy) =  dp * dy  1.0     dp
                      dy      -dp      1.0

                      1.0    dy * dp   -dy
Yaw(dy) * Pich(dp)  =   0     1.0       dp     
                       dy    -dp        1.0



they still look different but we also know that of if if dp and dy are a small value, then dp * dy is a secund order smaller values
ex: dp = 0.0393 * 0.0393 = 0.0015
this suggest that we can neglect the secund order small values comimg from the product of the sin of two or more small deltas, and we now get
Code: Select all
                       1.0f     0.0     -dy
 Pich(dp) * Yaw(dy) =  0.0      1.0     dp
                       dy      -dp      1.0

                       1.0    0.0   -dy
 Yaw(dy) * Pich(dp)  =   0     1.0       dp     
                        dy    -dp        1.0
and

wich proof that for a small angles, the product of tow rotaion matrices is comutative.
Pich(dp) * Yaw(dy) = Yaw(dy) * Pich(dp)


now going back to the product of two large angles, by using a sumantion of all teh small angles, we get
Code: Select all
 M  =  Pitch(dp(0)) * Yaw (dY(0)) *   Pitch(dp(1)) * Yaw (dY(1)) *  … Pitch(dp(n)) * Yaw (dY(n));
    = Pitch(dp(0)) * Pitch(dp(1)) * … Pitch(dp(n))) * Yaw (dY(0)) * Pitch(dy(1)) * … Pitch(dy(n)))
    ~= Pitch(dp(0)) * Yaw (dY(0)) *  Pitch(dp(1)) * Yaw (dY(1)) *  … Pitch(dp(n)) * Yaw (dY(n));

and this is what make possible to make a general 3dof euler joint, if we accept that teh Error is limiet to a max angule velocity
you cna mix any combination of angle and they will work
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Stiff Joint

Postby JoeJ » Wed May 30, 2012 3:06 am

That's very interesting. It took me a hour to understand, and another half to think about: What can it be good for?
Now i need to ask: Your solver uses 'tricks' like that to get closer to a solution after a single iteration, yes?

And if so, there comes another similar problem afterwards: The resulting matrix will be not orthonormal.
How do you normalize it? The usual way of taking an axis, normalizing it and crossing it with others... is also order dependent and would drift.
Now i would take all possible combinations, convert to quats and lerp them together weighted somehow by inertia...
but there are surely faster and exacter methods?
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Stiff Joint

Postby Julio Jerez » Wed May 30, 2012 7:53 am

it i sgood because the physics calculate toruques, an dforce, which are comutative.
angular rotation are no comutatiove, this is why angul ajoint are diffircult to make,
to go aroung the p[roblem of comutativity, you need to figure put axis that are mutually perpendiculat all the time.but that is not alway possible and some time
a set of axis that are perpedicular in one orientation, are not longer perpedicular in other make a joint unstable.

this aproximation make it possibel to make rubust joint, that are alway statble, teh probl;em is that teh joint will hae a "maximum angular velocity to maanitaian the constrant"
Like I said I am going to re implemnet teh 3Dof , an dteh Ragdoll power joint using that aproximantion.
the resulting matrix of a joint like that will not be completly orthogonal, however the orthonality problem is resolve after each integration step, since the rotation is projected back into a unit quaternion.

and not the solve does not make any assumption, it simple solve what imput it put in, it does not in validates for contation valiodity, if you imput gabage you get garbage out.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Previous

Return to General Discussion

Who is online

Users browsing this forum: Dave Gravel and 4 guests

cron