Rigid joints

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Rigid joints

Postby misho » Mon May 02, 2016 2:27 pm

Hi all,

This has been asked before, but I didn't find what I was looking for in the previous discussions.

I'm working on a spaceflight simulator, and I need to assemble stages of a rocket, and then "let them go" one by one. So, I need to join 2 objects together with a RIGID link (absolutely no degrees of freedom, as if whey were welded). Later, I need to destroy the link and let objects separate. What's the best way of doing this?

I tried a CustomHinge joint:

Code: Select all
      dMatrix mChildMatrix = dGetIdentityMatrix();
      mChildMatrix.m_posit = entChild->m_curPosition;
      hinge = new CustomHinge (mChildMatrix, entChild->nBody, entParent->nBody);
      hinge->EnableLimits(true);
      hinge->SetLimits(0.0,0.0);
      printf("Objects connected\n");


However, the joint is unstable. I have a time-compression feature in my sim and when I speed up the sim rate, there is a lot of wobble in a supposedly rigid joint.

I also thought of constructing a compound collision:

Code: Select all
   NewtonCollision* object[2];
   NewtonCollision* compound;

   object[0] = NewtonBodyGetCollision (entParent->nBody);
   object[1] = NewtonBodyGetCollision (entChild->nBody);

   // make a compound collision
   compound = NewtonCreateCompoundCollision (g_world, 0);
   NewtonCompoundCollisionBeginAddRemove (compound);
   NewtonCompoundCollisionAddSubCollision (compound, object[0]);   
   NewtonCompoundCollisionAddSubCollision (compound, object[1]);   
   NewtonCompoundCollisionEndAddRemove (compound);   

   for (int i = 0; i < int (sizeof (object) / sizeof (object[0])); i ++) {
      NewtonDestroyCollision(object[i]);
   }

   NewtonBodySetCollision (entParent->nBody, compound);
   printf("Objects 0 and 1 connected through compound collision\n");


but with this approach, I am not getting objects linked at all. I am not sure if I am doing this correctly... any thoughts?

Misho
Last edited by misho on Mon May 02, 2016 3:04 pm, edited 1 time in total.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Re: Rigid joints

Postby Julio Jerez » Mon May 02, 2016 2:44 pm

try like this
Code: Select all
      
dMatrix mChildMatrix = dGetIdentityMatrix();
      mChildMatrix.m_posit = entChild->m_curPosition;
      hinge = new CustomHinge (mChildMatrix, entChild->nBody, entParent->nBody);
      hinge->EnableLimits(true);
      hinge->SetLimits(0.0,0.0);
      printf("Objects connected\n");

   NewtonSkeletonContainer* const skeleton = NewtonSkeletonContainerCreate(g_world, entParent->nBody, NULL);
   NewtonSkeletonContainerAttachBone(skeleton, entChild->nBody, entParent->nBody);
   NewtonSkeletonContainerFinalize(skeleton);


do not forget to delete the skeleton before deleting the joint.
you can link joint many joints and then wrap them in a skeleton is a parent child relation.
each time to want to delete a joint you need to delete the skeleton and remake it if there are still joints left together.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby misho » Mon May 02, 2016 5:02 pm

Thanks Julio,

I've implemented it like you suggested:

Code: Select all
   static CustomHinge* hinge = NULL;
   static NewtonSkeletonContainer*  skeleton = NULL;
   if(!hinge)
   {
      dMatrix mChildMatrix = dGetIdentityMatrix();
      mChildMatrix.m_posit = entChild->m_curPosition;
      hinge = new CustomHinge (mChildMatrix, entChild->nBody, entParent->nBody);
      hinge->EnableLimits(true);
      hinge->SetLimits(0.0,0.0);
      skeleton = NewtonSkeletonContainerCreate(g_world, entParent->nBody, NULL);
      NewtonSkeletonContainerAttachBone(skeleton, entChild->nBody, entParent->nBody);
      NewtonSkeletonContainerFinalize(skeleton);
      printf("Objects connected\n");
   }
   else
   {
      NewtonSkeletonContainerDelete(skeleton);
      skeleton = NULL;
      delete hinge;
      hinge = NULL;
      printf("Objects 0 and 1 disonnected\n");
   }


However, I am still getting wild oscillations (my child object oscillates in relation to parent object) when using time compression (see my other post). Could it be that this is happening because of the large timestep values? I can see small oscillations even at 2x compression, and I get 60FPS, so the timestep value is around 0.033s. When I bring the sim down to "normal" time, I notice that the linked bodies have started to rotate.
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Re: Rigid joints

Postby Julio Jerez » Mon May 02, 2016 5:27 pm

you need to run the simulation at least 60 fps, I recommend 120.

the time dilation you need to do with frame interpolation.

