A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by Julio Jerez » Tue Jan 08, 2013 2:31 pm
I have not done yet, I will do it tonight but I start to see what might be happening.
You are using this friction value
CustomKinematicController *kj = new CustomKinematicController(sph, dVector (0,1,0));
kj->SetMaxLinearFriction (90000); // the bigger, the more penetration
I dop no see what mass value you are using, but if you mass value is low, let us say 1.0, this mean that this joint is capable of generating and acceleration of 90000 unit/sec2
What those mean is that at that level, what the join is in contact with the ground the acceleration on the joint is or the order of 900000, but the next acceleration to cancel that will also be or the order of 90000, let us say
90000 += some smaller acceleration like 1.0e-3
This means that the mantissa of a float does not have enough dynamics range to represent that.
I am almost 99% sure that this is the problem. A way to test this is to make the double precision version and see if the bug goes away. If it does I can take correction to deal with it.
Anyway I will recreate the demo, first and see if this is in fact the problem.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JoeJ » Tue Jan 08, 2013 2:36 pm
Note the second template, which is nice use case situation and uses friction of 1000.
The masses are 1.0, First param in CreateBody func.
I'll test double precission...
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by JoeJ » Tue Jan 08, 2013 2:53 pm
What do i need to do to use double prec.?
I added __USE_DOUBLE_PRECISION__ to precompiler definitions but i get many compiler errors, like:
error C2535: 'dBigVector::dBigVector(const TemplateVector<T> &)' : member function already defined or declared c:\dev\newton-dynamics-read-only\packages\dmath\dvector.h
error C2664: 'dgSimd::StoreScalar' : cannot convert parameter 1 from 'dgFloat32 *' to 'float *const ' c:\dev\newton-dynamics-read-only\corelibrary_300\source\physics\dgworlddynamicssimplesolversimd.cpp
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by Julio Jerez » Tue Jan 08, 2013 5:11 pm
I am not sure if double precision will work at this time. It may have some compiler issues
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JoeJ » Mon Jan 28, 2013 7:26 am
Any news on that issue?
I tried limiting joint friction / different world scale but no luck...
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by Julio Jerez » Mon Jan 28, 2013 9:25 am
I am fixng an inteface problems first.
whe I change the collsion form refrence cound base to be Instance base. the integafce to teh iuse is broken in some places. and I am fix this first.
after that I will cover this issue.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by SilentAssassin21 » Sat Feb 16, 2013 6:52 am
Hi, I was away for job reasons, is this problem fixed or should i post you the sample code? or you just need my .exe application with dynamic linked .dll library of newton which you will debug?
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by SilentAssassin21 » Mon Mar 18, 2013 8:28 am
Hi so I built the newton DLL with the double precision, and the damn thing is still penetrating inside the floor, here is my entire code for the custom hinge joint,
the body is made of 22 hinge joints.
- Code: Select all
#include "CustomHingeJoint.h"
#include <OgreVector3.h>
#include <OgreMatrix4.h>
#include <OgreQuaternion.h>
namespace Resources{ namespace Newton {
CCustomHingeJoint::CCustomHingeJoint(NewtonBody *child,NewtonBody *parent):NewtonCustomJoint(6,child,parent),
m_child(child),m_parent(parent)
{
m_childPart=(Robot::CBodyPart *)NewtonBodyGetUserData(child);
m_parentPart=(Robot::CBodyPart *)NewtonBodyGetUserData(parent);
double childMatrixF[16],parentMatrixF[16];
NewtonBodyGetMatrix(child,childMatrixF);
NewtonBodyGetMatrix(parent,parentMatrixF);
Ogre::Matrix4 childMatrix=GetMatrixFromFloat(childMatrixF);
Ogre::Matrix4 parentMatrix=GetMatrixFromFloat(parentMatrixF);
Ogre::Matrix4 pivotGlobalPosition=m_parentPart->MutableGlobalTransformation()*m_childPart->GetModel()->GetAnchorMatrix();
m_localChildToPivotMatrix=(childMatrix.inverse())*pivotGlobalPosition;
m_localParentoToPivotMatrix=(parentMatrix.inverse())*pivotGlobalPosition;
}
CCustomHingeJoint::~CCustomHingeJoint(void)
{
}
Ogre::Matrix4 CCustomHingeJoint::GetMatrixFromFloat(double *v)
{
return Ogre::Matrix4(
v[0],v[4],v[8],v[12],
v[1],v[5],v[9],v[13],
v[2],v[6],v[10],v[14],
v[3],v[7],v[11],v[15]
);
}
void CCustomHingeJoint::SubmitConstraints( dFloat timestep, int threadIndex )
{
Ogre::Vector3 omegaChild;
Ogre::Vector3 omegaParent;
NewtonBodyGetOmega(m_child,&omegaChild[0]);
NewtonBodyGetOmega(m_parent,&omegaParent[0]);
m_childPart->SetOmega(omegaChild);
m_parentPart->SetOmega(omegaParent);
// first the anchor has to be sticked to the correct place
Ogre::Vector3 dirX(1.f,0.f,0.f);
Ogre::Vector3 dirY(0.f,1.f,0.f);
Ogre::Vector3 dirZ(0.f,0.f,1.f);
double parentMF[16];
double childMF[16];
NewtonBodyGetMatrix(m_parent,parentMF);
NewtonBodyGetMatrix(m_child,childMF);
Ogre::Matrix4 parentM=GetMatrixFromFloat(parentMF);
Ogre::Matrix4 childM=GetMatrixFromFloat(childMF);
Ogre::Matrix4 parentPivotM=parentM*m_localParentoToPivotMatrix;
Ogre::Matrix4 childPivotM=childM*m_localChildToPivotMatrix;
Ogre::Vector3 parentPivot=parentPivotM.getTrans();
Ogre::Vector3 childPivot=childPivotM.getTrans();
Ogre::Vector3 dirToPivot=parentPivot-childPivot;
// put the child pivot in the right place
NewtonUserJointAddLinearRow (m_joint, &childPivot[0], &parentPivot[0], &dirX[0]);
SetupRow();
NewtonUserJointAddLinearRow (m_joint, &childPivot[0], &parentPivot[0], &dirY[0]);
SetupRow();
NewtonUserJointAddLinearRow (m_joint, &childPivot[0], &parentPivot[0], &dirZ[0]);
SetupRow();
// snap the rotation axis vector to where it should be
Ogre::Vector3 desiredAxisPoint=parentPivotM*m_childPart->GetModel()->GetRotationAxis();
Ogre::Vector3 actualAxisPoint=childPivotM*m_childPart->GetModel()->GetRotationAxis();
Ogre::Vector3 desiredAxisVector=(desiredAxisPoint-parentPivot).normalisedCopy();
if (!desiredAxisVector.isZeroLength())
{
Ogre::Vector3 n1=desiredAxisVector.perpendicular().normalisedCopy();
Ogre::Vector3 n2=desiredAxisVector.crossProduct(n1).normalisedCopy();
NewtonUserJointAddLinearRow(m_joint,&actualAxisPoint[0],&desiredAxisPoint[0],&n1[0]);
SetupRow();
NewtonUserJointAddLinearRow(m_joint,&actualAxisPoint[0],&desiredAxisPoint[0],&n2[0]);
SetupRow();
}
// the last, motor for the arm
// calculate the current actual angle
Ogre::Vector3 axisPerp=m_childPart->GetModel()->GetRotationAxisPerp();
Ogre::Vector3 currentRotatedDir=(childPivot-childPivotM*axisPerp).normalisedCopy();
Ogre::Vector3 currentZeroRotation=(parentPivot-parentPivotM*axisPerp).normalisedCopy();
Ogre::Vector3 currentDesiredRotation=(Ogre::Quaternion(Ogre::Degree(m_childPart->GetCurrentRotation()),-desiredAxisVector)*currentRotatedDir).normalisedCopy();
Ogre::Vector3 tempNormal=currentDesiredRotation.crossProduct(currentZeroRotation);
float angle=currentDesiredRotation.angleBetween(currentZeroRotation).valueRadians();
if (tempNormal.dotProduct(desiredAxisVector)<0)
{
angle=-angle;
}
NewtonUserJointAddAngularRow(m_joint,angle,&desiredAxisVector[0]);
SetupRow();
}
void CCustomHingeJoint::SetupRow()
{
NewtonUserJointSetRowStiffness(m_joint,0.99f);
}
}}
-
SilentAssassin21
-
- Posts: 32
- Joined: Sat Sep 22, 2012 4:05 pm
by Julio Jerez » Tue Mar 19, 2013 2:39 pm
can you post a picture of a movie?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JoeJ » Tue Mar 19, 2013 4:36 pm
@ Julio:
Great to hear you're back
Don't forget to try my code template at previous page that reproduces the penetration 'bug' with 2 bodies and one joint.
@ Assassin:
Looking closer at your hinge code i see that it is no powering what you do (!)
You use the angluar row to set a hard constraint (like the linear point to point at the beginning).
You'll get some behaviour that looks like powering, but it is some error reduction that newton does if joints gone wrong.
I remember Pjani initially made the same mistake, this is what i replied by PM:
// if the motor capability is on, then set angular acceleration with zero angular correction
NewtonUserJointAddAngularRow (joint, 0.0f, &axis[0]);
// override the angular acceleration for this Jacobian to the desired acceleration
NewtonUserJointSetRowAcceleration (joint, relAccel);
NewtonUserJointSetRowMinimumFriction (joint, -m_maxAngularFriction); // max "strength" of the motor
NewtonUserJointSetRowMaximumFriction (joint, m_maxAngularFriction);
Here the axis is where you apply the trorque, and relAccel is the relative acceleration that you want to have.
Newton caluculates the necessary torque to achieve that, not you - that's the solvers purpose.
You can see examples on how to calulate relAccel in the powered hinge post i've linked in the thread,
or in the Kinematic Controller joint.
If i assume you'd have no powered hinge yet (you have?), i'd suggest (again) to do the following:
* Create a powered hinge like a car engine (constant relAccel) - that's easy
* Modify it so that it can set and keep a variable angle between the bodies - that's what you need for ragdoll.
I've posted working powered hinge code somewhere in the forum.
-

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