Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
xsens700.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Christophe De Wagter
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 
28 #include "xsens700.h"
29 #include "xsens_common.h"
30 
31 #include "generated/airframe.h"
32 #include "led.h"
33 
34 #if USE_GPS_XSENS
36 #endif
37 
38 // FIXME Debugging Only
39 #include "mcu_periph/uart.h"
40 #include "pprzlink/messages.h"
42 
43 
49 
50 float xsens_gps_arm_x = 0;
51 float xsens_gps_arm_y = 0;
52 float xsens_gps_arm_z = 0;
53 
54 struct Xsens xsens700;
55 
56 volatile int xsens_configured = 0;
57 
58 void xsens700_init(void)
59 {
61  xsens_configured = 30;
62 
64  xsens_time_stamp = 0;
65 }
66 
68 {
69  uint8_t foo = 0;
70  XsensSend1ByAddr(&c1);
71  XsensSend1ByAddr(&c2);
72  XsensSend1ByAddr(&foo);
73  XsensSend1ByAddr(&freq);
74 }
75 
77 {
78  if (xsens_configured > 0) {
79  switch (xsens_configured) {
80  case 25:
81  /* send mode and settings to MT */
82  XSENS_GoToConfig();
83  //XSENS_SetOutputMode(xsens_output_mode);
84  //XSENS_SetOutputSettings(xsens_output_settings);
85  break;
86  case 18:
87  // Give pulses on SyncOut
88  //XSENS_SetSyncOutSettings(0,0x0002);
89  break;
90  case 17:
91 
92  XsensHeader(XSENS_SetOutputConfiguration_ID, 44);
93  xsens_ask_message_rate(0x10, 0x10, 4); // UTC
94  xsens_ask_message_rate(0x20, 0x30, 100); // Attitude Euler
95  xsens_ask_message_rate(0x40, 0x10, 100); // Delta-V
96  xsens_ask_message_rate(0x80, 0x20, 100); // Rate of turn
97  xsens_ask_message_rate(0xE0, 0x20, 50); // Status
98  xsens_ask_message_rate(0x30, 0x10, 50); // Baro Pressure
99  xsens_ask_message_rate(0x88, 0x40, 1); // NavSol
100  xsens_ask_message_rate(0x88, 0xA0, 1); // SV Info
101  xsens_ask_message_rate(0x50, 0x20, 50); // GPS Altitude Ellipsiod
102  xsens_ask_message_rate(0x50, 0x40, 50); // GPS Position
103  xsens_ask_message_rate(0xD0, 0x10, 50); // GPS Speed
104  XsensTrailer();
105  break;
106  case 2:
107  //XSENS_ReqLeverArmGps();
108  break;
109 
110  case 6:
111  //XSENS_ReqMagneticDeclination();
112  break;
113 
114  case 13:
115  //#ifdef AHRS_H_X
116  //#pragma message "Sending XSens Magnetic Declination."
117  //xsens_declination = atan2(AHRS_H_Y, AHRS_H_X);
118  //XSENS_SetMagneticDeclination(xsens_declination);
119  //#endif
120  break;
121  case 12:
122 #ifdef GPS_IMU_LEVER_ARM_X
123 #pragma message "Sending XSens GPS Arm."
124  XSENS_SetLeverArmGps(GPS_IMU_LEVER_ARM_X, GPS_IMU_LEVER_ARM_Y, GPS_IMU_LEVER_ARM_Z);
125 #endif
126  break;
127  case 10: {
128  uint8_t baud = 1;
129  XSENS_SetBaudrate(baud);
130  }
131  break;
132 
133  case 1:
134  XSENS_GoToMeasurment();
135  break;
136  default:
137  break;
138  }
140  return;
141  }
142 
143 }
144 
145 
147 {
148  uint8_t offset = 0;
149  if (xsens_id == XSENS_ReqLeverArmGpsAck_ID) {
150  xsens_gps_arm_x = XSENS_ReqLeverArmGpsAck_x(xsens_msg_buf);
151  xsens_gps_arm_y = XSENS_ReqLeverArmGpsAck_y(xsens_msg_buf);
152  xsens_gps_arm_z = XSENS_ReqLeverArmGpsAck_z(xsens_msg_buf);
153  } else if (xsens_id == XSENS_Error_ID) {
154  xsens_errorcode = XSENS_Error_errorcode(xsens_msg_buf);
155  } else if (xsens_id == XSENS_MTData2_ID) {
156  for (offset = 0; offset < xsens_len;) {
157  uint8_t code1 = xsens_msg_buf[offset];
158  uint8_t code2 = xsens_msg_buf[offset + 1];
159  int subpacklen = (int)xsens_msg_buf[offset + 2];
160  offset += 3;
161 
162  if (code1 == 0x10) {
163  if (code2 == 0x10) {
164  // UTC
165  } else if (code2 == 0x20) {
166  // Packet Counter
167  }
168  if (code2 == 0x30) {
169  // ITOW
170  }
171  } else if (code1 == 0x20) {
172  if (code2 == 0x30) {
173  // Attitude Euler
174  xsens700.euler.phi = XSENS_DATA_Euler_roll(xsens_msg_buf, offset) * M_PI / 180;
175  xsens700.euler.theta = XSENS_DATA_Euler_pitch(xsens_msg_buf, offset) * M_PI / 180;
176  xsens700.euler.psi = XSENS_DATA_Euler_yaw(xsens_msg_buf, offset) * M_PI / 180;
177 
179  }
180  } else if (code1 == 0x40) {
181  if (code2 == 0x10) {
182  // Delta-V
183  xsens700.accel.x = XSENS_DATA_Acceleration_x(xsens_msg_buf, offset) * 100.0f;
184  xsens700.accel.y = XSENS_DATA_Acceleration_y(xsens_msg_buf, offset) * 100.0f;
185  xsens700.accel.z = XSENS_DATA_Acceleration_z(xsens_msg_buf, offset) * 100.0f;
186  }
187  } else if (code1 == 0x80) {
188  if (code2 == 0x20) {
189  // Rate Of Turn
190  xsens700.gyro.p = XSENS_DATA_RateOfTurn_x(xsens_msg_buf, offset) * M_PI / 180;
191  xsens700.gyro.q = XSENS_DATA_RateOfTurn_y(xsens_msg_buf, offset) * M_PI / 180;
192  xsens700.gyro.r = XSENS_DATA_RateOfTurn_z(xsens_msg_buf, offset) * M_PI / 180;
193  }
194  } else if (code1 == 0x30) {
195  if (code2 == 0x10) {
196  // Baro Pressure
197  }
198  } else if (code1 == 0xE0) {
199  if (code2 == 0x20) {
200  // Status Word
201  xsens_msg_statusword = XSENS_DATA_StatusWord_status(xsens_msg_buf, offset);
202  //xsens700.gps.tow = xsens_msg_statusword;
203 #if USE_GPS_XSENS
204  if (bit_is_set(xsens_msg_statusword, 2) && bit_is_set(xsens_msg_statusword, 1)) {
205  if (bit_is_set(xsens_msg_statusword, 23) && bit_is_set(xsens_msg_statusword, 24)) {
206  xsens700.gps.fix = GPS_FIX_3D;
207  } else {
208  xsens700.gps.fix = GPS_FIX_2D;
209  }
210  } else { xsens700.gps.fix = GPS_FIX_NONE; }
211 #endif
212  }
213  } else if (code1 == 0x88) {
214  if (code2 == 0x40) {
215  xsens700.gps.week = XSENS_DATA_GpsSol_week(xsens_msg_buf, offset);
216  xsens700.gps.num_sv = XSENS_DATA_GpsSol_numSv(xsens_msg_buf, offset);
217  xsens700.gps.pacc = XSENS_DATA_GpsSol_pAcc(xsens_msg_buf, offset);
218  xsens700.gps.sacc = XSENS_DATA_GpsSol_sAcc(xsens_msg_buf, offset);
219  xsens700.gps.pdop = XSENS_DATA_GpsSol_pDop(xsens_msg_buf, offset);
220  } else if (code2 == 0xA0) {
221  // SVINFO
222  xsens700.gps.tow = XSENS_XDI_GpsSvInfo_iTOW(xsens_msg_buf + offset);
223 
224 #if USE_GPS_XSENS
225  xsens700.gps.nb_channels = XSENS_XDI_GpsSvInfo_nch(xsens_msg_buf + offset);
226 
227  xsens700.gps.last_3dfix_ticks = sys_time.nb_sec_rem;
228  xsens700.gps.last_3dfix_time = sys_time.nb_sec;
229 
230  uint8_t i;
231  // Do not write outside buffer
232  for (i = 0; i < Min(xsens700.gps.nb_channels, GPS_NB_CHANNELS); i++) {
233  uint8_t ch = XSENS_XDI_GpsSvInfo_chn(xsens_msg_buf + offset, i);
234  if (ch > xsens700.gps.nb_channels) { continue; }
235  xsens700.gps.svinfos[ch].svid = XSENS_XDI_GpsSvInfo_svid(xsens_msg_buf + offset, i);
236  xsens700.gps.svinfos[ch].flags = XSENS_XDI_GpsSvInfo_bitmask(xsens_msg_buf + offset, i);
237  xsens700.gps.svinfos[ch].qi = XSENS_XDI_GpsSvInfo_qi(xsens_msg_buf + offset, i);
238  xsens700.gps.svinfos[ch].cno = XSENS_XDI_GpsSvInfo_cnr(xsens_msg_buf + offset, i);
239  }
240 #endif
241  }
242  } else if (code1 == 0x50) {
243  if (code2 == 0x10) {
244  //xsens700.gps.hmsl = XSENS_DATA_Altitude_h(xsens_msg_buf,offset)* 1000.0f;
245  } else if (code2 == 0x20) {
246  // Altitude Elipsoid
247  xsens700.gps.lla_pos.alt = XSENS_DATA_Altitude_h(xsens_msg_buf, offset) * 1000.0f;
248 
249  // Compute geoid (MSL) height
251  xsens700.gps.hmsl = xsens700.gps.lla_pos.alt - (geoid_h * 1000.0f);
252  SetBit(xsens700.gps.valid_fields, GPS_VALID_HMSL_BIT);
253 
254  //xsens700.gps.tow = geoid_h * 1000.0f; //xsens700.gps.utm_pos.alt;
255  } else if (code2 == 0x40) {
256  // LatLong
257 #ifdef GPS_LED
258  LED_TOGGLE(GPS_LED);
259 #endif
260  xsens700.gps.last_3dfix_ticks = sys_time.nb_sec_rem;
261  xsens700.gps.last_3dfix_time = sys_time.nb_sec;
262  xsens700.gps.week = 0; // FIXME
263 
264  xsens700.lla_f.lat = RadOfDeg(XSENS_DATA_LatLon_lat(xsens_msg_buf, offset));
265  xsens700.lla_f.lon = RadOfDeg(XSENS_DATA_LatLon_lon(xsens_msg_buf, offset));
266  }
267  } else if (code1 == 0xD0) {
268  if (code2 == 0x10) {
269  // Velocity
270  xsens700.vel.x = XSENS_DATA_VelocityXYZ_x(xsens_msg_buf, offset);
271  xsens700.vel.y = XSENS_DATA_VelocityXYZ_y(xsens_msg_buf, offset);
272  xsens700.vel.z = XSENS_DATA_VelocityXYZ_z(xsens_msg_buf, offset);
273  xsens700.gps.ned_vel.x = xsens700.vel.x;
274  xsens700.gps.ned_vel.y = xsens700.vel.y;
275  xsens700.gps.ned_vel.z = xsens700.vel.x;
276  SetBit(xsens700.gps.valid_fields, GPS_VALID_VEL_NED_BIT);
277  }
278  }
279 
280  if (subpacklen < 0) {
281  subpacklen = 0;
282  }
283  offset += subpacklen;
284  }
285  }
286 }
volatile int xsens_configured
Definition: xsens700.c:56
unsigned short uint16_t
Definition: types.h:16
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define XsensTrailer()
Definition: xsens_common.h:59
static float wgs84_ellipsoid_to_geoid_f(float lat, float lon)
Get WGS84 ellipsoid/geoid separation.
static struct EcefCoor_d offset
uint32_t xsens_msg_statusword
Definition: xsens700.c:45
float phi
in radians
float xsens_gps_arm_z
Definition: xsens700.c:52
uint16_t xsens_output_mode
Definition: xsens700.c:47
#define GPS_VALID_VEL_NED_BIT
Definition: gps.h:52
uint32_t xsens_output_settings
Definition: xsens700.c:48
#define GPS_NB_CHANNELS
Definition: gps.h:57
float r
in rad/s
float psi
in radians
float xsens_gps_arm_x
Definition: xsens700.c:50
Parser for the Xsens protocol.
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:39
float q
in rad/s
float p
in rad/s
struct FloatVect3 vel
NED velocity in m/s.
Definition: xsens.h:58
uint8_t xsens_status
Definition: xsens_common.c:34
struct Xsens xsens700
Definition: xsens700.c:54
void parse_xsens700_msg(void)
Definition: xsens700.c:146
struct FloatVect3 accel
Definition: xsens.h:54
WGS-84 Geoid Heights.
float theta
in radians
#define TRUE
Definition: std.h:4
#define GPS_FIX_NONE
No GPS fix.
Definition: gps.h:37
#define GPS_FIX_2D
2D GPS fix
Definition: gps.h:38
#define XsensSend1ByAddr(x)
Definition: xsens_common.h:48
void xsens700_periodic(void)
Definition: xsens700.c:76
unsigned long uint32_t
Definition: types.h:18
uint8_t xsens_msg_buf[XSENS_MAX_PAYLOAD]
Definition: xsens_common.c:40
#define GPS_VALID_HMSL_BIT
Definition: gps.h:53
static uint16_t c1
Definition: baro_MS5534A.c:203
void xsens700_init(void)
Definition: xsens700.c:58
uint16_t foo
Definition: main_demo5.c:59
uint8_t xsens_len
Definition: xsens_common.c:35
#define Min(x, y)
Definition: main_fbw.c:52
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
#define LED_TOGGLE(i)
Definition: led_hw.h:51
uint16_t xsens_time_stamp
Definition: xsens700.c:46
unsigned char uint8_t
Definition: types.h:14
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
Definition: xsens.h:49
static uint16_t c2
Definition: baro_MS5534A.c:203
struct FloatEulers euler
Definition: xsens.h:61
float lon
in radians
arch independent LED (Light Emitting Diodes) API
struct LlaCoor_f lla_f
Definition: xsens.h:57
float lat
in radians
Parser for the Xsens protocol.
struct FloatRates gyro
Definition: xsens.h:53
uint8_t xsens_id
Includes macros generated from xsens_MTi-G.xml.
Definition: xsens_common.c:33
uint8_t xsens_errorcode
Definition: xsens700.c:44
static void xsens_ask_message_rate(uint8_t c1, uint8_t c2, uint8_t freq)
Definition: xsens700.c:67
#define XsensHeader(msg_id, len)
Definition: xsens_common.h:52
#define UNINIT
Receiving pprz messages.
Definition: protocol.c:11
volatile bool new_attitude
Definition: xsens.h:64
float xsens_gps_arm_y
Definition: xsens700.c:51