Porting from 3.xx to 4.00 - need help

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Tue Jul 18, 2023 3:18 pm

Julio Jerez wrote:ah yes, I added now.


Thanks Julio! Another one I came across is:

in 3.xx:

Code: Select all
dVector::DotProduct3(dVector v);


Is there an equivalent in 4.00 or just default to ndVector::DotProduct() ?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby Julio Jerez » Tue Jul 18, 2023 4:32 pm

ndVector::DotProduct().GetScalar();
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Thu Jul 20, 2023 12:09 pm

Julio Jerez wrote:ndVector::DotProduct().GetScalar();


Thanks Julio. A couple of other ones, if you can confirm:

NewtonCollision => ndShapeInstance
NewtonBody => ndBodyDynamic
NewtonJoint => ndContact
dCustomJoint => ?

Thanks!
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Tue Jul 25, 2023 4:57 pm

misho wrote:
Julio Jerez wrote:ndVector::DotProduct().GetScalar();


Thanks Julio. A couple of other ones, if you can confirm:

NewtonCollision => ndShapeInstance
NewtonBody => ndBodyDynamic
NewtonJoint => ndContact
dCustomJoint => ?

Thanks!


Hi Julio, just wondering if you could confirm the above?

Thanks!
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby Julio Jerez » Tue Jul 25, 2023 6:11 pm

these are right
NewtonCollision => ndShapeInstance
NewtonBody => ndBodyDynamic

theses:
dCustomJoint => teh base class is ndJointBilateralConstraint

dContact in 3.xx is the same ndContact
but those are managed by the scene, you can only query then

all joints are subclass ndConstraint.h
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Fri Jul 28, 2023 11:01 am

Thanks, Julio!

Ok, moving forward, the following functionality in 3.xx (which my code depends on) is also missing in 4.00:

dQuaternion::GetEulerAngles()
dQuaternion::RotateVector()
dQuaternion::UnrotateVector()

dMatrix::dMatrix(dQuaternion, dVector)
dMatrix::dGrammSchmidt()
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby Julio Jerez » Fri Jul 28, 2023 11:34 pm

added these tree
dQuaternion::GetEulerAngles()
dQuaternion::RotateVector()
dQuaternion::UnrotateVector()


these are:

dMatrix::dMatrix(dQuaternion, dVector)
is
ndMatrix ndCalculateMatrix(const ndQuaternion& quat, const ndVector& position)

dMatrix::dGrammSchmidt()
is
ndMatrix ndGramSchmidtMatrix(const ndVector& dir)
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Sat Jul 29, 2023 12:16 am

That was fast!! Thanks Julio, I really appreciate it!!
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Fri Aug 11, 2023 6:28 pm

Hi Julio!

Just wondering if you perhaps had some spare cycles to let me know how to do what we talked about over a month ago? Details below.

Thanks!!

misho wrote:Ok, to further clarify and simplify this test case, I have updated it to include 2 separate objects, a jet cargo aircraft, and a droppable fuel tank (shown in blue), attached to the red pylon (which is a part of the aircraft) on the left aircraft wing.

Image

Test case source, Aircraft and Fuel tank FBX files can be found here:

ndMishoTestCase.cpp
SimpleCargoPlane.fbx
SimpleFuelTank.FBX

The code first loads the Aircraft and Fuel tank, and joins them with the hard ndJointFix6dof Joint. Both bodies are Dynamic type. You can use "P" key to destroy the joint and drop the tank, and "O" key to position and re-attach the fuel tank by re-creating the ndJointFix6dof joint.

There is also a matrix called FlightSimPosition, which basically represents the position and orientation of the aircraft which would be dictated (set) by Flight Simulator. This matrix does nothing in the default state of the test case.

Then - you can use "U" key to UNLOCK the setting of the position of the FlightSimPosition matrix. What this does is,

  • MOVES the FlightSimPosition matrix horizontally by using I,J,K, and M keys
  • APPLIES this matrix to the Aircraft body's position

You can use "L" key to again LOCK the moving and application of this matrix to Aircraft body. In the LOCKED mode, Aircraft and Fuel Tank are locked tightly to each other. You can grab and tumble the aircraft around with a mouse pointer, and the Fuel Tank will stay attached to it, as expected. In the UNLOCKED mode, when aircraft is moved using the keys, Fuel Tank follows but with a "rubber band" delay.

So basically, the ask is to have the plane in the UNLOCKED mode so that its position (and orientation, but I have not implemented that) can be set externally, (in my case, by a Flight Simulator flight model), but all the attached objects stay rigidly attached to it. I hope this test case simplifies it a bit more.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Fri Nov 24, 2023 2:56 pm

Ok, so while Julio is busy with AI, I've decided to take a stab at this myself. I am following along the lines of the discussion I had with Julio way back in June, where he supplied a few lines of pseudo code on how to do this: (NOTE, I am doing this in 3.14, as Julio suggested this has been implemented by someone else in 3.14 with success)
Julio Jerez wrote:you can use a dynamics body.
then in the notify call back, give a force and torque callback that translate the conversion of the changes in the trajectory to impulses.
that is, in each frame once you calculate:

