Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
eff_scheduling_rotwing.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Dennis van Wijngaarden <D.C.vanWijngaarden@tudelft.nl>
3  *
4  * This file is part of paparazzi
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
27 
28 #include "generated/airframe.h"
29 #include "state.h"
30 
34 #include "autopilot.h"
35 
37 #include "modules/core/abi.h"
39 
40 #ifndef SERVO_ROTATION_MECH_IDX
41 #error ctrl_eff_sched_rotwing requires a servo named ROTATION_MECH_IDX
42 #endif
43 
44 #ifndef ROTWING_EFF_SCHED_IXX_BODY
45 #error "NO ROTWING_EFF_SCHED_IXX_BODY defined"
46 #endif
47 
48 #ifndef ROTWING_EFF_SCHED_IYY_BODY
49 #error "NO ROTWING_EFF_SCHED_IYY_BODY defined"
50 #endif
51 
52 #ifndef ROTWING_EFF_SCHED_IZZ
53 #error "NO ROTWING_EFF_SCHED_IZZ defined"
54 #endif
55 
56 #ifndef ROTWING_EFF_SCHED_IXX_WING
57 #error "NO ROTWING_EFF_SCHED_IXX_WING defined"
58 #endif
59 
60 #ifndef ROTWING_EFF_SCHED_IYY_WING
61 #error "NO ROTWING_EFF_SCHED_IYY_WING defined"
62 #endif
63 
64 #ifndef ROTWING_EFF_SCHED_M
65 #error "NO ROTWING_EFF_SCHED_M defined"
66 #endif
67 
68 #ifndef ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_PITCH
69 #error "NO ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_PITCH defined"
70 #endif
71 
72 #ifndef ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_ROLL
73 #error "NO ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_ROLL defined"
74 #endif
75 
76 #ifndef ROTWING_EFF_SCHED_HOVER_ROLL_PITCH_COEF
77 #error "NO ROTWING_EFF_SCHED_HOVER_ROLL_PITCH_COEF defined"
78 #endif
79 
80 #ifndef ROTWING_EFF_SCHED_HOVER_ROLL_ROLL_COEF
81 #error "NO ROTWING_EFF_SCHED_HOVER_ROLL_ROLL_COEF defined"
82 #endif
83 
84 #ifndef ROTWING_EFF_SCHED_K_ELEVATOR
85 #error "NO ROTWING_EFF_SCHED_K_ELEVATOR defined"
86 #endif
87 
88 #ifndef ROTWING_EFF_SCHED_K_RUDDER
89 #error "NO ROTWING_EFF_SCHED_K_RUDDER defined"
90 #endif
91 
92 #ifndef ROTWING_EFF_SCHED_K_AILERON
93 #error "NO ROTWING_EFF_SCHED_K_AILERON defined"
94 #endif
95 
96 #ifndef ROTWING_EFF_SCHED_K_FLAPERON
97 #error "NO ROTWING_EFF_SCHED_K_FLAPERON defined"
98 #endif
99 
100 #ifndef ROTWING_EFF_SCHED_K_PUSHER
101 #error "NO ROTWING_EFF_SCHED_K_PUSHER defined"
102 #endif
103 
104 #ifndef ROTWING_EFF_SCHED_K_ELEVATOR_DEFLECTION
105 #error "NO ROTWING_EFF_SCHED_K_ELEVATOR_DEFLECTION defined"
106 #endif
107 
108 #ifndef ROTWING_EFF_SCHED_D_RUDDER_D_PPRZ
109 #error "NO ROTWING_EFF_SCHED_D_RUDDER_D_PPRZ defined"
110 #endif
111 
112 #ifndef ROTWING_EFF_SCHED_K_RPM_PPRZ_PUSHER
113 #error "NO ROTWING_EFF_SCHED_K_RPM_PPRZ_PUSHER defined"
114 #endif
115 
116 #ifndef ROTWING_EFF_SCHED_K_LIFT_WING
117 #error "NO ROTWING_EFF_SCHED_K_LIFT_WING defined"
118 #endif
119 
120 #ifndef ROTWING_EFF_SCHED_K_LIFT_FUSELAGE
121 #error "NO ROTWING_EFF_SCHED_K_LIFT_FUSELAGE defined"
122 #endif
123 
124 #ifndef ROTWING_EFF_SCHED_K_LIFT_TAIL
125 #error "NO ROTWING_EFF_SCHED_K_LIFT_TAIL defined"
126 #endif
127 
129  .Ixx_body = ROTWING_EFF_SCHED_IXX_BODY,
130  .Iyy_body = ROTWING_EFF_SCHED_IYY_BODY,
131  .Izz = ROTWING_EFF_SCHED_IZZ,
132  .Ixx_wing = ROTWING_EFF_SCHED_IXX_WING,
133  .Iyy_wing = ROTWING_EFF_SCHED_IYY_WING,
134  .m = ROTWING_EFF_SCHED_M,
135  .DMdpprz_hover_pitch = ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_PITCH,
136  .DMdpprz_hover_roll = ROTWING_EFF_SCHED_DM_DPPRZ_HOVER_ROLL,
137  .hover_roll_pitch_coef = ROTWING_EFF_SCHED_HOVER_ROLL_PITCH_COEF,
138  .hover_roll_roll_coef = ROTWING_EFF_SCHED_HOVER_ROLL_ROLL_COEF,
139  .k_elevator = ROTWING_EFF_SCHED_K_ELEVATOR,
140  .k_rudder = ROTWING_EFF_SCHED_K_RUDDER,
141  .k_aileron = ROTWING_EFF_SCHED_K_AILERON,
142  .k_flaperon = ROTWING_EFF_SCHED_K_FLAPERON,
143  .k_pusher = ROTWING_EFF_SCHED_K_PUSHER,
144  .k_elevator_deflection = ROTWING_EFF_SCHED_K_ELEVATOR_DEFLECTION,
145  .d_rudder_d_pprz = ROTWING_EFF_SCHED_D_RUDDER_D_PPRZ,
146  .k_rpm_pprz_pusher = ROTWING_EFF_SCHED_K_RPM_PPRZ_PUSHER,
147  .k_lift_wing = ROTWING_EFF_SCHED_K_LIFT_WING,
148  .k_lift_fuselage = ROTWING_EFF_SCHED_K_LIFT_FUSELAGE,
149  .k_lift_tail = ROTWING_EFF_SCHED_K_LIFT_TAIL
150 };
151 
153 
154 // for negative values, still should be low_lim < up_lim
155 inline float bound_or_zero(float value, float low_lim, float up_lim) {
156  float output = value;
157  if (low_lim > 0.f) {
158  if (value < low_lim) {
159  output = 0.f;
160  } else if (value > up_lim) {
161  output = up_lim;
162  }
163  } else {
164  if (value > up_lim) {
165  output = 0.f;
166  } else if (value < low_lim) {
167  output = low_lim;
168  }
169  }
170  return output;
171 }
172 
173 float eff_sched_pusher_time = 0.002;
174 float roll_eff_slider = 12.f;
175 
176 static const float Wu_gih_original[GUIDANCE_INDI_HYBRID_U] = GUIDANCE_INDI_WLS_WU;
177 
179 
181 inline void eff_scheduling_rotwing_update_MMOI(void);
182 inline void eff_scheduling_rotwing_update_cmd(void);
190 inline void eff_scheduling_rotwing_schedule_liftd(void);
191 
192 inline float guidance_indi_get_liftd(float pitch UNUSED, float theta UNUSED);
194 inline void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle);
195 
196 
199 #ifndef WING_ROTATION_CAN_ROTWING_ID
200 #define WING_ROTATION_CAN_ROTWING_ID ABI_BROADCAST
201 #endif
204 
205 static void wing_position_cb(uint8_t sender_id UNUSED, struct act_feedback_t *pos_msg, uint8_t num_act)
206 {
207  for (int i=0; i<num_act; i++){
208  if (pos_msg[i].set.position && (pos_msg[i].idx == SERVO_ROTATION_MECH_IDX))
209  {
210  // Get wing rotation angle from sensor
211  eff_sched_var.wing_rotation_rad = 0.5 * M_PI - pos_msg[i].position;
212 
213  // Bound wing rotation angle
214  Bound(eff_sched_var.wing_rotation_rad, 0, 0.5 * M_PI);
215  }
216  }
217 }
218 
220 {
221  // Initialize variables to quad values
224  eff_sched_var.wing_rotation_rad = 0; // ABI input
226  eff_sched_var.cosr = 1;
227  eff_sched_var.sinr = 0;
228  eff_sched_var.cosr2 = 1;
229  eff_sched_var.sinr2 = 0;
230  eff_sched_var.sinr3 = 0;
231 
232  // Set moment derivative variables
233  float hover_thrust = 6000;
234  eff_sched_var.pitch_motor_dMdpprz = (eff_sched_p.DMdpprz_hover_pitch[0] + 2*hover_thrust * eff_sched_p.DMdpprz_hover_pitch[1]) / 10000.; // Dmdpprz hover pitch for hover thrust
235  eff_sched_var.roll_motor_dMdpprz = (eff_sched_p.DMdpprz_hover_roll[0] + 2*hover_thrust * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.; // Dmdpprz hover roll for hover thrust
236 
241 
244 
245  // Get wing angle
247 }
248 
250 {
251  // your periodic code here.
252  // freq = 500.0 Hz
257 
258  // Update the effectiveness values
266 }
267 
269 {
270  // Calculate sin and cosines of rotation
272 
275 
278 
280 
281 }
282 
284 {
287 
288  // Bound inertia
289  Bound(eff_sched_var.Ixx, 0.01, 100.);
290  Bound(eff_sched_var.Iyy, 0.01, 100.);
291 }
292 
294 {
295  // These indexes depend on the INDI sequence, not the actuator IDX
298  eff_sched_var.cmd_pusher_scaled = actuator_state_filt_vect[8] * 0.000853229; // Scaled with 8181 / 9600 / 1000
299  eff_sched_var.cmd_T_mean_scaled = (actuator_state_filt_vect[0] + actuator_state_filt_vect[1] + actuator_state_filt_vect[2] + actuator_state_filt_vect[3]) / 4. * 0.000853229; // Scaled with 8181 / 9600 / 1000
300 }
301 
303 {
305  Bound(eff_sched_var.airspeed, 0. , 30.);
307  Bound(eff_sched_var.airspeed2, 0. , 900.);
308 }
309 
311 {
312  float cmd_quat[4];
313  float dM_dpprz[4];
314  // Quadratic thrust (and therefore moment) model of the hover propellers
315  for (uint8_t i = 0; i < 4; i++) {
316  cmd_quat[i] = actuator_state_filt_vect[i];
317  Bound(cmd_quat[i], 2500, MAX_PPRZ);
318 
319  if(i==0 || i==2) { // pitch motors
320  dM_dpprz[i] = (eff_sched_p.DMdpprz_hover_pitch[0] + 2*cmd_quat[i] * eff_sched_p.DMdpprz_hover_pitch[1]) / 10000.;
321  // Bound dM_dpprz to half and 2 times the hover effectiveness
322  Bound(dM_dpprz[i], eff_sched_var.pitch_motor_dMdpprz * 0.5, eff_sched_var.pitch_motor_dMdpprz * 2.0);
323  } else { // roll motors
324  dM_dpprz[i] = (eff_sched_p.DMdpprz_hover_roll[0] + 2*cmd_quat[i] * eff_sched_p.DMdpprz_hover_roll[1]) / 10000.;
325  Bound(dM_dpprz[i], eff_sched_var.roll_motor_dMdpprz * 0.5, eff_sched_var.roll_motor_dMdpprz * 2.0);
326  }
327  }
328 
329  // Roll motor effectiveness
330  float dM_dpprz_right = dM_dpprz[1];
331  float dM_dpprz_left = dM_dpprz[3];;
332 
334  roll_motor_p_eff_right = bound_or_zero(roll_motor_p_eff_right, -1.f, -0.00001f);
335 
337  if(autopilot.in_flight) {
338  float roll_motor_airspeed_compensation = eff_sched_p.hover_roll_roll_coef[1] * eff_sched_var.airspeed * eff_sched_var.cosr / eff_sched_var.Ixx;
339  roll_motor_p_eff_left += roll_motor_airspeed_compensation;
340  }
341  roll_motor_p_eff_left = bound_or_zero(roll_motor_p_eff_left, 0.00001f, 1.f);
342 
344  Bound(roll_motor_q_eff, 0, 1);
345 
346  // Update front pitch motor q effectiveness
347  g1g2[1][0] = dM_dpprz[0] / eff_sched_var.Iyy; // pitch effectiveness front motor
348 
349  // Update back motor q effectiveness
350  g1g2[1][2] = - dM_dpprz[2] / eff_sched_var.Iyy; // pitch effectiveness back motor
351 
352 #ifdef RADIO_CONTROL_EFF_SWITCH
353  if (radio_control.values[RADIO_CONTROL_EFF_SWITCH] > 1750) {
354  g1g2[0][1] = - roll_eff_slider / 1000.f;
355  } else {
356  g1g2[0][1] = roll_motor_p_eff_right;
357  }
358 #else
359  g1g2[0][1] = roll_motor_p_eff_right; // roll effectiveness right motor (no airspeed compensation)
360 #endif
361  // Update right motor p and q effectiveness
362  g1g2[1][1] = roll_motor_q_eff; // pitch effectiveness right motor
363 
364  // Update left motor p and q effectiveness
365 #ifdef RADIO_CONTROL_EFF_SWITCH
366  if (radio_control.values[RADIO_CONTROL_EFF_SWITCH] > 1750) {
367  g1g2[0][3] = roll_eff_slider / 1000.f;
368  } else {
369  g1g2[0][3] = roll_motor_p_eff_left;
370  }
371 #else
372  g1g2[0][3] = roll_motor_p_eff_left; // roll effectiveness left motor
373 #endif
374  g1g2[1][3] = -roll_motor_q_eff; // pitch effectiveness left motor
375 }
376 
378 {
380 
381  float dMyde = (eff_sched_p.k_elevator[0] * de * eff_sched_var.airspeed2 +
384 
385  // scale the effectiveness of the elevator down if it has a large deflection to encourage it to become flat quickly (pragmatic, not physically inpsired)
386  float elevator_ineffectiveness_scaling = (50-de)/40;
387  Bound(elevator_ineffectiveness_scaling, 0.5, 1.0);
388 
389  float dMydpprz = dMyde * eff_sched_p.k_elevator_deflection[1];
390 
391  // Convert moment to effectiveness
392  float eff_y_elev = dMydpprz / eff_sched_var.Iyy;
393 
394  Bound(eff_y_elev, 0.00001, 0.1);
395 
396  g1g2[1][5] = eff_y_elev;
397 }
398 
400 {
404 
405  // Convert moment to effectiveness
406 
407  float dMzdpprz = dMzdr * eff_sched_p.d_rudder_d_pprz;
408 
409  // Convert moment to effectiveness
410  float eff_z_rudder = dMzdpprz / eff_sched_p.Izz;
411 
412  Bound(eff_z_rudder, 0.000001, 0.1);
413 
414  g1g2[2][4] = eff_z_rudder;
415 }
416 
418 {
419  float dMxdpprz = (eff_sched_p.k_aileron * eff_sched_var.airspeed2 * eff_sched_var.sinr3) / 1000000.;
420  float eff_x_aileron = dMxdpprz / eff_sched_var.Ixx;
421  Bound(eff_x_aileron, 0, 0.005)
422  g1g2[0][6] = eff_x_aileron;
423 
424  float dMydpprz = 4.0*(eff_sched_p.k_aileron * eff_sched_var.airspeed2 * eff_sched_var.sinr2 * eff_sched_var.cosr) / 1000000.;
425  float eff_y_aileron = dMydpprz / eff_sched_var.Iyy;
426  eff_y_aileron = bound_or_zero(eff_y_aileron, 0.00003f, 0.005f);
427  g1g2[1][6] = eff_y_aileron;
428 }
429 
431 {
432  float dMxdpprz = (eff_sched_p.k_flaperon * eff_sched_var.airspeed2 * eff_sched_var.sinr3) / 1000000.;
433  float eff_x_flap_aileron = dMxdpprz / eff_sched_var.Ixx;
434  Bound(eff_x_flap_aileron, 0, 0.005)
435  g1g2[0][7] = eff_x_flap_aileron;
436 }
437 
439 {
441 
442  float dFxdrpmP = eff_sched_p.k_pusher[0]*rpmP + eff_sched_p.k_pusher[1] * eff_sched_var.airspeed;
444 
445  float eff_pusher = (dFxdrpmP * drpmPdpprz / eff_sched_p.m) / 10000.;
446 
447  Bound(eff_pusher, 0.00030, 0.0015);
448  g1g2[4][8] = eff_pusher;
449 }
450 
452 
454 {
456  float lift_d_fuselage = eff_sched_p.k_lift_fuselage * eff_sched_var.airspeed2 / eff_sched_p.m;
458 
459  float lift_d = lift_d_wing + lift_d_fuselage + lift_d_tail;
461  lift_d = 0.0;
462  }
463  Bound(lift_d, -130., 0.);
465 }
466 
467 // Override standard LIFT_D function
468 float guidance_indi_get_liftd(float pitch UNUSED, float theta UNUSED) {
470 }
471 
473 {
474  // Calculate the min and max increments
475  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
478  wls_stab_p.u_pref[i] = act_pref[i];
479  if (i == 5) { // elevator
480  wls_stab_p.u_pref[i] = actuator_state_filt_vect[i]; // Set change in prefered state to 0 for elevator
481  wls_stab_p.u_min[i] = 0; // cmd 0 is lowest position for elevator
482  }
483  if (i == 7) { // flaperons
484  // If an offset is used, limit the max differential command to prevent unilateral saturation.
485  int32_t flap_saturation_limit = MAX_PPRZ - abs(rw_flap_offset);
486  BoundAbs(flap_saturation_limit, MAX_PPRZ);
487  wls_stab_p.u_min[i] = -flap_saturation_limit;
488  wls_stab_p.u_max[i] = flap_saturation_limit;
489  }
490  if (i==8) { // pusher
491  // dt (min to max) MAX_PPRZ / (dt * f) dt_min == 0.002
492  Bound(eff_sched_pusher_time, 0.002, 5.);
493  float max_increment = MAX_PPRZ / (eff_sched_pusher_time * 500);
494  wls_stab_p.u_min[i] = actuators_pprz[i] - max_increment;
495  wls_stab_p.u_max[i] = actuators_pprz[i] + max_increment;
496 
497  Bound(wls_stab_p.u_min[i], 0, MAX_PPRZ);
498  Bound(wls_stab_p.u_max[i], 0, MAX_PPRZ);
499  }
500  }
501 }
502 
503 void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle)
504 {
505  // adjust weights
506  float fixed_wing_percentile = (rotwing_state_hover_motors_idling())? 1:0; // TODO: when hover props go below 40%, ...
507  Bound(fixed_wing_percentile, 0, 1);
508 #define AIRSPEED_IMPORTANCE_IN_FORWARD_WEIGHT 16
509 
510  float Wv_original[GUIDANCE_INDI_HYBRID_V] = GUIDANCE_INDI_WLS_PRIORITIES;
511 
512  // Increase importance of forward acceleration in forward flight
513  wls_guid_p.Wv[0] = Wv_original[0] * (1.0f + fixed_wing_percentile *
514  AIRSPEED_IMPORTANCE_IN_FORWARD_WEIGHT); // stall n low hover motor_off (weight 16x more important than vertical weight)
515 
516  struct FloatEulers eulers_zxy;
518 
519  float du_min_thrust_z = ((MAX_PPRZ - actuator_state_filt_vect[0]) * g1g2[3][0] + (MAX_PPRZ -
522  Bound(du_min_thrust_z, -50., 0.);
523  float du_max_thrust_z = -(actuator_state_filt_vect[0] * g1g2[3][0] + actuator_state_filt_vect[1] * g1g2[3][1] +
525  Bound(du_max_thrust_z, 0., 50.);
526 
527  float roll_limit_rad = guidance_indi_max_bank;
528  float max_pitch_limit_rad = RadOfDeg(GUIDANCE_INDI_MAX_PITCH);
529  float min_pitch_limit_rad = RadOfDeg(GUIDANCE_INDI_MIN_PITCH);
530 
531  float fwd_pitch_limit_rad = RadOfDeg(GUIDANCE_INDI_MAX_PITCH);
532  float quad_pitch_limit_rad = RadOfDeg(5.0);
533 
534  float airspeed = stateGetAirspeed_f();
535 
536  float scheduled_pitch_angle = 0.f;
537  float pitch_angle_range = 3.;
538  float meas_skew_angle = rotwing_state.meas_skew_angle_deg;
539  Bound(meas_skew_angle, 0, 90); // Bound to prevent errors
540  if (meas_skew_angle < ROTWING_SKEW_ANGLE_STEP) {
541  scheduled_pitch_angle = ROTWING_QUAD_PREF_PITCH;
542  wls_guid_p.Wu[1] = Wu_gih_original[1];
543  max_pitch_limit_rad = quad_pitch_limit_rad;
544  } else {
545  float pitch_progression = (airspeed - rotwing_state.fw_min_airspeed) / 2.f;
546  Bound(pitch_progression, 0.f, 1.f);
547  scheduled_pitch_angle = pitch_angle_range * pitch_progression + ROTWING_QUAD_PREF_PITCH*(1.f-pitch_progression);
548  wls_guid_p.Wu[1] = Wu_gih_original[1] * (1.f - pitch_progression*0.99);
549  max_pitch_limit_rad = quad_pitch_limit_rad + (fwd_pitch_limit_rad - quad_pitch_limit_rad) * pitch_progression;
550  }
552  scheduled_pitch_angle = 8.;
553  max_pitch_limit_rad = fwd_pitch_limit_rad;
554  }
555  Bound(scheduled_pitch_angle, -5., 8.);
556  guidance_indi_pitch_pref_deg = scheduled_pitch_angle;
557 
558  float pitch_pref_rad = RadOfDeg(guidance_indi_pitch_pref_deg);
559 
560  // Set lower limits
561  wls_guid_p.u_min[0] = -roll_limit_rad - roll_angle; //roll
562  wls_guid_p.u_min[1] = min_pitch_limit_rad - pitch_angle; // pitch
563 
564  // Set upper limits limits
565  wls_guid_p.u_max[0] = roll_limit_rad - roll_angle; //roll
566  wls_guid_p.u_max[1] = max_pitch_limit_rad - pitch_angle; // pitch
567 
569  wls_guid_p.u_min[2] = du_min_thrust_z;
570  wls_guid_p.u_max[2] = du_max_thrust_z;
571  } else {
572  wls_guid_p.u_min[2] = 0.;
573  wls_guid_p.u_max[2] = 0.;
574  }
575 
577  wls_guid_p.u_min[3] = (-actuator_state_filt_vect[8] * g1g2[4][8]);
578  wls_guid_p.u_max[3] = 9.0; // Hacky value to prevent drone from pitching down in transition
579  } else {
580  wls_guid_p.u_min[3] = 0.;
581  wls_guid_p.u_max[3] = 0.;
582  }
583 
584  // Set prefered states
585  wls_guid_p.u_pref[0] = 0; // prefered delta roll angle
586  wls_guid_p.u_pref[1] = -pitch_angle + pitch_pref_rad;// prefered delta pitch angle
587  wls_guid_p.u_pref[2] = wls_guid_p.u_max[2]; // Low thrust better for efficiency
588  wls_guid_p.u_pref[3] = body_v[0]; // solve the body acceleration
589 }
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
Definition: abi_common.h:67
struct pprz_autopilot autopilot
Global autopilot structure.
Definition: autopilot.c:49
Core autopilot interface common to all firmwares.
bool in_flight
in flight status
Definition: autopilot.h:70
uint8_t last_wp UNUSED
if(GpsFixValid() &&e_identification_started)
void stabilization_indi_set_wls_settings(void)
Function that sets the u_min, u_max and u_pref if function not elsewhere defined.
void eff_scheduling_rotwing_update_flaperon_effectiveness(void)
void eff_scheduling_rotwing_update_rudder_effectiveness(void)
void eff_scheduling_rotwing_update_aileron_effectiveness(void)
float eff_scheduling_rotwing_lift_d
static const float Wu_gih_original[GUIDANCE_INDI_HYBRID_U]
struct rotwing_eff_sched_var_t eff_sched_var
void eff_scheduling_rotwing_update_MMOI(void)
#define WING_ROTATION_CAN_ROTWING_ID
ABI binding wing position data.
void eff_scheduling_rotwing_update_airspeed(void)
float roll_eff_slider
int32_t rw_flap_offset
void eff_scheduling_rotwing_update_cmd(void)
void eff_scheduling_rotwing_schedule_liftd(void)
float guidance_indi_get_liftd(float pitch UNUSED, float theta UNUSED)
#define AIRSPEED_IMPORTANCE_IN_FORWARD_WEIGHT
void eff_scheduling_rotwing_update_wing_angle(void)
struct rotwing_eff_sched_param_t eff_sched_p
void eff_scheduling_rotwing_update_hover_motor_effectiveness(void)
static abi_event wing_position_ev
void eff_scheduling_rotwing_init(void)
void eff_scheduling_rotwing_update_elevator_effectiveness(void)
float eff_sched_pusher_time
float bound_or_zero(float value, float low_lim, float up_lim)
void eff_scheduling_rotwing_update_pusher_effectiveness(void)
void eff_scheduling_rotwing_periodic(void)
static void wing_position_cb(uint8_t sender_id UNUSED, struct act_feedback_t *pos_msg, uint8_t num_act)
void guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle)
void float_eulers_of_quat_zxy(struct FloatEulers *e, struct FloatQuat *q)
euler rotation 'ZXY' This rotation order is useful if you need 90 deg pitch
euler angles
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition: state.h:1294
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition: state.h:1590
float guidance_indi_max_bank
float guidance_indi_pitch_pref_deg
struct FloatEulers eulers_zxy
state eulers in zxy order
A guidance mode based on Incremental Nonlinear Dynamic Inversion Come to ICRA2016 to learn more!
#define GUIDANCE_INDI_MAX_PITCH
#define GUIDANCE_INDI_MIN_PITCH
Hardware independent API for actuators (servos, motor controllers).
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
#define MAX_PPRZ
Definition: paparazzi.h:8
struct RadioControl radio_control
Definition: radio_control.c:33
Generic interface for radio control modules.
pprz_t values[RADIO_CONTROL_NB_CHANNEL]
Definition: radio_control.h:67
bool rotwing_state_pusher_motor_running(void)
bool rotwing_state_hover_motors_running(void)
bool rotwing_state_hover_motors_idling(void)
Check if hover motors are idling (COMMAND_THRUST < ROTWING_QUAD_IDLE_MIN_THRUST) for ROTWING_QUAD_IDL...
struct rotwing_state_t rotwing_state
Definition: rotwing_state.c:99
#define ROTWING_QUAD_PREF_PITCH
Definition: rotwing_state.h:38
float meas_skew_angle_deg
Definition: rotwing_state.h:70
#define ROTWING_SKEW_ANGLE_STEP
Definition: rotwing_state.h:33
float act_pref[INDI_NUM_ACT]
bool act_is_servo[INDI_NUM_ACT]
struct WLS_t wls_stab_p
float g1g2[INDI_OUTPUTS][INDI_NUM_ACT]
float actuator_state_filt_vect[INDI_NUM_ACT]
API to get/set the generic vehicle states.
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
float u_min[WLS_N_U_MAX]
Definition: wls_alloc.h:75
float u_max[WLS_N_U_MAX]
Definition: wls_alloc.h:76
float u_pref[WLS_N_U_MAX]
Definition: wls_alloc.h:74