Table of Contents

fastsim

Package containing modules for running FASTSim. For example usage, see

package_root

def package_root() -> Path

Returns the package root directory.

resources_root

def resources_root() -> Path

Returns the resources root directory.

fastsim.parameters

Global constants representing unit conversions that shourd never change, physical properties that should rarely change, and vehicle model parameters that can be modified by advanced users.

PhysicalProperties Objects

class PhysicalProperties(object)

Container class for physical constants that could change under certain special circumstances (e.g. high altitude or extreme weather)

copy_physical_properties

def copy_physical_properties(p: PhysicalProperties,
                             return_type: str = None,
                             deep: bool = True)

Returns copy of PhysicalProperties.

Arguments:

  • p - instantianed PhysicalProperties or RustPhysicalProperties return_type:
  • default - infer from type of p
  • 'dict' - dict
  • 'python' - PhysicalProperties
  • 'legacy' - LegacyPhysicalProperties -- NOT IMPLEMENTED YET; is it needed?
  • 'rust' - RustPhysicalProperties
  • deep - if True, uses deepcopy on everything

physical_properties_equal

def physical_properties_equal(a: PhysicalProperties,
                              b: PhysicalProperties) -> bool

Return True if the physical properties are equal by value

fc_perc_out_array

hardcoded ***

chg_eff

charger efficiency for PEVs, this should probably not be hard coded long term

fastsim.tests.test_rust

Tests using the Rust versions of SimDrive, Cycle, and Vehicle

TestRust Objects

class TestRust(unittest.TestCase)

test_discrepancies

def test_discrepancies(veh_type="ALL", use_dict=True, cyc_name="udds")

Function for testing for Rust/Python discrepancies, both in the vehicle database CSV as well as the individual model files. Uses test_vehicle_for_discrepancies as backend.

Arguments:

  • veh_type - type of vehicle to test for discrepancies can be "CONV", "HEV", "PHEV", "BEV", or "ALL"
  • use_dict - if True, use small cyc_dict to speed up test if false, default to UDDS
  • cyc_name - name of cycle from database to use if use_dict == False

test_vehicle_for_discrepancies

def test_vehicle_for_discrepancies(vnum=1,
                                   veh_filename=None,
                                   cyc_dict=None,
                                   cyc_name="udds")

Test for finding discrepancies between Rust and Python for single vehicle.

Arguments:

  • vnum - vehicle database number, optional, default option without any arguments
  • veh_filename - vehicle filename from vehdb folder, optional
  • cyc_dict - cycle dictionary for custom cycle, optional
  • cyc_name - cycle name from cycle database, optional

test_fueling_prediction_for_multiple_vehicle

def test_fueling_prediction_for_multiple_vehicle()

This test assures that Rust and Python agree on at least one example of all permutations of veh_pt_type and fc_eff_type.

fastsim.tests.test_simdrivelabel

fastsim.tests.test_vs_excel

Module for comparing python results with Excel by running all the vehicles in both Excel (uses archived results if Excel version not available) and Python FASTSim for both UDDS and HWFET cycles.

run

def run(vehicles=np.arange(1, 27), verbose=True, use_rust=False)

Runs python fastsim through 26 vehicles and returns list of dictionaries containing scenario descriptions.

Arguments:


verbose : Boolean if True, print progress

  • use_rust - Boolean, if True, use Rust versions of classes

run_excel

def run_excel(
        vehicles=np.arange(1, 28), prev_res_path=PREV_RES_PATH,
        rerun_excel=False)

Runs excel fastsim through 26 vehicles and returns list of dictionaries containing scenario descriptions.

Arguments:


prev_res_path : path (str) to prevous results in pickle (*.p) file rerun_excel : (Boolean) if True, re-runs Excel FASTSim, which must be open

compare

def compare(res_python, res_excel, err_tol=0.001, verbose=True)

Finds common vehicle names in both excel and python (hypothetically all of them, but there may be discrepancies) and then compares fuel economy results. Arguments: results from run_python and run_excel Returns dict of comparsion results.

Arguments:


res_python : output of run_python res_excel : output of run_excel err_tol : (float) error tolerance, default=1e-3 verbose : Boolean if True, print progress

main

def main(err_tol=0.001,
         prev_res_path=PREV_RES_PATH,
         rerun_excel=False,
         verbose=False)

Function for running both python and excel and then comparing

Arguments:


err_tol : (float) error tolerance, default=1e-3 prev_res_path : path (str) to prevous results in pickle (*.p) file rerun_excel : (Boolean) if True, re-runs Excel FASTSim, which must be open verbose : Boolean if True, print progress

TestExcel Objects

class TestExcel(unittest.TestCase)

test_vs_excel

def test_vs_excel()

Compares results against archived Excel results.

fastsim.tests.test_cycle

Test suite for cycle instantiation and manipulation.

calc_distance_traveled_m

def calc_distance_traveled_m(cyc, up_to=None)

Calculate the distance traveled in meters

  • cyc: a cycle dictionary
  • up_to: None or a positive number indicating a time in seconds. Will calculate the distance up-to that given time RETURN: Number, the distance traveled in meters

dicts_are_equal

def dicts_are_equal(d1, d2, d1_name=None, d2_name=None)

Checks if dictionaries are equal

  • d1: dict
  • d2: dict
  • d1_name: None or string, the name used for dict 1 in messaging
  • d2_name: None or string, the name used for dict 1 in messaging RETURN: (boolean, (Array string)), Returns (True, []) if the dictionaries are equal; otherwise, returns (False, [... list of issues here])

TestCycle Objects

class TestCycle(unittest.TestCase)

test_monotonicity

def test_monotonicity()

checks that time is monotonically increasing

test_load_dict

def test_load_dict()

checks that conversion from dict works

test_that_udds_has_18_microtrips

def test_that_udds_has_18_microtrips()

Check that the number of microtrips equals expected

test_roundtrip_of_microtrip_and_concat

def test_roundtrip_of_microtrip_and_concat()

A cycle split into microtrips and concatenated back together should equal the original

test_roundtrip_of_microtrip_and_concat_using_keep_name_arg

def test_roundtrip_of_microtrip_and_concat_using_keep_name_arg()

A cycle split into microtrips and concatenated back together should equal the original

test_set_from_dict_for_a_microtrip

def test_set_from_dict_for_a_microtrip()

Test splitting into microtrips and setting is as expected

test_duration_of_concatenated_cycles_is_the_sum_of_the_components

def test_duration_of_concatenated_cycles_is_the_sum_of_the_components()

Test that two cycles concatenated have the same duration as the sum of the constituents

test_cycle_equality

def test_cycle_equality()

Test structural equality of driving cycles

test_that_cycle_resampling_works_as_expected

def test_that_cycle_resampling_works_as_expected()

Test resampling the values of a cycle

test_resampling_and_concatenating_cycles

def test_resampling_and_concatenating_cycles()

Test that concatenating cycles at different sampling rates works as expected

test_resampling_with_hold_keys

def test_resampling_with_hold_keys()

Test that 'hold_keys' works with resampling

test_that_resampling_preserves_total_distance_traveled_using_rate_keys

def test_that_resampling_preserves_total_distance_traveled_using_rate_keys()

Distance traveled before and after resampling should be the same when rate_keys are used

test_clip_by_times

def test_clip_by_times()

Test that clipping by times works as expected

test_get_accelerations

def test_get_accelerations()

Test getting and processing accelerations

test_that_copy_creates_idential_structures

def test_that_copy_creates_idential_structures()

Checks that copy methods produce identical cycles

test_make_cycle

def test_make_cycle()

Check that make_cycle works as expected

test_key_conversion

