Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
guidance_indi_hybrid_tailsitter.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Ewoud Smeur <ewoud.smeur@gmail.com>
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, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
28 #include "state.h"
29 #include "generated/modules.h"
30 
41 void guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float v_gih[GUIDANCE_INDI_HYBRID_V]) {
42  // Get attitude
43  struct FloatEulers eulers_zxy;
45 
46 
47  /*Pre-calculate sines and cosines*/
48  float sphi = sinf(eulers_zxy.phi);
49  float cphi = cosf(eulers_zxy.phi);
50  float stheta = sinf(eulers_zxy.theta);
51  float ctheta = cosf(eulers_zxy.theta);
52  float spsi = sinf(eulers_zxy.psi);
53  float cpsi = cosf(eulers_zxy.psi);
54  //minus gravity is a guesstimate of the thrust force, thrust measurement would be better
55 
56 #ifndef GUIDANCE_INDI_PITCH_EFF_SCALING
57 #define GUIDANCE_INDI_PITCH_EFF_SCALING 1.0
58 #endif
59 
60  /*Amount of lift produced by the wing*/
61  float pitch_lift = eulers_zxy.theta;
62  Bound(pitch_lift,-M_PI_2,0);
63  float lift = sinf(pitch_lift)*9.81;
64  float T = cosf(pitch_lift)*-9.81;
65 
66  // get the derivative of the lift wrt to theta
68 
69  Gmat[0][0] = cphi*ctheta*spsi*T + cphi*spsi*lift;
70  Gmat[1][0] = -cphi*ctheta*cpsi*T - cphi*cpsi*lift;
71  Gmat[2][0] = -sphi*ctheta*T -sphi*lift;
72  Gmat[0][1] = (ctheta*cpsi - sphi*stheta*spsi)*T*GUIDANCE_INDI_PITCH_EFF_SCALING + sphi*spsi*liftd;
73  Gmat[1][1] = (ctheta*spsi + sphi*stheta*cpsi)*T*GUIDANCE_INDI_PITCH_EFF_SCALING - sphi*cpsi*liftd;
74  Gmat[2][1] = -cphi*stheta*T*GUIDANCE_INDI_PITCH_EFF_SCALING + cphi*liftd;
75  Gmat[0][2] = stheta*cpsi + sphi*ctheta*spsi;
76  Gmat[1][2] = stheta*spsi - sphi*ctheta*cpsi;
77  Gmat[2][2] = cphi*ctheta;
78 
79  v_gih[0] = a_diff.x;
80  v_gih[1] = a_diff.y;
81  v_gih[2] = a_diff.z;
82 }
83 
84 
85 #if GUIDANCE_INDI_HYBRID_USE_WLS
86 
87 
88 
89 void guidance_indi_hybrid_set_wls_settings(float body_v[3] UNUSED, float roll_angle, float pitch_angle)
90 {
91  // Set lower limits
92  wls_guid_p.u_min[0] = -guidance_indi_max_bank - roll_angle; // roll
93  wls_guid_p.u_min[1] = RadOfDeg(guidance_indi_min_pitch) - pitch_angle; // pitch
94  wls_guid_p.u_min[2] = (MAX_PPRZ - actuator_state_filt_vect[0]) * g1g2[3][0] + (MAX_PPRZ - actuator_state_filt_vect[1]) * g1g2[3][1] + (MAX_PPRZ - actuator_state_filt_vect[2]) * g1g2[3][2] + (MAX_PPRZ - actuator_state_filt_vect[3]) * g1g2[3][3];
95 
96  // Set upper limits limits
97  wls_guid_p.u_max[0] = guidance_indi_max_bank - roll_angle; //roll
98  wls_guid_p.u_max[1] = RadOfDeg(GUIDANCE_INDI_MAX_PITCH) - pitch_angle; // pitch
99  wls_guid_p.u_max[2] = -(actuator_state_filt_vect[0]*g1g2[3][0] + actuator_state_filt_vect[1]*g1g2[3][1] + actuator_state_filt_vect[2]*g1g2[3][2] + actuator_state_filt_vect[3]*g1g2[3][3]);
100 
101  // Set prefered states
102  wls_guid_p.u_pref[0] = -roll_angle; // prefered delta roll angle
103  wls_guid_p.u_pref[1] = -pitch_angle; // prefered delta pitch angle
104  wls_guid_p.u_pref[2] = wls_guid_p.u_max[2];
105 }
106 
107 
108 #endif
109 
110 
uint8_t last_wp UNUSED
float phi
in radians
float theta
in radians
float psi
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
float guidance_indi_max_bank
float guidance_indi_min_pitch
float WEAK guidance_indi_get_liftd(float airspeed, float theta)
Get the derivative of lift w.r.t.
struct FloatEulers eulers_zxy
state eulers in zxy order
float v_gih[3]
A guidance mode based on Incremental Nonlinear Dynamic Inversion Come to ICRA2016 to learn more!
void WEAK guidance_indi_hybrid_set_wls_settings(float body_v[3], float roll_angle, float pitch_angle)
#define GUIDANCE_INDI_MAX_PITCH
void guidance_indi_calcg_wing(float Gmat[GUIDANCE_INDI_HYBRID_V][GUIDANCE_INDI_HYBRID_U], struct FloatVect3 a_diff, float v_gih[GUIDANCE_INDI_HYBRID_V])
Calculate the matrix of partial derivatives of the roll, pitch and thrust w.r.t.
#define GUIDANCE_INDI_PITCH_EFF_SCALING
#define MAX_PPRZ
Definition: paparazzi.h:8
float g1g2[INDI_OUTPUTS][INDI_NUM_ACT]
float actuator_state_filt_vect[INDI_NUM_ACT]
API to get/set the generic vehicle states.