Description
This is the fastsim-3 version of NREL's FASTSim.
It introduces numerous new enhancements and features, including:
- ~10x faster! -- when setting
save_intervaltoNone, which means only the state at the last time step, which includes fuel consumption and/or battery depletion, among other useful cumulative state variables. - Roughly ~60% reduction in memory consumption (~160 mb in
fastsim-2v. 60 mb infastsim-3 - object-oriented, hierarchical model structure
- ability to control granularity of time-resolved data -- e.g. save at every time step, save at every _n_th time step, or never save at all (saving only cumulative trip-level results)
- component-specific vehicle models -- i.e. the conventional vehicle contains only data for the fuel
converter and other relevant components but does contain any dummy battery or motor parameters as
is the case in
fastsim-2 - file formats that are more robust and more human readable
- backwards compatibility with
fastsim-2 - flexible data structures to allow for future model types
- ability to simulate standalone component models
- flexible model interfacing (e.g. multiple folder/file formats for reading and/or writing data)
- more accurate interpolation methods
Installation
Python
Set up and activate a python environment (compatible with Python 3.8 - 3.10; we recommend Python 3.10) with the following steps.
Anaconda
- Create:
conda create -n fastsim python=3.10 - Activate:
conda activate fastsim
venv
There is some variation based on your Operating System:
-
PowerShell (windows):
- Create:
python -m venv fastsim-venv-- name is user decision - Activate:
fastsim-venv/Scripts/Activate.ps1
- Create:
-
Bash (i.e. unix/linux/mac):
- Create:
python -m venv fastsim-venv-- name is user decision - Activate:
source fastsim-venv/bin/activate
- Create:
-
Command Prompt (windows):
- Create:
python -m venv fastsim-venv-- name is user decision - Activate:
fastsim-venv/Scripts/activate.bat
- Create:
Pixi (recommended for developers)
pixi shell -e dev-- this creates the environment, installs all the dependencies, builds fastsim, and activates the environment
FASTSim-3
Via PyPI
In an active Python environment created above, run pip install fastsim.
Building from Scratch
Developers might want to install the code in place so that FASTSim files can be editable (the -e flag for
pip provides this behavior). This option can be handy since FASTSim will be installed in place from the
installation location and any updates will be propagated each time FASTSim is freshly imported. To do
this, you'll need to have the Rust toolchain installed.
- Option 1: run
sh build_and_test.shin root folder. - Option 2:
- Run
pip install -e ".[dev]"
Optional testing steps: - Run
cargo test - Run
pytest -v python/fastsim/tests/
- Run
Contributors
Chad Baker -- Chad.Baker@nrel.gov
Aaron Brooker -- Aaron.Brooker@nrel.gov
Kyle Carow -- Kyle.Carow@nrel.gov
Jeffrey Gonder -- Jeff.Gonder@nrel.gov
Jacob Holden -- Jacob.Holden@nrel.gov
Jinghu Hu -- Jinghu.Hu@nrel.gov
Jason Lustbader -- Jason.Lustbader@nrel.gov
Sean Lopp -- sean@rstudio.com
Matthew Moniot -- Matthew.Moniot@nrel.gov
Grant Payne -- Grant.Payne@nrel.gov
Laurie Ramroth -- lramroth@ford.com
Eric Wood -- Eric.Wood@nrel.gov
Robin Steuteville -- Robin.Steuteville@nrel.gov
About this book
This is the overall FASTSim documentation. We're working toward making this a fully integrated document that includes both the Python API and Rust core documentation for the fastsim-2 branch and eventually also for the fastsim-3 branch.
Documentation
Python
Rust
Developers
Table of Contents
- fastsim
- fastsim.utils.utilities
- fastsim.utils
- fastsim.copy_stub_docstrings
- fastsim.pymoo_api
- fastsim.tests.test_speedup
- fastsim.tests.test_serde
- fastsim.tests.test_utils
- fastsim.tests.test_resources
- fastsim.demos.demo_hev
- fastsim.demos.test_demos
- fastsim.demos.plot_utils
- fastsim.demos.demo_bev_thrml_sweep
- fastsim.demos.demo_bev_thrml_ws_ca
- fastsim.demos.demo_trace_miss
- fastsim.demos.demo_bev
- fastsim.demos.demo_hev_thrml_ws_ca
- fastsim.demos.demo_bev_thrml_ws_wa
- fastsim.demos.demo_hev_thrml_ws_wa
- fastsim.demos.demo_bev_thrml_cs_ca
- fastsim.demos.demo_cavs
- fastsim.demos.demo_hev_thrml_cs_ca
- fastsim.demos.demo_conv
- fastsim.demos
fastsim
Python API for fastsim
check_version_gte_311
def check_version_gte_311() -> bool
Return true if python version is greater than or equal to 3.11
package_root
def package_root() -> Path
Return the package root directory.
resources_root
def resources_root() -> Path
Return the resources root directory.
cyc_keys
def cyc_keys() -> list[str]
Return cycle keys
to_pydict
def to_pydict(self, data_fmt: str = "msg_pack", flatten: bool = False) -> dict
Return self converted to pure python dictionary with no nested Rust objects
Arguments
- -
flatten: if True, returns dict without any hierarchy - -
data_fmt: data format for intermediate conversion step
get_hist_len
def get_hist_len(obj: dict) -> int | None
Find nested history and gets lenth of first element
get_flattened
def get_flattened(obj: dict | list,
hist_len: int,
prepend_str: str = "") -> dict
Flatten and return dictionary, separating keys and indices with a "."
Arguments
- obj: object to flatten
- hist_len: length of any lists storing history data
- prepend_str: prepend this to all keys in the returned flat dict
from_pydict
@classmethod
def from_pydict(cls,
pydict: dict,
data_fmt: str = "msg_pack",
skip_init: bool = False) -> Self
Instantiate Self from pure python dictionary
Arguments
- -
pydict: dictionary to be converted to FASTSim object - -
data_fmt: data format for intermediate conversion step - -
skip_init: passed toSerdeAPImethods to control whether initialization is skipped
to_dataframe
def to_dataframe(self,
pandas: bool = False,
allow_partial: bool = False) -> pd.DataFrame | pl.DataFrame
Return time series results from fastsim object as a Polars or Pandas dataframe.
Arguments
- -
pandas: returns pandas dataframe if True; otherwise, returns polars dataframe by default - -
allow_partial: tries to return dataframe of length equal to solved time steps if simulation fails early
fastsim.utils.utilities
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
fastsim.copy_stub_docstrings
fastsim.pymoo_api
Module containing functions and classes for easy interaction with PyMOO
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.
Args:
model: array of values for signal from modeltest: array of values for signal from test datatime_steps: array (or scalar for constant) of values for model time steps [s]
Returns:
error: integral of absolute value of difference between model and test per time
ModelObjectives Objects
@dataclass
class ModelObjectives()
Class for calculating eco-driving objectives
Attributes/Fields
models(Dict[str, Dict]): dictionary of model dicts to be simulateddfs(Dict[str, pd.DataFrame]): dictionary of dataframes from test data corresponding tomodelsobj_fns(Tuple[Callable] | Tuple[Tuple[Callable, Callable]]): Tuple of functions for extracting objective signal values for either minimizing a scalar metric (e.g. fuel economy) or minimizing error relative to test data.- minimizing error in fuel consumption relative to test data
obj_fns = ( ( # model -- note, `lambda` only works for single thread lambda sd_dict: sd_dict['veh']['pt_type']['Conventional']['fc']['history']['energy_fuel_joules'], # test data lambda df: df['fuel_flow_gps'] * ... (conversion factors to get to same unit), ), # note that this trailing comma ensures `obj_fns` is interpreted as a tuple ) - minimizing fuel consumption
obj_fns = ( ( # note that a trailing comma ensures `obj_fns` is interpreted as tuple lambda sd_dict: sd_dict['veh']['pt_type']['Conventional']['fc']['state']['energy_fuel_joules'], ) )
- minimizing error in fuel consumption relative to test data
param_fns_and_boundsTuple[Tuple[Callable], Tuple[Tuple[float, float]]]: tuple containing functions to modify parameters and bounds for optimizer Exampledef new_peak_res_eff (sd_dict, new_peak_eff) -> Dict: sd_dict['veh']['pt_type']['HybridElectricVehicle']['res']['peak_eff'] = new_peak_eff return sd_dict ... param_fns_and_bounds = ( (new_peak_res_eff, (100.0, 200.0)), )verbose(bool): print more stuff or not
update_params
def update_params(xs: list[Any])
Updates model parameters based on x, which must match length of self.param_fns
get_errors
def get_errors(
sim_drives: dict[str, fsim.SimDrive],
return_mods: bool = False
) -> (tuple[dict[str, list[float]], dict[str, list[float]]]
| tuple[
dict[str, list[float]],
dict[str, list[float]],
dict[str, fsim.SimDrive | Any],
dict[str, fsim.SimDrive | Any],
])
Calculate model errors w.r.t. test data for each element in dfs/models for each objective.
Args:
sim_drives: dictionary with user-defined keys and SimDrive instancesreturn_mods: if true, also returns dict of solved models. Defaults to False.
Returns:
Objectives and optionally solved models
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) -> argparse.ArgumentParser
Generate parser for optimization hyper params and misc. other params
Args:
def_p: default number of processesdef_n_max_gen: max allowed generationsdef_pop_size: default population size
Returns:
argparse.ArgumentParser: description
fastsim.tests.test_speedup
fastsim.tests.test_serde
fastsim.tests.test_utils
fastsim.tests.test_resources
Test getting resource lists via Rust API
test_list_resources_for_cycle
def test_list_resources_for_cycle()
Assert list_resources works for Cycle
test_list_resources_for_vehicle
def test_list_resources_for_vehicle()
Assert list_resources works for Vehicle
fastsim.demos.demo_hev
Hybrid electric vehicle demo showcasing FASTSim-3 simulation capabilities.
plot_road_loads_comparison
def plot_road_loads_comparison() -> tuple[Figure, Axes]
Plot comparison of fastsim-3 v. fastsim-2 road loads
plot_fc_pwr
def plot_fc_pwr() -> tuple[Figure, Axes]
Plot fuel converter powers
plot_fc_energy
def plot_fc_energy() -> tuple[Figure, Axes]
Plot fuel converter energies
plot_res_pwr
def plot_res_pwr() -> tuple[Figure, Axes]
Plot reversible energy storage powers
plot_res_energy
def plot_res_energy() -> tuple[Figure, Axes]
Plot reversible energy storage energies
fastsim.demos.test_demos
Test suite for FASTSim demo scripts to ensure they run without errors.
demo_paths
def demo_paths()
Get list of all demo script paths.
test_demo
@pytest.mark.parametrize("demo_path",
demo_paths(),
ids=[dp.name for dp in demo_paths()])
def test_demo(demo_path: Path)
Test that each demo script runs successfully without errors.
fastsim.demos.plot_utils
Plotting utilities for FASTSim demo scripts.
get_paired_cycler
def get_paired_cycler(pair_attr: str = DEF_PAIR_ATTR)
Return a cycler for setting style in paired plots
Arguments:
pair_attr: whether the paired lines should match in"color"or"linestyle"
get_uni_cycler
def get_uni_cycler(pair_attr: str = DEF_PAIR_ATTR)
Get a uniform cycler for plotting.
Arguments:
pair_attr: ensures consistent behavior withget_paired_cycler
plot_bev_temperatures
def plot_bev_temperatures(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot BEV component temperatures over time.
plot_bev_hvac_pwr
def plot_bev_hvac_pwr(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot BEV HVAC power consumption over time.
plot_bev_res_pwr
def plot_bev_res_pwr(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot BEV reversible energy storage power over time.
plot_bev_res_energy
def plot_bev_res_energy(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot BEV reversible energy storage energy over time.
plot_road_loads
def plot_road_loads(df: pd.DataFrame, veh: fsim.Vehicle, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot vehicle road loads over time.
plot_hev_temperatures
def plot_hev_temperatures(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot HEV component temperatures including battery, engine, and cabin.
plot_hev_fc_pwr
def plot_hev_fc_pwr(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot HEV fuel converter powers
plot_hev_fc_energy
def plot_hev_fc_energy(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot HEV fuel converter energy consumption over time.
plot_hev_res_pwr
def plot_hev_res_pwr(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot HEV reversible energy storage power including electrical and thermal.
plot_hev_res_energy
def plot_hev_res_energy(df: pd.DataFrame, save_figs: bool,
show_plots: bool) -> tuple[Figure, Axes]
Plot HEV reversible energy storage energy including electrical and thermal.
fastsim.demos.demo_bev_thrml_sweep
BEV thermal demo with cold start and cold ambient conditions.
try_walk
def try_walk(sd: fsim.SimDrive, loc: str) -> None
Wrap walk in try to enable context
setup_sweep
def setup_sweep() -> pd.DataFrame
Set up sweep of ambient and initial conditions
sweep
def sweep(df: pd.DataFrame,
n_proc: int | None) -> tuple[pd.DataFrame, pd.DataFrame]
Sweep ambient and initial conditions
Arguments:
- df: dataframe of DOE
- n_proc: number of parallel processes
solve_row
def solve_row(iterrow: tuple[Hashable, pd.Series]) -> dict[str, Any]
Solve row of dataframe and return result
plot_time_series
def plot_time_series(df: pd.DataFrame,
verbose: bool = False,
show_plots: bool = False,
save_figs: bool = False) -> None
Plot time series temperature data
plot_sweep
def plot_sweep(df: pd.DataFrame,
cyc: str,
x_var: str,
par_var_sweep: list[float],
show_plots: bool = False,
save_figs: bool = False) -> tuple[plt.Figure, plt.Axes]
Plot sweep of ambient and initial temperatures, parameteric style
plot_sweep_cross_effects
def plot_sweep_cross_effects(
df: pd.DataFrame,
cyc: str,
x_var: str,
par_var_sweep: list[float],
show_plots: bool = False,
save_figs: bool = False) -> tuple[plt.Figure, plt.Axes]
Plot sweep of ambient and initial temperatures, parameteric style
print_cross_delta
def print_cross_delta(df: pd.DataFrame, cycle: str, fixed_var: str) -> None
Print percent increase in ECR for one variable when the other is fixed between 22C and 24C
fastsim.demos.demo_bev_thrml_ws_ca
BEV thermal demo with warm start and cold ambient conditions.
fastsim.demos.demo_trace_miss
A module that demonstrates trace-miss correction.
trace_miss_demo
def trace_miss_demo()
Run a vehicle over a cycle with a trace miss + correction
fastsim.demos.demo_bev
BEV demo showcasing FASTSim-3 vehicle simulation and plotting capabilities.
plot_res_pwr
def plot_res_pwr() -> tuple[Figure, Axes]
Plot reversible energy storage powers
plot_res_energy
def plot_res_energy() -> tuple[Figure, Axes]
Plot reversible energy storage energies
plot_road_loads_comparison
def plot_road_loads_comparison() -> tuple[Figure, Axes]
Plot comparison of fastsim-3 v. fastsim-2 road loads
test_this_file
def test_this_file()
To trigger automated testing
fastsim.demos.demo_hev_thrml_ws_ca
HEV thermal demo with warm start and cold ambient conditions.
fastsim.demos.demo_bev_thrml_ws_wa
BEV thermal demo with warm start and warm ambient conditions.
fastsim.demos.demo_hev_thrml_ws_wa
HEV thermal demo with warm start and warm ambient conditions.
fastsim.demos.demo_bev_thrml_cs_ca
BEV thermal demo with cold start and cold ambient conditions.
fastsim.demos.demo_cavs
Demonstration of Connected Automated Vehicle (CAV) Functionality in FASTSim
This module demonstrates:
- cycle manipulation utilities
- eco-approach: utilizing vehicle coasting to conserve fuel use
- eco-cruise: use of trajectories to remove unnecessary accelerations
microtrip_demo
def microtrip_demo()
Run a demonstration of cycle manipulation utilities
plot_speed_by_time
def plot_speed_by_time(df,
c0,
is_coast=None,
save_interval=1,
title=None,
with_elevation=False)
Plot speed by time
plot_speed_by_dist
def plot_speed_by_dist(df,
c0,
is_coast=None,
save_interval=1,
title=None,
with_elevation=False)
Plot speed by distance
setup_models
def setup_models(cyc_file="udds.csv", veh_file="2012_Ford_Fusion.yaml")
Set up and return cycle and vehicle models
basic_coasting_demo
def basic_coasting_demo()
Demonstrate coasting starting from a given speed
advanced_coasting_demo
def advanced_coasting_demo()
Demonstrate coasting starting from a given speed
basic_cruise_demo
def basic_cruise_demo()
Demonstrate basic Eco-Cruise usage
cruise_and_coast_demo
def cruise_and_coast_demo()
Demonstrate both cruise and coast
coast_with_grade_demo
def coast_with_grade_demo()
Coasting in the presence of grade
fastsim.demos.demo_hev_thrml_cs_ca
HEV thermal demo with cold start and cold ambient conditions.
fastsim.demos.demo_conv
Conventional vehicle demo showcasing FASTSim-3 simulation capabilities.
plot_fc_pwr
def plot_fc_pwr() -> tuple[Figure, Axes]
Plot fuel converter powers
plot_fc_energy
def plot_fc_energy() -> tuple[Figure, Axes]
Plot fuel converter energies
plot_road_loads_comparison
def plot_road_loads_comparison() -> tuple[Figure, Axes]
Plot comparison of fastsim-3 v. fastsim-2 road loads
fastsim.demos
Rust Documentation
How to compile/test Rust code
cargo build
cargo build will not compile when run in /rust due to problems compiling /rust/fastsim-py.
cargo build should compile when run in the /rust/fastsim-core.
cargo test
cargo test should compile when run in /rust because there are no tests in /rust/fastsim-py.
build_and_test.sh
Running sh build_and_test.sh from the root fastsim directory compile/tests the Rust code, and tests the Python code. It should compile without errors.
Releasing
Incrementing the Version Number
Increment the 3rd decimal place in the version number for small changes (e.g. minor bug fixes, new variables), the 2nd for medium changes (e.g. new methods or classes), and the 1st for large changes (e.g. changes to the interface that might affect backwards compatibility / the API interface).
Instructions
- Create and check out a new branch, e.g. for version X.X.X:
git checkout -b fastsim-X.X.X - Update the version number in the
pyproject.tomlfile - If changes have happened in
rust/, increment the Rust crate version numbers inrust/fastsim-core/Cargo.tomlandrust/fastsim-core/fastsim-proc-macros/Cargo.toml - Commit changes, as appropriate:
git add pyproject.toml README.md rust/fastsim-core/Cargo.toml rust/fastsim-core/fastsim-proc-macros/Cargo.tomlgit commit -m "vX.X.X" - Tag the commit with the new version number, prepended with a
v:
Or, optionally, you can also add a tag message with thegit tag vX.X.X-mflag, for example:git tag vX.X.X -m "release version X.X.X" - Push the commit to the GitHub.com repository (for Git remote setup instructions, see this page):
git push -u external fastsim-X.X.X - Push the tag:
This will start thegit push external vX.X.Xwheels.yamlGitHub Actions workflow and run all tests - Create a PR for the new version in the external repository, using the
releaselabel for organization - When all tests pass, and a review has been completed, merge the PR
- If changes were made in
rust/, publish the crates (you must be listed as an owner of both crates on crates.io):
If necessary, log into crates.io first after adding and verifying your email at https://crates.io/settings/profile:
Then, run these commands to update the crates (order matters):cargo login(cd rust/fastsim-core/fastsim-proc-macros && cargo publish) (cd rust/fastsim-core && cargo publish) - Start a new release at https://github.com/NREL/fastsim/releases/new, selecting
vX.X.Xas both the tag and the release name. Click "Generate release notes" to automatically create a detailed change log. - Click "Publish release". Wheels will then be built for various platforms and automatically uploaded to the PyPI at https://pypi.org/project/fastsim/. Check that the release workflow finished properly at https://github.com/NREL/fastsim/actions/workflows/release.yaml!
- Synchronize changes to the internal GitHub repository:
git pull external fastsim-2 git push origin fastsim-2
Calibration and Validation of Vehicle Models
FASTSim powertrain models can have varying levels of calibration and resolution based on available calibration and validation data. In the simplest (US) cases, the only available validation data for a powertrain model is the EPA "window sticker" energy consumption rates. However, there are also situations in which detailed dynamometer or on-road data is available for a particular vehicle, enabling much more detailed model calibration. This documentation is meant to summarize these various calibration levels and the tools available to help with more detailed calibration.
Calibration/Validation Levels
| Level | Calibration | Validation |
|---|---|---|
| 0 | Vehicle is parameterized without any fitting to performance data. This is called parameterization, not calibration. | Could be none or could be validated against aggregate energy consumption data like EPA window sticker values. |
| 1 | Vehicle parameters are adjusted so that model results reasonably match test data for aggregate, cycle-level data (e.g. fuel usage, net SOC change). | Model results reasonably match at least some aggregate, cycle-level test data not used in any calibration process. |
| 2 | Vehicle parameters are adjusted so that model results reasonably match test data for time-resolved test data (e.g. instantaneous fuel usage, instantaneous cumulative fuel usage, instantaneous SOC). | Model results reasonably match at least some time-resolved test data not used in any calibration process. |
| 3 | Some amount of component-level thermal modeling is included and vehicle parameters are adjusted so that model results reasonably match test data for time-resolved test data (e.g. instantaneous fuel usage, instantaneous cumulative fuel usage, instantaneous SOC). | Model results reasonably match time-resolved test data not used in any calibration process that covers various temperatures and/vehcile transient thermal states. |
Examples of calibration levels 0, 2, and 3 from the FASTSim Validation Report:
Calibration Level 0 (Parameterization) Guidelines
As noted in the table above, parameterization of a new FASTSim powertrain model is performed when little or no ground truth performance data is available for a specific vehicle. One example of this is if EPA window-sticker fuel economy is the only available performance data. In this situation, it is recommended to parameterize a FASTSim powertrain model using the most reliable vehicle parameters from available information (e.g., specification websites). This helps to avoid overfitting and relies on the robustness of the FASTSim approach to capture the most important powertrain dynamics and simulate energy consumption.
- Create a new vehicle file, either from a template or an existing vehicle model (ideally of the same powertrain type)
- Enter vehicle parameters from various specification sources (note: it is recommended to document the source of specifications that are used to determine each parameter)
veh_pt_typeandfc_eff_typeare important high level descriptors that define the powertrain technologyveh_pt_type: Vehicle powertrain type- Parameter values:
Conv: conventional (ICE, gasoline or diesel) vehicleHEV: hybrid electric vehiclePHEV: plug-in hybrid electric vehicleBEV: battery electric vehicle
- Parameter values:
fc_eff_type: Fuel converter efficiency type- This parameter is used to retrieve the default
fc_eff_mapfor a particular engine type if a custom map is not provided - Unnecessary and not used for vehicles without a fuel converter (e.g. BEVs)
- Parameter values:
SI: spark ignitionAtkinson: Atkinson cycle (typical for hybrids)Diesel: diesel (compression ignition)H2FC: hydrogen fuel cell (use withveh_pt_typeset toHEV)HD_Diesel: heavy-duty diesel
- This parameter is used to retrieve the default
veh_override_kgis the simplest way to specify total vehicle mass- If not provided, the various component mass parameters will be used to calculate total vehicle mass
- If
veh_override_kgis provided, component mass parameters are unnecessary and not used
drag_coefandwheel_rr_coefcan be calculated from dynamometer road load equation coefficients (ABCs) for vehicles tested by the US EPA usingfastsim.auxiliaries.abc_to_drag_coeffs. Test data, including the road load coefficients from coast-down testing, for cars tested by the US EPA is available here.drag_coefis sometimes provided on specification websites and reasonable values informed by engineering judgement forwheel_rr_coefcan be used , but when possible the ABCs andfastsim.auxiliaries.abc_to_drag_coeffsmethod should be used instead
wheel_radius_mis often not explicitly available for a vehicle, but a tire code can be supplied tofastsim.utils.calculate_tire_radiusto calculate a radius- Note: For hybrids, 'total system power' is often provided (e.g., combined ICE and electric motor powers). This should not be used for either
fc_max_kwormc_max_kw, peak engine-only power should be used forfc_max_kwand peak electric motor-only power formc_max_kw.
Calibration Level 2 Guidelines
- Copy calibration_demo.py to your project directory and modify as needed.
- By default, this script selects the model that minimizes the euclidean error across
all objectives, which may not be the way that you want to select your final design.
By looking at the plots that get generated in
save_path, you can use both the time series and parallel coordinates plots to down select an appropriate design. - Because PyMOO is a multi-objective optimizer that finds a multi-dimensional Pareto surface, it will not necessarily return a single best result -- rather, it will produce a pareto-optimal set of results, and you must down select. Often, the design with minimal euclidean error will be the best design, but it's good to pick a handful of designs from the pareto set and check how they behave in the time-resolved plots that can be optionally generated by the optimization script.
- Run
python calibration_demo.py --helpto see details about how to run calibration and validation. Greater population size typically results in faster convergence at the expense of increased run time for each generation. There's no benefit in having a number of processes larger than the population size.xtolandftol(see CLI help) can be used to adjust when the minimization is considered converged. If the optimization is terminating whenn_max_genis hit, then that means it has not converged, and you may want to increasen_max_gen. - Usually, start out with an existing vehicle model that is reasonably close to the new vehicle, and make sure to provide as many explicit parameters as possible. In some cases, a reasonable engineering judgment is appropriate.
- Resample data to 1 Hz. This is a good idea because higher frequency data will cause
fastsim to run more slowly. This can be done with
fastsim.resample.resample. Be sure to specifyrate_vars(e.g. fuel power flow rate [W]), which will be time averaged over the previous time step in the new frequency. - Identify test data signals and corresponding fastsim signals that need to match.
These pairs of signals will be used to construct minimization objectives. See
where
obj_namesis defined incalibration_demo.pyfor an example. - See where
cycs[key]gets assigned to see an example of constructing a Cycle from a dataframe. - Partition out calibration/validation data by specifying a tuple of regex patterns
that correspond to cycle names. See where
cal_cyc_patternsis defined for an example. Typically, it's good to reserve about 25-33% of your data for validation. - To set parameters and corresponding ranges that the optimizer is allowed to use in
getting the model to match test data, see where
params_and_boundsis defined below.
How to Update This Markdown Book
Setup
If not already done, install mdbook
Serving locally
Run the following in the repository root directory:
- If any python files were modified,
- Install pipx
- Install pydoc-markdown
- run
pydoc-markdown -I python/ --render-toc > docs/src/python-doc.md. Do not modify this file manually.
- Run
mdbook serve --open docs/
Publishing
- Update
book.tomlor files indocs/src/ - Make sure the docs look good locally by running the steps in Serving Locally.
- Commit files and push to
fastsim-2branch
After that, a GitHub action will build the book and publish it.
Release Notes
2.1.2 -- SerdeAPI revamp with many new functions, various new vehicles, calibration demo, better error propagation, demo testing
2.1.1 -- license changed to Apache 2.0, default cycle grade and road type to zero if not provided, defaults to regenerative braking parameters, optional documentation fields now generated in Rust
2.1.0 -- release and installation improvements, RustVehicle init cleanup, calibration improvements
2.0.11 - 2.0.22 -- PyPI fixes. Also, Rust version is now >100x faster than Python version.
2.0.10 -- logging fixes, proc macro reorganization, some CAVs performance fixes
2.0.9 -- support for mac ARM/RISC architecture
2.0.8 -- performance improvements
2.0.6 -- dist_v2_m fixes and preliminary CAV functionality
2.0.5 -- added to_rust method for cycle
2.0.4 -- exposed veh.set_veh_mass
2.0.3 -- exposed veh.__post_init__
2.0.2 -- provisioned for non-default vehdb path
2.0.1 -- bug fix
2.0.0 -- All second-by-second calculations are now implemented in both rust and python. Rust provides a ~30x speedup
1.3.1 -- fastsim.simdrive.copy_sim_drive function can deepcopy jit to non-jit (and back) for pickling
1.2.6 -- time dilation bug fix for zero speed
1.2.4 -- bug fix changing == to =
1.2.3 -- veh_file can be passed as standalone argument. fcEffType can be anything if fcEffMap is provided, but typing is otherwise enforced.
1.2.2 -- added checks for some conflicting vehicle parameters. Vehicle parameters fcEffType and vehPtType must now be str type.
1.2.1 -- improved time dilation and added test for it
1.1.7 -- get_numba_veh() and get_numba_cyc() can now be called from already jitted objects
1.1.6 -- another bug fix for numba compatibility with corresponding unit test
1.1.5 -- bug fix for numba compatibility of fcPeakEffOverride and mcPeakEffOverride
1.1.4 -- nan bug fix for fcPeakEffOverride and mcPeakEffOverride
1.1.3 -- provisioned for optional load time motor and engine peak overrides
1.1.2 -- made vehicle loading more more robust
1.1.1 -- made vehicle loading more robust
1.1.0 -- separated jitclasses into own module, made vehicle engine and motor efficiency setting more robust
1.0.4 -- bug fix with custom engine curve
1.0.3 -- bug fixes, faster testing
1.0.2 -- forced type np.float64 on vehicle mass attributes
1.0.1 -- Added vehYear attribute to vehicle and other minor changes.
1.0.0 -- Implemented unittest package. Fixed energy audit calculations to be based on achieved speed. Updated this file. Improved documentation. Vehicle can be instantiated as dict.
0.1.5 -- Updated to be compatible with ADOPT
0.1.4 -- Bug fix: mcEffMap is now robust to having zero as first element
0.1.3 -- Bug fix: fastsim.vehicle.Vehicle method set_init_calcs no longer overrides fcEffMap.
0.1.2 -- Fixes os-dependency of xlwings by not running stuff that needs xlwings. Improvements in functional test. Refinment utomated typying of jitclass objects.
0.1.1 -- Now includes label fuel economy and/or battery kW-hr/mi values that match excel and test for benchmarking against Excel values and CPU time.