Skip to content

Commit

Permalink
tests pass. Optional data has units
Browse files Browse the repository at this point in the history
  • Loading branch information
calbaker committed Aug 27, 2024
1 parent e9f8d5e commit f7c8f4e
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 202 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ opt-level = 0
opt-level = 3

[workspace.dependencies]
# TODO: uncomment and correct version `version = "~0.0.1"`
document-features = "0.2.10"
fastsim-core = { path = "fastsim-core" }
anyhow = "1.0.71"
Expand Down
9 changes: 3 additions & 6 deletions benchmarks/f3-save-int-1.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@

@profile(precision=3)
def build_and_run_sim_drive():
veh = fsim.Vehicle.from_file(
# TODO: figure out why `str` is needed here
str(fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml")
)
veh = fsim.Vehicle.from_resource("2012_Ford_Fusion.yaml")
fsim.set_param_from_path(veh, "save_interval", 1)
cyc = fsim.Cycle.from_resource("udds.csv")
sd = fsim.SimDrive(veh, cyc)
Expand All @@ -23,8 +20,8 @@ def build_and_run_sim_drive():
# 5 61.562 MiB 61.562 MiB 1 @profile(precision=3)
# 6 def build_and_run_sim_drive():
# 7 62.125 MiB 0.562 MiB 2 veh = fsim.Vehicle.from_file(
# 8 # TODO: figure out why `str` is needed here
# 9 61.562 MiB 0.000 MiB 1 str(fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml")
# 8
# 9 61.562 MiB 0.000 MiB 1 fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml"
# 10 )
# 11 62.125 MiB 0.000 MiB 1 veh.save_interval = 1
# 12 62.312 MiB 0.188 MiB 1 cyc = fsim.Cycle.from_resource("udds.csv")
Expand Down
9 changes: 3 additions & 6 deletions benchmarks/f3-save-int-none.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@

@profile(precision=3)
def build_and_run_sim_drive():
veh = fsim.Vehicle.from_file(
# TODO: figure out why `str` is needed here
str(fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml")
)
veh = fsim.Vehicle.from_resource("2012_Ford_Fusion.yaml")
fsim.set_param_from_path(veh, "save_interval", None)
cyc = fsim.Cycle.from_resource("udds.csv")
sd = fsim.SimDrive(veh, cyc)
Expand All @@ -23,8 +20,8 @@ def build_and_run_sim_drive():
# 5 61.203 MiB 61.203 MiB 1 @profile(precision=3)
# 6 def build_and_run_sim_drive():
# 7 61.766 MiB 0.562 MiB 2 veh = fsim.Vehicle.from_file(
# 8 # TODO: figure out why `str` is needed here
# 9 61.203 MiB 0.000 MiB 1 str(fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml")
# 8
# 9 61.203 MiB 0.000 MiB 1 fsim.package_root() / "../../tests/assets/2012_Ford_Fusion.yaml"
# 10 )
# 11 61.766 MiB 0.000 MiB 1 veh.save_interval = None
# 12 61.938 MiB 0.172 MiB 1 cyc = fsim.Cycle.from_resource("udds.csv")
Expand Down
2 changes: 0 additions & 2 deletions fastsim-core/fastsim-proc-macros/src/cumu_method_derive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::imports::*;

// TODO: make sure this macro is propagated and implementd everywhere it's needed

pub(crate) fn cumu_method_derive(input: TokenStream) -> TokenStream {
let item_struct = syn::parse_macro_input!(input as syn::ItemStruct);
let ident = &item_struct.ident;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,35 +207,34 @@ fn extract_type_path(ty: &syn::Type) -> Option<&syn::Path> {
}
}

#[allow(unused)]
/// adapted from https://stackoverflow.com/questions/55271857/how-can-i-get-the-t-from-an-optiont-when-using-syn
fn extract_type_from_option(ty: &syn::Type) -> Option<&syn::Type> {
use syn::{GenericArgument, Path, PathArguments, PathSegment};

// TODO store (with lazy static) the vec of string
// TODO maybe optimization, reverse the order of segments
fn extract_option_segment(path: &Path) -> Option<&PathSegment> {
let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| {
acc.push_str(&v.ident.to_string());
acc.push('|');
acc
});
vec!["Option|", "std|option|Option|", "core|option|Option|"]
.into_iter()
.find(|s| idents_of_path == *s)
.and_then(|_| path.segments.last())
fn extract_option_argument(path: &Path) -> Option<&GenericArgument> {
let mut ident_path = String::new();
for segment in &path.segments {
ident_path.push_str(&segment.ident.to_string());

// Exit when the inner brackets are found
match &segment.arguments {
syn::PathArguments::AngleBracketed(params) => {
return match ident_path.as_str() {
"Option" | "std::option::Option" | "core::option::Option" => {
params.args.first()
}
_ => None,
};
}
syn::PathArguments::None => {}
_ => return None,
}

ident_path.push_str("::");
}
None
}

extract_type_path(ty)
.and_then(extract_option_segment)
.and_then(|path_seg| {
let type_params = &path_seg.arguments;
// It should have only on angle-bracketed param ("<String>"):
match *type_params {
PathArguments::AngleBracketed(ref params) => params.args.first(),
_ => None,
}
})
.and_then(extract_option_argument)
.and_then(|generic_arg| match *generic_arg {
GenericArgument::Type(ref ty) => Some(ty),
_ => None,
Expand Down Expand Up @@ -310,11 +309,9 @@ pub(crate) fn impl_getters_and_setters(
let mut vec_layers: u8 = 0;
let mut inner_type = &ftype;

// TODO: figure this out and uncomment. Then check that all `Option` fields are handled appropriately.
// pull out `inner_type` from `Option<inner_type>`
// if let Some(opt_inner_type) = extract_type_from_option(inner_type) {
// inner_type = opt_inner_type;
// }
if let Some(opt_inner_type) = extract_type_from_option(inner_type) {
inner_type = opt_inner_type;
}

// pull out `inner_type` from `Vec<inner_type>`, recursively if there is any nesting
while let Some(vec_inner_type) = extract_type_from_vec(inner_type) {
Expand Down Expand Up @@ -346,6 +343,7 @@ pub(crate) fn impl_getters_and_setters(
"Mass" => extract_units!(uom::si::mass::kilogram),
"MomentOfInertia" => extract_units!(uom::si::moment_of_inertia::kilogram_square_meter),
"Power" => extract_units!(uom::si::power::watt),
"SpecificPower" => extract_units!(uom::si::specific_power::watt_per_kilogram),
"PowerRate" => extract_units!(uom::si::power_rate::watt_per_second),
"Pressure" => extract_units!(uom::si::pressure::kilopascal, uom::si::pressure::bar),
"Ratio" => extract_units!(uom::si::ratio::ratio),
Expand Down
4 changes: 3 additions & 1 deletion fastsim-core/fastsim-proc-macros/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ pub(crate) use proc_macro2::TokenStream as TokenStream2;
pub(crate) use proc_macro_error::{abort, abort_call_site, emit_error, proc_macro_error};
pub(crate) use quote::{quote, ToTokens, TokenStreamExt}; // ToTokens is implicitly used as a trait
pub(crate) use regex::Regex;
pub(crate) use syn::{spanned::Spanned, Ident, MetaNameValue, Meta, NestedMeta};
pub(crate) use syn::{
spanned::Spanned, GenericArgument, Ident, Meta, MetaNameValue, NestedMeta, Path,
};
8 changes: 4 additions & 4 deletions fastsim-core/resources/vehicles/2012_Ford_Fusion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pt_type:
pwr_ramp_lag_seconds: 1.0
energy_capacity_joules: 2124000000.0
fc:
mass: ~
specific_pwr: ~
mass_kilograms: ~
specific_pwr_watts_per_kilogram: ~
pwr_out_max_watts: 130500.0
pwr_out_max_init_watts: 21750.0
pwr_ramp_lag_seconds: 6.0
Expand Down Expand Up @@ -53,13 +53,13 @@ chassis:
wheel_rr_coef: 0.007
wheel_inertia_kilogram_square_meters: 0.82
num_wheels: 4
wheel_radius: 0.326
wheel_radius_meters: 0.326
cg_height_meters: 0.53
wheel_fric_coef: 0.7
drive_type: FWD
drive_axle_weight_frac: 0.59
wheel_base_meters: 2.72
mass: 1644.2724500334996
mass_kilograms: 1644.2724500334996
pwr_aux_watts: 700.0
trans_eff: 0.875
save_interval: 1
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ year: 2016
pt_type:
HybridElectricVehicle:
res:
mass: ~
specific_energy: ~
mass_kilograms: ~
specific_energy_joules_per_kilogram: ~
pwr_out_max_watts: 100000.0
energy_capacity_joules: 2700000.0
min_soc: 0.25
Expand All @@ -16,8 +16,8 @@ pt_type:
pwr_ramp_lag_seconds: 1.1
energy_capacity_joules: 1392840000.0
fc:
mass: ~
specific_pwr: ~
mass_kilograms: ~
specific_pwr_watts_per_kilogram: ~
pwr_out_max_watts: 71000.0
pwr_out_max_init_watts: 11639.344262295082
pwr_ramp_lag_seconds: 6.1
Expand Down Expand Up @@ -79,8 +79,8 @@ pt_type:
- 0.93
- 0.92
pwr_out_max_watts: 53000.0
specific_pwr: ~
mass: ~
specific_pwr_watts_per_kilogram: ~
mass_kilograms: ~
save_interval: 1
hev_controls: RESGreedy
mass: ~
Expand All @@ -90,13 +90,13 @@ chassis:
wheel_rr_coef: 0.0064
wheel_inertia_kilogram_square_meters: 0.815
num_wheels: 4
wheel_radius: 0.3175
wheel_radius_meters: 0.3175
cg_height_meters: 0.53
wheel_fric_coef: 0.7
drive_type: FWD
drive_axle_weight_frac: 0.59
wheel_base_meters: 2.7
mass: 1635.0
mass_kilograms: 1635.0
pwr_aux_watts: 1050.0
trans_eff: 0.98
save_interval: 1
2 changes: 1 addition & 1 deletion fastsim-core/src/bin/f3-2012-ford-fusion-udds.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// Binary for running the 2012 Ford Fusion in fastsim-3 with `cargo build
/// Binary for profiling the 2012 Ford Fusion in fastsim-3 with `cargo build
/// --profile profiling --bin f3-2012-ford-fusion-udds`. To run this for
/// profiling, install [samply] (https://github.com/mstange/samply) and then run
/// `samply record ./target/profiling/f3-2012-ford-fusion-udds`
Expand Down
7 changes: 3 additions & 4 deletions fastsim-core/src/simdrive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct SimParams {
pub ach_speed_max_iter: u32,
pub ach_speed_tol: si::Ratio,
pub ach_speed_solver_gain: f64,
#[api(skip_get, skip_set)] // TODO: manually write out getter and setter
#[api(skip_get, skip_set)]
pub trace_miss_tol: TraceMissTolerance,
}

Expand Down Expand Up @@ -80,7 +80,6 @@ impl SimDrive {
}
}

// #[timer] TODO: fix and uncomment
pub fn walk(&mut self) -> anyhow::Result<()> {
ensure!(self.cyc.len() >= 2, format_dbg!(self.cyc.len() < 2));
self.save_state();
Expand Down Expand Up @@ -398,7 +397,7 @@ mod tests {
#[test]
#[cfg(feature = "resources")]
fn test_sim_drive_conv() {
let _veh = mock_f2_conv_veh();
let _veh = mock_conv_veh();
let _cyc = Cycle::from_resource("udds.csv", false).unwrap();
let mut sd = SimDrive {
veh: _veh,
Expand All @@ -413,7 +412,7 @@ mod tests {
#[test]
#[cfg(feature = "resources")]
fn test_sim_drive_hev() {
let _veh = mock_f2_hev();
let _veh = mock_hev();
let _cyc = Cycle::from_resource("udds.csv", false).unwrap();
let mut sd = SimDrive {
veh: _veh,
Expand Down
8 changes: 0 additions & 8 deletions fastsim-core/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,10 @@ pub fn interp1d(
let y_first = y_data
.first()
.with_context(|| anyhow!("Unable to extract first element"))?;
// TODO: do this once on init
if y_data.iter().all(|y| y == y_first) {
// return first if all data is equal to first
Ok(*y_first)
} else {
// TODO: when `Interpolator` struct is implemented, make sure this sort of check happens on init
let size = x_data.len();

let mut i = 0;
Expand Down Expand Up @@ -566,12 +564,6 @@ mod tests {
);
}

// TODO: turn this back on and fix the problem it catches
// #[test]
// fn test_interp1d_with_duplicate_x_data() {
// assert!(interp1d(&0.5, &[0.0, 0.0], &[0.0, 1.0], Extrapolate::Yes).is_err());
// }

#[test]
fn test_linspace() {
assert_eq!(Vec::linspace(0.0, 1.0, 3), vec![0.0, 0.5, 1.0]);
Expand Down
51 changes: 13 additions & 38 deletions fastsim-core/src/vehicle/vehicle_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,8 +924,12 @@ impl Default for VehicleState {
pub(crate) mod tests {
use super::*;

fn vehicles_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("resources/vehicles")
}

#[cfg(feature = "yaml")]
pub(crate) fn mock_f2_conv_veh() -> Vehicle {
pub(crate) fn mock_conv_veh() -> Vehicle {
let file_contents = include_str!("fastsim-2_2012_Ford_Fusion.yaml");
use fastsim_2::traits::SerdeAPI;
let veh = {
Expand All @@ -934,21 +938,14 @@ pub(crate) mod tests {
veh.unwrap()
};

veh.to_file(vehicles_dir().join("2012_Ford_Fusion.yaml"))
.unwrap();
assert!(veh.pt_type.is_conventional_vehicle());

// TODO: come up with a fancier solution
// uncomment this if the fastsim-3 version needs to be rewritten
// veh.to_file(
// project_root::get_project_root()
// .unwrap()
// .join("tests/assets/2012_Ford_Fusion.yaml"),
// )
// .unwrap();
veh
}

#[cfg(feature = "yaml")]
pub(crate) fn mock_f2_hev() -> Vehicle {
pub(crate) fn mock_hev() -> Vehicle {
let file_contents = include_str!("fastsim-2_2016_TOYOTA_Prius_Two.yaml");
use fastsim_2::traits::SerdeAPI;
let veh = {
Expand All @@ -957,24 +954,17 @@ pub(crate) mod tests {
veh.unwrap()
};

veh.to_file(vehicles_dir().join("2016_TOYOTA_Prius_Two.yaml"))
.unwrap();
assert!(veh.pt_type.is_hybrid_electric_vehicle());

// TODO: come up with a fancier solution
// uncomment this if the fastsim-3 version needs to be rewritten
// veh.to_file(
// project_root::get_project_root()
// .unwrap()
// .join("tests/assets/2016_TOYOTA_Prius_Two.yaml"),
// )
// .unwrap();
veh
}

/// tests that vehicle can be initialized and that repeating has no net effect
#[test]
#[cfg(feature = "yaml")]
pub(crate) fn test_conv_veh_init() {
let veh = mock_f2_conv_veh();
let veh = mock_conv_veh();
let mut veh1 = veh.clone();
assert!(veh == veh1);
veh1.init().unwrap();
Expand All @@ -984,7 +974,7 @@ pub(crate) mod tests {
#[test]
#[cfg(all(feature = "csv", feature = "resources"))]
fn test_to_fastsim2_conv() {
let veh = mock_f2_conv_veh();
let veh = mock_conv_veh();
let cyc = crate::drive_cycle::Cycle::from_resource("udds.csv", false).unwrap();
let sd = crate::simdrive::SimDrive {
veh,
Expand All @@ -998,7 +988,7 @@ pub(crate) mod tests {
#[test]
#[cfg(all(feature = "csv", feature = "resources"))]
fn test_to_fastsim2_hev() {
let veh = mock_f2_hev();
let veh = mock_hev();
let cyc = crate::drive_cycle::Cycle::from_resource("udds.csv", false).unwrap();
let sd = crate::simdrive::SimDrive {
veh,
Expand All @@ -1008,19 +998,4 @@ pub(crate) mod tests {
let mut sd2 = sd.to_fastsim2().unwrap();
sd2.sim_drive(None, None).unwrap();
}

#[test]
#[cfg(feature = "yaml")]
fn test_hev_deserialize() {
let veh = mock_f2_hev();

let veh_from_file = Vehicle::from_file(
project_root::get_project_root()
.unwrap()
.join("tests/assets/2016_TOYOTA_Prius_Two.yaml"),
false,
)
.unwrap();
assert!(veh == veh_from_file);
}
}
Loading

0 comments on commit f7c8f4e

Please sign in to comment.