34 #include "generated/airframe.h"
68 float h_ctl_yaw_rate_setpoint;
69 pprz_t h_ctl_rudder_setpoint;
74 pprz_t h_ctl_flaps_setpoint;
86 #ifdef H_CTL_RATE_LOOP
87 float h_ctl_roll_rate_setpoint;
88 float h_ctl_roll_rate_mode;
89 float h_ctl_roll_rate_setpoint_pgain;
90 float h_ctl_hi_throttle_roll_rate_pgain;
91 float h_ctl_lo_throttle_roll_rate_pgain;
92 float h_ctl_roll_rate_igain;
93 float h_ctl_roll_rate_dgain;
96 #ifdef H_CTL_COURSE_SLEW_INCREMENT
97 float h_ctl_course_slew_increment;
103 #ifdef H_CTL_RATE_LOOP
104 static inline void h_ctl_roll_rate_loop(
void);
107 #ifndef H_CTL_COURSE_PRE_BANK_CORRECTION
108 #define H_CTL_COURSE_PRE_BANK_CORRECTION 1.
111 #ifndef H_CTL_COURSE_DGAIN
112 #define H_CTL_COURSE_DGAIN 0.
115 #ifndef H_CTL_ROLL_RATE_GAIN
116 #define H_CTL_ROLL_RATE_GAIN 0.
123 static float nav_ratio;
126 #if PERIODIC_TELEMETRY
145 h_ctl_pitch_mode = 0;
151 #ifdef H_CTL_ROLL_PGAIN
155 #ifdef H_CTL_AILERON_OF_THROTTLE
166 #ifdef H_CTL_RATE_LOOP
167 h_ctl_roll_rate_mode = H_CTL_ROLL_RATE_MODE_DEFAULT;
168 h_ctl_roll_rate_setpoint_pgain = H_CTL_ROLL_RATE_SETPOINT_PGAIN;
169 h_ctl_hi_throttle_roll_rate_pgain = H_CTL_HI_THROTTLE_ROLL_RATE_PGAIN;
170 h_ctl_lo_throttle_roll_rate_pgain = H_CTL_LO_THROTTLE_ROLL_RATE_PGAIN;
171 h_ctl_roll_rate_igain = H_CTL_ROLL_RATE_IGAIN;
172 h_ctl_roll_rate_dgain = H_CTL_ROLL_RATE_DGAIN;
175 #ifdef H_CTL_ROLL_SLEW
179 #ifdef H_CTL_COURSE_SLEW_INCREMENT
180 h_ctl_course_slew_increment = H_CTL_COURSE_SLEW_INCREMENT;
183 #ifdef H_CTL_ROLL_ATTITUDE_GAIN
192 #if PERIODIC_TELEMETRY
203 static float last_err;
211 const float reference_advance = (NOMINAL_AIRSPEED / 2.);
237 if (advance < -0.5) {
239 }
else if (advance < 0.) {
240 err = (-advance) * 2. * herr;
260 float d_err = err - last_err;
265 #ifdef H_CTL_COURSE_SLEW_INCREMENT
267 static float h_ctl_course_slew_rate = 0.;
269 float half_nav_angle_saturation = nav_angle_saturation / 2.;
271 if (err > half_nav_angle_saturation) {
272 h_ctl_course_slew_rate =
Max(h_ctl_course_slew_rate, 0.);
273 err =
Min(err, (half_nav_angle_saturation + h_ctl_course_slew_rate));
274 h_ctl_course_slew_rate += h_ctl_course_slew_increment;
275 }
else if (err < -half_nav_angle_saturation) {
276 h_ctl_course_slew_rate =
Min(h_ctl_course_slew_rate, 0.);
277 err =
Max(err, (-half_nav_angle_saturation + h_ctl_course_slew_rate));
278 h_ctl_course_slew_rate -= h_ctl_course_slew_increment;
280 h_ctl_course_slew_rate = 0.;
286 Bound(speed_depend_nav, 0.66, 1.5);
292 #if defined(AGR_CLIMB) && !USE_AIRSPEED
294 if (AGR_BLEND_START > AGR_BLEND_END && AGR_BLEND_END > 0) {
300 nav_ratio = AGR_CLIMB_NAV_RATIO + (1 - AGR_CLIMB_NAV_RATIO) * (1 - (fabs(
v_ctl_altitude_error) - AGR_BLEND_END) /
301 (AGR_BLEND_START - AGR_BLEND_END));
302 Bound(nav_ratio, AGR_CLIMB_NAV_RATIO, 1);
304 nav_ratio = AGR_DESCENT_NAV_RATIO + (1 - AGR_DESCENT_NAV_RATIO) * (1 - (fabs(
v_ctl_altitude_error) - AGR_BLEND_END) /
305 (AGR_BLEND_START - AGR_BLEND_END));
306 Bound(nav_ratio, AGR_DESCENT_NAV_RATIO, 1);
315 #ifdef H_CTL_ROLL_SLEW
335 #ifdef H_CTL_ROLL_ATTITUDE_GAIN
341 static float last_err = 0;
342 body_rate->
p = (err - last_err) / (1 / 60.);
352 #else // H_CTL_ROLL_ATTITUDE_GAIN
362 #ifdef H_CTL_RATE_LOOP
366 h_ctl_roll_rate_loop();
368 h_ctl_roll_rate_setpoint = h_ctl_roll_rate_setpoint_pgain * err;
369 BoundAbs(h_ctl_roll_rate_setpoint, H_CTL_ROLL_RATE_MAX_SETPOINT);
372 h_ctl_roll_rate_loop();
378 #ifdef H_CTL_RATE_LOOP
380 static inline void h_ctl_roll_rate_loop()
385 static float roll_rate_sum_err = 0.;
386 static uint8_t roll_rate_sum_idx = 0;
387 static float roll_rate_sum_values[H_CTL_ROLL_RATE_SUM_NB_SAMPLES];
389 roll_rate_sum_err -= roll_rate_sum_values[roll_rate_sum_idx];
390 roll_rate_sum_values[roll_rate_sum_idx] = err;
391 roll_rate_sum_err += err;
393 if (roll_rate_sum_idx >= H_CTL_ROLL_RATE_SUM_NB_SAMPLES) { roll_rate_sum_idx = 0; }
396 static float last_err = 0;
397 float d_err = err - last_err;
400 float throttle_dep_pgain =
401 Blend(h_ctl_hi_throttle_roll_rate_pgain, h_ctl_lo_throttle_roll_rate_pgain,
403 float cmd = throttle_dep_pgain * (err + h_ctl_roll_rate_igain * roll_rate_sum_err / H_CTL_ROLL_RATE_SUM_NB_SAMPLES +
404 h_ctl_roll_rate_dgain * d_err);
419 float v_ctl_auto_throttle_loiter_trim = V_CTL_AUTO_THROTTLE_LOITER_TRIM;
420 float v_ctl_auto_throttle_dash_trim = V_CTL_AUTO_THROTTLE_DASH_TRIM;
422 inline static float loiter(
void)
424 static float last_elevator_trim;
428 if (throttle_dif > 0) {
430 elevator_trim = throttle_dif / max_dif * v_ctl_auto_throttle_dash_trim;
433 elevator_trim = - throttle_dif / max_dif * v_ctl_auto_throttle_loiter_trim;
436 float max_change = (v_ctl_auto_throttle_loiter_trim - v_ctl_auto_throttle_dash_trim) / 80.;
437 Bound(elevator_trim, last_elevator_trim - max_change, last_elevator_trim + max_change);
439 last_elevator_trim = elevator_trim;
440 return elevator_trim;
447 static float last_err;
464 switch (h_ctl_pitch_mode) {
465 case H_CTL_PITCH_MODE_THETA:
468 case H_CTL_PITCH_MODE_AOA:
480 float d_err = err - last_err;