Skip to content

Commit

Permalink
Update voltage equations and tests to account for zero current at ful…
Browse files Browse the repository at this point in the history
…l battery, new resistance in table tests
  • Loading branch information
brtietz committed Oct 9, 2023
1 parent b82c6f2 commit ed71ab2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 24 deletions.
6 changes: 5 additions & 1 deletion shared/lib_battery_voltage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ double voltage_table_t::calculate_voltage(double DOD, double I) {
while (row < params->voltage_table.size() && DOD > params->voltage_table[row][0]) {
row++;
}
//
if (DOD < tolerance) {
I = 0.0; // At full, current must go to zero
}

return fmax(slopes[row] * DOD + intercepts[row], 0) - I * params->resistance;
}
Expand Down Expand Up @@ -291,7 +295,7 @@ double voltage_table_t::calculate_current_for_target_w(double P_watts, double q,
auto DOD_upper = params->voltage_table[upper][0];
auto DOD_lower = params->voltage_table[lower][0];
if (DOD_new <= DOD_upper && DOD_new >= DOD_lower) {
current = (q - (100. - DOD_new) * qmax / 100);
current = qmax * ((1. - DOD / 100.) - (1. - DOD_new / 100.)) / params->dt_hr;
double P = current * (a * DOD_new + b - current / params->num_strings * params->resistance);
if (std::abs(P) > std::abs(P_best)) {
P_best = P;
Expand Down
46 changes: 23 additions & 23 deletions test/shared_test/lib_battery_voltage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, updateCapacityTest){
I = 5;
cap->updateCapacity(I, dt_hour); // qmx = 10, I = 4.5, q0 = 0.5
model->updateVoltage(cap->q0(), cap->qmax(), cap->I(), 0, dt_hour);
EXPECT_NEAR(model->cell_voltage(), 1.35, tol);
EXPECT_NEAR(model->cell_voltage(), 1.336, tol);
EXPECT_NEAR(cap->q0(), 0.5, tol);
}

Expand All @@ -631,7 +631,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, updateCapacitySubHourly){
I = 5;
cap->updateCapacity(I, dt_hour); // qmx = 10, I = 4.5, q0 = 0.5
model->updateVoltage(cap->q0(), cap->qmax(), cap->I(), 0, dt_hour);
EXPECT_NEAR(model->cell_voltage(), 3.504, tol);
EXPECT_NEAR(model->cell_voltage(), 3.492, tol);
EXPECT_NEAR(cap->q0(), 2.5, tol);
}

Expand All @@ -654,7 +654,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, updateCapacitySubMinute){
I = 5;
cap->updateCapacity(I, dt_hour); // qmx = 10, I = 4.5, q0 = 0.5
model->updateVoltage(cap->q0(), cap->qmax(), cap->I(), 0, dt_hour);
EXPECT_NEAR(model->cell_voltage(), 3.689, tol);
EXPECT_NEAR(model->cell_voltage(), 3.677, tol);
EXPECT_NEAR(cap->q0(), 4.975, 1e-3);
}

Expand Down Expand Up @@ -888,15 +888,15 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeHourly){
// start at half SOC
double max_current;
double power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 1194, 1); // current ~4
EXPECT_NEAR(power, 1192.6, 1); // current ~4
double max_current_calc = model->calculate_current_for_target_w(power - 1, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, 2.45, 1e-2);
EXPECT_NEAR(max_current_calc, 2.44, 1e-2);
// Does not empty battery for highest power
cap->updateCapacity(max_current, dt_hour);
EXPECT_NEAR(cap->SOC(), 25.5, 1e-3);
// Check power
model->updateVoltage(cap->q0(), cap->qmax(), max_current_calc, 0, dt_hour);
EXPECT_NEAR(max_current_calc * model->battery_voltage(), power, 2);
model->updateVoltage(cap->q0(), cap->qmax(), max_current, 0, dt_hour);
EXPECT_NEAR(max_current * model->battery_voltage(), power, 2);

// start at empty SOC
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
Expand All @@ -915,15 +915,15 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeHourly){
while (cap->SOC() < 95)
cap->updateCapacity(I, dt_hour);
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 3569, 1);
EXPECT_NEAR(power, 3553, 1);
max_current_calc = model->calculate_current_for_target_w(power - 1, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, max_current, 1e-2);
EXPECT_NEAR(max_current_calc, max_current, 1e-1);
// Does not empty battery for highest power
cap->updateCapacity(max_current, dt_hour);
EXPECT_NEAR(cap->SOC(), 27.02, 1e-2);
// Check power
model->updateVoltage(cap->q0(), cap->qmax(), max_current_calc, 0, dt_hour);
EXPECT_NEAR(max_current_calc * model->battery_voltage(), power, 2);
model->updateVoltage(cap->q0(), cap->qmax(), max_current, 0, dt_hour);
EXPECT_NEAR(max_current * model->battery_voltage(), power, 2);
}

TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeHourlyInputErrors) {
Expand Down Expand Up @@ -962,17 +962,17 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeSubHourly){
// start at half SOC
double max_current;
double power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 2388, 1); // current ~4
EXPECT_NEAR(power, 2381, 1); // current ~4
double max_current_calc = model->calculate_current_for_target_w(power - 1, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current, 4.9, 1e-2);
EXPECT_NEAR(max_current_calc, 4.9, 1e-2);
EXPECT_NEAR(max_current, 4.90, 1e-2);
EXPECT_NEAR(max_current_calc, 4.90, 1e-1); //4.88 as of 10/9/2023
// Does not empty battery for highest power
cap->updateCapacity(max_current, dt_hour);
EXPECT_NEAR(cap->SOC(), 25.5, 1e-3);

