Joints stiffness

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Joints stiffness

Postby Julio Jerez » Mon Jul 13, 2015 6:01 pm

I got it stable by replacing the angular powered row of my joint with a linear row.

this should work realizably, you right it makes it a lot simple to make joints, by for some reason they seem to be softer.

I'll add my joints to your demo. Should be a good testcase...

yes if you add your joint to the test that will be a great help for testing this out.

I now revisited the Math again and Now I think I have the way to incorporate the stiffness.
It turn out I have almost right the first time, I apple the wrong sign, by since there were so many other bug, I could no figure that one. I will commit that check in to tonight after some test.

This actually important for stability, if you se the bridge in the play controller demo, It shakes very violently, there are 43 plank, and It thon kit is a t the limit of becoming unstable.
by adding a stiffened value the that can be controlled by the client app and I till still be strong.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby Julio Jerez » Mon Jul 13, 2015 6:37 pm

Joe, do not change your joints, from angular constraint to linear constraint.

It should the other way around, the angora row should be as solute as the linear rows, and believe I know what problems is.
I will test the tonight, and if I am right it is I that will change all the joint using linear rows to use angular rows. There no reason for angular roads to be so soft
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby JoeJ » Mon Jul 13, 2015 6:43 pm

Sounds good!
For sure i keep all versions of this damn ragdoll joint :)
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby Julio Jerez » Tue Jul 14, 2015 7:03 am

Ok Joe, I finally decide to no be lazy and do the correct angular rows, instead of faking it will linear row.
In the ear days of Newton I was trying to about trigonometry at all cost, and that's is how I end up using point to points to do almost every thing, only of the case where I need the angular row I use it,

although this trick is easy to visualize it has some drawback, and you found out.
1- it needs that extra ankle point at an arbitrary distance to generate the canceling torque, this actually has some nasty effect on eth mass matrix, because it make large matrices, WE god by because the solver is good enough to handle it, how ever I think is the long run is I cause a more poor converge.
2- It is no always clear that you can find a good set of six axis that are mutually perpendicular

to fix that problem is actually quiet eassy and no different the same way we do linear rows
the procces is as followe.

1-Get and axis the if fix in one body.
2-find a second axis the you know moist be perpendicular to the first axis.
2-Project the axis over is over it counter axis on the fist body, that will give the cox of the angle
3-Calcual the cross product of the axis and its counter part of the first body. the project over the fist axis, (a triple cross product) this will give the sine of the angle
4-the arch tangent of the sin and cos, is the angle the nee to be drive to zero
5-sublet an angle row wik the negative of the angle and the fist axis as argument

and that is all,
I did for the Hinge, please check it out, later I will migrate all the joints to use that system.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 8:53 am

I have added my Joint to your StandartJoints.cpp. (Added class JoesRagdollJoint, func AddJoesPoweredRagDoll and setup code at the very bottom).
There is a nice side by side comparision to your RagDollJoint.

I have linear and angular powering modes, but only angular works for now.
I must have made a mistake translating my own linear code. I may fix it, but i think i've found the reason why the angular joint blows up for me, so linear method will become obsolete most probably.



EDIT: Do not copy this code - i'm actually fixing terrible bugs and most of it got lost after editing post.



Code: Select all
/* Copyright (c) <2009> <Newton Game Dynamics>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely
*/

#include <toolbox_stdafx.h>
#include "SkyBox.h"
#include "DemoEntityManager.h"
#include "DemoCamera.h"
#include "PhysicsUtils.h"
#include "DemoMesh.h"
#include "OpenGlUtil.h"
#include <CustomGear.h>
#include <Custom6DOF.h>
#include <CustomHinge.h>
#include <CustomSlider.h>
#include <CustomPulley.h>
#include <CustomCorkScrew.h>
#include <CustomBallAndSocket.h>
#include <CustomRackAndPinion.h>

// optionally uncomment this for hard joint simulations
#define _USE_HARD_JOINTS

struct JoesRagdollJoint
{
   NewtonBody* m_body0;
   NewtonBody* m_body1; // parent
   dMatrix m_localMatrix0;
   dMatrix m_localMatrix1;
   NewtonJoint* m_joint;

