Using a force-based model for traffic simulation.
A realistic vehicle simulator requires quite a complex model to represent the vehicle and all its possible motions. For this experiment I’ve assumed a rather simple model, a so-called particle model. A particle has a position, speed and direction. For the purpose of a vehicle an extra attribute is added, namely, orientation. This is a requirement for stationary vehicles as their direction is zero, yet they still need to orientate towards a sensible direction.
Particles are allowed to instantly change their direction and speed, this is not at all realistic for vehicles. I propose we adjust the physics engine to find a suitable motion configuration that most closely resembles the particle’s properties. In practice this means we limit the acceleration and clamp the direction’s angle (called Max steering in the above demo.
Rather than using a geometrical representation of the road, a simple directed graph is used to mark the center of a road. Having the vehicles directly trace this graph isn’t possible nor realistic; as mentioned earlier, the vehicle’s motions are limited - the graph may contain a 90° angle, yet the vehicle’s turning radius cannot accommodate such sharp turn.
Crowd simulation literature solves this issue with the attraction point idiom, which conveniently works well for traffic simulation. This approach works as following;
- Identify which road the vehicle resides on.
- Find the point on the road nearest to the vehicle.
- Project a point n pixels ahead along the road, where n is some number (called Lookahead in the above demo). This is the attraction point. In case the attraction point does not lie on a road, it should be recomputed while taking a "turn" in to account, i.e., the attraction point follows corners.
- The vehicle's direction is the vector that steers towards the attraction point.
If every vehicle follows the same path, it may look a bit dull. This could be solved by offsetting the attraction point along the perpendicular axis along the road. In the above demo the offset is determined using a sine wave with respect to distance traveled. Admittedly it looks like a drunk driver is zig-zagging, it does demonstrate how a offset could work. Some literature suggest the use of Perlin noise for pretty looking variation. This is something I’ll be implementing soon.
Dealing with other vehicles
Thus far we have a bunch of vehicles following a road. What remains is for them to take each other into account. One could use a rule-based system (e.g., “if too close - use breaks”). A rule-based system requires an explicit rule for every traffic situation, which doesn’t scale well and takes effort to compose. As an experiment I implemented the separation steering behaviour as described in Craig Reynolds’ work, which negates the need for explicit formulation of rules.
A vehicle observes neighbouring vehicles within a given radius (called Viewrange in the above demo). It computes a direction that steers away from those vehicles (e.g., take the direction towards a neighbour and flip it). All these separation directions are averaged into a single separating direction. When computing the vehicle’s direction, the path following direction and separation are added together.
This yields some cool emergent behaviours;
- Vehicles sporadically overtake each other when their desired speeds vary significantly.
- The front vehicle in a tailgating situation accelerates. (A stressed driver?)
- Vehicles only sporadically overlap, rendering thorough collision detection unnecessary.
Thus far it looks cool, though it’s not quite a shippable product for a computer game. In my paper I also address traffic lights and vehicles taking turns, this is something I’ll be implementing at some point, and this will hopefully introduce more realism. You may encounter little bugs where vehicles drive in circles instead of taking a turn - I’m working on that!