def test_key_conversion()

check that legacy keys can still be generated

test_get_grade_by_distance

def test_get_grade_by_distance()

check that we can lookup grade by distance

test_dt_s_vs_dt_s_at_i

def test_dt_s_vs_dt_s_at_i()

Test that dt_s_at_i is a true replacement for dt_s[i]

test_trapz_step_start_distance

def test_trapz_step_start_distance()

Test the implementation of trapz_step_start_distance

test_that_cycle_cache_interp_grade_substitutes_for_average_grade_over_range

def test_that_cycle_cache_interp_grade_substitutes_for_average_grade_over_range(
)

Ensure that CycleCache.interp_grade actually predicts the same values as Cycle.average_grade_over_range(d, 0.0, cache=None|CycleCache) with and without using CycleCache

test_that_trapz_step_start_distance_equals_cache_trapz_distances

def test_that_trapz_step_start_distance_equals_cache_trapz_distances()

Test that cycle.trapz_step_start_distance(self.cyc0, i) == self._cyc0_cache.trapz_distances_m[i-1]

test_average_grade_over_range_with_and_without_cache

def test_average_grade_over_range_with_and_without_cache()

Ensure that CycleCache usage only speeds things up; doesn't change values...

fastsim.tests.test_coasting

Tests that check the drive cycle modification functionality.

make_coasting_plot

def make_coasting_plot(
        cyc0: fastsim.cycle.Cycle,
        cyc: fastsim.cycle.Cycle,
        use_mph: bool = False,
        title: Optional[str] = None,
        save_file: Optional[str] = None,
        do_show: bool = False,
        verbose: bool = False,
        gap_offset_m: float = 0.0,
        coast_brake_start_speed_m_per_s: Optional[float] = None)
  • cyc0: Cycle, the reference cycle (the "shadow trace" or "lead vehicle")
  • cyc: Cycle, the actual cycle driven
  • use_mph: Bool, if True, plot in miles per hour, else m/s
  • title: None or string, if string, set the title
  • save_file: (Or None string), if specified, save the file to disk
  • do_show: Bool, whether to show the file or not
  • verbose: Bool, if True, prints out
  • gap_offset_m: number, an offset to apply to the gap metrics (m)
  • coast_brake_start_speed_m_per_s: None | number, if supplied, plots the coast-start speed (m/s) RETURN: None
  • saves creates the given file and shows it

make_dvdd_plot

def make_dvdd_plot(cyc: fastsim.cycle.Cycle,
                   coast_to_break_speed_m__s: Union[float, None] = None,
                   use_mph: bool = False,
                   save_file: Union[None, str] = None,
                   do_show: bool = False,
                   curve_fit: bool = True,
                   additional_xs: Union[None, List[float]] = None,
                   additional_ys: Union[None, List[float]] = None)

Create a change in speed (dv) by change in distance (dd) plot

TestCoasting Objects

class TestCoasting(unittest.TestCase)

test_cycle_reported_distance_traveled_m

def test_cycle_reported_distance_traveled_m()

test_cycle_modifications_with_constant_jerk

def test_cycle_modifications_with_constant_jerk()

test_that_cycle_modifications_work_as_expected

def test_that_cycle_modifications_work_as_expected()

test_that_we_can_coast

def test_that_we_can_coast()

Test the standard interface to Eco-Approach for 'free coasting'

test_eco_approach_modeling

def test_eco_approach_modeling()

Test a simplified model of eco-approach

test_consistency_of_constant_jerk_trajectory

def test_consistency_of_constant_jerk_trajectory()

Confirm that acceleration, speed, and distances are as expected for constant jerk trajectory

test_that_final_speed_of_cycle_modification_matches_trajectory_calcs

def test_that_final_speed_of_cycle_modification_matches_trajectory_calcs()

test_that_cycle_distance_reported_is_correct

def test_that_cycle_distance_reported_is_correct()

Test the reported distances via cycDistMeters

test_brake_trajectory

def test_brake_trajectory()

test_logic_to_enter_eco_approach_automatically

def test_logic_to_enter_eco_approach_automatically()

Test that we can auto-enter eco-approach

test_that_coasting_works_going_uphill

def test_that_coasting_works_going_uphill()

Test coasting logic while hill climbing

test_that_coasting_logic_works_going_uphill

def test_that_coasting_logic_works_going_uphill()

When going uphill, we want to ensure we can still hit our coasting target

test_that_coasting_logic_works_going_downhill

def test_that_coasting_logic_works_going_downhill()

When going downhill, ensure we can still hit our coasting target

test_that_coasting_works_with_multiple_stops_and_grades

def test_that_coasting_works_with_multiple_stops_and_grades()

Ensure coasting hits distance target with multiple stops and both uphill/downhill

fastsim.tests.test_eco_cruise

Test the eco-cruise feature in FASTSim

fastsim.tests.test_vehicle

Test suite for cycle instantiation and manipulation.

TestVehicle Objects

class TestVehicle(unittest.TestCase)

test_equal

def test_equal()

Verify that a copied Vehicle and original are equal.

test_properties

def test_properties()

Verify that some of the property variables are working as expected.

test_fc_efficiency_override

def test_fc_efficiency_override()

Verify that we can scale FC

test_set_derived_init

def test_set_derived_init()

Verify that we can set derived parameters or not on init.

fastsim.tests.test_utils

fastsim.tests.test_following

Tests that check the drive cycle modification functionality.

TestFollowing Objects

class TestFollowing(unittest.TestCase)

test_that_we_have_a_gap_between_us_and_the_lead_vehicle

def test_that_we_have_a_gap_between_us_and_the_lead_vehicle()

A positive gap should exist between us and the lead vehicle

test_that_the_gap_changes_over_the_cycle

def test_that_the_gap_changes_over_the_cycle()

Ensure that our gap calculation is doing something

test_that_following_works_over_parameter_sweep

def test_that_following_works_over_parameter_sweep()

We're going to sweep through all of the parameters and see how it goes

test_that_we_can_use_the_idm

def test_that_we_can_use_the_idm()

Tests use of the IDM model for following

test_sweeping_idm_parameters

def test_sweeping_idm_parameters()

Tests use of the IDM model for following

test_distance_based_grade_on_following

def test_distance_based_grade_on_following()

Tests use of the IDM model for following

fastsim.tests

Package containing tests for FASTSim.

run_functional_tests

def run_functional_tests()

Runs all functional tests.

fastsim.tests.test_soc_correction

Tests an HEV correction methodology versus other techniques

TestSocCorrection Objects

class TestSocCorrection(unittest.TestCase)

test_that_soc_correction_method_works

def test_that_soc_correction_method_works()

Test using an SOC equivalency method versus other techniques

fastsim.tests.test_cav_sweep

Test fastsim/demos/cav_sweep.py for regressions

fastsim.tests.test_copy

Test various copy utilities

TestCopy Objects

class TestCopy(unittest.TestCase)

test_copy_cycle

def test_copy_cycle()

Test that cycle_copy works as expected

test_copy_physical_properties

def test_copy_physical_properties()

Test that copy_physical_properties works as expected

test_copy_vehicle

def test_copy_vehicle()

Test that vehicle_copy works as expected

test_copy_sim_params

def test_copy_sim_params()

Test that copy_sim_params works as expected

test_copy_sim_drive

def test_copy_sim_drive()

Test that copy_sim_drive works as expected

fastsim.tests.test_simdrive

Test suite for simdrive instantiation and usage.

TestSimDriveClassic Objects

class TestSimDriveClassic(unittest.TestCase)

Tests for fastsim.simdrive.SimDriveClassic methods

test_sim_drive_step

def test_sim_drive_step()

