Skip to content

Commit

Permalink
cleaned up several errors
Browse files Browse the repository at this point in the history
  • Loading branch information
calbaker committed Feb 4, 2025
1 parent 525a8e1 commit 93cdecd
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 50 deletions.
16 changes: 6 additions & 10 deletions cal_and_val/thermal/cal_bev.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
# Obtain the data from
# https://nrel.sharepoint.com/:f:/r/sites/EEMSCoreModelingandDecisionSupport2022-2024/Shared%20Documents/FASTSim/DynoTestData?csf=1&web=1&e=F4FEBp
# and then copy it to the local folder below
cyc_folder_path = Path(__file__).parent / "dyno_test_data/2020 Chevrolet Bolt EV/Extended Datasets"
cyc_folder_path = Path(__file__).parent / "dyno_test_data/2020 Chevrolet Bolt/Extended Datasets"
assert cyc_folder_path.exists(), cyc_folder_path

# Test data columns
time_column = "Time[s]_RawFacilities"
speed_column = "Dyno_Spd[mph]"
cabin_temp_column = "Cabin_Temp[C]"
cabin_temp_column = "Cabin_Driver_Headrest_Temp__C"
eng_clnt_temp_column = "engine_coolant_temp_PCAN__C"
cell_temp_column = "Cell_Temp[C]"
soc_column = "HVBatt_SOC_CAN4__per"
Expand Down Expand Up @@ -82,7 +82,7 @@
"62009040 Test Data.txt"
# "62009041 Test Data.txt"
]
cyc_files_for_cal: List[Path] = [cyc_file for cyc_file in cyc_files_dict if cyc_file.name in cyc_files_for_cal]
cyc_files_for_cal: List[Path] = [cyc_file for cyc_file in cyc_files if cyc_file.name in cyc_files_for_cal]
assert len(cyc_files_for_cal) > 0, cyc_files_for_cal
print("\ncyc_files_for_cal:\n", '\n'.join([cf.name for cf in cyc_files_for_cal]), sep='')

Expand All @@ -97,19 +97,18 @@ def df_to_cyc(df: pd.DataFrame) -> fsim.Cycle:
return fsim.Cycle.from_pydict(cyc_dict, skip_init=False)

pt_type_var = "BatteryElectricVehicle"
cabin_type_var = 'LumpedCabin'
hvac_type_var = 'LumpedCabinAndRES'

def veh_init(cyc_file_stem: str, dfs: Dict[str, pd.DataFrame]) -> fsim.Vehicle:

vd = deepcopy(veh_dict)

# initialize SOC
#
vd['pt_type'][pt_type_var]['res']['state']['soc'] = \
dfs[cyc_file_stem][soc_column].iloc[1] / 100
assert 0 < vd['pt_type'][pt_type_var]['res']['state']['soc'] < 1, "\ninit soc: {}\nhead: {}".format(
vd['pt_type'][pt_type_var]['res']['state']['soc'], dfs[cyc_file_stem]["HVBatt_SOC_CAN4__per"].head())
# initialize cabin temp
# not using `"Cabin_Lower_Vent_Temp__C"` because vent tempertature is way different from cabin temp!
vd['cabin'][cabin_type_var]['state']['temperature_kelvin'] = \
dfs[cyc_file_stem][cabin_temp_column][0] + celsius_to_kelvin_offset

Expand All @@ -123,7 +122,7 @@ def veh_init(cyc_file_stem: str, dfs: Dict[str, pd.DataFrame]) -> fsim.Vehicle:

# set HVAC set point temperature
te_set = next(iter([v["set temp [*C]"] for k, v in cyc_files_dict.items() if k.replace(".txt", "") == cyc_file_stem]))
vd['hvac'][cabin_type_var]['te_set_kelvin'] = te_set + celsius_to_kelvin_offset if te_set is not None else None
vd['hvac'][hvac_type_var]['te_set_kelvin'] = te_set + celsius_to_kelvin_offset if te_set is not None else None

return fsim.Vehicle.from_pydict(vd, skip_init=False)

Expand Down Expand Up @@ -190,9 +189,6 @@ def resample_df(df: pd.DataFrame) -> pd.DataFrame:
# Setup model objectives
## Parameter Functions

cabin_type_var = 'LumpedCabin'
hvac_type_var = 'LumpedCabinAndRES'

