Intelligent driver
The intelligent driver system of cars on a ring road.
- Class:
IntelligentDriverSystem - Import:
from skcomplex.systems.engineering.traffic import IntelligentDriverSystem - Field:
engineering/traffic - Topics:
traffic,jams,ode,car following - References: Treiber, Hennecke, and Helbing 2000; Chowdhury, Santen, and Schadschneider 2000
Use this system
from skcomplex.core.engine.runtime import simulate
from skcomplex.systems.engineering.traffic import IntelligentDriverSystem
trajectory = simulate(IntelligentDriverSystem())
Parameters
| Parameter | Default |
|---|---|
n_cars |
20 |
length |
500.0 |
v0 |
30.0 |
T |
1.5 |
a |
1.0 |
b |
1.5 |
s0 |
2.0 |
delta |
4.0 |
car_length |
5.0 |
perturbation |
1.0 |
Tags
| Tag | Values |
|---|---|
| Time | continuous |
| Space | none |
| Laws | rate |
| Randomness | deterministic |
| Domains | real |
| Structure | fixed |
Class
class IntelligentDriverSystem(BaseSystem):
"""The intelligent driver system of cars on a ring road.
Car `i` accelerates as `v' = a (1 - (v / v0)^δ - (s* / s)^2)` with the gap `s` to the car ahead and the desired gap
`s* = s0 + v T + v Δv / (2 sqrt(a b))`, where `Δv` is the speed difference to the car ahead. Cars start at rest. The
cars are one group, and the car ahead of car `i` is member `i + 1` along the ring. The system has the group `cars`
of positions `cars.x` and speeds `cars.v`, car `i + 1` ahead of car `i`.
Args:
n_cars:
The number of cars.
length:
The length of the ring road.
v0:
The desired speed.
T:
The safe time headway.
a:
The largest acceleration.
b:
The comfortable deceleration.
s0:
The jam distance.
delta:
The acceleration exponent.
car_length:
The length of a car, subtracted from the headway to give the gap.
perturbation:
The forward shift of the first car from uniform spacing.
label:
The label of the system, which names it when it is nested in another one.
Examples:
>>> from skcomplex.systems.engineering.traffic import IntelligentDriverSystem
>>> IntelligentDriverSystem(n_cars=4).prepare().system_.interactions[0].road_length
500.0
"""
field = 'engineering/traffic'
topics = ('traffic', 'jams', 'ode', 'car following')
references = ('Treiber, Hennecke, and Helbing 2000', 'Chowdhury, Santen, and Schadschneider 2000')
until = 100.0
dt = 1.0
def __init__(
self,
n_cars: int = 20,
length: float = 500.0,
*,
v0: float = 30.0,
T: float = 1.5,
a: float = 1.0,
b: float = 1.5,
s0: float = 2.0,
delta: float = 4.0,
car_length: float = 5.0,
perturbation: float = 1.0,
label: str = 'system',
) -> None:
super().__init__(label)
self.n_cars = n_cars
self.length = length
self.v0 = v0
self.T = T
self.a = a
self.b = b
self.s0 = s0
self.delta = delta
self.car_length = car_length
self.perturbation = perturbation
def _build_system(self) -> System:
"""Return the parts of the system built from its model parameters."""
cars = GroupElement(
'cars',
element=CarElement,
size=self.n_cars,
values={'x': _ring_positions(self.n_cars, self.length, self.perturbation), 'v': 0.0},
)
following = IntelligentDriverInteraction(
'follow',
target='cars',
v0=self.v0,
T=self.T,
a=self.a,
b=self.b,
s0=self.s0,
delta=self.delta,
length=self.car_length,
road_length=self.length,
)
return System(self.label, elements=[cars], interactions=[following])
Components
Elements:
CarElement, fromElement
Interactions:
IntelligentDriverInteraction, fromRateInteraction
class CarElement(Element):
"""Car on a road whose position `x` advances at its speed `v`."""
law_classes = (RateLaw,)
def __init__(
self,
label: str,
visual: VisualSpec | None = None,
*,
x: Annotated[object, StateSpec(role='position')] = 0.0,
v: Annotated[object, StateSpec(role='velocity')] = 0.0,
) -> None:
super().__init__(label, visual=visual)
self.x = x
self.v = v
def _get_laws(self, s: SimpleNamespace) -> list[BaseLaw]:
"""Return the advance of the position at the speed."""
return [RateLaw(s.x, s.v)]
class IntelligentDriverInteraction(RateInteraction):
"""Acceleration of every car of a ring road by the intelligent driver system.
The acceleration depends on its speed and the car ahead. The speed follows
`v' = a (1 - (v / v0)^δ - (s*(v, Δv) / (h - l))^2)`, with the desired gap `s* = s0 + v T + v Δv / (2 sqrt(a b))`,
the approach rate `Δv` to the next car, and the headway `h` less the car length `l`.
Args:
label:
The label of the interaction.
target:
The path of the group of cars, in the order they drive.
v0:
The desired speed.
T:
The safe time headway.
a:
The largest acceleration.
b:
The comfortable deceleration.
s0:
The jam distance.
delta:
The acceleration exponent.
length:
The length of a car.
road_length:
The length of the ring road.
"""
def __init__(
self,
label: str,
*,
target: Annotated[str, RoleSpec()],
v0: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 30.0,
T: Annotated[object, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 1.5,
a: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
b: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.5,
s0: Annotated[object, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 2.0,
delta: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 4.0,
length: Annotated[object, ParameterSpec(domain=RealSet.closed_open(0, oo))] = 5.0,
road_length: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 500.0,
) -> None:
super().__init__(label, target=target, state='v')
self.v0 = v0
self.T = T
self.a = a
self.b = b
self.s0 = s0
self.delta = delta
self.length = length
self.road_length = road_length
def _get_rate(self, namespace: SimpleNamespace) -> object:
"""Return the acceleration of the intelligent driver system."""
s, cars = namespace, namespace.target
gap = s.s0 + cars.v * s.T + cars.v * (cars.v - shift_member(cars.v, 1)) / (2 * sqrt(s.a * s.b))
return s.a * (
1
- (cars.v / s.v0) ** s.delta
- (gap / (OptimalVelocityInteraction._headway(cars.x, s.road_length) - s.length)) ** 2
)
Equations
cars.x[i]: diff(x_cars(t), t) == v_cars(t)
cars.v[i]: diff(v_cars(t), t) == -1/4*a_follow*(4*(v_cars(t)/v0_follow)^delta_follow + (2*T_follow*v_cars(t) - (v_cars__shift0 - v_cars(t))*v_cars(t)/sqrt(a_follow*b_follow) + 2*s0_follow)^2/(length_follow - mod(x_cars__shift1 - x_cars(t), road_length_follow))^2 - 4)