   dQuaternion m_target; // relative target rotatation to reach at next timestep

   float m_reduceError; // amount of error to reduce per timestep (for my ragdoll i need to use a low value of 0.2 in practice)
   float m_pin_length;
   float m_angularFriction;
   float m_linearFriction;

   bool m_useLienarMotor;

   JoesRagdollJoint (NewtonBody* child, NewtonBody* parent, const dMatrix &localMatrix0, const dMatrix &localMatrix1, NewtonWorld *world)
   {
      m_body0 = child;
      m_body1 = parent;
      m_localMatrix0 = localMatrix0;
      m_localMatrix1 = localMatrix1;
      m_target = dQuaternion (dVector(1,0,0), 0);
      m_joint = NewtonConstraintCreateUserJoint (world, 6, JoesRagdollJoint::Callback, 0, child, parent);
      NewtonJointSetUserData (m_joint, (void*) this);

      m_reduceError = 0.2f;
      m_pin_length = 10.0f;
      m_angularFriction = 1000.0f;
      m_linearFriction = 1000.0f;

      m_useLienarMotor = false;
   }

   //inline const dVector ArbitaryTangent (const dVector &v) const
   //{
   //   dVector ref;
   //   float x = v[0]*v[0];
   //   float y = v[1]*v[1];
   //   float z = v[2]*v[2];
   //   dVector temp;
   //   if (x<=y && x<=z)      temp = dVector(1,0,0,0);
   //   else if (y<=x && y<=z)   temp = dVector(0,1,0,0);
   //   else               temp = dVector(0,0,1,0);
   //   temp = v * temp;
   //   temp.Scale (1.0f / sqrt (temp % temp));
   //   return temp;
   //}

