Learning and Applying Mathematics using Computing

The Bus That Couldn’t Slow Down

This post is about two different ways of implementing braking.

In a recent post, we saw how to implement a drifting, asteroids-style of movement (and how to limit the maximum speed). As is traditional in asteroids, there was no braking: you just accelerate in the opposite direction to slow down. In this post, we’ll look at how two different ways to implement braking (and to fit with the title, our spaceship will become a bus).

Fixed Braking

One way to implement braking is to subtract a fixed amount from the current speed. (In effect, this performs an acceleration in the opposite direction to the one in which you are currently travelling — not pointing). We saw in our last post how to convert from cartesian to polar speeds, where speed becomes a single number. We can augment the code from our last post to add braking:

```    private void clampSpeedAndBrake()
{
double dir = calculateDirection(speedX, speedY);
double speed = calculateMagnitude(speedX, speedY);

final double MAX_SPEED = 10;

if (speed > MAX_SPEED)
{
speed = MAX_SPEED;
}

if (Greenfoot.isKeyDown("down"))
{
speed = speed - 0.1;
}

speedX = calculateX(dir, speed);
speedY = calculateY(dir, speed);
}
```

The braking is the second if-statement: if they’re pressing the down arrow, reduce the speed.

Problem: Pedalling Backwards To Brake

In the code above, braking works fine. But if you increase the strength of the braking, you’ll find a very strange effect. If that speed reduction is set to, say, 1.5, you’ll find that holding the brake key when stopped will jiggle you around. Consider what the above code does if your speed is zero: it reduces the speed to a negative number, but once that gets converted back to cartesian, it means that you are no longer stationary. This problem is quite easy to fix, by using the maximum function to make sure that speed is either reduced or zero, whichever is larger (you might need to think about that for a minute):

```        if (Greenfoot.isKeyDown("down"))
{
speed = Math.max(0, speed - 0.1);
}
```

Proportional Braking

The alternative to what I’ve called fixed braking (which reduces your speed by a fixed amount each frame) is proportional braking. The idea behind proportional braking is that instead of subtracting a fixed amount from your speed, you instead take off a proportion. So let’s say that each frame you brake should slow you by 2%: you just multiply the speed by 0.98, making the braking code:

```        if (Greenfoot.isKeyDown("down"))
{
speed = speed * 0.98;
}
```

Problem: Coming To A Complete Stop

One problem with proportional braking is that it gets a bit irritating as you come close to stopping. There is a thought experiment (not to be confused with Zeno’s paradox) that runs: “if every second you halve the distance between you and your destination, will you ever get there?”. And so it is in proportional braking: if your speed always reduces by 2%, will it ever actually hit zero — will you ever actually stop? In mathematics, the answer is: no ($\forall n. 0.98^n > 0$). In computing the answer is: eventually (because eventually the number will become so small it will be represented by zero).

Practically speaking (ignoring all this theory fluff!), the best thing to do is add a special case that once your speed is close enough to zero, just set it to zero. Not elegant, but effective:

```        if (Greenfoot.isKeyDown("down"))
{
speed = speed * 0.98;
}
if (speed <= 0.05)
{
speed = 0;
}
```

You can have a play with the two different styles of braking in this scenario. The bus with an “F” on it is controlled by WASD and does fixed braking, while the bus with a “P” on it is controlled by the arrow keys and does proportional braking. There’s no single right answer to which is a better system, but having played around, I prefer the fixed braking — the proportional braking takes a long time to come to a complete halt.