DevOxyz - BLOG

The simple maths behind bot cars.

Oct 25th
Nicolas Augustin

Writting a road safety VR application I had to create bot vehicles.
Please note that no NDA has been breached in this article.

The challenge

The player's controlled (Logitech driving wheel and pedals) car was placed on a curvy road surrounded by autonomous bots vehicles. These bot vehicles have to adapt their speed to the player's car speed but they also had to follow the road, change lane, avoid road obstacles. How would I make those vehicles follow the road programmatically ?

The solution

My first approach was to make these bots follow a path and add some side translations delta for lane changing. This approach was to be tedious in case the topology of the road changed, so I went for a more generic approach. The new approach consisted in getting inspired from how we actually follow a road: we anticipate the future position of the car on the road while keeping the car on the road, in the current lane.
Staying in the current lane actually consists in keeping the car sides at the same distance from a side of the road. We then steer the wheel to adjust the car position in the lane.

There we go, I had it. Now how can I implement that in Unity? The road was composed of sections, each section having a mesh collider matching the flat part of the road but also the external vertical plane matching the limits of the road section.
To keep the 3D car in the current lane, we have to compute where we want to place the car in the next frame, so that the car will stay at the same distance from the road side.

To do this, I computed a point ahead of the current position, P_Ahead, of the car (using simple local to world transformation). From this point a ray was cast in a direction matching the (right) side of the car (World X axis of the car). If the ray hits the vertical planes located on the side of the road at P_Collision, I move along the normal of the ray-plane collision point to compute P_DriveTo. The norm of the P_Collision P_DriveTo vector is the distance (DSide) we want between the car position in the next frame and the side of the road.

Great, now that we have P_DriveTo, the point that we want the bot car to be in the next frame, we have to steer the driving wheel so that the car reaches this position.

Steering is actually changing the front wheels angle and what we are looking for is this steering angle. At this point I used:

SA formula
This formula uses some geometry and the law of cosines to derive an *estimate* of the radius of curvature as a function of the steering wheel angle and wheel base.

And voila, we can get the steering angle to change the front wheels orientation to point the car towards the P_DriveTo destination point. We make this computation at each frame of course, and slowly changing DSide, we can achieve a lane change. If we change DSide an abrupt way, we can simulate a car avoiding an obstacle on the road as it just consists in brutally steering. Not changing DSide makes the car stays in the current lane.