add uncalibrated version of lv soc

This commit is contained in:
Leonard Gies 2025-07-22 18:12:43 +02:00
parent 2c470f43b2
commit 4354b03907
Signed by: l.gies
GPG Key ID: 6F6FB9338EE44F71
4 changed files with 47 additions and 0 deletions

View File

@ -165,6 +165,7 @@ typedef struct {
float tank_pressure_2;
float lv_voltage;
float lv_soc;
uint8_t apps_percent;
float brake_pressure_f;

View File

@ -64,6 +64,24 @@
#define CAN_ID_STW_BUTTONS 0x401
#define CAN_ID_STW_PARAM_SET 0x402
#define NUM_LV_SOC_VOLTAGE_MAP 11
struct { // percent and voltage must be monotonically decreasing
uint8_t percent;
float voltage;
} LV_SOC_VOLTAGE_MAP[NUM_LV_SOC_VOLTAGE_MAP] = {
{.percent = 100, .voltage = 27.20}, //
{.percent = 90, .voltage = 26.80}, //
{.percent = 80, .voltage = 26.56}, //
{.percent = 70, .voltage = 26.40}, //
{.percent = 60, .voltage = 26.16}, //
{.percent = 50, .voltage = 26.08}, //
{.percent = 40, .voltage = 26.00}, //
{.percent = 30, .voltage = 25.76}, //
{.percent = 20, .voltage = 25.60}, //
{.percent = 10, .voltage = 24.00}, //
{.percent = 0, .voltage = 20.00}, //
};
void vehicle_thread_entry(ULONG hfdcan_addr) {
memset(&vehicle_state, 0, sizeof(vehicle_state));
@ -140,6 +158,31 @@ void vehicle_broadcast_buttons(GPIO_PinState *button_states) {
ftcan_transmit(CAN_ID_STW_BUTTONS, &data, 1);
}
float calculate_lv_soc(float lv_voltage) {
// check if lv_voltage is in range of voltage map
if (lv_voltage >= LV_SOC_VOLTAGE_MAP[0].voltage) {
return LV_SOC_VOLTAGE_MAP[0].percent;
}
if (lv_voltage <= LV_SOC_VOLTAGE_MAP[NUM_LV_SOC_VOLTAGE_MAP - 1].voltage) {
return LV_SOC_VOLTAGE_MAP[NUM_LV_SOC_VOLTAGE_MAP - 1].percent;
}
size_t index_upper_volt = 0;
size_t index_lower_volt = 1;
while (index_lower_volt < NUM_LV_SOC_VOLTAGE_MAP && !(lv_voltage <= LV_SOC_VOLTAGE_MAP[index_upper_volt].voltage &&
lv_voltage >= LV_SOC_VOLTAGE_MAP[index_lower_volt].voltage)) {
index_upper_volt++;
index_lower_volt++;
}
// calculate f value between 0 and 1 for linear interpolation
float f = (lv_voltage - LV_SOC_VOLTAGE_MAP[index_lower_volt].voltage) /
(LV_SOC_VOLTAGE_MAP[index_upper_volt].voltage - LV_SOC_VOLTAGE_MAP[index_lower_volt].voltage);
return LV_SOC_VOLTAGE_MAP[index_lower_volt].percent * (1.0 - f) + LV_SOC_VOLTAGE_MAP[index_upper_volt].percent * f;
}
void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data) {
const uint8_t *ptr;
switch (id) {
@ -266,6 +309,7 @@ void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data) {
case CAN_ID_PDU_CURRENT4:
ptr = &data[2];
vehicle_state.lv_voltage = ftcan_unmarshal_signed(&ptr, 2) * 0.001f;
vehicle_state.lv_soc = calculate_lv_soc(vehicle_state.lv_voltage);
break;
case CAN_ID_DASHBOARD:
// TODO

View File

@ -55,6 +55,7 @@ CountedEnum(DataFieldType, size_t,
DF_TankPressure1,
DF_TankPressure2,
DF_LVVoltage,
DF_LVSOC,
DF_APPSPercent,
DF_BPF,
DF_BPR,

View File

@ -307,6 +307,7 @@ NamedFieldDescription dataFieldDescs[] = {
[DF_TankPressure1] = {NamedFieldKind::Float, "TnkPrs1", 3, 1, VEH_FIELD(tank_pressure_1)},
[DF_TankPressure2] = {NamedFieldKind::Float, "TnkPrs2", 3, 1, VEH_FIELD(tank_pressure_2)},
[DF_LVVoltage] = {NamedFieldKind::Float, "LV_V", 2, 2, VEH_FIELD(lv_voltage)},
[DF_LVSOC] = {NamedFieldKind::Float, "LV_SOC", 2, 0, VEH_FIELD(lv_soc)},
[DF_APPSPercent] = {NamedFieldKind::Int, "APPS", 3, 0, VEH_FIELD(apps_percent)},
[DF_BPF] = {NamedFieldKind::Float, "BPF", 3, 1, VEH_FIELD(brake_pressure_f)},
[DF_BPR] = {NamedFieldKind::Float, "BPR", 3, 1, VEH_FIELD(brake_pressure_r)},