Paparazzi UAS v7.1_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
eff_scheduling_plusquad.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 Tomaso De Ponti <T.M.L.DePonti@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#include "generated/airframe.h"
28#include "state.h"
30#include "modules/core/abi.h"
33
34#define FORCE_ONELOOP
35#ifdef FORCE_ONELOOP
38#else
40#endif
41
42#ifndef PLUSQUAD_EFF_SCHED_IXX
43#error "NO PLUSQUAD_EFF_SCHED_IXX defined"
44#endif
45
46#ifndef PLUSQUAD_EFF_SCHED_IYY
47#error "NO PLUSQUAD_EFF_SCHED_IYY defined"
48#endif
49
50#ifndef PLUSQUAD_EFF_SCHED_IZZ
51#error "NO PLUSQUAD_EFF_SCHED_IZZ defined"
52#endif
53
54#ifndef PLUSQUAD_EFF_SCHED_M
55#error "NO PLUSQUAD_EFF_SCHED_M defined"
56#endif
57
58bool manual_roll = false;
59bool manual_pitch = false;
60bool manual_yaw = false;
61
62float roll_mult = 1.0;
63float pitch_mult = 1.0;
64float yaw_mult = 1.0;
65float thrust_mult = 1.0;
66float cutoff_prev = 1.0;
67/* Effectiveness Matrix definition */
68float G2_RW[EFF_MAT_COLS_NB] = {0};//PLUSQUAD_EFF_SCHED_G2; //scaled by RW_G_SCALE
69float G1_RW[EFF_MAT_ROWS_NB][EFF_MAT_COLS_NB] = {0};//{PLUSQUAD_EFF_SCHED_G1_ZERO, PLUSQUAD_EFF_SCHED_G1_ZERO, PLUSQUAD_EFF_SCHED_G1_THRUST, PLUSQUAD_EFF_SCHED_G1_ROLL, PLUSQUAD_EFF_SCHED_G1_PITCH, PLUSQUAD_EFF_SCHED_G1_YAW}; //scaled by RW_G_SCALE
71float I_inv[3][3] = {0};
72static float flt_cut_a = 1.0e-6;
73static float flt_cut_ap = 2.0e-3;
74static float flt_cut = 1.0e-4;
75
80/* Temp variables*/
81int G2_on = 1;
82float roll_eff = 8.9;//15.402;//3.835;//3.835;5.5
83float yaw_eff = 0.237; // 1.3171*0.390=0.514 or 0.659 and 0.812 (pitch - roll)
84float ele_min = 0.0;
85/* Define Forces and Moments tructs for each actuator*/
86struct RW_Model RW;
87
89float temp_mQ_k = 1.37; //Manual Value For Tuning2
90void update_attitude(void);
91void sum_EFF_MAT_RW(void);
92void init_RW_Model(void);
93void calc_G1_G2_RW(void);
94float calc_thrust_curve(float k1, float k2, float k3, float u);
95float calc_thrust_curve_d(float k1, float k2, float u);
96void calc_all_thrust_curve(void);
97void init_all_thrust_curve(void);
98
99
100#include "generated/modules.h"
112
114{
115 // Inertia and mass
116 RW.I.xx = PLUSQUAD_EFF_SCHED_IXX; // [kgm²]
117 RW.I.yy = PLUSQUAD_EFF_SCHED_IYY; // [kgm²]
118 RW.I.zz = PLUSQUAD_EFF_SCHED_IZZ; // [kgm²]
119 RW.m = PLUSQUAD_EFF_SCHED_M; // [kg]
120
121 // Init the thrust curves
123 // Motor Front
128
129 // Motor Right
134
135 // Motor Back
140
141 // Motor Left
146
147 // Initialize attitude
148 RW.att.phi = 0.0;
149 RW.att.theta = 0.0;
150 RW.att.psi = 0.0;
151 RW.att.sphi = 0.0;
152 RW.att.cphi = 0.0;
153 RW.att.stheta = 0.0;
154 RW.att.ctheta = 0.0;
155 RW.att.spsi = 0.0;
156 RW.att.cpsi = 0.0;
157
159}
160
161/*Update the attitude*/
187/* Function to precalculate once some constant effectiveness values to improve efficiency*/
189{
190 // Inertia
191 int x = 0;
192 int y = 1;
193 int z = 2;
194 I_inv[x][x] = 1/RW.I.xx;
195 I_inv[x][y] = 0.0;
196 I_inv[x][z] = 0.0;
197 I_inv[y][x] = 0.0;
198 I_inv[y][y] = 1/RW.I.yy;
199 I_inv[y][z] = 0.0;
200 I_inv[z][x] = 0.0;
201 I_inv[z][y] = 0.0;
202 I_inv[z][z] = 1/RW.I.zz;
203 //printf("I_inv_x: %f %f %f\n", I_inv[x][x], I_inv[x][y], I_inv[x][z]);
204 //printf("I_inv_y: %f %f %f\n", I_inv[y][x], I_inv[y][y], I_inv[y][z]);
205 //printf("I_inv_z: %f %f %f\n", I_inv[z][x], I_inv[z][y], I_inv[z][z]);
206 //printf("Control - I: %f %f %f\n", 1.0/I_inv[x][x], 1.0/I_inv[y][y], 1.0/I_inv[z][z]);
207 // Calc motor and control effectiveness
209
210 // Motor Front
216 // Motor Right
222 // Motor Back
225 G1_RW[RW_aq][COMMAND_MOTOR_BACK] = -(RW.mB.dFdu * RW.mB.l) * I_inv[y][y];
228 // Motor Left
234}
235
242
243
250void sum_EFF_MAT_RW(void) {
251
252 // Thrust force estimation
253 float T = RW.T / RW.m; // Thrust specific force. Minus gravity is a guesstimate.
254 int i = 0;
255 int j = 0;
256
257 for (i = 0; i < EFF_MAT_COLS_NB; i++) {
258 switch (i) {
259 case (COMMAND_MOTOR_FRONT):
260 case (COMMAND_MOTOR_BACK):
261 case (COMMAND_MOTOR_RIGHT):
262 case (COMMAND_MOTOR_LEFT):
265 EFF_MAT_RW[RW_aD][i] = (RW.att.cphi * RW.att.ctheta ) * G1_RW[RW_aZ][i];
266 EFF_MAT_RW[RW_ap][i] = (G1_RW[RW_ap][i]) ;
267 EFF_MAT_RW[RW_aq][i] = (G1_RW[RW_aq][i]) ;
268 EFF_MAT_RW[RW_ar][i] = (G1_RW[RW_ar][i] + G2_RW[i]) ;
269 break;
270 case (COMMAND_ROLL):
271 EFF_MAT_RW[RW_aN][i] = (-RW.att.cphi * RW.att.ctheta * RW.att.spsi * T);
272 EFF_MAT_RW[RW_aE][i] = ( RW.att.cphi * RW.att.ctheta * RW.att.cpsi * T);
273 EFF_MAT_RW[RW_aD][i] = ( RW.att.sphi * RW.att.ctheta * T);
274 EFF_MAT_RW[RW_ap][i] = 0.0;
275 EFF_MAT_RW[RW_aq][i] = 0.0;
276 EFF_MAT_RW[RW_ar][i] = 0.0;
277 break;
278 case (COMMAND_PITCH):
279 EFF_MAT_RW[RW_aN][i] = (-(RW.att.ctheta * RW.att.cpsi - RW.att.sphi * RW.att.stheta * RW.att.spsi) * T);
280 EFF_MAT_RW[RW_aE][i] = (-(RW.att.ctheta * RW.att.spsi + RW.att.sphi * RW.att.stheta * RW.att.cpsi) * T);
281 EFF_MAT_RW[RW_aD][i] = ( RW.att.stheta * RW.att.cphi * T) ;
282 EFF_MAT_RW[RW_ap][i] = 0.0;
283 EFF_MAT_RW[RW_aq][i] = 0.0;
284 EFF_MAT_RW[RW_ar][i] = 0.0;
285 break;
286 default:
287 break;
288 }
289 }
290 for (i = 0; i < EFF_MAT_ROWS_NB; i++) {
291 for(j = 0; j < EFF_MAT_COLS_NB; j++) {
292 float abs = fabs(EFF_MAT_RW[i][j]);
293 switch (i) {
294 case (RW_aN):
295 case (RW_aE):
296 case (RW_aD):
297 if (abs < flt_cut_a) {
298 EFF_MAT_RW[i][j] = 0.0;
299 }
300 break;
301 case (RW_aq):
302 case (RW_ar):
303 if (abs < flt_cut) {
304 EFF_MAT_RW[i][j] = 0.0;
305 }
306 break;
307 case (RW_ap):
308 if (abs < flt_cut_ap) {
309 EFF_MAT_RW[i][j] = 0.0;
310 }
311 break;
312 }
313 }
314 }
315 if(manual_roll){
316 EFF_MAT_RW[RW_ap][1] = -0.0370*roll_mult;//-0.0317895*roll_mult;
317 EFF_MAT_RW[RW_ap][3] = 0.0370*roll_mult;// 0.0317895*roll_mult;
318
319 }
320 if(manual_pitch){
321 EFF_MAT_RW[RW_aq][0] = 0.0314*pitch_mult;// 0.0274249*pitch_mult;
322 EFF_MAT_RW[RW_aq][2] = -0.0314*pitch_mult;//-0.0274249*pitch_mult;
323 }
324 if(manual_yaw){
325 EFF_MAT_RW[RW_ar][0] = -0.0022*yaw_mult;//-0.0025*yaw_mult;
326 EFF_MAT_RW[RW_ar][1] = 0.0022*yaw_mult;// 0.0025*yaw_mult;
327 EFF_MAT_RW[RW_ar][2] = -0.0022*yaw_mult;//-0.0025*yaw_mult;
328 EFF_MAT_RW[RW_ar][3] = 0.0022*yaw_mult;// 0.0025*yaw_mult;
329 //G2_RW[0] = -2.1e-5;
330 //G2_RW[1] = 2.1e-5;
331 //G2_RW[2] = -2.1e-5;
332 //G2_RW[3] = 2.1e-5;
333 }
334}
335
336float calc_thrust_curve(float k1, float k2, float k3, float u){
337 return k1*u*u + k2*u + k3;
338}
339
340float calc_thrust_curve_d(float k1, float k2, float u){
341 float out= 2.0*k1*u + k2;
342 Bound(out, 1.0e-3, 1.0e-2);
343 return out;
344}
345
347 switch(thrust_curve){
348 case(0):
349 // Curve calculated at the Current Motor State
354 break;
355 case(1):
356 // Curve statically calculated at 50% throttle
361 break;
362 case(2):
363 // Manual thrust for tuning
364 RW.mF.dFdu = PLUSQUAD_EFF_SCHED_MF_k2*thrust_mult;//0.0009645*thrust_mult;//calc_thrust_curve_d(PLUSQUAD_EFF_SCHED_MF_k1, PLUSQUAD_EFF_SCHED_MF_k2, 4800.0);
365 RW.mR.dFdu = PLUSQUAD_EFF_SCHED_MR_k2*thrust_mult;//0.0009645*thrust_mult;//temp_mQ_k/RW_G_SCALE;
366 RW.mB.dFdu = PLUSQUAD_EFF_SCHED_MB_k2*thrust_mult;//0.0009645*thrust_mult;//calc_thrust_curve_d(PLUSQUAD_EFF_SCHED_MB_k1, PLUSQUAD_EFF_SCHED_MB_k2, 4800.0);;
367 RW.mL.dFdu = PLUSQUAD_EFF_SCHED_ML_k2*thrust_mult;//0.0009645*thrust_mult;//temp_mQ_k/RW_G_SCALE;
368 break;
369 }
370 // T = k1*u^2 + k2*u + k3-----|k1 | k2 | k3 | u
371 // float T_mF = calc_thrust_curve(PLUSQUAD_EFF_SCHED_MF_k1, PLUSQUAD_EFF_SCHED_MF_k2, PLUSQUAD_EFF_SCHED_MF_k3, actuator_state_1l[COMMAND_MOTOR_FRONT]);
372 // float T_mR = calc_thrust_curve(PLUSQUAD_EFF_SCHED_MR_k1, PLUSQUAD_EFF_SCHED_MR_k2, PLUSQUAD_EFF_SCHED_MR_k3, actuator_state_1l[COMMAND_MOTOR_RIGHT]);
373 // float T_mB = calc_thrust_curve(PLUSQUAD_EFF_SCHED_MB_k1, PLUSQUAD_EFF_SCHED_MB_k2, PLUSQUAD_EFF_SCHED_MB_k3, actuator_state_1l[COMMAND_MOTOR_BACK]);
374 // float T_mL = calc_thrust_curve(PLUSQUAD_EFF_SCHED_ML_k1, PLUSQUAD_EFF_SCHED_ML_k2, PLUSQUAD_EFF_SCHED_ML_k3, actuator_state_1l[COMMAND_MOTOR_LEFT]);
375 RW.T = RW.m*9.81/(RW.att.cphi * RW.att.ctheta);//T_mF + T_mR + T_mB + T_mL;
376 Bound(RW.T, 30.0, 180.0);
377}
378
Main include for ABI (AirBorneInterface).
void update_attitude(void)
float yaw_mult
float G2_RW[EFF_MAT_COLS_NB]
void calc_G1_G2_RW(void)
int thrust_curve
float G1_RW[EFF_MAT_ROWS_NB][EFF_MAT_COLS_NB]
float I_inv[3][3]
float ele_min
struct FloatEulers eulers_zxy_RW_EFF
static float flt_cut_ap
float thrust_mult
float cutoff_prev
struct RW_Model RW
bool manual_pitch
float calc_thrust_curve_d(float k1, float k2, float u)
static Butterworth2LowPass psi_filt
float roll_eff
void calc_all_thrust_curve(void)
float actuator_state_filt_vect[EFF_MAT_COLS_NB]
float EFF_MAT_RW[EFF_MAT_ROWS_NB][EFF_MAT_COLS_NB]
bool manual_roll
float pitch_mult
float yaw_eff
float calc_thrust_curve(float k1, float k2, float k3, float u)
void eff_scheduling_rotwing_init(void)
static Butterworth2LowPass theta_filt
void sum_EFF_MAT_RW(void)
Function that sums g1 and g2 to obtain the g1_g2 matrix.
static float flt_cut_a
void init_RW_Model(void)
static float flt_cut
bool manual_yaw
void eff_scheduling_rotwing_periodic(void)
float temp_mQ_k
void init_all_thrust_curve(void)
float roll_mult
static Butterworth2LowPass phi_filt
#define RW_G_SCALE
#define RW_aN
#define RW_aE
#define RW_aZ
#define EFF_MAT_COLS_NB
#define RW_ap
#define RW_ar
#define COMMAND_PITCH
#define COMMAND_ROLL
#define EFF_MAT_ROWS_NB
#define RW_aq
#define RW_aD
struct F_M_Body mL
struct F_M_Body mR
struct F_M_Body mF
struct RW_attitude att
struct F_M_Body mB
float phi
in radians
float theta
in radians
float psi
in radians
void float_eulers_of_quat_zxy(struct FloatEulers *e, const 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:1302
Integrated Navigation System interface.
Simple first order low pass filter with bilinear transform.
float o[2]
output history
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, const float tau, const float sample_time, const float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, const float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
uint16_t foo
Definition main_demo5.c:58
Hardware independent API for actuators (servos, motor controllers).
float actuator_state_1l[ANDI_NUM_ACT_TOT]
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
float oneloop_nB_filt_cutoff
Definition oneloop_nB.c:130
API to get/set the generic vehicle states.