Paparazzi UAS  v5.14.0_stable-0-g3f680d1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 "subsystems/abi.h"
32 #include <stdio.h>
33 
36 
37 // max string length
38 #define JEVOIS_MAX_LEN 32
39 // max number of coordinates
40 #define JEVOIS_MAX_COORD 18
41 // check delimiter
42 #define JEVOIS_CHECK_DELIM(_c) (_c == ' ' || _c == '\n' || _c == '\r' || _c == '\0')
43 
44 // generic JEVOIS message structure
45 struct jevois_msg_t {
47  char id[JEVOIS_MAX_LEN];
51  struct FloatQuat quat;
53 };
54 
55 // decoder state
57  JV_SYNC = 0,
66 };
67 
68 // jevois struct
69 struct jevois_t {
70  enum jevois_state state; // decoder state
71  char buf[JEVOIS_MAX_LEN]; // temp buffer
72  uint8_t idx; // temp buffer index
73  uint8_t n; // temp coordinates/dimension index
74  struct jevois_msg_t msg; // last decoded message
75 };
76 
78 
79 // initialization
80 void jevois_init(void)
81 {
82  // dummy settings
84  jevois_stream_setting = false;
85 
87  jevois.idx = 0;
88  jevois.n = 0;
89  memset(jevois.buf, 0, JEVOIS_MAX_LEN);
90 }
91 
92 // send specific message if requested
93 static void jevois_send_message(void)
94 {
95 #if JEVOIS_SEND_FOLLOW_TARGET
96  float cam_heading = (JEVOIS_HFOV / (2.f * JEVOIS_NORM)) * (float)(jevois.msg.coord[0]);
97  float cam_height = (JEVOIS_VFOV / (2.f * JEVOIS_NORM)) * (float)(jevois.msg.coord[1]);
98  // send a FOLLOW_TARGET message in camera frame
99  AbiSendMsgFOLLOW_TARGET(CAM_JEVOIS_ID, 0, 0, cam_heading, cam_height, 0.f);
100 #endif
101 }
102 
103 // raw message parsing function
104 static void jevois_parse(struct jevois_t *jv, char c)
105 {
106  switch (jv->state) {
107  case JV_SYNC:
108  // wait for sync (newline character)
109  if (c == '\n') {
110  jv->state = JV_TYPE;
111  jv->idx = 0;
112  jv->n = 0;
113  }
114  break;
115  case JV_TYPE:
116  jv->buf[jv->idx++] = c; // fill buffer
117  // parse type
118  if (jv->idx > 2) { // msg type + white space
119  if (jv->buf[0] == 'T' && jv->buf[1] == '1') {
120  jv->state = JV_COORD;
121  jv->msg.type = JEVOIS_MSG_T1;
122  jv->msg.nb = 1;
123  } else if (jv->buf[0] == 'N' && jv->buf[1] == '1') {
124  jv->state = JV_ID;
125  jv->msg.type = JEVOIS_MSG_N1;
126  jv->msg.nb = 1;
127  } else if (jv->buf[0] == 'D' && jv->buf[1] == '1') {
128  jv->state = JV_ID;
129  jv->msg.type = JEVOIS_MSG_D1;
130  jv->msg.nb = 2;
131  } else if (jv->buf[0] == 'T' && jv->buf[1] == '2') {
132  jv->state = JV_COORD;
133  jv->msg.type = JEVOIS_MSG_T2;
134  jv->msg.nb = 2;
135  } else if (jv->buf[0] == 'N' && jv->buf[1] == '2') {
136  jv->state = JV_ID;
137  jv->msg.type = JEVOIS_MSG_N2;
138  jv->msg.nb = 2;
139  } else if (jv->buf[0] == 'D' && jv->buf[1] == '2') {
140  jv->state = JV_ID;
141  jv->msg.type = JEVOIS_MSG_D2;
142  jv->msg.nb = 8;
143  } else if (jv->buf[0] == 'F' && jv->buf[1] == '2') {
144  jv->state = JV_ID;
145  jv->msg.type = JEVOIS_MSG_F2;
146  jv->msg.nb = 0;
147  } else if (jv->buf[0] == 'T' && jv->buf[1] == '3') {
148  jv->state = JV_COORD;
149  jv->msg.type = JEVOIS_MSG_T3;
150  jv->msg.nb = 3;
151  } else if (jv->buf[0] == 'N' && jv->buf[1] == '3') {
152  jv->state = JV_ID;
153  jv->msg.type = JEVOIS_MSG_N3;
154  jv->msg.nb = 3;
155  } else if (jv->buf[0] == 'D' && jv->buf[1] == '3') {
156  jv->state = JV_ID;
157  jv->msg.type = JEVOIS_MSG_D3;
158  jv->msg.nb = 3;
159  } else if (jv->buf[0] == 'F' && jv->buf[1] == '3') {
160  jv->state = JV_ID;
161  jv->msg.type = JEVOIS_MSG_F3;
162  jv->msg.nb = 0;
163  } else {
164  jv->state = JV_SYNC; // error
165  }
166  jv->idx = 0;
167  }
168  break;
169  case JV_ID:
170  if (JEVOIS_CHECK_DELIM(c)) {
171  jv->msg.id[jv->idx] = '\0'; // end string
172  if (jv->msg.type == JEVOIS_MSG_F2 ||
173  jv->msg.type == JEVOIS_MSG_F3) {
174  jv->state = JV_SIZE; // parse n before coordinates
175  } else {
176  jv->state = JV_COORD; // parse directly coordinates
177  }
178  jv->idx = 0;
179  break;
180  }
181  else {
182  jv->msg.id[jv->idx++] = c;
183  if (jv->idx > JEVOIS_MAX_LEN - 1) {
184  jv->state = JV_SYNC; // too long, return to sync
185  }
186  }
187  break;
188  case JV_SIZE:
189  if (JEVOIS_CHECK_DELIM(c)) {
190  jv->buf[jv->idx] = '\0'; // end string
191  jv->msg.nb = (uint8_t)atoi(jv->buf); // store size
192  jv->state = JV_COORD;
193  jv->idx = 0;
194  }
195  else {
196  jv->buf[jv->idx++] = c; // fill buffer
197  }
198  break;
199  case JV_COORD:
200  if (JEVOIS_CHECK_DELIM(c)) {
201  jv->buf[jv->idx] = '\0'; // end string
202  jv->msg.coord[jv->n++] = (int16_t)atoi(jv->buf); // store value
203  if (jv->n == 2 * jv->msg.nb) {
204  // got all coordinates, go to next state
205  jv->n = 0; // reset number of received elements
206  jv->idx = 0; // reset index
207  switch (jv->msg.type) {
208  case JEVOIS_MSG_T1:
209  case JEVOIS_MSG_T2:
210  case JEVOIS_MSG_T3:
211  jv->state = JV_SEND_MSG;
212  break;
213  case JEVOIS_MSG_N1:
214  case JEVOIS_MSG_N2:
215  case JEVOIS_MSG_N3:
216  case JEVOIS_MSG_D3:
217  jv->state = JV_DIM;
218  break;
219  case JEVOIS_MSG_D1:
220  case JEVOIS_MSG_D2:
221  case JEVOIS_MSG_F2:
222  case JEVOIS_MSG_F3:
223  jv->state = JV_EXTRA;
224  break;
225  default:
226  jv->state = JV_SYNC; // error
227  break;
228  }
229  }
230  jv->idx = 0; // reset index
231  }
232  else {
233  jv->buf[jv->idx++] = c; // fill buffer
234  }
235  break;
236  case JV_DIM:
237  if (JEVOIS_CHECK_DELIM(c)) {
238  jv->buf[jv->idx] = '\0'; // end string
239  jv->msg.dim[jv->n++] = (uint16_t)atoi(jv->buf); // store dimension
240  if (jv->n == jv->msg.nb) {
241  // got all dimensions, go to next state
242  jv->n = 0; // reset number of received elements
243  jv->idx = 0; // reset index
244  if (jv->msg.type == JEVOIS_MSG_D3) {
245  jv->state = JV_QUAT;
246  } else {
247  jv->state = JV_SEND_MSG;
248  }
249  break;
250  }
251  jv->idx = 0; // reset index
252  }
253  else {
254  jv->buf[jv->idx++] = c; // fill buffer
255  }
256  break;
257  case JV_QUAT:
258  if (JEVOIS_CHECK_DELIM(c)) {
259  jv->buf[jv->idx] = '\0';
260  float q = 0.f;//(float) atof(jv->buf);
261  switch (jv->n) {
262  case 0:
263  jv->msg.quat.qi = q; // TODO check quaternion order
264  break;
265  case 1:
266  jv->msg.quat.qx = q;
267  break;
268  case 2:
269  jv->msg.quat.qy = q;
270  break;
271  case 3:
272  jv->msg.quat.qz = q;
273  break;
274  case 4:
275  jv->state = JV_EXTRA;
276  break;
277  default:
278  jv->state = JV_SYNC; // error
279  break;
280  }
281  jv->n++;
282  jv->idx = 0; // reset index
283  }
284  else {
285  jv->buf[jv->idx++] = c; // fill buffer
286  }
287  break;
288  case JV_EXTRA:
289  if (JEVOIS_CHECK_DELIM(c)) {
290  jv->msg.extra[jv->idx] = '\0'; // end string
291  jv->state = JV_SEND_MSG;
292  jv->idx = 0; // reset index
293  }
294  else {
295  jv->msg.extra[jv->idx++] = c; // store extra string
296  if (jv->idx > JEVOIS_MAX_LEN - 1) {
297  jv->state = JV_SYNC; // too long, return to sync
298  }
299  }
300  break;
301  case JV_SEND_MSG:
302  // send ABI message
303  AbiSendMsgJEVOIS_MSG(CAM_JEVOIS_ID,
304  jv->msg.type,
305  jv->msg.id,
306  jv->msg.nb,
307  jv->msg.coord,
308  jv->msg.dim,
309  jv->msg.quat,
310  jv->msg.extra);
311  // also send specific messages if needed
313  jv->state = JV_SYNC;
314  break;
315  default:
316  // error, back to SYNC
317  jv->state = JV_SYNC;
318  break;
319  }
320 }
321 
322 
323 // UART polling function
324 void jevois_event(void)
325 {
326  // Look for data on serial link and send to parser
327  while (uart_char_available(&(JEVOIS_DEV))) {
328  uint8_t ch = uart_getch(&(JEVOIS_DEV));
329  jevois_parse(&jevois, ch);
330  }
331 }
332 
333 // utility function to send a string
334 static void send_string(char *s)
335 {
336  uint8_t i = 0;
337  while (s[i]) {
338  uart_put_byte(&(JEVOIS_DEV), 0, (uint8_t)(s[i]));
339  i++;
340  }
341 }
342 
343 void jevois_stream(bool activate)
344 {
345  jevois_stream_setting = activate;
346  if (activate) {
347  send_string("streamon\r\n");
348  } else {
349  send_string("streamoff\r\n");
350  }
351 }
352 
353 void jevois_setmapping(int number)
354 {
355  jevois_mapping_setting = number;
356  jevois_stream(false);
357  send_string("setmapping ");
358  char s[4];
359 #ifndef SITL
360  itoa(number, s, 10);
361 #endif
362  send_string(s);
363  send_string("\r\n");
364  jevois_stream(true);
365 }
366 
int jevois_mapping_setting
Definition: jevois.c:34
unsigned short uint16_t
Definition: types.h:16
Definition: jevois.c:59
#define CAM_JEVOIS_ID
Definition: jevois.c:58
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
char buf[JEVOIS_MAX_LEN]
Definition: jevois.c:71
void jevois_setmapping(int number)
Set video mapping.
Definition: jevois.c:353
Definition: jevois.c:62
#define JEVOIS_MSG_D3
Definition: jevois.h:41
void jevois_event(void)
Definition: jevois.c:324
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:840
bool jevois_stream_setting
Definition: jevois.c:35
uint8_t type
Definition: jevois.c:46
uint16_t dim[3]
Definition: jevois.c:50
#define JEVOIS_MSG_T2
Definition: jevois.h:35
uint16_t uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:324
Main include for ABI (AirBorneInterface).
struct FloatQuat quat
Definition: jevois.c:51
#define JEVOIS_MAX_COORD
Definition: jevois.c:40
void jevois_init(void)
Definition: jevois.c:80
uint8_t idx
Definition: jevois.c:72
static void jevois_send_message(void)
Definition: jevois.c:93
static void send_string(char *s)
Definition: jevois.c:334
Roation quaternion.
#define JEVOIS_MSG_D1
Definition: jevois.h:34
#define JEVOIS_MSG_F2
Definition: jevois.h:38
int16_t coord[JEVOIS_MAX_COORD]
Definition: jevois.c:49
Paparazzi floating point algebra.
Definition: jevois.c:63
static void jevois_parse(struct jevois_t *jv, char c)
Definition: jevois.c:104
signed short int16_t
Definition: types.h:17
#define JEVOIS_MSG_T1
JEVOIS messages types.
Definition: jevois.h:32
#define JEVOIS_MSG_N1
Definition: jevois.h:33
void jevois_stream(bool activate)
Start and stop streaming.
Definition: jevois.c:343
#define JEVOIS_MSG_N2
Definition: jevois.h:36
#define JEVOIS_CHECK_DELIM(_c)
Definition: jevois.c:42
char id[JEVOIS_MAX_LEN]
Definition: jevois.c:47
jevois_state
Definition: jevois.c:56
char extra[JEVOIS_MAX_LEN]
Definition: jevois.c:52
void uart_put_byte(struct uart_periph *p, long fd, uint8_t data)
Uart transmit implementation.
Definition: uart_arch.c:967
#define JEVOIS_MSG_T3
Definition: jevois.h:39
uint8_t n
Definition: jevois.c:73
unsigned char uint8_t
Definition: types.h:14
uint8_t nb
Definition: jevois.c:48
#define JEVOIS_NORM
Normalized data from JEVOIS are between -1000 and 1000.
Definition: jevois.h:45
struct jevois_t jevois
Definition: jevois.c:77
#define JEVOIS_MSG_F3
Definition: jevois.h:42
Definition: jevois.c:60
#define JEVOIS_MSG_N3
Definition: jevois.h:40
#define JEVOIS_MAX_LEN
Definition: jevois.c:38
#define JEVOIS_VFOV
Camera vertical FOV Camera has a 4/3 ratio.
Definition: jevois.h:59
enum jevois_state state
Definition: jevois.c:70
struct jevois_msg_t msg
Definition: jevois.c:74
Definition: jevois.c:57
#define JEVOIS_MSG_D2
Definition: jevois.h:37
#define JEVOIS_HFOV
Camera horizontal FOV From datasheet it should be 65deg, but it seems that better results are acheive...
Definition: jevois.h:52