def new_em_eff_max(sd_dict, new_eff_max) -> Dict:
"""
Set `new_eff_max` in `ElectricMachine`
Expand Down
83 changes: 51 additions & 32 deletions fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin_and_res.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::*;
/// HVAC system for [LumpedCabin] and [ReversibleEnergyStorage::thrml]
pub struct HVACSystemForLumpedCabinAndRES {
/// set point temperature
pub te_set: si::Temperature,
pub te_set: Option<si::Temperature>,
/// Deadband range. Any cabin temperature within this range of `te_set`
/// results in no HVAC power draw
pub te_deadband: si::TemperatureInterval,
Expand Down Expand Up @@ -62,7 +62,7 @@ pub struct HVACSystemForLumpedCabinAndRES {
impl Default for HVACSystemForLumpedCabinAndRES {
fn default() -> Self {
Self {
te_set: *TE_STD_AIR,
te_set: Some(*TE_STD_AIR),
te_deadband: 1.5 * uc::KELVIN_INT,
p_cabin: Default::default(),
i_cabin: Default::default(),
Expand Down Expand Up @@ -300,44 +300,49 @@ impl HVACSystemForLumpedCabinAndRES {
cab_heat_cap: si::HeatCapacity,
dt: si::Time,
) -> anyhow::Result<si::Power> {
let pwr_thrml_hvac_to_cabin = if cab_state.temperature <= (self.te_set + self.te_deadband)
&& cab_state.temperature >= (self.te_set - self.te_deadband)
let te_set = match self.te_set {
Some(te_set) => te_set,
None => return Ok(si::Power::ZERO),
};
let pwr_thrml_hvac_to_cabin = if cab_state.temperature <= (te_set + self.te_deadband)
&& cab_state.temperature >= (te_set - self.te_deadband)
{
// inside deadband; no hvac power is needed

self.state.pwr_i = si::Power::ZERO; // reset to 0.0
self.state.pwr_p = si::Power::ZERO;
self.state.pwr_d = si::Power::ZERO;
self.state.pwr_i_cab = si::Power::ZERO; // reset to 0.0
self.state.pwr_p_cab = si::Power::ZERO;
self.state.pwr_d_cab = si::Power::ZERO;
si::Power::ZERO
} else {
// outside deadband
let te_delta_vs_set = (cab_state.temperature.get::<si::degree_celsius>()
- self.te_set.get::<si::degree_celsius>())
- te_set.get::<si::degree_celsius>())
* uc::KELVIN_INT;

self.state.pwr_p = -self.p_cabin * te_delta_vs_set;
self.state.pwr_i -= self.i_cabin * uc::W / uc::KELVIN / uc::S * te_delta_vs_set * dt;
self.state.pwr_i = self
self.state.pwr_p_cab = -self.p_cabin * te_delta_vs_set;
self.state.pwr_i_cab -=
self.i_cabin * uc::W / uc::KELVIN / uc::S * te_delta_vs_set * dt;
self.state.pwr_i_cab = self
.state
.pwr_i
.pwr_i_cab
.max(-self.pwr_i_max_cabin)
.min(self.pwr_i_max_cabin);
self.state.pwr_d = -self.d_cabin * uc::J / uc::KELVIN
self.state.pwr_d_cab = -self.d_cabin * uc::J / uc::KELVIN
* ((cab_state.temperature.get::<si::degree_celsius>()
- cab_state.temp_prev.get::<si::degree_celsius>())
* uc::KELVIN_INT
/ dt);

let pwr_thrml_hvac_to_cabin: si::Power =
if cab_state.temperature > self.te_set + self.te_deadband {
let pwr_thrml_hvac_to_cab: si::Power =
if cab_state.temperature > te_set + self.te_deadband {
// COOLING MODE; cabin is hotter than set point

if self.state.pwr_i > si::Power::ZERO {
if self.state.pwr_i_cab > si::Power::ZERO {
// If `pwr_i` is greater than zero, reset to switch from heating to cooling
self.state.pwr_i = si::Power::ZERO;
self.state.pwr_i_cab = si::Power::ZERO;
}
let mut pwr_thrml_hvac_to_cab =
(self.state.pwr_p + self.state.pwr_i + self.state.pwr_d)
(self.state.pwr_p_cab + self.state.pwr_i_cab + self.state.pwr_d_cab)
.max(-self.pwr_thrml_max);

if (-pwr_thrml_hvac_to_cab / self.state.cop) > self.pwr_aux_for_hvac_max {
Expand All @@ -347,16 +352,21 @@ impl HVACSystemForLumpedCabinAndRES {
} else {
self.state.pwr_aux_for_hvac = pwr_thrml_hvac_to_cab / self.state.cop;
}
ensure!(
pwr_thrml_hvac_to_cab < si::Power::ZERO,
"{}\nHVAC should be cooling cabin",
format_dbg!(pwr_thrml_hvac_to_cab)
);
pwr_thrml_hvac_to_cab
} else {
// HEATING MODE; cabin is colder than set point

if self.state.pwr_i < si::Power::ZERO {
if self.state.pwr_i_cab < si::Power::ZERO {
// If `pwr_i` is less than zero reset to switch from cooling to heating
self.state.pwr_i = si::Power::ZERO;
self.state.pwr_i_cab = si::Power::ZERO;
}
let mut pwr_thrml_hvac_to_cabin: si::Power =
(self.state.pwr_p + self.state.pwr_i + self.state.pwr_d)
(self.state.pwr_p_cab + self.state.pwr_i_cab + self.state.pwr_d_cab)
.min(self.pwr_thrml_max);

// Assumes blower has negligible impact on aux load, may want to revise later
Expand All @@ -370,7 +380,12 @@ impl HVACSystemForLumpedCabinAndRES {
.with_context(|| format_dbg!())?;
pwr_thrml_hvac_to_cabin
};
pwr_thrml_hvac_to_cabin
ensure!(
pwr_thrml_hvac_to_cab >= si::Power::ZERO,
"{}\nHVAC should be heating cabin",
format_dbg!(pwr_thrml_hvac_to_cab)
);
pwr_thrml_hvac_to_cab
};
Ok(pwr_thrml_hvac_to_cabin)
}
Expand All @@ -383,8 +398,12 @@ impl HVACSystemForLumpedCabinAndRES {
res_temp_prev: si::Temperature,
dt: si::Time,
) -> anyhow::Result<si::Power> {
let pwr_thrml_hvac_to_res = if res_temp <= self.te_set + self.te_deadband
&& res_temp >= self.te_set - self.te_deadband
let te_set = match self.te_set {
Some(te_set) => te_set,
None => return Ok(si::Power::ZERO),
};
let pwr_thrml_hvac_to_res = if res_temp <= te_set + self.te_deadband
&& res_temp >= te_set - self.te_deadband
{
// inside deadband; no hvac power is needed

Expand All @@ -395,7 +414,7 @@ impl HVACSystemForLumpedCabinAndRES {
} else {
// outside deadband
let te_delta_vs_set = (res_temp.get::<si::degree_celsius>()
- self.te_set.get::<si::degree_celsius>())
- te_set.get::<si::degree_celsius>())
* uc::KELVIN_INT;
self.state.pwr_p_res = -self.p_res * te_delta_vs_set;
self.state.pwr_i_res -= self.i_res * uc::W / uc::KELVIN / uc::S * te_delta_vs_set * dt;
Expand All @@ -410,7 +429,7 @@ impl HVACSystemForLumpedCabinAndRES {
* uc::KELVIN_INT
/ dt);

let pwr_thrml_hvac_to_res: si::Power = if res_temp > self.te_set + self.te_deadband {
let pwr_thrml_hvac_to_res: si::Power = if res_temp > te_set + self.te_deadband {
// COOLING MODE; Reversible Energy Storage is hotter than set point

if self.state.pwr_i_res > si::Power::ZERO {
Expand Down Expand Up @@ -493,17 +512,17 @@ pub struct HVACSystemForLumpedCabinAndRESState {
/// time step counter
pub i: u32,
/// portion of total HVAC cooling/heating (negative/positive) power due to proportional gain
pub pwr_p: si::Power,
pub pwr_p_cab: si::Power,
/// portion of total HVAC cooling/heating (negative/positive) cumulative energy due to proportional gain
pub energy_p: si::Energy,
pub energy_p_cab: si::Energy,
/// portion of total HVAC cooling/heating (negative/positive) power due to integral gain
pub pwr_i: si::Power,
pub pwr_i_cab: si::Power,
/// portion of total HVAC cooling/heating (negative/positive) cumulative energy due to integral gain
pub energy_i: si::Energy,
pub energy_i_cab: si::Energy,
/// portion of total HVAC cooling/heating (negative/positive) power due to derivative gain
pub pwr_d: si::Power,
pub pwr_d_cab: si::Power,
/// portion of total HVAC cooling/heating (negative/positive) cumulative energy due to derivative gain
pub energy_d: si::Energy,
pub energy_d_cab: si::Energy,
/// portion of total HVAC cooling/heating (negative/positive) power to [ReversibleEnergyStorage::thrml] due to proportional gain
pub pwr_p_res: si::Power,
/// portion of total HVAC cooling/heating (negative/positive) cumulative energy to [ReversibleEnergyStorage::thrml] due to proportional gain
Expand Down
10 changes: 2 additions & 8 deletions python/fastsim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,8 @@ def from_pydict(cls, pydict: Dict, data_fmt: str = "msg_pack", skip_init: bool =
obj = cls.from_yaml(yaml.dump(pydict), skip_init=skip_init)
case "msg_pack":
import msgpack
try:
obj = cls.from_msg_pack(
msgpack.packb(pydict), skip_init=skip_init)
except Exception as err:
print(
f"{err}\nFalling back to YAML.")
obj = cls.from_pydict(
pydict, data_fmt="yaml", skip_init=skip_init)
obj = cls.from_msg_pack(
msgpack.packb(pydict), skip_init=skip_init)
case "json":
from json import dumps
obj = cls.from_json(dumps(pydict), skip_init=skip_init)
Expand Down

0 comments on commit 93cdecd

Please sign in to comment.