Behavior¶
Other simulated vehicles follow simple and realistic behaviors that dictate how they accelerate and
steer on the road. They are implemented in the IDMVehicle
class.
Longitudinal Behavior¶
The acceleration of the vehicle is given by the Intelligent Driver Model (IDM) from [THH00].
where \(v\) is the vehicle velocity, \(d\) is the distance to its front vehicle. The dynamics are parametrised by:
\(v_0\) the desired velocity, as
target_velocity
\(T\) the desired time gap, as
TIME_WANTED
\(d_0\) the jam distance, as
DISTANCE_WANTED
\(a,\,b\) the maximum acceleration and deceleration, as
COMFORT_ACC_MAX
andCOMFORT_ACC_MIN
\(\delta\) the velocity exponent, as
DELTA
It is implemented in acceleration()
method.
Lateral Behavior¶
The discrete lane change decisions are given by the Minimizing Overall Braking Induced by Lane change (MOBIL) model from [KTH07]. According to this model, a vehicle decides to change lane when:
it is safe (do not cut-in):
there is an incentive (for the ego-vehicle and possibly its followers):
where
\(c\) is the center (ego-) vehicle, \(o\) is its old follower before the lane change, and \(n\) is its new follower after the lane change
\(a, \tilde{a}\) are the acceleration of the vehicles before and after the lane change, respectively.
\(p\) is a politeness coefficient, implemented as
POLITENESS
\(\Delta a_\text{th}\) the acceleration gain required to trigger a lane change, implemented as
LANE_CHANGE_MIN_ACC_GAIN
\(b_\text{safe}\) the maximum braking imposed to a vehicle during a cut-in, implemented as
LANE_CHANGE_MAX_BRAKING_IMPOSED
It is implemented in the mobil()
method.
Note
In the LinearVehicle
class, the longitudinal and lateral behaviours
are approximated as linear weightings of several features, such as the distance and speed difference to the leading
vehicle.
API¶
- class highway_env.vehicle.behavior.IDMVehicle(road: Road, position: ndarray | Sequence[float], heading: float = 0, speed: float = 0, target_lane_index: int | None = None, target_speed: float | None = None, route: List[Tuple[str, str, int]] | None = None, enable_lane_change: bool = True, timer: float | None = None)[source]¶
A vehicle using both a longitudinal and a lateral decision policies.
Longitudinal: the IDM model computes an acceleration given the preceding vehicle’s distance and speed.
Lateral: the MOBIL model decides when to change lane by maximizing the acceleration of nearby vehicles.
- Parameters:
road – the road instance where the object is placed in
position – cartesian position of object in the surface
heading – the angle from positive direction of horizontal axis
speed – cartesian speed of object in the surface
- ACC_MAX = 6.0¶
Maximum acceleration.
- COMFORT_ACC_MAX = 3.0¶
Desired maximum acceleration.
- COMFORT_ACC_MIN = -5.0¶
Desired maximum deceleration.
- DISTANCE_WANTED = 10.0¶
Desired jam distance to the front vehicle.
- TIME_WANTED = 1.5¶
Desired time gap to the front vehicle.
- DELTA = 4.0¶
Exponent of the velocity term.
- DELTA_RANGE = [3.5, 4.5]¶
Range of delta when chosen randomly.
- classmethod create_from(vehicle: ControlledVehicle) IDMVehicle [source]¶
Create a new vehicle from an existing one.
The vehicle dynamics and target dynamics are copied, other properties are default.
- Parameters:
vehicle – a vehicle
- Returns:
a new vehicle at the same dynamical state
- act(action: dict | str = None)[source]¶
Execute an action.
For now, no action is supported because the vehicle takes all decisions of acceleration and lane changes on its own, based on the IDM and MOBIL models.
- Parameters:
action – the action
- step(dt: float)[source]¶
Step the simulation.
Increases a timer used for decision policies, and step the vehicle dynamics.
- Parameters:
dt – timestep
- acceleration(ego_vehicle: ControlledVehicle, front_vehicle: Vehicle | None = None, rear_vehicle: Vehicle | None = None) float [source]¶
Compute an acceleration command with the Intelligent Driver Model.
The acceleration is chosen so as to: - reach a target speed; - maintain a minimum safety distance (and safety time) w.r.t the front vehicle.
- Parameters:
ego_vehicle – the vehicle whose desired acceleration is to be computed. It does not have to be an IDM vehicle, which is why this method is a class method. This allows an IDM vehicle to reason about other vehicles behaviors even though they may not IDMs.
front_vehicle – the vehicle preceding the ego-vehicle
rear_vehicle – the vehicle following the ego-vehicle
- Returns:
the acceleration command for the ego-vehicle [m/s2]
- desired_gap(ego_vehicle: Vehicle, front_vehicle: Vehicle | None = None, projected: bool = True) float [source]¶
Compute the desired distance between a vehicle and its leading vehicle.
- Parameters:
ego_vehicle – the vehicle being controlled
front_vehicle – its leading vehicle
projected – project 2D velocities in 1D space
- Returns:
the desired distance between the two [m]
- change_lane_policy() None [source]¶
Decide when to change lane.
Based on: - frequency; - closeness of the target lane; - MOBIL model.
- mobil(lane_index: Tuple[str, str, int]) bool [source]¶
MOBIL lane change model: Minimizing Overall Braking Induced by a Lane change
The vehicle should change lane only if: - after changing it (and/or following vehicles) can accelerate more; - it doesn’t impose an unsafe braking on its new following vehicle.
- Parameters:
lane_index – the candidate lane for the change
- Returns:
whether the lane change should be performed
- class highway_env.vehicle.behavior.LinearVehicle(road: Road, position: ndarray | Sequence[float], heading: float = 0, speed: float = 0, target_lane_index: int | None = None, target_speed: float | None = None, route: List[Tuple[str, str, int]] | None = None, enable_lane_change: bool = True, timer: float | None = None, data: dict | None = None)[source]¶
A Vehicle whose longitudinal and lateral controllers are linear with respect to parameters.
- Parameters:
road – the road instance where the object is placed in
position – cartesian position of object in the surface
heading – the angle from positive direction of horizontal axis
speed – cartesian speed of object in the surface
- TIME_WANTED = 2.5¶
Desired time gap to the front vehicle.
- act(action: dict | str = None)[source]¶
Execute an action.
For now, no action is supported because the vehicle takes all decisions of acceleration and lane changes on its own, based on the IDM and MOBIL models.
- Parameters:
action – the action
- acceleration(ego_vehicle: ControlledVehicle, front_vehicle: Vehicle | None = None, rear_vehicle: Vehicle | None = None) float [source]¶
Compute an acceleration command with a Linear Model.
The acceleration is chosen so as to: - reach a target speed; - reach the speed of the leading (resp following) vehicle, if it is lower (resp higher) than ego’s; - maintain a minimum safety distance w.r.t the leading vehicle.
- Parameters:
ego_vehicle – the vehicle whose desired acceleration is to be computed. It does not have to be an Linear vehicle, which is why this method is a class method. This allows a Linear vehicle to reason about other vehicles behaviors even though they may not Linear.
front_vehicle – the vehicle preceding the ego-vehicle
rear_vehicle – the vehicle following the ego-vehicle
- Returns:
the acceleration command for the ego-vehicle [m/s2]
- steering_control(target_lane_index: Tuple[str, str, int]) float [source]¶
Linear controller with respect to parameters.
Overrides the non-linear controller ControlledVehicle.steering_control()
- Parameters:
target_lane_index – index of the lane to follow
- Returns:
a steering wheel angle command [rad]
- class highway_env.vehicle.behavior.AggressiveVehicle(road: Road, position: ndarray | Sequence[float], heading: float = 0, speed: float = 0, target_lane_index: int | None = None, target_speed: float | None = None, route: List[Tuple[str, str, int]] | None = None, enable_lane_change: bool = True, timer: float | None = None, data: dict | None = None)[source]¶
- Parameters:
road – the road instance where the object is placed in
position – cartesian position of object in the surface
heading – the angle from positive direction of horizontal axis
speed – cartesian speed of object in the surface
- class highway_env.vehicle.behavior.DefensiveVehicle(road: Road, position: ndarray | Sequence[float], heading: float = 0, speed: float = 0, target_lane_index: int | None = None, target_speed: float | None = None, route: List[Tuple[str, str, int]] | None = None, enable_lane_change: bool = True, timer: float | None = None, data: dict | None = None)[source]¶
- Parameters:
road – the road instance where the object is placed in
position – cartesian position of object in the surface
heading – the angle from positive direction of horizontal axis
speed – cartesian speed of object in the surface