paparazzi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paparazzi-commits] [5009] new horizontal control loop


From: Gautier Hattenberger
Subject: [paparazzi-commits] [5009] new horizontal control loop
Date: Tue, 29 Jun 2010 10:57:18 +0000

Revision: 5009
          http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=5009
Author:   gautier
Date:     2010-06-29 10:57:17 +0000 (Tue, 29 Jun 2010)
Log Message:
-----------
new horizontal control loop

Modified Paths:
--------------
    paparazzi3/trunk/sw/airborne/fw_h_ctl_a.c
    paparazzi3/trunk/sw/airborne/fw_h_ctl_a.h

Modified: paparazzi3/trunk/sw/airborne/fw_h_ctl_a.c
===================================================================
--- paparazzi3/trunk/sw/airborne/fw_h_ctl_a.c   2010-06-28 11:23:00 UTC (rev 
5008)
+++ paparazzi3/trunk/sw/airborne/fw_h_ctl_a.c   2010-06-29 10:57:17 UTC (rev 
5009)
@@ -1,7 +1,7 @@
 /*
  * Paparazzi $Id: fw_h_ctl.c 3603 2009-07-01 20:06:53Z hecto $
  *  
- * Copyright (C) 2006  Pascal Brisset, Antoine Drouin, Michel Gorraz
+ * Copyright (C) 2009-2010 ENAC
  *
  * This file is part of paparazzi.
  *
@@ -60,33 +60,41 @@
 float h_ctl_ref_pitch_angle;
 float h_ctl_ref_pitch_rate;
 float h_ctl_ref_pitch_accel;
-#define H_CTL_REF_W 10.
+#define H_CTL_REF_W 2.5
 #define H_CTL_REF_XI 0.85
+#define H_CTL_REF_MAX_P RadOfDeg(100.)
+#define H_CTL_REF_MAX_P_DOT RadOfDeg(500.)
+#define H_CTL_REF_MAX_Q RadOfDeg(100.)
+#define H_CTL_REF_MAX_Q_DOT RadOfDeg(500.)
 
 /* inner roll loop parameters */
-float  h_ctl_roll_setpoint;
+float h_ctl_roll_setpoint;
 float h_ctl_roll_attitude_gain;
 float h_ctl_roll_rate_gain;
-float  h_ctl_roll_igain;
-float  h_ctl_pitch_igain;
-float  h_ctl_roll_sum_err;
-float  h_ctl_pitch_sum_err;
-float h_ctl_roll_Kff;
+float h_ctl_roll_igain;
+float h_ctl_roll_sum_err;
+float h_ctl_roll_Kffa;
+float h_ctl_roll_Kffd;
 pprz_t h_ctl_aileron_setpoint;
-float  h_ctl_roll_slew;
+float h_ctl_roll_slew;
 
-float  h_ctl_roll_pgain;
+float h_ctl_roll_pgain;
 
 /* inner pitch loop parameters */
-float  h_ctl_pitch_setpoint;
-float  h_ctl_pitch_loop_setpoint;
-float  h_ctl_pitch_pgain;
-float  h_ctl_pitch_dgain;
+float h_ctl_pitch_setpoint;
+float h_ctl_pitch_loop_setpoint;
+float h_ctl_pitch_pgain;
+float h_ctl_pitch_dgain;
+float h_ctl_pitch_igain;
+float h_ctl_pitch_sum_err;
+float h_ctl_pitch_Kffa;
+float h_ctl_pitch_Kffd;
 pprz_t h_ctl_elevator_setpoint;
 
 /* inner loop pre-command */
 float h_ctl_aileron_of_throttle;
 float h_ctl_elevator_of_roll;
+float h_ctl_pitch_of_roll; // Should be used instead of elevator_of_roll
 
 
 inline static void h_ctl_roll_loop( void );
@@ -104,10 +112,6 @@
 #define H_CTL_ROLL_RATE_GAIN 0.
 #endif
 