Verify that sim_drive_step produces an expected result.

test_sim_drive_walk

def test_sim_drive_walk()

Verify that sim_drive_walk produces an expected result.

fastsim.tests.test_auxiliaries

fastsim.tests.test_resources

Test getting resource lists via Rust API

TestListResources Objects

class TestListResources(unittest.TestCase)

test_list_resources_for_cycle

def test_list_resources_for_cycle()

check if list_resources works for RustCycle

test_list_resources_for_vehicles

def test_list_resources_for_vehicles()

check if list_resources works for RustVehicle

fastsim.tests.test_logging

fastsim.tests.test_simdrive_sweep

Test script that saves results from 26 vehicles currently in master branch of FASTSim as of 17 December 2019 for 3 standard cycles. From command line, pass True (default if left blank) or False argument to use JIT compilation or not, respectively.

main

def main(err_tol=1e-4, verbose=True, use_rust=False)

Runs test test for 26 vehicles and 3 cycles. Test compares cumulative positive and negative energy values to a benchmark from earlier.

Arguments:


err_tol : error tolerance default of 1e-4 was selected to prevent minor errors from showing. As of 31 December 2020, a recent python update caused errors that are smaller than this and therefore ok to neglect.

  • verbose - if True, prints progress
  • use_rust - Boolean, if True, use Rust version of classes, else python version

Returns:


df_err : pandas datafram, fractional errors df : pandas dataframe, new values df0 : pandas dataframe, original benchmark values

  • col_for_max_error - string or None, the column name of the column having max absolute error
  • max_abs_err - number or None, the maximum absolute error if it exists

TestSimDriveSweep Objects

class TestSimDriveSweep(unittest.TestCase)

test_sweep

def test_sweep()

Compares results against benchmark.

fastsim.vehicle

Module containing classes and methods for for loading vehicle data.

clean_data

def clean_data(raw_data)

Cleans up data formatting. Argument:

raw_data: cell of vehicle dataframe

Output: clean_data: cleaned up data

Vehicle Objects

@dataclass
class Vehicle(object)

Class for loading and contaning vehicle attributes See from_vehdb, from_file, and from_dict methods for usage instructions.

from_vehdb

@classmethod
def from_vehdb(cls,
               vnum: int,
               veh_file: str = None,
               to_rust: bool = False) -> Self

Load vehicle vnum from default vehdb or veh_file.

Arguments:

  • vnum - vehicle number
  • veh_file - path to vehicle database file
  • to_rust - if True, convert to rust-compatible vehicle

from_file

@classmethod
def from_file(cls,
              filename: str,
              vnum: int = None,
              to_rust: bool = False) -> Self

Loads vehicle from file filename (str). Looks in working dir and then fastsim/resources/vehdb, which also contains numerous examples of vehicle csv files. vnum is needed for multi-vehicle files.

Arguments:

  • filename - path to vehicle database file
  • vnum - vehicle number
  • to_rust - if True, convert to rust-compatible vehicle

from_df

@classmethod
def from_df(cls,
            vehdf: pd.DataFrame,
            vnum: int,
            veh_file: Path,
            to_rust: bool = False) -> Self

Given vehdf, generates dict to feed to from_dict.

Arguments:

  • vehdf - pandas dataframe of vehicle attributes
  • vnum - vehicle number
  • veh_file - path to vehicle database file
  • to_rust - if True, convert to rust-compatible vehicle

from_dict

@classmethod
def from_dict(cls, veh_dict: dict, to_rust: bool = False) -> Self

Load vehicle from dict with snake_case key names.

Arguments:

  • veh_dict - dict of vehicle attributes
  • to_rust - if True, convert to rust-compatible vehicle

__post_init__

def __post_init__(converted_to_rust: bool = False)

Sets derived parameters.

Arguments:


  • fc_peak_eff_override - float (0, 1) or -1, if provided and not -1, overrides engine peak efficiency with proportional scaling. Default of -1 has no effect.
  • mc_peak_eff_override - float (0, 1) or -1, if provided and not -1, overrides motor peak efficiency with proportional scaling. Default of -1 has no effect.

set_derived

def set_derived()

Sets derived parameters.

Arguments:


  • fc_peak_eff_override - float (0, 1) or -1, if provided and not -1, overrides engine peak efficiency with proportional scaling. Default of -1 has no effect.
  • mc_peak_eff_override - float (0, 1) or -1, if provided and not -1, overrides motor peak efficiency with proportional scaling. Default of -1 has no effect.

set_veh_mass

def set_veh_mass()

Calculate total vehicle mass. Sum up component masses if positive real number is not specified for self.veh_override_kg

veh_type_selection

@property
def veh_type_selection() -> str

Copying veh_pt_type to additional key to be consistent with Excel version but not used in Python version

get_mcPeakEff

def get_mcPeakEff() -> float

Return np.max(self.mc_eff_array)

set_mcPeakEff

def set_mcPeakEff(new_peak)

Set motor peak efficiency EVERYWHERE.

Arguments:


  • new_peak - float, new peak motor efficiency in decimal form

get_fcPeakEff

def get_fcPeakEff() -> float

Return np.max(self.fc_eff_array)

set_fcPeakEff

def set_fcPeakEff(new_peak)

Set fc peak efficiency EVERWHERE.

Arguments:


  • new_peak - float, new peak fc efficiency in decimal form

get_numba_veh

def get_numba_veh()

Deprecated.

to_rust

def to_rust() -> RustVehicle

Return a Rust version of the vehicle

reset_orphaned

def reset_orphaned()

Dummy method for flexibility between Rust/Python version interfaces

LegacyVehicle Objects

class LegacyVehicle(object)

Implementation of Vehicle with legacy keys.

__init__

def __init__(vehicle: Vehicle)

Given cycle, returns legacy cycle.

to_native_type

def to_native_type(value)

Attempts to map from numpy and other types to python native for better yaml (de-)serialization

copy_vehicle

def copy_vehicle(
    veh: Vehicle,
    return_type: str = None,
    deep: bool = True
) -> Dict[str, np.ndarray] | Vehicle | LegacyVehicle | RustVehicle

Returns copy of Vehicle.

Arguments:

  • veh - instantiated Vehicle or RustVehicle return_type:
  • 'dict' - dict
  • 'vehicle' - Vehicle
  • 'legacy' - LegacyVehicle
  • 'rust' - RustVehicle

veh_equal

def veh_equal(veh1: Vehicle, veh2: Vehicle, full_out: bool = False) -> bool

Given veh1 and veh2, which can be Vehicle and/or RustVehicle instances, return True if equal.

Arguments:


fastsim.auxiliaries

Auxiliary functions that require fastsim and provide faster access FASTSim vehicle properties.

R_air

J/(kg*K)

abc_to_drag_coeffs

def abc_to_drag_coeffs(veh: Vehicle,
                       a_lbf: float,
                       b_lbf__mph: float,
                       c_lbf__mph2: float,
                       custom_rho: bool = False,
                       custom_rho_temp_degC: float = 20.,
                       custom_rho_elevation_m: float = 180.,
                       simdrive_optimize: bool = True,
                       show_plots: bool = False,
                       use_rust=True) -> Tuple[float, float]

For a given vehicle and target A, B, and C coefficients; calculate and return drag and rolling resistance coefficients.