// start at empty SOC
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 1163, 1);
EXPECT_NEAR(power, 1161, 1);
max_current_calc = model->calculate_current_for_target_w(power - 1, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current, 2.44, 1e-1);
EXPECT_NEAR(max_current_calc, 2.44, 1e-1);
Expand All @@ -985,9 +985,9 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeSubHourly){
while (cap->SOC() < 95)
cap->updateCapacity(I, dt_hour);
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 7139, 1);
EXPECT_NEAR(power, 7073, 1);
max_current_calc = model->calculate_current_for_target_w(power - 1, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, max_current, 1e-2);
EXPECT_NEAR(max_current_calc, max_current, 2e-1);
// Does not empty battery for highest power
cap->updateCapacity(max_current, dt_hour);
EXPECT_NEAR(cap->SOC(), 27.02, 1e-2);
Expand All @@ -1000,7 +1000,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeHourly_table
// start at half SOC
double max_current;
double power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 293, &max_current);
EXPECT_NEAR(power, 719.25, 1); // current ~4
EXPECT_NEAR(power, 714.44, 1); // current ~4
double max_current_calc = model->calculate_current_for_target_w(power, cap->q0(), cap->qmax(), 293);
EXPECT_NEAR(max_current, 3.94, 1e-2);
EXPECT_NEAR(max_current_calc, 3.94, 1e-2);
Expand Down Expand Up @@ -1028,7 +1028,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeHourly_table
while (cap->SOC() < 95)
cap->updateCapacity(I, dt_hour);
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 293, &max_current);
EXPECT_NEAR(power, 1480.35, 1);
EXPECT_NEAR(power, 1462.98, 1);
max_current_calc = model->calculate_current_for_target_w(power, cap->q0(), cap->qmax(), 293);
EXPECT_NEAR(max_current, 7.5, 1e-2);
EXPECT_NEAR(max_current_calc, 7.5, 1e-2);
Expand All @@ -1047,7 +1047,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeSubMinute){
// start at half SOC
double max_current;
double power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 238891, 1); // current ~8
EXPECT_NEAR(power, 164727, 1); // current ~8
double max_current_calc = model->calculate_current_for_target_w(power, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, max_current, 0.2);
// Does not empty battery for highest power
Expand All @@ -1059,7 +1059,7 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeSubMinute){

// start at empty SOC
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 116333, 1);
EXPECT_NEAR(power, 97792, 1);
max_current_calc = model->calculate_current_for_target_w(power, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, max_current, 1e-1);
// Does not empty battery for highest power
Expand All @@ -1074,12 +1074,12 @@ TEST_F(voltage_table_lib_battery_voltage_test, calculateMaxDischargeSubMinute){
while (cap->SOC() < 95)
cap->updateCapacity(I, dt_hour);
power = model->calculate_max_discharge_w(cap->q0(), cap->qmax(), 0, &max_current);
EXPECT_NEAR(power, 685795, 1);
EXPECT_NEAR(power, 207281, 1);
max_current_calc = model->calculate_current_for_target_w(power, cap->q0(), cap->qmax(), 0);
EXPECT_NEAR(max_current_calc, max_current, 0.3);
// Does not empty battery for highest power
cap->updateCapacity(max_current, dt_hour);
EXPECT_NEAR(cap->SOC(), 24.52, 1e-3);
EXPECT_NEAR(cap->SOC(), 48.0, 1e-3);
// Check power
model->updateVoltage(cap->q0(), cap->qmax(), max_current_calc, 293, dt_hour);
EXPECT_NEAR(max_current_calc * model->battery_voltage(), power, 1e-2);
Expand Down
4 changes: 4 additions & 0 deletions test/shared_test/lib_battery_voltage_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class voltage_table_lib_battery_voltage_test : public lib_battery_voltage_test
88.9, Vnom, 99, 0});
table = util::matrix_t<double>(4, 2, &vals);

R = 0.02;

cap = std::unique_ptr<capacity_lithium_ion_t>(new capacity_lithium_ion_t(10, 50, 95, 5, dt_hr));
model = std::unique_ptr<voltage_t>(new voltage_table_t(n_cells_series, n_strings, voltage_nom, table, R, dt_hr));
model->set_initial_SOC(50);
Expand All @@ -137,6 +139,7 @@ class voltage_table_lib_battery_voltage_test : public lib_battery_voltage_test
std::vector<double> voltage_vals = { 0, 1.7, 4, 1.69, 5, 1.58, 60, 1.5, 85, 1.4, 90, 1.3, 93, 1.2, 95, 1, 96, 0.9 };
util::matrix_t<double> voltage_table(9, 2, &voltage_vals);

R = 0.02;
voltage_nom = 1.5;
cap = std::unique_ptr<capacity_lithium_ion_t>(new capacity_lithium_ion_t(10, 50, 95, 5, dt_hr));
model = std::unique_ptr<voltage_t>(new voltage_table_t(n_cells_series, n_strings, voltage_nom, voltage_table, R,
Expand Down Expand Up @@ -174,6 +177,7 @@ class voltage_table_lib_battery_voltage_test : public lib_battery_voltage_test
n_cells_series = 6;
n_strings = 28;
voltage_nom = 12;
R = 0.02;

cap = std::unique_ptr<capacity_lithium_ion_t>(new capacity_lithium_ion_t(10, 50, 95, 5, dt_hr));
model = std::unique_ptr<voltage_t>(new voltage_table_t(n_cells_series, n_strings, voltage_nom, voltage_table, R,
Expand Down

0 comments on commit ed71ab2

Please sign in to comment.