-#ifdef AGR_CLIMB
-static float nav_ratio;
-#endif
-
 void h_ctl_init( void ) {
   h_ctl_course_setpoint = 0.;
   h_ctl_course_pre_bank = 0.;
@@ -119,6 +123,12 @@
   h_ctl_disabled = FALSE;
 
   h_ctl_roll_setpoint = 0.;
+  h_ctl_roll_attitude_gain = H_CTL_ROLL_ATTITUDE_GAIN;
+  h_ctl_roll_rate_gain = H_CTL_ROLL_RATE_GAIN;
+  h_ctl_roll_igain = H_CTL_ROLL_IGAIN;
+  h_ctl_roll_sum_err = 0;
+  h_ctl_roll_Kffa = H_CTL_ROLL_KFFA;
+  h_ctl_roll_Kffd = H_CTL_ROLL_KFFD;
   h_ctl_aileron_setpoint = 0;
 #ifdef H_CTL_AILERON_OF_THROTTLE
   h_ctl_aileron_of_throttle = H_CTL_AILERON_OF_THROTTLE;
@@ -128,19 +138,16 @@
   h_ctl_pitch_loop_setpoint = 0.;
   h_ctl_pitch_pgain = H_CTL_PITCH_PGAIN;
   h_ctl_pitch_dgain = H_CTL_PITCH_DGAIN;
+  h_ctl_pitch_igain = H_CTL_PITCH_IGAIN;
+  h_ctl_pitch_sum_err = 0.;
+  h_ctl_pitch_Kffa = H_CTL_PITCH_KFFA;
+  h_ctl_pitch_Kffd = H_CTL_PITCH_KFFD;
   h_ctl_elevator_setpoint = 0;
-  h_ctl_elevator_of_roll = H_CTL_ELEVATOR_OF_ROLL;
+  h_ctl_elevator_of_roll = 0; //H_CTL_ELEVATOR_OF_ROLL;
+#ifdef H_CTL_PITCH_OF_ROLL
+  h_ctl_pitch_of_roll = H_CTL_PITCH_OF_ROLL;
+#endif
 
-  h_ctl_roll_attitude_gain = H_CTL_ROLL_ATTITUDE_GAIN;
-  h_ctl_roll_rate_gain = H_CTL_ROLL_RATE_GAIN;
-
-  h_ctl_roll_igain = H_CTL_ROLL_IGAIN;
-  h_ctl_roll_sum_err = 0;
-  h_ctl_roll_Kff = H_CTL_ROLL_KFF;
-
-#ifdef AGR_CLIMB
-nav_ratio=0;
-#endif
 }
 
 /** 
@@ -156,44 +163,21 @@
 
   float d_err = err - last_err;
   last_err = err;
-
   NormRadAngle(d_err);
 
   float speed_depend_nav = estimator_hspeed_mod/NOMINAL_AIRSPEED; 
   Bound(speed_depend_nav, 0.66, 1.5);
 
-  float cmd = h_ctl_course_pgain * speed_depend_nav * (err + d_err * 
h_ctl_course_dgain);
+  h_ctl_roll_setpoint = h_ctl_course_pre_bank_correction * 
h_ctl_course_pre_bank
+    + h_ctl_course_pgain * speed_depend_nav * err
+    + h_ctl_course_dgain * d_err;
 
-
-
-#if defined AGR_CLIMB
-  /** limit navigation during extreme altitude changes */
-  if (AGR_BLEND_START > AGR_BLEND_END && AGR_BLEND_END > 0) { /* prevent 
divide by zero, reversed or negative values */
-    if (v_ctl_auto_throttle_submode == V_CTL_AUTO_THROTTLE_AGRESSIVE || 
V_CTL_AUTO_THROTTLE_BLENDED) {
-      BoundAbs(cmd, h_ctl_roll_max_setpoint); /* bound cmd before NAV_RATIO 
and again after */
-      if (v_ctl_altitude_error < 0) {
-       nav_ratio = AGR_CLIMB_NAV_RATIO + (1 - AGR_CLIMB_NAV_RATIO) * (1 - 
(fabs(v_ctl_altitude_error) - AGR_BLEND_END) / (AGR_BLEND_START - 
AGR_BLEND_END));
-       Bound (nav_ratio, AGR_CLIMB_NAV_RATIO, 1);
-      } else {
-       nav_ratio = AGR_DESCENT_NAV_RATIO + (1 - AGR_DESCENT_NAV_RATIO) * (1 - 
(fabs(v_ctl_altitude_error) - AGR_BLEND_END) / (AGR_BLEND_START - 
AGR_BLEND_END));
-       Bound (nav_ratio, AGR_DESCENT_NAV_RATIO, 1);
-      }
-      cmd *= nav_ratio;
-    }
-  }
-#endif
-
-  float roll_setpoint = cmd + h_ctl_course_pre_bank_correction * 
h_ctl_course_pre_bank;
-
-  h_ctl_roll_setpoint = roll_setpoint;
-
   BoundAbs(h_ctl_roll_setpoint, h_ctl_roll_max_setpoint);
 }
 
 static float airspeed_ratio2;
 