Arguments:


  • veh - vehicle.Vehicle with all parameters correct except for drag and rolling resistance coefficients a_lbf, b_lbf__mph, c_lbf__mph2: coastdown coefficients for road load [lbf] vs speed [mph]
  • custom_rho - if True, use fastsim.utilities.get_rho_air() to calculate the current ambient density
  • custom_rho_temp_degC - ambient temperature [degree C] for get_rho_air(); will only be used when custom_rho is True
  • custom_rho_elevation_m - location elevation [degree C] for get_rho_air(); will only be used when custom_rho is True; default value is elevation of Chicago, IL
  • simdrive_optimize - if True, use SimDrive to optimize the drag and rolling resistance; otherwise, directly use target A, B, C to calculate the results
  • show_plots - if True, plots are shown
  • use_rust - if True, use rust implementation of drag coefficient calculation.

drag_coeffs_to_abc

def drag_coeffs_to_abc(veh,
                       custom_rho: bool = False,
                       custom_rho_temp_degC: float = 20.,
                       custom_rho_elevation_m: float = 180.,
                       fit_with_curve: bool = False,
                       show_plots: bool = False) -> Tuple[float, float, float]

For a given vehicle mass, frontal area, dragCoef, and wheelRrCoef, calculate and return ABCs.

Arguments:


  • veh - vehicle.Vehicle with correct drag and rolling resistance
  • custom_rho - if True, use fastsim.utilities.get_rho_air() to calculate the current ambient density
  • custom_rho_temp_degC - ambient temperature [degree C] for get_rho_air(); will only be used when custom_rho is True
  • custom_rho_elevation_m - location elevation [degree C] for get_rho_air(); will only be used when custom_rho is True; default value is elevation of Chicago, IL
  • fit_with_curve - if True, use scipy.curve_fit to get A, B, Cs; otherwise, directly calculate A, B, Cs from given drag and rolling resistance
  • show_plots - if True, plots are shown

Returns:

a_lbf, b_lbf__mph, c_lbf__mph2: coastdown coefficients for road load [lbf] vs speed [mph]

fastsim.simdrive

Module containing classes and methods for simulating vehicle drive cycle.

SimDriveParams Objects

class SimDriveParams(object)

Class containing attributes used for configuring sim_drive. Usually the defaults are ok, and there will be no need to use this.

See comments in code for descriptions of various parameters that affect simulation behavior. If, for example, you want to suppress warning messages, use the following pastable code EXAMPLE:

import logging logging.getLogger("fastsim").setLevel(logging.DEBUG)

from_dict

@classmethod
def from_dict(cls, sdp_dict)

Create from a dictionary

__init__

def __init__()

Default values that affect simulation behavior. Can be modified after instantiation.

to_rust

def to_rust()

Change to the Rust version

reset_orphaned

def reset_orphaned()

Dummy method for flexibility between Rust/Python version interfaces

copy_sim_params

def copy_sim_params(sdp: SimDriveParams, return_type: str = None)

Returns copy of SimDriveParams.

Arguments:

  • sdp - instantianed SimDriveParams or RustSimDriveParams return_type:
  • default - infer from type of sdp
  • 'dict' - dict
  • 'python' - SimDriveParams
  • 'rust' - RustSimDriveParams
  • deep - if True, uses deepcopy on everything

sim_params_equal

def sim_params_equal(a: SimDriveParams, b: SimDriveParams) -> bool

Returns True if objects are structurally equal (i.e., equal by value), else false.

Arguments:

  • a - instantiated SimDriveParams object
  • b - instantiated SimDriveParams object

SimDrive Objects

class SimDrive(object)

Class containing methods for running FASTSim vehicle fuel economy simulations. This class is not compiled and will run slower for large batch runs.

Arguments:


  • cyc - cycle.Cycle instance
  • veh - vehicle.Vehicle instance

__init__

def __init__(cyc: cycle.Cycle, veh: vehicle.Vehicle)

Initalizes arrays, given vehicle.Vehicle() and cycle.Cycle() as arguments. sim_params is needed only if non-default behavior is desired.

gap_to_lead_vehicle_m

@property
def gap_to_lead_vehicle_m()

Provides the gap-with lead vehicle from start to finish

sim_drive

def sim_drive(init_soc: Optional[float] = None,
              aux_in_kw_override: Optional[np.ndarray] = None)

Initialize and run sim_drive_walk as appropriate for vehicle attribute vehPtType. Arguments

init_soc: initial SOC for electrified vehicles.
aux_in_kw: aux_in_kw override. Array of same length as cyc.time_s.
Default of None causes veh.aux_kw to be used.

init_for_step

def init_for_step(init_soc: float,
                  aux_in_kw_override: Optional[np.ndarray] = None)

This is a specialty method which should be called prior to using sim_drive_step in a loop.

Arguments

init_soc: initial battery state-of-charge (SOC) for electrified vehicles aux_in_kw: aux_in_kw override. Array of same length as cyc.time_s.
Default of None causes veh.aux_kw to be used.

sim_drive_walk

def sim_drive_walk(init_soc: float,
                   aux_in_kw_override: Optional[np.ndarray] = None)

Receives second-by-second cycle information, vehicle properties, and an initial state of charge and runs sim_drive_step to perform a backward facing powertrain simulation. Method 'sim_drive' runs this iteratively to achieve correct SOC initial and final conditions, as needed.

Arguments

init_soc: initial battery state-of-charge (SOC) for electrified vehicles aux_in_kw: aux_in_kw override. Array of same length as cyc.time_s.
Default of None causes veh.aux_kw to be used.

activate_eco_cruise

def activate_eco_cruise(by_microtrip: bool = False,
                        extend_fraction: float = 0.1,
                        blend_factor: float = 0.0,
                        min_target_speed_m_per_s: float = 8.0)

Sets the intelligent driver model parameters for an eco-cruise driving trajectory. This is a convenience method instead of setting the sim_params.idm* parameters yourself.

  • by_microtrip: bool, if True, target speed is set by microtrip, else by cycle
  • extend_fraction: float, the fraction of time to extend the cycle to allow for catch-up of the following vehicle
  • blend_factor: float, a value between 0 and 1; only used of by_microtrip is True, blends between microtrip average speed and microtrip average speed when moving. Must be between 0 and 1 inclusive

sim_drive_step

def sim_drive_step()

Step through 1 time step. TODO: create self.set_speed_for_target_gap(self.i): TODO: consider implementing for battery SOC dependence

solve_step

def solve_step(i)

Perform all the calculations to solve 1 time step.

set_misc_calcs

def set_misc_calcs(i)

Sets misc. calculations at time step 'i'

Arguments:


  • i - index of time step

set_comp_lims

def set_comp_lims(i)

Sets component limits for time step 'i' Arguments

i: index of time step init_soc: initial SOC for electrified vehicles

set_power_calcs

def set_power_calcs(i)

Calculate power requirements to meet cycle and determine if cycle can be met.
Arguments

i: index of time step

set_ach_speed

def set_ach_speed(i)

Calculate actual speed achieved if vehicle hardware cannot achieve trace speed. Arguments

i: index of time step

set_hybrid_cont_calcs

def set_hybrid_cont_calcs(i)

Hybrid control calculations. Arguments

i: index of time step

set_fc_forced_state

def set_fc_forced_state(i)

Calculate control variables related to engine on/off state Arguments

i: index of time step

set_hybrid_cont_decisions

def set_hybrid_cont_decisions(i)

Hybrid control decisions. Arguments

i: index of time step

set_fc_power

def set_fc_power(i)

Sets fcKwOutAch and fcKwInAch. Arguments

i: index of time step

set_post_scalars

def set_post_scalars()

Sets scalar variables that can be calculated after a cycle is run. This includes mpgge, various energy metrics, and others

to_rust

def to_rust()

Create a rust version of SimDrive

copy_sim_drive

def copy_sim_drive(sd: SimDrive,
                   return_type: str = None,
                   deep: bool = True) -> SimDrive