   void SubmitConstraints (dFloat timestep, int threadIndex)
   {
      float invTimestep = 1.0f / timestep;
      
      dMatrix body0Matrix; NewtonBodyGetMatrix(m_body0, &body0Matrix[0][0]);
      dMatrix body1Matrix; NewtonBodyGetMatrix(m_body1, &body1Matrix[0][0]);      
      dMatrix matrix0 = m_localMatrix0 * body0Matrix;
      dMatrix matrix1 = m_localMatrix1 * body1Matrix;

      // point to point constraint

      dVector p0 (matrix0.m_posit);
      dVector p1 (matrix1.m_posit);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_front[0]);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_up[0]);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_right[0]);


      // measure error

      dQuaternion q0 (matrix0);
      dQuaternion q1 (matrix1);

      dQuaternion qt0 = m_target * q1;
      dQuaternion qErr = (q0.DotProduct(qt0) < 0.0f
         ? dQuaternion (-q0.m_q0,  q0.m_q1,  q0.m_q2,  q0.m_q3)
         : dQuaternion ( q0.m_q0, -q0.m_q1, -q0.m_q2, -q0.m_q3)) * qt0;

      dVector errorAxis (qErr.m_q1, qErr.m_q2, qErr.m_q3);
      float sql = errorAxis % errorAxis;
      
      if (sql   < 1.0e-5f)
      {
         // error is tiny - do we need to make a fixed joint / some damping here?
         // To me it seems ok to do nothing.
      }
      else
      {
         errorAxis.Scale(1.0f / sqrt (sql));         
         float errorAngle = 2.0f * acos (max (-1.0f, min (1.0f, qErr.m_q0)));
         
         // fix rotation axis

         dVector pin = p1 + errorAxis.Scale(m_pin_length);
         dMatrix basis (dGrammSchmidt (errorAxis));
         //dMatrix basis;
         //basis[0] = pin;
         //basis[1] = ArbitaryTangent(pin);
         //basis[2] = basis[0] * basis[1];

         NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[1]);
         NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[2]);

         dVector angVel0, angVel1;
         NewtonBodyGetOmega (m_body0, (float*)&angVel0);
         NewtonBodyGetOmega (m_body1, (float*)&angVel1);                  
                  
         // motor

         if (!m_useLienarMotor) // default angular motor
         {
            dVector errorAngVel = errorAxis.Scale (errorAngle * invTimestep * m_reduceError) - (angVel0 - angVel1);

            NewtonUserJointAddAngularRow (m_joint, 0.0f, &errorAxis[0]);
            NewtonUserJointSetRowAcceleration (m_joint, errorAxis % errorAngVel * invTimestep);
            NewtonUserJointSetRowMinimumFriction (m_joint, -m_angularFriction);
            NewtonUserJointSetRowMaximumFriction (m_joint,  m_angularFriction);
         }
         else // linear motor // todo: DOES NOT WORK - BUG SOMEWHERE
         {
            // construct two pins that remove error if they match
            dVector pin0 (p1 + basis[1].Scale(m_pin_length));
            dVector pin1 (p1 + (basis[2].Scale(sin(errorAngle)) + basis[1].Scale(cos(errorAngle)) ).Scale(m_pin_length));
            dVector diff = pin1 - pin0;

            // calculate velocity at pins
            dVector linVel0, linVel1;
            NewtonBodyGetVelocity (m_body0, (float*)&linVel0);
            NewtonBodyGetVelocity (m_body1, (float*)&linVel1);   
            dVector com0, com1;
            //NewtonBodyGetCentreOfMass (m_body0, (float*)&com0);
            //NewtonBodyGetCentreOfMass (m_body1, (float*)&com1);
            com0 = body0Matrix.m_posit;// TransformVector (com0);
            com1 = body1Matrix.m_posit;// TransformVector (com1);                  
            dVector v0 (angVel0 * (pin0 - com0) + linVel0);
            dVector v1 (angVel1 * (pin1 - com1) + linVel1);

            dVector relAcc ( (diff.Scale(m_reduceError * invTimestep) - (v0 - v1)).Scale(invTimestep) );
            diff.Scale (1.0f / sqrt(diff % diff));

            NewtonUserJointAddLinearRow (m_joint, (float*)&pin0, (float*)&pin1, (float*)&diff);
            NewtonUserJointSetRowAcceleration (m_joint, relAcc % diff);
            NewtonUserJointSetRowMinimumFriction (m_joint, -m_linearFriction);
            NewtonUserJointSetRowMaximumFriction (m_joint,  m_linearFriction);
         }
      }
      
   }

   static void Callback (const NewtonJoint* joint, float timestep, int threadIndex)
   {
      JoesRagdollJoint *custom = (JoesRagdollJoint*) NewtonJointGetUserData(joint);
      custom->SubmitConstraints (timestep, threadIndex);
   }
};

// ...
Last edited by JoeJ on Tue Jul 14, 2015 10:51 am, edited 2 times in total.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 8:59 am

Ok Joe, I finally decide to no be lazy and do the correct angular rows, instead of faking it will linear row.
In the ear days of Newton I was trying to about trigonometry at all cost, and that's is how I end up using point to points to do almost every thing, only of the case where I need the angular row I use it,

although this trick is easy to visualize it has some drawback, and you found out.
1- it needs that extra ankle point at an arbitrary distance to generate the canceling torque, this actually has some nasty effect on eth mass matrix, because it make large matrices, WE god by because the solver is good enough to handle it, how ever I think is the long run is I cause a more poor converge.
2- It is no always clear that you can find a good set of six axis that are mutually perpendicular

to fix that problem is actually quiet eassy and no different the same way we do linear rows
the procces is as followe.

1-Get and axis the if fix in one body.
2-find a second axis the you know moist be perpendicular to the first axis.
2-Project the axis over is over it counter axis on the fist body, that will give the cox of the angle
3-Calcual the cross product of the axis and its counter part of the first body. the project over the fist axis, (a triple cross product) this will give the sine of the angle
4-the arch tangent of the sin and cos, is the angle the nee to be drive to zero
5-sublet an angle row wik the negative of the angle and the fist axis as argument

and that is all,
I did for the Hinge, please check it out, later I will migrate all the joints to use that system.


Yep, there are some things in joint lib that never looked really right to me (flipping behaviour in limit ball socket is best example). I agree you overused linear rows for angular purposes.
I'll look at the hinge, pls do the same for my ragdoll.
I'll add some procedural animation so it's visible what this is about...
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby Julio Jerez » Tue Jul 14, 2015 11:56 am

