Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
guidance_hybrid.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Ewoud Smeur <e.j.j.smeur@tudelft.nl>
3 * This is code for guidance of hybrid UAVs. It needs a simple velocity
4 * model to control the ground velocity of the UAV while estimating the
5 * wind velocity.
6 *
7 * This file is part of paparazzi.
8 *
9 * paparazzi is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * paparazzi is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with paparazzi; see the file COPYING. If not, write to
21 * the Free Software Foundation, 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
23 */
24
39
40/* for guidance_v.thrust_coeff */
42
43#include "firmwares/rotorcraft/guidance/guidance_pid.h" // FIXME is it really what we want ?
44
45// max airspeed for quadshot guidance
46#ifndef MAX_AIRSPEED
47#define MAX_AIRSPEED 15
48#endif
49
50// high res frac for integration of angles
51#define INT32_ANGLE_HIGH_RES_FRAC 18
52
53// Variables used for settings
61
62#define AIRSPEED_HOVER 4
63#define AIRSPEED_FORWARD 12
64#define CRUISE_THROTTLE 4000
65#define FWD_SPEED_P_GAIN 30
66#define FWD_ALT_THRUST_GAIN 0.35
67#define FWD_PID_DIV 2
68#define FWD_NOMINAL_PITCH 78.0
69#define FWD_PITCH_GAIN 2.1
70#define HOVER_P_GAIN 12
71
79
80// Private variables
89
98
99#if PERIODIC_TELEMETRY
101
120
121#endif
122
149
150#define INT32_ANGLE_HIGH_RES_NORMALIZE(_a) { \
151 while ((_a) > (INT32_ANGLE_PI << (INT32_ANGLE_HIGH_RES_FRAC - INT32_ANGLE_FRAC))) (_a) -= (INT32_ANGLE_2_PI << (INT32_ANGLE_HIGH_RES_FRAC - INT32_ANGLE_FRAC)); \
152 while ((_a) < -(INT32_ANGLE_PI << (INT32_ANGLE_HIGH_RES_FRAC - INT32_ANGLE_FRAC))) (_a) += (INT32_ANGLE_2_PI << (INT32_ANGLE_HIGH_RES_FRAC - INT32_ANGLE_FRAC)); \
153 }
154
162
164{
165 // compute position error
167 // Compute ground speed setpoint
169 return guidance_hybrid_run();
170}
171
173{
174 // directly set ground speed setpoint
176 return guidance_hybrid_run();
177}
178
180{
181 struct StabilizationSetpoint sp = { 0 };
182 // TODO
183 return sp;
184}
185
187{
188 struct ThrustSetpoint th = guidance_pid_v_run_pos(in_flight, gv);
190}
191
197
203
204
207{
208
209 //notes:
210 //in forward flight, it is preferred to first get to min(airspeed_sp, airspeed_ref) and then change heading and then get to airspeed_sp
211 //in hover, just a gradual change is needed, or maybe not even needed
212 //changes between flight regimes should be handled
213
214 //determine the heading of the airspeed_sp vector
215 int32_t omega = 0;
218 //only for debugging
220
221 //The difference of the current heading with the required heading.
224
225 //only for debugging
226 heading_diff_disp = (int32_t)(heading_diff / 3.14 * 180.0);
227
228 //calculate the norm of the airspeed setpoint
231
232 //reference goes with a steady pace towards the setpoint airspeed
233 //hold ref norm below 4 m/s until heading is aligned
235 && (guidance_hybrid_norm_ref_airspeed > ((AIRSPEED_HOVER << 8) - 10)) && (fabs(heading_diff) > (5.0 / 180.0 * 3.14)))) {
237 guidance_hybrid_norm_ref_airspeed) * 2 - 1) * 3 / 2;
239 }
240
242
243 int32_t psi = ypr_sp->psi;
245 PPRZ_ITRIG_SIN(s_psi, psi);
246 PPRZ_ITRIG_COS(c_psi, psi);
247
250
253 // translate speed_sp into bank angle and heading
254
255 // change heading to direction of airspeed, faster if the airspeed is higher
256 if (heading_diff > 0.0) {
258 } else if (heading_diff < 0.0) {
260 }
261
262 if (omega > ANGLE_BFP_OF_REAL(0.8)) { omega = ANGLE_BFP_OF_REAL(0.8); }
263 if (omega < ANGLE_BFP_OF_REAL(-0.8)) { omega = ANGLE_BFP_OF_REAL(-0.8); }
264
265 // 2) calculate roll/pitch commands
266 struct Int32Vect2 hover_sp;
267 //if the setpoint is beyond 4m/s but the ref is not, the norm of the hover sp will stay at 4m/s
268 if (norm_sp_airspeed > (AIRSPEED_HOVER << 8)) {
271 } else {
274 }
275
276 // gain of 10 means that for 4 m/s an angle of 40 degrees is needed
277 ypr_sp->theta = (((- (c_psi * hover_sp.x + s_psi * hover_sp.y)) >> INT32_TRIG_FRAC) * hover_p_gain * INT32_ANGLE_PI / 180) >> 8;
278 ypr_sp->phi = ((((- s_psi * hover_sp.x + c_psi * hover_sp.y)) >> INT32_TRIG_FRAC) * hover_p_gain * INT32_ANGLE_PI / 180) >> 8;
279 } else {
281 // translate speed_sp into theta + thrust
282 // coordinated turns to change heading
283
284 // calculate required pitch angle from airspeed_sp magnitude
287 } else {
292 }
293
294 // if the sp_airspeed is within hovering range, don't start a coordinated turn
295 if (norm_sp_airspeed < (AIRSPEED_HOVER << 8)) {
296 omega = 0;
297 ypr_sp->phi = 0;
298 } else { // coordinated turn
300 if (ypr_sp->phi > ANGLE_BFP_OF_REAL(max_turn_bank / 180.0 * M_PI)) { ypr_sp->phi = ANGLE_BFP_OF_REAL(max_turn_bank / 180.0 * M_PI); }
301 if (ypr_sp->phi < ANGLE_BFP_OF_REAL(-max_turn_bank / 180.0 * M_PI)) { ypr_sp->phi = ANGLE_BFP_OF_REAL(-max_turn_bank / 180.0 * M_PI); }
302
303 //feedforward estimate angular rotation omega = g*tan(phi)/v
305
306 if (omega > ANGLE_BFP_OF_REAL(0.7)) { omega = ANGLE_BFP_OF_REAL(0.7); }
307 if (omega < ANGLE_BFP_OF_REAL(-0.7)) { omega = ANGLE_BFP_OF_REAL(-0.7); }
308 }
309 }
310
311 //only for debugging purposes
312 omega_disp = omega;
313
314 //go to higher resolution because else the increment is too small to be added
316
318
319 // go back to angle_frac
321 ypr_sp->theta = ypr_sp->theta + v_control_pitch;
322}
323
325{
328
329 //create setpoint groundspeed with a norm of 15 m/s
331 //scale the groundspeed_sp to 15 m/s if large enough to begin with
332 if (norm_groundspeed_sp > 1 << 8) {
335 } else { //groundspeed_sp is very small, so continue with the current heading
338 PPRZ_ITRIG_SIN(s_psi, psi);
339 PPRZ_ITRIG_COS(c_psi, psi);
342 }
343 }
344
345 struct Int32Vect2 airspeed_sp;
349
352
353 //Check if the airspeed_sp is larger than the max airspeed. If so, give the wind cancellatioin priority.
360 8) - (max_airspeed << 8) * max_airspeed;
361
363 float d_sqrt_f = sqrtf(dv);
365
366 int32_t result = ((-bv + d_sqrt) << 8) / (2 * av);
367
370 } else {
371 // Add the wind to get the airspeed setpoint
374 }
375
376 // limit the airspeed setpoint to 15 m/s, because else saturation+windup will occur
378 // add check for non-zero airspeed (in case the max_airspeed is ever set to zero
379 if ((norm_airspeed_sp > (max_airspeed << 8)) && (norm_airspeed_sp != 0)) {
382 }
383}
384
386{
387
388 /* compute speed error */
393
394 //Low pass wind_estimate, because we know the wind usually only changes slowly
395 //But not too slow, because the wind_estimate is also an adaptive element for the airspeed model inaccuracies
398
401}
402
404{
406
407 /* orientation vector describing simultaneous rotation of roll/pitch */
408 struct FloatVect3 ov;
409 ov.x = ANGLE_FLOAT_OF_BFP(sp_cmd->phi);
410 ov.y = ANGLE_FLOAT_OF_BFP(sp_cmd->theta);
411 ov.z = 0.0;
412 /* quaternion from that orientation vector */
413 struct FloatQuat q_rp;
415 struct Int32Quat q_rp_i;
417
418 // get the vertical vector to rotate the roll pitch setpoint around
419 struct Int32Vect3 zaxis = {0, 0, 1};
420
421 /* get current heading setpoint */
422 struct Int32Quat q_yaw_sp;
424
425 // first apply the roll/pitch setpoint and then the yaw
426 struct Int32Quat quat_sp;
428
430}
431
437{
440
446
449
450 /* Hover regime */
453
454 // Do not control pitch and only PID for hover
455 v_control_pitch = 0;
459 }
460 /* Forward regime */
463
464 //Control altitude with pitch, now only proportional control
469 }
470 /* Transition regime */
471 else {
475
476 // Control by both thrust and pitch
481 }
482
484}
485
486
487#if GUIDANCE_HYBRID_USE_AS_DEFAULT
488// guidance hybrid is implementing the default functions of guidance
489
490void guidance_h_run_enter(void)
491{
492 /*Obtain eulers with zxy rotation order*/
493 struct FloatEulers eulers_zxy;
496}
497
498void guidance_v_run_enter(void)
499{
500 // nothing to do
501}
502
504{
505 return guidance_hybrid_h_run_pos(in_flight, gh);
506}
507
509{
510 return guidance_hybrid_h_run_speed(in_flight, gh);
511}
512
514{
515 return guidance_hybrid_h_run_accel(in_flight, gh);
516}
517
519{
520 return guidance_hybrid_v_run_pos(in_flight, gv);
521}
522
524{
525 return guidance_hybrid_v_run_speed(in_flight, gv);
526}
527
529{
530 return guidance_hybrid_v_run_accel(in_flight, gv);
531}
532
533#endif
534
#define UNUSED(x)
float psi
in radians
#define FLOAT_ANGLE_NORMALIZE(_a)
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
void float_quat_of_orientation_vect(struct FloatQuat *q, const struct FloatVect3 *ov)
Quaternion from orientation vector.
euler angles
Roation quaternion.
#define VECT2_ADD(_a, _b)
#define VECT2_DIFF(_c, _a, _b)
#define VECT2_COPY(_a, _b)
#define VECT2_SDIV(_vo, _vi, _s)
#define QUAT_BFP_OF_REAL(_qi, _qf)
int32_t phi
in rad with INT32_ANGLE_FRAC
int32_t psi
in rad with INT32_ANGLE_FRAC
int32_t theta
in rad with INT32_ANGLE_FRAC
void int32_quat_comp(struct Int32Quat *a2c, struct Int32Quat *a2b, struct Int32Quat *b2c)
Composition (multiplication) of two quaternions.
void int32_quat_of_axis_angle(struct Int32Quat *q, struct Int32Vect3 *uv, int32_t angle)
Quaternion from unit vector and angle.
#define INT_MULT_RSHIFT(_a, _b, _r)
#define INT32_POS_FRAC
#define ANGLE_BFP_OF_REAL(_af)
#define INT32_ANGLE_PI
#define INT32_TRIG_FRAC
static uint32_t int32_vect2_norm(struct Int32Vect2 *v)
return norm of 2D vector
#define POS_FLOAT_OF_BFP(_ai)
#define FLOAT_OF_BFP(_vbfp, _frac)
#define INT32_ANGLE_FRAC
#define INT_VECT2_ZERO(_v)
#define ANGLE_FLOAT_OF_BFP(_ai)
#define INT32_VECT2_RSHIFT(_o, _i, _r)
#define POS_BFP_OF_REAL(_af)
#define INT_EULERS_ZERO(_e)
euler angles
Rotation quaternion.
int32_t y
East.
int32_t x
North.
vector in North East Down coordinates
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition state.h:1294
static struct NedCoor_i * stateGetPositionNed_i(void)
Get position in local NED coordinates (int).
Definition state.h:794
static struct NedCoor_i * stateGetSpeedNed_i(void)
Get ground speed in local NED coordinates (int).
Definition state.h:1004
struct StabilizationSetpoint guidance_hybrid_h_run_pos(bool in_flight UNUSED, struct HorizontalGuidance *gh)
struct StabilizationSetpoint guidance_hybrid_h_run_speed(bool in_flight UNUSED, struct HorizontalGuidance *gh)
float fwd_pitch_gain
int32_t guidance_hybrid_norm_ref_airspeed
#define FWD_NOMINAL_PITCH
float guidance_hybrid_norm_ref_airspeed_f
float fwd_alt_thrust_gain
static int32_t omega_disp
static int32_t v_control_pitch
#define FWD_PID_DIV
#define MAX_AIRSPEED
static struct Int32Vect2 guidance_h_pos_err
static struct Int32Eulers guidance_hybrid_ypr_sp
float fwd_pid_div
float turn_bank_gain
static int32_t airspeed_sp_heading_disp
struct StabilizationSetpoint guidance_hybrid_run(void)
Runs the Hybrid Guidance main functions.
static struct Int32Vect2 guidance_hybrid_groundspeed_sp
static void send_hybrid_guidance(struct transport_tx *trans, struct link_device *dev)
#define HOVER_P_GAIN
struct StabilizationSetpoint guidance_hybrid_h_run_accel(bool in_flight UNUSED, struct HorizontalGuidance *gh UNUSED)
#define CRUISE_THROTTLE
#define FWD_ALT_THRUST_GAIN
static bool guidance_hovering
void guidance_hybrid_determine_wind_estimate(void)
Description.
static struct Int32Vect2 guidance_hybrid_airspeed_sp
int32_t max_airspeed
#define INT32_ANGLE_HIGH_RES_NORMALIZE(_a)
int32_t hover_p_gain
static int32_t heading_diff_disp
struct ThrustSetpoint guidance_hybrid_vertical(struct ThrustSetpoint *th)
Take a thrust command as input and returns the modified value according to the current flight regime.
int32_t fwd_speed_p_gain
float fwd_nominal_pitch
#define FWD_PITCH_GAIN
void guidance_hybrid_groundspeed_to_airspeed(void)
Description.
static struct Int32Vect2 wind_estimate_high_res
static struct Int32Vect2 guidance_hybrid_airspeed_ref
struct ThrustSetpoint guidance_hybrid_v_run_speed(bool in_flight, struct VerticalGuidance *gv)
void guidance_hybrid_airspeed_to_attitude(struct Int32Eulers *ypr_sp)
Convert a required airspeed to a certain attitude for the Quadshot.
int32_t horizontal_speed_gain
struct ThrustSetpoint guidance_hybrid_v_run_accel(bool in_flight, struct VerticalGuidance *gv)
int32_t wind_gain
int32_t cruise_throttle
#define FWD_SPEED_P_GAIN
struct StabilizationSetpoint guidance_hybrid_set_cmd_i(struct Int32Eulers *sp_cmd)
Creates the attitude set-points from an orientation vector.
static int32_t high_res_psi
float max_turn_bank
static struct Int32Vect2 guidance_hybrid_ref_airspeed
static struct Int32Vect2 wind_estimate
#define AIRSPEED_FORWARD
void guidance_hybrid_init(void)
Hybrid Guidance Initialization function.
#define INT32_ANGLE_HIGH_RES_FRAC
#define AIRSPEED_HOVER
bool force_forward_flight
static int32_t norm_sp_airspeed_disp
struct ThrustSetpoint guidance_hybrid_v_run_pos(bool in_flight, struct VerticalGuidance *gv)
Guidance controllers (horizontal and vertical) for Hybrid UAV configurations.
struct FloatEulers eulers_zxy
state eulers in zxy order
void guidance_v_run_enter(void)
struct ThrustSetpoint guidance_v_run_pos(bool in_flight UNUSED, struct VerticalGuidance *gv)
struct ThrustSetpoint guidance_v_run_speed(bool in_flight UNUSED, struct VerticalGuidance *gv)
struct ThrustSetpoint guidance_v_run_accel(bool in_flight UNUSED, struct VerticalGuidance *gv)
struct ThrustSetpoint guidance_pid_v_run_accel(bool in_flight UNUSED, struct VerticalGuidance *gv UNUSED)
struct ThrustSetpoint guidance_pid_v_run_pos(bool in_flight, struct VerticalGuidance *gv)
struct ThrustSetpoint guidance_pid_v_run_speed(bool in_flight, struct VerticalGuidance *gv)
struct GuidancePID guidance_pid
Guidance PID structyre.
Guidance controller with PID for rotorcrafts.
uint16_t foo
Definition main_demo5.c:58
#define MAX_PPRZ
Definition paparazzi.h:8
#define PPRZ_ITRIG_SIN(_s, _a)
#define PPRZ_ITRIG_COS(_c, _a)
Generic interface for radio control modules.
Horizontal guidance for rotorcrafts.
void guidance_h_run_enter(void)
struct StabilizationSetpoint guidance_h_run_pos(bool in_flight, struct HorizontalGuidance *gh)
struct StabilizationSetpoint guidance_h_run_speed(bool in_flight, struct HorizontalGuidance *gh)
struct StabilizationSetpoint guidance_h_run_accel(bool in_flight, struct HorizontalGuidance *gh)
struct VerticalGuidance guidance_v
Definition guidance_v.c:60
Vertical guidance for rotorcrafts.
float nominal_throttle
nominal throttle for hover.
Definition guidance_v.h:102
struct RotorcraftNavigation nav
Definition navigation.c:51
float heading
heading setpoint (in radians)
Definition navigation.h:133
General attitude stabilization interface for rotorcrafts.
struct StabilizationSetpoint stab_sp_from_quat_i(struct Int32Quat *quat)
struct ThrustSetpoint th_sp_from_thrust_i(int32_t thrust, uint8_t axis)
int32_t th_sp_to_thrust_i(struct ThrustSetpoint *th, int32_t thrust, uint8_t axis)
#define THRUST_AXIS_Z
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
Stabilization setpoint.
union StabilizationSetpoint::@278 sp
Thrust setpoint // TODO to a setpoint header Structure to store the desired thrust vector with differ...
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
int int32_t
Typedef defining 32 bit int type.