diff --git a/cal_and_val/thermal/cal_hev.py b/cal_and_val/thermal/cal_hev.py index 678ef584..dbe276d3 100644 --- a/cal_and_val/thermal/cal_hev.py +++ b/cal_and_val/thermal/cal_hev.py @@ -32,7 +32,8 @@ veh_dict = veh.to_pydict() sim_params_dict = fsim.SimParams.default().to_pydict() -sim_params_dict["trace_miss_opts"] = +sim_params_dict["trace_miss_opts"] = "Allow" +sim_params = fsim.SimParams.from_pydict(sim_params_dict) # Obtain the data from # https://nrel.sharepoint.com/:f:/r/sites/EEMSCoreModelingandDecisionSupport2022-2024/Shared%20Documents/FASTSim/DynoTestData?csf=1&web=1&e=F4FEBp @@ -142,7 +143,7 @@ def veh_init(cyc_file_stem: str, dfs: Dict[str, pd.DataFrame]) -> fsim.Vehicle: cyc: fsim.Cycle # NOTE: maybe change `save_interval` to 5 veh = veh_init(cyc_file_stem, dfs_for_cal) - sds_for_cal[cyc_file_stem] = fsim.SimDrive(veh, cyc).to_pydict() + sds_for_cal[cyc_file_stem] = fsim.SimDrive(veh, cyc, sim_params).to_pydict() cyc_files_for_val: List[Path] = list(set(cyc_files) - set(cyc_files_for_cal)) assert len(cyc_files_for_val) > 0 @@ -165,7 +166,7 @@ def veh_init(cyc_file_stem: str, dfs: Dict[str, pd.DataFrame]) -> fsim.Vehicle: cyc_file_stem: str cyc: fsim.Cycle veh = veh_init(cyc_file_stem, dfs_for_val) - sds_for_val[cyc_file_stem] = fsim.SimDrive(veh, cyc).to_pydict() + sds_for_val[cyc_file_stem] = fsim.SimDrive(veh, cyc, sim_params).to_pydict() # Setup model objectives ## Parameter Functions diff --git a/fastsim-core/src/simdrive.rs b/fastsim-core/src/simdrive.rs index 3a418967..ffa6065f 100644 --- a/fastsim-core/src/simdrive.rs +++ b/fastsim-core/src/simdrive.rs @@ -17,11 +17,19 @@ use crate::prelude::*; /// Solver parameters pub struct SimParams { #[serde(default = "SimParams::def_ach_speed_max_iter")] + /// max number of iterations allowed in setting achieved speed when trace + /// cannot be achieved pub ach_speed_max_iter: u32, #[serde(default = "SimParams::def_ach_speed_tol")] + /// tolerance in change in speed guess in setting achieved speed when trace + /// cannot be achieved pub ach_speed_tol: si::Ratio, #[serde(default = "SimParams::def_ach_speed_solver_gain")] + /// Newton method gain for setting achieved speed pub ach_speed_solver_gain: f64, + // TODO: plumb this up to actually do something + /// When implemented, this will set the tolerance on how much trace miss + /// is allowed #[serde(default = "SimParams::def_trace_miss_tol")] pub trace_miss_tol: TraceMissTolerance, #[serde(default = "SimParams::def_trace_miss_opts")] @@ -453,10 +461,10 @@ pwr deficit: {} kW // initial guess let speed_guess = (1e-3 * uc::MPS).max(cyc_speed); // stop criteria - let max_iter = self.sim_params.ach_speed_max_iter; - let xtol = self.sim_params.ach_speed_tol; + let max_iter = &self.sim_params.ach_speed_max_iter; + let xtol = &self.sim_params.ach_speed_tol; // solver gain - let g = self.sim_params.ach_speed_solver_gain; + let g = &self.sim_params.ach_speed_solver_gain; let pwr_err_fn = |speed_guess: si::Velocity| -> si::Power { t3 * speed_guess.powi(typenum::P3::new()) + t2 * speed_guess.powi(typenum::P2::new()) @@ -480,10 +488,10 @@ pwr deficit: {} kW // speed achieved iteration counter let mut spd_ach_iter_counter = 1; let mut converged = pwr_err <= si::Power::ZERO; - while spd_ach_iter_counter < max_iter && !converged { + while &spd_ach_iter_counter < max_iter && !converged { let speed_guess = *speed_guesses.iter().last().with_context(|| format_dbg!())? * (1.0 - g) - - g * *new_speed_guesses + - *g * *new_speed_guesses .iter() .last() .with_context(|| format_dbg!())? @@ -496,7 +504,7 @@ pwr deficit: {} kW d_pwr_err_per_d_speed_guesses.push(pwr_err_per_speed_guess); new_speed_guesses.push(new_speed_guess); // is the fractional change between previous and current speed guess smaller than `xtol` - converged = ((*speed_guesses.iter().last().with_context(|| format_dbg!())? + converged = &((*speed_guesses.iter().last().with_context(|| format_dbg!())? - speed_guesses[speed_guesses.len() - 2]) / speed_guesses[speed_guesses.len() - 2]) .abs() @@ -533,9 +541,17 @@ pwr deficit: {} kW #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, HistoryMethods)] #[non_exhaustive] pub struct TraceMissTolerance { + /// if the vehicle falls this far behind trace in terms of absolute + /// difference and [TraceMissOptions::is_allow_checked], fail tol_dist: si::Length, + /// if the vehicle falls this far behind trace in terms of fractional + /// difference and [TraceMissOptions::is_allow_checked], fail tol_dist_frac: si::Ratio, + /// if the vehicle falls this far behind instantaneous speed and + /// [TraceMissOptions::is_allow_checked], fail tol_speed: si::Velocity, + /// if the vehicle falls this far behind instantaneous speed in terms of + /// fractional difference and [TraceMissOptions::is_allow_checked], fail tol_speed_frac: si::Ratio, } @@ -545,11 +561,10 @@ impl Init for TraceMissTolerance {} impl Default for TraceMissTolerance { fn default() -> Self { Self { - // TODO: update these values - tol_dist: 666. * uc::M, - tol_dist_frac: 666. * uc::R, - tol_speed: 666. * uc::MPS, - tol_speed_frac: 666. * uc::R, + tol_dist: 100. * uc::M, + tol_dist_frac: 0.01 * uc::R, + tol_speed: 10. * uc::MPS, + tol_speed_frac: 0.5 * uc::R, } } } @@ -558,6 +573,9 @@ impl Default for TraceMissTolerance { pub enum TraceMissOptions { /// Allow trace miss without any fanfare Allow, + // TODO: plumb this up + /// Allow trace miss within error tolerance + AllowChecked, #[default] /// Error out when trace miss happens Error, diff --git a/fastsim-core/src/vehicle/hev.rs b/fastsim-core/src/vehicle/hev.rs index 4cb8772e..3cfedf86 100644 --- a/fastsim-core/src/vehicle/hev.rs +++ b/fastsim-core/src/vehicle/hev.rs @@ -588,11 +588,13 @@ impl HEVPowertrainControls { "{} `pwr_out_req`: {} kW `em_state.pwr_mech_fwd_out_max`: {} kW -`fc_state.pwr_prop_max`: {} kW", +`fc_state.pwr_prop_max`: {} kW +`res.state.soc`: {}", format_dbg!(), pwr_prop_req.get::(), em_state.pwr_mech_fwd_out_max.get::(), - fc_state.pwr_prop_max.get::() + fc_state.pwr_prop_max.get::(), + res.state.soc.get::() ); // # Brain dump for thermal stuff diff --git a/python/fastsim/pymoo_api.py b/python/fastsim/pymoo_api.py index fb35dfb9..a5735939 100644 --- a/python/fastsim/pymoo_api.py +++ b/python/fastsim/pymoo_api.py @@ -26,7 +26,7 @@ from pymoo.util.ref_dirs import get_reference_directions # noqa: F401 PYMOO_AVAILABLE = True except ModuleNotFoundError as err: - logger.warning( + print( f"{err}\nTry running `pip install pymoo==0.6.0.1` to use all features in " + "`fastsim.calibration`" )