3.3 Gear Changing

Implementation

I will show you an implementation similar to that used by the "Damned" robot from Eric Espié. I show you this, because it's simply better than my implementation in the berniw robot.

/* Compute gear */
int Driver::getGear(tCarElt *car)
{
    if (car->_gear <= 0) return 1;

If we are in neutral or reverse shift to the first gear.

    float gr_up = car->_gearRatio[car->_gear + car->_gearOffset];
    float omega = car->_enginerpmRedLine/gr_up;
    float wr = car->_wheelRadius(2);

    if (omega*wr*SHIFT < car->_speed_x) {
        return car->_gear + 1;

Shift up if the allowed speed for the current gear (omega*wr*SHIFT) is exceeded.

    } else {
        float gr_down = car->_gearRatio[car->_gear + car->_gearOffset - 1];
        omega = car->_enginerpmRedLine/gr_down;
        if (car->_gear > 1 && omega*wr*SHIFT > car->_speed_x + SHIFT_MARGIN) {
            return car->_gear - 1;

If the current gear is greater than one (we don't want to shift to neutral here), check if the current speed (plus a constant) is lower than the allowed speed with the next lower gear. If that's true, shift down. We add the constant to avoid oscillating up- and down-shifting.

        }
    }
    return car->_gear;
}

If all of the above didn't apply, simply return the current gear. You have to put the new constants at the beginning of driver.cpp.

const float Driver::SHIFT = 0.9;         /* [-] (% of rpmredline) */
const float Driver::SHIFT_MARGIN = 4.0;  /* [m/s] */

We have to add the call to the drive method in driver.cpp.

        car->ctrl.gear = getGear(car);

Finally we put the method interface and the constants into driver.h.

        int getGear(tCarElt *car);

        static const float SHIFT;
        static const float SHIFT_MARGIN;

Testdrive

Do again some test runs with the different cars. Because we accelerate from the first gear we face a new problem: the driven wheels are skidding, because we apply full throttle. It will be necessary to add some kind of traction control. The current lap times are:

  • mixed-2: 1:43:93, 619 damage.
  • e-track-2: 1:46:93, 0 damage.
  • e-track-4: 2:15:13, 4 damage.

Code Performance

You have seen an implementation for gear changing and braking. You should have recognized, that we compute in every timestep a lot of stuff we could put in a preprocess and just compute it once (e. g the allowed speed on a segment, the gear ratios, ...). Why we didn't do that? It's because we need still some additional code, so in fact we don't know how the robot looks like in the end. I would recommend to develop first straightforward, and if you are happy with the result, then you can start improving performance. But you should do it, because there are some poor guys like me with just 550MHz.

Downloads

In case you got lost, you can download my robot for TORCS 1.2.0 or later.

Summary

  • You know a way to change the gears.
  • You have implemented it.