Returns copy of SimDriveClassic or SimDriveJit as SimDriveClassic.

Arguments:


  • sd - instantiated SimDriveClassic or SimDriveJit return_type:
  • default - infer from type of sd
  • 'python' - Cycle
  • 'legacy' - LegacyCycle
  • 'rust' - RustCycle
  • deep - if True, uses deepcopy on everything

sim_drive_equal

def sim_drive_equal(a: SimDrive, b: SimDrive) -> bool

run_simdrive_for_accel_test

def run_simdrive_for_accel_test(sd: SimDrive)

Initialize and run sim_drive_walk as appropriate for vehicle attribute vehPtType.

SimDrivePost Objects

class SimDrivePost(object)

Class for post-processing of SimDrive instance. Requires already-run SimDrive instance.

__init__

def __init__(sim_drive: SimDrive)

Arguments:


  • sim_drive - solved sim_drive object

get_diagnostics

def get_diagnostics()

This method is to be run after runing sim_drive if diagnostic variables are needed. Diagnostic variables are returned in a dict. Diagnostic variables include:

  • final integrated value of all positive powers
  • final integrated value of all negative powers
  • total distance traveled
  • miles per gallon gasoline equivalent (mpgge)

set_battery_wear

def set_battery_wear()

Battery wear calcs

SimDriveJit

def SimDriveJit(cyc_jit, veh_jit)

deprecated

estimate_soc_corrected_fuel_kJ

def estimate_soc_corrected_fuel_kJ(sd: SimDrive) -> float
  • sd: SimDriveClassic, the simdrive instance after simulation RETURN: number, the kJ of fuel corrected for SOC imbalance

fastsim.cycle

Module containing classes and methods for cycle data.

CycleCache Objects

class CycleCache()

interp_grade

def interp_grade(dist: float)

Interpolate the single-point grade at the given distance. Assumes that the grade at i applies from sample point (i-1, i]

interp_elevation

def interp_elevation(dist: float)

Interpolate the elevation at the given distance

Cycle Objects

@dataclass
class Cycle(object)

Object for containing time, speed, road grade, and road charging vectors for drive cycle. Instantiate with the from_file or from_dict method.

from_file

@classmethod
def from_file(cls, filename: str) -> Self

Load cycle from filename (str). Can be absolute or relative path. If relative, looks in working dir first and then in fastsim/resources/cycles.

File must contain columns for: -- cycSecs or time_s -- cycMps or mps -- cycGrade or grade (optional) -- cycRoadType or road_type (optional)

from_dict

@classmethod
def from_dict(cls, cyc_dict: dict) -> Self

Load cycle from dict, which must contain keys for: -- cycSecs or time_s -- cycMps or mps -- cycGrade or grade (optional) -- cycRoadType or road_type (optional)

get_numba_cyc

def get_numba_cyc()

Deprecated.

build_cache

def build_cache() -> CycleCache

Calculates a dataclass containing expensive-to-calculate items. The data created can persist between calls and optionally be passed into methods that can use it which will result in a performance enhancement. RETURN: CycleCache

dt_s_at_i

def dt_s_at_i(i: int) -> float

Calculate the time-step duration for time-step i. Returns: the time-step duration in seconds

delta_elev_m

@property
def delta_elev_m() -> np.ndarray

Cumulative elevation change w.r.t. to initial

__len__

def __len__() -> int

return cycle length

to_dict

def to_dict() -> Dict[str, np.ndarray]

Returns cycle as dict rather than class instance.

reset_orphaned

def reset_orphaned()

Dummy method for flexibility between Rust/Python version interfaces

copy

def copy() -> Self

Return a copy of this Cycle instance.

average_grade_over_range

def average_grade_over_range(distance_start_m,
                             delta_distance_m,
                             cache: Optional[CycleCache] = None)

Returns the average grade over the given range of distances

  • distance_start_m: non-negative-number, the distance at start of evaluation area (m)
  • delta_distance_m: non-negative-number, the distance traveled from distance_start_m (m) RETURN: number, the average grade (rise over run) over the given distance range Note: grade is assumed to be constant from just after the previous sample point until the current sample point. That is, grade[i] applies over the range of distances, d, from (d[i - 1], d[i]]

calc_distance_to_next_stop_from

def calc_distance_to_next_stop_from(distance_m: float,
                                    cache: Optional[CycleCache] = None
                                    ) -> float

Calculate the distance to next stop from distance_m

  • distance_m: non-negative-number, the current distance from start (m) RETURN: returns the distance to the next stop from distance_m NOTE: distance may be negative if we're beyond the last stop

modify_by_const_jerk_trajectory

def modify_by_const_jerk_trajectory(idx, n, jerk_m__s3, accel0_m__s2)

Modifies the cycle using the given constant-jerk trajectory parameters

  • idx: non-negative integer, the point in the cycle to initiate modification (note: THIS point is modified since trajectory should be calculated from idx-1)
  • jerk_m__s3: number, the "Jerk" associated with the trajectory (m/s3)
  • accel0_m__s2: number, the initial acceleration (m/s2) NOTE:
  • modifies cyc in place to hit any critical rendezvous_points by a trajectory adjustment
  • CAUTION: NOT ROBUST AGAINST VARIABLE DURATION TIME-STEPS RETURN: Number, final modified speed (m/s)

modify_with_braking_trajectory

def modify_with_braking_trajectory(brake_accel_m__s2: float,
                                   idx: int,
                                   dts_m: Optional[float] = None) -> tuple

Add a braking trajectory that would cover the same distance as the given constant brake deceleration

  • brake_accel_m__s2: negative number, the braking acceleration (m/s2)
  • idx: non-negative integer, the index where to initiate the stop trajectory, start of the step (i in FASTSim)
  • dts_m: None | float: if given, this is the desired distance-to-stop in meters. If not given, it is calculated based on braking deceleration. RETURN: (non-negative-number, positive-integer)
  • the final speed of the modified trajectory (m/s)
  • the number of time-steps required to complete the braking maneuver NOTE:
  • modifies the cycle in place for the braking trajectory

LegacyCycle Objects

class LegacyCycle(object)

Implementation of Cycle with legacy keys.

__init__

def __init__(cycle: Cycle)

Given cycle, returns legacy cycle.

cyc_equal

def cyc_equal(a: Cycle, b: Cycle) -> bool

Return True if a and b are equal

to_microtrips

def to_microtrips(cycle, stop_speed_m__s=1e-6, keep_name=False)

Split a cycle into an array of microtrips with one microtrip being a start to subsequent stop plus any idle (stopped time).

Arguments:


  • cycle - drive cycle converted to dictionary by cycle.to_dict()
  • stop_speed_m__s - speed at which vehicle is considered stopped for trip separation
  • keep_name - (optional) bool, if True and cycle contains "name", adds that name to all microtrips

make_cycle

def make_cycle(ts, vs, gs=None, rs=None) -> dict

(Array Num) (Array Num) (Array Num)? -> Dict Create a cycle from times, speeds, and grades. If grades is not specified, it is set to zero.

Arguments:


  • ts - array of times [s]
  • vs - array of vehicle speeds [mps]
  • gs - array of grades
  • rs - array of road types (charging or not)

equals

def equals(c1, c2) -> bool

Dict Dict -> Bool Returns true if the two cycles are equal, false otherwise

Arguments:


  • c1 - cycle as dictionary from to_dict()
  • c2 - cycle as dictionary from to_dict()

concat

def concat(cycles, name=None)

Concatenates cycles together one after another into a single dictionary (Array Dict) String -> Dict

Arguments:


  • cycles - (Array Dict)
  • name - (optional) string or None, if a string, adds the "name" key to the output

