[Fixed]Gearbox... Works!

Langhole

28-03-2007 07:31:45

Before I dive deep into the Stunt Playground source, I figured that I should at least make one last effort to finding any 'documentation' regarding this subject. So far, the search function on the forums have only pointed me to posts I've already read, on materialPairs for friction. I'm just wondering if there are any guides, or documentation in general on any sort of gearbox in the vehicle class or how to set up a custom gearbox. I'm writing my own currently but it's not going well, hopefully the stuntplayground will help too :)

thx

Langhole

29-03-2007 04:23:09

Ok, I've been playing around with a sort of custom gear box now, so far no errors, I can't really test it out yet though, because when switching gears, I am setting the friction in a material pair to something slightly higher so the car will pick up more speed, and not slip and slide everywhere.

Basically it runs updateGears() which calculates the next gear based on the current kmph of the vehicle. After it figures the gear out, it applies the new torque value, and then calls this function:


void OgreNewtonFrameListener::updateFriction(Ogre::Real friction)
{
mPair->setDefaultFriction(friction, friction);
}


It compiles, but brings up the debugger, brings me to ogrenewt_materialid.h and points at "int getID() const { return id; }"

the debugger says m_World is undefined, and so is m_DefaultId

I'm wondering if I should look into a callback function for the material pair, buuuuuut... I don't know the first thing about a callback function, could someone shift me on the right track possibly?

I'd really appreciate it, thx.

Langhole

29-03-2007 21:35:53

My fix: 8)

callbacks.h
class carCallback : public OgreNewt::ContactCallback
{
public:
void setupCallback(OgreNewt::MaterialID* m1, OgreNewt::MaterialID* m2, OgreNewt::MaterialPair* mP, SimpleVehicle* c)
{
mat1 = m1;
mat2 = m2;
matPair = mP;
car = c;
friction = NULL;
}

private:
int userBegin(){ return 1; }
int userProcess();
void userEnd(){}

protected:
SimpleVehicle* car;
Ogre::Real friction;
int* gear;
OgreNewt::MaterialID* mat1;
OgreNewt::MaterialID* mat2;
OgreNewt::MaterialPair* matPair;

};


callbacks.cpp
int carCallback::userProcess()
{
switch(car->gear)
{
case 0:
friction = Ogre::Real(1.0);
break;
case 1:
friction = Ogre::Real(1.1);
break;
case 2:
friction = Ogre::Real(1.2);
break;
case 3:
friction = Ogre::Real(1.3);
break;
case 4:
friction = Ogre::Real(1.4);
break;
default:
friction = Ogre::Real(1.0);
break;
}

setContactStaticFrictionCoef(friction, 0);
setContactStaticFrictionCoef(friction, 1);

setContactKineticFrictionCoef(friction, 0);
setContactKineticFrictionCoef(friction, 1);

car->carVsArenaFriction = friction;

return 1;
}


Hurray for callbacks!

-----------------------------------------------------------------------------------

Now for the Gearbox:

SimpleVehicle.h (added these public vars)

int gear; // current gear
Ogre::Real gasTorque; // torque for wheels
Ogre::Real carVsArenaFriction; // friction for the current gear


SimpleVehicle.cpp (init vars)

gear = 0;
gasTorque = Ogre::Real(0.0);


FrameListener.h (toggle keys, function)

bool mE;
bool mQ;
void updateGears();


FrameListener.cpp (last code block, don't worry :P)

int* pGear; // pointer to gear var
pGear = &mCar->gear; // point the pointer!
updateGears(); // update the gearbox


//--------------------------------------
// -- Gear Change (Manual) --
//--------------------------------------
// gear UP press
if(mKeyboard->isKeyDown(OIS::KC_E) && (!mE)) // E
{
// pressed
mE = true;
int newGear = *pGear + 1;
if(newGear > 4)
newGear = 4;
*pGear = newGear;
}
if(!mKeyboard->isKeyDown(OIS::KC_E)){ mE = false; };

// gear DOWN press
if(mKeyboard->isKeyDown(OIS::KC_Q) && (!mQ)) // Q
{
// pressed
mQ = true;
int newGear = *pGear - 1;
if(newGear < 0)
newGear = 0;
*pGear = newGear;
}
if(!mKeyboard->isKeyDown(OIS::KC_Q)){ mQ = false; };

//--------------------------------------
// -- Driving Input --
//--------------------------------------
// !Forward!
if(mKeyboard->isKeyDown(OIS::KC_W)) // W
{
torque += mCar->gasTorque;
}

...
}

