A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by SilentAssassin21 » Mon Mar 18, 2013 11:18 am
Can someone tell me what is the contact point and it's direction, okey I got 2 bodies penetrating, and the contact points are taken from where, and since i have 2 bodies, the direction is going in which direction? and can I apply additional force on a body inside the ContactProcess callback?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by JoeJ » Mon Mar 18, 2013 2:07 pm
Maybe the code fragment helps a little bit.
That's how i collect contacts for my feet bodies and at least should answer the 'which direction' question.
You have the idea to fight the penetration problem by raising contact forces?
I blindly assume this can only make it worse, but let us know if you have some success

It seems that newton does not store 2 contact points for 2 bodies (which would be nice to measure penetration).
You could get that info by raytracing along the contact normal... just an idea i've not tried yet.
- Code: Select all
for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(body); joint;
joint = NewtonBodyGetNextContactJoint(body, joint))
{
Body *cbody0 = NewtonJointGetBody0(joint);
Body *cbody1 = NewtonJointGetBody1(joint);
if ((cbody0 == body) || (cbody1 == body))
{
for (void* contact = NewtonContactJointGetFirstContact (joint); contact;
contact = NewtonContactJointGetNextContact (joint, contact))
{
ContactInfo cinfo;
NewtonMaterial* const material = NewtonContactGetMaterial (contact);
NewtonMaterialGetContactPositionAndNormal (material, body, (float*)&cinfo.pos, (float*)&cinfo.norm);
NewtonMaterialGetContactForce(material, body, (float*)&cinfo.force);
if (body == cbody0)
{
cinfo.body = cbody1;
}
else
{
cinfo.body = cbody0; cinfo.norm *= -1.0;
}
...
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by SilentAssassin21 » Tue Mar 19, 2013 3:25 am
Well my final thesis is based on the use of this engine, so i have to get this thing right, I can't move without this getting fixed :S
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by SilentAssassin21 » Tue Mar 19, 2013 6:01 am
it would also be nice to have more documentation on the APIs, and also some more tutorials , you spent all this effort to create this mega engine (I really like it even though the code design is a bit weird and stuff) but you seriously understand the physics and made this work, but spent so little effort on documentation which eliminates everything, I think the comunity and the ammount of people using it would grow larger... anyway I read something about this contact acceleration, I still have problems thinking what the contact normal is when objects penetrate, is it one of the normals of the surfaces that collide? or is it the normal of the normals , or how is it calculated or something , the API doesnt help much here
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by JoeJ » Tue Mar 19, 2013 6:54 am
About contact normals, they are usually depending on those cases:
Point-Face penetration: Face normal (= closest distance)
Edge-Edge penetration: Edge directions cross product (= closest distance too)
Then anti-penetration force is calculated along the normal, and friction forces act perpendicular to normal (called tangential in newton?)
Infos like that are newton independent and you can find them in lots of papers about collision detection.
Julio seems to be out of time at the moment, so i hope my answers can help a little.
To reduce the penetration i can suggest 2 things:
* Use uniform inertias for all ragdoll bodies (like they would be a sphere with the same volume and mass).
This makes the whole thing easier to solve for newton without great visual difference - worth to try out.
* Balance the dude so that the penetration is equal at all sides.
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by SilentAssassin21 » Tue Mar 19, 2013 7:06 am
Hi thanks for your answers, this should help i guess, and about reducing the penetration,
first step is not for me as I am using a custom hinge joint,
and second thing... well actually my main objective is to construct a humanoid robot and teach him how to walk, (I want to make him run) using AI techniques , and also do this in my own simulator (which I am making using NGD), and this robot can be like a real robot, it has a motor at the joint place, and i only tell him how to rotate which joint when and the top level effect would be that he will do something
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by JoeJ » Tue Mar 19, 2013 9:12 am
I use custom joints too, even powered cone twist, which is much more complex and sensitive to simulation errors.
Also i use more joints than you (two bodies for each foot, 3 for spine, clavicle between torso and arms...) and have the same goals as you.
My balancing on 2 feet is stable enough to compensate the penetration problem - i can also move the hip in all directions while balancing.
But i still fail to balance while standing on only one foot... after that is ok walking should not be that hard.
I hope it can be done even if there is no penetration fix possible - a real person would not loose balance because of a little jitter.
The uniform inertia trick helps and is not related to joints, only to body creation / setup.
If your balancing moves the dudes mass center nicely above the average mass center of the feet, equal penetration is result.
Note that using only hinges you can not move the legs sideways and walking is impossible.
You can combine 2 hinges to achieve that or you need a powered cone twist (i derived mine from kinematic joint).
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by Julio Jerez » Tue Mar 19, 2013 2:34 pm
the contact direction is no really relevant for calculation contact force of contact impulse.
This is because what determine the diretion of the contact normal is the contact relative velocity for an impulse
or the contact relative acceleration for a force.
however because contact diretion is important for an application, teh function NewtonMaterialGetContactPositionAndNormal does repost the contact diretion for each body. this is why in late newton 2.xx and newton 3.00 teh funtion take teh body as an argumnet
here is the implementation
- Code: Select all
void NewtonMaterialGetContactPositionAndNormal(const NewtonMaterial* const materialHandle, NewtonBody* const body, dFloat* const positPtr, dFloat* const normalPtr)
{
TRACE_FUNCTION(__FUNCTION__);
dgContactMaterial* const material = (dgContactMaterial*) materialHandle;
positPtr[0] = material->m_point.m_x;
positPtr[1] = material->m_point.m_y;
positPtr[2] = material->m_point.m_z;
normalPtr[0] = material->m_normal.m_x;
normalPtr[1] = material->m_normal.m_y;
normalPtr[2] = material->m_normal.m_z;
if ((dgBody*)body != material->m_body0) {
normalPtr[0] *= dgFloat32 (-1.0f);
normalPtr[1] *= dgFloat32 (-1.0f);
normalPtr[2] *= dgFloat32 (-1.0f);
}
}
As for the question, and can I apply additional force on a body inside the ContactProcess callback?
answer si that is does not make sence to talk abput setting a force at a contact point, this is because the force is the unknoin variable.
You can however ever set the contact normal acceleration, usin this function
- Code: Select all
void NewtonMaterialSetContactNormalAcceleration(const NewtonMaterial* const materialHandle, dFloat accel)
{
TRACE_FUNCTION(__FUNCTION__);
dgContactMaterial* const material = (dgContactMaterial*) materialHandle;
// if (accel > dFloat (0.0f)) {
material->m_normal_Force = accel;
// material->m_overrideNormalAccel = true;
material->m_flags |= dgContactMaterial::m_overrideNormalAccel;
// }
}
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by SilentAssassin21 » Tue Mar 19, 2013 6:42 pm
Hi okey i'm studying about this NewtonMaterialSetContactNormalAcceleration i think I almost got it right, the question is ,
what exactly does the input do to the result contacts ? and how does it relate to the velocity returned by NewtonMaterialGetContactNormalSpeed ?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by SilentAssassin21 » Wed Mar 20, 2013 4:48 am
also in the code snippet from NewtonMaterialSetContactNormalAcceleration the line that says
material->m_normal_Force = accel;
i mean is accel really and acceleration , or should it be force or what? cause this line makes me think i am assigning acceleration to a member that should be force ?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by SilentAssassin21 » Wed Mar 20, 2013 4:55 am
oh and to summarize , i thought the contact point is where the object 1 meats object 2. The robot is trying to stand on a surface that has the thickness 0, and the top side of the surface is located on y coordinate exactly 0! .
So how come i get a contact position at some point like -0.003 and so on... I mean all contacts should be on y = 0 right? or wrong?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by Julio Jerez » Wed Mar 20, 2013 12:47 pm
There are methods for calculation reation forces:
1-Generalized coordinate system
2-Reduced coordinate systems
Newton uses the Reduced codinated system.
This is the method that is taught on any elementary class of Newtonian physics
basically all of the bodies are resolved in a common coordinate system, usually the global space,
at each contact point the velocities and acceleration are known variables, and the system calculate teh forces necessary to satisfy the acceptations and velocities at those contact point.
The acceleration and velocities generated by contacts and joint are defined by the values that the state derivatives equations at the instance of time.
when you wan a contact acceleration of a joint acceleration different than what the derivative of the velocity equation state, then that contact or that joint is named a Motor.
In the case of a joint the acceleration is set by function
void NewtonUserJointSetRowAcceleration(const NewtonJoint* const joint, dFloat acceleration)
from a call back
when the accelration is a collision point and you wnat to override the calculated acceleration then function, you use
void NewtonMaterialSetContactNormalAcceleration(const NewtonMaterial* const materialHandle, dFloat accel)
from a collision callback
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by SilentAssassin21 » Wed Mar 20, 2013 2:46 pm
okey so with some proper reaction i fixed the interpenetration with the following code
- Code: Select all
void CNewtonResource::GenericContactProcess (const NewtonJoint* contact, dFloat timestep, int threadIndex)
{
dgContact* joint=(dgContact*)contact;
dgVector omega = joint->GetBody0()->GetOmega();
dgVector velocity1 = joint->GetBody0()->GetVelocity();
dgVector bodyCenter = joint->GetBody0()->GetPosition();
dgMatrix bodyMatrix = joint->GetBody0()->GetMatrix();
dgMatrix rotQX(dgQuaternion(dgVector(1,0,0,1),omega.m_x*timestep),dgVector(0,0,0,1));
dgMatrix rotQY(dgQuaternion(dgVector(0,0,0,1),omega.m_y*timestep),dgVector(0,0,0,1));
dgMatrix rotQZ(dgQuaternion(dgVector(0,0,1,1),omega.m_z*timestep),dgVector(0,0,0,1));
dgMatrix rotatedBodyMatrix = bodyMatrix * rotQX * rotQY * rotQZ;
for (void* contactJoint = NewtonContactJointGetFirstContact(contact);contactJoint!=NULL;contactJoint = NewtonContactJointGetNextContact(contact,contactJoint))
{
dgVector contactPosition;
dgVector contactNormal;
NewtonMaterial *mat = NewtonContactGetMaterial(contactJoint);
NewtonMaterialGetContactPositionAndNormal(mat,&contactPosition[0],&contactNormal[0]);
dgVector translationVector = contactPosition - bodyCenter;
dgVector contactPositionLater = rotatedBodyMatrix.TransformVector(translationVector) + velocity1.Scale(timestep);
dgVector contactSpeedVector = (contactPositionLater - contactPosition).Scale(1.f/timestep);
if (contactPositionLater.m_y < 0.f)
{
float actualSpeed = surfaceHeight -contactPositionLater.m_y /timestep - contactSpeedVector.m_y;
if (actualSpeed > 0)
NewtonMaterialSetContactNormalAcceleration(mat,actualSpeed);
}
}
}
i took into account also the angular velocity of the body that is on the ground. I calculated the position of the contact point in the next frame by applying omega times timestep and applied the body velocity. The robot now stands stable. I think the internal solver should take into account bodies omega to solve the impulses correctly,
also i would not have to use the matrix to calculate the result, but i can't remember how to calculate angular velocity vector from omega vector

One last is i guess i should switch the parent of the body (joint top parent) to the robots feet, because i guess i would help the solver or something, but then i would need 2 parents , cause i have 2 feet, and that i guess doesnt work :\
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by JoeJ » Wed Mar 20, 2013 3:33 pm
Whooo!
You say it is that simple? I have some doupts, but I'll give it a try
but i can't remember how to calculate angular velocity vector from omega vector
Angular velocity IS omega.
Maybe what you want is to convert that to axis and angle rotation?
(Actually the euler angle method you use should give problems if stuff isn't axis aligned)
Because angular velocity is rotation axis times angle, that's as easy as that:
angle = angvel.length
axis = angvel.unit
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by SilentAssassin21 » Wed Mar 20, 2013 3:44 pm
i mean how to calculate the vector from omega the vector at a specific time at some point from center
(Actually the euler angle method you use should give problems if stuff isn't axis aligned)
Well i don't know if the omega is a vector of euler angles rotX,rotY,rotZ or what, maybe i should do a quaternion?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 1 guest