Skip to content

Commit 8f6e10e

Browse files
efuse fault handling overhaul
1 parent 8a96b39 commit 8f6e10e

File tree

20 files changed

+628
-313
lines changed

20 files changed

+628
-313
lines changed

firmware/quintuna/VC/CMakeLists.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ list(APPEND IO_SRCS
2929
"${SHARED_IO_INCLUDE_DIR}/io_led.c"
3030
"${SHARED_IO_INCLUDE_DIR}/io_time.c"
3131
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse.c"
32-
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST/io_efuse_ST.c"
33-
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI/io_efuse_TI.c"
32+
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.c"
33+
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.c"
3434
"${SHARED_IO_INCLUDE_DIR}/io_potentiometer.c"
3535
"${SHARED_IO_INCLUDE_DIR}/io_bootHandler.c"
3636
"${SHARED_IO_INCLUDE_DIR}/io_imu.c"
3737
)
38-
set(IO_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/io" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_TI" "${CMAKE_CURRENT_SOURCE_DIR}/src/io/io_efuse/io_efuse_ST" "${SHARED_IO_INCLUDE_DIR}" "${SHARED_IO_INCLUDE_QUINTUNA_DIR}")
38+
set(IO_INCLUDE_DIRS
39+
"${CMAKE_CURRENT_SOURCE_DIR}/src/io"
40+
"${SHARED_IO_INCLUDE_DIR}"
41+
"${SHARED_IO_INCLUDE_DIR}/io_efuse"
42+
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_TI_TPS25"
43+
"${SHARED_IO_INCLUDE_DIR}/io_efuse/io_efuse_ST_VND5"
44+
"${SHARED_IO_INCLUDE_QUINTUNA_DIR}"
45+
)
3946