Code: Select all
v to move from p(body) to p(plane)
w to move from q(body) to q(plane)


you can calculate a Linear and angular impulse.
Code: Select all
LinearImpulse = (v - v(body)) * inverseMass
angularImpulse = (w - w(body)) * inverseInertia


them use the function on the dynamics body to apply the impulse to the dynamic body representing the plane.

this is how was done in 3.xx, and I believe the will probably be simpler for you.
The plane will be a dynamics body and will work with everything that you are used to.
so it will be a full physics object.

What I have now is an airplane in my sim, which:
  • has a Newton Dynamic Body attached to it, WITHOUT Force and Torque callback, which is set to NULL
  • Newton Dynamic Body is positioned and oriented by the data from the SIM
I have another Newton Dynamic Body which represents a weapon (a missile), which I can "on-demand" attach to airplane's wing. When added (and the aircraft is stationary), the missile is aligned properly and fixed to the airplane using a hard (fixed) joint. When I start to MOVE the airplane, the missile follows, but with a large lag (the faster the airplane moves, the larger the lag is). If I STOP moving the airplane, the missile catches up into its correct position. So far, I think I have this set up correctly (as far as setting the position of the aircraft body and the missile linking), because the missile is being oriented correctly (aligned with aircraft body) no matter what position or orientation the aircraft is.

Now, the only part missing is how to close the lag between the missile and the aircraft, when the aircraft is in motion. Julio provided pseudo code for this (at the top of this post) which employs applying impulse to the missile to allow it to catch up to the airplane (Although Julio specified that the impulse be applied to the aircraft, which I assume is a typo), and I've taken a stab at it to see if I can get it going. I think I am understanding everything, and I've implemented the code to the best of my understanding, however, I am STILL observing the gap/lag. Here is the code, with comments on how I interpret what needs to be done: (NOTE: I am doing the linear impulse first, no angular impulse calcs for now)

Code: Select all
// Phys_ProcessBodyImpulse() is a member function of the TBEntity class,
// and it is being applied to the CHILD (missile) object
// and called from ApplyForceAndTorqueCallback()
// Parent's (aircraft) "Attach point 0" is a 3D point on PARENT object in
// local space where missile is being attached
// Child's (missile) "Attach point 0" is a 3D point on CHILD object in
// local space where missile is being attached

void TBEntity::Phys_ProcessBodyImpulse(double dBodyTimeStep)
{
      dVector vDeltaV(0.0, 0.0, 0.0, 1.0); // speed needed for linear impulse
      dVector dvNull(0.0, 0.0, 0.0, 1.0); // null vector needed for angular impulse
      dVector LinearImpulse(0.0, 0.0, 0.0, 1.0); // linear impulse vector

      // Get the PARENT (aircraft) entity and its body matrix:
      TBEntity *pParentEnt = NewtonGetUserEntity();
      dMatrix ParentBodyMatrix;
      NewtonBodyGetMatrix(pParentEnt->nBody, &ParentBodyMatrix[0][0]);

      // Get the INVERSE body mass, basically GetCurrentBodyMass(bool bGetInverseMass)
      // calls NewtonBodyGetInvMass() and returns inverse mass
      double dInvBodyMass = GetCurrentBodyMass(true);

      // Get position of where CHILD object should be
      // (a point under the PARENT's wing)
      // (parent pos + parent ap in global space)
      dVector vParentAPPosition = pParentEnt->GetAttachPoint(0)->location;
      dVector vParentPosition = pParentEnt->GetPosition() + ParentBodyMatrix.RotateVector(vParentAPPosition);

      // Get position of where CHILD object is
      // (current CHILD object pos + CHILD object ap in global space)
      dVector vAPPosition = GetAttachPoint(0)->location;
      dVector vPosition = GetPosition() + bodyMatrix.RotateVector(vAPPosition);

      // calculate speed needed to get from where it is to where it should be:
      vDeltaV = (vPosition - vParentPosition).Scale(1.0f / dBodyTimeStep);

      // calculate impulse needed using this speed
      LinearImpulse = (vDeltaV - GetVelocity()).Scale(dInvBodyMass);

      // Finally, apply impulse
      NewtonBodyApplyImpulsePair(nBody, &LinearImpulse[0], &dvNull[0], dBodyTimeStep);
}


I've done some checks and the calculations for vPosition and vParentPosition seems to be correct (the difference between these 2 vectors decreases to zero as the missile catches up to the aircraft), so I think vDeltaV calculation is also correct - basically, difference between 2 points in space divided by time should give me velocity vector vDeltaV.

LinearImpulse calculation is also as per Julio's pseudo code, although I am not certain what exactly is Inverse Mass being applied to it.

Finally, applying this impulse TO THE MISSILE, not to the airplane (as Julio suggested, since I think it may be a typo) does not fix the lag at all, nor does it diminishes it in any way. :cry:

Can anyone please check the code and let me know if and what I am doing wrong? I would greatly appreciate it. Please feel free to ask for any clarifications to the above.
Last edited by misho on Fri Nov 24, 2023 5:26 pm, edited 1 time in total.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby JoeJ » Fri Nov 24, 2023 5:03 pm

