40 #include "generated/airframe.h"
49 #define INDI_ALLOWED_G_FACTOR 2.0
67 STABILIZATION_INDI_REF_ERR_P,
68 STABILIZATION_INDI_REF_ERR_Q,
69 STABILIZATION_INDI_REF_ERR_R,
70 STABILIZATION_INDI_REF_RATE_P,
71 STABILIZATION_INDI_REF_RATE_Q,
72 STABILIZATION_INDI_REF_RATE_R,
75 #if STABILIZATION_INDI_USE_ADAPTIVE
81 #ifdef STABILIZATION_INDI_ACT_RATE_LIMIT
82 float act_rate_limit[INDI_NUM_ACT] = STABILIZATION_INDI_ACT_RATE_LIMIT;
85 #ifdef STABILIZATION_INDI_ACT_IS_SERVO
86 bool act_is_servo[INDI_NUM_ACT] = STABILIZATION_INDI_ACT_IS_SERVO;
91 #ifdef STABILIZATION_INDI_ACT_PREF
93 float act_pref[INDI_NUM_ACT] = STABILIZATION_INDI_ACT_PREF;
99 float act_dyn[INDI_NUM_ACT] = STABILIZATION_INDI_ACT_DYN;
102 #ifndef STABILIZATION_INDI_MAX_RATE
103 #define STABILIZATION_INDI_MAX_RATE 6.0
106 #ifdef STABILIZATION_INDI_WLS_PRIORITIES
107 static float Wv[INDI_OUTPUTS] = STABILIZATION_INDI_WLS_PRIORITIES;
110 static float Wv[INDI_OUTPUTS] = {1000, 1000, 1, 100};
133 float mu1[INDI_OUTPUTS] = {0.00001, 0.00001, 0.000003, 0.000002};
155 float g2[INDI_NUM_ACT] = STABILIZATION_INDI_G2;
156 float g1[INDI_OUTPUTS][INDI_NUM_ACT] = {STABILIZATION_INDI_G1_ROLL,
157 STABILIZATION_INDI_G1_PITCH, STABILIZATION_INDI_G1_YAW, STABILIZATION_INDI_G1_THRUST
159 float g1g2[INDI_OUTPUTS][INDI_NUM_ACT];
160 float g1_est[INDI_OUTPUTS][INDI_NUM_ACT];
175 #if PERIODIC_TELEMETRY
179 pprz_msg_send_INDI_G(trans, dev, AC_ID, INDI_NUM_ACT,
g1_est[0],
189 pprz_msg_send_AHRS_REF_QUAT(trans, dev, AC_ID,
223 for (i = 0; i < INDI_OUTPUTS; i++) {
236 for (i = 0; i < INDI_NUM_ACT; i++) {
240 #if PERIODIC_TELEMETRY
271 float sample_time = 1.0 / PERIODIC_FREQUENCY;
274 for (i = 0; i < 3; i++) {
280 for (i = 0; i < INDI_NUM_ACT; i++) {
356 / reference_acceleration.
rate_p;
358 / reference_acceleration.
rate_q;
360 / reference_acceleration.
rate_r;
369 angular_accel_ref.
p = (rate_ref.
p - body_rates->
p) * reference_acceleration.
rate_p;
370 angular_accel_ref.
q = (rate_ref.
q - body_rates->
q) * reference_acceleration.
rate_q;
371 angular_accel_ref.
r = (rate_ref.
r - body_rates->
r) * reference_acceleration.
rate_r;
375 for (i = 0; i < INDI_NUM_ACT; i++) {
381 float v_thrust = 0.0;
387 for (i = 0; i < INDI_NUM_ACT; i++) {
394 for (i = 0; i < INDI_NUM_ACT; i++) {
406 #if STABILIZATION_INDI_ALLOCATION_PSEUDO_INVERSE
408 for (i = 0; i < INDI_NUM_ACT; i++) {
416 for (i = 0; i < INDI_NUM_ACT; i++) {
424 wls_alloc(
indi_du,
indi_v,
du_min,
du_max,
Bwls, 0, 0,
Wv, 0,
du_pref, 10000, 10);
431 for (i = 0; i < INDI_NUM_ACT; i++) {
447 for (i = 0; i < INDI_NUM_ACT; i++) {
454 actuator_state_filt_vectd[i] = (estimation_input_lowpass_filters[i].
o[0] - estimation_input_lowpass_filters[i].
o[1]) * PERIODIC_FREQUENCY;
464 for (i = 0; i < INDI_NUM_ACT; i++) {
480 float rate_vect[3] = {body_rates->
p, body_rates->
q, body_rates->
r};
482 for (i = 0; i < 3; i++) {
488 - measurement_lowpass_filters[i].
o[1]) * PERIODIC_FREQUENCY;
492 estimation_rate_d[i] = (estimation_output_lowpass_filters[i].
o[0] - estimation_output_lowpass_filters[i].
o[1]) * PERIODIC_FREQUENCY;
520 #if USE_EARTH_BOUND_RC_SETPOINT
537 #if INDI_RPM_FEEDBACK
542 float UNUSED prev_actuator_state;
543 for (i = 0; i < INDI_NUM_ACT; i++) {
549 #ifdef STABILIZATION_INDI_ACT_RATE_LIMIT
550 if ((
actuator_state[i] - prev_actuator_state) > act_rate_limit[i]) {
552 }
else if ((
actuator_state[i] - prev_actuator_state) < -act_rate_limit[i]) {
607 float indi_accel_d = (acceleration_lowpass_filter.
o[0]
608 - acceleration_lowpass_filter.
o[1]) * PERIODIC_FREQUENCY;
620 for (i = 0; i < INDI_OUTPUTS; i++) {
622 float ddx_error = - ddx_estimation[i];
624 for (j = 0; j < INDI_NUM_ACT; j++) {
634 for (j = 0; j < INDI_NUM_ACT; j++) {
639 if (fabs(indi_accel_d) > 60.0) {
645 for (j = 0; j < INDI_NUM_ACT; j++) {
657 #if STABILIZATION_INDI_ALLOCATION_PSEUDO_INVERSE
672 for (i = 0; i < INDI_OUTPUTS; i++) {
673 for (j = 0; j < INDI_NUM_ACT; j++) {
687 for (row = 0; row < INDI_OUTPUTS; row++) {
688 for (col = 0; col < INDI_OUTPUTS; col++) {
690 for (i = 0; i < INDI_NUM_ACT; i++) {
691 element = element +
g1g2[row][i] *
g1g2[col][i];
708 for (row = 0; row < INDI_NUM_ACT; row++) {
709 for (col = 0; col < INDI_OUTPUTS; col++) {
711 for (i = 0; i < INDI_OUTPUTS; i++) {
712 element = element +
g1g2[i][row] *
g1g2inv[col][i];
721 #if INDI_RPM_FEEDBACK
723 for (i = 0; i < num_act; i++) {
724 act_obs[i] = (rpm[i] - get_servo_min(i));
725 act_obs[i] *= (
MAX_PPRZ / (float)(get_servo_max(i) - get_servo_min(i)));
744 for (j = 0; j < INDI_NUM_ACT; j++) {
749 for (i = 0; i < INDI_OUTPUTS; i++) {
758 if (
g1_est[i][j] > max_limit) {
761 if (
g1_est[i][j] < min_limit) {
775 if (
g2_est[j] > max_limit) {
778 if (
g2_est[j] < min_limit) {
int32_t psi
in rad with INT32_ANGLE_FRAC
Event structure to store callbacks in a linked list.
float g1g2[INDI_OUTPUTS][INDI_NUM_ACT]
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
static void float_vect_sum(float *o, const float *a, const float *b, const int n)
o = a + b
void stabilization_indi_init(void)
Function that initializes important values upon engaging INDI.
float du_pref[INDI_NUM_ACT]
void stabilization_attitude_read_rc_setpoint_quat_f(struct FloatQuat *q_sp, bool in_flight, bool in_carefree, bool coordinated_turn)
Read attitude setpoint from RC as quaternion Interprets the stick positions as axes.
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static struct Int32Vect3 * stateGetAccelBody_i(void)
Get acceleration in Body coordinates (int).
static void int32_quat_normalize(struct Int32Quat *q)
normalize a quaternion inplace
void stabilization_indi_set_failsafe_setpoint(void)
Function that calculates the failsafe setpoint.
struct ReferenceSystem reference_acceleration
bool indi_thrust_increment_set
void int32_quat_inv_comp(struct Int32Quat *b2c, struct Int32Quat *a2b, struct Int32Quat *a2c)
Composition (multiplication) of two quaternions.
void init_filters(void)
Function that resets the filters to zeros.
float du_min[INDI_NUM_ACT]
Periodic telemetry system header (includes downlink utility and generated code).
General attitude stabilization interface for rotorcrafts.
float * Bwls[INDI_OUTPUTS]
int32_t theta
in rad with INT32_ANGLE_FRAC
void int32_quat_of_eulers(struct Int32Quat *q, struct Int32Eulers *e)
Quaternion from Euler angles.
Simple first order low pass filter with bilinear transform.
int32_t stabilization_attitude_get_heading_i(void)
Butterworth2LowPass actuator_lowpass_filters[INDI_NUM_ACT]
#define STABILIZATION_INDI_MAX_RATE
Maximum rate you can request in RC rate mode (rad/s)
Read an attitude setpoint from the RC.
bool float_mat_inv_4d(float invOut[16], float mat_in[16])
4x4 Matrix inverse
Main include for ABI (AirBorneInterface).
static void calc_g2_element(float dx_error, int8_t j, float mu_extra)
void stabilization_indi_set_rpy_setpoint_i(struct Int32Eulers *rpy)
Butterworth2LowPass acceleration_lowpass_filter
void stabilization_indi_enter(void)
Function that resets important values upon engaging INDI.
pprz_t values[RADIO_CONTROL_NB_CHANNEL]
static void stabilization_indi_calc_cmd(struct Int32Quat *att_err, bool rate_control, bool in_flight)
struct FloatVect3 body_accel_f
static struct Int32Quat * stateGetNedToBodyQuat_i(void)
Get vehicle body attitude quaternion (int).
float indi_v[INDI_OUTPUTS]
static void calc_g1_element(float dx_error, int8_t i, int8_t j, float mu_extra)
void stabilization_indi_run(bool in_flight, bool rate_control)
Butterworth2LowPass estimation_input_lowpass_filters[INDI_NUM_ACT]
float estimation_rate_dd[INDI_NUM_ACT]
float g2_est[INDI_NUM_ACT]
void stabilization_attitude_read_rc_setpoint_quat_earth_bound_f(struct FloatQuat *q_sp, bool in_flight, bool in_carefree, bool coordinated_turn)
float g1_est[INDI_OUTPUTS][INDI_NUM_ACT]
#define PPRZ_ITRIG_SIN(_s, _a)
#define INDI_ALLOWED_G_FACTOR
Hardware independent API for actuators (servos, motor controllers).
float act_dyn[INDI_NUM_ACT]
Paparazzi floating point algebra.
float g1g2_trans_mult[INDI_OUTPUTS][INDI_OUTPUTS]
float du_max[INDI_NUM_ACT]
float ddu_estimation[INDI_NUM_ACT]
static void bound_g_mat(void)
void stabilization_indi_read_rc(bool in_flight, bool in_carefree, bool coordinated_turn)
static void float_vect_zero(float *a, const int n)
a = 0
float act_pref[INDI_NUM_ACT]
#define QUAT_BFP_OF_REAL(_qi, _qf)
int32_t stabilization_att_indi_cmd[COMMANDS_NB]
#define DefaultPeriodic
Set default periodic telemetry.
#define STABILIZATION_INDI_ESTIMATION_FILT_CUTOFF
float g1g2_pseudo_inv[INDI_NUM_ACT][INDI_OUTPUTS]
struct RadioControl radio_control
float estimation_rate_d[INDI_NUM_ACT]
int wls_alloc(float *u, float *v, float *umin, float *umax, float **B, float *u_guess, float *W_init, float *Wv, float *Wu, float *up, float gamma_sq, int imax)
active set algorithm for control allocation
static void float_vect_smul(float *o, const float *a, const float s, const int n)
o = a * s
static void calc_g1g2_pseudo_inv(void)
Function that calculates the pseudo-inverse of (G1+G2).
struct FloatRates angular_accel_ref
#define ACCELS_FLOAT_OF_BFP(_ef, _ei)
static void thrust_cb(uint8_t sender_id, float thrust_increment)
static struct FloatRates * stateGetBodyRates_f(void)
Get vehicle body angular rate (float).
#define THRUST_INCREMENT_ID
static void lms_estimation(void)
Function that estimates the control effectiveness of each actuator online.
static void get_actuator_state(void)
Function that tries to get actuator feedback.
#define QUAT1_FLOAT_OF_BFP(_qi)
static const struct usb_device_descriptor dev
void stabilization_indi_set_earth_cmd_i(struct Int32Vect2 *cmd, int32_t heading)
float actuator_state[INDI_NUM_ACT]
#define STABILIZATION_INDI_FILT_CUTOFF
static void send_indi_g(struct transport_tx *trans, struct link_device *dev)
float du_estimation[INDI_NUM_ACT]
Butterworth2LowPass estimation_output_lowpass_filters[3]
int32_t phi
in rad with INT32_ANGLE_FRAC
float actuator_state_filt_vectd[INDI_NUM_ACT]
API to get/set the generic vehicle states.
bool act_is_servo[INDI_NUM_ACT]
float indi_du[INDI_NUM_ACT]
static void float_vect_scale(float *a, const float s, const int n)
a *= s
static void int32_quat_wrap_shortest(struct Int32Quat *q)
static void float_vect_copy(float *a, const float *b, const int n)
a = b
float act_obs[INDI_NUM_ACT]
int32_t stabilization_cmd[COMMANDS_NB]
Stabilization commands.
static void send_ahrs_ref_quat(struct transport_tx *trans, struct link_device *dev)
float g2_init[INDI_NUM_ACT]
float angular_acceleration[3]
Butterworth2LowPass measurement_lowpass_filters[3]
float indi_u[INDI_NUM_ACT]
Second order low pass filter structure.
static float Wv[INDI_OUTPUTS]
static struct Int32Eulers * stateGetNedToBodyEulers_i(void)
Get vehicle body attitude euler angles (int).
float actuator_state_filt_vect[INDI_NUM_ACT]
float g1_init[INDI_OUTPUTS][INDI_NUM_ACT]
static void rpm_cb(uint8_t sender_id, uint16_t *rpm, uint8_t num_act)
float g1[INDI_OUTPUTS][INDI_NUM_ACT]
float g1g2inv[INDI_OUTPUTS][INDI_OUTPUTS]
float actuator_state_filt_vectdd[INDI_NUM_ACT]
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
float indi_thrust_increment
struct Int32Quat stab_att_sp_quat
with INT32_QUAT_FRAC
struct Int32Eulers stab_att_sp_euler
with INT32_ANGLE_FRAC
#define PPRZ_ITRIG_COS(_c, _a)