resample

def resample(cycle: Dict[str, Any],
             new_dt: Optional[float] = None,
             start_time: Optional[float] = None,
             end_time: Optional[float] = None,
             hold_keys: Optional[Set[str]] = None,
             hold_keys_next: Optional[Set[str]] = None,
             rate_keys: Optional[Set[str]] = None)

Cycle new_dt=?Real start_time=?Real end_time=?Real -> Cycle Resample a cycle with a new delta time from start time to end time.

  • cycle: Dict with keys 'time_s': numpy.array Real giving the elapsed time
  • new_dt: Real, optional the new delta time of the sampling. Defaults to the difference between the first two times of the cycle passed in
  • start_time: Real, optional the start time of the sample. Defaults to 0.0 seconds
  • end_time: Real, optional the end time of the cycle. Defaults to the last time of the passed in cycle.
  • hold_keys: None or (Set String), if specified, yields values that should be interpolated step-wise, holding their value until an explicit change (i.e., NOT interpolated)
  • hold_keys_next: None or (Set String), similar to hold_keys but yields values that should be interpolated step-wise, taking the NEXT value as the value (vs hold_keys which uses the previous)
  • rate_keys: None or (Set String), if specified, yields values that maintain the interpolated value of the given rate. So, for example, if a speed, will set the speed such that the distance traveled is consistent. Note: using rate keys for mps may result in non-zero starting and ending speeds Resamples all non-time metrics by the new sample time.

clip_by_times

def clip_by_times(cycle, t_end, t_start=0)

Cycle Number Number -> Cycle INPUT:

  • cycle: Dict, a legitimate driving cycle
  • t_start: Number, time to start
  • t_end: Number, time to end RETURNS: Dict, the cycle with fields snipped to times >= t_start and <= t_end Clip the cycle to the given times and return

accelerations

def accelerations(cycle)

Cycle -> Real Return the acceleration of the given cycle INPUTS:

  • cycle: Dict, a legitimate driving cycle OUTPUTS: Real, the maximum acceleration

peak_acceleration

def peak_acceleration(cycle)

Cycle -> Real Return the maximum acceleration of the given cycle INPUTS:

  • cycle: Dict, a legitimate driving cycle OUTPUTS: Real, the maximum acceleration

peak_deceleration

def peak_deceleration(cycle)

Cycle -> Real Return the minimum acceleration (maximum deceleration) of the given cycle INPUTS:

  • cycle: Dict, a legitimate driving cycle OUTPUTS: Real, the maximum acceleration

calc_constant_jerk_trajectory

def calc_constant_jerk_trajectory(n: int, D0: float, v0: float, Dr: float,
                                  vr: float, dt: float) -> tuple

Num Num Num Num Num Int -> (Tuple 'jerk_m__s3': Num, 'accel_m__s2': Num) INPUTS:

  • n: Int, number of time-steps away from rendezvous
  • D0: Num, distance of simulated vehicle (m/s)
  • v0: Num, speed of simulated vehicle (m/s)
  • Dr: Num, distance of rendezvous point (m)
  • vr: Num, speed of rendezvous point (m/s)
  • dt: Num, step duration (s) RETURNS: (Tuple 'jerk_m__s3': Num, 'accel_m__s2': Num) Returns the constant jerk and acceleration for initial time step.

accel_for_constant_jerk

def accel_for_constant_jerk(n, a0, k, dt)

Calculate the acceleration n timesteps away INPUTS:

  • n: Int, number of times steps away to calculate
  • a0: Num, initial acceleration (m/s2)
  • k: Num, constant jerk (m/s3)
  • dt: Num, time-step duration in seconds NOTE:
  • this is the constant acceleration over the time-step from sample n to sample n+1 RETURN: Num, the acceleration n timesteps away (m/s2)

speed_for_constant_jerk

def speed_for_constant_jerk(n, v0, a0, k, dt)

Int Num Num Num Num -> Num Calculate speed (m/s) n timesteps away INPUTS:

  • n: Int, numer of timesteps away to calculate
  • v0: Num, initial speed (m/s)
  • a0: Num, initial acceleration (m/s2)
  • k: Num, constant jerk
  • dt: Num, duration of a timestep (s) NOTE:
  • this is the speed at sample n
  • if n == 0, speed is v0
  • if n == 1, speed is v0 + a0*dt, etc. RETURN: Num, the speed n timesteps away (m/s)

dist_for_constant_jerk

def dist_for_constant_jerk(n, d0, v0, a0, k, dt)

Calculate distance (m) after n timesteps INPUTS:

  • n: Int, numer of timesteps away to calculate
  • d0: Num, initial distance (m)
  • v0: Num, initial speed (m/s)
  • a0: Num, initial acceleration (m/s2)
  • k: Num, constant jerk
  • dt: Num, duration of a timestep (s) NOTE:
  • this is the distance traveled from start (i.e., n=0) measured at sample point n RETURN: Num, the distance at n timesteps away (m)

detect_passing

def detect_passing(cyc: Cycle,
                   cyc0: Cycle,
                   i: int,
                   dist_tol_m: float = 0.1) -> PassingInfo

Reports back information of the first point where cyc passes cyc0, starting at step i until the next stop of cyc.

  • cyc: fastsim.Cycle, the proposed cycle of the vehicle under simulation
  • cyc0: fastsim.Cycle, the reference/lead vehicle/shadow cycle to compare with
  • i: int, the time-step index to consider
  • dist_tol_m: float, the distance tolerance away from lead vehicle to be seen as "deviated" from the reference/shadow trace (m) RETURNS: PassingInfo

average_step_speeds

def average_step_speeds(cyc: Cycle) -> np.ndarray

Calculate the average speed per each step in m/s

average_step_speed_at

def average_step_speed_at(cyc: Cycle, i: int) -> float

Calculate the average step speed at step i in m/s (i.e., from sample point i-1 to i)

trapz_step_distances

def trapz_step_distances(cyc: Cycle) -> np.ndarray

Sum of the distance traveled over each step using trapezoidal integration

trapz_step_start_distance

def trapz_step_start_distance(cyc: Cycle, i: int) -> float

The distance traveled from start at the beginning of step i (i.e., distance traveled up to sample point i-1) Distance is in meters.

trapz_distance_for_step

def trapz_distance_for_step(cyc: Cycle, i: int) -> float

The distance traveled during step i in meters (i.e., from sample point i-1 to i)

trapz_distance_over_range

def trapz_distance_over_range(cyc: Cycle, i_start: int, i_end: int) -> float

Calculate the distance from step i_start to the start of step i_end (i.e., distance from sample point i_start-1 to i_end-1)

extend_cycle

def extend_cycle(cyc: Cycle,
                 absolute_time_s: float = 0.0,
                 time_fraction: float = 0.0,
                 use_rust: bool = False) -> Cycle
  • cyc: fastsim.cycle.Cycle
  • absolute_time_s: float, the seconds to extend
  • time_fraction: float, the fraction of the original cycle time to add on
  • use_rust: bool, if True, return a RustCycle instance, else a normal Python Cycle RETURNS: fastsim.cycle.Cycle (or fastsimrust.RustCycle), the new cycle with stopped time appended NOTE: additional time is rounded to the nearest second

create_dist_and_target_speeds_by_microtrip

def create_dist_and_target_speeds_by_microtrip(
        cyc: Cycle,
        blend_factor: float = 0.0,
        min_target_speed_mps: float = 8.0) -> list

