Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
nav_rotorcraft_hybrid.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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
28#include "math/pprz_isa.h"
29#include "generated/flight_plan.h"
30
31// if NAV_HYBRID_MAX_BANK is not defined, set it to 30 degrees.
32#ifndef NAV_HYBRID_MAX_BANK
33float nav_hybrid_max_bank = 0.52f;
34#else
36#endif
37
38// Max ground speed that will be commanded
39#ifndef NAV_HYBRID_MAX_AIRSPEED
40#define NAV_HYBRID_MAX_AIRSPEED 15.0f
41#endif
42
43#ifndef NAV_HYBRID_SPEED_MARGIN
44#define NAV_HYBRID_SPEED_MARGIN 10.0f
45#endif
46
47#define NAV_MAX_SPEED (NAV_HYBRID_MAX_AIRSPEED + NAV_HYBRID_SPEED_MARGIN)
49
50#ifndef NAV_HYBRID_GOTO_MAX_SPEED
51#define NAV_HYBRID_GOTO_MAX_SPEED NAV_MAX_SPEED
52#endif
53
54#ifndef NAV_HYBRID_MAX_DECELERATION
55#define NAV_HYBRID_MAX_DECELERATION 1.0
56#endif
57
58#ifndef NAV_HYBRID_MAX_ACCELERATION
59#define NAV_HYBRID_MAX_ACCELERATION 4.0
60#endif
61
62#ifndef NAV_HYBRID_SOFT_ACCELERATION
63#define NAV_HYBRID_SOFT_ACCELERATION NAV_HYBRID_MAX_ACCELERATION
64#endif
65
66float nav_max_deceleration_sp = NAV_HYBRID_MAX_DECELERATION; //Maximum deceleration allowed for the set-point
67float nav_max_acceleration_sp = NAV_HYBRID_MAX_ACCELERATION; //Maximum acceleration allowed for the set-point
68float nav_hybrid_soft_acceleration = NAV_HYBRID_SOFT_ACCELERATION; //Soft acceleration limit allowed for the set-point (Equal to the maximum acceleration by default)
69float nav_hybrid_max_acceleration = NAV_HYBRID_MAX_ACCELERATION; //Maximum general limit in acceleration allowed for the hybrid navigation
70
71#ifndef NAV_HYBRID_MAX_EXPECTED_WIND
72#define NAV_HYBRID_MAX_EXPECTED_WIND 5.0f
73#endif
75
76#ifdef NAV_HYBRID_LINE_GAIN
78#else
80#endif
81
82#ifndef NAV_HYBRID_NAV_LINE_DIST
83#define NAV_HYBRID_NAV_LINE_DIST 50.f
84#endif
85
86#ifndef NAV_HYBRID_NAV_CIRCLE_DIST
87#define NAV_HYBRID_NAV_CIRCLE_DIST 40.f
88#endif
89
90#ifdef GUIDANCE_INDI_POS_GAIN
92#elif defined(NAV_HYBRID_POS_GAIN)
94#else
96#endif
97
98#if defined(NAV_HYBRID_POS_GAIN) && defined(GUIDANCE_INDI_POS_GAIN)
99#warning "NAV_HYBRID_POS_GAIN and GUIDANCE_INDI_POS_GAIN serve similar purpose and are both defined, using GUIDANCE_INDI_POS_GAIN"
100#endif
101
102#ifndef GUIDANCE_INDI_HYBRID
103bool force_forward = 0.0f;
104#endif
105
106/* When using external vision, run the nav functions in position mode for better tracking*/
107#ifndef NAV_HYBRID_EXT_VISION_SETPOINT_MODE
108#define NAV_HYBRID_EXT_VISION_SETPOINT_MODE FALSE
109#endif
110
111/* Use max target groundspeed and max acceleration to limit circle radius*/
112#ifndef NAV_HYBRID_LIMIT_CIRCLE_RADIUS
113#define NAV_HYBRID_LIMIT_CIRCLE_RADIUS FALSE
114#endif
115
116static float max_speed_for_deceleration(float dist_to_wp);
117
121static void nav_hybrid_goto(struct EnuCoor_f *wp)
122{
126 VECT2_COPY(nav.target, *wp);
127
128 // Calculate position error
129 struct FloatVect2 pos_error;
130 struct EnuCoor_f *pos = stateGetPositionEnu_f();
132
133 struct FloatVect2 speed_sp;
135
136 // Bound the setpoint velocity vector
138 if (!force_forward) {
139 // If not in force_forward, compute speed based on deceleration and nav_max_speed
140 // Calculate distance to waypoint
143 }
145
148
149 // In optitrack tests use position mode for more precise hovering
150#if NAV_HYBRID_EXT_VISION_SETPOINT_MODE
152#else
154#endif
155}
156
158{
162
163 // Calculate magnitude of the desired speed vector based on distance to waypoint
165 float desired_speed;
166 if (force_forward) {
168 } else {
172 }
173
174 // Calculate length of line segment
175 float length_line = Max(float_vect2_norm(&wp_diff), 0.01f);
176 // Normal vector to the line, with length of the line
177 struct FloatVect2 normalv;
179 // Length of normal vector is the same as of the line segment
180 float length_normalv = length_line; // >= 0.01
181 // Distance along the normal vector
183 // Normal vector scaled to be the distance to the line
187 // The distance that needs to be traveled along the line
190 // Calculate the desired direction to converge to the line
191 struct FloatVect2 direction;
192 VECT2_SMUL(direction, v_along_line, (1.f / (1.f + fabsf(dist_to_line) * 0.05f)));
195 // Scale to have the desired speed
197 // final target position, should be on the line, for display
199
205}
206
215 float max_speed_decel2 = fabsf(2.f * dist_to_wp * nav_max_deceleration_sp); // dist_to_wp can only be positive, but just in case
217 // Bound the setpoint velocity vector
219 return max_h_speed;
220}
221
222static bool nav_hybrid_approaching(struct EnuCoor_f *wp, struct EnuCoor_f *from, float approaching_time)
223{
224 float dist_to_point;
225 struct FloatVect2 diff;
226 struct EnuCoor_f *pos = stateGetPositionEnu_f();
227
228 /* if an approaching_time is given, estimate diff after approching_time secs */
229 if (approaching_time > 0.f) {
232 struct EnuCoor_f *speed = stateGetSpeedEnu_f();
236 }
237 /* else use current position */
238 else {
239 VECT2_DIFF(diff, *wp, *pos);
240 }
241 /* compute distance of estimated/current pos to target wp
242 */
244
245 /* return TRUE if we have arrived */
247 return true;
248 }
249
250 /* if coming from a valid waypoint */
251 if (from != NULL) {
252 /* return TRUE if normal line at the end of the segment is crossed */
253 struct FloatVect2 from_diff;
254 VECT2_DIFF(from_diff, *wp, *from);
255 return (diff.x * from_diff.x + diff.y * from_diff.y < 0.f);
256 }
257
258 return false;
259}
260
261static void nav_hybrid_circle(struct EnuCoor_f *wp_center, float radius)
262{
263 struct FloatVect2 pos_diff;
264 float desired_speed;
265
267 // direction of rotation
268 float sign_radius = (radius > 0.f) ? 1.f : (radius < 0.f) ? -1.f : 0.f;
269 // absolute radius
270 float abs_radius = fabsf(radius);
271#if NAV_HYBRID_LIMIT_CIRCLE_RADIUS
274#endif
275 if (abs_radius > 0.1f) {
276 // store last qdr
278 // compute qdr
280 // increment circle radians
284 // progress angle
286 Bound(progress_angle, M_PI / 16.f, M_PI / 4.f);
288 // final target position, should be on the circle, for display
289 nav.target.x = wp_center->x + cosf(alpha) * abs_radius;
290 nav.target.y = wp_center->y + sinf(alpha) * abs_radius;
291 }
292 else {
293 // radius is too small, direct to center
294 VECT2_COPY(nav.target, *wp_center);
295 }
296 // compute desired speed
299 // far from circle, speed proportional to diff
302 } else {
303 // close to circle, speed function of radius for a feasible turn
304 // 0.8 * MAX_BANK gives some margins for the turns
307 }
308 if (force_forward) {
311 }
313 // compute speed vector from target position
314 struct FloatVect2 speed_unit;
318 nav_rotorcraft_base.circle.center = *wp_center;
322}
323
340
341
#define Min(x, y)
Definition esc_dshot.c:109
void float_vect2_bound_in_2d(struct FloatVect2 *vect2, float bound)
static float float_vect2_norm(struct FloatVect2 *v)
static void float_vect2_normalize(struct FloatVect2 *v)
normalize 2D vector in place
#define VECT2_ADD(_a, _b)
#define VECT2_SMUL(_vo, _vi, _s)
#define VECT2_DIFF(_c, _a, _b)
#define VECT2_COPY(_a, _b)
#define VECT2_SUM(_c, _a, _b)
#define VECT2_ASSIGN(_a, _x, _y)
#define PPRZ_ISA_GRAVITY
earth-surface gravitational acceleration in m/s^2
Definition pprz_isa.h:56
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:848
static struct EnuCoor_f * stateGetSpeedEnu_f(void)
Get ground speed in local ENU coordinates (float).
Definition state.h:1058
struct FloatVect3 speed_sp
#define GUIDANCE_INDI_POS_GAIN
uint16_t foo
Definition main_demo5.c:58
float leg_progress
progress over leg
Definition nav_base.h:39
struct EnuCoor_f center
center WP position
Definition nav_base.h:46
struct NavGoto_t goto_wp
Definition nav_base.h:63
float leg_length
leg length
Definition nav_base.h:40
struct EnuCoor_f to
end WP position
Definition nav_base.h:37
float dist2_to_wp
squared distance to next waypoint
Definition nav_base.h:38
struct NavCircle_t circle
Definition nav_base.h:64
struct EnuCoor_f from
start WP position
Definition nav_base.h:36
float radians
incremental angular distance
Definition nav_base.h:49
float radius
radius in meters
Definition nav_base.h:47
float qdr
qdr in radians
Definition nav_base.h:48
struct NavBase_t nav_rotorcraft_base
Basic Nav struct.
float nav_max_deceleration_sp
bool force_forward
forward flight for hybrid nav
static void nav_hybrid_circle(struct EnuCoor_f *wp_center, float radius)
#define NAV_HYBRID_MAX_ACCELERATION
static void nav_hybrid_goto(struct EnuCoor_f *wp)
Implement basic nav function for the hybrid case.
#define NAV_HYBRID_SOFT_ACCELERATION
#define NAV_HYBRID_NAV_LINE_DIST
#define NAV_HYBRID_NAV_CIRCLE_DIST
static void nav_hybrid_route(struct EnuCoor_f *wp_start, struct EnuCoor_f *wp_end)
float nav_max_speed
float nav_hybrid_max_bank
float nav_max_acceleration_sp
#define NAV_HYBRID_MAX_EXPECTED_WIND
float nav_hybrid_max_expected_wind
float nav_hybrid_line_gain
float nav_hybrid_pos_gain
static bool nav_hybrid_approaching(struct EnuCoor_f *wp, struct EnuCoor_f *from, float approaching_time)
static float max_speed_for_deceleration(float dist_to_wp)
Calculate max speed when decelerating at MAX capacity a_max distance travelled d = 1/2 a_max t^2 The ...
void nav_rotorcraft_hybrid_init(void)
Init and register nav functions.
#define NAV_HYBRID_MAX_DECELERATION
float nav_hybrid_max_acceleration
float nav_hybrid_soft_acceleration
#define NAV_MAX_SPEED
Specific navigation functions for hybrid aircraft.
struct FloatVect2 pos_diff
uint8_t direction
float y
in meters
float x
in meters
vector in East North Up coordinates Units: meters
Paparazzi atmospheric pressure conversion utilities.
struct RotorcraftNavigation nav
Definition navigation.c:51
void nav_register_circle(navigation_circle nav_circle)
Definition navigation.c:399
void nav_register_goto_wp(navigation_goto nav_goto, navigation_route nav_route, navigation_approaching nav_approaching)
Registering functions.
Definition navigation.c:392
float get_dist2_to_point(struct EnuCoor_f *p)
Returns squared horizontal distance to given point.
Definition navigation.c:308
Rotorcraft navigation functions.
struct EnuCoor_f speed
speed setpoint (in m/s)
Definition navigation.h:128
#define NAV_HORIZONTAL_MODE_WAYPOINT
Nav modes these modes correspond to the flight plan instructions used to set the high level navigatio...
Definition navigation.h:85
#define NAV_HORIZONTAL_MODE_CIRCLE
Definition navigation.h:87
#define NAV_HORIZONTAL_MODE_ROUTE
Definition navigation.h:86
#define NAV_SETPOINT_MODE_SPEED
Definition navigation.h:101
#define DEFAULT_CIRCLE_RADIUS
default nav_circle_radius in meters
Definition navigation.h:42
#define NAV_SETPOINT_MODE_POS
Nav setpoint modes these modes correspond to submodes defined by navigation routines to tell which se...
Definition navigation.h:100
struct EnuCoor_f target
final target position (in meters)
Definition navigation.h:126
#define ARRIVED_AT_WAYPOINT
minimum horizontal distance to waypoint to mark as arrived
Definition navigation.h:55
float alpha
Definition textons.c:133