Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
imu_chimu.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 The Paparazzi Team
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 /*---------------------------------------------------------------------------
23  Copyright (c) Ryan Mechatronics 2008. All Rights Reserved.
24 
25  File: *.c
26 
27  Description: CHIMU Protocol Parser
28 
29 
30  Public Functions:
31  CHIMU_Init Create component instance
32  CHIMU_Parse Parse the RX byte stream message
33 
34  Applicable Documents:
35  CHIMU User Manual
36 
37  Adapted to paparazzi by C. De Wagter
38 
39  ---------------------------------------------------------------------------*/
40 
41 #include "imu_chimu.h"
42 #include "string.h"
43 #include "math.h"
44 
45 
46 /***************************************************************************
47  * Cyclic Redundancy Checksum
48  */
49 
50 static unsigned long UpdateCRC(unsigned long CRC_acc, void *data, unsigned long data_len)
51 {
52  unsigned long i; // loop counter
53 #define POLY 0xEDB88320 // bit-reversed version of the poly 0x04C11DB7
54  // Create the CRC "dividend" for polynomial arithmetic (binary arithmetic
55  // with no carries)
56 
57  unsigned char *CRC_input = (unsigned char*)data;
58  for (unsigned long j = data_len; j; --j) {
59 
60  CRC_acc = CRC_acc ^ *CRC_input++;
61  // "Divide" the poly into the dividend using CRC XOR subtraction
62  // CRC_acc holds the "remainder" of each divide
63  //
64  // Only complete this division for 8 bits since input is 1 byte
65  for (i = 0; i < 8; i++) {
66  // Check if the MSB is set (if MSB is 1, then the POLY can "divide"
67  // into the "dividend")
68  if ((CRC_acc & 0x00000001) == 0x00000001) {
69  // if so, shift the CRC value, and XOR "subtract" the poly
70  CRC_acc = CRC_acc >> 1;
71  CRC_acc ^= POLY;
72  }
73  else {
74  // if not, just shift the CRC value
75  CRC_acc = CRC_acc >> 1;
76  }
77  }
78  }
79  // Return the final remainder (CRC value)
80  return CRC_acc;
81 }
82 
83 void CHIMU_Checksum(unsigned char *data, unsigned char buflen)
84 {
85  data[buflen-1] = (unsigned char) (UpdateCRC(0xFFFFFFFF , data , (unsigned long) (buflen - 1) ) & 0xff) ;
86 }
87 
88 
89 /***************************************************************************
90  * CHIMU Protocol Definition
91  */
92 
93 // Lowlevel Protocol Decoding
94 #define CHIMU_STATE_MACHINE_START 0
95 #define CHIMU_STATE_MACHINE_HEADER2 1
96 #define CHIMU_STATE_MACHINE_LEN 2
97 #define CHIMU_STATE_MACHINE_DEVICE 3
98 #define CHIMU_STATE_MACHINE_ID 4
99 #define CHIMU_STATE_MACHINE_PAYLOAD 5
100 #define CHIMU_STATE_MACHINE_XSUM 6
101 
102 // Communication Definitions
103 #define CHIMU_COM_ID_HIGH 0x1F //Must set this to the max ID expected above
104 
105 /*---------------------------------------------------------------------------
106  Name: CHIMU_Init
107 
108  ---------------------------------------------------------------------------*/
110 {
111  unsigned char i;
113  pstData->m_Checksum = 0x00;
114  pstData->m_ReceivedChecksum = 0x00;
115  pstData->m_Index = 0;
116  pstData->m_PayloadIndex = 0;
117 
118  //Sensor data holder
119  pstData->m_sensor.cputemp=0.0;
120  for (i=0;i<3;i++) {
121  pstData->m_sensor.acc[i]=0.0;
122  pstData->m_sensor.rate[i]=0.0;
123  pstData->m_sensor.mag[i]=0.0;
124  }
125  pstData->m_sensor.spare1=0.0;
126  //Attitude data
127  pstData->m_attitude.euler.phi = 0.0;
128  pstData->m_attitude.euler.theta = 0.0;
129  pstData->m_attitude.euler.psi = 0.0;
130  //Attitude rate data
131  pstData->m_attrates.euler.phi = 0.0;
132  pstData->m_attrates.euler.theta = 0.0;
133  pstData->m_attrates.euler.psi = 0.0;
134 
135  for (i=0; i<CHIMU_RX_BUFFERSIZE; i++) {
136  pstData->m_Payload[i]= 0x00;
137  pstData->m_FullMessage[i]= 0x00;
138  }
139  pstData->m_MsgLen = 0;
140  pstData->m_MsgID = 0;
141  pstData->m_TempDeviceID =0;
142  pstData->m_DeviceID = 0x01; //look at this later
143 }
144 
145 /*---------------------------------------------------------------------------
146  Name: CHIMU_Parse
147  Abstract: Parse message, returns TRUE if new data.
148  ---------------------------------------------------------------------------*/
149 
150 unsigned char CHIMU_Parse(
151  unsigned char btData, /* input byte stream buffer */
152  unsigned char bInputType, /* for future use if special builds of CHIMU data are performed */
153  CHIMU_PARSER_DATA *pstData) /* resulting data */
154 {
155 
156  char bUpdate = FALSE;
157 
158  switch (pstData->m_State) {
159  case CHIMU_STATE_MACHINE_START: // Waiting for start character 0xAE
160  if(btData == 0xAE) {
162  pstData->m_Index = 0;
163  pstData->m_FullMessage[pstData->m_Index++] = btData;
164  } else {
165  ;;
166  }
167  bUpdate = FALSE;
168  break;
169  case CHIMU_STATE_MACHINE_HEADER2: // Waiting for second header character 0xAE
170  if(btData == 0xAE) {
171  pstData->m_State = CHIMU_STATE_MACHINE_LEN;
172  pstData->m_FullMessage[pstData->m_Index++]=btData;
173  } else {
175  } //Fail to see header. Restart.
176  break;
177  case CHIMU_STATE_MACHINE_LEN: // Get chars to read
178  if( btData <= CHIMU_RX_BUFFERSIZE) {
179  pstData->m_MsgLen = btData ; // It might be invalid, but we do a check on buffer size
180  pstData->m_FullMessage[pstData->m_Index++]=btData;
182  } else {
183  pstData->m_State = CHIMU_STATE_MACHINE_START; //Length byte exceeds buffer. Signal a fail and restart
184  //BuiltInTest(BIT_COM_UART_RECEIPTFAIL, BIT_FAIL);
185  }
186  break;
187  case CHIMU_STATE_MACHINE_DEVICE: // Get device. If not us, ignore and move on. Allows common com with Monkey / Chipmunk
188  if( (btData == pstData->m_DeviceID) || (btData == 0xAA)) {
189  //0xAA is global message
190  pstData->m_TempDeviceID = btData;
191  pstData->m_FullMessage[pstData->m_Index++]=btData;
192  pstData->m_State = CHIMU_STATE_MACHINE_ID;
193  } else {
195  } //Fail to see correct device ID. Restart.
196  break;
197  case CHIMU_STATE_MACHINE_ID: // Get ID
198  pstData->m_MsgID = btData; // might be invalid, chgeck it out here:
199  if ( pstData->m_MsgID>CHIMU_COM_ID_HIGH) {
201  //BuiltInTest(BIT_COM_UART_RECEIPTFAIL, BIT_FAIL);
202  } else {
203  pstData->m_FullMessage[pstData->m_Index++]=btData;
204  pstData->m_PayloadIndex = 0;
205  pstData->m_State = CHIMU_STATE_MACHINE_PAYLOAD; //Finally....Good to go...
206  }
207  break;
208  case CHIMU_STATE_MACHINE_PAYLOAD: // Waiting for number of bytes in payload
209  pstData->m_Payload[pstData->m_PayloadIndex++]= btData;
210  pstData->m_FullMessage[pstData->m_Index++]=btData;
211  if ((pstData->m_Index) >= (pstData->m_MsgLen + 5)) {
212  //Now we have the payload. Verify XSUM and then parse it next
213  pstData->m_Checksum = (unsigned char) ((UpdateCRC(0xFFFFFFFF , pstData->m_FullMessage , (unsigned long) (pstData->m_MsgLen)+5)) & 0xFF);
215  } else {
216  return FALSE;
217  }
218  break;
219  case CHIMU_STATE_MACHINE_XSUM: // Verify
220  pstData->m_ReceivedChecksum = btData;
221  pstData->m_FullMessage[pstData->m_Index++]=btData;
222  if (pstData->m_Checksum!=pstData->m_ReceivedChecksum) {
223  bUpdate = FALSE;
224  //BuiltInTest(BIT_COM_UART_RECEIPTFAIL, BIT_FAIL);
225  } else {
226  //Xsum passed, go parse it.
227  // We have pstData->m_MsgID to parse off of, pstData->m_pstData->m_Payload as the data.
228  bUpdate = CHIMU_ProcessMessage(&pstData->m_MsgID, pstData->m_Payload, pstData);
229  }
231  break;
232  default:
234  } /* End of SWITCH */
235  return (bUpdate);
236 }
237 
238 
240 // Process CHIMU sentence - Use the CHIMU address (*pCommand) and call the
241 // appropriate sentence data processor.
243 
245 {
247  ps = attitude;
248  float x, sqw,sqx,sqy,sqz,norm;
249  sqw = ps.q.s * ps.q.s;
250  sqx = ps.q.v.x * ps.q.v.x;
251  sqy = ps.q.v.y * ps.q.v.y;
252  sqz = ps.q.v.z * ps.q.v.z;
253  norm = sqrt(sqw + sqx + sqy + sqz);
254  //Normalize the quat
255  ps.q.s = ps.q.s / norm;
256  ps.q.v.x = ps.q.v.x / norm;
257  ps.q.v.y = ps.q.v.y / norm;
258  ps.q.v.z = ps.q.v.z / norm;
259  ps.euler.phi =atan2(2.0 * (ps.q.s * ps.q.v.x + ps.q.v.y * ps.q.v.z), (1 - 2 * (sqx + sqy)));
260  if (ps.euler.phi < 0) ps.euler.phi = ps.euler.phi + 2 *M_PI;
261  x = ((2.0 * (ps.q.s * ps.q.v.y - ps.q.v.z * ps.q.v.x)));
262  //Below needed in event normalization not done
263  if (x > 1.0) x = 1.0;
264  if (x < -1.0) x = -1.0;
265  //
266  if ((ps.q.v.x * ps.q.v.y + ps.q.v.z * ps.q.s) == 0.5) {
267  ps.euler.theta = 2 *atan2(ps.q.v.x, ps.q.s);
268  }
269  else
270  if ((ps.q.v.x * ps.q.v.y + ps.q.v.z * ps.q.s) == -0.5) {
271  ps.euler.theta = -2 *atan2(ps.q.v.x, ps.q.s);
272  }
273  else{
274  ps.euler.theta = asin(x);
275  }
276  ps.euler.psi = atan2(2.0 * (ps.q.s * ps.q.v.z + ps.q.v.x * ps.q.v.y), (1 - 2 * (sqy + sqz)));
277  if (ps.euler.psi < 0) {
278  ps.euler.psi = ps.euler.psi + (2 * M_PI);
279  }
280 
281  return(ps);
282 
283 }
284 
285 static unsigned char BitTest (unsigned char input, unsigned char n)
286 {
287  //Test a bit in n and return TRUE or FALSE
288  if ( input & (1 << n)) return TRUE; else return FALSE;
289 }
290 unsigned char CHIMU_ProcessMessage(unsigned char *pMsgID, unsigned char *pPayloadData, CHIMU_PARSER_DATA *pstData)
291 {
292  //Msgs from CHIMU are off limits (i.e.any CHIMU messages sent up the uplink should go to
293  //CHIMU).
294 
295  //Any CHIMU messages coming from the ground should be ignored, as that byte stream goes up to CHIMU
296  // by itself. However, here we should decode CHIMU messages being received and
297  // a) pass them down to ground
298  // b) grab the data from the CHIMU for our own needs / purposes
299  int CHIMU_index =0;
300  float sanity_check=0.0;
301 
302  switch (pstData->m_MsgID){
303  case CHIMU_Msg_0_Ping:
304  CHIMU_index = 0;
305  pstData->gCHIMU_SW_Exclaim = pPayloadData[CHIMU_index]; CHIMU_index++;
306  pstData->gCHIMU_SW_Major = pPayloadData[CHIMU_index]; CHIMU_index++;
307  pstData->gCHIMU_SW_Minor = pPayloadData[CHIMU_index]; CHIMU_index++;
308  pstData->gCHIMU_SW_SerialNumber = (pPayloadData[CHIMU_index]<<8) & (0x0000FF00); CHIMU_index++;
309  pstData->gCHIMU_SW_SerialNumber += pPayloadData[CHIMU_index]; CHIMU_index++;
310 
311  return TRUE;
312  break;
313  case CHIMU_Msg_1_IMU_Raw:
314  break;
315  case CHIMU_Msg_2_IMU_FP:
316  CHIMU_index = 0;
317  memmove (&pstData->m_sensor.cputemp, &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.cputemp));CHIMU_index += (sizeof(pstData->m_sensor.cputemp));
318  pstData->m_sensor.cputemp = FloatSwap(pstData->m_sensor.cputemp);
319  memmove (&pstData->m_sensor.acc[0], &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.acc));CHIMU_index += (sizeof(pstData->m_sensor.acc));
320  pstData->m_sensor.acc[0] = FloatSwap(pstData->m_sensor.acc[0]);
321  pstData->m_sensor.acc[1] = FloatSwap(pstData->m_sensor.acc[1]);
322  pstData->m_sensor.acc[2] = FloatSwap(pstData->m_sensor.acc[2]);
323  memmove (&pstData->m_sensor.rate[0], &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.rate));CHIMU_index += (sizeof(pstData->m_sensor.rate));
324  pstData->m_sensor.rate[0] = FloatSwap(pstData->m_sensor.rate[0]);
325  pstData->m_sensor.rate[1] = FloatSwap(pstData->m_sensor.rate[1]);
326  pstData->m_sensor.rate[2] = FloatSwap(pstData->m_sensor.rate[2]);
327  memmove (&pstData->m_sensor.mag[0], &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.mag));CHIMU_index += (sizeof(pstData->m_sensor.mag));
328  pstData->m_sensor.mag[0] = FloatSwap(pstData->m_sensor.mag[0]);
329  pstData->m_sensor.mag[1] = FloatSwap(pstData->m_sensor.mag[1]);
330  pstData->m_sensor.mag[2] = FloatSwap(pstData->m_sensor.mag[2]);
331  memmove (&pstData->m_sensor.spare1, &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.spare1));CHIMU_index += (sizeof(pstData->m_sensor.spare1));
332  pstData->m_sensor.spare1 = FloatSwap(pstData->m_sensor.spare1);
333  return TRUE;
334  break;
336  //Attitude message data from CHIMU
337  // Includes attitude and rates only, along with configuration bits
338  // All you need for control
339 
340  //Led_On(LED_RED);
341 
342  CHIMU_index = 0;
343  memmove (&pstData->m_attitude.euler, &pPayloadData[CHIMU_index], sizeof(pstData->m_attitude.euler));CHIMU_index += sizeof(pstData->m_attitude.euler);
344  pstData->m_attitude.euler.phi = FloatSwap(pstData->m_attitude.euler.phi);
345  pstData->m_attitude.euler.theta = FloatSwap(pstData->m_attitude.euler.theta);
346  pstData->m_attitude.euler.psi = FloatSwap(pstData->m_attitude.euler.psi);
347  memmove (&pstData->m_sensor.rate[0], &pPayloadData[CHIMU_index], sizeof(pstData->m_sensor.rate)); CHIMU_index += (sizeof(pstData->m_sensor.rate));
348  pstData->m_sensor.rate[0] = FloatSwap(pstData->m_sensor.rate[0]);
349  pstData->m_sensor.rate[1] = FloatSwap(pstData->m_sensor.rate[1]);
350  pstData->m_sensor.rate[2] = FloatSwap(pstData->m_sensor.rate[2]);
351 
352  memmove (&pstData->m_attitude.q, &pPayloadData[CHIMU_index], sizeof(pstData->m_attitude.q));CHIMU_index += sizeof(pstData->m_attitude.q);
353  pstData->m_attitude.q.s = FloatSwap(pstData->m_attitude.q.s);
354  pstData->m_attitude.q.v.x = FloatSwap(pstData->m_attitude.q.v.x);
355  pstData->m_attitude.q.v.y = FloatSwap(pstData->m_attitude.q.v.y);
356  pstData->m_attitude.q.v.z = FloatSwap(pstData->m_attitude.q.v.z);
357 
358  memmove (&pstData->m_attrates.q, &pPayloadData[CHIMU_index], sizeof(pstData->m_attrates.q));CHIMU_index += sizeof(pstData->m_attitude.q);
359  pstData->m_attrates.q.s = FloatSwap(pstData->m_attrates.q.s);
360  pstData->m_attrates.q.v.x = FloatSwap(pstData->m_attrates.q.v.x);
361  pstData->m_attrates.q.v.y = FloatSwap(pstData->m_attrates.q.v.y);
362  pstData->m_attrates.q.v.z = FloatSwap(pstData->m_attrates.q.v.z);
363 
364  //Now put the rates into the Euler section as well. User can use pstData->m_attitude and pstData->m_attrates structures for control
365  pstData->m_attrates.euler.phi = pstData->m_sensor.rate[0];
366  pstData->m_attrates.euler.theta = pstData->m_sensor.rate[1];
367  pstData->m_attrates.euler.psi = pstData->m_sensor.rate[2];
368 
369  pstData->gCalStatus = pPayloadData[CHIMU_index]; CHIMU_index ++;
370  pstData->gCHIMU_BIT = pPayloadData[CHIMU_index]; CHIMU_index ++;
371  pstData->gConfigInfo = pPayloadData[CHIMU_index]; CHIMU_index ++;
372 
373  // TODO: Read configuration bits
374 
375  /* bC0_SPI_En = BitTest (gConfigInfo, 0);
376  bC1_HWCentrip_En = BitTest (gConfigInfo, 1);
377  bC2_TempCal_En = BitTest (gConfigInfo, 2);
378  bC3_RateOut_En = BitTest (gConfigInfo, 3);
379  bC4_TBD = BitTest (gConfigInfo, 4);
380  bC5_Quat_Est = BitTest (gConfigInfo, 5);
381  bC6_SWCentrip_En = BitTest (gConfigInfo, 6);
382  bC7_AllowHW_Override = BitTest (gConfigInfo, 7);
383  */
384  //CHIMU currently (v 1.3) does not compute Eulers if quaternion estimator is selected
385  if(BitTest (pstData->gConfigInfo, 5) == TRUE)
386  {
387  pstData->m_attitude = GetEulersFromQuat((pstData->m_attitude));
388  }
389 
390  //NEW: Checks for bad attitude data (bad SPI maybe?)
391  // Only allow globals to contain updated data if it makes sense
392  sanity_check = (pstData->m_attitude.q.s * pstData->m_attitude.q.s);
393  sanity_check += (pstData->m_attitude.q.v.x * pstData->m_attitude.q.v.x);
394  sanity_check += (pstData->m_attitude.q.v.y * pstData->m_attitude.q.v.y);
395  sanity_check += (pstData->m_attitude.q.v.z * pstData->m_attitude.q.v.z);
396 
397  //Should be 1.0 (normalized quaternion)
398  if ((sanity_check > 0.8) && (sanity_check < 1.2)) {
399  // gAttitude = pstData->m_attitude;
400  // gAttRates = pstData->m_attrates;
401  // gSensor = pstData->m_sensor;
402  } else {
403  //TODO: Log BIT that indicates IMU message incoming failed (maybe SPI error?)
404  }
405 
406  return TRUE;
407  break;
408  case CHIMU_Msg_4_BiasSF:
409  case CHIMU_Msg_5_BIT:
410  case CHIMU_Msg_6_MagCal:
412  case CHIMU_Msg_8_TempCal:
414  case CHIMU_Msg_10_Res:
415  case CHIMU_Msg_11_Res:
416  case CHIMU_Msg_12_Res:
417  case CHIMU_Msg_13_Res:
420  break;
421  default:
422  return FALSE;
423  break;
424  }
425  return FALSE;
426 }
static unsigned long UpdateCRC(unsigned long CRC_acc, void *data, unsigned long data_len)
Definition: imu_chimu.c:50
#define CHIMU_RX_BUFFERSIZE
Definition: imu_chimu.h:155
#define FloatSwap(X)
Definition: imu_chimu.h:113
#define POLY
#define CHIMU_Msg_1_IMU_Raw
Definition: imu_chimu.h:72
#define CHIMU_Msg_3_IMU_Attitude
Definition: imu_chimu.h:74
#define CHIMU_Msg_15_SFCheck
Definition: imu_chimu.h:86
unsigned char m_State
Definition: imu_chimu.h:158
#define CHIMU_Msg_4_BiasSF
Definition: imu_chimu.h:75
CHIMU_Euler euler
Definition: imu_chimu.h:136
#define CHIMU_Msg_14_RefVector
Definition: imu_chimu.h:85
#define CHIMU_STATE_MACHINE_START
Definition: imu_chimu.c:94
#define CHIMU_Msg_13_Res
Definition: imu_chimu.h:84
unsigned char m_Payload[CHIMU_RX_BUFFERSIZE]
Definition: imu_chimu.h:167
unsigned char m_ReceivedChecksum
Definition: imu_chimu.h:160
CHIMU_sensor_data m_sensor
Definition: imu_chimu.h:171
#define CHIMU_Msg_12_Res
Definition: imu_chimu.h:83
unsigned char m_FullMessage[CHIMU_RX_BUFFERSIZE]
Definition: imu_chimu.h:168
#define CHIMU_Msg_7_GyroBias
Definition: imu_chimu.h:78
void CHIMU_Checksum(unsigned char *data, unsigned char buflen)
Definition: imu_chimu.c:83
#define CHIMU_Msg_11_Res
Definition: imu_chimu.h:82
static CHIMU_attitude_data GetEulersFromQuat(CHIMU_attitude_data attitude)
Definition: imu_chimu.c:244
#define FALSE
Definition: imu_chimu.h:141
static unsigned char BitTest(unsigned char input, unsigned char n)
Definition: imu_chimu.c:285
CHIMU_Quaternion q
Definition: imu_chimu.h:137
unsigned char CHIMU_ProcessMessage(unsigned char *pMsgID, unsigned char *pPayloadData, CHIMU_PARSER_DATA *pstData)
Definition: imu_chimu.c:290
CHIMU_attitude_data m_attrates
Definition: imu_chimu.h:170
#define CHIMU_Msg_10_Res
Definition: imu_chimu.h:81
uint8_t gConfigInfo
Definition: imu_chimu.h:182
uint16_t gCHIMU_SW_SerialNumber
Definition: imu_chimu.h:177
unsigned char m_TempDeviceID
Definition: imu_chimu.h:165
void CHIMU_Init(CHIMU_PARSER_DATA *pstData)
Definition: imu_chimu.c:109
#define CHIMU_Msg_8_TempCal
Definition: imu_chimu.h:79
#define CHIMU_COM_ID_HIGH
Definition: imu_chimu.c:103
unsigned char CHIMU_Parse(unsigned char btData, unsigned char bInputType, CHIMU_PARSER_DATA *pstData)
Definition: imu_chimu.c:150
uint8_t gCHIMU_SW_Major
Definition: imu_chimu.h:175
CHIMU_attitude_data m_attitude
Definition: imu_chimu.h:169
#define CHIMU_Msg_9_DAC_Offsets
Definition: imu_chimu.h:80
float phi
Definition: imu_chimu.h:119
#define CHIMU_STATE_MACHINE_DEVICE
Definition: imu_chimu.c:97
#define CHIMU_STATE_MACHINE_PAYLOAD
Definition: imu_chimu.c:99
#define TRUE
Definition: imu_chimu.h:144
#define CHIMU_STATE_MACHINE_LEN
Definition: imu_chimu.c:96
unsigned char m_PayloadIndex
Definition: imu_chimu.h:162
CHIMU_Vector v
Definition: imu_chimu.h:132
unsigned char m_Index
Definition: imu_chimu.h:161
#define CHIMU_STATE_MACHINE_HEADER2
Definition: imu_chimu.c:95
#define CHIMU_Msg_5_BIT
Definition: imu_chimu.h:76
#define CHIMU_STATE_MACHINE_ID
Definition: imu_chimu.c:98
uint8_t gCHIMU_BIT
Definition: imu_chimu.h:181
float psi
Definition: imu_chimu.h:121
unsigned char m_Checksum
Definition: imu_chimu.h:159
float theta
Definition: imu_chimu.h:120
unsigned char m_MsgLen
Definition: imu_chimu.h:164
uint8_t gCalStatus
Definition: imu_chimu.h:180
#define CHIMU_STATE_MACHINE_XSUM
Definition: imu_chimu.c:100
uint8_t gCHIMU_SW_Exclaim
Definition: imu_chimu.h:174
#define CHIMU_Msg_0_Ping
Definition: imu_chimu.h:71
unsigned char m_DeviceID
Definition: imu_chimu.h:166
unsigned char m_MsgID
Definition: imu_chimu.h:163
#define CHIMU_Msg_6_MagCal
Definition: imu_chimu.h:77
uint8_t gCHIMU_SW_Minor
Definition: imu_chimu.h:176
#define CHIMU_Msg_2_IMU_FP
Definition: imu_chimu.h:73