Vehicle Bouncing when stationary

mcimolin

15-06-2010 23:30:53

Hey, I'm fairly new to NxOgre ,Ogre in general really, and I'm having a strange problem. I've created a vehicle based off of Betajaen's code here on the forum, however,
when the vehicle is sitting stationary with no torque applied to the wheels, it vibrates in place. This vibration also occurs when the vehicle is moving.

I've used the external debugger to check that the wheels aren't bumping into the convex hull, which they don't seem to be. Also, the vehicle vibrates in the
debugger so I know it's not a rendering issue with Ogre.

None of the other objects in my scene are vibrating at all, and the vibration occurs both on triangle meshes and on plane geometry.
I've tried applying both vertical and angular damping, but with little success. It did stop the vehicle from rolling forward due to the vibration, but it still vibrates.

Here is the code. I'm using NxOgre 1.5.5 and Ogre 1.7.0

#include "WheelChairVehicle.h"

/*
Create and Register the Vehicle
*/
WheelChairVehicle::WheelChairVehicle(const NxOgre::Vec3& position, NxOgre::Scene* scene, OGRE3DRenderSystem* renderSystem)
{
Machine();
mScene = scene;
mRenderSystem = renderSystem;

NxOgre::RigidBodyDescription description;

description.mMass = 40; // Make it heavy.
description.mWakeUpCounter = 1E30; // Never go to sleep.

wheelDriveTorque = 0;
wheelBrakeTorque = 0;
wheelAngle = 0;

//Load Resources
NxOgre::ResourceSystem::getSingleton()->openArchive("media", "file:media/");

//Convert to standard string
std::string mMesh = "media:WheelChairHull.mesh.nxs";
const char* cMesh = mMesh.c_str();


NxOgre::Resource* rMesh = NxOgre::ResourceSystem::getSingleton()->open(cMesh, NxOgre::Enums::ResourceAccess_ReadOnly);

NxOgre::Mesh* convexMesh = NxOgre::MeshManager::getSingleton()->load(rMesh);

mChassisShape = new NxOgre::Convex(convexMesh);

NxOgre::Shapes shapes;

shapes.insert(mChassisShape);

addWheel(0.5f, NxOgre::Vec3(-0.105f, 0.2f, 0.49f), false, false, false);
addWheel(0.5f, NxOgre::Vec3(0.375f, 0.2f, 0.49f), false, false, false);
addWheel(1, NxOgre::Vec3(-0.105f, 0.1f, -0.422f), false, false, false);
addWheel(1, NxOgre::Vec3(0.375f, 0.1f, -0.422f), false, false, false);
addWheel(1, NxOgre::Vec3(-0.155f, 0.1f, 0.24f), true, true, true);
addWheel(1, NxOgre::Vec3(0.425f, 0.1f, 0.24f), true, true, true);

for (unsigned int i=0; i < mWheels.size(); i++)
shapes.insert(mWheels[i].mWheel);

mActor = mScene->createActor(shapes, position, description);
mActor->setCMassOffsetLocalPosition(NxOgre::Vec3(0,0,0));

mPointRenderable = mRenderSystem->createPointRenderable("WheelChair.mesh");

mActor->getNxActor()->setGroup(1);

mActor->setAngularDamping(0);
mActor->setLinearDamping(0.5);

mScene->registerMachine(this);

}

/*
Destructor
*/
WheelChairVehicle::~WheelChairVehicle()
{
mScene->unregisterMachine(this);
}

/*
Creates and adds wheels to the vehicle
*/
void WheelChairVehicle::addWheel(float radius, const NxOgre::Vec3& position, bool driving, bool steering, bool braking)
{
CarWheel w;

// Create the physics wheel, which our rules and point renderable will represent and work with.
NxOgre::WheelBlueprint* blueprint = new NxOgre::WheelBlueprint();
blueprint->mRadius = 0.433f * 0.25f * radius;
blueprint->mLocalPose.set(position);
w.mWheel = new NxOgre::Wheel(blueprint);

// Create our rules about this wheel.
w.mDriving = driving;
w.mSteering = steering;
w.mBraking = braking;

//Add Suspension
//NxOgre::SpringDescription springDesc;
//springDesc.mDamper = 0.5;
//springDesc.mSpring = 0.5;

//w.mWheel->setSuspension(springDesc);
mWheels.insert(w);

// Then create the machine part of that wheel, so rules can be applied to it, and it can be rendered.
createWheelMachinePart(w.mWheel, mRenderSystem->createPointRenderable("wheel.mesh"));
}

/*
Applies a driving(forward) torque to the wheels, up to the
max torque
*/
void WheelChairVehicle::drive(float torque)
{
if(this->bNeedsBrake){
this->bNeedsBrake = false;
}

this->wheelDriveTorque = this->wheelDriveTorque + torque;
this->wheelBrakeTorque = 0;

if(this->wheelDriveTorque > maxDriveTorque)
this->wheelDriveTorque = maxDriveTorque;

for (unsigned int i=0;i < mWheels.size();i++){
if (mWheels[1].mBraking)
mWheels[i].mWheel->setBrakeTorque(this->wheelBrakeTorque);

if (mWheels[i].mDriving)
mWheels[i].mWheel->setMotorTorque(this->wheelDriveTorque);
}
}

