Paparazzi UAS v7.1_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
ctc.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017 Hector Garcia de Marina
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 */
22
23#include <math.h>
24#include <std.h>
25#include <stdio.h>
26
31#include "autopilot.h"
32
34#ifndef CTC_MAX_AC
35#define CTC_MAX_AC 4
36#endif
37
38#if PERIODIC_TELEMETRY
39static void send_ctc(struct transport_tx *trans, struct link_device *dev)
40{
41 pprz_msg_send_CTC(trans, dev, AC_ID, 6 * CTC_MAX_AC, &(tableNei[0][0]));
42}
43
44static void send_ctc_control(struct transport_tx *trans, struct link_device *dev)
45{
46 pprz_msg_send_CTC_CONTROL(trans, dev, AC_ID, &ctc_control.v_centroid_x, &ctc_control.v_centroid_y,
47 &ctc_control.target_vx, &ctc_control.target_vy, &ctc_control.target_px, &ctc_control.target_py,
48 &ctc_control.ref_px, &ctc_control.ref_py);
49}
50#endif // PERIODIC TELEMETRY
51
52// Control
54#ifndef CTC_GAIN_K1
55#define CTC_GAIN_K1 0.001
56#endif
57#ifndef CTC_GAIN_K2
58#define CTC_GAIN_K2 0.001
59#endif
60#ifndef CTC_GAIN_ALPHA
61#define CTC_GAIN_ALPHA 0.01
62#endif
64#ifndef CTC_TIMEOUT
65#define CTC_TIMEOUT 1500
66#endif
68#ifndef CTC_OMEGA
69#define CTC_OMEGA 0.25
70#endif
72#ifndef CTC_TIME_BROAD
73#define CTC_TIME_BROAD 100
74#endif
75
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CTC_OMEGA, CTC_TIME_BROAD
78 };
79
84
86
91
92bool ctc_gogo = false;
93bool ctc_first_time = true;
95
96void ctc_init(void)
97{
98 for (int i = 0; i < CTC_MAX_AC; i++) {
99 tableNei[i][0] = -1;
100 }
101
102#if PERIODIC_TELEMETRY
105#endif
106}
107
109{
110 ctc_control.target_px = moving_target_px;
111 ctc_control.target_py = moving_target_py;
112 ctc_control.target_vx = moving_target_vx;
113 ctc_control.target_vy = moving_target_vy;
114
116
117 return true;
118}
119
121{
122 ctc_control.target_px = waypoints[wp].x;
123 ctc_control.target_py = waypoints[wp].y;
124 ctc_control.target_vx = 0;
125 ctc_control.target_vy = 0;
126
128
129 return true;
130}
131
132bool collective_tracking_point(float x, float y)
133{
134 ctc_control.target_px = x;
135 ctc_control.target_py = y;
136 ctc_control.target_vx = 0;
137 ctc_control.target_vy = 0;
138
140
141 return true;
142}
143
145{
147 struct EnuCoor_f *v = stateGetSpeedEnu_f();
149 float vx = v->x;
150 float vy = v->y;
151 float px = p->x;
152 float py = p->y;
153
154 ctc_control.vx = vx;
155 ctc_control.vy = vy;
156 ctc_control.px = px;
157 ctc_control.py = py;
158
159 ctc_control.v_centroid_x = vx;
160 ctc_control.v_centroid_y = vy;
161 ctc_control.p_centroid_x = px;
162 ctc_control.p_centroid_y = py;
163
164
165 float u_vel = 0;
166 float u_spa = 0;
167
168 if (ctc_first_time) {
170 ctc_first_time = false;
171 }
172
174 float dt = (now - before) / 1000.0;
175 before = now;
176
177 int num_neighbors = 0;
178
179 int num_neighbors = 0;
180
181 for (int i = 0; i < CTC_MAX_AC; i++) {
182 if (tableNei[i][0] != -1) {
183 uint32_t timeout = now - last_info[i];
184 if (timeout > ctc_control.timeout) {
185 tableNei[i][5] = ctc_control.timeout;
186 } else {
187 tableNei[i][5] = (uint16_t)timeout;
188 num_neighbors++;
189 float vx_nei = tableNei[i][1] / 100.0;
190 float vy_nei = tableNei[i][2] / 100.0;
191 float px_nei = tableNei[i][3] / 100.0;
192 float py_nei = tableNei[i][4] / 100.0;
193
194 ctc_control.v_centroid_x += vx_nei;
195 ctc_control.v_centroid_y += vy_nei;
196 ctc_control.p_centroid_x += px_nei;
197 ctc_control.p_centroid_y += py_nei;
198 }
199 }
200 }
201 else{
202
203 int num_neighbors = 0;
204
205 for (int i = 0; i < CTC_MAX_AC; i++) {
206 if (tableNei[i][0] != -1) {
207 uint32_t timeout = now - last_info[i];
208 if (timeout > ctc_control.timeout) {
209 tableNei[i][5] = ctc_control.timeout;
210 } else {
211 tableNei[i][5] = (uint16_t)timeout;
212 num_neighbors++;
213 float vx_nei = tableNei[i][1] / 100.0;
214 float vy_nei = tableNei[i][2] / 100.0;
215 float px_nei = tableNei[i][3] / 100.0;
216 float py_nei = tableNei[i][4] / 100.0;
217
218 ctc_control.v_centroid_x += vx_nei;
219 ctc_control.v_centroid_y += vy_nei;
220 ctc_control.p_centroid_x += px_nei;
221 ctc_control.p_centroid_y += py_nei;
222 }
223 }
224 }
225 }
226
227 if (num_neighbors != 0) {
228 ctc_control.v_centroid_x /= (num_neighbors + 1);
229 ctc_control.v_centroid_y /= (num_neighbors + 1);
230 ctc_control.p_centroid_x /= (num_neighbors + 1);
231 ctc_control.p_centroid_y /= (num_neighbors + 1);
232
233 float error_target_x = ctc_control.target_px - ctc_control.p_centroid_x;
234 float error_target_y = ctc_control.target_py - ctc_control.p_centroid_y;
235 float error_target_ref_x = ctc_control.target_px - ctc_control.ref_px;
236 float error_target_ref_y = ctc_control.target_py - ctc_control.ref_py;
237
238 if(num_neighbors != 0){
239 ctc_control.v_centroid_x /= (num_neighbors + 1);
240 ctc_control.v_centroid_y /= (num_neighbors + 1);
241 ctc_control.p_centroid_x /= (num_neighbors + 1);
242 ctc_control.p_centroid_y /= (num_neighbors + 1);
243
244 float error_target_x = ctc_control.target_px - ctc_control.p_centroid_x;
245 float error_target_y = ctc_control.target_py - ctc_control.p_centroid_y;
246 float error_target_ref_x = ctc_control.target_px - ctc_control.ref_px;
247 float error_target_ref_y = ctc_control.target_py - ctc_control.ref_py;
248
249 float distance_target_ref = sqrtf(error_target_ref_x*error_target_ref_x + error_target_ref_y*error_target_ref_y);
250 if(distance_target_ref < 0.1)
251 distance_target_ref = 0.1;
252 float aux = (1-expf(-ctc_control.alpha*distance_target_ref)) / distance_target_ref;
253 float v_ref_x = ctc_control.target_vx + aux*(error_target_x);
254 float v_ref_y = ctc_control.target_vy + aux*(error_target_y);
255
256 ctc_control.ref_px += v_ref_x*dt;
257 ctc_control.ref_py += v_ref_y*dt;
258
259 float error_v_x = ctc_control.v_centroid_x - v_ref_x;
260 float error_v_y = ctc_control.v_centroid_y - v_ref_y;
261 u_vel = -ctc_control.k1*(-error_v_x*vy + error_v_y*vx);
262
263
264 float error_ref_x = px - ctc_control.ref_px;
265 float error_ref_y = py - ctc_control.ref_py;
266 u_spa = ctc_control.omega*(1 + ctc_control.k2*(error_ref_x*vx + error_ref_y*vy));
267 }
268
269 float u = u_vel + u_spa;
270
273 -atanf(u * (sqrtf(vx * vx + vy * vy)) / 9.8 / cosf(att->theta));
275
277 }
278
279 if (((now - last_transmision) > ctc_control.time_broad) && (autopilot_get_mode() == AP_MODE_AUTO2)) {
281 last_transmision = now;
282 }
283}
284
285void ctc_send_info_to_nei(void)
286{
287 struct pprzlink_msg msg;
288
289 for (int i = 0; i < CTC_MAX_AC; i++)
290 if (tableNei[i][0] != -1) {
291 msg.trans = &(DefaultChannel).trans_tx;
292 msg.dev = &(DefaultDevice).device;
293 msg.sender_id = AC_ID;
294 msg.receiver_id = tableNei[i][0];
295 msg.component_id = 0;
296 pprzlink_msg_send_CTC_INFO_TO_NEI(&msg, &ctc_control.vx, &ctc_control.vy, &ctc_control.px, &ctc_control.py);
297 }
298}
299
301{
302 uint8_t ac_id = DL_CTC_REG_TABLE_ac_id(buf);
303 if (ac_id == AC_ID) {
304 uint8_t nei_id = DL_CTC_REG_TABLE_nei_id(buf);
305 for (int i = 0; i < CTC_MAX_AC; i++)
306 if (tableNei[i][0] == -1) {
307 tableNei[i][0] = (int16_t)nei_id;
308 return;
309 }
310 }
311}
312
314{
315 uint8_t ac_id = DL_CTC_REG_TABLE_ac_id(uint8_t *buf);
316 if (ac_id == AC_ID)
317 for (int i = 0; i < CTC_MAX_AC; i++) {
318 tableNei[i][0] = -1;
319 }
320
321 // Reset the control variables as well
322 ctc_control.p_centroid_x = 0;
323 ctc_control.p_centroid_y = 0;
324 ctc_control.v_centroid_x = 0;
325 ctc_control.v_centroid_y = 0;
326 ctc_control.target_px = 0;
327 ctc_control.target_py = 0;
328 ctc_control.target_vx = 0;
329 ctc_control.target_vy = 0;
330 ctc_control.vx = 0;
331 ctc_control.vy = 0;
332 ctc_control.px = 0;
333 ctc_control.py = 0;
334 ctc_control.ref_px = 0;
335 ctc_control.ref_py = 0;
336
337 // We force again 2 seconds of waiting before the algorithm starts, so all the aircraft have transmitted the necessary information to their neighbors
338 ctc_gogo = false;
339}
340
342{
343 int16_t sender_id = (int16_t)(SenderIdOfPprzMsg(buf));
344 for (int i = 0; i < CTC_MAX_AC; i++)
345 if (tableNei[i][0] == sender_id) {
347 tableNei[i][1] = (int16_t)(DL_CTC_INFO_TO_NEI_vx(buf) * 100);
348 tableNei[i][2] = (int16_t)(DL_CTC_INFO_TO_NEI_vy(buf) * 100);
349 tableNei[i][3] = (int16_t)(DL_CTC_INFO_TO_NEI_px(buf) * 100);
350 tableNei[i][4] = (int16_t)(DL_CTC_INFO_TO_NEI_py(buf) * 100);
351 break;
352 }
353}
354
356{
357 moving_target_px = DL_CTC_INFO_FROM_TARGET_px(buf);
358 moving_target_py = DL_CTC_INFO_FROM_TARGET_py(buf);
359 moving_target_vx = DL_CTC_INFO_FROM_TARGET_vx(buf);
360 moving_target_vy = DL_CTC_INFO_FROM_TARGET_vy(buf);
361}
uint8_t autopilot_get_mode(void)
get autopilot mode
Definition autopilot.c:229
Core autopilot interface common to all firmwares.
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition common_nav.c:44
bool collective_tracking_vehicle()
Definition ctc.c:108
float moving_target_vy
Definition ctc.c:90
static void send_ctc_control(struct transport_tx *trans, struct link_device *dev)
Definition ctc.c:44
uint32_t last_transmision
Definition ctc.c:82
#define CTC_TIME_BROAD
Definition ctc.c:73
uint32_t time_init_table
Definition ctc.c:85
bool ctc_first_time
Definition ctc.c:93
void ctc_init(void)
Definition ctc.c:96
bool ctc_gogo
Definition ctc.c:92
void collective_tracking_control()
Definition ctc.c:144
bool collective_tracking_waypoint(uint8_t wp)
Definition ctc.c:120
#define CTC_GAIN_ALPHA
Definition ctc.c:61
float moving_target_py
Definition ctc.c:88
float moving_target_vx
Definition ctc.c:89
static void send_ctc(struct transport_tx *trans, struct link_device *dev)
Definition ctc.c:39
ctc_con ctc_control
Definition ctc.c:76
#define CTC_OMEGA
Definition ctc.c:69
uint32_t starting_time
Definition ctc.c:94
float moving_target_px
Definition ctc.c:87
#define CTC_GAIN_K1
Definition ctc.c:55
#define CTC_TIMEOUT
Definition ctc.c:65
uint32_t before
Definition ctc.c:83
#define CTC_GAIN_K2
Definition ctc.c:58
#define CTC_MAX_AC
Definition ctc.c:35
uint32_t last_info[CTC_MAX_AC]
Definition ctc.c:81
int16_t tableNei[CTC_MAX_AC][6]
Definition ctc.c:80
bool collective_tracking_point(float x, float y)
Definition ctc.c:132
Collective Tracking Control.
void parse_ctc_NeiInfoTable(uint8_t *buf)
void parse_ctc_TargetInfo(uint8_t *buf)
void ctc_send_info_to_nei(void)
void parse_ctc_RegTable(uint8_t *buf)
void parse_ctc_CleanTable(uint8_t *buf)
Definition ctc.h:33
static struct uart_periph * dev
uint8_t lateral_mode
#define LATERAL_MODE_ROLL
#define AP_MODE_AUTO2
Fixed wing horizontal control.
float theta
in radians
euler angles
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
Definition state.h:1325
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:859
static struct EnuCoor_f * stateGetSpeedEnu_f(void)
Get ground speed in local ENU coordinates (float).
Definition state.h:1069
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer).
static float p[2][2]
static float timeout
float y
in meters
float x
in meters
vector in East North Up coordinates Units: meters
float h_ctl_roll_max_setpoint
float h_ctl_roll_setpoint
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_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
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.