diff --git a/conf/settings/tuning_ctl_new.xml b/conf/settings/tuning_ctl_new.xml index 8ace2c0b9e..d283b907fb 100644 --- a/conf/settings/tuning_ctl_new.xml +++ b/conf/settings/tuning_ctl_new.xml @@ -16,7 +16,7 @@ - + @@ -56,8 +56,12 @@ - - + + + + + + diff --git a/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.c b/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.c index fcc14344f1..6daedeaa1a 100644 --- a/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.c +++ b/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.c @@ -57,7 +57,7 @@ float v_ctl_auto_throttle_pgain; float v_ctl_auto_throttle_igain; float v_ctl_auto_throttle_dgain; float v_ctl_auto_throttle_sum_err; -#define V_CTL_AUTO_THROTTLE_MAX_SUM_ERR 0.3 +#define V_CTL_AUTO_THROTTLE_MAX_SUM_ERR 0.4 float v_ctl_auto_throttle_pitch_of_vz_pgain; float v_ctl_auto_throttle_pitch_of_vz_dgain; @@ -91,14 +91,20 @@ uint8_t v_ctl_speed_mode; #ifdef USE_AIRSPEED float v_ctl_auto_airspeed_setpoint; float v_ctl_auto_airspeed_controlled; -float v_ctl_auto_airspeed_pgain; -float v_ctl_auto_airspeed_igain; -float v_ctl_auto_airspeed_sum_err; +float v_ctl_auto_airspeed_throttle_pgain; +float v_ctl_auto_airspeed_throttle_dgain; +float v_ctl_auto_airspeed_throttle_igain; +float v_ctl_auto_airspeed_throttle_sum_err; +float v_ctl_auto_airspeed_pitch_pgain; +float v_ctl_auto_airspeed_pitch_dgain; +float v_ctl_auto_airspeed_pitch_igain; +float v_ctl_auto_airspeed_pitch_sum_err; float v_ctl_auto_groundspeed_setpoint; float v_ctl_auto_groundspeed_pgain; float v_ctl_auto_groundspeed_igain; float v_ctl_auto_groundspeed_sum_err; -#define V_CTL_AUTO_AIRSPEED_MAX_SUM_ERR 200 +#define V_CTL_AUTO_AIRSPEED_PITCH_MAX_SUM_ERR (RadOfDeg(15.)) +#define V_CTL_AUTO_AIRSPEED_THROTTLE_MAX_SUM_ERR 0.2 #define V_CTL_AUTO_GROUNDSPEED_MAX_SUM_ERR 100 #endif @@ -139,9 +145,14 @@ void v_ctl_init( void ) { #ifdef USE_AIRSPEED v_ctl_auto_airspeed_setpoint = V_CTL_AUTO_AIRSPEED_SETPOINT; v_ctl_auto_airspeed_controlled = V_CTL_AUTO_AIRSPEED_SETPOINT; - v_ctl_auto_airspeed_pgain = V_CTL_AUTO_AIRSPEED_PGAIN; - v_ctl_auto_airspeed_igain = V_CTL_AUTO_AIRSPEED_IGAIN; - v_ctl_auto_airspeed_sum_err = 0.; + v_ctl_auto_airspeed_throttle_pgain = V_CTL_AUTO_AIRSPEED_THROTTLE_PGAIN; + v_ctl_auto_airspeed_throttle_dgain = V_CTL_AUTO_AIRSPEED_THROTTLE_DGAIN; + v_ctl_auto_airspeed_throttle_igain = V_CTL_AUTO_AIRSPEED_THROTTLE_IGAIN; + v_ctl_auto_airspeed_throttle_sum_err = 0.; + v_ctl_auto_airspeed_pitch_pgain = V_CTL_AUTO_AIRSPEED_PITCH_PGAIN; + v_ctl_auto_airspeed_pitch_dgain = V_CTL_AUTO_AIRSPEED_PITCH_DGAIN; + v_ctl_auto_airspeed_pitch_igain = V_CTL_AUTO_AIRSPEED_PITCH_IGAIN; + v_ctl_auto_airspeed_pitch_sum_err = 0.; v_ctl_auto_groundspeed_setpoint = V_CTL_AUTO_GROUNDSPEED_SETPOINT; v_ctl_auto_groundspeed_pgain = V_CTL_AUTO_GROUNDSPEED_PGAIN; @@ -236,17 +247,69 @@ static inline void v_ctl_set_throttle( void ) { } #ifdef USE_AIRSPEED +#define AIRSPEED_LOOP_PERIOD (1./60.) + +// Airspeed control loop (input: [airspeed controlled, climb_setpoint], output: [throttle controlled, pitch setpoint]) static inline void v_ctl_set_airspeed( void ) { + static float last_err_vz = 0.; + static float last_err_as = 0.; + // Bound airspeed setpoint Bound(v_ctl_auto_airspeed_setpoint, V_CTL_AIRSPEED_MIN, V_CTL_AIRSPEED_MAX); - // Airspeed control loop (input: airspeed controlled, output: throttle controlled) + // Compute errors + float err_vz = estimator_z_dot - v_ctl_climb_setpoint; + float d_err_vz = (err_vz - last_err_vz)*AIRSPEED_LOOP_PERIOD; + last_err_vz = err_vz; + if (v_ctl_auto_throttle_igain < 0.) { + v_ctl_auto_throttle_sum_err += err_vz*AIRSPEED_LOOP_PERIOD; + BoundAbs(v_ctl_auto_throttle_sum_err, V_CTL_AUTO_THROTTLE_MAX_SUM_ERR / (-v_ctl_auto_throttle_igain)); + } + if (v_ctl_auto_pitch_igain < 0.) { + v_ctl_auto_pitch_sum_err += err_vz*AIRSPEED_LOOP_PERIOD; + BoundAbs(v_ctl_auto_pitch_sum_err, V_CTL_AUTO_PITCH_MAX_SUM_ERR / (-v_ctl_auto_pitch_igain)); + } + float err_airspeed = v_ctl_auto_airspeed_setpoint - estimator_airspeed; - v_ctl_auto_airspeed_sum_err += err_airspeed; - BoundAbs(v_ctl_auto_airspeed_sum_err, V_CTL_AUTO_AIRSPEED_MAX_SUM_ERR); + float d_err_airspeed = (err_airspeed - last_err_as)*AIRSPEED_LOOP_PERIOD; + last_err_as = err_airspeed; + if (v_ctl_auto_airspeed_throttle_igain > 0.) { // ! sign + v_ctl_auto_airspeed_throttle_sum_err += err_airspeed*AIRSPEED_LOOP_PERIOD; + BoundAbs(v_ctl_auto_airspeed_throttle_sum_err, V_CTL_AUTO_AIRSPEED_THROTTLE_MAX_SUM_ERR / v_ctl_auto_airspeed_throttle_igain); + } + if (v_ctl_auto_airspeed_pitch_igain > 0.) { // ! sign + v_ctl_auto_airspeed_pitch_sum_err += err_airspeed*AIRSPEED_LOOP_PERIOD; + BoundAbs(v_ctl_auto_airspeed_pitch_sum_err, V_CTL_AUTO_AIRSPEED_PITCH_MAX_SUM_ERR / v_ctl_auto_airspeed_pitch_igain); + } + + + // Reset integrators in manual or before flight + if (pprz_mode == PPRZ_MODE_MANUAL || launch == 0) { + v_ctl_auto_throttle_sum_err = 0.; + v_ctl_auto_pitch_sum_err = 0.; + v_ctl_auto_airspeed_throttle_sum_err = 0.; + v_ctl_auto_airspeed_pitch_sum_err = 0.; + } + + // Pitch loop + nav_pitch = 0. //nav_pitch FIXME it really sucks ! + + v_ctl_auto_throttle_pitch_of_vz_pgain * v_ctl_climb_setpoint + + v_ctl_auto_pitch_pgain * err_vz + + v_ctl_auto_pitch_dgain * d_err_vz + + v_ctl_auto_pitch_igain * v_ctl_auto_pitch_sum_err + - v_ctl_auto_airspeed_pitch_pgain * err_airspeed + - v_ctl_auto_airspeed_pitch_dgain * d_err_airspeed + - v_ctl_auto_airspeed_pitch_igain * v_ctl_auto_airspeed_pitch_sum_err; + + // Throttle loop controlled_throttle = v_ctl_auto_throttle_cruise_throttle - + v_ctl_auto_airspeed_pgain * err_airspeed - + v_ctl_auto_airspeed_igain * v_ctl_auto_airspeed_sum_err; + + v_ctl_auto_throttle_climb_throttle_increment * v_ctl_climb_setpoint + + v_ctl_auto_throttle_pgain * err_vz + + v_ctl_auto_throttle_dgain * d_err_vz + + v_ctl_auto_throttle_igain * v_ctl_auto_throttle_sum_err + + v_ctl_auto_airspeed_throttle_pgain * err_airspeed + + v_ctl_auto_airspeed_throttle_dgain * d_err_airspeed + + v_ctl_auto_airspeed_throttle_igain * v_ctl_auto_airspeed_throttle_sum_err; } @@ -262,13 +325,11 @@ static inline void v_ctl_set_groundspeed( void ) { void v_ctl_climb_loop ( void ) { - // Set pitch - v_ctl_set_pitch(); - Bound(nav_pitch, V_CTL_AUTO_PITCH_MIN_PITCH, V_CTL_AUTO_PITCH_MAX_PITCH); - - // Set throttle switch (v_ctl_speed_mode) { case V_CTL_SPEED_THROTTLE: + // Set pitch + v_ctl_set_pitch(); + // Set throttle v_ctl_set_throttle(); break; #ifdef USE_AIRSPEED @@ -285,6 +346,8 @@ void v_ctl_climb_loop ( void ) { break; } + // Set Pitch output + Bound(nav_pitch, V_CTL_AUTO_PITCH_MIN_PITCH, V_CTL_AUTO_PITCH_MAX_PITCH); // Set Throttle output v_ctl_throttle_setpoint = TRIM_UPPRZ(controlled_throttle * MAX_PPRZ); diff --git a/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.h b/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.h index d020a8cbb2..20cf4fa143 100644 --- a/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.h +++ b/sw/airborne/firmwares/fixedwing/guidance/guidance_v_n.h @@ -36,6 +36,14 @@ #define V_CTL_SPEED_GROUNDSPEED 2 extern float v_ctl_auto_pitch_dgain; +extern float v_ctl_auto_airspeed_throttle_pgain; +extern float v_ctl_auto_airspeed_throttle_dgain; +extern float v_ctl_auto_airspeed_throttle_igain; +extern float v_ctl_auto_airspeed_throttle_sum_err; +extern float v_ctl_auto_airspeed_pitch_pgain; +extern float v_ctl_auto_airspeed_pitch_dgain; +extern float v_ctl_auto_airspeed_pitch_igain; +extern float v_ctl_auto_airspeed_pitch_sum_err; extern uint8_t v_ctl_speed_mode;