Force to stop a point of body in given direction

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Force to stop a point of body in given direction

Postby kallaspriit » Mon Jul 19, 2010 4:35 am

Is there a way to calculate/ask NGD how much force you would have to apply in opposite direction to given direction at a given point of a body to stop it moving in that direction at that point.

I'm doing a ray/convex-cast car and right now I'm using custom joint linear row in the lateral direction of the tire with min/max friction to apply tire lateral force. I'm thinking whether it is possible to calculate the force needed to apply to the body at tire position and lateral direction that would stop the body of the car from skidding sideways at that point?
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm

Re: Force to stop a point of body in given direction

Postby Julio Jerez » Mon Jul 19, 2010 8:31 am

you can calculate the impulse you need to do that, and you can multiply by the time step.
I can post the code for that if you want.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Force to stop a point of body in given direction

Postby kallaspriit » Mon Jul 19, 2010 10:58 am

I would appreciate it very much :)
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm

Re: Force to stop a point of body in given direction

Postby kallaspriit » Mon Jul 19, 2010 2:02 pm

Do you mean finding the velocity at given point and then adding impulse to that position opposite to the direction of velocity with the same magnitude as existing velocity, that would cancel the existing velocity?

I would like the actual force that I need to apply to given point in lateral direction that would stop that body from moving in given direction. I would then use a force that is minimum of either this stopping force or the maximum a tire can generate.

I tried the following and it actually seems to work, but is it correct? I'm doing this in a custom joint between the frame body and NULL body.
Code: Select all
Ogre::Real stopLateralForce = (contact.lateralVelocity * frame->getMass());
Ogre::Real useLateralForce = std::min(fabs(stopLateralForce), tireMaxLateralForce) * (stopLateralForce < 0.0f ? -1.0f : 1.0f);

frame->addGlobalForce(contact.lateralOrientation * Ogre::Vector3::NEGATIVE_UNIT_X * useLateralForce, lateralForceApplicationPosition);
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm

Re: Force to stop a point of body in given direction

Postby Julio Jerez » Mon Jul 19, 2010 2:15 pm

More or less, to force a point on a body to aquire a velocity, is by defintion an impulse calculation problem.
basically you need a pice of code that calculate the velocity and angular velocity you shoud apply to a body in orther for a point on that bopdy to adquire a desired velocity.

I will post the code I use for calculating impulse in the engine, it does very much just that, you can take it and adapt it for what you want.
But I am at work now, remind me tonight.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Force to stop a point of body in given direction

Postby kallaspriit » Tue Jul 20, 2010 6:15 am

Not sure how to remind but it might still help :)
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm

Re: Force to stop a point of body in given direction

Postby Julio Jerez » Tue Jul 20, 2010 10:30 am

here is teh code that calculate teh impulse.

