Skip to content

Commit

Permalink
allowed trace miss in cal_hev.py
Browse files Browse the repository at this point in the history
put in comments and some infrastructure to do `AllowChecked` trace miss option to use tolerances instead of on/off
doc strings and such
  • Loading branch information
calbaker committed Jan 29, 2025
1 parent dc9f243 commit bb104bb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
7 changes: 4 additions & 3 deletions cal_and_val/thermal/cal_hev.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
40 changes: 29 additions & 11 deletions fastsim-core/src/simdrive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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())
Expand All @@ -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!())?
Expand All @@ -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()
Expand Down Expand Up @@ -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,
}

Expand All @@ -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,
}
}
}
Expand All @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions fastsim-core/src/vehicle/hev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<si::kilowatt>(),
em_state.pwr_mech_fwd_out_max.get::<si::kilowatt>(),
fc_state.pwr_prop_max.get::<si::kilowatt>()
fc_state.pwr_prop_max.get::<si::kilowatt>(),
res.state.soc.get::<si::ratio>()
);

// # Brain dump for thermal stuff
Expand Down
2 changes: 1 addition & 1 deletion python/fastsim/pymoo_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`"
)
Expand Down

0 comments on commit bb104bb

Please sign in to comment.