Ok I now converted more of standard joints
hinge, slider, corkscrew, and universal. later will do the ball and socked all flavors and the power ragdooll and the 6dof

The joint no can shared no common functionality with is nice.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 1:59 pm

I have fixed all bugs, now it should be a good test.
Animation and linear mode working now.
You can see my joints are less stiff than yours.
But it does not reproduce my problem that angular mode has for my ragdoll.
I will see if it's a matter of complexity, tweaking or bugs...

Joint code:
Code: Select all
struct JoesRagdollJoint
{
   NewtonBody* m_body0;
   NewtonBody* m_body1; // parent
   dMatrix m_localMatrix0;
   dMatrix m_localMatrix1;
   NewtonJoint* m_joint;

   dQuaternion m_target; // relative target rotatation to reach at next timestep

   float m_reduceError;
   float m_pin_length;
   float m_angularFriction;
   float m_linearFriction;
   float m_stiffness;

   bool m_useLienarMotor;
   float m_anim_speed;
   float m_anim_offset;
   float m_anim_time;

   JoesRagdollJoint (NewtonBody* child, NewtonBody* parent, const dMatrix &localMatrix0, const dMatrix &localMatrix1, NewtonWorld *world)
   {
      m_body0 = child;
      m_body1 = parent;
      m_localMatrix0 = localMatrix0;
      m_localMatrix1 = localMatrix1;
      m_target = dQuaternion (dVector(1.0f,0,0), 0.0f);
      m_joint = NewtonConstraintCreateUserJoint (world, 6, JoesRagdollJoint::Callback, 0, child, parent);
      NewtonJointSetUserData (m_joint, (void*) this);

      m_reduceError = 0.2f; // amount of error to reduce per timestep (more -> oszillation)
      m_pin_length = 10.0f;
      m_angularFriction = 300.0f;
      m_linearFriction = 100.0f;
      m_stiffness = 0.9f;

      m_useLienarMotor = false;
      m_anim_speed = 0.0f;
      m_anim_offset = 0.0f;
      m_anim_time = 0.0f;
   }

