Timing and FPS question

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Timing and FPS question

Postby misho » Tue Jun 19, 2018 3:31 pm

This probably has nothing to do with Newton (except that I am using dGetTimeInMicroseconds() to get the current time), but with the way I have this set up. I have a rocket object, and it has several rocket engines that work in unison to produce thrust. I calculate thrust generated from the given engine parameters (max thrust, thrust percentage, ISP at sea level, ISP in vacuum, etc). I call these calculations each visual (NOT physics) loop. They are basically used to measure time passed, and calculate how much fuel was expended in that time, and by how much my rocket is "lighter". Here is the general function that I go through every visual frame:

Code: Select all
void   ProcessAllRocketEngineSequences(void)
{
   m_currentTime = dGetTimeInMicroseconds();
   for (unsigned int i = 0; i < m_RocketEngineGroupList.size(); i++)
      ProcessRocketEngineSequence(m_RocketEngineGroupList[i].strLabel);
   m_previousTime = m_currentTime;
}


Everything works well when my sim runs, but when the visual frame rate drops (for whatever reason), I notice that the rocket engine performance drastically changes - the fuel consumption jumps and thrust drops. Since the calcs are based on the time slice, and I am using the m_currentTime and m_previousTime to determine the time elapsed, why would the FPS drop matter? It would just mean that the time slice is larger, and the calcs adjust accordingly, right?

Relying on the demoSandbox code, the following function

Code: Select all
void DemoEntityManager::UpdatePhysics(dFloat timestep)


does not use timestep parameter at all, but relies on the internal code to determine the timestep.

[EDIT] I just checked the parameters, and the thrust and fuel consumption do not change, but the rocket slows down, and it basically takes twice the time to travel the given distance. So obviously, visual FPS is somehow tied into Physics engine - but how? I obviously left out something from my code... What am I missing?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby misho » Tue Jun 19, 2018 6:38 pm

Ok, I figured it out :mrgreen:

Since the rocket expends the fuel, I have to continuously adjust for the mass of the rocket. However, I was making calls to

Code: Select all
NewtonBodySetMassMatrix(nBody, fCurrentMass, inertia.m_x, inertia.m_y, inertia.m_z);


on every physics frame (not visual frame), and that was tasking the physics engine. I adjusted the code to make changes to the body mass on every visual frame, and it seems to be working properly for the moment :wink:
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby misho » Wed Jul 04, 2018 12:45 pm

Ok - I definitely have a valid problem here. In fact, I NEED to change mass on every physics frame, and this method:
Code: Select all
NewtonBodySetMassMatrix(nBody, fCurrentMass, inertia.m_x, inertia.m_y, inertia.m_z);

is definitely a bottleneck.

In my previous post I indicated that I moved this method from a physics FPS level to a visual frame FPS level. This approach is presenting a problem when the visual FPS varies (drops) for various reasons (scene complexity, etc). In that case, the rocket mass loss is being updated less frequently, resulting in a severe rocket performance degradation that is dependant on visual FPS. That is unnaceptable for a high-fidelity spaceflight simulation.

I need a better, faster method for changing body's mass, something that will perform without any performance hit on a physics update level. Any suggestions? Can anything be added to the API that will perform better than the above method? Please advise.

Otherwise, things are going pretty good. check out my YouTube channel and the launch video I just made: https://www.youtube.com/watch?v=VOrClkqCPSg
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby Dave Gravel » Wed Jul 04, 2018 7:08 pm

Nice video, Do you use UserData for your objects ?
Maybe you can get the body UserData object from the NewtonApplyForceAndTorque callback,
And adjust the mass for any objects that need to become updated with a tag info or something like this.

I think you can use a empty custom joint too, and create a listener manager to control a object list from the joint callbacks and change the objects in runtime.
I'm not 100% sure it depend from what you need, but I have already use similar methods with good results.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 800
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Timing and FPS question

Postby misho » Wed Jul 04, 2018 7:19 pm

Dave Gravel wrote:Nice video, Do you use UserData for your objects ?
Maybe you can get the body UserData object from the NewtonApplyForceAndTorque callback,
And adjust the mass for any objects that need to become updated with a tag info or something like this.


