Hinge joints going nutts

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Hinge joints going nutts

Postby Spek » Tue Apr 26, 2011 11:01 am

Both with Newton 1.xx and 2.xx, I often had the problem of connected bodies (usually 2 simple convex hulls with a ball-socket or hinge between) going insane as soon as they fall in a somehow wrong way on the static mesh (collision tree).
Ragdolls would fly around like helicopters, but also more simple stuff had this issue sometimes.

Now I've been trying to make my own joints. So far I just copied the code from dCustomJointHinge.cpp and such. The Ball-Socket Joint seems to behave better now, but the Hinge still goes madd way too often. Also with lower mass values.

Some more details:
- I move the object by trigger a body impulse first (on both bodies)
- Object falls on the static mesh, then it goes madd sometimes
- Gravity is 0,-9.8,0
- Tried pinDirections on all 3 main-axis. It happens in all cases.
- Contact settings (kinematics, softness, elasticity) are overrided
- Bodies can't collide with each other (collisionState = 0)
- See picture

If you like, I can post some code-parts.
Attachments
HingeBoxes.jpg
HingeBoxes.jpg (36.23 KiB) Viewed 1927 times
Spek
 
Posts: 66
Joined: Sat Oct 04, 2008 8:54 am

Re: Hinge joints going nutts

Postby Julio Jerez » Tue Apr 26, 2011 11:53 am

usually when this happens is becaus ethe inertia is wrong.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Hinge joints going nutts

Postby Spek » Tue Apr 26, 2011 12:51 pm

Hmmm. The inertia for both objects is calculated with the
NewtonConvexCollisionCalculateInertialMatrix() function
Then for each body it is set like this:
Code: Select all
                NewtonBodySetMassMatrix( nBody, props.mass,
                                         props.inertia[0] * props.mass,
                                         props.inertia[1] * props.mass,
                                         props.inertia[2] * props.mass );

Don't know if the results are right though:
big box (convex hull with 8 vertices in the shape of a cube, size = 1x1x1 ):
mass = 40
inertia vector = {0.16666, 0.16666, 0.16666} (multiplied with 40 makes {6.666, 6.666, 6.666})

small box (convex hull with 8 vertices in the shape of a cube, size = 0.5x0.5x0.5 ):
mass = 20
inertia vector = {0.04166, 0.04166, 0.04166} (multiplied with 20 makes {0.8332, 0.8332, 0.8332})

Would that be a proper setup?
Cheers
Spek
 
Posts: 66
Joined: Sat Oct 04, 2008 8:54 am

Re: Hinge joints going nutts

Postby Julio Jerez » Tue Apr 26, 2011 10:43 pm

are you calculation the inertia using the newton funtion?
had you run in debug mode and see if it crashe some where in the engine?
do you have a test demo?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Hinge joints going nutts

Postby Spek » Wed Apr 27, 2011 3:12 am

Yep, using the Newton function, using version 2.32.

As for crashes. Not sure if I'm doing it right, but to use Debug modus, you'll have to use the "newton_d.dll" right? Well, there is one error right at the start when I create that joint:
"Debug Assertaion Failed!"
...\source\newton\NewtonClass.cpp
Line: 238
Expression: 0

It doesn't crash right in the constructor, but as soon the joint callback comes, I get this error. Some more details:
- Delphi crashes on this exact line in the joint-callback
Code: Select all
                NewtonUserJointAddAngularRow(userJoint, Angle, @globalMatrix0[0, 0]);
                NewtonUserJointSetRowStiffness(userJoint, 0.4);
     -->           NewtonUserJointSetRowSpringDamperAcceleration(userJoint, 0.991{K spring stifness}, 0.991{D spring damper});

Commenting the last line removes the error message.

- When not using this function, the "hinge maddness" still happens btw.
- With Newton 2.33 I don't have this error btw... I didn't update the headers yet, so that's why I'm using version 2.32.

I'm afraid I can't wrap a demo quickly, as I'm using Delphi & some custom packages.
Spek
 
Posts: 66
Joined: Sat Oct 04, 2008 8:54 am

Re: Hinge joints going nutts

Postby Julio Jerez » Wed Apr 27, 2011 10:11 am

If it geta an assert on any of this lines
Code: Select all
NewtonUserJointAddAngularRow(userJoint, Angle, @globalMatrix0[0, 0]);
                NewtonUserJointSetRowStiffness(userJoint, 0.4);
     -->           NewtonUserJointSetRowSpringDamperAcceleration(userJoint, 0.991{K spring stifness}, 0.991{D spring damper});

