Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
jevois.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017 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 */
27
28#include "std.h"
29#include "mcu_periph/uart.h"
30#include "modules/core/abi.h"
33#include <string.h>
34#include <stdio.h>
35
38
39// max string length
40#define JEVOIS_MAX_LEN 32
41// max number of coordinates
42#define JEVOIS_MAX_COORD 18
43// check delimiter
44#define JEVOIS_CHECK_DELIM(_c) (_c == ' ' || _c == '\n' || _c == '\r' || _c == '\0')
45
46// generic JEVOIS message structure
56
57// decoder state
68
69// jevois struct
70struct jevois_t {
71 enum jevois_state state; // decoder state
72 char buf[JEVOIS_MAX_LEN]; // temp buffer
73 uint8_t idx; // temp buffer index
74 uint8_t n; // temp coordinates/dimension index
75 struct jevois_msg_t msg; // last decoded message
76 bool data_available; // new data to report
77};
78
80
81// reporting function, send telemetry message
82void jevois_report(void)
83{
84 if (jevois.data_available == false) {
85 // no new data, return
86 return;
87 }
88
89 float quat[4] = {
94 };
95 uint8_t len = strlen(jevois.msg.id);
96 char none[] = "None";
97 char *id = jevois.msg.id;
98 if (len == 0) {
99 id = none;
100 len = 4;
101 }
103 &jevois.msg.type,
104 len, id,
105 &jevois.msg.nb,
107 jevois.msg.dim,
108 quat);
109 jevois.data_available = false;
110}
111
112// initialization
113void jevois_init(void)
114{
115 // dummy settings
117 jevois_stream_setting = false;
118
120 jevois.idx = 0;
121 jevois.n = 0;
122 jevois.data_available = false;
124}
125
126// extrat a number (int) from an idea string
127// this might be needed as jevois ID can start with a letter
128// this will extract the first substring with a number
129// and return the result of atoi function
131 unsigned int i, j = 0;
132 bool first = false;
133 char out[JEVOIS_MAX_LEN];
134 for (i = 0; i < strlen(in)+1; i++) {
135 if ((in[i] >= '0' && in[i] < '9') || in[i] == '-') {
136 out[j++] = in[i];
137 first = true;
138 } else if (first || in[i] == '\0') {
139 out[j] = '\0';
140 break;
141 }
142 }
143 return atoi(out);
144}
145
146// send specific message if requested
147static void jevois_send_message(void)
148{
149#if JEVOIS_SEND_MSG
150 // send pprzlink JEVOIS message
152#endif
153#if JEVOIS_SEND_FOLLOW_TARGET
154 float cam_heading = (JEVOIS_HFOV / (2.f * JEVOIS_NORM)) * (float)(jevois.msg.coord[0]);
155 float cam_height = (JEVOIS_VFOV / (2.f * JEVOIS_NORM)) * (float)(jevois.msg.coord[1]);
156 // send a FOLLOW_TARGET message in camera frame
158#endif
159#if JEVOIS_SEND_VISUAL_DETECTION
161 jevois.msg.coord[0],
162 jevois.msg.coord[1],
163 jevois.msg.dim[0],
164 jevois.msg.dim[1],
165 0,
167#endif
168}
169
170static void jevois_handle_msg(struct jevois_t *jv) {
171 // send ABI message
173 jv->msg.type,
174 jv->msg.id,
175 jv->msg.nb,
176 jv->msg.coord,
177 jv->msg.dim,
178 jv->msg.quat,
179 jv->msg.extra);
180 // also send specific messages if needed
182 jv->data_available = true;
183 jv->idx = 0;
184 jv->n = 0;
185}
186
187// raw message parsing function
188static void jevois_parse(struct jevois_t *jv, char c)
189{
190 switch (jv->state) {
191 case JV_SYNC:
192 // wait for sync (newline character)
193 if (c == '\n') {
194 jv->state = JV_TYPE;
195 jv->idx = 0;
196 jv->n = 0;
197 }
198 break;
199 case JV_TYPE:
200 jv->buf[jv->idx++] = c; // fill buffer
201 // parse type
202 if (jv->idx > 2) { // msg type + white space
203 if (jv->buf[0] == 'T' && jv->buf[1] == '1') {
204 jv->state = JV_COORD;
205 jv->msg.type = JEVOIS_MSG_T1;
206 jv->msg.nb = 1;
207 } else if (jv->buf[0] == 'N' && jv->buf[1] == '1') {
208 jv->state = JV_ID;
209 jv->msg.type = JEVOIS_MSG_N1;
210 jv->msg.nb = 1;
211 } else if (jv->buf[0] == 'D' && jv->buf[1] == '1') {
212 jv->state = JV_ID;
213 jv->msg.type = JEVOIS_MSG_D1;
214 jv->msg.nb = 2;
215 } else if (jv->buf[0] == 'T' && jv->buf[1] == '2') {
216 jv->state = JV_COORD;
217 jv->msg.type = JEVOIS_MSG_T2;
218 jv->msg.nb = 2;
219 } else if (jv->buf[0] == 'N' && jv->buf[1] == '2') {
220 jv->state = JV_ID;
221 jv->msg.type = JEVOIS_MSG_N2;
222 jv->msg.nb = 2;
223 } else if (jv->buf[0] == 'D' && jv->buf[1] == '2') {
224 jv->state = JV_ID;
225 jv->msg.type = JEVOIS_MSG_D2;
226 jv->msg.nb = 8;
227 } else if (jv->buf[0] == 'F' && jv->buf[1] == '2') {
228 jv->state = JV_ID;
229 jv->msg.type = JEVOIS_MSG_F2;
230 jv->msg.nb = 0;
231 } else if (jv->buf[0] == 'T' && jv->buf[1] == '3') {
232 jv->state = JV_COORD;
233 jv->msg.type = JEVOIS_MSG_T3;
234 jv->msg.nb = 3;
235 } else if (jv->buf[0] == 'N' && jv->buf[1] == '3') {
236 jv->state = JV_ID;
237 jv->msg.type = JEVOIS_MSG_N3;
238 jv->msg.nb = 3;
239 } else if (jv->buf[0] == 'D' && jv->buf[1] == '3') {
240 jv->state = JV_ID;
241 jv->msg.type = JEVOIS_MSG_D3;
242 jv->msg.nb = 3;
243 } else if (jv->buf[0] == 'F' && jv->buf[1] == '3') {
244 jv->state = JV_ID;
245 jv->msg.type = JEVOIS_MSG_F3;
246 jv->msg.nb = 0;
247 } else {
248 jv->state = JV_SYNC; // error
249 }
250 jv->idx = 0;
251 }
252 break;
253 case JV_ID:
254 if (JEVOIS_CHECK_DELIM(c)) {
255 jv->msg.id[jv->idx] = '\0'; // end string
256 if (jv->msg.type == JEVOIS_MSG_F2 ||
257 jv->msg.type == JEVOIS_MSG_F3) {
258 jv->state = JV_SIZE; // parse n before coordinates
259 } else {
260 jv->state = JV_COORD; // parse directly coordinates
261 }
262 jv->idx = 0;
263 break;
264 }
265 else {
266 jv->msg.id[jv->idx++] = c;
267 if (jv->idx > JEVOIS_MAX_LEN - 1) {
268 jv->state = JV_SYNC; // too long, return to sync
269 }
270 }
271 break;
272 case JV_SIZE:
273 if (JEVOIS_CHECK_DELIM(c)) {
274 jv->buf[jv->idx] = '\0'; // end string
275 jv->msg.nb = (uint8_t)atoi(jv->buf); // store size
276 jv->state = JV_COORD;
277 jv->idx = 0;
278 }
279 else {
280 jv->buf[jv->idx++] = c; // fill buffer
281 }
282 break;
283 case JV_COORD:
284 if (JEVOIS_CHECK_DELIM(c)) {
285 jv->buf[jv->idx] = '\0'; // end string
286 jv->msg.coord[jv->n++] = (int16_t)atoi(jv->buf); // store value
287 if (jv->n == jv->msg.nb) {
288 // got all coordinates, go to next state
289 jv->n = 0; // reset number of received elements
290 jv->idx = 0; // reset index
291 switch (jv->msg.type) {
292 case JEVOIS_MSG_T1:
293 case JEVOIS_MSG_T2:
294 case JEVOIS_MSG_T3:
296 jv->state = JV_TYPE;
297 break;
298 case JEVOIS_MSG_N1:
299 case JEVOIS_MSG_N2:
300 case JEVOIS_MSG_N3:
301 case JEVOIS_MSG_D3:
302 jv->state = JV_DIM;
303 break;
304 case JEVOIS_MSG_D1:
305 case JEVOIS_MSG_D2:
306 case JEVOIS_MSG_F2:
307 case JEVOIS_MSG_F3:
308 jv->state = JV_EXTRA;
309 break;
310 default:
311 jv->state = JV_SYNC; // error
312 break;
313 }
314 }
315 jv->idx = 0; // reset index
316 }
317 else {
318 jv->buf[jv->idx++] = c; // fill buffer
319 }
320 break;
321 case JV_DIM:
322 if (JEVOIS_CHECK_DELIM(c)) {
323 jv->buf[jv->idx] = '\0'; // end string
324 jv->msg.dim[jv->n++] = (uint16_t)atoi(jv->buf); // store dimension
325 if (jv->n == jv->msg.nb) {
326 // got all dimensions, go to next state
327 jv->n = 0; // reset number of received elements
328 jv->idx = 0; // reset index
329 if (jv->msg.type == JEVOIS_MSG_D3) {
330 jv->state = JV_QUAT;
331 } else {
333 jv->state = JV_TYPE;
334 }
335 break;
336 }
337 jv->idx = 0; // reset index
338 }
339 else {
340 jv->buf[jv->idx++] = c; // fill buffer
341 }
342 break;
343 case JV_QUAT:
344 if (JEVOIS_CHECK_DELIM(c)) {
345 jv->buf[jv->idx] = '\0';
346 float q = (float)atof(jv->buf);
347 switch (jv->n) {
348 case 0:
349 jv->msg.quat.qi = q;
350 break;
351 case 1:
352 jv->msg.quat.qx = q;
353 break;
354 case 2:
355 jv->msg.quat.qy = q;
356 break;
357 case 3:
358 jv->msg.quat.qz = q;
359 jv->state = JV_EXTRA;
360 break;
361 default:
362 jv->state = JV_SYNC; // error
363 break;
364 }
365 jv->n++;
366 jv->idx = 0; // reset index
367 }
368 else {
369 jv->buf[jv->idx++] = c; // fill buffer
370 }
371 break;
372 case JV_EXTRA:
373 if (JEVOIS_CHECK_DELIM(c)) {
374 jv->msg.extra[jv->idx] = '\0'; // end string
375
376 if (c == '\n') {
378 jv->state = JV_TYPE;
379 } else if( c=='\r') {
380 // do nothing, just to consume '\r'
381 }
382 else {
383 jv->state = JV_SYNC;
384 }
385 }
386 else {
387 jv->msg.extra[jv->idx++] = c; // store extra string
388 if (jv->idx > JEVOIS_MAX_LEN - 1) {
389 jv->state = JV_SYNC; // too long, return to sync
390 }
391 }
392 break;
393 default:
394 // error, back to SYNC
395 jv->state = JV_SYNC;
396 break;
397 }
398}
399
400
401// UART polling function
402void jevois_event(void)
403{
404 // Look for data on serial link and send to parser
405 while (uart_char_available(&(JEVOIS_DEV))) {
408 }
409}
410
411// utility function to send a string
413{
414 uint8_t i = 0;
415 while (s[i]) {
416 uart_put_byte(&(JEVOIS_DEV), 0, (uint8_t)(s[i]));
417 i++;
418 }
419}
420
422{
424 if (activate) {
425 jevois_send_string("streamon\r\n");
426 } else {
427 jevois_send_string("streamoff\r\n");
428 }
429}
430
432{
434 jevois_stream(false);
435 jevois_send_string("setmapping ");
436 char s[4];
437#ifndef SITL
438 itoa(number, s, 10);
439#endif
441 jevois_send_string("\r\n");
442 jevois_stream(true);
443}
444
446{
447 char str[32] __attribute__((unused));
448#if JEVOIS_SEND_ALT
449 // send current altitude in millimeter
450 int alt_mm = (int)(stateGetPositionEnu_f()->z * 1000.f);
451 Bound(alt_mm, -999999, 999999);
452 sprintf(str, "alt %d\r\n", alt_mm);
454#endif
455#if JEVOIS_SEND_POS
456 // send current position in millimeter
457 struct EnuCoor_f pos = *stateGetPositionEnu_f();
458 int x_mm = (int)(pos.x * 1000.f);
459 int y_mm = (int)(pos.y * 1000.f);
460 int z_mm = (int)(pos.z * 1000.f);
461 Bound(x_mm, -999999, 999999);
462 Bound(y_mm, -999999, 999999);
463 Bound(z_mm, -999999, 999999);
464 sprintf(str, "pos %d %d %d\r\n", x_mm, y_mm, z_mm);
466#endif
467#if JEVOIS_SEND_QUAT
468 // send quaternion
469 struct FloatQuat quat = *stateGetNedToBodyQuat_f();
470 int qi = (int)(quat.qi * 1000.f);
471 int qx = (int)(quat.qx * 1000.f);
472 int qy = (int)(quat.qy * 1000.f);
473 int qz = (int)(quat.qz * 1000.f);
474 Bound(qi, -9999, 9999);
475 Bound(qx, -9999, 9999);
476 Bound(qy, -9999, 9999);
477 Bound(qz, -9999, 9999);
478 sprintf(str, "quat %d %d %d %d\r\n", qi, qx, qy, qz);
480#endif
481}
Main include for ABI (AirBorneInterface).
#define CAM_JEVOIS_ID
volatile int32_t alt_mm
Definition exif_module.c:33
Roation quaternion.
static struct FloatQuat * stateGetNedToBodyQuat_f(void)
Get vehicle body attitude quaternion (float).
Definition state.h:1294
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:848
bool jevois_stream_setting
Definition jevois.c:37
static void jevois_parse(struct jevois_t *jv, char c)
Definition jevois.c:188
void jevois_setmapping(int number)
Set video mapping.
Definition jevois.c:431
char id[JEVOIS_MAX_LEN]
Definition jevois.c:49
static void jevois_handle_msg(struct jevois_t *jv)
Definition jevois.c:170
uint8_t idx
Definition jevois.c:73
uint8_t type
Definition jevois.c:48
char buf[JEVOIS_MAX_LEN]
Definition jevois.c:72
char extra[JEVOIS_MAX_LEN]
Definition jevois.c:54
void jevois_stream(bool activate)
Start and stop streaming.
Definition jevois.c:421
static void jevois_send_message(void)
Definition jevois.c:147
uint8_t nb
Definition jevois.c:50
struct jevois_t jevois
Definition jevois.c:79
void jevois_report(void)
Definition jevois.c:82
int jevois_mapping_setting
Definition jevois.c:36
void jevois_event(void)
Definition jevois.c:402
int16_t coord[JEVOIS_MAX_COORD]
Definition jevois.c:51
int jevois_extract_nb(char *in)
Extract a number from jevoid ID field.
Definition jevois.c:130
uint16_t dim[3]
Definition jevois.c:52
#define JEVOIS_CHECK_DELIM(_c)
Definition jevois.c:44
void jevois_send_string(char *s)
Generic function to send a string command to Jevois.
Definition jevois.c:412
struct jevois_msg_t msg
Definition jevois.c:75
void jevois_send_state(void)
Send state to camera.
Definition jevois.c:445
struct FloatQuat quat
Definition jevois.c:53
uint8_t n
Definition jevois.c:74
#define JEVOIS_MAX_COORD
Definition jevois.c:42
#define JEVOIS_MAX_LEN
Definition jevois.c:40
bool data_available
Definition jevois.c:76
void jevois_init(void)
Definition jevois.c:113
jevois_state
Definition jevois.c:58
@ JV_QUAT
Definition jevois.c:65
@ JV_DIM
Definition jevois.c:64
@ JV_SIZE
Definition jevois.c:62
@ JV_EXTRA
Definition jevois.c:66
@ JV_TYPE
Definition jevois.c:60
@ JV_COORD
Definition jevois.c:63
@ JV_ID
Definition jevois.c:61
@ JV_SYNC
Definition jevois.c:59
enum jevois_state state
Definition jevois.c:71
#define JEVOIS_MSG_D2
Definition jevois.h:37
#define JEVOIS_MSG_T3
Definition jevois.h:39
#define JEVOIS_MSG_F3
Definition jevois.h:42
#define JEVOIS_HFOV
Camera horizontal FOV From datasheet it should be 65deg, but it seems that better results are acheive...
Definition jevois.h:52
#define JEVOIS_VFOV
Camera vertical FOV Camera has a 4/3 ratio.
Definition jevois.h:59
#define JEVOIS_MSG_F2
Definition jevois.h:38
#define JEVOIS_MSG_N1
Definition jevois.h:33
#define JEVOIS_MSG_D1
Definition jevois.h:34
#define JEVOIS_NORM
Normalized data from JEVOIS are between -1000 and 1000.
Definition jevois.h:45
#define JEVOIS_MSG_N3
Definition jevois.h:40
#define JEVOIS_MSG_N2
Definition jevois.h:36
#define JEVOIS_MSG_D3
Definition jevois.h:41
#define JEVOIS_MSG_T1
JEVOIS messages types.
Definition jevois.h:32
#define JEVOIS_MSG_T2
Definition jevois.h:35
static uint32_t s
void uart_put_byte(struct uart_periph *periph, long fd, uint8_t data)
Definition uart_arch.c:306
int uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition uart_arch.c:357
uint8_t uart_getch(struct uart_periph *p)
Definition uart_arch.c:348
uint16_t foo
Definition main_demo5.c:58
Paparazzi floating point algebra.
float y
in meters
float x
in meters
float z
in meters
vector in East North Up coordinates Units: meters
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.