38#ifndef IMU_INTEGRATION
39#define IMU_INTEGRATION false
43#if defined(IMU_GYRO_CALIB) && (defined(IMU_GYRO_P_SIGN) || defined(IMU_GYRO_Q_SIGN) || defined(IMU_GYRO_R_SIGN))
44#warning "The IMU_GYRO_?_SIGN's aren't compatible with the IMU_GYRO_CALIB define in the airframe"
46#ifndef IMU_GYRO_P_SIGN
47#define IMU_GYRO_P_SIGN 1
49#ifndef IMU_GYRO_Q_SIGN
50#define IMU_GYRO_Q_SIGN 1
52#ifndef IMU_GYRO_R_SIGN
53#define IMU_GYRO_R_SIGN 1
57#if defined(IMU_GYRO_P_NEUTRAL) || defined(IMU_GYRO_Q_NEUTRAL) || defined(IMU_GYRO_R_NEUTRAL)
58#define GYRO_NEUTRAL {IMU_GYRO_P_NEUTRAL, IMU_GYRO_Q_NEUTRAL, IMU_GYRO_R_NEUTRAL}
62#if defined(IMU_GYRO_P_SENS) || defined(IMU_GYRO_Q_SENS) || defined(IMU_GYRO_R_SENS)
63#define GYRO_SCALE {{IMU_GYRO_P_SIGN*IMU_GYRO_P_SENS_NUM, IMU_GYRO_Q_SIGN*IMU_GYRO_Q_SENS_NUM, IMU_GYRO_R_SIGN*IMU_GYRO_R_SENS_NUM}, {IMU_GYRO_P_SENS_DEN, IMU_GYRO_Q_SENS_DEN, IMU_GYRO_R_SENS_DEN}}
67#if defined(GYRO_NEUTRAL) && defined(GYRO_SCALE)
68#define IMU_GYRO_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true, .scale=true}, .neutral=GYRO_NEUTRAL, .scale=GYRO_SCALE}}
69#elif defined(GYRO_NEUTRAL)
70#define IMU_GYRO_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true}, .neutral=GYRO_NEUTRAL}}
71#elif defined(GYRO_SCALE)
72#define IMU_GYRO_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.scale=true}, .scale=GYRO_SCALE}}
73#elif !defined(IMU_GYRO_CALIB)
74#define IMU_GYRO_CALIB {}
77#if defined(IMU_IMU_ACCEL_CALIB)
78#error IMU_IMU_ACCEL_CALIB defined. Rename it "ACCEL_CALIB" if your calibration is in a section with the "IMU_" prefix.
82#if defined(IMU_ACCEL_CALIB) && (defined(IMU_ACCEL_X_SIGN) || defined(IMU_ACCEL_Y_SIGN) || defined(IMU_ACCEL_Z_SIGN))
83#warning "The IMU_ACCEL_?_SIGN's aren't compatible with the IMU_ACCEL_CALIB define in the airframe"
85#ifndef IMU_ACCEL_X_SIGN
86#define IMU_ACCEL_X_SIGN 1
88#ifndef IMU_ACCEL_Y_SIGN
89#define IMU_ACCEL_Y_SIGN 1
91#ifndef IMU_ACCEL_Z_SIGN
92#define IMU_ACCEL_Z_SIGN 1
96#if defined(IMU_ACCEL_X_NEUTRAL) || defined(IMU_ACCEL_Y_NEUTRAL) || defined(IMU_ACCEL_Z_NEUTRAL)
97#define ACCEL_NEUTRAL {IMU_ACCEL_X_NEUTRAL, IMU_ACCEL_Y_NEUTRAL, IMU_ACCEL_Z_NEUTRAL}
101#if defined(IMU_ACCEL_X_SENS) || defined(IMU_ACCEL_Y_SENS) || defined(IMU_ACCEL_Z_SENS)
102#define ACCEL_SCALE {{IMU_ACCEL_X_SIGN*IMU_ACCEL_X_SENS_NUM, IMU_ACCEL_Y_SIGN*IMU_ACCEL_Y_SENS_NUM, IMU_ACCEL_Z_SIGN*IMU_ACCEL_Z_SENS_NUM}, {IMU_ACCEL_X_SENS_DEN, IMU_ACCEL_Y_SENS_DEN, IMU_ACCEL_Z_SENS_DEN}}
106#if defined(ACCEL_NEUTRAL) && defined(ACCEL_SCALE)
107#define IMU_ACCEL_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true, .scale=true}, .neutral=ACCEL_NEUTRAL, .scale=ACCEL_SCALE}}
108#elif defined(ACCEL_NEUTRAL)
109#define IMU_ACCEL_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true}, .neutral=ACCEL_NEUTRAL}}
110#elif defined(ACCEL_SCALE)
111#define IMU_ACCEL_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.scale=true}, .scale=ACCEL_SCALE}}
112#elif !defined(IMU_ACCEL_CALIB)
113#define IMU_ACCEL_CALIB {}
117#if defined(IMU_MAG_CALIB) && (defined(IMU_MAG_X_SIGN) || defined(IMU_MAG_Y_SIGN) || defined(IMU_MAG_Z_SIGN))
118#warning "The IMU_MAG_?_SIGN's aren't compatible with the IMU_MAG_CALIB define in the airframe"
120#ifndef IMU_MAG_X_SIGN
121#define IMU_MAG_X_SIGN 1
123#ifndef IMU_MAG_Y_SIGN
124#define IMU_MAG_Y_SIGN 1
126#ifndef IMU_MAG_Z_SIGN
127#define IMU_MAG_Z_SIGN 1
131#if defined(IMU_MAG_X_NEUTRAL) || defined(IMU_MAG_Y_NEUTRAL) || defined(IMU_MAG_Z_NEUTRAL)
132#define MAG_NEUTRAL {IMU_MAG_X_NEUTRAL, IMU_MAG_Y_NEUTRAL, IMU_MAG_Z_NEUTRAL}
136#if defined(IMU_MAG_X_SENS) || defined(IMU_MAG_Y_SENS) || defined(IMU_MAG_Z_SENS)
137#define MAG_SCALE {{IMU_MAG_X_SIGN*IMU_MAG_X_SENS_NUM, IMU_MAG_Y_SIGN*IMU_MAG_Y_SENS_NUM, IMU_MAG_Z_SIGN*IMU_MAG_Z_SENS_NUM}, {IMU_MAG_X_SENS_DEN, IMU_MAG_Y_SENS_DEN, IMU_MAG_Z_SENS_DEN}}
141#if defined(MAG_NEUTRAL) && defined(MAG_SCALE)
142#define IMU_MAG_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true, .scale=true}, .neutral=MAG_NEUTRAL, .scale=MAG_SCALE}}
143#elif defined(MAG_NEUTRAL)
144#define IMU_MAG_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.neutral=true}, .neutral=MAG_NEUTRAL}}
145#elif defined(MAG_SCALE)
146#define IMU_MAG_CALIB {{.abi_id=ABI_BROADCAST, .calibrated={.scale=true}, .scale=MAG_SCALE}}
147#elif !defined(IMU_MAG_CALIB)
148#define IMU_MAG_CALIB {}
153#if !defined(IMU_BODY_TO_IMU_PHI) && !defined(IMU_BODY_TO_IMU_THETA) && !defined(IMU_BODY_TO_IMU_PSI)
154#define IMU_BODY_TO_IMU_PHI 0
155#define IMU_BODY_TO_IMU_THETA 0
156#define IMU_BODY_TO_IMU_PSI 0
163#ifndef IMU_GYRO_ABI_SEND_ID
164#define IMU_GYRO_ABI_SEND_ID ABI_BROADCAST
169#ifndef IMU_ACCEL_ABI_SEND_ID
170#define IMU_ACCEL_ABI_SEND_ID ABI_BROADCAST
175#ifndef IMU_MAG_ABI_SEND_ID
176#define IMU_MAG_ABI_SEND_ID ABI_BROADCAST
181#ifndef IMU_LOG_HIGHSPEED_DEVICE
182#define IMU_LOG_HIGHSPEED_DEVICE flightrecorder_sdlog
186#if PERIODIC_TELEMETRY
347 chprintf(sh,
" calibrated: neutral %d, scale %d, rotation %d, current %d, filter %d\r\n",
352 chprintf(sh,
" %s: %ld, %ld, %ld\r\n", name, v->
x, v->
y, v->
z);
356 chprintf(sh,
" %s: %f, %f, %f\r\n", name, v->
x, v->
y, v->
z);
360 chprintf(sh,
" %s: %ld, %ld, %ld\r\n", name, r->
p, r->
q, r->
r);
364 chprintf(sh,
" %s: %f, %f, %f\r\n", name, r->
p, r->
q, r->
r);
370 chprintf(sh,
" %ld, %ld, %ld\r\n",
MAT33_ELMT(*m, 0, 0),
MAT33_ELMT(*m, 0, 1),
MAT33_ELMT(*m, 0, 2));
371 chprintf(sh,
" %ld, %ld, %ld\r\n",
MAT33_ELMT(*m, 1, 0),
MAT33_ELMT(*m, 1, 1),
MAT33_ELMT(*m, 1, 2));
372 chprintf(sh,
" %ld, %ld, %ld\r\n",
MAT33_ELMT(*m, 2, 0),
MAT33_ELMT(*m, 2, 1),
MAT33_ELMT(*m, 2, 2));
395 chprintf(sh,
" -> gyro (rad/s): %.3f, %.3f, %.3f\r\n",
gf.p,
gf.q,
gf.r);
410 chprintf(sh,
" -> accel (m/s2): %.3f, %.3f, %.3f\r\n",
af.x,
af.y,
af.z);
425 chprintf(sh,
" -> mag (unit): %.3f, %.3f, %.3f\r\n", mf.x, mf.y, mf.z);
608#if PERIODIC_TELEMETRY
789 integrated.
p = integrated.
p * (1.f / rate);
790 integrated.
q = integrated.
q * (1.f / rate);
791 integrated.
r = integrated.
r * (1.f / rate);
885 integrated.
x = integrated.
x * (1.f / rate);
886 integrated.
y = integrated.
y * (1.f / rate);
887 integrated.
z = integrated.
z * (1.f / rate);
Main include for ABI (AirBorneInterface).
#define ABI_DISABLE
Reserved ABI ID to disable callback.
#define ABI_BROADCAST
Broadcast address.
Event structure to store callbacks in a linked list.
struct FloatVect3 accel_float
struct FloatVect3 mag_float
static struct uart_periph * dev
struct Electrical electrical
Interface for electrical status: supply voltage, current, battery status, etc.
float current
current in A
void chprintf(BaseSequentialStream *lchp, const char *fmt,...)
void float_rmat_transp_ratemult(struct FloatRates *rb, const struct FloatRMat *m_b2a, const struct FloatRates *ra)
rotate anglular rates by transposed rotation matrix.
void float_rmat_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_a2b, const struct FloatVect3 *va)
rotate 3D vector by rotation matrix.
void float_rmat_ratemult(struct FloatRates *rb, const struct FloatRMat *m_a2b, const struct FloatRates *ra)
rotate anglular rates by rotation matrix.
void float_rmat_transp_vmult(struct FloatVect3 *vb, const struct FloatRMat *m_b2a, const struct FloatVect3 *va)
rotate 3D vector by transposed rotation matrix.
#define MAGS_FLOAT_OF_BFP(_ef, _ei)
#define RATES_COPY(_a, _b)
#define RATES_ASSIGN(_ra, _p, _q, _r)
#define EULERS_BFP_OF_REAL(_ei, _ef)
#define RMAT_FLOAT_OF_BFP(_ef, _ei)
#define RMAT_COPY(_o, _i)
#define VECT3_ASSIGN(_a, _x, _y, _z)
#define VECT3_COPY(_a, _b)
#define RATES_FLOAT_OF_BFP(_rf, _ri)
#define MAT33_ELMT(_m, _row, _col)
#define ACCELS_FLOAT_OF_BFP(_ef, _ei)
int32_t p
in rad/s with INT32_RATE_FRAC
int32_t r
in rad/s with INT32_RATE_FRAC
int32_t q
in rad/s with INT32_RATE_FRAC
#define INT_RATES_ZERO(_e)
#define int32_rmat_of_eulers
Rotation matrix from Euler angles.
#define RATE_FLOAT_OF_BFP(_ai)
void int32_rmat_comp_inv(struct Int32RMat *m_a2b, const struct Int32RMat *m_a2c, const struct Int32RMat *m_b2c)
Composition (multiplication) of two rotation matrices.
void int32_rmat_transp_ratemult(struct Int32Rates *rb, struct Int32RMat *m_b2a, struct Int32Rates *ra)
rotate anglular rates by transposed rotation matrix.
#define INT_VECT3_ZERO(_v)
void int32_rmat_transp_vmult(struct Int32Vect3 *vb, struct Int32RMat *m_b2a, struct Int32Vect3 *va)
rotate 3D vector by transposed rotation matrix.
void int32_rmat_comp(struct Int32RMat *m_a2c, const struct Int32RMat *m_a2b, const struct Int32RMat *m_b2c)
Composition (multiplication) of two rotation matrices.
static void int32_rmat_identity(struct Int32RMat *rm)
initialises a rotation matrix to identity
#define ACCEL_FLOAT_OF_BFP(_ai)
static void orientationSetEulers_f(struct OrientationReps *orientation, struct FloatEulers *eulers)
Set vehicle body attitude from euler angles (float).
static struct Int32RMat * orientationGetRMat_i(struct OrientationReps *orientation)
Get vehicle body attitude rotation matrix (int).
static struct FloatEulers * orientationGetEulers_f(struct OrientationReps *orientation)
Get vehicle body attitude euler angles (float).
static bool stateIsAttitudeValid(void)
Test if attitudes are valid.
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
#define IMU_MAG_ABI_SEND_ID
Which mag measurements to send over telemetry/logging.
#define IMU_GYRO_ABI_SEND_ID
Which gyro measurements to send over telemetry/logging.
#define IMU_MAG_CALIB
Default mag calibration is for single IMU with old format.
static void imu_gyro_raw_cb(uint8_t sender_id, uint32_t stamp, struct Int32Rates *data, uint8_t samples, float rate, float temp)
#define IMU_BODY_TO_IMU_THETA
static void send_mag_raw(struct transport_tx *trans, struct link_device *dev)
#define IMU_GYRO_P_SIGN
By default gyro signs are positive for single IMU with old format or defaults.
void imu_set_defaults_gyro(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Rates *neutral, const struct FloatRates *scale_f)
Set the defaults for a gyro sensor WARNING: Should be called before sensor is publishing messages to ...
struct imu_gyro_t * imu_get_gyro(uint8_t sender_id, bool create)
Find or create the gyro in the imu structure.
static abi_event imu_accel_raw_ev
static abi_event imu_mag_raw_ev
#define IMU_MAG_X_SIGN
By default mag signs are positive for single IMU with old format and defaults.
struct imu_accel_t * imu_get_accel(uint8_t sender_id, bool create)
Find or create the accel in the imu structure.
void imu_SetBodyToImuTheta(float theta)
#define IMU_ACCEL_X_SIGN
By default accel signs are positive for single IMU with old format and defaults.
#define IMU_BODY_TO_IMU_PHI
Default body to imu is 0 (radians)
static void imu_accel_raw_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *data, uint8_t samples, float rate, float temp)
void imu_set_defaults_accel(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Vect3 *neutral, const struct FloatVect3 *scale_f)
Set the defaults for a accel sensor WARNING: Should be called before sensor is publishing messages to...
#define IMU_ACCEL_CALIB
Default accel calibration is for single IMU with old format.
#define IMU_LOG_HIGHSPEED_DEVICE
By default log highspeed on the flightrecorder.
static void imu_set_body_to_imu_eulers(struct FloatEulers *body_to_imu_eulers)
Set the body to IMU rotation in eulers This will update all the sensor values.
static void send_mag_scaled(struct transport_tx *trans, struct link_device *dev)
static void send_mag_current(struct transport_tx *trans, struct link_device *dev)
struct Imu imu
global IMU state
#define IMU_BODY_TO_IMU_PSI
#define IMU_GYRO_CALIB
Default gyro calibration is for single IMU with old format.
void imu_init(void)
External functions.
void imu_SetBodyToImuPsi(float psi)
static abi_event imu_gyro_raw_ev
static void send_accel_raw(struct transport_tx *trans, struct link_device *dev)
void imu_SetBodyToImuCurrent(float set)
struct imu_mag_t * imu_get_mag(uint8_t sender_id, bool create)
Find or create the mag in the imu structure.
static void send_gyro_scaled(struct transport_tx *trans, struct link_device *dev)
static void send_gyro(struct transport_tx *trans, struct link_device *dev)
void imu_SetBodyToImuPhi(float phi)
static void send_accel(struct transport_tx *trans, struct link_device *dev)
static void imu_mag_raw_cb(uint8_t sender_id, uint32_t stamp, struct Int32Vect3 *data)
static void send_accel_scaled(struct transport_tx *trans, struct link_device *dev)
static void send_mag(struct transport_tx *trans, struct link_device *dev)
static void send_gyro_raw(struct transport_tx *trans, struct link_device *dev)
#define IMU_ACCEL_ABI_SEND_ID
Which accel measurements to send over telemetry/logging.
void imu_set_defaults_mag(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Vect3 *neutral, const struct FloatVect3 *scale_f)
Set the defaults for a mag sensor WARNING: Should be called before sensor is publishing messages to e...
Inertial Measurement Unit interface.
uint32_t last_stamp
Last measurement timestamp for integration.
struct Int32Rates scaled
Last scaled values in body frame.
struct Int32RMat body_to_sensor
Rotation from body to sensor frame (body to imu combined with imu to sensor)
struct imu_calib_t calibrated
Calibration bitmask.
struct FloatVect3 current_scale
Current scaling multiplying.
struct imu_accel_t accels[IMU_MAX_SENSORS]
The accelerometer sensors.
struct FloatEulers body_to_sensor_f
Rotation from body to sensor frame (with floating points eulers)
uint8_t abi_id
ABI sensor ID.
bool scale
Scale calibrated.
float temperature
Temperature in degrees celcius.
Butterworth2LowPass filter[3]
Lowpass filter optional.
float filter_freq
Lowpass filter frequency (Hz)
struct FloatRates scale_f
Scaling.
uint32_t last_stamp
Last measurement timestamp for integration.
float filter_sample_freq
Lowpass filter sample frequency (Hz)
struct FloatVect3 scale_f
Scaling.
struct Int32Vect3 neutral
Neutral values, compensation on unscaled->scaled.
uint8_t mag_abi_send_id
Filter out and send only a specific ABI id in telemetry for the magnetometer.
struct OrientationReps body_to_imu
Rotation from body to imu (all sensors) frame.
bool filter
Enable the lowpass filter.
struct Int32Vect3 unscaled
Last unscaled values in sensor frame.
bool rot_euler
Rotation calibrated with floating point eulers.
float temperature
Temperature in degrees celcius.
struct Int32Rates neutral
Neutral values, compensation on unscaled->scaled.
bool current
Current calibrated.
struct Int32RMat body_to_sensor
Rotation from body to sensor frame (body to imu combined with imu to sensor)
bool initialized
Check if the IMU is initialized.
struct FloatEulers body_to_sensor_f
Rotation from body to sensor frame (with floating points eulers)
Butterworth2LowPass filter[3]
Lowpass filter optional.
struct imu_calib_t calibrated
Calibration bitmask.
struct FloatVect3 scale_f
Scaling.
struct Int32Vect3 scale[2]
Scaling, first is numerator and second denominator.
bool scale_f
Scale calibrated with floating point.
struct Int32Rates scale[2]
Scaling, first is numerator and second denominator.
float filter_sample_freq
Lowpass filter sample frequency (Hz)
struct Int32Vect3 scaled
Last scaled values in body frame.
struct imu_gyro_t gyros[IMU_MAX_SENSORS]
The gyro sensors.
struct Int32RMat body_to_sensor
Rotation from body to sensor frame (body to imu combined with imu to sensor)
struct Int32Rates unscaled
Last unscaled values in sensor frame.
uint8_t abi_id
ABI sensor ID.
struct imu_mag_t mags[IMU_MAX_SENSORS]
The magnetometer sensors.
struct Int32Vect3 scale[2]
Scaling, first is numerator and second denominator.
bool neutral
Neutral values calibrated.
bool b2i_set_current
flag for adjusting body_to_imu via settings.
struct FloatEulers body_to_sensor_f
Rotation from body to sensor frame (with floating points eulers)
struct Int32Vect3 neutral
Neutral values, compensation on unscaled->scaled.
struct Int32Vect3 unscaled
Last unscaled values in sensor frame.
float filter_freq
Filter frequency.
struct imu_calib_t calibrated
Calibration bitmask.
uint8_t accel_abi_send_id
Filter out and send only a specific ABI id in telemetry for the accelerometer.
struct Int32Vect3 scaled
Last scaled values in body frame.
bool rotation
Rotation calibrated.
uint8_t gyro_abi_send_id
Filter out and send only a specific ABI id in telemetry for the gyro.
uint8_t abi_id
ABI sensor ID.
abstract IMU interface providing fixed point interface
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, const float tau, const float sample_time, const float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, const float value)
Update second order Butterworth low pass filter state with a new value.
static TRICAL_instance_t mag_calib
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
struct pprzlog_transport pprzlog_tp
PPRZLOG transport structure.
Mini printf-like functionality.
void shell_add_entry(char *cmd_name, shell_cmd_t *cmd)
Add dynamic entry.
BaseSequentialStream shell_stream_t
API to get/set the generic vehicle states.
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.