see if you undernad it
Code: Select all
void dgBody::AddImpulse (const dgVector& pointDeltaVeloc, const dgVector& pointPosit)
{
   dgInt32 i;
   dgInt32 j;
   dgMatrix tmpMatrix;

   tmpMatrix[0][0] = m_invMass[0] * m_matrix[0][0];
   tmpMatrix[0][1] = m_invMass[1] * m_matrix[1][0];
   tmpMatrix[0][2] = m_invMass[2] * m_matrix[2][0];
   tmpMatrix[0][3] = dgFloat32 (0.0f);

   tmpMatrix[1][0] = m_invMass[0] * m_matrix[0][1];
   tmpMatrix[1][1] = m_invMass[1] * m_matrix[1][1];
   tmpMatrix[1][2] = m_invMass[2] * m_matrix[2][1];
   tmpMatrix[1][3] = dgFloat32 (0.0f);

   tmpMatrix[2][0] = m_invMass[0] * m_matrix[0][2];
   tmpMatrix[2][1] = m_invMass[1] * m_matrix[1][2];
   tmpMatrix[2][2] = m_invMass[2] * m_matrix[2][2];
   tmpMatrix[2][3] = dgFloat32 (0.0f);

   tmpMatrix[3][0] = dgFloat32 (0.0f);
   tmpMatrix[3][1] = dgFloat32 (0.0f);
   tmpMatrix[3][2] = dgFloat32 (0.0f);
   tmpMatrix[3][3] = dgFloat32 (1.0f);
   dgMatrix invInertia (tmpMatrix * m_matrix);

   // get contact matrix
   dgMatrix tmp;
   //dgVector globalContact (pointPosit - m_matrix.m_posit);
   dgVector globalContact (pointPosit - m_globalCentreOfMass);

   //globalContact[0] = dgFloat32 (0.0f);
   //globalContact[1] = dgFloat32 (0.0f);
   //globalContact[2] = dgFloat32 (0.0f);

   tmp[0][0] = dgFloat32 (0.0f);
   tmp[0][1] = + globalContact[2];
   tmp[0][2] = - globalContact[1];
   tmp[0][3] = dgFloat32 (0.0f);

   tmp[1][0] = -globalContact[2];
   tmp[1][1] = dgFloat32 (0.0f);
   tmp[1][2] = +globalContact[0];
   tmp[1][3] = dgFloat32 (0.0f);

   tmp[2][0] = +globalContact[1];
   tmp[2][1] = -globalContact[0];
   tmp[2][2] = dgFloat32 (0.0f);
   tmp[2][3] = dgFloat32 (0.0f);

   tmp[3][0] = dgFloat32 (0.0f);
   tmp[3][1] = dgFloat32 (0.0f);
   tmp[3][2] = dgFloat32 (0.0f);
   tmp[3][3] = dgFloat32 (1.0f);

   dgMatrix contactMatrix (tmp * invInertia * tmp);
   for (i = 0; i < 3; i ++) {
      for (j = 0; j < 3; j ++) {
         contactMatrix[i][j] *= -dgFloat32 (1.0f);
      }
   }
   contactMatrix[0][0] += m_invMass.m_w;   
   contactMatrix[1][1] += m_invMass.m_w;   
   contactMatrix[2][2] += m_invMass.m_w;   

   contactMatrix = contactMatrix.Symetric3by3Inverse ();

   // change of momentum
   dgVector changeOfMomentum (contactMatrix.RotateVector (pointDeltaVeloc));


   dgVector dv (changeOfMomentum.Scale (m_invMass.m_w));
   dgVector dw (invInertia.RotateVector (globalContact * changeOfMomentum));

   m_veloc += dv;
   m_omega += dw;

   m_sleeping   = false;
   m_equilibrium = false;
   Unfreeze ();
}


basically gine a point on teh body in global space, and a chenge of velocity at tha point, teh funtion add the nessesary velocity and angula velocity to teh body,
to make sure the velocity at tehe point of interest is chnage by the desire amount.

basically all you need to do is calculate teh velocity at teh point you want

v = v_origin + cross ((p - origin) , omega))

if you wan to mak ethe velocity zero, the negate V
v = v.Scale (-1)

the call you version of the function above.

you can write your own flavor becasue as you can see the newton version only work for one point, and also modify some of the internal states of the body,
and you may not want that.
if you want to change more than one opoint at a time, you can use it a loop cycling over the points for few ietration utim all the point get the desires velocity with it some smal tolerance.

also if you are goin to use it for changing the velocity of more than one point
you can separate it in two

the first part calculate the inertia matrix and is common to all ieration since the position and orienation do no change when teh velocity is changes
dgMatrix tmpMatrix;

tmpMatrix[0][0] = m_invMass[0] * m_matrix[0][0];
tmpMatrix[0][1] = m_invMass[1] * m_matrix[1][0];
tmpMatrix[0][2] = m_invMass[2] * m_matrix[2][0];
tmpMatrix[0][3] = dgFloat32 (0.0f);

tmpMatrix[1][0] = m_invMass[0] * m_matrix[0][1];
tmpMatrix[1][1] = m_invMass[1] * m_matrix[1][1];
tmpMatrix[1][2] = m_invMass[2] * m_matrix[2][1];
tmpMatrix[1][3] = dgFloat32 (0.0f);

tmpMatrix[2][0] = m_invMass[0] * m_matrix[0][2];
tmpMatrix[2][1] = m_invMass[1] * m_matrix[1][2];
tmpMatrix[2][2] = m_invMass[2] * m_matrix[2][2];
tmpMatrix[2][3] = dgFloat32 (0.0f);

tmpMatrix[3][0] = dgFloat32 (0.0f);
tmpMatrix[3][1] = dgFloat32 (0.0f);
tmpMatrix[3][2] = dgFloat32 (0.0f);
tmpMatrix[3][3] = dgFloat32 (1.0f);
dgMatrix invInertia (tmpMatrix * m_matrix);



the rest goies in the loop and you can iterate as many time as you wnat.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Force to stop a point of body in given direction

Postby kallaspriit » Mon Jul 26, 2010 11:57 am

Thank you, I'll try to chew through it :)
kallaspriit
 
Posts: 216
Joined: Sun Aug 14, 2005 6:31 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron