Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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"
32
33
34void vn200_check_status(struct VNData *vn_data);
36
37
41void 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;
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
72static 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
90static 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
104static 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
114{
115 struct link_device *dev = &(VN_PORT.device);
116 if (dev->char_available(dev->periph)) {
118 }
119}
120
121
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) {
155 vnp->datalength = VN_PAYLOAD_SIZE + VN_HEADER_SIZE;
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
184void 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
euler angles
uint16_t foo
Definition main_demo5.c:58
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.
unsigned long long uint64_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
void vn200_read_message(struct VNPacket *vn_packet, struct VNData *vn_data)
Read received message and populate data struct with new measurements.
void vn200_event(struct VNPacket *vnp)
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),...
static unsigned short calculateCRC(unsigned char data[], unsigned int length)
Calculates the 16-bit CRC for the given ASCII or binary message.
void vn200_check_status(struct VNData *vn_data)
Check INS status.
static void vn200_read_buffer(struct VNPacket *vnp)
void vn200_parse(struct VNPacket *vnp, uint8_t c)
Packet Collection & state machine.
static bool verify_chk(unsigned char data[], unsigned int length, uint16_t *calc_chk, uint16_t *rec_chk)
Verify checksum.
Vectornav VN-200 INS subsystem.
#define VN_GROUP_BYTES
uint8_t err
see page 122 of VN-200 datasheet
struct FloatRates gyro
Rates in the imu frame m/s.
struct FloatEulers attitude
Attitude, float, [rad], yaw, pitch, roll.
uint8_t msg_buf[VN_BUFFER_SIZE]
struct FloatEulers ypr_u
Attitude uncertainty, 1sigma, float, [degrees], yaw, pitch, roll.
uint64_t tow
tow (in nanoseconds), uint64
struct FloatVect3 accel
Acceleration in the imu frame, m/s.
#define VN_OUTPUT_GROUP
uint8_t mode
0-not tracking, 1 - poor performance, 2- OK
float timestamp
Time since VN startup [s].
float pos_u[3]
The current GPS position uncertainty in the North East Down (NED) coordinate frame,...
@ VNMsgData
@ VNMsgHeader
@ VNMsgSync
@ VNMsgGroup
uint16_t ins_status
see page 122 of VN-200 datasheet
#define VN_HEADER_SIZE
struct FloatVect3 vel_body
The estimated velocity in the imu frame, given in m/s.
double pos_lla[3]
#define VN_PAYLOAD_SIZE
float vel_u
NED velocity uncertainty [m/s].
uint8_t gps_fix
None|2D|3D.
uint8_t num_sv
number of visible satellites
struct FloatVect3 lin_accel
Linear acceleration in imu frame [m/s^2].
uint64_t nanostamp
struct NedCoor_f vel_ned
The estimated velocity in the North East Down (NED) frame, given in m/s.
#define VN_SYNC