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].

\[\begin{split}\dot{v} &= a\left[1-\left(\frac{v}{v_0}\right)^\delta - \left(\frac{d^*}{d}\right)^2\right] \\ d^* &= d_0 + Tv + \frac{v\Delta v}{2\sqrt{ab}} \\\end{split}\]

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

  • \(\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):

\[\tilde{a}_n \geq - b_\text{safe};\]
  • there is an incentive (for the ego-vehicle and possibly its followers):

\[\underbrace{\tilde{a}_c - a_c}_{\text{ego-vehicle}} + p\left(\underbrace{\tilde{a}_n - a_n}_{\text{new follower}} + \underbrace{\tilde{a}_o - a_o}_{\text{old follower}}\right) \geq \Delta a_\text{th},\]

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: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = 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.

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.

POLITENESS = 0.0
LANE_CHANGE_MIN_ACC_GAIN = 0.2
LANE_CHANGE_MAX_BRAKING_IMPOSED = 2.0
LANE_CHANGE_DELAY = 1.0
__init__(road: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = None)[source]

Initialize self. See help(type(self)) for accurate signature.

randomize_behavior()[source]
classmethod create_from(vehicle: highway_env.vehicle.controller.ControlledVehicle) → highway_env.vehicle.behavior.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: Union[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: highway_env.vehicle.controller.ControlledVehicle, front_vehicle: highway_env.vehicle.kinematics.Vehicle = None, rear_vehicle: highway_env.vehicle.kinematics.Vehicle = 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: highway_env.vehicle.kinematics.Vehicle, front_vehicle: highway_env.vehicle.kinematics.Vehicle = None) → 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

Returns

the desired distance between the two [m]

maximum_speed(front_vehicle: highway_env.vehicle.kinematics.Vehicle = None) → Tuple[float, float][source]

Compute the maximum allowed speed to avoid Inevitable Collision States.

Assume the front vehicle is going to brake at full deceleration and that it will be noticed after a given delay, and compute the maximum speed which allows the ego-vehicle to brake enough to avoid the collision.

Parameters

front_vehicle – the preceding vehicle

Returns

the maximum allowed speed, and suggested acceleration

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

recover_from_stop(acceleration: float) → float[source]

If stopped on the wrong lane, try a reversing maneuver.

Parameters

acceleration – desired acceleration from IDM

Returns

suggested acceleration to recover from being stuck

__module__ = 'highway_env.vehicle.behavior'
target_speed = None
class highway_env.vehicle.behavior.LinearVehicle(road: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = None, data: dict = None)[source]

A Vehicle whose longitudinal and lateral controllers are linear with respect to parameters.

ACCELERATION_PARAMETERS = [0.3, 0.3, 2.0]
STEERING_PARAMETERS = [5.0, 8.333333333333332]
ACCELERATION_RANGE = array([[0.15, 0.15, 1. ], [0.45, 0.45, 3. ]])
STEERING_RANGE = array([[4.93 , 6.83333333], [5.07 , 9.83333333]])
TIME_WANTED = 2.5
__init__(road: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = None, data: dict = None)[source]

Initialize self. See help(type(self)) for accurate signature.

act(action: Union[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

randomize_behavior()[source]
acceleration(ego_vehicle: highway_env.vehicle.controller.ControlledVehicle, front_vehicle: highway_env.vehicle.kinematics.Vehicle = None, rear_vehicle: highway_env.vehicle.kinematics.Vehicle = 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]

acceleration_features(ego_vehicle: highway_env.vehicle.controller.ControlledVehicle, front_vehicle: highway_env.vehicle.kinematics.Vehicle = None, rear_vehicle: highway_env.vehicle.kinematics.Vehicle = None) → numpy.ndarray[source]
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]

steering_features(target_lane_index: Tuple[str, str, int]) → numpy.ndarray[source]

A collection of features used to follow a lane

Parameters

target_lane_index – index of the lane to follow

Returns

a array of features

longitudinal_structure()[source]
lateral_structure()[source]
collect_data()[source]

Store features and outputs for parameter regression.

add_features(data, lane_index, output_lane=None)[source]
__module__ = 'highway_env.vehicle.behavior'
target_speed = None
class highway_env.vehicle.behavior.AggressiveVehicle(road: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = None, data: dict = None)[source]
LANE_CHANGE_MIN_ACC_GAIN = 1.0
MERGE_ACC_GAIN = 0.8
MERGE_VEL_RATIO = 0.75
MERGE_TARGET_VEL = 30
ACCELERATION_PARAMETERS = [0.10666666666666667, 0.035555555555555556, 0.5]
__module__ = 'highway_env.vehicle.behavior'
target_speed = None
class highway_env.vehicle.behavior.DefensiveVehicle(road: highway_env.road.road.Road, position: Union[numpy.ndarray, Sequence[float]], heading: float = 0, speed: float = 0, target_lane_index: int = None, target_speed: float = None, route: List[Tuple[str, str, int]] = None, enable_lane_change: bool = True, timer: float = None, data: dict = None)[source]
__module__ = 'highway_env.vehicle.behavior'
target_speed = None
LANE_CHANGE_MIN_ACC_GAIN = 1.0
MERGE_ACC_GAIN = 1.2
MERGE_VEL_RATIO = 0.75
MERGE_TARGET_VEL = 30
ACCELERATION_PARAMETERS = [0.16, 0.05333333333333333, 2.0]