Simplification of CustomLimitBallAndSocket

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Simplification of CustomLimitBallAndSocket

Postby JoeWright » Sun Dec 21, 2008 9:33 pm

In an attempt to get more fluent with the kind of geometrical thinking needed for joints, I've been going through the source for CustomLimitBallAndSocket and looking to understand everything. When I've finished I'll put my results on the Wiki because I think the mathematical/geometrical interpretation of the code may prove useful for others.

I've come across a section of CustomLimitBallAndSocket::SubmitConstrainst (2.0 beta 17) that initially puzzled me. However, after a bit of algebra I think it simplifies to something that is much more interpretable. Here is the original code:

Code: Select all
      if ((twistDirUp % twistDirUp) > 0.25f)
      {
         dFloat x;
         dFloat y;
         y = twistDirUp % matrix0.m_up; // scalar projection of twistDirUp onto matrix0.m_up
         x = (matrix0.m_up * twistDirUp) % matrix0.m_front;
         angle = dAtan2 (x, y);
      }


and here is my simplification:

Code: Select all
      if ((twistDirUp % twistDirUp) > 0.25f)
      {
         dFloat x;
         dFloat y;
         y = matrix1.m_up % matrix0.m_up;
         x = matrix1.m_up % matrix0.m_right;
         angle = dAtan2 (x, y);
      }


My algebraic justification is as follows (hopefully I've got it right):

y = twistDirUp % matrix0.m_up = (matrix1.m_up - matrix0.m_front.Scale (matrix1.m_up % matrix0.m_front)).matrix0.m_up = matrix1.m_up % matrix0.m_up
since matrix0.m_front is prependicular to matrix0.m_up

x = (matrix0.m_up * matrix1.m_up - matrix0.m_up * matrix0.m_front.Scale(...)) % matrix0.m_front
= (matrix0.m_up * matrix1.m_up) % matrix0.m_front , since matrix0.m_up * matrix0.m_front.Scale(...) is prependicular to matrix0.m_front
taking matrix1.m_up = a * matrix0.m_up + b * matrix0.m_right + c * matrix0.m_front gives:
matrix0.m_up * matrix1.m_up = b * matrix0.m_front - c * matrix0.m_right
so (matrix0.m_up * matrix1.m_up) % matrix0.m_front = b = matrix1.m_up % matrix0.m_right
so x = matrix1.m_up % matrix0.m_right

This gives an easier interpretation of x and y as the projection of matrix1.m_up onto the rotation plane with axis matrix0.m_front. And therefore the angle is the relative twist between the two bodies around matrix0.m_front.

I hope I've got all this right. If so: Julio, how did you arrive at the form in the original code? Does it have a useful methodology to its derivation that could be applied elsewhere?

Also, I think there is a mistake in the definition of dAtan2(x,y). It should be dFloat (atan2 (dFloat(y), dFloat(x))). In other words, the x and y should be swapped. Actually, for the above code I think it helps because by definition atan2 gives the angle from the x-axis so if there was no twist it would give pi/2. With the correct form of atan2 I think it would be better to replace matrix1.m_up with matrix1.m_right.

What are people's thoughts? Is my maths wrong?

Thanks, Joe
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm

Re: Simplification of CustomLimitBallAndSocket

Postby JoeWright » Mon Dec 22, 2008 8:54 pm

Its all a bit quiet :(

One more thing, nearly at the end there's this call: NewtonUserJointAddLinearRow (m_joint, &r0[0], &r1[0], &lateralDir[0]);

However, looking at the code, I think there's only going to be a difference in r0 and r1 along lateralDir if there is a difference between p0 and p1. Any difference between p0 and p1 is being driven to 0 at the top of the function so is this line really necessary? Surely just NewtonUserJointAddLinearRow (m_joint, &r0[0], &r1[0], &longitudinalDir[0]); is needed?

Joe
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm

Re: Simplification of CustomLimitBallAndSocket

Postby Julio Jerez » Mon Dec 22, 2008 10:27 pm

I looked at it,
There are many different ways to do the same. some are better that others but one thing is certain,
and that is the in some orientation the child joint will lose one degree of fredom and the there angles cannot be recovered by projection and axis from one frame over teh other reference frame.
this happen when the orientation is such that one axis o fone of eth frame is almost parallel to one of the other reference frame.

there is nothing wrong with the way you are doing it or with the way I am doing it, both methiods are special variant of Grand Smith Hotogonalization
which is basicall recovering a coordenat esystem from a set of axis that are no mutually perpendicular. Bu teh methdoi suffer fro that fact of lossing DOF.

The best way to make a ball and sukect joint is by using the Rodrigues parameter (quaternion) but it is harder to visualize.
Had you tryed that method? I beleve I ther is a joint that try that, but I am no sure
The good thing is that it will never losses DOF.

note:
when you feel confortable with your joint, if you want I can replace the custom joint in the engine to use your implementation.
Julio Jerez
Moderator
Moderator
 
Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simplification of CustomLimitBallAndSocket

Postby JoeWright » Tue Dec 23, 2008 8:10 am

Thanks Julio.

What I'm doing is going through CustomLimitBallAndSocket in order to better understand this kind of gemotrical thinking. Although my degree was largely applied, we didn't cover this type of gemetrical manipulation.

As I've being going through your code I was expanding out the algebra of the cross and dot products in order to try and get a geometrical understanding. In doing so, they simplified to what I posted so I think what you have coded and what I have written are effectively identical.

My main aim is to make a ball and socket joint with independent min/max angle limits for all 3 axes. My first attempt didn't work so I thought I'd going back to your code so as to educate myself. I think I'm getting a better feel for this stuff and will attempt the new joint soon.

I haven't done anything with quaternions before. It took a bit of reading on wikipedia before I understood the last bit of your code where you used one for a rotation. I only did Gram Schmidt in the one module of pure maths that I did in my degree. That was focusing on linear algebra and I did not recognise it in this context.

More learning for me to do.

Cheers, Joe
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 6 guests