the the joint definition is wrong and will definitly behave the way is does.
comention it out will remov teh waring but will no fi xthe crash of the malfuntion.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Hinge joints going nutts

Postby Spek » Wed Apr 27, 2011 11:16 am

Ok, makes sense. But I wonder what I'm doing wrong of course. The code is pretty much a copy of the custom hinge in Newton.
Code: Select all
< Joint Constructor >
            nJoint      := NewtonConstraintCreateUserJoint(
                                          nWorld,
                                          6,  // MaxDOF
                                          @callBack_Joint, // Callback function
                                          nil, // no getInfo callback
                                          aChild, aParent  );
            NewtonJointSetCollisionState( nJoint, 0 );
            NewtonJointSetUserData( nJoint, self );
            self.calculateLocalPivotMatrices( aPin, aPivot );

Not sure if anything can cause violations here. Or is the "getInfo" callback required for the debug DLL?

Onto the callBack then.
Code: Select all
             self.calculateGlobalMatrices(globMatrix0, globMatrix1);

             // Restrict the movement on the pivot point along all tree orthonormal direction
             NewtonUserJointAddLinearRow(userJoint, @globMatrix0[3,0], @globMatrix1[3,0], @globMatrix0[0,0]); // Restrict Forward axis
             NewtonUserJointAddLinearRow(userJoint, @globMatrix0[3,0], @globMatrix1[3,0], @globMatrix0[1,0]); // Restrict Up axis
             NewtonUserJointAddLinearRow(userJoint, @globMatrix0[3,0], @globMatrix1[3,0], @globMatrix0[2,0]); // Restrict Right axis

             // get a point along the pin axis at some reasonable large distance from the pivot
            vectorScale( globMatrix0[0], MIN_JOINT_PIN_LENGTH, q0 );
            vectorScale( globMatrix1[0], MIN_JOINT_PIN_LENGTH, q1 );
            AddVector( q0, globMatrix0[3] );   // Add q0 to globalMatrix position
            AddVector( q1, globMatrix1[3] );

             // two constraints row perpendicular to the pin vector
              NewtonUserJointAddLinearRow(userJoint, @q0[0], @q1[0], @globMatrix0[1]);
             NewtonUserJointAddLinearRow(userJoint, @q0[0], @q1[0], @globMatrix0[0]);

The actual code has some more lines (see block below), to apply that Damping/Spring, and to limit the angle. However, if I comment all that stuff out:
- I don't get a crash anymore
- But the hinge object still goes crazy

The only reason I can think off, is that either the matrices are wrong somehow (although normally the child does rotate around the parent in a correct way). Or I forgot to do something.


But to make the code complete, here the last part of the callback:
Code: Select all
            { Limit angle between a min/max angle (if we have any) }
             sinAngle := vectorDotProduct( globMatrix0[0], vectorCrossProduct( globMatrix0[1] , globMatrix1[1] ) );
             cosAngle := vectorDotProduct( globMatrix0[1], globMatrix1[1] );
            angle    := ArcTan2(sinAngle, cosAngle);

              // the joint angle can be determine by getting the angle between any two non parallel vectors
              if (angle < self.FMinAngle) then
            begin
                   relAngle := angle - self.FMinAngle; // Get error
                   // tell joint error will minimize the exceeded angle error
                   NewtonUserJointAddAngularRow( userJoint, relAngle, @globMatrix0[0,0] );
                   // need high stiffness here
                   NewtonUserJointSetRowStiffness ( userJoint, 1.0);
                   // allow the joint to move back freely
                   NewtonUserJointSetRowMaximumFriction(self.nJoint, 0.0);
              end else
            if (angle  > self.FMaxAngle ) then
            begin
                   relAngle := angle - self.FMaxAngle;
                   // tell joint error will minimize the exceeded angle error
                   NewtonUserJointAddAngularRow( userJoint, relAngle, @globMatrix0[0,0] );
                   // need high stiffness here
                   NewtonUserJointSetRowStiffness (userJoint, 1.0);
                   // allow the joint to move back freely
                   NewtonUserJointSetRowMaximumFriction(self.nJoint, 0.0);
            end else
            begin
                { Angle in tolerated range }
                { spring / damper }
                NewtonUserJointAddAngularRow(userJoint, Angle, @globMatrix0[0, 0]);
                NewtonUserJointSetRowStiffness(userJoint, 0.4);
     CRASH           NewtonUserJointSetRowSpringDamperAcceleration(userJoint, 0.991{K spring stifness}, 0.991{D spring damper});
            end;


Something missing? Wrong order of doing things maybe?
Spek
 
Posts: 66
Joined: Sat Oct 04, 2008 8:54 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron