RayCast vehicle - I think it's almost done

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

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);
}

franklyn

29-10-2007 00:36:30

Hey there did you get this to work ? , im actually working on a raycast car myself and im having a lot of problems with the suspensions. i was wondering if you had any articles or tips of your own. we really need to get one up on the wiki.

Dirso

29-10-2007 13:40:02

Hey there did you get this to work ? , im actually working on a raycast car myself and im having a lot of problems with the suspensions. i was wondering if you had any articles or tips of your own. we really need to get one up on the wiki.
I didn't get it working yet, but if you want, you can use the suspension part of this code, it works like a charm. I also will publish an OpenSource FrameWork (or Engine someday) by the weekend and all the code I've got so far will be there and I hope to get more contributions to finish this. It's a plugin based FrameWork, so the Raycast car will work with any physics system. Of course it's still the version 0.1

Best Regards,
Dirso