Create distance and target speeds by microtrip This helper function splits a cycle up into microtrips and returns a list of 2-tuples of: (distance from start in meters, target speed in meters/second)

  • cyc: the cycle to operate on
  • blend_factor: float, from 0 to 1 if 0, use average speed of the microtrip if 1, use average speed while moving (i.e., no stopped time) else something in between
  • min_target_speed_mps: float, the minimum target speed allowed (m/s) RETURN: list of 2-tuple of (float, float) representing the distance of start of each microtrip and target speed for that microtrip NOTE: target speed per microtrip is not allowed to be below min_target_speed_mps

copy_cycle

def copy_cycle(
    cyc: Cycle,
    return_type: str = None,
    deep: bool = True
) -> Dict[str, np.ndarray] | Cycle | LegacyCycle | RustCycle

Returns copy of Cycle.

Arguments:

  • cyc - instantianed Cycle or CycleJit return_type:
  • default - infer from type of cyc
  • 'dict' - dict
  • 'python' - Cycle
  • 'legacy' - LegacyCycle
  • 'rust' - RustCycle
  • deep - if True, uses deepcopy on everything

fastsim.resample

resample

def resample(df: pd.DataFrame,
             dt_new: Optional[float] = 1.0,
             time_col: Optional[str] = "Time[s]",
             rate_vars: Optional[Tuple[str]] = [],
             hold_vars: Optional[Tuple[str]] = []) -> pd.DataFrame

Resamples dataframe df.

Arguments:

  • df: dataframe to resample
  • dt_new: new time step size, default 1.0 s
  • time_col: column for time in s
  • rate_vars: list of variables that represent rates that need to be time averaged
  • hold_vars: vars that need zero-order hold from previous nearest time step (e.g. quantized variables like current gear)

fastsim.demos.demo_abc_drag_coef_conv

fastsim.demos.cav_sweep

ABSOLUTE_EXTENDED_TIME_S

180.0

make_debug_plot

def make_debug_plot(sd: fastsim.simdrive.SimDrive,
                    save_file: Optional[str] = None,
                    do_show: bool = False)

load_cycle

def load_cycle(cyc_name: str, use_rust: bool = False) -> fastsim.cycle.Cycle

Load the given cycle and return

main

def main(cycle_name=None,
         powertrain=None,
         do_show=None,
         use_rust=False,
         verbose=True,
         save_dir=None,
         maneuver=None)

fastsim.demos.stop_start_demo

fastsim.demos.fusion_thermal_cal_post

save_path

seems to be best

fastsim.demos.2017_Ford_F150_thermal_val

lhv_fuel_btu_per_lbm

from "2012FordFusionV6Overview V5.pdf"

fastsim.demos.calibration_demo

Script for demonstrating how to calibrate a vehicle model. See FASTSim Calibration/Validation documentation for more info on how to use this.

lhv_fuel_btu_per_lbm

from "2012FordFusionV6Overview V5.pdf"

load_data

def load_data() -> Dict[str, pd.DataFrame]

Loads dyno test data from csv files 61811011, 61811012, 61811013, and 61811014 downloaded from https://www.anl.gov/taps/d3-2018-toyota-camry-xle

Returns:

Dict[str, pd.DataFrame]: dictionary of dataframes

get_cal_and_val_objs

def get_cal_and_val_objs(dfs: Dict[str, pd.DataFrame] = load_data()) -> Tuple[
        fsim.cal.ModelObjectives, fsim.cal.ModelObjectives, List[Tuple[
            float, float]]]

Returns objects to be used by PyMOO optimizer

Arguments:

  • dfs Dict[str, pd.DataFrame] - output of load_data

Returns:

Tuple[fsim.cal.ModelObjectives, fsim.cal.ModelObjectives, List[Tuple[float, float]]]: description

fastsim.demos.cav_demo

fastsim.demos

fastsim.demos.test_demos

fastsim.demos.accel_demo

create_accel_cyc

def create_accel_cyc(length_in_seconds=300, spd_mph=89.48, grade=0.0, hz=10)

Create a synthetic Drive Cycle for acceleration targeting. Defaults to a 15 second acceleration cycle. Should be adjusted based on target acceleration time and initial vehicle acceleration time, so that time isn't wasted on cycles that are needlessly long.

spd_mph @ 89.48 FASTSim XL version mph default speed for acceleration cycles grade @ 0 and hz @ 10 also matches XL version settings

main

def main()

Arguments:


fastsim.demos.fusion_thermal_demo

fastsim.demos.time_dilation_demo

fastsim.demos.vehicle_import_demo

Vehicle Import Demonstration This module demonstrates the vehicle import API

other_inputs

None -> calculate from EPA data

fastsim.demos.fusion_thermal_cal

lhv_fuel_btu_per_lbm

from "2012FordFusionV6Overview V5.pdf"

fastsim.demos.wltc_calibration

WILLANS_FACTOR

gCO2/MJ

E10_HEAT_VALUE

kWh/L

fastsim.demos.demo

v2

should not have derived params

data_path

path to drive cycles

veh

load vehicle using name

fastsim.demos.demo_eu_vehicle_wltp

fastsim.demos.timing_demo

fastsim.simdrivelabel

Module containing classes and methods for calculating label fuel economy.

get_label_fe

def get_label_fe(veh: vehicle.Vehicle,
                 full_detail: bool = False,
                 verbose: bool = False,
                 chg_eff: float = None,
                 use_rust=False)

Generates label fuel economy (FE) values for a provided vehicle.

Arguments:


veh : vehicle.Vehicle() full_detail : boolean, default False If True, sim_drive objects for each cycle are also returned. verbose : boolean, default false If true, print out key results chg_eff : float between 0 and 1 Override for chg_eff -- currently not functional

  • use_rust - bool, if True, use rust version of classes, else Python

    Returns label fuel economy values as a dict and (optionally) simdrive.SimDriveClassic objects.

fastsim.vehicle_base

Boiler plate stuff needed for vehicle.py

fastsim.inspect_utils

Utilities to assist with object introspection.

isprop

def isprop(attr) -> bool

Checks if instance attribute is a property.

isfunc

def isfunc(attr) -> bool

Checks if instance attribute is method.

get_attrs

def get_attrs(instance)

Given an instantiated object, returns attributes that are not: -- callable
-- special (i.e. start with __)
-- properties

fastsim.calibration

get_error_val

def get_error_val(model: npt.NDArray[np.float64],
                  test: npt.NDArray[np.float64],
                  time_steps: npt.NDArray[np.float64]) -> float

Returns time-averaged error for model and test signal.

Arguments:

  • model npt.NDArray[np.float64] - array of values for signal from model
  • test npt.NDArray[np.float64] - array of values for signal from test data
  • time_steps npt.NDArray[np.float64] - array (or scalar for constant) of values for model time steps [s]

Returns:

  • float - integral of absolute value of difference between model and test per time

ModelObjectives Objects

@dataclass
class ModelObjectives(object)

Class for calculating eco-driving objectives

get_errors

def get_errors(
    sim_drives: Dict[str, fsr.RustSimDrive | fsr.SimDriveHot],
    return_mods: bool = False,
    plot: bool = False,
    plot_save_dir: Optional[str] = None,
    plot_perc_err: bool = False,
    show: bool = False,
    fontsize: float = 12,
    plotly: bool = False
) -> Union[
        Dict[str, Dict[str, float]],
        # or if return_mods is True
        Tuple[Dict[str, fsim.simdrive.SimDrive], Dict[str, Dict[str, float]]]]

Calculate model errors w.r.t. test data for each element in dfs/models for each objective.