/*
Applies a reverse(backwards) torque to the wheels, up to the
max torque
*/
void WheelChairVehicle::reverse(float torque)
{
if(this->bNeedsBrake){
this->bNeedsBrake = false;
}

this->wheelDriveTorque = this->wheelDriveTorque - torque;
this->wheelBrakeTorque = 0;

if(this->wheelDriveTorque < -maxDriveTorque)
this->wheelDriveTorque = -maxDriveTorque;

for (unsigned int i=0;i < mWheels.size();i++){
if (mWheels[1].mBraking)
mWheels[i].mWheel->setBrakeTorque(this->wheelBrakeTorque);

if (mWheels[i].mDriving)
mWheels[i].mWheel->setMotorTorque(this->wheelDriveTorque);
}
}

/*
Applies a stopping(reverse) torque to the wheels, down
to 0, then applies a brakeing torque.
*/
void WheelChairVehicle::slow(float torque)
{
if(this->wheelDriveTorque > 0)
this->wheelDriveTorque = this->wheelDriveTorque - torque;
else if(this->wheelDriveTorque < 0)
this->wheelDriveTorque = this->wheelDriveTorque + torque;
else{
this->wheelDriveTorque = 0;
this->wheelBrakeTorque = maxBrakeTorque;
}

brake(10.0f);

for (unsigned int i=0;i < mWheels.size();i++){
if (mWheels[1].mBraking)
mWheels[i].mWheel->setBrakeTorque(this->wheelBrakeTorque);

if (mWheels[i].mDriving)
mWheels[i].mWheel->setMotorTorque(this->wheelDriveTorque);
}
this->bNeedsBrake = true;
}

/*
Applies a brakeing torque to the wheels.
*/
void WheelChairVehicle::brake(float torque)
{
this->wheelBrakeTorque = this->wheelBrakeTorque + torque;
this->wheelDriveTorque = 0;

if(this->wheelBrakeTorque > maxBrakeTorque)
this->wheelBrakeTorque = maxBrakeTorque;

for (unsigned int i=0;i < mWheels.size();i++){
if (mWheels[i].mBraking)
mWheels[i].mWheel->setBrakeTorque(this->wheelBrakeTorque);

if (mWheels[i].mDriving)
mWheels[i].mWheel->setMotorTorque(this->wheelBrakeTorque);
}
}

/*
Sets the steering angle of the wheels, between
the maximum and -maximum values.
*/
void WheelChairVehicle::steer(float angle)
{
this->wheelAngle = this->wheelAngle + Ogre::Degree(angle).valueRadians();

if(this->wheelAngle > maxAngle)
this->wheelAngle = maxAngle;

if(this->wheelAngle < -maxAngle)
this->wheelAngle = -maxAngle;

for (unsigned int i=0;i < mWheels.size();i++)
if (mWheels[i].mSteering)
mWheels[i].mWheel->setSteeringAngle(this->wheelAngle);
}

/*
Sets the position and orientation of the Vehicle
*/
void WheelChairVehicle::setPositionAndOrientation(NxOgre::Vec3 position, Ogre::Quaternion orientation){

mActor->setGlobalPosition(position);
mActor->setGlobalOrientationQuat(orientation);

}


And the .h file

#ifndef WHEEL_CHAIR_VEHICLE_H
#define WHEEL_CHAIR_VEHICLE_H

#include <NxOgre.h>
#include <NxOgreOGRE3D.H>
#include <NxActor.h>
#include "HelpfulUtilities.h"

static const float maxBrakeTorque = 100.0f;
static const float maxDriveTorque = 100.0f;
static const float maxAngle = Ogre::Degree(40.0f).valueRadians();

class WheelChairVehicle: public NxOgre::Machine, public NxOgre::Callback
{
public:

WheelChairVehicle(const NxOgre::Vec3& position, NxOgre::Scene* scene, OGRE3DRenderSystem* renderSystem);

~WheelChairVehicle();

void addWheel(float radius, const NxOgre::Vec3& position, bool driving, bool steering, bool braking);

void drive(float torque);

void reverse(float torque);

void slow(float torque);

void brake(float torque);

void steer(float angle);

void WheelChairVehicle::setPositionAndOrientation(NxOgre::Vec3 position, Ogre::Quaternion orientation);

float wheelBrakeTorque;
float wheelDriveTorque;
float wheelAngle;
bool bNeedsBrake;

protected:
struct CarWheel
{
NxOgre::Wheel* mWheel;
bool mDriving;
bool mSteering;
bool mBraking;
};

NxOgre::Array<CarWheel> mWheels;

NxOgre::Scene* mScene;
OGRE3DRenderSystem* mRenderSystem;
NxOgre::Convex* mChassisShape;

};
#endif


Any hints or suggestions would be greatly appreciated.