Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
eff_scheduling_nederdrone.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 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 
32 #include "state.h"
33 #include "autopilot.h"
35 //#include "generated/radio.h"
37 #define INDI_SCHEDULING_LOWER_BOUND_G1 0.0001
38 
39 // Airspeed at which tip props should be turned on
40 #ifndef INDI_SCHEDULING_LOW_AIRSPEED
41 #define INDI_SCHEDULING_LOW_AIRSPEED 12.0
42 #endif
43 
44 #if INDI_NUM_ACT < 8
45 #error "This module works with a Nederdrone with 8 (grouped) actuators"
46 #endif
47 
48 #ifndef INDI_SCHEDULING_TRIM_ELEVATOR
49 #define INDI_SCHEDULING_TRIM_ELEVATOR 0.0
50 #endif
51 
52 #ifndef INDI_SCHEDULING_TRIM_FLAPS
53 #define INDI_SCHEDULING_TRIM_FLAPS 0.0
54 #endif
55 
58 
59 // Factor that changes cost of the flaps and motors if v>15.0 m/s
60 // Higher factor means prefer using the flaps
61 float pref_flaps_factor = INDI_SCHEDULING_PREF_FLAPS_FACTOR;
62 
63 float indi_Wu_original[INDI_NUM_ACT] = STABILIZATION_INDI_WLS_WU;
64 
65 bool all_act_fwd_sched = false;
66 
68 
69 float thrust_eff_scaling = 1.0;
72 
73 static float g_forward[4][INDI_NUM_ACT] = {STABILIZATION_INDI_G1_ROLL_FWD, STABILIZATION_INDI_G1_PITCH_FWD, STABILIZATION_INDI_G1_YAW_FWD, STABILIZATION_INDI_G1_THRUST_FWD};
74 
75 #ifdef STABILIZATION_INDI_G1
76 static float g_hover[4][INDI_NUM_ACT] = STABILIZATION_INDI_G1;
77 #else
78 static float g_hover[4][INDI_NUM_ACT] = {STABILIZATION_INDI_G1_ROLL, STABILIZATION_INDI_G1_PITCH, STABILIZATION_INDI_G1_YAW, STABILIZATION_INDI_G1_THRUST};
79 #endif
80 
81 // Functions to schedule switching on and of of tip props on front wing
83 // If pitch lower, pitch props gradually switch off till sched_tip_prop_lower_pitch_limit_deg (1 > sched_ratio_tip_props > 0)
85 // If pitch lower, pitch props switch fully off (sched_ratio_tip_props goes to 0)
87 // Setting to not switch off tip props during forward flight
89 
91 
93 {
94  // your init code here
95  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
96  g_hover[0][i] = g_hover[0][i] / INDI_G_SCALING;
97  g_hover[1][i] = g_hover[1][i] / INDI_G_SCALING;
98  g_hover[2][i] = g_hover[2][i] / INDI_G_SCALING;
99  g_hover[3][i] = g_hover[3][i] / INDI_G_SCALING;
100 
101  g_forward[0][i] = g_forward[0][i] / INDI_G_SCALING;
102  g_forward[1][i] = g_forward[1][i] / INDI_G_SCALING;
103  g_forward[2][i] = g_forward[2][i] / INDI_G_SCALING;
104  g_forward[3][i] = g_forward[3][i] / INDI_G_SCALING;
105  }
106 }
107 
109 {
110 #ifdef SITL
111  sched_ratio_tip_props = 1.0;
112 #else
114 #endif
115 
116  act_pref[0] = 0.0;
117  act_pref[1] = 0.0;
118  act_pref[2] = 0.0;
119  act_pref[3] = 0.0;
120  // read settings and trim the aerodynamic surfaces
125 }
126 
132  float airspeed = stateGetAirspeed_f();
133 
134  float ratio = 0.0;
135  struct FloatEulers eulers_zxy;
137 
138  // Ratio is only based on pitch now, as the pitot tube is often not mounted.
139  if (use_scheduling == 1) {
140  ratio = fabs(eulers_zxy.theta) / M_PI_2;
141  } else {
142  ratio = 0.0;
143  }
144  Bound(ratio,0.0,1.0);
145 
146  float stall_speed = 14.0; // m/s
147  float pitch_ratio = 0.0;
148  // Assume hover or stalled conditions below 14 m/s
149  if (use_scheduling == 1) {
150  if ( (eulers_zxy.theta > -M_PI_4) || (airspeed < stall_speed) ) {
151  if (eulers_zxy.theta > -M_PI_4) {
152  pitch_ratio = 0.0;
153  } else {
154  pitch_ratio = fabs(1.0 - eulers_zxy.theta/(-M_PI_4));
155  }
156 
157  } else {
158  pitch_ratio = 1.0;
159  }
160  } else {
161  pitch_ratio = 0.0;
162  }
163  Bound(pitch_ratio,0.0,1.0);
164 
165  float airspeed_pitch_eff = airspeed;
166  Bound(airspeed_pitch_eff, 8.0, 30.0);
167 
168  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
169 
170  // Roll
171  g1g2[0][i] = g_hover[0][i] * (1.0 - ratio) + g_forward[0][i] * ratio;
172  //Pitch, scaled with v^2
173  if (i>3 || all_act_fwd_sched) {
174  g1g2[1][i] = g_hover[1][i] * (1.0 - pitch_ratio) + g_forward[1][i] * pitch_ratio;
175  } else {
176  g1g2[1][i] = g_hover[1][i] * (1.0 - pitch_ratio) + g_forward[1][i] * pitch_ratio * airspeed_pitch_eff * airspeed_pitch_eff / (16.0*16.0);
177  }
178  // With this factor the pitch effectiveness of the back wing can be scaled
179  if( (i ==2) || (i==3)) {
181  }
182  //Yaw
183  g1g2[2][i] = g_hover[2][i] * (1.0 - ratio) + g_forward[2][i] * ratio;
184 
185  // Determine thrust of the wing to adjust the effectiveness of servos
186  float wing_thrust_scaling = 1.0;
187 #if INDI_NUM_ACT != 8
188 #error "ctfl_eff_scheduling_nederdrone is very specific and only works for one Nederdrone configuration!"
189 #endif
190  if (i>3) {
191  // Increase servo effectiveness depending on the thrust of the propeller of that wing: 0,1,2,3 = motors, 4,5,6,7 = flaps
192  float wing_thrust = actuators_pprz[i-4];
193  Bound(wing_thrust,3000.0,9600.0);
194  wing_thrust_scaling = wing_thrust/9600.0/0.8;
195  }
196 
197  g1g2[0][i] *= wing_thrust_scaling;
198  g1g2[1][i] *= wing_thrust_scaling;
199  g1g2[2][i] *= wing_thrust_scaling;
200  }
201 
202  // Thrust effectiveness
203  float ratio_spec_force = 0.0;
204  float airspeed_spec_force = airspeed;
205  Bound(airspeed_spec_force, 8.0, 20.0);
206  ratio_spec_force = (airspeed_spec_force-8.0) / 12.0;
207 
208  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
209  // Thrust
210  g1g2[3][i] = g_hover[3][i] * (1.0 - ratio_spec_force) + g_forward[3][i] * ratio_spec_force;
211  g1g2[3][i] *= thrust_eff_scaling;
212  // With this factor the thrust effectiveness of the back wing can be scaled
213  if( (i ==2) || (i==3)) {
215  }
216  }
217 
218  bool low_airspeed = stateGetAirspeed_f() < INDI_SCHEDULING_LOW_AIRSPEED;
219 
220  // Tip prop ratio
221  float pitch_deg = eulers_zxy.theta / M_PI * 180.f;
223  if (sched_tip_props_always_on || low_airspeed || radio_control.values[RADIO_AUX2] > 0) {
224  sched_ratio_tip_props = 1.0;
225  } else {
226  float pitch_offset = pitch_deg - sched_tip_prop_lower_pitch_limit_deg;
227  sched_ratio_tip_props = pitch_offset / pitch_range_deg;
228  }
229  Bound(sched_ratio_tip_props, 0.0, 1.0);
230 
231  // Blance the cost of using motors and aerodynamic surfaces
232  if(airspeed > 15.0) {
233  uint8_t i;
234  for (i = 0; i < 4; i++) {
236  }
237  for (i = 4; i < 8; i++) {
239  }
240  } else {
241  uint8_t i;
242  for (i = 0; i < 8; i++) {
244  }
245  }
246 }
Core autopilot interface common to all firmwares.
#define INDI_SCHEDULING_LOW_AIRSPEED
int32_t use_scheduling
float pref_flaps_factor
float sched_tip_prop_upper_pitch_limit_deg
#define INDI_SCHEDULING_TRIM_ELEVATOR
float trim_elevator
float indi_Wu_original[INDI_NUM_ACT]
bool all_act_fwd_sched
float sched_ratio_tip_props
#define INDI_SCHEDULING_TRIM_FLAPS
void ctrl_eff_scheduling_periodic(void)
Periodic function that interpolates between gain sets depending on the scheduling variable.
void schdule_control_effectiveness(void)
Function that calculates control effectiveness values for the Nederdrone inner loop.
bool sched_tip_props_always_on
float backwing_thrust_eff_scaling
float thrust_eff_scaling
static float g_hover[4][INDI_NUM_ACT]
float trim_flaps
float sched_tip_prop_lower_pitch_limit_deg
float backwing_pitch_eff_scaling
static float g_forward[4][INDI_NUM_ACT]
void ctrl_eff_scheduling_init(void)
Initialises periodic loop;.
float theta
in radians
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
struct FloatEulers eulers_zxy
state eulers in zxy order
Hardware independent API for actuators (servos, motor controllers).
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
float act_pref[INDI_NUM_ACT]
struct WLS_t wls_stab_p
float g1g2[INDI_OUTPUTS][INDI_NUM_ACT]
#define INDI_G_SCALING
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 Wu[WLS_N_U_MAX]
Definition: wls_alloc.h:73