How to make my own contact point.

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

How to make my own contact point.

Postby JoeJ » Fri Nov 22, 2013 5:30 am

Now because the friction issue is solved, it seems i can predict the contact forces with good accuracy on my double inverted pendulum model.
I verify by averaging newton contact positions by force length and summing up forces and display that vector.
My own predicted contact force at center of pressure looks similar at motion and is identical at rest.

Now i have the idea to replace newton collision detection partially with my own result.
My output is very smooth, requires only one contact per foot and maybe this can approximate a non rigid foot and the toes work very well.
Also it should limit jitter and the penetration problem... worth to try out.

I want to keep newton coll. det. enabled for unpredictable cases, to make this work i want to make the feet 'hover' 1 cm over ground.
Meaning my custom contact point should be placed 1 cm below the foot and i'll leave calculation of the force itself to newton.
Thus if things become unpredictable (loosing balance, obstacles...) newton will create additional contacts at foot edges and anything keeps working as usual.

So i simply need to do a 1 cm raycast from center of pressure and if there's a hit, inject a contact... how can i do that?
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: How to make my own contact point.

Postby sova » Fri Nov 22, 2013 8:15 am

I use hack to generate my own contact points...

file: dgCollisionConvex.cpp
Code: Select all
dgInt32 dgCollisionConvex::CalculateConvexToConvexContact (dgCollisionParamProxy& proxy) const
{
// hack
   if(IsType(dgCollision::dgCollisionBox_RTTI) // I use box as ground
      && proxy.m_floatingCollision->IsType(dgCollision::dgCollisionConvexHull_RTTI) // ... and convexes as objects
      && proxy.m_referenceBody->GetUserData() != NULL // my box data here
      && proxy.m_floatingBody->GetUserData() != NULL) // my convex data here
   {   // fill contactOut array
      // and return number of contacts
      // ...
   }
}


also I fix file dgNarrowPhaseCollision.cpp function
CalculateConvexToConvexContacts (dgCollisionParamProxy& proxy) const
Code: Select all
// after line
   bool flipShape = dgCollisionConvex::m_priorityOrder.m_swapPriority[id1][id2];

   // sova: box always as referenceBody
   if(id1 == m_boxCollision) flipShape = false;
   if(id2 == m_boxCollision) flipShape = true;


I hope this will help.
sova
 
Posts: 23
Joined: Mon Mar 05, 2012 8:58 am

Re: How to make my own contact point.

Postby JoeJ » Fri Nov 22, 2013 10:15 am

Thanks, that should do it!
I've tried it but i only get asserts :(
Because i handle normal flipping here it should not be necessary to change dgNarrowPhaseCollision.cpp for me?
The scene contains only 2 boxes, groundbox topside is at y=0, and the dynamic foot box is 0.4x0.4x0.4 units and starts nicely resting on the ground.
I try to generate a contact below its com. Any idea what i'm doing wrong?



Code: Select all
dgInt32 dgCollisionConvex::CalculateConvexToConvexContact (dgCollisionParamProxy& proxy) const
{
   dgInt32 count = 0;
   // hack
   if(IsType(dgCollision::dgCollisionBox_RTTI) // I use box as ground
      && proxy.m_floatingCollision->IsType(dgCollision::dgCollisionBox_RTTI)) // ... and box as object too
   {   // fill contactOut array
      // and return number of contacts
      // ...

      dgBody *body0 = proxy.m_referenceBody;
      dgBody *body1 = proxy.m_floatingBody;

      dgBody *foot = body0;
      if (body0->GetPosition()[1]<0) foot = body1;
      dgVector footCom = foot->GetPosition();
      float penetration = 0.2 - footCom[1];

      if (penetration > 0)
      {
         dgContactPoint* const contactOut = proxy.m_contacts;
      
         contactOut[count].m_point = footCom;
         contactOut[count].m_point[1] = 0;

         contactOut[count].m_normal = dgVector (0,1,0,0);
         if (foot == body1) contactOut[count].m_normal.Scale3(-1.0); // also tried opposite direction
         contactOut[count].m_penetration = penetration; // also tried -penetration
         count++;
         return 1; // gives assert somewhere; if i remove this line my contact may get optimized away resulting in standard 4 contacts at corners
      }
   }



User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: How to make my own contact point.

Postby sova » Fri Nov 22, 2013 11:03 am

I have no idea)

I write simplest example code that returns contact point.
One box fall to another (static).
It works ok. (but box slightly jumping because penetration is constant here)

Code: Select all
   if(proxy.m_floatingBody->GetPosition().m_y > 0) return 0;

   dgContactPoint* const contactOut = proxy.m_contacts;
      
   contactOut[0].m_point = dgVector(0.f, 0.f, 0.f, 0.f);
   contactOut[0].m_normal = dgVector(0.f, -1.f, 0.f, 0.f);
   contactOut[0].m_penetration = 0.1f;
   return 1;
sova
 
Posts: 23
Joined: Mon Mar 05, 2012 8:58 am

Re: How to make my own contact point.

Postby JoeJ » Fri Nov 22, 2013 11:19 am

Yes this works, now i can figure out...
Thanks! :D
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: How to make my own contact point.

Postby Julio Jerez » Fri Nov 22, 2013 12:21 pm

sova wrote:I use hack to generate my own contact points...

file: dgCollisionConvex.cpp
Code: Select all
dgInt32 dgCollisionConvex::CalculateConvexToConvexContact (dgCollisionParamProxy& proxy) const
{
// hack
   if(IsType(dgCollision::dgCollisionBox_RTTI) // I use box as ground
      && proxy.m_floatingCollision->IsType(dgCollision::dgCollisionConvexHull_RTTI) // ... and convexes as objects
      && proxy.m_referenceBody->GetUserData() != NULL // my box data here
      && proxy.m_floatingBody->GetUserData() != NULL) // my convex data here
   {   // fill contactOut array
      // and return number of contacts
      // ...
   }
}

I hope this will help.

wow, clever idea, using the use define data, to customized the behavior of the collision system. :)

I had a plan to add a custom contact callback. similar to what custom joint are.
my idea was to use that for sticky a contacts demo.
basically these are contact that have a not zero normal friction when the try to separate.
by the I thought that I can do that by adding a option to the material system, so I did no do it.

A contact and a joint are the same thing, contact are managed by the narrow and broad phase collision system, for creation, destruction, and populate the rows and column of the contact constraints.
each contact has 3 DOF, so you can make a custom contact joint of up to two contacts, more if you do not use friction rows.

all you need to do is get the code that convert the calculation of the normal at the contact point, to generate the contact row of your contact joint. the code is in function:
void dgContact::JacobianContactDerivative (dgContraintDescritor& params, const dgContactMaterial& contact, dgInt32 normalIndex, dgInt32& frictionIndex)

file ../newton-dynamics\coreLibrary_300\source\physics\dgContact.cpp

basically that function is the equivalent of SubmitRow for a custom joint.
you will nee to made the nessesary modifications. and you nee to manage when the joint should be destroyed.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: How to make my own contact point.

Postby JoeJ » Fri Nov 22, 2013 2:49 pm

It works - the 3 bodies model keeps balanced when using only one contact, even if i animate it.
Looks magic and nicely soft :)

I see one problem with Sovas method. Because for me the contact point is outside the body,
Broadphase checks could prevent CalculateConvexToConvexContact from being called?
So i'll look at the joint method...
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests

cron