JoeJ wrote:I found that the result from NewtonUserJointGetRowForce is not what i've expected (i expected it to be the force calculated during previous timestep)....
Is this a bug that can be easily fixed?
yes you are rioght correct, that was correct in earlly versions Newton 2.xx and lower and for the exact solver.
Netwon 2.08 (I beleive) uses a runge kuta order 4 solver/integrator for the iterative solver.
a RK 4 will do four sub steps and it requires calcualtion of the the partical derivative of the joint, for predicting the joint veleocity
at 1/4, 1/2 and 3/4 of teh tiem step.
those wierd numbers that you see in the functions that calculate the joint derivative comes from the calculation these derivative.
for contacts is more dificult because the contacts are discotinieus functions so that partial derivative can not tbe compute analitically,
but it can be stamated numarically by making some asumptions.
Bascially I asume that an island will not generate contacts doring an integration step and teh contact position position changes linearally,
this allowes me to predict the contacts velocity form teh first derivative and teh coeftion of restitution or friction.
what you are seeing is the force that was calculated at the last sub step.
The reason I save that is because that force is used to set the initial guess for the solution of the next integeration step.
The effect of and KR4 is that is smooth the forces acrosss the time step.
when I was doing the destrution demo, I faced a simular problem, I was never getting the correct impulse,
so I added an extra member to the contact joint for saving the largest parcial force of the integration step.
That function is exposed as NewtonMaterialGetContactMaxNormalImpact(material);
I use it in this function
- Code: Select all
void SimulationPostListener(DemoEntityManager* const scene, DemoEntityManager::dListNode* const mynode, dFloat timeStep)
{
// see if the net force on the body comes fr a high impact collision
dFloat breakImpact = 0.0f;
for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_myBody); joint; joint = NewtonBodyGetNextContactJoint(m_myBody, joint)) {
for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) {
dVector contactForce;
NewtonMaterial* const material = NewtonContactGetMaterial (contact);
dFloat impulseImpact = NewtonMaterialGetContactMaxNormalImpact(material);
if (impulseImpact > breakImpact) {
breakImpact = impulseImpact;
}
}
}
The value is an impulse, but it can eassy be converted to the average force by deviding by the time step.
maybe you can use that.