Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

CAVS: Intro to Maneuvers

The Maneuver struct applies Connected Automated Vehicle (CAV) maneuvers to a drive cycle and returns the modified cycle. This demo walks through the core Maneuver workflow.

import os

import matplotlib.pyplot as plt
import seaborn as sns

import fastsim as fsim
sns.set_theme()

SHOW_PLOTS = os.environ.get("SHOW_PLOTS", "true").lower() == "true"

Creating a Maneuver

Maneuver.create_from creates a Maneuver from a cycle and vehicle. It copies chassis data from the vehicle and solver settings from SimParams defaults.

veh = fsim.Vehicle.from_resource("2012_Ford_Fusion.yaml")
veh.set_save_interval(1)

cyc = fsim.Cycle.from_resource("udds.csv")
cyc0 = cyc.copy()

man = fsim.Maneuver.create_from(cyc, veh.copy())

Inspecting and Modifying Parameters

to_pydict() serializes the Maneuver to a Python dictionary. Parameters can be modified in the dictionary and then loaded back with Maneuver.from_pydict().

The Maneuver struct has two groups of configurable parameters:

Coasting (coast_*): controls whether and how coasting is applied to the cycle.

IDM (idm_*): Intelligent Driver Model, Adaptive Cruise Control version.

d = man.to_pydict()

print("Coasting parameters:")
for k in sorted(d):
    if k.startswith("coast"):
        print(f"  {k}: {d[k]}")

print("\nIDM parameters:")
for k in sorted(d):
    if k.startswith("idm"):
        print(f"  {k}: {d[k]}")
Coasting parameters:
  coast_allow: False
  coast_allow_passing: False
  coast_brake_accel_meters_per_second_squared: -2.5
  coast_brake_start_speed_meters_per_second: 8.9408
  coast_delay_index: [0, 0]
  coast_max_speed_meters_per_second: 40.0
  coast_start_speed_meters_per_second: 0.0
  coast_time_horizon_for_adjustment_seconds: 20.0

IDM parameters:
  idm_acceleration_meters_per_second_squared: 1.0
  idm_allow: False
  idm_deceleration_meters_per_second_squared: 1.5
  idm_delta: 4.0
  idm_desired_speed_by_distance: None
  idm_desired_speed_meters_per_second: 33.528
  idm_headway_seconds: 1.0
  idm_minimum_gap_meters: 2.0
  idm_target_speed_m_per_s: [0.0, 0.0]

Applying Maneuvers

Enable coasting and call apply_maneuvers() to get a modified cycle. The returned Cycle can then be passed to SimDrive for simulation.

d["coast_allow"] = True
d["coast_start_speed_meters_per_second"] = 15.0
man = fsim.Maneuver.from_pydict(d)

cyc_modified = man.apply_maneuvers()

Comparing Original and Modified Cycles

The modified cycle deviates from the original where coasting is applied.

if SHOW_PLOTS:
    c0 = cyc0.to_pydict()
    cm = cyc_modified.to_pydict()

    fig, ax = plt.subplots(figsize=(10, 4))
    ax.plot(c0["time_seconds"], c0["speed_meters_per_second"], label="Original")
    ax.plot(cm["time_seconds"], cm["speed_meters_per_second"], linestyle="--", label="Modified")
    ax.set_xlabel("Time [s]")
    ax.set_ylabel("Speed [m/s]")
    ax.set_title("Original vs. Modified Cycle")
    ax.legend()
    plt.tight_layout()
    plt.show()
<Figure size 1000x400 with 1 Axes>

Simulating with the Modified Cycle

sd = fsim.SimDrive(veh, cyc_modified)
sd.walk()
if SHOW_PLOTS:
    df = sd.to_dataframe()

    fig, ax = plt.subplots(figsize=(10, 4))
    ax.plot(c0["time_seconds"], c0["speed_meters_per_second"], label="Original Cycle")
    ax.plot(
        df["cyc.time_seconds"],
        df["veh.history.speed_ach_meters_per_second"],
        linestyle="--",
        label="Achieved Speed",
    )
    ax.set_xlabel("Time [s]")
    ax.set_ylabel("Speed [m/s]")
    ax.set_title("Achieved Speed with Coasting Maneuver")
    ax.legend()
    plt.tight_layout()
    plt.show()
<Figure size 1000x400 with 1 Axes>

Source: fastsim/docs/demo_scripts/vehicle_controls/demo_maneuver_intro.py