   void SubmitConstraints (dFloat timestep, int threadIndex)
   {

      float invTimestep = 1.0f / timestep;
     
      dMatrix body0Matrix; NewtonBodyGetMatrix(m_body0, &body0Matrix[0][0]);
      dMatrix body1Matrix; NewtonBodyGetMatrix(m_body1, &body1Matrix[0][0]);     
      dMatrix matrix0 = m_localMatrix0 * body0Matrix;
      dMatrix matrix1 = m_localMatrix1 * body1Matrix;

      if (m_anim_speed != 0.0f) // some animation to illustrate purpose
      {
         m_anim_time += timestep * m_anim_speed;
         float a0 = sin (m_anim_time);
         float a1 = m_anim_offset * 3.14f;
         dVector axis (sin(a1), 0.0f, cos(a1));
         //dVector axis (1,0,0);
         m_target = dQuaternion (axis, a0 * 0.5f);
      }

      // point to point constraint

      dVector p0 (matrix0.m_posit);
      dVector p1 (matrix1.m_posit);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_front[0]);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_up[0]);
      NewtonUserJointAddLinearRow (m_joint, &p0[0], &p1[0], &matrix1.m_right[0]);


      // measure error

      dQuaternion q0 (matrix0);
      dQuaternion q1 (matrix1);

      dQuaternion qt0 = m_target * q1;
      dQuaternion qErr = (q0.DotProduct(qt0) < 0.0f
         ? dQuaternion (-q0.m_q0,  q0.m_q1,  q0.m_q2,  q0.m_q3)
         : dQuaternion ( q0.m_q0, -q0.m_q1, -q0.m_q2, -q0.m_q3)) * qt0;
      
      float errorAngle = 2.0f * acos (max (-1.0f, min (1.0f, qErr.m_q0)));

      if (errorAngle < 1.0e-10f)
      {
         // error is tiny - do we need to make a fixed joint / some damping here?
         // To me it seems ok to do nothing.
      }
      else
      {
         dVector errorAxis (qErr.m_q1, qErr.m_q2, qErr.m_q3, 0.0f);
         errorAxis = errorAxis.Scale(1.0f / dSqrt (errorAxis % errorAxis));         
         
         // fix rotation axis

         dVector pin = p1 + errorAxis.Scale(m_pin_length);
         dMatrix basis (dGrammSchmidt (errorAxis));
         
         NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[1]);
         NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[2]);

         dVector angVel0, angVel1;
         NewtonBodyGetOmega (m_body0, (float*)&angVel0);
         NewtonBodyGetOmega (m_body1, (float*)&angVel1);                 
                 
         // motor

         if (!m_useLienarMotor) // default angular motor
         {
            dVector errorAngVel = errorAxis.Scale (errorAngle * invTimestep * m_reduceError) - (angVel0 - angVel1);

            NewtonUserJointAddAngularRow (m_joint, 0.0f, &errorAxis[0]);
            NewtonUserJointSetRowAcceleration (m_joint, errorAxis % errorAngVel * invTimestep);
            NewtonUserJointSetRowMinimumFriction (m_joint, -m_angularFriction);
            NewtonUserJointSetRowMaximumFriction (m_joint,  m_angularFriction);
            NewtonUserJointSetRowStiffness (m_joint, m_stiffness);
         }
         else // linear motor
         {
            // construct two pins that remove error if they match
            dVector pin0 (p1 + basis[1].Scale(m_pin_length));
            dVector pin1 (p1 + ( basis[2].Scale(sin(errorAngle)) + basis[1].Scale(cos(errorAngle)) ).Scale(m_pin_length));
            dVector diff = pin1 - pin0;
         
            // calculate velocity at pins
            dVector linVel0, linVel1;
            NewtonBodyGetVelocity (m_body0, (float*)&linVel0);
            NewtonBodyGetVelocity (m_body1, (float*)&linVel1);   
            dVector com0, com1;
            NewtonBodyGetCentreOfMass (m_body0, (float*)&com0);
            NewtonBodyGetCentreOfMass (m_body1, (float*)&com1);
            com0 = body0Matrix.TransformVector (com0);
            com1 = body1Matrix.TransformVector (com1);                 
            dVector v0 (angVel0 * (pin0 - com0) + linVel0);
            dVector v1 (angVel1 * (pin1 - com1) + linVel1);
         
            dVector relAcc ( (diff.Scale(m_reduceError * invTimestep) - (v0 - v1)).Scale(invTimestep) );
            diff = diff.Scale (1.0f / sqrt(diff % diff));
         
            NewtonUserJointAddLinearRow (m_joint, (float*)&pin0, (float*)&pin1, (float*)&diff);
            NewtonUserJointSetRowAcceleration (m_joint, relAcc % diff);
            NewtonUserJointSetRowMinimumFriction (m_joint, -m_linearFriction);
            NewtonUserJointSetRowMaximumFriction (m_joint,  m_linearFriction);
            NewtonUserJointSetRowStiffness (m_joint, m_stiffness);
         }
      }
     
   }

   static void Callback (const NewtonJoint* joint, float timestep, int threadIndex)
   {
      JoesRagdollJoint *custom = (JoesRagdollJoint*) NewtonJointGetUserData(joint);
      custom->SubmitConstraints (timestep, threadIndex);
   }
};