4047
file(GLOB_RECURSE HW_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/hw/*.c")
4148
list(APPEND HW_SRCS

firmware/quintuna/VC/src/io/io_efuses.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,57 @@
22
#include "hw_gpios.h"
33
#include "hw_i2cs.h"
44
#include "io_efuses.h"
5-
#include "io_efuse/io_efuse_ST/io_efuse_ST.h"
6-
#include "io_efuse/io_efuse_TI/io_efuse_TI.h"
7-
8-
static ST_Efuse f_inv_st_efuse = { .stby_reset_gpio = &fr_stby_inv };
9-
static ST_Efuse rsm_st_efuse = { .stby_reset_gpio = &fr_stby_inv };
10-
static ST_Efuse bms_st_efuse = { .stby_reset_gpio = &fr_stby_front };
11-
static ST_Efuse r_inv_st_efuse = { .stby_reset_gpio = &fr_stby_front };
12-
static ST_Efuse dam_st_efuse = { .stby_reset_gpio = &fr_stby_rear };
13-
static ST_Efuse front_st_efuse = { .stby_reset_gpio = &fr_stby_rear };
14-
static TI_Efuse rl_pump_ti_efuse = { .pgood = &rl_pump_pgood };
15-
static ST_Efuse r_rad_fan_st_efuse = { .stby_reset_gpio = &fr_stby_rad };
5+
#include "io_efuse/io_efuse_ST_VND5/io_efuse_ST_VND5.h"
6+
#include "io_efuse/io_efuse_TI_TPS25/io_efuse_TI_TPS25.h"
7+
8+
static ST_VND5_Efuse f_inv_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_inv };
9+
static ST_VND5_Efuse rsm_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_inv };
10+
static ST_VND5_Efuse bms_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_front };
11+
static ST_VND5_Efuse r_inv_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_front };
12+
static ST_VND5_Efuse dam_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rear };
13+
static ST_VND5_Efuse front_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rear };
14+
static TI_TPS25_Efuse rl_pump_TI_TPS25_Efuse = { .pgood = &rl_pump_pgood };
15+
static ST_VND5_Efuse r_rad_fan_ST_VND5_Efuse = { .stby_reset_gpio = &fr_stby_rad };
1616

1717
const Efuse f_inv_efuse = { .enable_gpio = &f_inv_en,
1818
.sns_adc_channel = &inv_f_pwr_i_sns,
19-
.st = &f_inv_st_efuse,
20-
.efuse_functions = &st_efuse_functions };
19+
.st_vnd5 = &f_inv_ST_VND5_Efuse,
20+
.efuse_functions = &ST_VND5_Efuse_functions };
2121

2222
const Efuse rsm_efuse = { .enable_gpio = &rsm_en,
2323
.sns_adc_channel = &rsm_i_sns,
24-
.st = &f_inv_st_efuse,
25-
.efuse_functions = &st_efuse_functions };
24+
.st_vnd5 = &f_inv_ST_VND5_Efuse,
25+
.efuse_functions = &ST_VND5_Efuse_functions };
2626

2727
const Efuse bms_efuse = { .enable_gpio = &bms_en,
2828
.sns_adc_channel = &bms_i_sns,
29-
.st = &bms_st_efuse,
30-
.efuse_functions = &st_efuse_functions };
29+
.st_vnd5 = &bms_ST_VND5_Efuse,
30+
.efuse_functions = &ST_VND5_Efuse_functions };
3131

3232
const Efuse r_inv_efuse = { .enable_gpio = &r_inv_en,
3333
.sns_adc_channel = &inv_r_pwr_i_sns,
34-
.st = &r_inv_st_efuse,
35-
.efuse_functions = &st_efuse_functions };
34+
.st_vnd5 = &r_inv_ST_VND5_Efuse,
35+
.efuse_functions = &ST_VND5_Efuse_functions };
3636

3737
const Efuse dam_efuse = { .enable_gpio = &dam_en,
3838
.sns_adc_channel = &dam_i_sns,
39-
.st = &dam_st_efuse,
40-
.efuse_functions = &st_efuse_functions };
39+
.st_vnd5 = &dam_ST_VND5_Efuse,
40+
.efuse_functions = &ST_VND5_Efuse_functions };
4141

4242
const Efuse front_efuse = { .enable_gpio = &front_en,
4343
.sns_adc_channel = &front_i_sns,
44-
.st = &front_st_efuse,
45-
.efuse_functions = &st_efuse_functions };
44+
.st_vnd5 = &front_ST_VND5_Efuse,
45+
.efuse_functions = &ST_VND5_Efuse_functions };
4646

4747
const Efuse rl_pump_efuse = { .enable_gpio = &rl_pump_en,
4848
.sns_adc_channel = &pump_rl_pwr_i_sns,
49-
.ti = &rl_pump_ti_efuse,
50-
.efuse_functions = &ti_efuse_functions };
49+
.ti_tps25 = &rl_pump_TI_TPS25_Efuse,
50+
.efuse_functions = &TI_TPS25_Efuse_functions };
5151

5252
const Efuse r_rad_fan_efuse = { .enable_gpio = &rr_rad_fan_en,
5353
.sns_adc_channel = &r_rad_fan_i_sns,
54-
.st = &r_rad_fan_st_efuse,
55-
.efuse_functions = &ti_efuse_functions };
54+
.st_vnd5 = &r_rad_fan_ST_VND5_Efuse,
55+
.efuse_functions = &TI_TPS25_Efuse_functions };
5656

5757
const Efuse *const efuse_channels[NUM_EFUSE_CHANNELS] = {
5858
[EFUSE_CHANNEL_F_INV] = &f_inv_efuse, [EFUSE_CHANNEL_RSM] = &rsm_efuse,

firmware/shared/src/app/app_ekf.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#pragma once
2+
3+
#include "app_math.h"
4+
5+
/**
6+
* General Extended Kalman Filter API
7+
*
8+
* How to use:
9+
*
10+
* 1) Include in your file like this along with the dimensions
11+
* #define DIM x
12+
* #include "app_ekf.h"
13+
*
14+
* 2) Define the functions in the function pointers
15+
*
16+
* 3) Define your measurement functions in your estimator api
17+
* (They are not stored in the ekf struct which will allow multiple
18+
* measurement functions and thus multiple sensors if required)
19+
*
20+
* Note: If you have more than 2 sensors for the update/measurement step,
21+
* usually you will need the same amount of measurement functions.
22+
* Thus, the user must swap the measurement functions in the ekf struct
23+
* before calling the update step again with the new measurements
24+
* Explain why velocity estimator is an exception
25+
*/
26+
27+
typedef struct
28+
{
29+
// estimations
30+
Matrix state_estimate;
31+
Matrix covariance_estimate;
32+
// internal variables
33+
Matrix F_jacobian;
34+
Matrix H_jacobian;
35+
Matrix measurement_pred;
36+
// user implementable functions functions
37+
void (*state_transition)(Matrix *state_estimate, Matrix *prev_state, Matrix *control_input);
38+
void (*state_jacobian)(Matrix *F_jacobian, Matrix *prev_state, Matrix *control_input);
39+
void (*measurement_jacobian)(Matrix *H_jacobian, Matrix *prev_state);
40+
void (*measurement_func)(Matrix *measurement_pred, Matrix *prev_state);
41+
} EKF;
42+
43+
static inline void predict(EKF *ekf, Matrix *prev_state, Matrix *control_input, Matrix *process_noise_cov)
44+
{
45+
Matrix temp_cov = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
46+
Matrix F_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
47+
48+
// state prediction
49+
ekf->state_transition(&ekf->state_estimate, prev_state, control_input);
50+
ekf->state_jacobian(&ekf->F_jacobian, prev_state, control_input);
51+
52+
// prediction covariance prediction
53+
mult(&temp_cov, &ekf->F_jacobian, &ekf->covariance_estimate);
54+
transpose(&F_transpose, &ekf->F_jacobian);
55+
mult(&ekf->covariance_estimate, &temp_cov, &F_transpose);
56+
add(&ekf->covariance_estimate, &ekf->covariance_estimate, process_noise_cov);
57+
}
58+
59+
/**
60+
* Updates the prediction, gives the final, corrected state and covariance estimate
61+
* with measured values given previous state and noise covariance
62+
*
63+
* measurement pred is obtained from your measurement function
64+
*/
65+
static inline void update(EKF *ekf, Matrix *measurement, Matrix *prev_state, Matrix *measurement_noise_cov)
66+
{
67+
Matrix PH_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
68+
Matrix Ky = { .mat = (float[DIM * 1U]){ 0.0f }, .rows = DIM, .cols = 1 };
69+
Matrix H_transpose = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
70+
Matrix S = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
71+
Matrix S_inv = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
72+
Matrix K = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
73+
Matrix residual = { .mat = (float[DIM * 1U]){ 0.0f }, .rows = DIM, .cols = 1 };
74+
Matrix KH = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
75+
Matrix KHP = { .mat = (float[DIM * DIM]){ 0.0f }, .rows = DIM, .cols = DIM };
76+
77+
// measurement prediction
78+
ekf->measurement_func(&ekf->measurement_pred, prev_state);
79+
ekf->measurement_jacobian(&ekf->H_jacobian, prev_state);
80+
81+
// measurement covariance prediction
82+
transpose(&H_transpose, &ekf->H_jacobian);
83+
mult(&PH_transpose, &ekf->covariance_estimate, &H_transpose);
84+
mult(&S, &ekf->H_jacobian, &PH_transpose);
85+
add(&S, &S, measurement_noise_cov);
86+
87+
// kalman gain calculation
88+
inverse2x2(&S_inv, &S);
89+
mult(&K, &PH_transpose, &S_inv);
90+
91+
// measurement residual calculation
92+
sub(&residual, measurement, &ekf->measurement_pred);
93+
94+
// state estimation
95+
mult(&Ky, &K, &residual);
96+
add(&ekf->state_estimate, prev_state, &Ky);
97+
98+
// covariance estimation
99+
mult(&KH, &K, &ekf->H_jacobian);
100+
mult(&KHP, &KH, &ekf->covariance_estimate);
101+
sub(&ekf->covariance_estimate, &ekf->covariance_estimate, &KHP);
102+
}

firmware/shared/src/io/io_efuse/io_efuse_ST/io_efuse_ST.c

Lines changed: 0 additions & 83 deletions
This file was deleted.

0 commit comments

Comments
 (0)