Paparazzi UAS  v6.2.0_stable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 bool all_act_fwd_sched = false;
45 
47 
48 float thrust_eff_scaling = 1.0;
49 
50 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};
51 
52 static float g_hover[4][INDI_NUM_ACT] = {STABILIZATION_INDI_G1_ROLL, STABILIZATION_INDI_G1_PITCH, STABILIZATION_INDI_G1_YAW, STABILIZATION_INDI_G1_THRUST};
53 
54 // Functions to schedule switching on and of of tip props on front wing
56 // If pitch lower, pitch props gradually switch off till sched_tip_prop_lower_pitch_limit_deg (1 > sched_ratio_tip_props > 0)
58 // If pitch lower, pitch props switch fully off (sched_ratio_tip_props goes to 0)
60 // Setting to not switch off tip props during forward flight
62 
64 
66 {
67  // your init code here
68  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
69  g_hover[0][i] = g_hover[0][i] / INDI_G_SCALING;
70  g_hover[1][i] = g_hover[1][i] / INDI_G_SCALING;
71  g_hover[2][i] = g_hover[2][i] / INDI_G_SCALING;
72  g_hover[3][i] = g_hover[3][i] / INDI_G_SCALING;
73 
74  g_forward[0][i] = g_forward[0][i] / INDI_G_SCALING;
75  g_forward[1][i] = g_forward[1][i] / INDI_G_SCALING;
76  g_forward[2][i] = g_forward[2][i] / INDI_G_SCALING;
77  g_forward[3][i] = g_forward[3][i] / INDI_G_SCALING;
78  }
79 }
80 
82 {
83 #ifdef SITL
85 #else
87 #endif
88 }
89 
95  float airspeed = stateGetAirspeed_f();
96 
97  float ratio = 0.0;
98  struct FloatEulers eulers_zxy;
100 
101  // Ratio is only based on pitch now, as the pitot tube is often not mounted.
102  if (use_scheduling == 1) {
103  ratio = fabs(eulers_zxy.theta) / M_PI_2;
104  } else {
105  ratio = 0.0;
106  }
107  Bound(ratio,0.0,1.0);
108 
109  float stall_speed = 14.0; // m/s
110  float pitch_ratio = 0.0;
111  // Assume hover or stalled conditions below 14 m/s
112  if (use_scheduling == 1) {
113  if ( (eulers_zxy.theta > -M_PI_4) || (airspeed < stall_speed) ) {
114  if (eulers_zxy.theta > -M_PI_4) {
115  pitch_ratio = 0.0;
116  } else {
117  pitch_ratio = fabs(1.0 - eulers_zxy.theta/(-M_PI_4));
118  }
119 
120  } else {
121  pitch_ratio = 1.0;
122  }
123  } else {
124  pitch_ratio = 0.0;
125  }
126  Bound(pitch_ratio,0.0,1.0);
127 
128  float airspeed_pitch_eff = airspeed;
129  Bound(airspeed_pitch_eff, 8.0, 30.0);
130 
131  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
132 
133  // Roll
134  g1g2[0][i] = g_hover[0][i] * (1.0 - ratio) + g_forward[0][i] * ratio;
135  //Pitch, scaled with v^2
136  if (i>3 || all_act_fwd_sched) {
137  g1g2[1][i] = g_hover[1][i] * (1.0 - pitch_ratio) + g_forward[1][i] * pitch_ratio;
138  } else {
139  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);
140  }
141  //Yaw
142  g1g2[2][i] = g_hover[2][i] * (1.0 - ratio) + g_forward[2][i] * ratio;
143 
144  // Determine thrust of the wing to adjust the effectiveness of servos
145  float wing_thrust_scaling = 1.0;
146 #if INDI_NUM_ACT != 8
147 #error "ctfl_eff_scheduling_nederdrone is very specific and only works for one Nederdrone configuration!"
148 #endif
149  if (i>3) {
150  float wing_thrust = actuators_pprz[i-4];
151  Bound(wing_thrust,3000.0,9600.0);
152  wing_thrust_scaling = wing_thrust/9600.0/0.8;
153  }
154 
155  g1g2[0][i] *= wing_thrust_scaling;
156  g1g2[1][i] *= wing_thrust_scaling;
157  g1g2[2][i] *= wing_thrust_scaling;
158  }
159 
160  // Thrust effectiveness
161  float ratio_spec_force = 0.0;
162  float airspeed_spec_force = airspeed;
163  Bound(airspeed_spec_force, 8.0, 20.0);
164  ratio_spec_force = (airspeed_spec_force-8.0) / 12.0;
165 
166  for (uint8_t i = 0; i < INDI_NUM_ACT; i++) {
167  // Thrust
168  g1g2[3][i] = g_hover[3][i] * (1.0 - ratio_spec_force) + g_forward[3][i] * ratio_spec_force;
169  g1g2[3][i] *= thrust_eff_scaling;
170  }
171 
172  bool low_airspeed = stateGetAirspeed_f() < INDI_SCHEDULING_LOW_AIRSPEED;
173 
174  // Tip prop ratio
175  float pitch_deg = eulers_zxy.theta / M_PI * 180.f;
177  if (sched_tip_props_always_on || low_airspeed || radio_control.values[RADIO_AUX2] > 0) {
178  sched_ratio_tip_props = 1.0;
179  } else {
180  float pitch_offset = pitch_deg - sched_tip_prop_lower_pitch_limit_deg;
181  sched_ratio_tip_props = pitch_offset / pitch_range_deg;
182  }
183  Bound(sched_ratio_tip_props, 0.0, 1.0);
184 }
Core autopilot interface common to all firmwares.
#define INDI_SCHEDULING_LOW_AIRSPEED
int32_t use_scheduling
float sched_tip_prop_upper_pitch_limit_deg
bool all_act_fwd_sched
float sched_ratio_tip_props
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 thrust_eff_scaling
static float g_hover[4][INDI_NUM_ACT]
float sched_tip_prop_lower_pitch_limit_deg
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:1131
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition: state.h:1407
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
#define RADIO_AUX2
Definition: rc_intermcu.h:42
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