# 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:

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: Optional[int] = None, target_speed: Optional[float] = None, route: Optional[List[Tuple[str, str, int]]] = None, enable_lane_change: bool = True, timer: Optional[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.

DELTA_RANGE = [3.5, 4.5]

Range of delta when chosen randomly.

classmethod create_from(vehicle: highway_env.vehicle.controller.ControlledVehicle) [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: Optional[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: Optional[highway_env.vehicle.kinematics.Vehicle] = None, rear_vehicle: Optional[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: Optional[highway_env.vehicle.kinematics.Vehicle] = 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

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

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: Optional[int] = None, target_speed: Optional[float] = None, route: Optional[List[Tuple[str, str, int]]] = None, enable_lane_change: bool = True, timer: Optional[float] = None, data: Optional[dict] = None)[source]

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

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

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

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

collect_data()[source]

Store features and outputs for parameter regression.

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: Optional[int] = None, target_speed: Optional[float] = None, route: Optional[List[Tuple[str, str, int]]] = None, enable_lane_change: bool = True, timer: Optional[float] = None, data: Optional[dict] = None)[source]
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: Optional[int] = None, target_speed: Optional[float] = None, route: Optional[List[Tuple[str, str, int]]] = None, enable_lane_change: bool = True, timer: Optional[float] = None, data: Optional[dict] = None)[source]