misho wrote:although I am not certain what exactly is Inverse Mass being applied to it.


Looking up the code you got it wrong:

double dInvBodyMass = GetCurrentBodyMass(true);

should be the inverse mass, so 1 / mass.

I think there is a function to return this directly, to spare a division.
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Fri Nov 24, 2023 5:39 pm

JoeJ wrote:
Looking up the code you got it wrong:

double dInvBodyMass = GetCurrentBodyMass(true);

should be the inverse mass, so 1 / mass.

I think there is a function to return this directly, to spare a division.


Thanks for you input JoeJ!

Actually, I think I have it right (explanation is in the comments). The "true" parameter in my GetCurrentBodyMass function means I want an inverse mass.

Code: Select all
      // Get the INVERSE body mass, basically GetCurrentBodyMass(bool bGetInverseMass)
      // calls NewtonBodyGetInvMass() and returns inverse mass
      double dInvBodyMass = GetCurrentBodyMass(true);


my function GetCurrentBodyMass(bool bGetInverseMass) looks like this:

Code: Select all
double TBEntity::GetCurrentBodyMass(bool bInverse)
{
   dFloat Ixx;
   dFloat Iyy;
   dFloat Izz;
   dFloat mass;

   if (nBody)
   {
      if (bInverse)
         NewtonBodyGetInvMass(nBody, &mass, &Ixx, &Iyy, &Izz);
      else
         NewtonBodyGetMass(nBody, &mass, &Ixx, &Iyy, &Izz);
   }
   return mass;
}


Yes, I wasn't sure why there is a function that returns just a 1/value, but there are some explanations online that specify this as a method of saving ALU cycles when 1/mass is called repeatedly, and spares a division.

I am still unsure why Julio specified calculation of the impulse to be I = v*(1/m) when the physics equation is

I = v*m.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby JoeJ » Fri Nov 24, 2023 6:14 pm

Oh, sorry.
I'm totally unused to impulses, and can't tell if maybe mass vs. invMass was a typo too. (try both ofc.)
But i can give some pseudo code on driving the attached missile by applying force:
Code: Select all
Vec3 targetVel = (missile.pos - airplane.pos) / timestep;
Vec3 curVel = missile.vel;
Vec3 accel = (targetVel - curVel) / timestep;
Vec3 force = accel * missile.mass;
// hopefully that's right ;)

You could apply this force instead the impulse. I assume technically there should be no difference, but not sure.

EDIT: Fixed the snippet, thought about syncing velocity instead position
Last edited by JoeJ on Fri Nov 24, 2023 8:40 pm, edited 1 time in total.
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Fri Nov 24, 2023 8:01 pm

JoeJ wrote:You could apply this force instead the impulse. I assume technically there should be no difference, but not sure.


Right - thanks, I will give it a try - and the permutations on the mass/invMass. Julio was mentioning that the "impulse injection" was successfully used by someone who was working on a driving simulator that had a similar setup to mine (a simulator driven object with Newton attached objects). Hopefully he can chime in and shed some light and perhaps add a bit more detail.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Porting from 3.xx to 4.00 - need help

Postby misho » Sat Nov 25, 2023 12:06 am

Ok, I gave the Force method a try:
Code: Select all
      // Try velocity/force...
      TBEntity *pParentEnt = NewtonGetUserEntity();
      dMatrix ParentBodyMatrix;
      // get the Body Matrix;
      NewtonBodyGetMatrix(pParentEnt->nBody, &ParentBodyMatrix[0][0]);

      // Get position of where object should be
      // (parent pos + parent ap in global space)
      dVector vParentAPPosition = pParentEnt->GetAttachPoint(0)->location;
      dVector vParentPosition = pParentEnt->GetPosition() + ParentBodyMatrix.RotateVector(vParentAPPosition);

      // Get position of where object is
      // (current object pos + object ap in global space)
      dVector vAPPosition = GetAttachPoint(0)->location;
      dVector vPosition = GetPosition() + bodyMatrix.RotateVector(vAPPosition);

      // Get velocity, acceleration, and then the force
      dVector vTargetVel = (vPosition - vParentPosition).Scale(1.0/dBodyTimeStep);
      dVector vCurVel = GetVelocity();
      dVector vAccel = (vTargetVel - vCurVel).Scale(1.0/dBodyTimeStep);
      dVector vForce = vAccel.Scale(GetCurrentBodyMass());

      if(vLength(vForce))
         GlobalPropulsionForce = vForce;


The result is that the missile is momentarily visible, and then it seems it is pushed away, at which point I get an assert in dgBillateralContraint.cpp, at line 354:

Code: Select all
         dgAssert (dgAbs(relCentr) < dgFloat32 (4.0f));


I set up a few on-screen watches, and it seems there is some kind of an oscillation thing going, as this force goes from very very small value at the beginning, and it balloons very quickly to a huge number, at which point I see the assert. I put a limiter on how much force can be applied and that prevented an assert... but the behavior hasn't changed - the missile is still attached to the aircraft by a "rubber band" :roll: ... Not sure what to do at this point.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 39 guests