Setup code:
Code: Select all
void AddJoesPoweredRagDoll (DemoEntityManager* const scene, const dVector& origin, const int jointType = 1, const float animSpeed = 0.0f, const int numSegments = 4)
{
   float height = 1.0f;
   float width = 4.0f;

   dVector size (width, height, width);
   NewtonBody* parent = CreateBox (scene, origin + dVector (0.0f,  0.5f, 0.0f, 0.0f), size);

#ifdef _USE_HARD_JOINTS
   NewtonSkeletonContainer* const skeleton = NewtonSkeletonContainerCreate (scene->GetNewton(), parent, NULL);
#endif

   for (int i=0; i<numSegments; i++)
   {
      float height = 1.0f;
      float width = 0.5f;

      dVector size (width, height, width);
      NewtonBody* child = CreateBox (scene, origin + dVector (0.0f,  0.5f + height * float(i+1), 0.0f, 0.0f), size);

      if (jointType == 0) // Julios
      {
         dMatrix pinMatrix = dGrammSchmidt (dVector (0.0f, -1.0f, 1.0f, 0.0f));
         dMatrix matrix0; NewtonBodyGetMatrix (parent, &matrix0[0][0]);
         dMatrix matrix1; NewtonBodyGetMatrix (child, &matrix1[0][0]);
         pinMatrix.m_posit = (matrix0.m_posit + matrix1.m_posit).Scale (0.5f);
         CustomControlledBallAndSocket* const joint = new CustomControlledBallAndSocket (pinMatrix, child, parent);
      }
     else
      {
         dMatrix matrix0 = dGetIdentityMatrix(); matrix0.m_posit = dVector (0.0f, height*-0.5f, 0.0f, 1.0f);
         dMatrix matrix1 = dGetIdentityMatrix(); matrix1.m_posit = dVector (0.0f, height*0.5f, 0.0f, 1.0f);
         JoesRagdollJoint* joint = new JoesRagdollJoint (child, parent, matrix0, matrix1, scene->GetNewton());

       if (jointType == 2) joint->m_useLienarMotor = true;
       if (animSpeed != 0.0f) joint->m_anim_speed = animSpeed, joint->m_anim_offset = float(i) / float(numSegments); // animated
      }

#ifdef _USE_HARD_JOINTS
      NewtonSkeletonContainerAttachBone (skeleton, child, parent);
#endif
     
      parent = child;
   }


#ifdef _USE_HARD_JOINTS
   NewtonSkeletonContainerFinalize(skeleton);
#endif
   
}


and this at the bottom:
Code: Select all
   AddJoesPoweredRagDoll (scene, dVector (0.0f, 0.0f, -15.0f), 1, 1.5f); // angular + animated
   AddJoesPoweredRagDoll (scene, dVector (0.0f, 0.0f, -5.0f), 1); // angular
   AddJoesPoweredRagDoll (scene, dVector (0.0f, 0.0f, 5.0f), 2); // linear
   AddJoesPoweredRagDoll (scene, dVector (0.0f, 0.0f, 15.0f), 0); // Julio
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 2:14 pm

JoeJ wrote:But it does not reproduce my problem that angular mode has for my ragdoll.


Oh, i see you have already fixed. Angular Mode works now with ragdoll + skeleton. Great! :mrgreen:


