Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
rot_wing_automation.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Dennis van Wijngaarden <D.C.vanWijngaarden@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 "state.h"
30 #include "state.h"
31 
33 #include "modules/nav/waypoints.h"
34 #include "generated/modules.h"
35 
36 /*** Longitudinal maximum acceleration during a transition */
37 #ifndef ROT_WING_AUTOMATION_TRANS_ACCEL
38 #define ROT_WING_AUTOMATION_TRANS_ACCEL 1.0
39 #endif
40 
41 /*** Longitudinal maximum deceleration during a transition */
42 #ifndef ROT_WING_AUTOMATION_TRANS_DECEL
43 #define ROT_WING_AUTOMATION_TRANS_DECEL 0.5
44 #endif
45 
46 /*** Maximum transition distance (at which to draw waypoints) */
47 #ifndef ROT_WING_AUTOMATION_TRANS_LENGTH
48 #define ROT_WING_AUTOMATION_TRANS_LENGTH 200.0
49 #endif
50 
51 /*** Airspeed threshold above which the transiton is considered complete */
52 #ifndef ROT_WING_AUTOMATION_TRANS_AIRSPEED
53 #define ROT_WING_AUTOMATION_TRANS_AIRSPEED 15.0
54 #endif
55 
56 /*** Wind low-pass filtering cutoff frequency */
57 #ifndef ROT_WING_AUTOMATION_WIND_FILT_CUTOFF
58 #define ROT_WING_AUTOMATION_WIND_FILT_CUTOFF 0.001
59 #endif
60 
62 
63 // Declare filters (for windspeed estimation)
65 
66 // declare function
67 inline void update_waypoint_rot_wing_automation(uint8_t wp_id, struct FloatVect3 *target_ned);
68 inline void update_wind_vector(void);
69 
71 {
76 
77  rot_wing_a.transitioned = false;
78  rot_wing_a.windvect.x = 0.0;
79  rot_wing_a.windvect.y = 0.0;
80  rot_wing_a.windvect_f.x = 0.0;
81  rot_wing_a.windvect_f.y = 0.0;
82 
83  // Init windvector low pass filter
84  float tau = 1.0 / (2.0 * M_PI * ROT_WING_AUTOMATION_WIND_FILT_CUTOFF);
85  float sample_time = 1.0 / PERIODIC_ROT_WING_AUTOMATION_FREQ;
88 }
89 
90 // periodic function
92 {
94  float airspeed = stateGetAirspeed_f();
95  if (airspeed > rot_wing_a.trans_airspeed) {
96  rot_wing_a.transitioned = true;
97  } else {
98  rot_wing_a.transitioned = false;
99  }
100 }
101 
102 // Update a waypoint such that you can see on the GCS where the drone wants to go
104 {
105 
106  // Update the waypoint
107  struct EnuCoor_f target_enu;
108  ENU_OF_TO_NED(target_enu, *target_ned);
109  waypoint_set_enu(wp_id, &target_enu);
110 
111  // Send waypoint update roughly every half second
112  RunOnceEvery(100 / 2, {
113  // Send to the GCS that the waypoint has been moved
114  DOWNLINK_SEND_WP_MOVED_ENU(DefaultChannel, DefaultDevice, &wp_id,
115  &waypoints[wp_id].enu_i.x,
116  &waypoints[wp_id].enu_i.y,
117  &waypoints[wp_id].enu_i.z);
118  });
119 }
120 
122 {
123  float psi = stateGetNedToBodyEulers_f()->psi;
124 
125  float cpsi = cosf(psi);
126  float spsi = sinf(psi);
127 
128  float airspeed = stateGetAirspeed_f();
129  struct NedCoor_f *groundspeed = stateGetSpeedNed_f();
130  struct FloatVect2 airspeed_v = { cpsi * airspeed, spsi * airspeed };
131  VECT2_DIFF(rot_wing_a.windvect, *groundspeed, airspeed_v);
132 
133  // Filter the wind
136 }
137 
138 // Function to visualize from flightplan, call repeadely
139 void rot_wing_vis_transition(uint8_t wp_transition_id, uint8_t wp_decel_id, uint8_t wp_end_id)
140 {
141  //state eulers in zxy order
142  struct FloatEulers eulers_zxy;
143 
144  // get heading and cos and sin of heading
146  float psi = eulers_zxy.psi;
147  float cpsi = cosf(psi);
148  float spsi = sinf(psi);
149 
150  // get airspeed
151  float airspeed = stateGetAirspeed_f();
152  // get groundspeed
154 
155  // get drone position
156  struct NedCoor_f *drone_pos = stateGetPositionNed_f();
157 
158  // Move reference waypoints
159  // Move end transition waypoint at the correct length
160  struct FloatVect3 end_transition_rel_pos;
161  VECT3_COPY(end_transition_rel_pos, *drone_pos);
162  end_transition_rel_pos.x = cpsi * rot_wing_a.trans_length;
163  end_transition_rel_pos.y = spsi * rot_wing_a.trans_length;
164  struct FloatVect3 end_transition_pos;
165  VECT3_SUM(end_transition_pos, end_transition_rel_pos, *drone_pos);
166  end_transition_pos.z = drone_pos->z;
167  update_waypoint_rot_wing_automation(wp_end_id, &end_transition_pos);
168 
169  // Move transition waypoint
170  float airspeed_error = rot_wing_a.trans_airspeed - airspeed;
171  float transition_time = airspeed_error / rot_wing_a.trans_accel;
172  float average_ground_speed = ground_speed + airspeed_error / 2.;
173  float transition_distance = average_ground_speed * transition_time;
174 
175  struct FloatVect3 transition_rel_pos;
176  VECT3_COPY(transition_rel_pos, *drone_pos);
177  transition_rel_pos.x = cpsi * transition_distance;
178  transition_rel_pos.y = spsi * transition_distance;
179  struct FloatVect3 transition_pos;
180  VECT3_SUM(transition_pos, transition_rel_pos, *drone_pos);
181  transition_pos.z = drone_pos->z;
182  update_waypoint_rot_wing_automation(wp_transition_id, &transition_pos);
183 
184  // Move decel point
185  float final_groundspeed = ground_speed + airspeed_error;
186  float decel_time = final_groundspeed / rot_wing_a.trans_decel;
187  float decel_distance = (final_groundspeed / 2.) * decel_time;
188  float decel_distance_from_drone = rot_wing_a.trans_length - decel_distance;
189 
190  struct FloatVect3 decel_rel_pos;
191  VECT3_COPY(decel_rel_pos, *drone_pos);
192  decel_rel_pos.x = cpsi * decel_distance_from_drone;
193  decel_rel_pos.y = spsi * decel_distance_from_drone;
194  struct FloatVect3 decel_pos;
195  VECT3_SUM(decel_pos, decel_rel_pos, *drone_pos);
196  decel_pos.z = drone_pos->z;
197  update_waypoint_rot_wing_automation(wp_decel_id, &decel_pos);
198 }
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition: common_nav.c:39
float y
Definition: common_nav.h:41
float x
Definition: common_nav.h:40
static float ground_speed
Definition: follow_me.c:76
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
#define VECT3_SUM(_c, _a, _b)
Definition: pprz_algebra.h:161
#define VECT2_DIFF(_c, _a, _b)
Definition: pprz_algebra.h:92
#define VECT3_COPY(_a, _b)
Definition: pprz_algebra.h:140
#define ENU_OF_TO_NED(_po, _pi)
Definition: pprz_geodetic.h:41
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
Definition: state.h:1143
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition: state.h:1131
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
Definition: state.h:710
static float stateGetHorizontalSpeedNorm_f(void)
Get norm of horizontal ground speed (float).
Definition: state.h:935
static struct NedCoor_f * stateGetSpeedNed_f(void)
Get ground speed in local NED coordinates (float).
Definition: state.h:908
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition: state.h:1407
struct FloatEulers eulers_zxy
state eulers in zxy order
Simple first order low pass filter with bilinear transform.
static void init_butterworth_2_low_pass(Butterworth2LowPass *filter, float tau, float sample_time, float value)
Init a second order Butterworth filter.
static float update_butterworth_2_low_pass(Butterworth2LowPass *filter, float value)
Update second order Butterworth low pass filter state with a new value.
Second order low pass filter structure.
void waypoint_set_enu(uint8_t wp_id, struct EnuCoor_f *enu)
Set local ENU waypoint coordinates.
Definition: waypoints.c:177
Paparazzi floating point algebra.
float z
in meters
vector in East North Up coordinates Units: meters
vector in North East Down coordinates Units: meters
struct rot_wing_automation rot_wing_a
#define ROT_WING_AUTOMATION_WIND_FILT_CUTOFF
void update_waypoint_rot_wing_automation(uint8_t wp_id, struct FloatVect3 *target_ned)
void init_rot_wing_automation(void)
void rot_wing_vis_transition(uint8_t wp_transition_id, uint8_t wp_decel_id, uint8_t wp_end_id)
Butterworth2LowPass rot_wing_automation_wind_filter[2]
#define ROT_WING_AUTOMATION_TRANS_ACCEL
#define ROT_WING_AUTOMATION_TRANS_AIRSPEED
#define ROT_WING_AUTOMATION_TRANS_DECEL
void update_wind_vector(void)
#define ROT_WING_AUTOMATION_TRANS_LENGTH
void periodic_rot_wing_automation(void)
struct FloatVect2 windvect
struct FloatVect2 windvect_f
API to get/set the generic vehicle states.
Periodic telemetry system header (includes downlink utility and generated code).
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98