Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ins_xsens.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
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 
27 #include "ins_module.h"
28 #include "ins_xsens.h"
29 #include "subsystems/ins.h"
30 
31 #include <inttypes.h>
32 
33 #include "generated/airframe.h"
34 
35 #include "mcu_periph/sys_time.h"
36 #include "messages.h"
37 
38 #if USE_GPS_XSENS
39 #if !USE_GPS
40 #error "USE_GPS needs to be 1 to use the Xsens GPS!"
41 #endif
42 #include "subsystems/gps.h"
43 #include "subsystems/abi.h"
46 #include "subsystems/navigation/common_nav.h" /* needed for nav_utm_zone0 */
47 bool_t gps_xsens_msg_available;
48 #endif
49 
50 // positions
54 
55 // velocities
59 
60 // body angles
64 
65 // angle rates
69 
70 // accelerations
74 
75 // magnetic
79 
80 #if USE_INS_MODULE
81 float ins_pitch_neutral;
82 float ins_roll_neutral;
83 #endif
84 
85 
87 //
88 // XSens Specific
89 //
90 
92 
93 #define XsensInitCheksum() { send_ck = 0; }
94 #define XsensUpdateChecksum(c) { send_ck += c; }
95 
96 #define XsensSend1(c) { uint8_t i8=c; InsUartSend1(i8); XsensUpdateChecksum(i8); }
97 #define XsensSend1ByAddr(x) { XsensSend1(*x); }
98 #define XsensSend2ByAddr(x) { XsensSend1(*(x+1)); XsensSend1(*x); }
99 #define XsensSend4ByAddr(x) { XsensSend1(*(x+3)); XsensSend1(*(x+2)); XsensSend1(*(x+1)); XsensSend1(*x); }
100 
101 #define XsensHeader(msg_id, len) { \
102  InsUartSend1(XSENS_START); \
103  XsensInitCheksum(); \
104  XsensSend1(XSENS_BID); \
105  XsensSend1(msg_id); \
106  XsensSend1(len); \
107  }
108 #define XsensTrailer() { uint8_t i8=0x100-send_ck; InsUartSend1(i8); }
109 
111 #include "xsens_protocol.h"
112 
113 
114 #define XSENS_MAX_PAYLOAD 254
116 
117 /* output mode : calibrated, orientation, position, velocity, status
118  * -----------
119  *
120  * bit 0 temp
121  * bit 1 calibrated
122  * bit 2 orentation
123  * bit 3 aux
124  *
125  * bit 4 position
126  * bit 5 velocity
127  * bit 6-7 Reserved
128  *
129  * bit 8-10 Reserved
130  * bit 11 status
131  *
132  * bit 12 GPS PVT+baro
133  * bit 13 Reserved
134  * bit 14 Raw
135  * bit 15 Reserved
136  */
137 
138 #ifndef XSENS_OUTPUT_MODE
139 #define XSENS_OUTPUT_MODE 0x1836
140 #endif
141 /* output settings : timestamp, euler, acc, rate, mag, float, no aux, lla, m/s, NED
142  * -----------
143  *
144  * bit 01 0=none, 1=sample counter, 2=utc, 3=sample+utc
145  * bit 23 0=quaternion, 1=euler, 2=DCM
146  *
147  * bit 4 1=disable acc output
148  * bit 5 1=disable gyro output
149  * bit 6 1=disable magneto output
150  * bit 7 Reserved
151  *
152  * bit 89 0=float, 1=fixedpoint12.20, 2=fixedpoint16.32
153  * bit 10 1=disable aux analog 1
154  * bit 11 1=disable aux analog 2
155  *
156  * bit 12-15 0-only: 14-16 WGS84
157  *
158  * bit 16-19 0-only: 16-18 m/s XYZ
159  *
160  * bit 20-23 Reserved
161  *
162  * bit 24-27 Reseverd
163  *
164  * bit 28-30 Reseverd
165  * bit 31 0=X-North-Z-Up, 1=North-East-Down
166  */
167 #ifndef XSENS_OUTPUT_SETTINGS
168 #define XSENS_OUTPUT_SETTINGS 0x80000C05
169 #endif
170 
171 #define UNINIT 0
172 #define GOT_START 1
173 #define GOT_BID 2
174 #define GOT_MID 3
175 #define GOT_LEN 4
176 #define GOT_DATA 5
177 #define GOT_CHECKSUM 6
178 
179 // FIXME Debugging Only
180 #include "mcu_periph/uart.h"
181 #include "messages.h"
183 
184 
190 
191 
193 float xsens_gps_arm_x = 0;
194 float xsens_gps_arm_y = 0;
195 float xsens_gps_arm_z = 0;
196 
197 #if USE_GPS_XSENS
198 struct LlaCoor_f lla_f;
199 struct UtmCoor_f utm_f;
200 #endif
201 
203 
208 static uint8_t ck;
210 
211 volatile int xsens_configured = 0;
212 
213 void xsens_init(void);
214 
215 void xsens_init(void)
216 {
217 
219  xsens_configured = 20;
220 
221 #if USE_INS_MODULE
224 #endif
225 
226  xsens_msg_status = 0;
227  xsens_time_stamp = 0;
230 }
231 
232 #if USE_IMU
234 
235 void imu_impl_init(void)
236 {
237  xsens_init();
241 }
242 
243 void imu_periodic(void)
244 {
245  xsens_periodic();
246 }
247 #endif /* USE_IMU */
248 
249 #if USE_INS_MODULE
250 void ins_xsens_update_gps(struct GpsState *gps_s);
251 
252 void ins_xsens_init(void)
253 {
254  struct UtmCoor_f utm0 = { nav_utm_north0, nav_utm_east0, 0., nav_utm_zone0 };
256  stateSetPositionUtm_f(&utm0);
257 
258  xsens_init();
259 }
260 
261 #include "subsystems/abi.h"
262 static abi_event gps_ev;
263 static void gps_cb(uint8_t sender_id __attribute__((unused)),
264  uint32_t stamp __attribute__((unused)),
265  struct GpsState *gps_s)
266 {
267  ins_xsens_update_gps(gps_s);
268 }
269 
270 void ins_xsens_register(void)
271 {
272  ins_register_impl(ins_xsens_init);
273  AbiBindMsgGPS(ABI_BROADCAST, &gps_ev, gps_cb);
274 }
275 
276 void ins_xsens_update_gps(struct GpsState *gps_s)
277 {
278  struct UtmCoor_f utm;
279  utm.east = gps_s->utm_pos.east / 100.;
280  utm.north = gps_s->utm_pos.north / 100.;
281  utm.zone = nav_utm_zone0;
282  utm.alt = gps_s->hmsl / 1000.;
283 
284  // set position
285  stateSetPositionUtm_f(&utm);
286 
287  struct NedCoor_f ned_vel = {
288  gps_s->ned_vel.x / 100.,
289  gps_s->ned_vel.y / 100.,
290  gps_s->ned_vel.z / 100.
291  };
292  // set velocity
293  stateSetSpeedNed_f(&ned_vel);
294 }
295 #endif
296 
297 #if USE_GPS_XSENS
298 void gps_impl_init(void)
299 {
300  gps.nb_channels = 0;
301 }
302 
303 static void gps_xsens_publish(void)
304 {
305  // publish gps data
306  uint32_t now_ts = get_sys_time_usec();
309  if (gps.fix == GPS_FIX_3D) {
312  }
313  AbiSendMsgGPS(GPS_XSENS_ID, now_ts, &gps);
314 }
315 #endif
316 
317 void xsens_periodic(void)
318 {
319  if (xsens_configured > 0) {
320  switch (xsens_configured) {
321  case 20:
322  /* send mode and settings to MT */
323  XSENS_GoToConfig();
324  XSENS_SetOutputMode(xsens_output_mode);
325  XSENS_SetOutputSettings(xsens_output_settings);
326  break;
327  case 18:
328  // Give pulses on SyncOut
329  XSENS_SetSyncOutSettings(0, 0x0002);
330  break;
331  case 17:
332  // 1 pulse every 100 samples
333  XSENS_SetSyncOutSettings(1, 100);
334  break;
335  case 2:
336  XSENS_ReqLeverArmGps();
337  break;
338 
339  case 6:
340  XSENS_ReqMagneticDeclination();
341  break;
342 
343  case 13:
344 #ifdef AHRS_H_X
345 #pragma message "Sending XSens Magnetic Declination."
346  xsens_declination = atan2(AHRS_H_Y, AHRS_H_X);
347  XSENS_SetMagneticDeclination(xsens_declination);
348 #endif
349  break;
350  case 12:
351 #ifdef GPS_IMU_LEVER_ARM_X
352 #pragma message "Sending XSens GPS Arm."
353  XSENS_SetLeverArmGps(GPS_IMU_LEVER_ARM_X, GPS_IMU_LEVER_ARM_Y, GPS_IMU_LEVER_ARM_Z);
354 #endif
355  break;
356  case 10: {
357  uint8_t baud = 1;
358  XSENS_SetBaudrate(baud);
359  }
360  break;
361 
362  case 1:
363  XSENS_GoToMeasurment();
364  break;
365 
366  default:
367  break;
368  }
370  return;
371  }
372 
373  RunOnceEvery(100, XSENS_ReqGPSStatus());
374 }
375 
376 #if USE_INS_MODULE
377 #include "state.h"
378 
379 static inline void update_state_interface(void)
380 {
381  // Send to Estimator (Control)
382 #ifdef XSENS_BACKWARDS
383  struct FloatEulers att = {
386  ins_psi + RadOfDeg(180)
387  };
388  struct FloatRates rates = {
389  -ins_p,
390  -ins_q,
391  ins_r
392  };
393 #else
394  struct FloatEulers att = {
397  ins_psi
398  };
399  struct FloatRates rates = {
400  ins_p,
401  ins_q,
402  ins_r
403  };
404 #endif
406  stateSetBodyRates_f(&rates);
407 }
408 #endif /* USE_INS_MODULE */
409 
410 void handle_ins_msg(void)
411 {
412 
413 #if USE_INS_MODULE
414  update_state_interface();
415 #endif
416 
417 #if USE_IMU
418  uint32_t now_ts = get_sys_time_usec();
419 #ifdef XSENS_BACKWARDS
424  AbiSendMsgIMU_GYRO_INT32(IMU_XSENS_ID, now_ts, &imu.gyro);
425  }
430  AbiSendMsgIMU_ACCEL_INT32(IMU_XSENS_ID, now_ts, &imu.accel);
431  }
432  if (imu_xsens.mag_available) {
435  imu_scale_mag(&imu);
436  AbiSendMsgIMU_MAG_INT32(IMU_XSENS_ID, now_ts, &imu.mag);
437  }
438 #else
443  AbiSendMsgIMU_GYRO_INT32(IMU_XSENS_ID, now_ts, &imu.gyro);
444  }
449  AbiSendMsgIMU_ACCEL_INT32(IMU_XSENS_ID, now_ts, &imu.accel);
450  }
451  if (imu_xsens.mag_available) {
454  imu_scale_mag(&imu);
455  AbiSendMsgIMU_MAG_INT32(IMU_XSENS_ID, now_ts, &imu.mag);
456  }
457 #endif /* XSENS_BACKWARDS */
458 #endif /* USE_IMU */
459 
460 #if USE_GPS_XSENS
461 
462  // Horizontal speed
463  float fspeed = sqrt(ins_vx * ins_vx + ins_vy * ins_vy);
464  if (gps.fix != GPS_FIX_3D) {
465  fspeed = 0;
466  }
467  gps.gspeed = fspeed * 100.;
468  gps.speed_3d = (uint16_t)(sqrt(ins_vx * ins_vx + ins_vy * ins_vy + ins_vz * ins_vz) * 100);
469 
470  float fcourse = atan2f((float)ins_vy, (float)ins_vx);
471  gps.course = fcourse * 1e7;
472 #endif // USE_GPS_XSENS
473 }
474 
475 void parse_ins_msg(void)
476 {
477  uint8_t offset = 0;
478  if (xsens_id == XSENS_ReqOutputModeAck_ID) {
479  xsens_output_mode = XSENS_ReqOutputModeAck_mode(xsens_msg_buf);
480  } else if (xsens_id == XSENS_ReqOutputSettings_ID) {
481  xsens_output_settings = XSENS_ReqOutputSettingsAck_settings(xsens_msg_buf);
482  } else if (xsens_id == XSENS_ReqMagneticDeclinationAck_ID) {
483  xsens_declination = DegOfRad(XSENS_ReqMagneticDeclinationAck_declination(xsens_msg_buf));
484 
487  } else if (xsens_id == XSENS_ReqLeverArmGpsAck_ID) {
488  xsens_gps_arm_x = XSENS_ReqLeverArmGpsAck_x(xsens_msg_buf);
489  xsens_gps_arm_y = XSENS_ReqLeverArmGpsAck_y(xsens_msg_buf);
490  xsens_gps_arm_z = XSENS_ReqLeverArmGpsAck_z(xsens_msg_buf);
491 
494  } else if (xsens_id == XSENS_Error_ID) {
495  xsens_errorcode = XSENS_Error_errorcode(xsens_msg_buf);
496  }
497 #if USE_GPS_XSENS
498  else if (xsens_id == XSENS_GPSStatus_ID) {
499  gps.nb_channels = XSENS_GPSStatus_nch(xsens_msg_buf);
500  gps.num_sv = 0;
501 
502  uint8_t i;
503  // Do not write outside buffer
504  for (i = 0; i < Min(gps.nb_channels, GPS_NB_CHANNELS); i++) {
505  uint8_t ch = XSENS_GPSStatus_chn(xsens_msg_buf, i);
506  if (ch > gps.nb_channels) { continue; }
507  gps.svinfos[ch].svid = XSENS_GPSStatus_svid(xsens_msg_buf, i);
508  gps.svinfos[ch].flags = XSENS_GPSStatus_bitmask(xsens_msg_buf, i);
509  gps.svinfos[ch].qi = XSENS_GPSStatus_qi(xsens_msg_buf, i);
510  gps.svinfos[ch].cno = XSENS_GPSStatus_cnr(xsens_msg_buf, i);
511  if (gps.svinfos[ch].flags > 0) {
512  gps.num_sv++;
513  }
514  }
515  }
516 #endif
517  else if (xsens_id == XSENS_MTData_ID) {
518  /* test RAW modes else calibrated modes */
519  //if ((XSENS_MASK_RAWInertial(xsens_output_mode)) || (XSENS_MASK_RAWGPS(xsens_output_mode))) {
520  if (XSENS_MASK_RAWInertial(xsens_output_mode)) {
521  ins_p = XSENS_DATA_RAWInertial_gyrX(xsens_msg_buf, offset);
522  ins_q = XSENS_DATA_RAWInertial_gyrY(xsens_msg_buf, offset);
523  ins_r = XSENS_DATA_RAWInertial_gyrZ(xsens_msg_buf, offset);
524 #if USE_IMU
526 #endif
527  offset += XSENS_DATA_RAWInertial_LENGTH;
528  }
529  if (XSENS_MASK_RAWGPS(xsens_output_mode)) {
530 #if USE_GPS_XSENS_RAW_DATA && USE_GPS_XSENS
531 
532  gps.week = 0; // FIXME
533  gps.tow = XSENS_DATA_RAWGPS_itow(xsens_msg_buf, offset) * 10;
534  gps.lla_pos.lat = XSENS_DATA_RAWGPS_lat(xsens_msg_buf, offset);
535  gps.lla_pos.lon = XSENS_DATA_RAWGPS_lon(xsens_msg_buf, offset);
536  gps.lla_pos.alt = XSENS_DATA_RAWGPS_alt(xsens_msg_buf, offset);
537 
538  /* Set the real UTM zone */
539  gps.utm_pos.zone = (gps.lla_pos.lon / 1e7 + 180) / 6 + 1;
542  /* convert to utm */
544  /* copy results of utm conversion */
545  gps.utm_pos.east = utm_f.east * 100;
546  gps.utm_pos.north = utm_f.north * 100;
548 
549  ins_x = utm_f.east;
550  ins_y = utm_f.north;
551  // Altitude: Xsens LLH gives ellipsoid height
552  ins_z = -(INS_FORMAT)XSENS_DATA_RAWGPS_alt(xsens_msg_buf, offset) / 1000.;
553 
554  // Compute geoid (MSL) height
555  float hmsl = wgs84_ellipsoid_to_geoid(lla_f.lat, lla_f.lon);
556  gps.hmsl = XSENS_DATA_RAWGPS_alt(xsens_msg_buf, offset) - (hmsl * 1000.0f);
557 
558  ins_vx = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf, offset)) / 100.;
559  ins_vy = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf, offset)) / 100.;
560  ins_vz = ((INS_FORMAT)XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf, offset)) / 100.;
561  gps.ned_vel.x = XSENS_DATA_RAWGPS_vel_n(xsens_msg_buf, offset);
562  gps.ned_vel.y = XSENS_DATA_RAWGPS_vel_e(xsens_msg_buf, offset);
563  gps.ned_vel.z = XSENS_DATA_RAWGPS_vel_d(xsens_msg_buf, offset);
564  gps.pacc = XSENS_DATA_RAWGPS_hacc(xsens_msg_buf, offset) / 100;
565  gps.sacc = XSENS_DATA_RAWGPS_sacc(xsens_msg_buf, offset) / 100;
566  gps.pdop = 5; // FIXME Not output by XSens
567 
568  gps_xsens_publish();
569 #endif
570  offset += XSENS_DATA_RAWGPS_LENGTH;
571  }
572  //} else {
573  if (XSENS_MASK_Temp(xsens_output_mode)) {
574  offset += XSENS_DATA_Temp_LENGTH;
575  }
576  if (XSENS_MASK_Calibrated(xsens_output_mode)) {
577  uint8_t l = 0;
578  if (!XSENS_MASK_AccOut(xsens_output_settings)) {
579  ins_ax = XSENS_DATA_Calibrated_accX(xsens_msg_buf, offset);
580  ins_ay = XSENS_DATA_Calibrated_accY(xsens_msg_buf, offset);
581  ins_az = XSENS_DATA_Calibrated_accZ(xsens_msg_buf, offset);
582 #if USE_IMU
584 #endif
585  l++;
586  }
587  if (!XSENS_MASK_GyrOut(xsens_output_settings)) {
588  ins_p = XSENS_DATA_Calibrated_gyrX(xsens_msg_buf, offset);
589  ins_q = XSENS_DATA_Calibrated_gyrY(xsens_msg_buf, offset);
590  ins_r = XSENS_DATA_Calibrated_gyrZ(xsens_msg_buf, offset);
591 #if USE_IMU
593 #endif
594  l++;
595  }
596  if (!XSENS_MASK_MagOut(xsens_output_settings)) {
597  ins_mx = XSENS_DATA_Calibrated_magX(xsens_msg_buf, offset);
598  ins_my = XSENS_DATA_Calibrated_magY(xsens_msg_buf, offset);
599  ins_mz = XSENS_DATA_Calibrated_magZ(xsens_msg_buf, offset);
600 #if USE_IMU
602 #endif
603  l++;
604  }
605  offset += l * XSENS_DATA_Calibrated_LENGTH / 3;
606  }
607  if (XSENS_MASK_Orientation(xsens_output_mode)) {
608  if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x00) {
609  float q0 = XSENS_DATA_Quaternion_q0(xsens_msg_buf, offset);
610  float q1 = XSENS_DATA_Quaternion_q1(xsens_msg_buf, offset);
611  float q2 = XSENS_DATA_Quaternion_q2(xsens_msg_buf, offset);
612  float q3 = XSENS_DATA_Quaternion_q3(xsens_msg_buf, offset);
613  float dcm00 = 1.0 - 2 * (q2 * q2 + q3 * q3);
614  float dcm01 = 2 * (q1 * q2 + q0 * q3);
615  float dcm02 = 2 * (q1 * q3 - q0 * q2);
616  float dcm12 = 2 * (q2 * q3 + q0 * q1);
617  float dcm22 = 1.0 - 2 * (q1 * q1 + q2 * q2);
618  ins_phi = atan2(dcm12, dcm22);
619  ins_theta = -asin(dcm02);
620  ins_psi = atan2(dcm01, dcm00);
621  offset += XSENS_DATA_Quaternion_LENGTH;
622  }
623  if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x01) {
624  ins_phi = XSENS_DATA_Euler_roll(xsens_msg_buf, offset) * M_PI / 180;
625  ins_theta = XSENS_DATA_Euler_pitch(xsens_msg_buf, offset) * M_PI / 180;
626  ins_psi = XSENS_DATA_Euler_yaw(xsens_msg_buf, offset) * M_PI / 180;
627  offset += XSENS_DATA_Euler_LENGTH;
628  }
629  if (XSENS_MASK_OrientationMode(xsens_output_settings) == 0x10) {
630  offset += XSENS_DATA_Matrix_LENGTH;
631  }
632  new_ins_attitude = 1;
633  }
634  if (XSENS_MASK_Auxiliary(xsens_output_mode)) {
635  uint8_t l = 0;
636  if (!XSENS_MASK_Aux1Out(xsens_output_settings)) {
637  l++;
638  }
639  if (!XSENS_MASK_Aux2Out(xsens_output_settings)) {
640  l++;
641  }
642  offset += l * XSENS_DATA_Auxiliary_LENGTH / 2;
643  }
644  if (XSENS_MASK_Position(xsens_output_mode)) {
645 #if (! USE_GPS_XSENS_RAW_DATA) && USE_GPS_XSENS
646  lla_f.lat = RadOfDeg(XSENS_DATA_Position_lat(xsens_msg_buf, offset));
647  lla_f.lon = RadOfDeg(XSENS_DATA_Position_lon(xsens_msg_buf, offset));
648  gps.lla_pos.lat = (int32_t)(DegOfRad(lla_f.lat) * 1e7);
649  gps.lla_pos.lon = (int32_t)(DegOfRad(lla_f.lon) * 1e7);
650  gps.utm_pos.zone = (DegOfRad(lla_f.lon) + 180) / 6 + 1;
651  /* convert to utm */
653  /* copy results of utm conversion */
654  gps.utm_pos.east = utm_f.east * 100;
655  gps.utm_pos.north = utm_f.north * 100;
656  ins_x = utm_f.east;
657  ins_y = utm_f.north;
658  ins_z = XSENS_DATA_Position_alt(xsens_msg_buf, offset); //TODO is this hms or above ellipsoid?
659  gps.hmsl = ins_z * 1000;
660  // what about gps.lla_pos.alt and gps.utm_pos.alt ?
661 
662  gps_xsens_publish();
663 #endif
664  offset += XSENS_DATA_Position_LENGTH;
665  }
666  if (XSENS_MASK_Velocity(xsens_output_mode)) {
667 #if (! USE_GPS_XSENS_RAW_DATA) && USE_GPS_XSENS
668  ins_vx = XSENS_DATA_Velocity_vx(xsens_msg_buf, offset);
669  ins_vy = XSENS_DATA_Velocity_vy(xsens_msg_buf, offset);
670  ins_vz = XSENS_DATA_Velocity_vz(xsens_msg_buf, offset);
671 #endif
672  offset += XSENS_DATA_Velocity_LENGTH;
673  }
674  if (XSENS_MASK_Status(xsens_output_mode)) {
675  xsens_msg_status = XSENS_DATA_Status_status(xsens_msg_buf, offset);
676 #if USE_GPS_XSENS
677  if (bit_is_set(xsens_msg_status, 2)) { gps.fix = GPS_FIX_3D; } // gps fix
678  else if (bit_is_set(xsens_msg_status, 1)) { gps.fix = 0x01; } // efk valid
679  else { gps.fix = GPS_FIX_NONE; }
680 #ifdef GPS_LED
681  if (gps.fix == GPS_FIX_3D) {
682  LED_ON(GPS_LED);
683  } else {
684  LED_TOGGLE(GPS_LED);
685  }
686 #endif // GPS_LED
687 #endif // USE_GPS_XSENS
688  offset += XSENS_DATA_Status_LENGTH;
689  }
690  if (XSENS_MASK_TimeStamp(xsens_output_settings)) {
691  xsens_time_stamp = XSENS_DATA_TimeStamp_ts(xsens_msg_buf, offset);
692 #if USE_GPS_XSENS
694 #endif
695  offset += XSENS_DATA_TimeStamp_LENGTH;
696  }
697  if (XSENS_MASK_UTC(xsens_output_settings)) {
698  xsens_time.hour = XSENS_DATA_UTC_hour(xsens_msg_buf, offset);
699  xsens_time.min = XSENS_DATA_UTC_min(xsens_msg_buf, offset);
700  xsens_time.sec = XSENS_DATA_UTC_sec(xsens_msg_buf, offset);
701  xsens_time.nanosec = XSENS_DATA_UTC_nanosec(xsens_msg_buf, offset);
702  xsens_time.year = XSENS_DATA_UTC_year(xsens_msg_buf, offset);
703  xsens_time.month = XSENS_DATA_UTC_month(xsens_msg_buf, offset);
704  xsens_time.day = XSENS_DATA_UTC_day(xsens_msg_buf, offset);
705 
706  offset += XSENS_DATA_UTC_LENGTH;
707  }
708  //}
709  }
710 
711 }
712 
713 
715 {
716  ck += c;
717  switch (xsens_status) {
718  case UNINIT:
719  if (c != XSENS_START) {
720  goto error;
721  }
722  xsens_status++;
723  ck = 0;
724  break;
725  case GOT_START:
726  if (c != XSENS_BID) {
727  goto error;
728  }
729  xsens_status++;
730  break;
731  case GOT_BID:
732  xsens_id = c;
733  xsens_status++;
734  break;
735  case GOT_MID:
736  xsens_len = c;
738  goto error;
739  }
740  xsens_msg_idx = 0;
741  xsens_status++;
742  break;
743  case GOT_LEN:
745  xsens_msg_idx++;
746  if (xsens_msg_idx >= xsens_len) {
747  xsens_status++;
748  }
749  break;
750  case GOT_DATA:
751  if (ck != 0) {
752  goto error;
753  }
755  goto restart;
756  break;
757  default:
758  break;
759  }
760  return;
761 error:
762 restart:
764  return;
765 }
uint8_t qi
quality bitfield (GPS receiver specific)
Definition: gps.h:60
INS_FORMAT ins_my
Definition: ins_xsens.c:77
Event structure to store callbacks in a linked list.
Definition: abi_common.h:65
unsigned short uint16_t
Definition: types.h:16
int32_t north
in centimeters
static void stateSetNedToBodyEulers_f(struct FloatEulers *ned_to_body_eulers)
Set vehicle body attitude from euler angles (float).
Definition: state.h:1076
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
struct SVinfo svinfos[GPS_NB_CHANNELS]
holds information from the Space Vehicles (Satellites)
Definition: gps.h:87
#define XSENS_OUTPUT_SETTINGS
Definition: ins_xsens.c:168
void xsens_init(void)
Definition: ins_xsens.c:215
INS_FORMAT ins_y
Definition: ins_xsens.c:52
float east
in meters
#define Min(x, y)
uint32_t pacc
position accuracy in cm
Definition: gps.h:77
int8_t month
Definition: ins_xsens.h:40
float north
in meters
float xsens_gps_arm_x
Definition: ins_xsens.c:193
void imu_scale_gyro(struct Imu *_imu)
Definition: ahrs_gx3.c:349
#define UNINIT
Definition: ins_xsens.c:171
uint8_t nb_channels
Number of scanned satellites.
Definition: gps.h:86
INS_FORMAT ins_psi
Definition: ins_xsens.c:63
void imu_scale_accel(struct Imu *_imu)
Definition: ahrs_gx3.c:350
bool_t accel_available
Definition: ins_xsens.h:60
INS_FORMAT ins_p
Definition: ins_xsens.c:66
uint16_t week
GPS week.
Definition: gps.h:83
static uint8_t xsens_id
Definition: ins_xsens.c:204
bool_t gyro_available
Definition: ins_xsens.h:59
uint8_t xsens_msg_buf[XSENS_MAX_PAYLOAD]
Definition: ins_xsens.c:115
static uint8_t xsens_status
Definition: ins_xsens.c:205
#define VECT3_ASSIGN(_a, _x, _y, _z)
Definition: pprz_algebra.h:124
#define RATES_ASSIGN(_ra, _p, _q, _r)
Definition: pprz_algebra.h:329
Main include for ABI (AirBorneInterface).
uint8_t xsens_msg_status
Definition: ins_xsens.c:186
uint8_t nav_utm_zone0
Definition: common_nav.c:44
Integrated Navigation System interface.
#define IMU_XSENS_ID
int8_t day
Definition: ins_xsens.h:41
INS_FORMAT ins_x
Definition: ins_xsens.c:51
INS_FORMAT ins_vz
Definition: ins_xsens.c:58
position in UTM coordinates Units: meters
int32_t east
in centimeters
struct ImuXsens imu_xsens
Definition: ins_xsens.c:233
int32_t nanosec
Definition: ins_xsens.h:38
uint8_t svid
Satellite ID.
Definition: gps.h:58
INS_FORMAT ins_vy
Definition: ins_xsens.c:57
uint16_t speed_3d
norm of 3d speed in cm/s
Definition: gps.h:75
int16_t year
Definition: ins_xsens.h:39
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:43
#define INS_ROLL_NEUTRAL_DEFAULT
Definition: ahrs_sim.c:43
int32_t z
Down.
volatile int xsens_configured
Definition: ins_xsens.c:211
struct UtmCoor_i utm_pos
position in UTM (north,east: cm; alt: mm over ellipsoid)
Definition: gps.h:70
uint32_t xsens_output_settings
Definition: ins_xsens.c:189
#define GOT_BID
Definition: ins_xsens.c:173
volatile uint8_t ins_msg_received
Definition: ins_xsens.c:91
int8_t sec
Definition: ins_xsens.h:37
uint8_t xsens_errorcode
Definition: ins_xsens.c:185
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:89
#define FALSE
Definition: std.h:5
#define GOT_MID
Definition: ins_xsens.c:174
int32_t alt
in millimeters above WGS84 reference ellipsoid
WGS-84 Geoid Heights.
static uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.h:39
euler angles
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:78
#define LED_TOGGLE(i)
Definition: led_hw.h:44
int32_t y
East.
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:92
struct Int32Vect3 mag_unscaled
unscaled magnetometer measurements
Definition: imu.h:52
static void stateSetPositionUtm_f(struct UtmCoor_f *utm_pos)
Set position from UTM coordinates (float).
Definition: state.h:565
uint8_t zone
UTM zone number.
Paparazzi floating point math for geodetic calculations.
static abi_event gps_ev
Definition: ahrs_infrared.c:58
vector in Latitude, Longitude and Altitude
#define GPS_XSENS_ID
static void stateSetSpeedNed_f(struct NedCoor_f *ned_speed)
Set ground speed in local NED coordinates (float).
Definition: state.h:792
struct Int32Rates gyro_unscaled
unscaled gyroscope measurements
Definition: imu.h:50
#define TRUE
Definition: std.h:4
struct Int32Vect3 accel
accelerometer measurements in m/s^2 in BFP with INT32_ACCEL_FRAC
Definition: imu.h:43
void parse_ins_buffer(uint8_t c)
Definition: ins_xsens.c:714
struct LlaCoor_f lla_f
Definition: ins_xsens700.c:159
int32_t hmsl
height above mean sea level in mm
Definition: gps.h:71
uint8_t cno
Carrier to Noise Ratio (Signal Strength) in dbHz.
Definition: gps.h:61
int32_t nav_utm_north0
Definition: common_nav.c:43
vector in North East Down coordinates Units: meters
uint8_t send_ck
Definition: ins_xsens.c:209
int8_t hour
Definition: ins_xsens.h:35
#define MAG_BFP_OF_REAL(_af)
Architecture independent timing functions.
struct XsensTime xsens_time
Definition: ins_xsens.c:202
data structure for GPS information
Definition: gps.h:67
uint32_t tow
GPS time of week in ms.
Definition: gps.h:84
#define GPS_FIX_NONE
No GPS fix.
Definition: gps.h:41
Device independent GPS code (interface)
INS_FORMAT ins_theta
Definition: ins_xsens.c:62
uint16_t pdop
position dilution of precision scaled by 100
Definition: gps.h:80
struct Imu imu
global IMU state
Definition: imu_aspirin2.c:43
int32_t x
North.
unsigned long uint32_t
Definition: types.h:18
void parse_ins_msg(void)
Definition: ins_xsens.c:475
int32_t lon
in degrees*1e7
INS_FORMAT ins_mx
Definition: ins_xsens.c:76
uint16_t xsens_time_stamp
Definition: ins_xsens.c:187
#define INS_PITCH_NEUTRAL_DEFAULT
Definition: ahrs_sim.c:46
struct Int32Vect3 mag
magnetometer measurements scaled to 1 in BFP with INT32_MAG_FRAC
Definition: imu.h:44
uint8_t zone
UTM zone number.
Library for the XSENS AHRS.
Definition: ins_xsens.h:34
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:70
struct UtmCoor_f utm_f
Definition: ins_xsens700.c:160
float ins_pitch_neutral
Definition: ins_arduimu.c:15
void handle_ins_msg(void)
Definition: ins_xsens.c:410
#define GOT_START
Definition: ins_xsens.c:172
signed long int32_t
Definition: types.h:19
#define INS_FORMAT
Definition: ins_module.h:35
static void gps_cb(uint8_t sender_id, uint32_t stamp, struct GpsState *gps_s)
Definition: ahrs_infrared.c:68
int8_t min
Definition: ins_xsens.h:36
#define LED_ON(i)
Definition: led_hw.h:42
INS_FORMAT ins_vx
Definition: ins_xsens.c:56
static float wgs84_ellipsoid_to_geoid(float lat, float lon)
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:90
INS_FORMAT ins_q
Definition: ins_xsens.c:67
int32_t alt
in millimeters above WGS84 reference ellipsoid
unsigned char uint8_t
Definition: types.h:14
INS_FORMAT ins_phi
Definition: ins_xsens.c:61
void imu_scale_mag(struct Imu *_imu)
Definition: ahrs_gx3.c:351
API to get/set the generic vehicle states.
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:76
volatile uint8_t new_ins_attitude
INS_FORMAT ins_mz
Definition: ins_xsens.c:78
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:69
#define GOT_LEN
Definition: ins_xsens.c:175
int32_t nav_utm_east0
Definition: common_nav.c:42
float xsens_gps_arm_y
Definition: ins_xsens.c:194
static uint8_t ck
Definition: ins_xsens.c:208
uint16_t xsens_output_mode
Definition: ins_xsens.c:188
float xsens_gps_arm_z
Definition: ins_xsens.c:195
uint8_t flags
bitfield with GPS receiver specific flags
Definition: gps.h:59
float lon
in radians
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:91
uint8_t num_sv
number of sat in fix
Definition: gps.h:81
struct Int32Vect3 accel_unscaled
unscaled accelerometer measurements
Definition: imu.h:51
#define ABI_BROADCAST
Broadcast address.
Definition: abi_common.h:56
void imu_periodic(void)
optional.
Definition: ins_xsens.c:243
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:74
float lat
in radians
INS_FORMAT ins_z
Definition: ins_xsens.c:53
float ins_roll_neutral
Definition: ins_arduimu.c:14
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:69
INS_FORMAT ins_ay
Definition: ins_xsens.c:72
float xsens_declination
Definition: ins_xsens.c:192
#define ACCEL_BFP_OF_REAL(_af)
void imu_impl_init(void)
must be defined by underlying hardware
Definition: ins_xsens.c:235
INS_FORMAT ins_ax
Definition: ins_xsens.c:71
INS_FORMAT ins_r
Definition: ins_xsens.c:68
void xsens_periodic(void)
Definition: ins_xsens.c:317
int32_t lat
in degrees*1e7
static uint8_t xsens_len
Definition: ins_xsens.c:206
static void stateSetBodyRates_f(struct FloatRates *body_rate)
Set vehicle body angular rate (float).
Definition: state.h:1152
static uint8_t xsens_msg_idx
Definition: ins_xsens.c:207
uint8_t fix
status of fix
Definition: gps.h:82
void ins_register_impl(InsInit init)
Definition: ins.c:53
#define XSENS_OUTPUT_MODE
Definition: ins_xsens.c:139
#define GOT_DATA
Definition: ins_xsens.c:176
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:73
static void stateSetLocalUtmOrigin_f(struct UtmCoor_f *utm_def)
Set the local (flat earth) coordinate frame origin from UTM (float).
Definition: state.h:460
struct GpsState gps
global GPS state
Definition: gps.c:41
angular rates
Device independent INS code.
bool_t mag_available
Definition: ins_xsens.h:61
#define LLA_FLOAT_OF_BFP(_o, _i)
INS_FORMAT ins_az
Definition: ins_xsens.c:73
#define XSENS_MAX_PAYLOAD
Includes macros generated from xsens_MTi-G.xml.
Definition: ins_xsens.c:114
void utm_of_lla_f(struct UtmCoor_f *utm, struct LlaCoor_f *lla)
struct Int32Rates gyro
gyroscope measurements in rad/s in BFP with INT32_RATE_FRAC
Definition: imu.h:42
#define RATE_BFP_OF_REAL(_af)