JoeJ wrote:I also see some strange things (let's ignore them for now):

Improved stiffness shows up only after i reset the ragdoll once (teleporting bodies to startpose and zeroing velocities).


This effect is still there, but it makes more sense now.
Looking at the arms of balancing ragdoll. It holds them straight and stiff for some seconds, then suddenly left arm falls down a bit ("nonstiff mode"). Ater a second it snaps back up to "stiff mode" and so forth.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby Julio Jerez » Tue Jul 14, 2015 2:25 pm

Ha very cool, tonight when I apply the change to the Power Rag doll, I will take your joint and add a new demo to standard joint, then we can see why they are different, in the end they soul be very similar. One reason for a dof becoming soft is when they are not orthogonal.
This is quite hard to check when sun angular dof, whey is one of the reason why I used the lean DOF why make is easer to select orthogonal dof.

a way to detect the if the mass matrix Jacobians are orthogonal is by calculations the joint mass matrix and check if it PDS. The more skew the matrix is the softer the joints becomes.

Tonight I will add the new function to the SDK, it will be debug check for validation the joints.
It is amassing how more and more we are coming full circle, almost all the functionality that was in 1.5 is now coming back again, but the time we learned from the mistakes.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 5:37 pm

Julio Jerez wrote:and that is all,
I did for the Hinge, please check it out, later I will migrate all the joints to use that system.


Ha - looking at your new hinge, you not only control angle limit with an angular row, but also fix the rotation axis with angular rows.
That's the way i did with my inital hinge.
Later i replaced by linear approach because i thought it minimizes the "many order indipendent angles" problem that you mentioned.
I thought linear rows are always order independent, so the solver likes them more.
Guess that's wrong and it's just like "It's bad when rows work against each other - no matter if linear or angular." ?

Let's see how this works with the powered ragdoll :) ...
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby Julio Jerez » Tue Jul 14, 2015 6:39 pm

JoeJ wrote:I thought linear rows are always order independent, so the solver likes them more.
Guess that's wrong and it's just like "It's bad when rows work against each other - no matter if linear or angular." ?

I said that it is easier to visualize mutually perpendicular Degree of freedom when using linear rows than it is when using angular rows

The way you the angular rows geometrailly is by answering the question, Given two bodies and on axis of rotation, what acceleration have to be applied to the body so ta the relative annual velocity remedy contacts. so if Dir the direction vector, you vane stable a constrain we only the pin

the reaosn si the whenyou calcual the angualderivative

w = der (dir) / drev (dt) = cross (omega, dir) % dir = const
but ta expression is always zero, so it is no suffeunct for stabilizing the constraint

on the size when using linear rows, the expression is, given a point on body what accelratikomn si nessesati to make the velocity contanct.
the is
P = p0 + R

where p0 is the cent of mass and R the vector for the origin to the point, the derivative of the expression is
V = (veloc + cross (Omega, R)) % dir = const

as you can see the expression is no zero, so the constant fact can be extracted and the are the jacobian. that what submit linear row does,

for the angular to work similarly you need an auxiliary vector perpendicular to the pin. and the where the problem is, because et is no always clear how to get the vector

assuming you can get the vector the expression becomes
dir % V = zero
the derivative Is

(cross (omega, dir) % V + dir % cross (omega, v)) % dir = const
afeter some algebarica manipulation you get the jacobian is gien bu vetor

cross (dir, V) * Omega

bu the is no intuitive, because the rotation axis is perpendicular to V and dir., so what I do is the I extract that put of the calculation and let the joint pass
cross (dir, V), and that is more intuitive, by it still have the problem that when using more the one row, it is no always easy to find three expression

cross (dir1, V1)
cross (dir2, V2)
cross (dir3, V3)

that are mutually perpendicular, because usually dir fix to one body while V is fixed to the other the other, in some cases like the 3dof it may be that neither is fixed to any body.
after I convert al the joints hopefully it will make more sense.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Joints stiffness

Postby JoeJ » Tue Jul 14, 2015 7:04 pm

Ok, will need to read this sometimes to get a bit :)
It may be related to this question...

Code: Select all
// fix rotation axis

dMatrix basis (dGrammSchmidt (errorAxis));
if (0)
{
   dVector pin = p1 + errorAxis.Scale(m_pin_length);   
   NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[1]);
   NewtonUserJointAddLinearRow (m_joint, (float*)&pin, (float*)&pin, (float*)&basis[2]);
}
else
{
NewtonUserJointAddAngularRow (m_joint, 0, &basis[1][0]);
NewtonUserJointAddAngularRow (m_joint, 0, &basis[2][0]);
}

// do motor on errorAxis...


I did this in the meantime on the joint code posted above and it works as good as the linear method.

But no matter if using linear or angular, does it matter what directions basis 1+2 have?
I do not like they are random. Would it make sense to rotate base around the errorAxis?
Maybe aligning this with relative acceleration somehow can improve the result?
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby JoeJ » Thu Jul 16, 2015 1:29 pm

I'm pretty sure the missing stiffness for my joint is because of the low reduceError factor and has nothing to do with the skeleton.
Also i think the factor has to be low because the base made from the error angle is unstable.
In the past i had success smoothing this and will try again...
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Joints stiffness

Postby Julio Jerez » Thu Jul 16, 2015 2:23 pm

I am going over all the joints now, doing the conversion,
one problem is the all familiar Gimbal lock do show up, so when converting the joints with more than on angular dof, I have to be careful.
I have a hard time doing the universal because of that. but I converted already

I converted many more already, I still need to do the powered rag doll, The I will covert you joint and put a demo, jour joint should after because just as strong as the Newton Custom.
Maybe one more day or tow to get every thing.

edit: I see that you added a comment to you joint, after get your later, please post again so that I can take a look. Meant time I will on over the custom Power rag doll
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: Julio Jerez and 5 guests