Skip to content

Commit

Permalink
fixed a bunch of missing temperature signals in history
Browse files Browse the repository at this point in the history
  • Loading branch information
calbaker committed Jan 18, 2025
1 parent 9d090e3 commit 6a09c4a
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pt_type:
energy_capacity_joules: 5760000.0
eff_interp:
Interp0D: 0.9848857801796105
min_soc: 0.0
max_soc: 1.0
min_soc: 0.5
max_soc: 0.95
save_interval: 1
fs:
pwr_out_max_watts: 2000000.0
Expand Down
40 changes: 37 additions & 3 deletions fastsim-core/src/vehicle/cabin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,28 @@ pub enum CabinOption {
#[default]
None,
}
impl SaveState for CabinOption {
fn save_state(&mut self) {
match self {
Self::LumpedCabin(lc) => lc.save_state(),
Self::LumpedCabinWithShell => {
todo!()
}
Self::None => {}
}
}
}
impl Step for CabinOption {
fn step(&mut self) {
match self {
Self::LumpedCabin(lc) => lc.step(),
Self::LumpedCabinWithShell => {
todo!()
}
Self::None => {}
}
}
}
impl Init for CabinOption {
fn init(&mut self) -> anyhow::Result<()> {
match self {
Expand Down Expand Up @@ -133,9 +155,7 @@ impl LumpedCabin {
}

#[fastsim_api]
#[derive(
Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative,
)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)]
#[serde(default)]
pub struct LumpedCabinState {
/// time step counter
Expand All @@ -161,5 +181,19 @@ pub struct LumpedCabinState {
pub reynolds_for_plate: si::Ratio,
}

impl Default for LumpedCabinState {
fn default() -> Self {
Self {
i: Default::default(),
temperature: *TE_STD_AIR,
temp_prev: *TE_STD_AIR,
pwr_thermal_from_hvac: Default::default(),
energy_thermal_from_hvac: Default::default(),
pwr_thermal_from_amb: Default::default(),
energy_thermal_from_amb: Default::default(),
reynolds_for_plate: Default::default(),
}
}
}
impl Init for LumpedCabinState {}
impl SerdeAPI for LumpedCabinState {}
10 changes: 6 additions & 4 deletions fastsim-core/src/vehicle/hev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ impl HEVPowertrainControls {
handle_fc_on_causes_for_temp(fc, rgwdb, hev_state)?;
handle_fc_on_causes_for_speed(veh_state, rgwdb, hev_state)?;
handle_fc_on_causes_for_low_soc(res, rgwdb, hev_state, veh_state)?;
// `handle_fc_*` below here are asymmetrical for positive tractive power only
handle_fc_on_causes_for_pwr_demand(
rgwdb,
pwr_out_req,
Expand All @@ -618,13 +619,15 @@ impl HEVPowertrainControls {
// split, cannot exceed ElectricMachine max output power.
// Excess demand will be handled by `fc`. Favors drawing
// power from `em` before engine
let em_pwr = pwr_out_req.min(em_state.pwr_mech_fwd_out_max);
let mut em_pwr = pwr_out_req.min(em_state.pwr_mech_fwd_out_max);
let fc_pwr: si::Power = if hev_state.fc_on_causes.is_empty() {
// engine does not need to be on
si::Power::ZERO
} else {
// engine has been forced on
// power demand from engine before adjusting for efficient operating point
// power demand from engine such that engine handles all
// power demand beyond the em capability, before adjusting for efficient operating
// point
let mut fc_pwr_req = pwr_out_req - em_pwr;
// if the engine is on, load it up to get closer to peak
// efficiency
Expand All @@ -640,7 +643,7 @@ impl HEVPowertrainControls {
fc_pwr_req
};
// recalculate `em_pwr` based on `fc_pwr`
let em_pwr = pwr_out_req - fc_pwr;
em_pwr = pwr_out_req - fc_pwr;

ensure!(
fc_pwr >= si::Power::ZERO,
Expand Down Expand Up @@ -859,7 +862,6 @@ impl Init for RESGreedyWithDynamicBuffers {
self.speed_fc_forced_on = self.speed_fc_forced_on.or(Some(uc::MPH * 75.));
self.frac_pwr_demand_fc_forced_on =
self.frac_pwr_demand_fc_forced_on.or(Some(uc::R * 0.75));
// TODO: consider changing this default
self.frac_of_most_eff_pwr_to_run_fc =
self.frac_of_most_eff_pwr_to_run_fc.or(Some(1.0 * uc::R));
Ok(())
Expand Down
8 changes: 7 additions & 1 deletion fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,13 @@ pub enum CabinHeatSource {
impl Init for CabinHeatSource {}
impl SerdeAPI for CabinHeatSource {}

#[fastsim_api]
#[fastsim_api(
#[pyo3(name = "default")]
#[staticmethod]
fn default_py() -> Self {
Self::default()
}
)]
#[derive(
Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative,
)]
Expand Down
4 changes: 2 additions & 2 deletions fastsim-core/src/vehicle/powertrain/electric_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ impl ElectricMachine {
),
);
ensure!(
-pwr_out_req <= self.state.pwr_mech_bwd_out_max,
almost_le_uom(&pwr_out_req.abs(), &self.state.pwr_mech_bwd_out_max, None),
format!(
"{}\nedrv required charge power ({:.6} kW) exceeds current max charge power ({:.6} kW)",
format_dbg!(pwr_out_req <= self.state.pwr_mech_bwd_out_max),
format_dbg!(pwr_out_req.abs() <= self.state.pwr_mech_bwd_out_max),
pwr_out_req.get::<si::kilowatt>(),
self.state.pwr_mech_bwd_out_max.get::<si::kilowatt>()
),
Expand Down
17 changes: 17 additions & 0 deletions fastsim-core/src/vehicle/powertrain/fuel_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ use std::f64::consts::PI;
pub struct FuelConverter {
/// [Self] Thermal plant, including thermal management controls
#[serde(default, skip_serializing_if = "FuelConverterThermalOption::is_none")]
#[has_state]
pub thrml: FuelConverterThermalOption,
/// [Self] mass
#[serde(default)]
Expand Down Expand Up @@ -407,6 +408,22 @@ pub enum FuelConverterThermalOption {
None,
}

impl SaveState for FuelConverterThermalOption {
fn save_state(&mut self) {
match self {
Self::FuelConverterThermal(fct) => fct.save_state(),
Self::None => {}
}
}
}
impl Step for FuelConverterThermalOption {
fn step(&mut self) {
match self {
Self::FuelConverterThermal(fct) => fct.step(),
Self::None => {}
}
}
}
impl Init for FuelConverterThermalOption {
fn init(&mut self) -> anyhow::Result<()> {
match self {
Expand Down
25 changes: 24 additions & 1 deletion fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const TOL: f64 = 1e-3;
pub struct ReversibleEnergyStorage {
/// [Self] Thermal plant, including thermal management controls
#[serde(default, skip_serializing_if = "RESThermalOption::is_none")]
#[has_state]
pub thrml: RESThermalOption,
/// ReversibleEnergyStorage mass
#[serde(default)]
Expand Down Expand Up @@ -722,6 +723,22 @@ pub enum RESThermalOption {
#[default]
None,
}
impl SaveState for RESThermalOption {
fn save_state(&mut self) {
match self {
Self::RESLumpedThermal(rlt) => rlt.save_state(),
Self::None => {}
}
}
}
impl Step for RESThermalOption {
fn step(&mut self) {
match self {
Self::RESLumpedThermal(rlt) => rlt.step(),
Self::None => {}
}
}
}
impl Init for RESThermalOption {
fn init(&mut self) -> anyhow::Result<()> {
match self {
Expand Down Expand Up @@ -823,7 +840,13 @@ impl RESLumpedThermal {
}
}

#[fastsim_api]
#[fastsim_api(
#[pyo3(name = "default")]
#[staticmethod]
fn default_py() -> Self {
Self::default()
}
)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)]
#[serde(default)]
pub struct RESLumpedThermalState {
Expand Down
1 change: 1 addition & 0 deletions fastsim-core/src/vehicle/vehicle_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ pub struct Vehicle {

/// Cabin thermal model
#[serde(default, skip_serializing_if = "CabinOption::is_none")]
#[has_state]
pub cabin: CabinOption,

/// HVAC model
Expand Down
63 changes: 56 additions & 7 deletions python/fastsim/demos/demo_hev_thrml.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@
# simulation start time
t0 = time.perf_counter()
# run simulation
try:
sd.walk()
except Exception as err:
print(f"still need to fix {err}")
sd.walk()
# simulation end time
t1 = time.perf_counter()
t_fsim3_si1 = t1 - t0
Expand All @@ -54,9 +51,60 @@

# %%
df = sd.to_dataframe(allow_partial=True)
sd_dict = sd.to_pydict(flatten=True)
# # Visualize results


def plot_temperatures() -> Tuple[Figure, Axes]:
fig, ax = plt.subplots(2, 1, sharex=True, figsize=figsize_3_stacked)
plt.suptitle("Component Temperatures")

ax[0].set_prop_cycle(get_uni_cycler())
ax[0].plot(
df["cyc.time_seconds"],
df["cyc.temp_amb_air_kelvin"] - 273.15,
label="amb",
)
ax[0].plot(
df["cyc.time_seconds"],
df["veh.cabin.LumpedCabin.history.temperature_kelvin"] - 273.15,
label="cabin",
)
ax[0].plot(
df["cyc.time_seconds"],
df["veh.pt_type.HybridElectricVehicle.res.thrml." +
"RESLumpedThermal.history.temperature_kelvin"] - 273.15,
label="res",
)
ax[0].plot(
df["cyc.time_seconds"],
df["veh.pt_type.HybridElectricVehicle.fc.thrml." +
"FuelConverterThermal.history.temperature_kelvin"] - 273.15,
label="fc",
)
ax[0].set_ylabel("Temperatures [°C]")
ax[0].legend()

ax[-1].set_prop_cycle(get_paired_cycler())
ax[-1].plot(
df["cyc.time_seconds"],
df["veh.history.speed_ach_meters_per_second"],
label="ach",
)
ax[-1].legend()
ax[-1].set_xlabel("Time [s]")
ax[-1].set_ylabel("Ach Speed [m/s]")
x_min, x_max = ax[-1].get_xlim()[0], ax[-1].get_xlim()[1]
x_max = (x_max - x_min) * 1.15
ax[-1].set_xlim([x_min, x_max])

plt.tight_layout()
if SAVE_FIGS:
plt.savefig(Path("./plots/temps.svg"))

return fig, ax


def plot_fc_pwr() -> Tuple[Figure, Axes]:
fig, ax = plt.subplots(3, 1, sharex=True, figsize=figsize_3_stacked)
plt.suptitle("Fuel Converter Power")
Expand Down Expand Up @@ -106,7 +154,7 @@ def plot_fc_pwr() -> Tuple[Figure, Axes]:
ax[-1].plot(
df["cyc.time_seconds"],
df["veh.history.speed_ach_meters_per_second"],
label="f3",
label="ach",
)
ax[-1].legend()
ax[-1].set_xlabel("Time [s]")
Expand Down Expand Up @@ -145,7 +193,7 @@ def plot_fc_energy() -> Tuple[Figure, Axes]:
ax[-1].plot(
df["cyc.time_seconds"],
df["veh.history.speed_ach_meters_per_second"],
label="f3",
label="ach",
)
ax[-1].legend()
ax[-1].set_xlabel("Time [s]")
Expand Down Expand Up @@ -271,7 +319,7 @@ def plot_road_loads() -> Tuple[Figure, Axes]:
ax[-1].plot(
df["cyc.time_seconds"][::veh.save_interval],
df["veh.history.speed_ach_meters_per_second"],
label="f3",
label="ach",
)
ax[-1].legend()
ax[-1].set_xlabel("Time [s]")
Expand All @@ -289,6 +337,7 @@ def plot_road_loads() -> Tuple[Figure, Axes]:
fig_fc_energy, ax_fc_energy = plot_fc_energy()
fig_res_pwr, ax_res_pwr = plot_res_pwr()
fig_res_energy, ax_res_energy = plot_res_energy()
fig_temps, ax_temps = plot_temperatures()
# fig, ax = plot_road_loads()
plt.show()
# %%
Expand Down

0 comments on commit 6a09c4a

Please sign in to comment.