A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by PJani » Wed Nov 21, 2012 4:03 pm
Hey. I am working on "motorics" for my ragdoll and i was thinking of using torque for muscular driving of bones.
this is my code for driving, but for some reason my skeleton explodes 0_0
- Code: Select all
using namespace Ogre;
Quaternion orient = m_body->getOrientation();
Vector3 omega = m_body->getOgreNewtBody()->getOmega();
Quaternion dorient = orient;
Vector3 domega = omega;
if(m_parent)
{
Game::Physics::Body* const parent_body = m_parent->getBody();
dorient = orient * parent_body->getOrientation().Inverse();
domega = omega - parent_body->getOgreNewtBody()->getOmega();
}
Vector3 angles;
angles.x = dorient.getPitch().valueRadians();
angles.y = dorient.getYaw().valueRadians();
angles.z = dorient.getRoll().valueRadians();
float torq = 2f; //m_muscule_torque_per_angle;
Vector3 torque;
torque.x = NewtonCalculateSpringDamperAcceleration(dt, torq, angles.x, 0.9, domega.x);
torque.y = NewtonCalculateSpringDamperAcceleration(dt, torq, angles.y, 0.9, domega.y);
torque.z = NewtonCalculateSpringDamperAcceleration(dt, torq, angles.z, 0.9, domega.z);
body->addTorque(torque);
if(m_parent)
{
m_parent->getBody()->addTorque(-torque); //oposite force...
}
Any other idea?
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by Julio Jerez » Wed Nov 21, 2012 4:41 pm
why do you use springs?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by PJani » Wed Nov 21, 2012 7:53 pm
heh that was my idea to use torsion spring with high damping and large coef...this NewtonCalculateSpringDamperAcceleration was meant to be calculation for torsion torque.
Any other idea would be very apriciated.
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by JoeJ » Thu Nov 22, 2012 5:56 am
One thing that might be wrong: If you calculate the torque to match the target from child to parent, and apply the opposite torque to the parent, you need only half the torque.
Because both bodies rotate half the angle (if they have the same inertia) to meet at the relative target.
Also i have doubts the way you calculate 3 angles is correct. I've used a single axis and angle rotation, from which it's easy to calculate wanted angular velocity and then torque.
I'd wait on Julios rotational joint. My problem is that to make powered joint stable, they get slow in practice, because of the 3 angles problem.
That's why i use torques, as they help to be a little more responsive. Torques may not be necessary anymore when using the new joint, and it will be much easier too.
To keep a full ragdoll stiff enough for animation using troques only, using a simple iterative solver (predicting results and refine from that), i needed > 300 newton steps per second (!) ...plus this times 8-16 steps for my solver.
Now with powered joints, at 120 newton steps it's stiff enough also for realtime behaviour. Maybe the new joint allows 60 steps...
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by PJani » Thu Nov 22, 2012 8:53 am
Huh that sounds like an performance kill
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by PJani » Thu Nov 22, 2012 9:59 am
One question...
how can i add torque to body at certain global point?
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by JoeJ » Fri Nov 23, 2012 10:13 am
PJani wrote:how can i add torque to body at certain global point?
I derived this form someones code here at the forum.
It's not in use and i don't know if it works.
It would be better to search for the original post, seems i didn't change the variables names.
- Code: Select all
inline void AddTemporaryGlobalTorque (sVec3 &cForce, sVec3 &cTorque,
sVec3 kPoint, sVec3 kAxis, float kTorque, sVec3 com,
sMat4 &matrix, float mass, float Ixx, float Iyy, float Izz)
{
sVec3 R = com - kPoint - kAxis * (kAxis.Dot(com-kPoint) / kAxis.SqL());
sVec3 norm_axis (kAxis.Unit());
if (R.Length() < 0.0001f)
{
norm_axis *= kTorque;
cTorque = norm_axis;
cForce = sVec3(0,0,0);
return;
}
sVec3 In;// (mInertiaTensor.TransformVector(norm_axis));
In = ApplyInertia (norm_axis, matrix, Ixx, Iyy, Izz);
float inertia = In.Dot(norm_axis);
float local_torque = kTorque * inertia / (inertia + mass * R.SqL());
cForce = (norm_axis.Cross(R.Unit())) * ((kTorque-local_torque) / R.Length());
cTorque = norm_axis * local_torque;
}
inline sVec3 ApplyInertia ( sVec3 &vec, sMat4 &matrix, float Ixx, float Iyy, float Izz)
{
sVec3 torque = vec;
torque = matrix.Unrotate (torque);
torque[0] *= Ixx;
torque[1] *= Iyy;
torque[2] *= Izz;
torque = matrix.Rotate (torque);
return torque;
}
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by PJani » Fri Nov 23, 2012 5:00 pm
@JoeJ tnx

i will see how i will use it

Does anybody know what exactly is that friction in joint rows(angular and linear)? I mean what units(or just coefs) they are.
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by PJani » Sat Nov 24, 2012 3:07 pm
If i have linear rows in joint...how can i check how much force is used to pull together two points in linear row? Or "clip" linear row force?
I got an idea to use joints and power of joint rows instead of torque. Only problem is my character is stiff

| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by JoeJ » Sat Nov 24, 2012 6:08 pm
Min / max friction is the maximum power the joint will use in both directions, so you can use it to set maximum muscle power.
But to make a powered joint, you need to do it different than with the usual joints with stiff limits.
You need to use the acceleration functions, see the kinematic joint, which shows that for both linear and angular use.
-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by PJani » Sun Nov 25, 2012 9:37 am
Any idea how to solve jitter?
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by PJani » Sun Dec 09, 2012 12:34 pm
Hey julio i have one annoying problem. Per limb or limb joint i use two joints one is actual constraint(ball and socket or hinge) the second is controller. Controller joint controls two "dimensions"(twist and cone) of rotation freedom when using ball and socket or one "dimension" of rotation freedom when using hinge. both dimensions/rows are linear(i calculate unit vector direction in global space). Controller joint works relative to its parent limb/body(if hand rotates for 20 deg along some axis it will stay aligned with its parent).
Now the thing is, i am expirancing annoying oscillation which is not bad from distance but from close is worse especially because i need to attach camera to my controller ragdoll head.
The worsest are limbs! Head, Hands, Legs.
this is my controller joint code:
- Code: Select all
using namespace Ogre;
Rig::Bone* const this_main_bone = m_child->m_main_bone;
Rig::Skeleton* const skeleton = this_main_bone->getSkeleton();
//controller state...disable enable
if(!skeleton->getControllerEnabled())
return;
Real inv_dt = 1/dt;
Game::Physics::Body* const parent_body = (m_parent) ? m_parent->getBody() : NULL;
Game::Physics::Body* const this_body = m_child->getBody();
OgreNewt::Body* const parent_bdy = (m_parent) ? parent_body->getOgreNewtBody() : NULL;
OgreNewt::Body* const this_bdy = this_body->getOgreNewtBody();
Rig::PrototypeBone* const this_pbone = this_main_bone->getPrototypeBone();
Quaternion parent_orient = (parent_body) ? (parent_body->getOrientation() * m_parent->m_inverse_orientation) : skeleton->getGlobalOrientation() ;
Quaternion this_orient = (this_body->getOrientation() * m_child->m_inverse_orientation) * this_main_bone->getOrientation();
Vector3 vel1 = this_bdy->getVelocity();
Vector3 omg1 = this_bdy->getOmega();
Vector3 cg1 = this_bdy->getCenterOfMass();
Vector3 pos1 = this_bdy->getPosition();
Vector3 point_vel0(0,0,0);
Vector3 vel0(0,0,0);
Vector3 omg0(0,0,0);
Vector3 cg0(0,0,0);
Vector3 pos0(pos1);
Vector3 local_dir(0,1,0);
Vector3 local_dir_left(0,0,1);
if(parent_body)
{
vel0 = parent_bdy->getVelocity();
omg0 = parent_bdy->getOmega();
cg0 = parent_bdy->getCenterOfMass();
pos0 = this_bdy->getPosition();
local_dir = this_pbone->getDir();
local_dir_left = this_pbone->getDirLeft();
}
Vector3 this_dir(this_orient * local_dir);
Vector3 parent_dir(parent_orient * local_dir);
float frict = 1300.0f * m_child->getSupportingMass() / (skeleton->getMass());
if(parent_dir.absDotProduct(this_dir) < PRECISION_DELTA_INV )
{
Vector3 this_dir_pin(this_dir);
Vector3 parent_dir_pin(parent_dir);
Vector3 pull_dir(parent_dir_pin - this_dir_pin);
Vector3 pull_trajectory(pull_dir);
Real distance = pull_trajectory.normalise();
addLinearRow(this_body->getPosition() + this_dir_pin, this_body->getPosition() + parent_dir_pin, pull_trajectory);
setRowMinimumFriction(-frict);
setRowMaximumFriction( frict);
if(ACCEL_ROW_ENABLE_DISTANCE <= distance && !m_child->isAccelerationDisabled())
{
Vector3 local_offset = parent_orient.Inverse() * ((parent_dir + pos1) - pos0);
Vector3 point_vel0 = vel0 + omg0.crossProduct(parent_orient*(local_offset - cg0));
Vector3 point_vel1 = vel1 + omg1.crossProduct(this_orient*(local_dir - cg1));
Vector3 reldvel(point_vel0 - point_vel1);
Vector3 rel_vel(pull_dir * inv_dt - reldvel);
Vector3 rel_accel(rel_vel * (inv_dt * ACCEL_COEF));
setRowAcceleration(rel_accel.dotProduct(pull_trajectory));
}
}
bool is_rotation_locked = true;
is_rotation_locked = (parent_body)?this_pbone->getParent()->getBoneJointType() == Rig::BJT_LIMITED_BALL:true;
if(is_rotation_locked)
{
Vector3 this_dir_left = this_orient * local_dir_left;
Vector3 parent_dir_left = parent_orient * local_dir_left;
if(parent_dir_left.absDotProduct(this_dir_left) < PRECISION_DELTA_INV )
{
Vector3 pull_dir((parent_dir_left - this_dir_left).normalisedCopy());
addLinearRow(this_body->getPosition() + this_dir_left * PIN_LENGTH, this_body->getPosition() + parent_dir_left * PIN_LENGTH, pull_dir);
setRowMinimumFriction(-frict * 0.6f);
setRowMaximumFriction( frict * 0.6f);
}
}
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by PJani » Tue Dec 11, 2012 11:46 am
Anyway how are torque XYZ axis defined? Are axis aligned to world XYZ or local to object axis i am applying torque to?
| i7-5930k@4.2Ghz, EVGA 980Ti FTW, 32GB RAM@3000 |
| Dell XPS 13 9370, i7-8550U, 16GB RAM |
| Ogre 1.7.4 | VC++ 9 | custom OgreNewt, Newton 300 |
| C/C++, C# |
-

PJani
-
- Posts: 448
- Joined: Mon Feb 02, 2009 7:18 pm
- Location: Slovenia
by Julio Jerez » Tue Dec 11, 2012 12:44 pm
Oh I was not folloing this thread because is was between JoeJ and you.
you are talking of tow Joint betenn teh same bodies, that does not sound like a good idea
can you make a skecth of wha you want?
I whiel back I was mentioning to make a newer version of the Geneal 6DOF joint for newton 300.
basicually tshi joint will use the compest that teh produc of small angles is comutative.
I beleive I mentione thsi ti JoeJ but maybe I did no explane well.
Bu teh idea is that a Joint that uses prosiple of "teh product of small angled matrix is comutative"
can be implemnet is a way that angel pitic Yaw and Roll can be controll as inedepnde variable.
the only draw back is that this joint requeried the extra paramater of wah is a Small Angle, and in one step wuodl no be anle to correct for more that that error.
the effect is that tshi joint will have some intrisic Lag, that can only be reduce by teh simulation frame rate.
In return this joint can be very robust for controllynd teh kind of stuff that you want to do.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Tue Dec 11, 2012 1:12 pm
The typical scenario for this joint would be a control joint when the tree angle are be specified by the player.
say you want to make a upper Leg ball socked, and you want to create a kick.
here the angle Pitch, Yaw and Roll are always given as input.
The application want those angles to be the target and it does no care how they are generated all it care is that they are realized by that leg.
say the threes are; Pitch, Yaw, Roll
all of the Joint in the joint library, will try to achieve the target in one step.
however that causes a bit problem because the difficulty that, the tree torques that need to be generated by the solver are linear to cannot be proportional to the each respective error angle.
they have to be produce in one and only one order.
with the proposed joint, The joint code will get the same tree angle and it will clamp the to the "small angle"
now instead of solving for Pitch, Yaw, Roll, it solve for
Pitch0 = Clamp (Pitch, -smallAngle, smallAngle);
Yaw0 = Clamp (Yaw, -smallAngle, smallAngle);
Roll0 = Clamp (Roll, -smallAngle, smallAngle);
now the engine will emit three angle rows, in any order, and each oen will generate a torque the will be proportional to Pitch0, Yaw0 and Roll0 and because the fat that
Matrix(Pitch0) * Matrix (Yaw0) * Matrix (Roll0) ~= Matrix (Yaw0) * Matrix(Pitch0) * Matrix (Roll0) ~= any other permutation of the same angle
The effect is that, the joint will tend to correct the error, but It will require time to do the complete correction.
The effect is that you can control the angle independently at will, and without Gimbals Lock
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 0 guests