Files
CommanderRedYT 460f40ce47 Removed doubles
2022-06-12 17:51:31 +02:00

314 lines
8.0 KiB
C++

#include "battery.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <cpputils.h>
// local includes
#include "drivingstatistics.h"
#include "globals.h"
#include "newsettings.h"
float getBatteryPercentage(float batVoltage, BatteryCellType cellType)
{
const float cellVoltage = batVoltage / configs.battery.cellsSeries.value();
switch (cellType)
{
case BatteryCellType::_22P:
{
const float expected_ah = BAT_MIN_AH_22P;
if (cellVoltage > 4.15f)
return 100.f;
BAT_CURVE_22P(PERCENTAGE);
break;
}
case BatteryCellType::MH1:
{
const float expected_ah = BAT_MIN_AH_MH1;
if (cellVoltage > 4.15f)
return 100.f;
BAT_CURVE_MH1(PERCENTAGE);
break;
}
case BatteryCellType::HG2:
{
const float expected_ah = BAT_MIN_AH_HG2;
if (cellVoltage > 4.15f)
return 100.f;
BAT_CURVE_HG2(PERCENTAGE);
break;
}
case BatteryCellType::VTC5:
{
const float expected_ah = BAT_MIN_AH_VTC5;
if (cellVoltage > 4.15f)
return 100.f;
BAT_CURVE_VTC5(PERCENTAGE);
break;
}
case BatteryCellType::BAK_25R:
{
const float expected_ah = BAT_MIN_AH_BAK_25R;
if(cellVoltage > 4.15f){
return 100.f;
}
BAT_CURVE_25R(PERCENTAGE);
break;
}
case BatteryCellType::HE4:
{
const float expected_ah = BAT_MIN_AH_HE4;
if(cellVoltage > 4.15f){
return 100.f;
}
BAT_CURVE_HE4(PERCENTAGE);
break;
}
}
return 0.f;
}
float getRemainingWattHours()
{
float target_mah = getTarget_mAh();
if (const auto avgVoltage = controllers.getAvgVoltage(); avgVoltage)
{
return (target_mah / 1000.f) * 3.7f * configs.battery.cellsParallel.value() * configs.battery.cellsSeries.value() * (getBatteryPercentage(*avgVoltage, BatteryCellType(configs.battery.cellType.value())) / 100);
}
else
return 0.f;
}
float getPercentageByWh(float wh)
{
const float maxWh = (getTarget_mAh() / 1000.f) * 3.7f * configs.battery.cellsParallel.value() * configs.battery.cellsSeries.value();
return maxWh / wh;
}
float getBatteryWattHours()
{
return (getTarget_mAh() / 1000.f) * 3.7f * configs.battery.cellsParallel.value() * configs.battery.cellsSeries.value();
}
float getTarget_mAh()
{
float target_mah = 2000; //default
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::_22P) target_mah = 2200;
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::HG2) target_mah = 3000;
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::MH1) target_mah = 3200;
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::VTC5) target_mah = 2600;
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::BAK_25R) target_mah = 2500;
if(BatteryCellType(configs.battery.cellType.value()) == BatteryCellType::HE4) target_mah = 2300;
return target_mah;
}
std::string getBatteryPercentageString()
{
if (const auto avgVoltage = controllers.getAvgVoltage(); avgVoltage)
{
std::string output = fmt::format("Battery: {:.1f}%", getBatteryPercentage(*avgVoltage, BatteryCellType(configs.battery.cellType.value())));
return output;
}
else
return "No Battery.";
}
std::string getBatteryAdvancedPercentageString()
{
std::string output = fmt::format("Battery: {:.1f}%", getPercentageByWh(drivingStatistics.batteryWhEstimate));
return output;
}
std::string getBatteryRemainingWattHoursString()
{
return fmt::format("{:.1f}Wh", getRemainingWattHours());
}
std::string getRemainingRangeString()
{
return fmt::format("{:.1f} km", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value());
}
std::string getBatteryDebugString()
{
if (const auto avgVoltage = controllers.getAvgVoltage(); avgVoltage)
{
return fmt::format("{:.1f}V {}A", *avgVoltage, sumCurrent);
}
return "No Battery";
}
float getMinBatCellVoltage(BatteryCellType cellType) {
float minimumVoltage = std::numeric_limits<float>::max();
switch (cellType)
{
case BatteryCellType::_22P:
{
BAT_CURVE_22P(GET_MINIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::HG2:
{
BAT_CURVE_HG2(GET_MINIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::MH1:
{
BAT_CURVE_MH1(GET_MINIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::VTC5:
{
BAT_CURVE_VTC5(GET_MINIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::BAK_25R:
{
BAT_CURVE_25R(GET_MINIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::HE4:
{
BAT_CURVE_HE4(GET_MINIMUM_BAT_VOLTAGE);
break;
}
default:
return 0.f;
}
return minimumVoltage;
}
float getMaxBatCellVoltage(BatteryCellType cellType)
{
switch (cellType)
{
case BatteryCellType::_22P:
{
BAT_CURVE_22P(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::HG2:
{
BAT_CURVE_HG2(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::MH1:
{
BAT_CURVE_MH1(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::VTC5:
{
BAT_CURVE_VTC5(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::BAK_25R:
{
BAT_CURVE_25R(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
case BatteryCellType::HE4:
{
BAT_CURVE_HE4(GET_MAXIMUM_BAT_VOLTAGE);
break;
}
}
return 0.f;
}
uint8_t count_curve_points(BatteryCellType cellType)
{
#define COUNT_CURVE_POINTS(higherVoltage,lowerVoltage,fromAh,toAh) \
count++;
uint8_t count = 0;
switch (cellType)
{
case BatteryCellType::_22P:
{
BAT_CURVE_22P(COUNT_CURVE_POINTS);
break;
}
case BatteryCellType::HG2:
{
BAT_CURVE_HG2(COUNT_CURVE_POINTS);
break;
}
case BatteryCellType::MH1:
{
BAT_CURVE_MH1(COUNT_CURVE_POINTS);
break;
}
case BatteryCellType::VTC5:
{
BAT_CURVE_VTC5(COUNT_CURVE_POINTS);
break;
}
case BatteryCellType::BAK_25R:
{
BAT_CURVE_25R(COUNT_CURVE_POINTS);
break;
}
case BatteryCellType::HE4:
{
BAT_CURVE_HE4(COUNT_CURVE_POINTS);
break;
}
}
return count;
}
std::optional<CalibrationPointVoltages> get_point_n_voltages(BatteryCellType cellType, uint8_t num)
{
#define GET_POINT_N_VOLTAGES(higherVoltage,lowerVoltage,fromAh,toAh) \
if (count == num) { \
uint16_t minVoltage = (lowerVoltage) * 100; \
uint16_t maxVoltage = (higherVoltage) * 100; \
return CalibrationPointVoltages{ .minVoltage=minVoltage, .maxVoltage=maxVoltage }; \
} \
count++;
uint8_t count = 0;
switch (cellType)
{
case BatteryCellType::_22P:
{
BAT_CURVE_22P(GET_POINT_N_VOLTAGES);
break;
}
case BatteryCellType::HG2:
{
BAT_CURVE_HG2(GET_POINT_N_VOLTAGES);
break;
}
case BatteryCellType::MH1:
{
BAT_CURVE_MH1(GET_POINT_N_VOLTAGES);
break;
}
case BatteryCellType::VTC5:
{
BAT_CURVE_VTC5(GET_POINT_N_VOLTAGES);
break;
}
case BatteryCellType::BAK_25R:
{
BAT_CURVE_25R(GET_POINT_N_VOLTAGES);
break;
}
case BatteryCellType::HE4:
{
BAT_CURVE_HE4(GET_POINT_N_VOLTAGES);
break;
}
}
return std::nullopt;
}
namespace battery {
std::optional<float> bootBatPercentage;
std::optional<float> bootBatWh;
}