-void h_ctl_attitude_loop ( void ) {
-  if (!h_ctl_disabled) {
+static inline void compute_airspeed_ratio( void ) {
     float throttle_diff =  v_ctl_throttle_setpoint / (float)MAX_PPRZ - 
v_ctl_auto_throttle_nominal_cruise_throttle;
     float airspeed = NOMINAL_AIRSPEED; /* Estimated from the throttle */
     if (throttle_diff > 0)
@@ -204,61 +188,109 @@
     float airspeed_ratio = airspeed / NOMINAL_AIRSPEED;
     Bound(airspeed_ratio, 0.5, 2.);
     airspeed_ratio2 = airspeed_ratio*airspeed_ratio;
+}
+
+void h_ctl_attitude_loop ( void ) {
+  if (!h_ctl_disabled) {
+    // compute_airspeed_ratio();
     h_ctl_roll_loop();
     h_ctl_pitch_loop();
   }
 }
 
 #define H_CTL_REF_DT (1./60.)
+#define KFFA_UPDATE 0.1
+#define KFFD_UPDATE 0.05
 
 inline static void h_ctl_roll_loop( void ) {
 
+  static float cmd_fb = 0.;
+
   if (pprz_mode == PPRZ_MODE_MANUAL)
     h_ctl_roll_sum_err = 0;
 
+  // Update reference setpoints for roll
+  h_ctl_ref_roll_angle += h_ctl_ref_roll_rate * H_CTL_REF_DT;
+  h_ctl_ref_roll_rate += h_ctl_ref_roll_accel * H_CTL_REF_DT;
   h_ctl_ref_roll_accel = H_CTL_REF_W*H_CTL_REF_W * (h_ctl_roll_setpoint - 
h_ctl_ref_roll_angle) - 2*H_CTL_REF_XI*H_CTL_REF_W * h_ctl_ref_roll_rate;
-  h_ctl_ref_roll_rate += h_ctl_ref_roll_accel * H_CTL_REF_DT;
-  h_ctl_ref_roll_angle += h_ctl_ref_roll_rate * H_CTL_REF_DT;
+  // Saturation on references
+  BoundAbs(h_ctl_ref_roll_accel, H_CTL_REF_MAX_P_DOT);
+  if (h_ctl_ref_roll_rate > H_CTL_REF_MAX_P) {
+    h_ctl_ref_roll_rate = H_CTL_REF_MAX_P;
+    if (h_ctl_ref_roll_accel > 0.) h_ctl_ref_roll_accel = 0.;
+  }
+  else if (h_ctl_ref_roll_rate < - H_CTL_REF_MAX_P) {
+    h_ctl_ref_roll_rate = - H_CTL_REF_MAX_P;
+    if (h_ctl_ref_roll_accel < 0.) h_ctl_ref_roll_accel = 0.;
+  }
 
+#ifdef USE_KFF_UPDATE
+  // update Kff gains
+  h_ctl_roll_Kffa -= KFFA_UPDATE * h_ctl_ref_roll_accel * cmd_fb / 
(H_CTL_REF_MAX_P_DOT*H_CTL_REF_MAX_P_DOT);
+  h_ctl_roll_Kffd -= KFFD_UPDATE * h_ctl_ref_roll_rate  * cmd_fb / 
(H_CTL_REF_MAX_P*H_CTL_REF_MAX_P);
+#ifdef SITL
+  printf("%f %f %f\n", h_ctl_roll_Kffa, h_ctl_roll_Kffd, cmd_fb);
+#endif
+  h_ctl_roll_Kffa = Min(h_ctl_roll_Kffa, 0);
+  h_ctl_roll_Kffd = Min(h_ctl_roll_Kffd, 0);
+#endif
+
+  // Compute errors
   float err = estimator_phi - h_ctl_ref_roll_angle;
 #ifdef SITL
   static float last_err = 0;
   estimator_p = (err - last_err)/(1/60.);
   last_err = err;
 #endif
-  float derr = estimator_p - h_ctl_ref_roll_rate;
+  float d_err = (estimator_p - h_ctl_ref_roll_rate) / H_CTL_REF_DT;
+
   h_ctl_roll_sum_err += err * H_CTL_REF_DT;
   BoundAbs(h_ctl_roll_sum_err, H_CTL_ROLL_SUM_ERR_MAX);
-  float cmd = h_ctl_roll_Kff * h_ctl_ref_roll_accel
-    - h_ctl_roll_attitude_gain * err
-    - h_ctl_roll_rate_gain * derr
+
+  cmd_fb = h_ctl_roll_attitude_gain * err;// + h_ctl_roll_rate_gain * derr;
+  float cmd = h_ctl_roll_Kffa * h_ctl_ref_roll_accel
+    + h_ctl_roll_Kffd * h_ctl_ref_roll_rate
+    - cmd_fb
+    - h_ctl_roll_rate_gain * d_err
     - h_ctl_roll_igain * h_ctl_roll_sum_err
     + v_ctl_throttle_setpoint * h_ctl_aileron_of_throttle;
+  //float cmd = h_ctl_roll_Kffp * h_ctl_ref_roll_accel
+  //  + h_ctl_roll_Kffd * h_ctl_ref_roll_rate
+  //  - h_ctl_roll_attitude_gain * err
+  //  - h_ctl_roll_rate_gain * derr
+  //  - h_ctl_roll_igain * h_ctl_roll_sum_err
+  //  + v_ctl_throttle_setpoint * h_ctl_aileron_of_throttle;
 
   //x  cmd /= airspeed_ratio2;
 
+  // Set aileron commands
   h_ctl_aileron_setpoint = TRIM_PPRZ(cmd); 
 }
 
 
+// NOT USED
 #ifdef LOITER_TRIM
 float v_ctl_auto_throttle_loiter_trim = V_CTL_AUTO_THROTTLE_LOITER_TRIM;
 float v_ctl_auto_throttle_dash_trim = V_CTL_AUTO_THROTTLE_DASH_TRIM;
+#endif
 
+#ifdef PITCH_TRIM
+float v_ctl_pitch_loiter_trim = V_CTL_PITCH_LOITER_TRIM;
+float v_ctl_pitch_dash_trim = V_CTL_PITCH_DASH_TRIM;
 
-inline static float loiter(void) {
-  float elevator_trim;
+inline static void loiter(void) {
+  float pitch_trim;
 
-  float throttle_dif = v_ctl_auto_throttle_cruise_throttle - 
v_ctl_auto_throttle_nominal_cruise_throttle;
-  if (throttle_dif > 0) {
-    float max_dif = Max(V_CTL_AUTO_THROTTLE_MAX_CRUISE_THROTTLE - 
v_ctl_auto_throttle_nominal_cruise_throttle, 0.1);
-    elevator_trim = throttle_dif / max_dif * v_ctl_auto_throttle_dash_trim;
+  float throttle_diff = v_ctl_throttle_setpoint / (float)MAX_PPRZ - 
v_ctl_auto_throttle_nominal_cruise_throttle;
+  if (throttle_diff > 0) {
+    float max_diff = Max(V_CTL_AUTO_THROTTLE_MAX_CRUISE_THROTTLE - 
v_ctl_auto_throttle_nominal_cruise_throttle, 0.1);
+    pitch_trim = throttle_diff / max_diff * v_ctl_pitch_dash_trim;
   } else {
-    float max_dif = Max(v_ctl_auto_throttle_nominal_cruise_throttle - 
V_CTL_AUTO_THROTTLE_MIN_CRUISE_THROTTLE, 0.1);
-    elevator_trim = - throttle_dif / max_dif * v_ctl_auto_throttle_loiter_trim;
+    float max_diff = Max(v_ctl_auto_throttle_nominal_cruise_throttle - 
V_CTL_AUTO_THROTTLE_MIN_CRUISE_THROTTLE, 0.1);
+    pitch_trim = -throttle_diff / max_diff * v_ctl_pitch_loiter_trim;
   }
 
-  return elevator_trim / h_ctl_pitch_pgain; /* Normalisation to keep 
historical values */
+  h_ctl_pitch_loop_setpoint += pitch_trim;
 }
 #endif
 
@@ -266,33 +298,46 @@
 inline static void h_ctl_pitch_loop( void ) {
   static float last_err;
   /* sanity check */
-  if (h_ctl_elevator_of_roll <0.)
-    h_ctl_elevator_of_roll = 0.;
+  if (h_ctl_pitch_of_roll <0.)
+    h_ctl_pitch_of_roll = 0.;
 
-  h_ctl_pitch_loop_setpoint =
-    h_ctl_pitch_setpoint 
-    - h_ctl_elevator_of_roll / h_ctl_pitch_pgain * fabs(estimator_phi);
+  if (pprz_mode == PPRZ_MODE_MANUAL)
+    h_ctl_pitch_sum_err = 0;
 
+  h_ctl_pitch_loop_setpoint = h_ctl_pitch_setpoint + h_ctl_pitch_of_roll * 
fabs(estimator_phi);
+#ifdef PITCH_TRIM
+  loiter();
+#endif
+
+  // Update reference setpoints for pitch
   h_ctl_ref_pitch_accel = H_CTL_REF_W*H_CTL_REF_W * (h_ctl_pitch_loop_setpoint 
- h_ctl_ref_pitch_angle) - 2*H_CTL_REF_XI*H_CTL_REF_W * h_ctl_ref_pitch_rate;
   h_ctl_ref_pitch_rate += h_ctl_ref_pitch_accel * H_CTL_REF_DT;
   h_ctl_ref_pitch_angle += h_ctl_ref_pitch_rate * H_CTL_REF_DT;
+  // Saturation on references
+  BoundAbs(h_ctl_ref_pitch_accel, H_CTL_REF_MAX_Q_DOT);
+  if (h_ctl_ref_pitch_rate > H_CTL_REF_MAX_Q) {
+    h_ctl_ref_pitch_rate = H_CTL_REF_MAX_Q;
+    if (h_ctl_ref_pitch_accel > 0.) h_ctl_ref_pitch_accel = 0.;
+  }
+  else if (h_ctl_ref_pitch_rate < - H_CTL_REF_MAX_Q) {
+    h_ctl_ref_pitch_rate = - H_CTL_REF_MAX_Q;
+    if (h_ctl_ref_pitch_accel < 0.) h_ctl_ref_pitch_accel = 0.;
+  }
 
-#ifdef LOITER_TRIM
-  h_ctl_pitch_loop_setpoint -= loiter();
-#endif
-
+  // Compute errors
   float err = estimator_theta - h_ctl_ref_pitch_angle;
+  float d_err = (err - last_err)/H_CTL_REF_DT - h_ctl_ref_pitch_rate;
+  last_err = err;
 
-  if (pprz_mode == PPRZ_MODE_MANUAL)
-    h_ctl_pitch_sum_err = 0;
   h_ctl_pitch_sum_err += err * H_CTL_REF_DT;
   BoundAbs(h_ctl_pitch_sum_err, H_CTL_ROLL_SUM_ERR_MAX);
 
+  float cmd = h_ctl_pitch_Kffa * h_ctl_ref_pitch_accel
+    + h_ctl_pitch_Kffd * h_ctl_ref_pitch_rate
+    + h_ctl_pitch_pgain * err
+    + h_ctl_pitch_dgain * d_err
+    + h_ctl_pitch_igain * h_ctl_pitch_sum_err;
 
-  float d_err = (err - last_err)/H_CTL_REF_DT - h_ctl_ref_pitch_rate;
-  last_err = err;
-  float cmd = h_ctl_pitch_pgain * err + h_ctl_pitch_dgain * d_err + 
h_ctl_pitch_igain * h_ctl_pitch_sum_err;
-
   //  cmd /= airspeed_ratio2;
 
   h_ctl_elevator_setpoint = TRIM_PPRZ(cmd);

Modified: paparazzi3/trunk/sw/airborne/fw_h_ctl_a.h
===================================================================
--- paparazzi3/trunk/sw/airborne/fw_h_ctl_a.h   2010-06-28 11:23:00 UTC (rev 
5008)
+++ paparazzi3/trunk/sw/airborne/fw_h_ctl_a.h   2010-06-29 10:57:17 UTC (rev 
5009)
@@ -40,8 +40,14 @@
 extern float h_ctl_pitch_sum_err;
 extern float h_ctl_roll_igain;
 extern float h_ctl_pitch_igain;
-extern float h_ctl_roll_Kff;
+extern float h_ctl_roll_Kffa;
+extern float h_ctl_roll_Kffd;
+extern float h_ctl_pitch_Kffa;
+extern float h_ctl_pitch_Kffd;
+extern float h_ctl_pitch_of_roll;
+
 #define H_CTL_ROLL_SUM_ERR_MAX 100.
+#define H_CTL_PITCH_SUM_ERR_MAX 100.
 
 #define fw_h_ctl_a_SetRollIGain(_gain) { \
   h_ctl_roll_sum_err = 0; \




reply via email to

[Prev in Thread] Current Thread [Next in Thread]