diff --git a/conf/airframes/TUDELFT/tudelft_bebop_indi.xml b/conf/airframes/TUDELFT/tudelft_bebop_indi.xml
index bea1065a23..74bd47bd05 100644
--- a/conf/airframes/TUDELFT/tudelft_bebop_indi.xml
+++ b/conf/airframes/TUDELFT/tudelft_bebop_indi.xml
@@ -100,7 +100,7 @@
-
+
@@ -139,6 +139,9 @@
+
+
+
diff --git a/conf/settings/control/stabilization_indi.xml b/conf/settings/control/stabilization_indi.xml
index bd73eb2301..4a7e550136 100644
--- a/conf/settings/control/stabilization_indi.xml
+++ b/conf/settings/control/stabilization_indi.xml
@@ -15,7 +15,8 @@
-
+
+
diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c
index dc283914c4..6eb4076e90 100644
--- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c
+++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.c
@@ -71,6 +71,10 @@
#warning "Use caution with adaptive indi. See the wiki for more info"
#endif
+#ifndef STABILIZATION_INDI_MAX_R
+#define STABILIZATION_INDI_MAX_R STABILIZATION_ATTITUDE_SP_MAX_R
+#endif
+
struct Int32Eulers stab_att_sp_euler;
struct Int32Quat stab_att_sp_quat;
@@ -83,6 +87,7 @@ static inline void lms_estimation(void);
#define INDI_EST_SCALE 0.001 //The G values are scaled to avoid numerical problems during the estimation
struct IndiVariables indi = {
.max_rate = STABILIZATION_INDI_MAX_RATE,
+ .attitude_max_yaw_rate = STABILIZATION_INDI_MAX_R,
.g1 = {STABILIZATION_INDI_G1_P, STABILIZATION_INDI_G1_Q, STABILIZATION_INDI_G1_R},
.g2 = STABILIZATION_INDI_G2_R,
@@ -206,28 +211,33 @@ static inline void stabilization_indi_calc_cmd(int32_t indi_commands[], struct I
struct FloatRates *body_rates = stateGetBodyRates_f();
stabilization_indi_second_order_filter(&indi.rate, body_rates);
+ //The rates used for feedback are by default the measured rates. If needed they can be filtered (see below)
+ struct FloatRates rates_for_feedback;
+ RATES_COPY(rates_for_feedback, (*body_rates));
+
+ //If there is a lot of noise on the gyroscope, it might be good to use the filtered value for feedback.
+ //Note that due to the delay, the PD controller can not be as aggressive.
#if STABILIZATION_INDI_FILTER_ROLL_RATE
- indi.angular_accel_ref.p = indi.reference_acceleration.err_p * QUAT1_FLOAT_OF_BFP(att_err->qx)
- - indi.reference_acceleration.rate_p * indi.rate.x.p;
-#else
- indi.angular_accel_ref.p = indi.reference_acceleration.err_p * QUAT1_FLOAT_OF_BFP(att_err->qx)
- - indi.reference_acceleration.rate_p * body_rates->p;
+ rates_for_feedback.p = indi.rate.x.p;
#endif
#if STABILIZATION_INDI_FILTER_PITCH_RATE
- indi.angular_accel_ref.q = indi.reference_acceleration.err_q * QUAT1_FLOAT_OF_BFP(att_err->qy)
- - indi.reference_acceleration.rate_q * indi.rate.x.q;
-#else
- indi.angular_accel_ref.q = indi.reference_acceleration.err_q * QUAT1_FLOAT_OF_BFP(att_err->qy)
- - indi.reference_acceleration.rate_q * body_rates->q;
+ rates_for_feedback.q = indi.rate.x.q;
#endif
#if STABILIZATION_INDI_FILTER_YAW_RATE
- indi.angular_accel_ref.r = indi.reference_acceleration.err_r * QUAT1_FLOAT_OF_BFP(att_err->qz)
- - indi.reference_acceleration.rate_r * indi.rate.x.r;
-#else
- indi.angular_accel_ref.r = indi.reference_acceleration.err_r * QUAT1_FLOAT_OF_BFP(att_err->qz)
- - indi.reference_acceleration.rate_r * body_rates->r;
+ rates_for_feedback.r = indi.rate.x.r;
#endif
+ indi.angular_accel_ref.p = indi.reference_acceleration.err_p * QUAT1_FLOAT_OF_BFP(att_err->qx)
+ - indi.reference_acceleration.rate_p * rates_for_feedback.p;
+
+ indi.angular_accel_ref.q = indi.reference_acceleration.err_q * QUAT1_FLOAT_OF_BFP(att_err->qy)
+ - indi.reference_acceleration.rate_q * rates_for_feedback.q;
+
+ //This separates the P and D controller and lets you impose a maximum yaw rate.
+ float rate_ref_r = indi.reference_acceleration.err_r * QUAT1_FLOAT_OF_BFP(att_err->qz)/indi.reference_acceleration.rate_r;
+ BoundAbs(rate_ref_r, indi.attitude_max_yaw_rate);
+ indi.angular_accel_ref.r = indi.reference_acceleration.rate_r * (rate_ref_r - rates_for_feedback.r);
+
/* Check if we are running the rate controller and overwrite */
if(rate_control) {
indi.angular_accel_ref.p = indi.reference_acceleration.rate_p * ((float)radio_control.values[RADIO_ROLL] / MAX_PPRZ * indi.max_rate - body_rates->p);
diff --git a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.h b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.h
index c703f50de8..1b211888f5 100644
--- a/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.h
+++ b/sw/airborne/firmwares/rotorcraft/stabilization/stabilization_indi.h
@@ -82,7 +82,8 @@ struct IndiVariables {
struct ReferenceSystem reference_acceleration;
bool adaptive; ///< Enable adataptive estimation
- float max_rate; ///< Maximum rate in rate control
+ float max_rate; ///< Maximum rate in rate control in rad/s
+ float attitude_max_yaw_rate; ///< Maximum yaw rate in atttiude control in rad/s
struct IndiEstimation est; ///< Estimation parameters for adaptive INDI
};