Thanks - Yes, I use UserData, in an "entity" form, much like the tutorials. I tried applying the mass inside NewtonApplyForceAndTorque callback (which is at physics cycle, let's say 500 fps) and it does work, but that function seems to be very "expensive" - it is very computationally intensive and it slows things down drastically. So, I had to move it to visual refresh level (60 FPS) which made it way better, but now the physics engine is working with the wrong mass 7 out of 8 physics frames, and it is throwing the simulation off.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby Dave Gravel » Wed Jul 04, 2018 7:29 pm

Maybe you can just simulate the mass with a force apply to the body without use the NewtonBodySetMassMatrix. I use this with vehicle to change the main chassis mass when the engine accelerate or decelerate.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 800
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Timing and FPS question

Postby misho » Wed Jul 04, 2018 7:35 pm

Dave Gravel wrote:Maybe you can just simulate the mass with a force apply to the body without use the NewtonBodySetMassMatrix. I use this with vehicle to change the main chassis mass when the engine accelerate or decelerate.


Cheat the physics engine?? LOL I don't think that would work properly... There has to be a better way to change mass ... the present method requires inertia matrix, and that is not changing, so the calculations there can be avoided... I'm guessing here.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby Dave Gravel » Wed Jul 04, 2018 7:49 pm

Yes it can look like cheat.
With wheeled vehicle it's a bit different, I change the chassis force and torque for my need.

I don't think it is cheating if you do it from a custom joint and if you use real life value to get what you need.
If you think about it, Player controller or Vehicle raycast is all cheating maths ?
If yes some method give good result with real value.

Sorry to don't have better solutions, and about my english.
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 800
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Timing and FPS question

Postby Julio Jerez » Wed Jul 04, 2018 10:09 pm

misho wrote:Since the rocket expends the fuel, I have to continuously adjust for the mass of the rocket. However, I was making calls to
Code: Select all
NewtonBodySetMassMatrix(nBody, fCurrentMass, inertia.m_x, inertia.m_y, inertia.m_z);



I am very confused, takes of the order of few nanosecond of time to execute, here is the body
Code: Select all
void dgBody::SetMassMatrix(dgFloat32 mass, const dgMatrix& inertia)
{
   dgFloat32 Ixx = inertia[0][0];
   dgFloat32 Iyy = inertia[1][1];
   dgFloat32 Izz = inertia[2][2];
   mass = dgAbs (mass);
   if (m_collision->IsType(dgCollision::dgCollisionMesh_RTTI) || m_collision->IsType(dgCollision::dgCollisionScene_RTTI)) {
      mass = DG_INFINITE_MASS * 2.0f;
   }

   if (mass < DG_MINIMUM_MASS) {
      mass = DG_INFINITE_MASS * 2.0f;
   }

   //dgAssert (m_masterNode);
   m_world->GetBroadPhase()->CheckStaticDynamic(this, mass);

   if (mass >= DG_INFINITE_MASS) {
      m_mass.m_x = DG_INFINITE_MASS;
      m_mass.m_y = DG_INFINITE_MASS;
      m_mass.m_z = DG_INFINITE_MASS;
      m_mass.m_w = DG_INFINITE_MASS;
      m_invMass.m_x = dgFloat32 (0.0f);
      m_invMass.m_y = dgFloat32 (0.0f);
      m_invMass.m_z = dgFloat32 (0.0f);
      m_invMass.m_w = dgFloat32 (0.0f);

      if (m_masterNode) {
         dgBodyMasterList& masterList (*m_world);
         if (masterList.GetFirst() != m_masterNode) {
            masterList.InsertAfter (masterList.GetFirst(), m_masterNode);
         }
      }

   } else {
      Ixx = dgAbs (Ixx);
      Iyy = dgAbs (Iyy);
      Izz = dgAbs (Izz);

      dgFloat32 Ixx1 = dgClamp (Ixx, dgFloat32 (0.001f) * mass, dgFloat32 (1000.0f) * mass);
      dgFloat32 Iyy1 = dgClamp (Iyy, dgFloat32 (0.001f) * mass, dgFloat32 (1000.0f) * mass);
      dgFloat32 Izz1 = dgClamp (Izz, dgFloat32 (0.001f) * mass, dgFloat32 (1000.0f) * mass);

      dgAssert (Ixx > dgFloat32 (0.0f));
      dgAssert (Iyy > dgFloat32 (0.0f));
      dgAssert (Izz > dgFloat32 (0.0f));

      m_mass.m_x = Ixx1;
      m_mass.m_y = Iyy1;
      m_mass.m_z = Izz1;
      m_mass.m_w = mass;

      m_invMass.m_x = dgFloat32 (1.0f) / Ixx1;
      m_invMass.m_y = dgFloat32 (1.0f) / Iyy1;
      m_invMass.m_z = dgFloat32 (1.0f) / Izz1;
      m_invMass.m_w = dgFloat32 (1.0f) / mass;

      if (m_masterNode) {
         dgBodyMasterList& masterList (*m_world);
         masterList.RotateToEnd (m_masterNode);
      }
   }


#ifdef _DEBUG
   dgBodyMasterList& me = *m_world;
   for (dgBodyMasterList::dgListNode* refNode = me.GetFirst(); refNode; refNode = refNode->GetNext()) {
      dgBody* const body0 = refNode->GetInfo().GetBody();
      dgVector invMass (body0->GetInvMass());
      if (invMass.m_w != 0.0f) {
         for (; refNode; refNode = refNode->GetNext()) {
            dgBody* const body1 = refNode->GetInfo().GetBody();
            dgVector invMass1 (body1->GetInvMass());
            dgAssert (invMass1.m_w != 0.0f);
         }
         break;
      }
   }
#endif
   UpdateLumpedMatrix();
}


I assume you are calling it few time per frame, but you should be able to call it thousands of time per frames before it makes any impact of on the total physics time.
it most be some different.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Timing and FPS question

Postby JoeJ » Thu Jul 05, 2018 6:40 am

misho wrote:the present method requires inertia matrix, and that is not changing


If mass decreases, moment of inertia must decrease as well. Or is this a special case where the fuel is distributed evenly around rotation axis, and it does not have to rotate with the body, so does not effect turning resistance? However, if rotation axis is off, or you consider the fuel to be part of a rigid body, you'd need to decrease inertia too, i guess.

If it turns out mass changes are indeed expensive (does the function iterate over joints to change cached forces?), the you could do it time sliced: At each physics step do it for a maximum of n bodies while keeping the update rate per body uniform. I guess this would be accurate enough.
User avatar
JoeJ
 
Posts: 1453
Joined: Tue Dec 21, 2010 6:18 pm

Re: Timing and FPS question

Postby Julio Jerez » Thu Jul 05, 2018 9:09 am

misho are you compiling the sdk in debug?

the only reason the function would be slower that it need to be is if you are calling it many time per frame and you have many rigid bodies in the scene.

That is because this debug code
Code: Select all
#ifdef _DEBUG
   dgBodyMasterList& me = *m_world;
   for (dgBodyMasterList::dgListNode* refNode = me.GetFirst(); refNode; refNode = refNode->GetNext()) {
      dgBody* const body0 = refNode->GetInfo().GetBody();
      dgVector invMass (body0->GetInvMass());
      if (invMass.m_w != 0.0f) {
         for (; refNode; refNode = refNode->GetNext()) {
            dgBody* const body1 = refNode->GetInfo().GetBody();
            dgVector invMass1 (body1->GetInvMass());
            dgAssert (invMass1.m_w != 0.0f);
         }
         break;
      }
   }
#endif


that because of the fiorst like
#ifdef _DEBUG

you can change to #if 0

and the code will no execute, but that should compile out is release.
oeth thet that I do not see any rerason for the to be slow at all.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Timing and FPS question

Postby misho » Thu Jul 05, 2018 10:58 am

JoeJ wrote:If mass decreases, moment of inertia must decrease as well. Or is this a special case where the fuel is distributed evenly around rotation axis, and it does not have to rotate with the body, so does not effect turning resistance? However, if rotation axis is off, or you consider the fuel to be part of a rigid body, you'd need to decrease inertia too, i guess.


Indeed - in the video, the whole launch "stack" has about 13 components, but at launch, only 3 are burning fuel: Core (fat orange rocket) and 2 solid rocket boosters. And yes, those bodies are centered around rotation axis symmetrically and the mass change should not affect turning resistance. I consider the fuel to be distributed over the whole body (have the same density as the body) and I change the mass of it as the fuel is expended. I don't understand your comment about "fuel to be part of a rigid body" - it is part of a rigid body, but also it is evenly and symmetrically distributed so I don't see a need for inertia matrix recalculation.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby misho » Thu Jul 05, 2018 11:05 am

Julio Jerez wrote:misho are you compiling the sdk in debug?


Thanks Julio. No, I use "release_double" versions, as in:

Code: Select all
$(NEWTON_HOME)/sdk/projects/visualStudio_2015_static_mt/Win32/dgCore/release_double


Is it possibly because it is a "_double" version?

In fact, I link to release_double SDK with both release and debug versions of my code - I usually don't have any need to go into SDK, stuff I do is fairly simple compared to what I see some people are doing with Newton :mrgreen:
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Re: Timing and FPS question

Postby Julio Jerez » Thu Jul 05, 2018 11:19 am

Um, you may be linking to a debug library, newton in release is over ten time faster because of all those expensive debug code that is all over the place, can you set a break point a step through it?
That function should be not more than a dozen line of code in release.

Anyway I am write a simple frame capture profiler so that we can determine where this inconsistencies com from.
I am almost done with the instrumented part, it will be few day for the client.
I will use Windows form for simplicity, so it will be a windows only tool.
Does your project supports windows?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Timing and FPS question

Postby misho » Thu Jul 05, 2018 11:21 am

Julio Jerez wrote:I am very confused, takes of the order of few nanosecond of time to execute

I assume you are calling it few time per frame, but you should be able to call it thousands of time per frames before it makes any impact of on the total physics time.
it most be some different.


Hi Julio and JoeJ,

Here is the method I use to calculate the the new mass. Note, inertia matrix is calculated and saved at the time of body creation, and I don't re-calculate it again, I just pass the new mass. I am not sure what NewtonBodySetMassMatrix does with inertia matrix:

Code: Select all
void   TBEntity::AdjustEntityMass(void)
{
   // set new entity mass:
   // mass depeletion due to propellant expenditure
   double fCurrentMass = GetPropellantMass() + GetEmptyMass();

   // set the body mass matrix
   if (fCurrentMass)
   {
      dFloat massScale = fCurrentMass / GetGrossMass();
      inertia.Scale(massScale);
      NewtonBodySetMassMatrix(nBody, fCurrentMass, inertia.m_x, inertia.m_y, inertia.m_z);
   }
}


I tried using this in ApplyForceAndTorqueCallback, but it had a significant performance impact. I had to move it to a once-per-visual-frame level loop...
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 673
Joined: Tue May 04, 2010 10:13 am

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 13 guests