//-## GEARBOX ##-//
void OgreNewtonFrameListener::updateGears()
{
//-- vars --//
Ogre::Real gTorque; // temp torque var used to change curTorque
Ogre::Real* curTorque; // pointer to the current torque
curTorque = &mCar->gasTorque; // point the pointer!

//-- Automatic Transmission ( Disabled - wasn't working ) --//
switch(mCar->gear)
{
case 0:
gTorque = 600;
break;
case 1:
gTorque = 800;
break;
case 2:
gTorque = 1000;
break;
case 3:
gTorque = 1200;
break;
case 4:
gTorque = 1400;
break;
}
*curTorque = gTorque; // change current gear's torque value

// TODO: REVERSE GEAR.. AND BRAKES
}


I know, I know, I can technically just set the torque when i'm changing gears manually, but I've already created this function, it could be used in the future for automatic transmission, so I'll just keep it, with *some* use at least, instead of having to re-write it later.. it's not like it bogs the app down...

Anyways, could someone please give me some feedback on my fixes to the SimpleVehicle class!!! I've been working pretty hard on all this, I'd like to hear from you guys/gals :P (probably mostly guys :P)

Tubez

29-03-2007 23:59:21

Cool, thanks! I've been looking for something like this.

What I don't understand though is why you are varying the friction coefficients when shifting up, since they should be material properties of the tires and the street and be more or less constant across the entire range of velocities. The idea of gears is to try and keep the engine running at the RPMs where it produces the most torque, so you'd think that the main difference would be in the place in the torque curve at which the engine is operating.

Langhole

30-03-2007 09:10:51

The only reason I'm increasing friction with gears is so I can have the car move faster without wheel slippage... though I'm going to need to redo this anyways because turning at a high speed results in a flipping car...

This is my second attempt at any sort of 'gear' system, I've done no research yet on actual gear setup.

I'll revise it and post my changes here :) I'm thinking of even attempting a gear class possibly embedded in the vehicle class... though I'm not sure of any benefit to doing that..

Tubez

02-04-2007 10:50:30

Balancing handling vs stability is an open problem in vehicle design. If you take a sharp turn at full speed and you wheels let you (you maintain grip on the tires) you should fully expect to flip over.

Anyway, the way I implemented by gearbox system is like this:

Let's assume you are powering your wheels. Then the wheel omega * final drive ratio * the gear ratio * the unit conversion (rad/s to RPM) factor gives you the engine RPM. This you can look up in the torque curve for your engine, which gives you the torque at full throttle. I store my torque curve as a list of (x,y) tuples and interpolate linearly, ymmv.
Scale this for your throttle setting. I do this linearly, but this is just an approximation.
Now we have the torque output at the engine. This determines the engine power that is delivered to the wheels. Power is RPM*torque. So if the power is the same but the RPM lower (due to the gear and final drive), the torque will be higher. In other words wheeltorque = enginetorque * finaldrive * gear.
You will need some fudge constants to get everything workign in world units if you use real torque curves (Nm over RPM), but for the rest it should be happy.

Note that at various points in your drivetrain you have the options of doing "active" things. Like limit the engine torque if the rear wheels are slipping (traction control), easing braking torques if wheels are blocked (ABS) or brakign tires independently if you have a sideways momentum (stability control/ESP). All these make the car easier to handle on slippery surfaces and are pretty much standard on modern cars and car simulations.

Langhole

02-04-2007 11:06:42

Crazy, that's some wicked in-depth info there man thx a lot :)

I've taken a break from the vehicles for a few days, but I will get back to this, I'm extremely intrigued with this solution. I'm still sort of new to C++, but I get 90% of what you're saying, once I set up the vehicle in my *new* framework, I'll try and implement the gearbox as you've suggested... should prove a fun little project lol

I decided after 2 days of messing around in Demo_5 that I really need my own framework if I'm going to do any serious work with the engine, and 3 days later I've finally finished it, even OIS implemented for the camera (so far just the camera, but later the vehicle of course) I'm really happy with the result, and everything looks so clean and flows a little better... you know how it is...

Anyway, the camera has a slight problem I'd like to fix first before I start implementing new classes, even before I set up OgreNewt for my project.

Basically, camera is smooth, looks around fine enough, but if you look too far down, the terrain I've put in there ( a mesh ) just disappears from view, look up and it appears again, almost like the near/farclipping is messed up somehow, but I've set them manually and that's not the problem... lol... I'll mess with it a bit, while I implement another game state for the main menu...

But yeh, thx a lot Tubez for your help, once I get into it I'll let u know my progress, hopefully it'll work out nicely :)

batnom

16-09-2008 07:13:25

I'm having a lot of trouble with the tyres slipping.. i've increased torque a bit and a lot, same with friction in every combination imaginable but can't stop them slipping >_>

Is there any other variables I can fiddle with?