Paparazzi UAS  v5.0.5_stable-7-g4b8bbb7
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
stabilization_attitude_quat_float.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2009 Antoine Drouin <poinix@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 
29 #include <stdio.h>
31 #include "math/pprz_algebra_int.h"
32 #include "state.h"
33 #include "generated/airframe.h"
34 
36 
39 
41 
42 float stabilization_att_fb_cmd[COMMANDS_NB];
43 float stabilization_att_ff_cmd[COMMANDS_NB];
44 
46 
47 static const float phi_pgain[] = STABILIZATION_ATTITUDE_PHI_PGAIN;
48 static const float theta_pgain[] = STABILIZATION_ATTITUDE_THETA_PGAIN;
49 static const float psi_pgain[] = STABILIZATION_ATTITUDE_PSI_PGAIN;
50 
51 static const float phi_dgain[] = STABILIZATION_ATTITUDE_PHI_DGAIN;
52 static const float theta_dgain[] = STABILIZATION_ATTITUDE_THETA_DGAIN;
53 static const float psi_dgain[] = STABILIZATION_ATTITUDE_PSI_DGAIN;
54 
55 static const float phi_igain[] = STABILIZATION_ATTITUDE_PHI_IGAIN;
56 static const float theta_igain[] = STABILIZATION_ATTITUDE_THETA_IGAIN;
57 static const float psi_igain[] = STABILIZATION_ATTITUDE_PSI_IGAIN;
58 
59 static const float phi_ddgain[] = STABILIZATION_ATTITUDE_PHI_DDGAIN;
60 static const float theta_ddgain[] = STABILIZATION_ATTITUDE_THETA_DDGAIN;
61 static const float psi_ddgain[] = STABILIZATION_ATTITUDE_PSI_DDGAIN;
62 
63 static const float phi_dgain_d[] = STABILIZATION_ATTITUDE_PHI_DGAIN_D;
64 static const float theta_dgain_d[] = STABILIZATION_ATTITUDE_THETA_DGAIN_D;
65 static const float psi_dgain_d[] = STABILIZATION_ATTITUDE_PSI_DGAIN_D;
66 
67 
68 #if defined COMMAND_ROLL_SURFACE && defined COMMAND_PITCH_SURFACE && defined COMMAND_YAW_SURFACE
69 #define HAS_SURFACE_COMMANDS 1
70 #endif
71 
72 #ifdef HAS_SURFACE_COMMANDS
73 static const float phi_pgain_surface[] = STABILIZATION_ATTITUDE_PHI_PGAIN_SURFACE;
74 static const float theta_pgain_surface[] = STABILIZATION_ATTITUDE_THETA_PGAIN_SURFACE;
75 static const float psi_pgain_surface[] = STABILIZATION_ATTITUDE_PSI_PGAIN_SURFACE;
76 
77 static const float phi_dgain_surface[] = STABILIZATION_ATTITUDE_PHI_DGAIN_SURFACE;
78 static const float theta_dgain_surface[] = STABILIZATION_ATTITUDE_THETA_DGAIN_SURFACE;
79 static const float psi_dgain_surface[] = STABILIZATION_ATTITUDE_PSI_DGAIN_SURFACE;
80 
81 static const float phi_igain_surface[] = STABILIZATION_ATTITUDE_PHI_IGAIN_SURFACE;
82 static const float theta_igain_surface[] = STABILIZATION_ATTITUDE_THETA_IGAIN_SURFACE;
83 static const float psi_igain_surface[] = STABILIZATION_ATTITUDE_PSI_IGAIN_SURFACE;
84 
85 static const float phi_ddgain_surface[] = STABILIZATION_ATTITUDE_PHI_DDGAIN_SURFACE;
86 static const float theta_ddgain_surface[] = STABILIZATION_ATTITUDE_THETA_DDGAIN_SURFACE;
87 static const float psi_ddgain_surface[] = STABILIZATION_ATTITUDE_PSI_DDGAIN_SURFACE;
88 #endif
89 
90 #define IERROR_SCALE 1024
91 
93 
95 
96  for (int i = 0; i < STABILIZATION_ATTITUDE_GAIN_NB; i++) {
102 #ifdef HAS_SURFACE_COMMANDS
103  VECT3_ASSIGN(stabilization_gains[i].surface_p, phi_pgain_surface[i], theta_pgain_surface[i], psi_pgain_surface[i]);
104  VECT3_ASSIGN(stabilization_gains[i].surface_d, phi_dgain_surface[i], theta_dgain_surface[i], psi_dgain_surface[i]);
105  VECT3_ASSIGN(stabilization_gains[i].surface_i, phi_igain_surface[i], theta_igain_surface[i], psi_igain_surface[i]);
106  VECT3_ASSIGN(stabilization_gains[i].surface_dd, phi_ddgain_surface[i], theta_ddgain_surface[i], psi_ddgain_surface[i]);
107 #endif
108  }
109 
113 }
114 
116 {
118  // This could be bad -- Just say no.
119  return;
120  }
121  gain_idx = idx;
123 }
124 
126 
127  /* reset psi setpoint to current psi angle */
129 
131 
134 }
135 
137  /* set failsafe to zero roll/pitch and current heading */
138  float heading2 = stabilization_attitude_get_heading_f() / 2;
139  stab_att_sp_quat.qi = cosf(heading2);
140  stab_att_sp_quat.qx = 0.0;
141  stab_att_sp_quat.qy = 0.0;
142  stab_att_sp_quat.qz = sinf(heading2);
143 }
144 
149 }
150 
151 #ifndef GAIN_PRESCALER_FF
152 #define GAIN_PRESCALER_FF 1
153 #endif
154 static void attitude_run_ff(float ff_commands[], struct FloatAttitudeGains *gains, struct FloatRates *ref_accel)
155 {
156  /* Compute feedforward based on reference acceleration */
157 
158  ff_commands[COMMAND_ROLL] = GAIN_PRESCALER_FF * gains->dd.x * ref_accel->p;
159  ff_commands[COMMAND_PITCH] = GAIN_PRESCALER_FF * gains->dd.y * ref_accel->q;
160  ff_commands[COMMAND_YAW] = GAIN_PRESCALER_FF * gains->dd.z * ref_accel->r;
161 #ifdef HAS_SURFACE_COMMANDS
162  ff_commands[COMMAND_ROLL_SURFACE] = GAIN_PRESCALER_FF * gains->surface_dd.x * ref_accel->p;
163  ff_commands[COMMAND_PITCH_SURFACE] = GAIN_PRESCALER_FF * gains->surface_dd.y * ref_accel->q;
164  ff_commands[COMMAND_YAW_SURFACE] = GAIN_PRESCALER_FF * gains->surface_dd.z * ref_accel->r;
165 #endif
166 }
167 
168 #ifndef GAIN_PRESCALER_P
169 #define GAIN_PRESCALER_P 1
170 #endif
171 #ifndef GAIN_PRESCALER_D
172 #define GAIN_PRESCALER_D 1
173 #endif
174 #ifndef GAIN_PRESCALER_I
175 #define GAIN_PRESCALER_I 1
176 #endif
177 static void attitude_run_fb(float fb_commands[], struct FloatAttitudeGains *gains, struct FloatQuat *att_err,
178  struct FloatRates *rate_err, struct FloatRates *rate_err_d, struct FloatQuat *sum_err)
179 {
180  /* PID feedback */
181  fb_commands[COMMAND_ROLL] =
182  GAIN_PRESCALER_P * gains->p.x * att_err->qx +
183  GAIN_PRESCALER_D * gains->d.x * rate_err->p +
184  GAIN_PRESCALER_D * gains->rates_d.x * rate_err_d->p +
185  GAIN_PRESCALER_I * gains->i.x * sum_err->qx;
186 
187  fb_commands[COMMAND_PITCH] =
188  GAIN_PRESCALER_P * gains->p.y * att_err->qy +
189  GAIN_PRESCALER_D * gains->d.y * rate_err->q +
190  GAIN_PRESCALER_D * gains->rates_d.y * rate_err_d->q +
191  GAIN_PRESCALER_I * gains->i.y * sum_err->qy;
192 
193  fb_commands[COMMAND_YAW] =
194  GAIN_PRESCALER_P * gains->p.z * att_err->qz +
195  GAIN_PRESCALER_D * gains->d.z * rate_err->r +
196  GAIN_PRESCALER_D * gains->rates_d.z * rate_err_d->r +
197  GAIN_PRESCALER_I * gains->i.z * sum_err->qz;
198 
199 #ifdef HAS_SURFACE_COMMANDS
200  fb_commands[COMMAND_ROLL_SURFACE] =
201  GAIN_PRESCALER_P * gains->surface_p.x * att_err->qx +
202  GAIN_PRESCALER_D * gains->surface_d.x * rate_err->p +
203  GAIN_PRESCALER_I * gains->surface_i.x * sum_err->qx;
204 
205  fb_commands[COMMAND_PITCH_SURFACE] =
206  GAIN_PRESCALER_P * gains->surface_p.y * att_err->qy +
207  GAIN_PRESCALER_D * gains->surface_d.y * rate_err->q +
208  GAIN_PRESCALER_I * gains->surface_i.y * sum_err->qy;
209 
210  fb_commands[COMMAND_YAW_SURFACE] =
211  GAIN_PRESCALER_P * gains->surface_p.z * att_err->qz +
212  GAIN_PRESCALER_D * gains->surface_d.z * rate_err->r +
213  GAIN_PRESCALER_I * gains->surface_i.z * sum_err->qz;
214 #endif
215 }
216 
217 void stabilization_attitude_run(bool_t enable_integrator) {
218 
219  /*
220  * Update reference
221  */
223 
224  /*
225  * Compute errors for feedback
226  */
227 
228  /* attitude error */
229  struct FloatQuat att_err;
230  struct FloatQuat* att_quat = stateGetNedToBodyQuat_f();
231  FLOAT_QUAT_INV_COMP(att_err, *att_quat, stab_att_ref_quat);
232  /* wrap it in the shortest direction */
233  FLOAT_QUAT_WRAP_SHORTEST(att_err);
234 
235  /* rate error */
236  struct FloatRates rate_err;
237  struct FloatRates* body_rate = stateGetBodyRates_f();
238  RATES_DIFF(rate_err, stab_att_ref_rate, *body_rate);
239  /* rate_d error */
240  struct FloatRates body_rate_d;
241  RATES_DIFF(body_rate_d, *body_rate, last_body_rate);
242  RATES_COPY(last_body_rate, *body_rate);
243 
244  /* integrated error */
245  if (enable_integrator) {
246  struct FloatQuat new_sum_err, scaled_att_err;
247  /* update accumulator */
248  scaled_att_err.qi = att_err.qi;
249  scaled_att_err.qx = att_err.qx / IERROR_SCALE;
250  scaled_att_err.qy = att_err.qy / IERROR_SCALE;
251  scaled_att_err.qz = att_err.qz / IERROR_SCALE;
252  FLOAT_QUAT_COMP(new_sum_err, stabilization_att_sum_err_quat, scaled_att_err);
253  FLOAT_QUAT_NORMALIZE(new_sum_err);
256  } else {
257  /* reset accumulator */
260  }
261 
263 
264  attitude_run_fb(stabilization_att_fb_cmd, &stabilization_gains[gain_idx], &att_err, &rate_err, &body_rate_d, &stabilization_att_sum_err_quat);
265 
266  stabilization_cmd[COMMAND_ROLL] = stabilization_att_fb_cmd[COMMAND_ROLL] + stabilization_att_ff_cmd[COMMAND_ROLL];
267  stabilization_cmd[COMMAND_PITCH] = stabilization_att_fb_cmd[COMMAND_PITCH] + stabilization_att_ff_cmd[COMMAND_PITCH];
268  stabilization_cmd[COMMAND_YAW] = stabilization_att_fb_cmd[COMMAND_YAW] + stabilization_att_ff_cmd[COMMAND_YAW];
269 
270 #ifdef HAS_SURFACE_COMMANDS
271  stabilization_cmd[COMMAND_ROLL_SURFACE] = stabilization_att_fb_cmd[COMMAND_ROLL_SURFACE] + stabilization_att_ff_cmd[COMMAND_ROLL_SURFACE];
272  stabilization_cmd[COMMAND_PITCH_SURFACE] = stabilization_att_fb_cmd[COMMAND_PITCH_SURFACE] + stabilization_att_ff_cmd[COMMAND_PITCH_SURFACE];
273  stabilization_cmd[COMMAND_YAW_SURFACE] = stabilization_att_fb_cmd[COMMAND_YAW_SURFACE] + stabilization_att_ff_cmd[COMMAND_YAW_SURFACE];
274 #endif
275 
276  /* bound the result */
277  BoundAbs(stabilization_cmd[COMMAND_ROLL], MAX_PPRZ);
278  BoundAbs(stabilization_cmd[COMMAND_PITCH], MAX_PPRZ);
279  BoundAbs(stabilization_cmd[COMMAND_YAW], MAX_PPRZ);
280 }
281 
282 void stabilization_attitude_read_rc(bool_t in_flight) {
283 
285  //FLOAT_QUAT_WRAP_SHORTEST(stab_att_sp_quat);
286 }
#define FLOAT_QUAT_COPY(_qo, _qi)
#define FLOAT_RATES_ZERO(_r)
void stabilization_attitude_ref_schedule(uint8_t idx)
#define RATES_DIFF(_c, _a, _b)
Definition: pprz_algebra.h:336
struct FloatRates last_body_rate
static const float theta_dgain[]
static const float theta_ddgain[]
static int gain_idx
static const float phi_igain[]
angular rates
static const float psi_dgain_d[]
#define RATES_COPY(_a, _b)
Definition: pprz_algebra.h:301
float stabilization_att_fb_cmd[COMMANDS_NB]
Read an attitude setpoint from the RC.
struct FloatEulers stabilization_att_sum_err_eulers
void stabilization_attitude_ref_enter()
static const float phi_pgain[]
void stabilization_attitude_read_rc_setpoint_quat_f(struct FloatQuat *q_sp, bool_t in_flight)
struct FloatQuat stab_att_ref_quat
euler angles
#define FLOAT_QUAT_OF_EULERS(_q, _e)
struct FloatAttitudeGains stabilization_gains[STABILIZATION_ATTITUDE_GAIN_NB]
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition: state.h:1017
static void attitude_run_ff(float ff_commands[], struct FloatAttitudeGains *gains, struct FloatRates *ref_accel)
float p
in rad/s^2
static const float phi_dgain_d[]
Roation quaternion.
void stabilization_attitude_gain_schedule(uint8_t idx)
void stabilization_attitude_read_rc(bool_t in_flight)
void stabilization_attitude_enter(void)
Paparazzi floating point algebra.
static const float psi_dgain[]
static void attitude_run_fb(float fb_commands[], struct FloatAttitudeGains *gains, struct FloatQuat *att_err, struct FloatRates *rate_err, struct FloatRates *rate_err_d, struct FloatQuat *sum_err)
static const float psi_ddgain[]
static const float theta_dgain_d[]
struct Int32Quat stab_att_sp_quat
with INT32_QUAT_FRAC
static const float psi_pgain[]
void stabilization_attitude_run(bool_t enable_integrator)
void stabilization_attitude_init(void)
struct Int32Eulers stab_att_sp_euler
with INT32_ANGLE_FRAC
#define FLOAT_QUAT_WRAP_SHORTEST(_q)
void stabilization_attitude_ref_init(void)
static const float psi_igain[]
void stabilization_attitude_ref_update()
static const float theta_igain[]
float r
in rad/s^2
#define FLOAT_QUAT_INV_COMP(_b2c, _a2b, _a2c)
static struct FloatRates * stateGetBodyRates_f(void)
Get vehicle body angular rate (float).
Definition: state.h:1078
static const float phi_dgain[]
#define FLOAT_QUAT_NORMALIZE(_q)
#define VECT3_ASSIGN(_a, _x, _y, _z)
Definition: pprz_algebra.h:97
#define FLOAT_EULERS_ZERO(_e)
#define FLOAT_QUAT_COMP(_a2c, _a2b, _b2c)
unsigned char uint8_t
Definition: types.h:14
API to get/set the generic vehicle states.
#define FLOAT_EULERS_OF_QUAT(_e, _q)
int32_t psi
in rad with INT32_ANGLE_FRAC
General stabilization interface for rotorcrafts.
int32_t stabilization_cmd[COMMANDS_NB]
Stabilization commands.
Definition: stabilization.c:28
#define EULERS_FLOAT_OF_BFP(_ef, _ei)
Definition: pprz_algebra.h:567
static float p[2][2]
float q
in rad/s^2
float stabilization_att_ff_cmd[COMMANDS_NB]
#define MAX_PPRZ
Definition: paparazzi.h:8
float stabilization_attitude_get_heading_f(void)
#define STABILIZATION_ATTITUDE_GAIN_IDX_DEFAULT
static const float theta_pgain[]
static const float phi_ddgain[]
#define FLOAT_QUAT_ZERO(_q)
struct FloatQuat stabilization_att_sum_err_quat
struct FloatRates stab_att_ref_rate
with REF_RATE_FRAC
void stabilization_attitude_set_from_eulers_i(struct Int32Eulers *sp_euler)
void stabilization_attitude_set_failsafe_setpoint(void)
struct FloatRates stab_att_ref_accel
with REF_ACCEL_FRAC
Paparazzi fixed point algebra.
#define STABILIZATION_ATTITUDE_GAIN_NB
euler angles