basically you play the current frame and the next frame into the future.
the any value can get extracted for these tow.

for slow motion it mean you interplayed many frame, for a large time step you advance the simulation time until the current frame and the current frame and on into the future.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby misho » Mon May 02, 2016 5:36 pm

Julio Jerez wrote:you need to run the simulation at least 60 fps, I recommend 120.


By simulation, you mean Newton, right?

So basically, I need to decouple my Newton simulation from my visual simulation, let it run at high FPS (let's say, 120), and poll data every time my sim cycles (60 or less FPS), correct?

Is the joint instability the cause of the oscillations I am observing with large timesteps?

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

Re: Rigid joints

Postby Julio Jerez » Mon May 02, 2016 5:39 pm

yes.
joints are not linear they need a high frame rate to simulate properly, plus there stiffness factor in the code that is calibrated to work a 60 hz frequency is a, so 30 is too slow.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby JoeJ » Tue May 03, 2016 3:54 am

You should try the compound again, it's faster, more stable and would allow taking large timesteps.
I can't spot a bug in your code, here is what works for me:

Code: Select all
      Shape *cShapes[3];
      sMat4 cTrans[3];

      cTrans[0].Identity();
      *cTrans[0].Translation() = sVec3 (-2,0,0);
      cTrans[0].Reset4thColumn();
      cShapes[0] = CreateSphereShape (2.5, &cTrans[0]); // == NewtonCreateSphere (world, radius, some id, &cTrans[0]);
      
      cTrans[1].Identity();
      *cTrans[1].Translation() = sVec3 (2,0,0);
      cTrans[1].Reset4thColumn();
      cShapes[1] = CreateSphereShape (3.3, &cTrans[1]);
      
      cTrans[2].Identity();
      *cTrans[2].Translation() = sVec3 (0,2,0);
      cTrans[2].Reset4thColumn();
      cShapes[2] = CreateSphereShape (2.3, &cTrans[2]);
      
      NewtonCollision *compoundShape = NewtonCreateCompoundCollision (world, 1002);
      NewtonCompoundCollisionBeginAddRemove(compoundShape);
      NewtonCompoundCollisionAddSubCollision(compoundShape, cShapes[0]);
      ReleaseShape (cShapes[0]);
      NewtonCompoundCollisionAddSubCollision(compoundShape, cShapes[1]);
      ReleaseShape (cShapes[1]);
      NewtonCompoundCollisionAddSubCollision(compoundShape, cShapes[2]);
      ReleaseShape (cShapes[2]);
      NewtonCompoundCollisionEndAddRemove(compoundShape);
      
      trans.Identity();
      trans.Reset4thColumn();
      *trans.Translation() = sVec3 (-10,60,-20);
      CreateRigidBody (100, trans, compoundShape);

      ReleaseShape (compoundShape);


'Shape' is what's called 'Collision' in Newton.

Maybe the collisions you get from your entities are already linked to a body and thus it does not work?
If that's the reason, you would initially need to create a single body from multiple collisions, and when detaching, delete the single body and create 2 new bodies?
Don't know, but somehow it should work.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Rigid joints

Postby misho » Tue May 03, 2016 12:06 pm

Hi JoeJ,

JoeJ wrote:Maybe the collisions you get from your entities are already linked to a body and thus it does not work?


That's correct, I already have bodies assigned to collisions. I basically took their collisions and added them to a compound collision, and then assigned that compound collision to a parent body. Perhaps that's why it isn't working.

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

Re: Rigid joints

Postby Julio Jerez » Tue May 03, 2016 12:13 pm

I too agree with Joe, using compound is a better way to do it,

you nee to make a data structure that have information fo make each body, by only have one body and one compound collision.

the when a body part separates, you find that body part for the compound collision. and the body wit the information for new body just make a new body with that body part and remove the sub shape form the compound.
you can store user data point on the sub collision shape, you cause that to associate the information need it to create that detaching section.

this is far more robust that using a fix joint.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby misho » Tue May 03, 2016 2:13 pm

Ok... I have a class Entity which wraps (much like Newton tutorials), among other things, a pointer to a Newton body and an ID which is an ID for my simulator object... it is my connection to the visual system (simulator).

So if I am following you, if I want to connect 2 entities, entParent and entChild, I need to:

  1. create compound collision from the parent and child entities (using NewtonBodyGetCollision (entParent->nBody), NewtonBodyGetCollision (entChild->nBody))
  2. create new entity eCompoundEntity
  3. create rigid body for this entity from compound collision
  4. assign entParent simulator ID to eCompoundEntity
  5. inherit parent parameters (velocity, damping...) for new eCompoundEntity
  6. inherit transform matrix from entParent
  7. delete entParent and entChild

However - I don't see a way how to assign entChild ID and tell simulator where my child body is. All I have is its collision embeded in the compound collision, but I've lost child entity and its body. I would prefer to keep the parent and child entities (and bodies), but have them connected through shared collision. Is that possible?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Re: Rigid joints

Postby Julio Jerez » Tue May 03, 2016 2:28 pm

no this is wrong

Code: Select all
1.create compound collision from the parent and child entities (using NewtonBodyGetCollision (entParent->nBody), NewtonBodyGetCollision (entChild->nBody))


a collision have not have two bodies. The idea is that the rocket is one body with one compound collision.
then parts of the compound collision store information to make a Newton Body with the child collsion shape that is detached form the compound when the section is going to be detach.

basically you modify the compound as the rocket loses part. and those part are new Newton Bodies that are spawn at that moment.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby misho » Tue May 03, 2016 3:02 pm

Julio Jerez wrote:a collision have not have two bodies. The idea is that the rocket is one body with one compound collision.
then parts of the compound collision store information to make a Newton Body with the child collsion shape that is detached form the compound when the section is going to be detach.

basically you modify the compound as the rocket loses part. and those part are new Newton Bodies that are spawn at that moment.


Okay - this is true when a compound is losing its components, as in rocket staging. However, I also need to assemble compounds, as when a space capsule is docking at space station, or I assemble a space station from various parts.

I guess what I am asking is, if my visual components are separate parts, how to tell simulator where they are in the compound collision? By getting sub-collision matrix? Looking at the API, I was looking for something like

NewtonCompoundCollisionGetSubCollisionMatrix()

Is there a way to get a collision matrix from collision?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Re: Rigid joints

Postby misho » Wed May 04, 2016 7:57 pm

misho wrote:Is there a way to get a collision matrix from collision?


Any thoughts on this? My objects are structured just like in "200" series of Newton tutorials. Each visual simulator object is represented by Entity class. For each Entity class I create a Newton body, and Newton body's user data is Entityclass.

So, when creating compound collisions, I need to destroy 2 bodies and create a new body which contains 2 collisions from the 2 joined bodies. However, this breaks the body-entity relationship. My simulator relies on this relationship to place and orient actual visual elements... so, how do I structure my compound collision so that my entities are still intact (and have distinct positions and orientations) but are grouped in a common Newton body?

For example: Let's say I have 3 separate bodies floating in space, A, B, and C. Each have the Entity class associated with them. I read a list of all the entities and set my visual object positions and rotations.

Now, I decide to join objects B and C. Now I will have 2 bodies floating in space, but still a list of 3 entities. B and C entities position and rotations will be locked to each other, but they are still 2 distinct visual objects.

This would mean that Newton body made from compound collisions would need to have a way to identify the positions and rotations of all its components, but I don't see a way of doing this. Any thoughts on what would be the best way to accomplish this?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Re: Rigid joints

Postby Julio Jerez » Wed May 04, 2016 8:44 pm

Code: Select all
      NewtonCompoundCollisionBeginAddRemove(compound);   
      void* handle1 = NewtonCompoundCollisionGetNodeByIndex (compound, pointsCount / 3);
      NewtonCollision* const shape1 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle1);
      NewtonCollision* const newStageShape = NewtonCollisionCreateInstance (shape1);

                NewtonCompoundCollisionRemoveSubCollision (NewtonCollision* const compoundCollision, handle1);   
            NewtonCompoundCollisionEndAddRemove(compound);   


// now here you have newStageShape that you can use to build your new entity.
you can use any of the interface function to get info from the shape, like
Code: Select all
void NewtonCollisionSetMatrix (const NewtonCollision* const collision, const dFloat* const matrix);
void NewtonCollisionGetMatrix (const NewtonCollision* const collision, dFloat* const matrix);
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Rigid joints

Postby misho » Wed May 04, 2016 9:47 pm

Ok, thanks, NewtonCollisionGetMatrix() is exactly what I was looking for, not sure why I didn't see it :roll: .

However, I am not sure why I need to build a new entity. Entity represents a single visual simulator unit (a rocket stage, a capsule, orbiter, space station module...), and it has its own collision, plus physical properties (weight). Body, on the other hand, is a collection of one or more entities (rocket stack, space station...), and it can be built and destroyed as needed.

I was hoping to keep the entities, but build and destroy new bodies. I think I need to de-couple my entity from NewtonBody (because right now NewtonBody can have only one entity) and couple it with individual collisions within the body (using NewtonCollisionSetUserData())

Does that make sense?
Misho Katulic
CTO, FSX SpacePort
TerraBuilder
www.terrabuilder.com
misho
 
Posts: 675
Joined: Tue May 04, 2010 10:13 am

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron