Dirso
23-09-2007 15:56:06
Hi,
I think I'm almost there, the suspension is working fine, and I also think I'm considering all forces, including the normals (since the wheels don't exist physicly, I add this force manually as the wheels were there applying this forces over the body - the point where the forces are applied is susAct, locally, and posSusAct, its global coordinates).
Anyway, this code, i think, should works fine, I'm killing lateral forces and when I steer the wheels I apply a perpendicular force to that wheels to kill that acceleration too and that way I think the car should make the turn, but it isn't and that's the reason of my post.
But that's not what happens It actually starts "shaking" and making turns right then left then right again and so on not repecting my inputs, I think it might be a problem with the math, wrong angle calculation and velocity components.
Here is the main code, any help will be appreciated
Thanks,
Dirso
I think I'm almost there, the suspension is working fine, and I also think I'm considering all forces, including the normals (since the wheels don't exist physicly, I add this force manually as the wheels were there applying this forces over the body - the point where the forces are applied is susAct, locally, and posSusAct, its global coordinates).
Anyway, this code, i think, should works fine, I'm killing lateral forces and when I steer the wheels I apply a perpendicular force to that wheels to kill that acceleration too and that way I think the car should make the turn, but it isn't and that's the reason of my post.
But that's not what happens It actually starts "shaking" and making turns right then left then right again and so on not repecting my inputs, I think it might be a problem with the math, wrong angle calculation and velocity components.
Here is the main code, any help will be appreciated
Thanks,
Dirso
Ogre::Quaternion quat = getOrientation();
Ogre::Vector3 velocityVector(me->getVelocity());
Ogre::Real mass = _loader._carMass;
Ogre::Vector3 com = me->getCenterOfMass() + _loader._CoM;
// that's because Newton give me getCenterOfMass as an offset of the original CoM
// gravity force
Ogre::Vector3 Fg = Ogre::Vector3(0,-9.8, 0) * mass;
me->addForce(Fg);
// local vars
Ogre::Real deltaT = me->getWorld()->getTimeStep();
// for each wheel calculates all forces on each wheel
for(RayCastTireListIt it = _tires.begin(); it != _tires.end(); it++)
{
// draw the rotation
Quaternion WheelYaw((*it)->_steer * mSteerAngle, _worldOr);
// suspension
Ogre::Vector3 posSusAct((*it)->_wheelSusAct->getWorldPosition());
Ogre::Real r = (*it)->_radius;
Ogre::Real rayLength = r + (*it)->_susLength;
Ogre::Vector3 uVector(quat*_worldOr);
OgreNewt::BasicRaycast ray(mWorld, posSusAct, posSusAct - uVector*rayLength);
OgreNewt::BasicRaycast::BasicRaycastInfo info = ray.getFirstHit();
//
Ogre::Vector3 susAct = (*it)->_wheelSusAct->getPosition();
Ogre::Vector3 dWheel1 = (*it)->_wheelNode->getPosition();
Ogre::Vector3 dWheel2;
if(info.mBody)
{
// orientation vector
Ogre::Vector3 rVector(quat*WheelYaw*(*it)->_pin);
Ogre::Vector3 wheelVelocity(velocityVector + (susAct - com)*me->getOmega());
Ogre::Vector3 wheelVelocityN(wheelVelocity);
Ogre::Real velocityLen(wheelVelocityN.normalise());
Ogre::Real cos1(rVector.dotProduct(wheelVelocityN)),
cos2(uVector.dotProduct(wheelVelocityN)),
sin1(Math::Sqrt(1 - cos1*cos1)),
cosUp(uVector.dotProduct(_worldOr));
if(cos2 < 0.0) sin1 = -sin1;
// calculate the new position of the wheel
dWheel2 = susAct - (info.mDistance*rayLength - r)*uVector;
// calculate the suspension force
Ogre::Real dist1 = MathHelperClass::getDistance(dWheel2, susAct),
dist2 = MathHelperClass::getDistance(dWheel1, susAct);
Ogre::Real Fs = (*it)->_susSpring*((*it)->_susLength - dist1),
Fd = (dist2 - dist1)*(*it)->_susShock;
Ogre::Vector3 Fn(-Fg*Math::Abs(cosUp)/4.0);
Ogre::Vector3 Ft(Fn + quat*(Fd + Fs)*_worldOr);
// drive force
if(((*it)->_drive > 0.01) && (wheel_torque > 0.01))
{
Ogre::Vector3 driveForce(quat*_carAccelDir *
((*it)->_drive * wheel_torque / (*it)->_radius) );
Ft += driveForce;
}
// calculate the steering forces
Ogre::Vector3 friction(velocityLen*sin1*rVector*mass/4.0);
friction.y = 0.0f;
Ft += friction;
// set the final force
me->addLocalForce(Ft, (*it)->_wheelSusAct->getPosition());
}
else
{
dWheel2 = susAct - uVector*(*it)->_susLength;
}
(*it)->_wheelNode->setPosition(dWheel2);
(*it)->setOmega(getVelocity() / (*it)->_radius);
mCurrRotZ += Ogre::Radian((*it)->getOmega()*deltaT);
Quaternion WheelRotation(mCurrRotZ, (*it)->_pin);
(*it)->_wheelNode->setOrientation(WheelYaw*WheelRotation);
}