35 #include "generated/airframe.h"
43 #if !defined AHRS_FC_MAG_ID && !defined AHRS_ICE_MAG_ID && !defined AHRS_MLKF_MAG_ID && !defined AHRS_FINV_MAG_ID && \
44 !defined AHRS_DCM_MAG_ID && !defined AHRS_ICQ_MAG_ID && !defined INS_FINV_MAG_ID
45 #warning "your AHRS/INS configuration might be wrong to use onboard mag calibration, please refer to the documentation"
48 #if defined AHRS_FC_MAG_ID && (AHRS_FC_MAG_ID != MAG_CALIB_UKF_ID)
49 #warning "your AHRS_FC_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
52 #if defined AHRS_ICE_MAG_ID && (AHRS_ICE_MAG_ID != MAG_CALIB_UKF_ID)
53 #warning "your AHRS_ICE_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
56 #if defined AHRS_MLKF_MAG_ID && (AHRS_MLKF_MAG_ID != MAG_CALIB_UKF_ID)
57 #warning "your AHRS_MLKF_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
60 #if defined AHRS_FINV_MAG_ID && (AHRS_FINV_MAG_ID != MAG_CALIB_UKF_ID)
61 #warning "your AHRS_FINV_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
64 #if defined AHRS_DCM_MAG_ID && (AHRS_DCM_MAG_ID != MAG_CALIB_UKF_ID)
65 #warning "your AHRS_DCM_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
68 #if defined AHRS_ICQ_MAG_ID && (AHRS_ICQ_MAG_ID != MAG_CALIB_UKF_ID)
69 #warning "your AHRS_ICQ_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
72 #if defined INS_FINV_MAG_ID && (INS_FINV_MAG_ID != MAG_CALIB_UKF_ID)
73 #warning "your INS_FINV_MAG_ID might by wrong please set to MAG_CALIB_UKF_ID to use onboard mag calibration"
81 #ifndef MAG_CALIB_UKF_VERBOSE
82 #define MAG_CALIB_UKF_VERBOSE FALSE
85 #if MAG_CALIB_UKF_VERBOSE
87 #define VERBOSE_PRINT(string,...) fprintf(stderr, "[CALIB_UKF->%s()] " string,__FUNCTION__ , ##__VA_ARGS__)
89 #define VERBOSE_PRINT(...)
93 #ifndef MAG_CALIB_UKF_ABI_BIND_ID
94 #define MAG_CALIB_UKF_ABI_BIND_ID ABI_BROADCAST
98 #ifndef MAG_CALIB_UKF_NORM
99 #define MAG_CALIB_UKF_NORM 1.0f
103 #ifndef MAG_CALIB_UKF_NOISE_RMS
104 #define MAG_CALIB_UKF_NOISE_RMS 2e-1f
109 #ifndef MAG_CALIB_UKF_HOTSTART
110 #define MAG_CALIB_UKF_HOTSTART FALSE
114 #ifndef MAG_CALIB_UKF_HOTSTART_SAVE_FILE
115 #define MAG_CALIB_UKF_HOTSTART_SAVE_FILE /data/ftp/internal_000/mag_ukf_calib.txt
127 static struct
FloatVect3 H = { .
x = AHRS_H_X, .y = AHRS_H_Y, .z = AHRS_H_Z};
129 #if MAG_CALIB_UKF_HOTSTART
131 static char hotstart_file_name[512];
140 #ifdef MAG_CALIB_UKF_INITIAL_STATE
141 float initial_state[12] = MAG_CALIB_UKF_INITIAL_STATE;
142 memcpy(&
mag_calib.state, &initial_state, 12 *
sizeof(
float));
152 float measurement[3] = {0.0f, 0.0f, 0.0f};
153 float calibrated_measurement[3] = {0.0f, 0.0f, 0.0f};
166 if (mag->
x != 0 || mag->
y != 0 || mag->
z != 0) {
171 float expected_mag_field[3] = { expected_measurement.
x, expected_measurement.
y, expected_measurement.
z };
176 TRICAL_estimate_update(&
mag_calib, measurement, expected_mag_field);
177 TRICAL_measurement_calibrate(&
mag_calib, measurement, calibrated_measurement);
187 VERBOSE_PRINT(
"magnetometer measurement (x: %4.2f y: %4.2f z: %4.2f) norm: %4.2f\n", measurement[0], measurement[1], measurement[2], hypot(hypot(measurement[0], measurement[1]), measurement[2]));
189 VERBOSE_PRINT(
"expected measurement (x: %4.2f y: %4.2f z: %4.2f) norm: %4.2f\n", expected_mag_field[0], expected_mag_field[1], expected_mag_field[2], hypot(hypot(expected_mag_field[0], expected_mag_field[1]), expected_mag_field[2]));
190 VERBOSE_PRINT(
"calibrated measurement (x: %4.2f y: %4.2f z: %4.2f) norm: %4.2f\n\n", calibrated_measurement[0], calibrated_measurement[1], calibrated_measurement[2], hypot(hypot(calibrated_measurement[0], calibrated_measurement[1]), calibrated_measurement[2]));
203 H.
x = (float)(h->
x / n);
204 H.
y = (float)(h->
y / n);
205 H.
z = (float)(h->
z / n);
206 VERBOSE_PRINT(
"Updating local magnetic field from geo_mag module (Hx: %4.2f, Hy: %4.2f, Hz: %4.2f)\n",
H.
x,
H.
y,
H.
z);
217 #if MAG_CALIB_UKF_HOTSTART
219 fp = fopen(hotstart_file_name,
"r");
221 fread(
mag_calib.state,
sizeof(
float), 12, fp);
224 "bias {%4.2f, %4.2f, %4.2f}\n"
225 "scale {%4.2f, %4.2f, %4.2f}\n"
226 " {%4.2f, %4.2f, %4.2f}\n"
227 " {%4.2f, %4.2f, %4.2f}\n",
239 #if USE_MAGNETOMETER && MAG_CALIB_UKF_HOTSTART
240 fp = fopen(hotstart_file_name,
"w");
242 fwrite(
mag_calib.state,
sizeof(
float), 12, fp);
245 "bias {%4.2f, %4.2f, %4.2f}\n"
246 "scale {%4.2f, %4.2f, %4.2f}\n"
247 " {%4.2f, %4.2f, %4.2f}\n"
248 " {%4.2f, %4.2f, %4.2f}\n",
Event structure to store callbacks in a linked list.
bool mag_calib_ukf_send_state
#define MAG_CALIB_UKF_NORM
Periodic telemetry system header (includes downlink utility and generated code).
#define MAG_CALIB_UKF_NOISE_RMS
Main include for ABI (AirBorneInterface).
#define MAG_FLOAT_OF_BFP(_ai)
#define MAG_CALIB_UKF_VERBOSE
struct Int32Vect3 calibrated_mag
struct Imu imu
global IMU state
void mag_calib_hotstart_write(void)
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
void mag_calib_send_state(void)
static float float_vect3_norm(struct FloatVect3 *v)
#define VERBOSE_PRINT(...)
void mag_calib_hotstart_read(void)
#define MAG_CALIB_UKF_HOTSTART_SAVE_FILE
#define MAG_BFP_OF_REAL(_af)
void mag_calib_ukf_init(void)
#define MAG_CALIB_UKF_ABI_BIND_ID
void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, const struct FloatVect3 *v_in)
rotate 3D vector by quaternion.
struct Int32Vect3 mag
magnetometer measurements scaled to 1 in BFP with INT32_MAG_FRAC
Inertial Measurement Unit interface.
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
API to get/set the generic vehicle states.
static void mag_calib_update_field(uint8_t sender_id, struct FloatVect3 *h)
Callback function to update reference magnetic field from geo_mag module.
static TRICAL_instance_t mag_calib
static struct FloatVect3 H
#define ABI_BROADCAST
Broadcast address.
Paparazzi double precision floating point algebra.
bool mag_calib_ukf_reset_state
static void mag_calib_ukf_run(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *mag)
Callback function run for every new mag measurement.
#define MAG_CALIB_UKF_HOTSTART