Arguments:

  • sim_drives Dict[str, fsr.RustSimDrive | fsr.SimDriveHot] - dictionary with user-defined keys and SimDrive or SimDriveHot instances
  • return_mods bool, optional - if true, also returns dict of solved models. Defaults to False.
  • plot bool, optional - if true, plots objectives using matplotlib.pyplot. Defaults to False.
  • plot_save_dir Optional[str], optional - directory in which to save plots. If None, plots are not saved. Defaults to None.
  • plot_perc_err bool, optional - whether to include % error axes in plots. Defaults to False.
  • show bool, optional - whether to show matplotlib.pyplot plots. Defaults to False.
  • fontsize float, optional - plot font size. Defaults to 12.
  • plotly bool, optional - whether to generate plotly plots, which can be opened manually in a browser window. Defaults to False.

Returns:

Objectives and optionally solved models

update_params

def update_params(xs: List[Any])

Updates model parameters based on x, which must match length of self.params

get_parser

def get_parser(
        def_description: str = "Program for calibrating fastsim models.",
        def_p: int = 4,
        def_n_max_gen: int = 500,
        def_pop_size: int = 12,
        def_save_path: Optional[str] = "pymoo_res") -> argparse.ArgumentParser

Generate parser for optimization hyper params and misc. other params

Arguments:

  • def_p int, optional - default number of processes. Defaults to 4.
  • def_n_max_gen int, optional - max allowed generations. Defaults to 500.
  • def_pop_size int, optional - default population size. Defaults to 12.
  • def_save_path str, optional - default save path. Defaults to pymoo_res.

Returns:

  • argparse.ArgumentParser - description

fastsim.utils.vehicle_import_preproc

Module for pre-processing data from fueleconomy.gov and EPA vehicle testing that is used for "vehicle import" functionality. Vehicle import allows FASTSim to import vehicles by specifying make, model, and year. See fastsim.demos.vehicle_import_demo for usage.

In order to run this pre-processing script, the data from the sources below should be placed in the "input_dir" (see the run function).

fueleconomy.gov data: https://www.fueleconomy.gov/feg/download.shtml

  • vehicles.csv
  • emissions.csv

EPA Test data: https://www.epa.gov/compliance-and-fuel-economy-data/data-cars-used-testing-fuel-economy

  • the data for emissions by year; e.g., 20tstcar-2021-03-02.xlsx
  • note: there are multiple formats in use

process_csv

def process_csv(path: Path, fn)

write_csvs_for_each_year

def write_csvs_for_each_year(output_data_dir, basename, rows_by_year, header)

sort_fueleconomygov_data_by_year

def sort_fueleconomygov_data_by_year(input_data_dir: Path,
                                     output_data_dir: Path)

Opens up the vehicles.csv and emissions.csv and breaks them up to be by year and saves them again.

xlsx_to_csv

def xlsx_to_csv(xlsx_path, csv_path)

process_epa_test_data

def process_epa_test_data(input_dir, output_dir)

create_zip_archives_by_year

def create_zip_archives_by_year(files_dir, zip_dir)

Takes files in the files_dir that start with \d\d\d\d-*.csv and adds them to a \d\d\d\d.zip in the zip_dir

fastsim.utils.utilities

Various optional utilities that may support some applications of FASTSim.

R_air

J/(kg*K)

get_rho_air

def get_rho_air(temperature_degC, elevation_m=180)

Returns air density [kg/m**3] for given elevation and temperature. Source: https://www.grc.nasa.gov/WWW/K-12/rocket/atmosmet.html

Arguments:


temperature_degC : ambient temperature [°C] elevation_m : elevation above sea level [m]. Default 180 m is for Chicago, IL

l__100km_to_mpg

def l__100km_to_mpg(l__100km)

Given fuel economy in L/100km, returns mpg.

mpg_to_l__100km

def mpg_to_l__100km(mpg)

Given fuel economy in mpg, returns L/100km.

rollav

def rollav(x, y, width=10)

Returns x-weighted backward-looking rolling average of y. Good for resampling data that needs to preserve cumulative information.

Arguments:


x : x data y : y data (len(y) == len(x) must be True)

  • width - rolling average width

camel_to_snake

def camel_to_snake(name)

Given camelCase, returns snake_case.

set_log_level

def set_log_level(level: str | int) -> int

Sets logging level for both Python and Rust FASTSim. The default logging level is WARNING (30). https://docs.python.org/3/library/logging.html#logging-levels

Parameters

level: str | int Logging level to set. str level name or int logging level

=========== ================
Level       Numeric value
=========== ================
CRITICAL    50
ERROR       40
WARNING     30
INFO        20
DEBUG       10
NOTSET      0

Returns

int Previous log level

disable_logging

def disable_logging() -> int

Disable FASTSim logs from being shown by setting log level to CRITICAL+1 (51).

Returns

int Previous log level

enable_logging

def enable_logging(level: Optional[int | str] = None)

Re-enable FASTSim logging, optionally to a specified log level, otherwise to the default WARNING (30) level.

Parameters

level: str | int, optional Logging level to set. str level name or int logging level. See utils.set_log_level() docstring for more details on logging levels.

suppress_logging

@contextmanager
def suppress_logging()

Disable, then re-enable FASTSim logging using a context manager. The log level is returned to its previous value. Logging is re-enabled even if the nested code throws an error.

Example:

with fastsim.utils.suppress_logging():
    ...  # do stuff with logging suppressed

get_containers_with_path

def get_containers_with_path(struct: Any, path: str | list) -> list

Get all attributes containers from nested struct using path to attribute.

Parameters

struct: Any Outermost struct where first name in path is an attribute path: str | list Dot-separated path, e.g. "sd.veh.drag_coef" or ["sd", "veh", "drag_coef"]

Returns

List[Any] Ordered list of containers, from outermost to innermost

get_attr_with_path

def get_attr_with_path(struct: Any, path: str | list) -> Any

Get attribute from nested struct using path to attribute.

Parameters

struct: Any Outermost struct where first name in path is an attribute path: str | list Dot-separated path, e.g. "sd.veh.drag_coef" or ["sd", "veh", "drag_coef"]

Returns

Any Requested attribute

set_attr_with_path

def set_attr_with_path(struct: Any, path: str | list, value: Any) -> Any

Set attribute on nested struct using path to attribute.

Parameters

struct: Any Outermost struct where first name in path is an attribute path: str | list Dot-separated path, e.g. "sd.veh.drag_coef" or ["sd", "veh", "drag_coef"] value: Any

Returns

Any struct with nested value set

set_attrs_with_path

def set_attrs_with_path(struct: Any, paths_and_values: Dict[str, Any]) -> Any

Set multiple attributes on nested struct using path: value pairs.

Parameters

struct: Any Outermost struct where first name in path is an attribute paths_and_values: Dict[str | list, Any] Mapping of dot-separated path (e.g. sd.veh.drag_coef or ["sd", "veh", "drag_coef"]) to values (e.g. 0.32)

Returns

Any struct with nested values set

calculate_tire_radius

def calculate_tire_radius(tire_code: str, units: str = "m")

Calculate tire radius from ISO tire code, with variable units

Unit options: "m", "cm", "mm", "ft", "in". Default is "m".

Examples:

fastsim.utils.calculate_tire_radius("P205/60R16") 0.3262 fastsim.utils.calculate_tire_radius("225/70Rx19.5G", units="in") 15.950787401574804

show_plots

def show_plots() -> bool

Returns true if plots should be displayed

do_tests

def do_tests() -> bool

Returns true if plots should be displayed

copy_demo_files

def copy_demo_files(path_for_copies: Path = Path("demos"))

Copies demo files from demos folder into specified local directory

Arguments

  • - path_for_copies: path to copy files into (relative or absolute in)

Warning

Running this function will overwrite existing files with the same name in the specified directory, so make sure any files with changes you'd like to keep are renamed.

fastsim.utils