add uncalibrated version of lv soc
This commit is contained in:
@ -165,6 +165,7 @@ typedef struct {
|
|||||||
float tank_pressure_2;
|
float tank_pressure_2;
|
||||||
|
|
||||||
float lv_voltage;
|
float lv_voltage;
|
||||||
|
float lv_soc;
|
||||||
|
|
||||||
uint8_t apps_percent;
|
uint8_t apps_percent;
|
||||||
float brake_pressure_f;
|
float brake_pressure_f;
|
||||||
|
|||||||
@ -64,6 +64,24 @@
|
|||||||
#define CAN_ID_STW_BUTTONS 0x401
|
#define CAN_ID_STW_BUTTONS 0x401
|
||||||
#define CAN_ID_STW_PARAM_SET 0x402
|
#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) {
|
void vehicle_thread_entry(ULONG hfdcan_addr) {
|
||||||
memset(&vehicle_state, 0, sizeof(vehicle_state));
|
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);
|
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) {
|
void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data) {
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
switch (id) {
|
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:
|
case CAN_ID_PDU_CURRENT4:
|
||||||
ptr = &data[2];
|
ptr = &data[2];
|
||||||
vehicle_state.lv_voltage = ftcan_unmarshal_signed(&ptr, 2) * 0.001f;
|
vehicle_state.lv_voltage = ftcan_unmarshal_signed(&ptr, 2) * 0.001f;
|
||||||
|
vehicle_state.lv_soc = calculate_lv_soc(vehicle_state.lv_voltage);
|
||||||
break;
|
break;
|
||||||
case CAN_ID_DASHBOARD:
|
case CAN_ID_DASHBOARD:
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
@ -55,6 +55,7 @@ CountedEnum(DataFieldType, size_t,
|
|||||||
DF_TankPressure1,
|
DF_TankPressure1,
|
||||||
DF_TankPressure2,
|
DF_TankPressure2,
|
||||||
DF_LVVoltage,
|
DF_LVVoltage,
|
||||||
|
DF_LVSOC,
|
||||||
DF_APPSPercent,
|
DF_APPSPercent,
|
||||||
DF_BPF,
|
DF_BPF,
|
||||||
DF_BPR,
|
DF_BPR,
|
||||||
|
|||||||
@ -307,6 +307,7 @@ NamedFieldDescription dataFieldDescs[] = {
|
|||||||
[DF_TankPressure1] = {NamedFieldKind::Float, "TnkPrs1", 3, 1, VEH_FIELD(tank_pressure_1)},
|
[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_TankPressure2] = {NamedFieldKind::Float, "TnkPrs2", 3, 1, VEH_FIELD(tank_pressure_2)},
|
||||||
[DF_LVVoltage] = {NamedFieldKind::Float, "LV_V", 2, 2, VEH_FIELD(lv_voltage)},
|
[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_APPSPercent] = {NamedFieldKind::Int, "APPS", 3, 0, VEH_FIELD(apps_percent)},
|
||||||
[DF_BPF] = {NamedFieldKind::Float, "BPF", 3, 1, VEH_FIELD(brake_pressure_f)},
|
[DF_BPF] = {NamedFieldKind::Float, "BPF", 3, 1, VEH_FIELD(brake_pressure_f)},
|
||||||
[DF_BPR] = {NamedFieldKind::Float, "BPR", 3, 1, VEH_FIELD(brake_pressure_r)},
|
[DF_BPR] = {NamedFieldKind::Float, "BPR", 3, 1, VEH_FIELD(brake_pressure_r)},
|
||||||
|
|||||||
Reference in New Issue
Block a user