Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
vn200_serial.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Michal Podhradsky, michal.podhradsky@aggiemail.usu.edu
3  * Utah State University, http://aggieair.usu.edu/
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
30 #include "mcu_periph/uart.h"
31 #include "mcu_periph/usb_serial.h"
32 
33 
34 void vn200_check_status(struct VNData *vn_data);
35 void vn200_yaw_pitch_roll_to_attitude(struct FloatEulers *vn_attitude);
36 
37 
41 void vn200_check_status(struct VNData *vn_data)
42 {
43  vn_data->mode = (uint8_t)(vn_data->ins_status & 0x03);
44  vn_data->err = (uint8_t)((vn_data->ins_status >> 3) & 0x0F);
45 }
46 
47 
55 {
56  static struct FloatEulers att_rad;
57  att_rad.phi = RadOfDeg(vn_attitude->psi);
58  att_rad.theta = RadOfDeg(vn_attitude->theta);
59  att_rad.psi = RadOfDeg(vn_attitude->phi);
60 
61  vn_attitude->phi = att_rad.phi;
62  vn_attitude->theta = att_rad.theta;
63  vn_attitude->psi = att_rad.psi;
64 }
65 
66 
72 static inline unsigned short calculateCRC(unsigned char data[], unsigned int length)
73 {
74  unsigned int i;
75  unsigned short crc = 0;
76  for (i = 0; i < length; i++) {
77  crc = (unsigned char)(crc >> 8) | (crc << 8);
78  crc ^= data[i];
79  crc ^= (unsigned char)(crc & 0xff) >> 4;
80  crc ^= crc << 12;
81  crc ^= (crc & 0x00ff) << 5;
82  }
83  return crc;
84 }
85 
86 
90 static inline bool verify_chk(unsigned char data[], unsigned int length, uint16_t *calc_chk, uint16_t *rec_chk)
91 {
92  unsigned short calc_crc = calculateCRC(data, length);
93  unsigned short rec_crc = (unsigned short)(data[length] << 8 | data[length + 1]);
94  *calc_chk = (uint16_t) calc_crc;
95  *rec_chk = (uint16_t) rec_crc;
96  if (calc_crc == rec_crc) {
97  return 1;
98  } else {
99  return 0;
100  }
101 }
102 
103 
104 static inline void vn200_read_buffer(struct VNPacket *vnp)
105 {
106  struct link_device *dev = &(VN_PORT.device);
107  while (dev->char_available(dev->periph) && !(vnp->msg_available)) {
108  vn200_parse(vnp, dev->get_byte(dev->periph));
109  }
110 }
111 
112 
113 void vn200_event(struct VNPacket *vnp)
114 {
115  struct link_device *dev = &(VN_PORT.device);
116  if (dev->char_available(dev->periph)) {
117  vn200_read_buffer(vnp);
118  }
119 }
120 
121 
125 void vn200_parse(struct VNPacket *vnp, uint8_t c)
126 {
127  switch (vnp->status) {
128  case VNMsgSync:
129  // sync the header
130  vnp->msg_idx = 0;
131  if (c == VN_SYNC) {
132  vnp->status = VNMsgHeader;
133  } else {
134  vnp->hdr_error++;
135  }
136  break;
137  case VNMsgHeader:
138  // read header data (we expect 0x39)
139  if (c == VN_OUTPUT_GROUP) {
140  // increment idx and save current byte for checksum
141  vnp->status = VNMsgGroup;
142  vnp->msg_buf[vnp->msg_idx] = c;
143  vnp->msg_idx++;
144  } else {
145  vnp->hdr_error++;
146  vnp->status = VNMsgSync;
147  }
148  break;
149  break;
150  case VNMsgGroup:
151  // read header data
152  vnp->msg_buf[vnp->msg_idx] = c;
153  vnp->msg_idx++;
154  if (vnp->msg_idx == VN_GROUP_BYTES) {
156  vnp->status = VNMsgData;
157  }
158  break;
159  case VNMsgData:
160  vnp->msg_buf[vnp->msg_idx] = c;
161  vnp->msg_idx++;
162  if (vnp->msg_idx == (vnp->datalength + 2)) {
163  if (verify_chk(vnp->msg_buf, vnp->datalength, &(vnp->calc_chk), &(vnp->rec_chk))) {
164  vnp->msg_available = true;
165  vnp->counter++;
166  } else {
167  vnp->msg_available = false;
168  vnp->chksm_error++;
169  }
170  vnp->status = VNMsgSync;
171  }
172  break;
173  default:
174  vnp->status = VNMsgSync;
175  vnp->msg_idx = 0;
176  break;
177  }
178 }
179 
180 
184 void vn200_read_message(struct VNPacket *vn_packet, struct VNData *vn_data)
185 {
187 
188  // Timestamp [nanoseconds] since startup
189  memcpy(&vn_data->nanostamp, &vn_packet->msg_buf[idx], sizeof(uint64_t));
190  idx += sizeof(uint64_t);
191 
192  // Timestamp [s]
193  vn_data->timestamp = ((float)vn_data->nanostamp / 1000000000); // [nanoseconds to seconds]
194 
195  //Attitude, float, [degrees], yaw, pitch, roll, NED frame
196  memcpy(&vn_data->attitude, &vn_packet->msg_buf[idx], 3 * sizeof(float));
197  idx += 3 * sizeof(float);
198 
199  // correctly rearrange YawPitchRoll to attitude (plus scale to radians)
200  vn200_yaw_pitch_roll_to_attitude(&vn_data->attitude); // convert to correct units and axis [rad]
201 
202  // Rates (imu frame), float, [rad/s]
203  memcpy(&vn_data->gyro, &vn_packet->msg_buf[idx], 3 * sizeof(float));
204  idx += 3 * sizeof(float);
205 
206  //Pos LLA, double,[deg, deg, m]
207  //The estimated position given as latitude, longitude, and altitude given in [deg, deg, m] respectfully.
208  memcpy(&vn_data->pos_lla, &vn_packet->msg_buf[idx], 3 * sizeof(double));
209  idx += 3 * sizeof(double);
210 
211  //VelNed, float [m/s]
212  //The estimated velocity in the North East Down (NED) frame, given in m/s.
213  memcpy(&vn_data->vel_ned, &vn_packet->msg_buf[idx], 3 * sizeof(float));
214  idx += 3 * sizeof(float);
215 
216  // Accel (imu-frame), float, [m/s^-2]
217  memcpy(&vn_data->accel, &vn_packet->msg_buf[idx], 3 * sizeof(float));
218  idx += 3 * sizeof(float);
219 
220  // tow (in nanoseconds), uint64
221  memcpy(&vn_data->tow, &vn_packet->msg_buf[idx], sizeof(uint64_t));
222  idx += sizeof(uint64_t);
223  vn_data->tow = vn_data->tow / 1000000; // nanoseconds to miliseconds
224 
225  //num sats, uint8
226  vn_data->num_sv = vn_packet->msg_buf[idx];
227  idx++;
228 
229  //gps fix, uint8
230  vn_data->gps_fix = vn_packet->msg_buf[idx];
231  idx++;
232 
233  //posU, float[3]
234  memcpy(&vn_data->pos_u, &vn_packet->msg_buf[idx], 3 * sizeof(float));
235  idx += 3 * sizeof(float);
236 
237  //velU, float
238  memcpy(&vn_data->vel_u, &vn_packet->msg_buf[idx], sizeof(float));
239  idx += sizeof(float);
240 
241  //linear acceleration imu-body frame, float [m/s^2]
242  //The estimated linear acceleration (without gravity) reported in m/s^2, and given in the body frame. The
243  //acceleration measurement has been bias compensated by the onboard INS filter, and the gravity
244  //component has been removed using the current gravity reference vector model. This measurement is
245  //attitude dependent, since the attitude solution is required to map the gravity reference vector (known
246  //in the inertial NED frame), into the body frame so that it can be removed from the measurement. If the
247  //device is stationary and the onboard INS filter is tracking, the measurement nominally will read 0 in all
248  //three axes.
249  memcpy(&vn_data->lin_accel, &vn_packet->msg_buf[idx], 3 * sizeof(float));
250  idx += 3 * sizeof(float);
251 
252  //YprU, float[3]
253  memcpy(&vn_data->ypr_u, &vn_packet->msg_buf[idx], 3 * sizeof(float));
254  idx += 3 * sizeof(float);
255 
256  //instatus, uint16
257  memcpy(&vn_data->ins_status, &vn_packet->msg_buf[idx], sizeof(uint16_t));
258  idx += sizeof(uint16_t);
259 
260  vn200_check_status(vn_data); // Check INS status
261 
262  //Vel body, float [m/s]
263  // The estimated velocity in the body (i.e. imu) frame, given in m/s.
264  memcpy(&vn_data->vel_body, &vn_packet->msg_buf[idx], sizeof(float));
265  idx += sizeof(float);
266 }
float phi
in radians
float theta
in radians
float psi
in radians
euler angles
static uint32_t idx
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
arch independent USB API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned long long uint64_t
Definition: vl53l1_types.h:72
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
void vn200_read_message(struct VNPacket *vn_packet, struct VNData *vn_data)
Read received message and populate data struct with new measurements.
Definition: vn200_serial.c:184
void vn200_event(struct VNPacket *vnp)
Definition: vn200_serial.c:113
void vn200_yaw_pitch_roll_to_attitude(struct FloatEulers *vn_attitude)
Convert yaw, pitch, and roll data from VectorNav to correct attitude yaw(0), pitch(1),...
Definition: vn200_serial.c:54
static unsigned short calculateCRC(unsigned char data[], unsigned int length)
Calculates the 16-bit CRC for the given ASCII or binary message.
Definition: vn200_serial.c:72
void vn200_check_status(struct VNData *vn_data)
Check INS status.
Definition: vn200_serial.c:41
static void vn200_read_buffer(struct VNPacket *vnp)
Definition: vn200_serial.c:104
void vn200_parse(struct VNPacket *vnp, uint8_t c)
Packet Collection & state machine.
Definition: vn200_serial.c:125
static bool verify_chk(unsigned char data[], unsigned int length, uint16_t *calc_chk, uint16_t *rec_chk)
Verify checksum.
Definition: vn200_serial.c:90
Vectornav VN-200 INS subsystem.
#define VN_GROUP_BYTES
Definition: vn200_serial.h:46
uint32_t hdr_error
Definition: vn200_serial.h:64
uint8_t err
see page 122 of VN-200 datasheet
Definition: vn200_serial.h:96
struct FloatRates gyro
Rates in the imu frame m/s.
Definition: vn200_serial.h:89
struct FloatEulers attitude
Attitude, float, [rad], yaw, pitch, roll.
Definition: vn200_serial.h:87
uint16_t datalength
Definition: vn200_serial.h:68
uint8_t msg_buf[VN_BUFFER_SIZE]
Definition: vn200_serial.h:65
uint16_t calc_chk
Definition: vn200_serial.h:72
struct FloatEulers ypr_u
Attitude uncertainty, 1sigma, float, [degrees], yaw, pitch, roll.
Definition: vn200_serial.h:93
uint64_t tow
tow (in nanoseconds), uint64
Definition: vn200_serial.h:98
struct FloatVect3 accel
Acceleration in the imu frame, m/s.
Definition: vn200_serial.h:88
#define VN_OUTPUT_GROUP
Definition: vn200_serial.h:45
uint8_t mode
0-not tracking, 1 - poor performance, 2- OK
Definition: vn200_serial.h:95
float timestamp
Time since VN startup [s].
Definition: vn200_serial.h:85
float pos_u[3]
The current GPS position uncertainty in the North East Down (NED) coordinate frame,...
Definition: vn200_serial.h:90
@ VNMsgData
Definition: vn200_serial.h:57
@ VNMsgHeader
Definition: vn200_serial.h:55
@ VNMsgSync
Definition: vn200_serial.h:54
@ VNMsgGroup
Definition: vn200_serial.h:56
uint16_t ins_status
see page 122 of VN-200 datasheet
Definition: vn200_serial.h:94
#define VN_HEADER_SIZE
Definition: vn200_serial.h:49
struct FloatVect3 vel_body
The estimated velocity in the imu frame, given in m/s.
Definition: vn200_serial.h:97
double pos_lla[3]
Definition: vn200_serial.h:101
#define VN_PAYLOAD_SIZE
Definition: vn200_serial.h:50
float vel_u
NED velocity uncertainty [m/s].
Definition: vn200_serial.h:91
uint8_t gps_fix
None|2D|3D.
Definition: vn200_serial.h:100
uint8_t num_sv
number of visible satellites
Definition: vn200_serial.h:99
struct FloatVect3 lin_accel
Linear acceleration in imu frame [m/s^2].
Definition: vn200_serial.h:92
uint16_t counter
Definition: vn200_serial.h:74
uint64_t nanostamp
Definition: vn200_serial.h:84
bool msg_available
Definition: vn200_serial.h:62
struct NedCoor_f vel_ned
The estimated velocity in the North East Down (NED) frame, given in m/s.
Definition: vn200_serial.h:102
uint16_t rec_chk
Definition: vn200_serial.h:73
uint32_t chksm_error
Definition: vn200_serial.h:63
#define VN_SYNC
Definition: vn200_serial.h:44
uint8_t msg_idx
Definition: vn200_serial.h:67
enum VNMsgStatus status
Definition: vn200_serial.h:66