SELKIELogger  1.0.0
LPMSMessages.c
1 /*
2  * Copyright (C) 2023 Swansea University
3  *
4  * This file is part of the SELKIELogger suite of tools.
5  *
6  * SELKIELogger is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * SELKIELogger is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this SELKIELogger product.
18  * If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "LPMSMessages.h"
27 #include "LPMSTypes.h"
28 
29 #include <assert.h>
30 
42 bool lpms_from_bytes(const uint8_t *in, const size_t len, lpms_message *msg, size_t *pos) {
43  if (in == NULL || msg == NULL || len < 10 || pos == NULL) { return NULL; }
44 
45  ssize_t start = -1;
46  while (((*pos) + 10) < len) {
47  if ((in[(*pos)] == LPMS_START)) {
48  start = (*pos);
49  break;
50  }
51  (*pos)++;
52  }
53 
54  if (start < 0) {
55  // Nothing found, so bail early
56  // (*pos) marks the end of the searched data
57  return false;
58  }
59 
60  msg->id = in[start + 1] + ((uint16_t)in[start + 2] << 8);
61  msg->command = in[start + 3] + ((uint16_t)in[start + 4] << 8);
62  msg->length = in[start + 5] + ((uint16_t)in[start + 6] << 8);
63 
64  if (msg->length == 0) {
65  msg->data = NULL;
66  } else {
67  // Check there's enough bytes in buffer to cover message header
68  // (6 bytes), footer (4 bytes), and embedded data
69  if ((len - start - 10) < msg->length) {
70  msg->id = 0xFF;
71  return false;
72  }
73  msg->data = calloc(msg->length, sizeof(uint8_t));
74  if (msg->data == NULL) {
75  msg->id = 0xAA;
76  return false;
77  }
78 
79  (*pos) += 7; // Move (*pos) up now we know we can read data in
80  for (int i = 0; i < msg->length; i++) {
81  msg->data[i] = in[(*pos)++];
82  }
83  }
84  msg->checksum = in[(*pos)] + ((uint16_t)in[(*pos) + 1] << 8);
85  (*pos) += 2;
86  if ((in[(*pos)] != LPMS_END1) || (in[(*pos) + 1] != LPMS_END2)) {
87  msg->id = 0xEE;
88  return false;
89  }
90  (*pos) += 2;
91  return true;
92 }
93 
104 bool lpms_to_bytes(const lpms_message *msg, uint8_t **out, size_t *len) {
105  if ((msg == NULL) || (out == NULL)) { return false; }
106  (*len) = msg->length + 11;
107  (*out) = calloc((*len), sizeof(uint8_t));
108  if ((*out) == NULL) {
109  perror("lpms_to_bytes");
110  return false;
111  }
112  (*out)[0] = LPMS_START;
113  (*out)[1] = (msg->id & 0x00FF);
114  (*out)[2] = (msg->id & 0xFF00) >> 8;
115  (*out)[3] = (msg->command & 0x00FF);
116  (*out)[4] = (msg->command & 0xFF00) >> 8;
117  (*out)[5] = (msg->length & 0x00FF);
118  (*out)[6] = (msg->length & 0xFF00) >> 8;
119  size_t p = 7;
120  for (int j = 0; j < msg->length; j++) {
121  (*out)[p++] = msg->data[j];
122  }
123  (*out)[p++] = (msg->checksum & 0x00FF);
124  (*out)[p++] = (msg->checksum & 0xFF00) >> 8;
125  (*out)[p++] = LPMS_END1;
126  (*out)[p++] = LPMS_END2;
127  return (p == (*len));
128 }
129 
135 bool lpms_checksum(const lpms_message *msg, uint16_t *csum) {
136  if (msg == NULL || csum == NULL) { return false; }
137  uint16_t cs = 0;
138  cs += (msg->id & 0x00FF);
139  cs += (msg->id & 0xFF00) >> 8;
140  cs += (msg->command & 0x00FF);
141  cs += (msg->command & 0xFF00) >> 8;
142  cs += (msg->length & 0x00FF);
143  cs += (msg->length & 0xFF00) >> 8;
144  if (msg->length > 0) {
145  if (msg->data == NULL) { return false; }
146  for (int i = 0; i < msg->length; ++i) {
147  cs += msg->data[i];
148  }
149  }
150  (*csum) = cs;
151  return true;
152 }
153 
162  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
163  if (msg->length < 4) { return false; }
164 
165  d->timestamp = msg->data[0] + ((uint32_t)msg->data[1] << 8) + ((uint32_t)msg->data[2] << 16) +
166  ((uint32_t)msg->data[3] << 24);
167  return true;
168 }
169 
179  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
180  if (!LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { return false; }
181  size_t ix = 4;
182  memcpy(d->accel_raw, &(msg->data[ix]), 12);
183  return true;
184 }
185 
195  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
196  if (!LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { return false; }
197 
198  // Skip timestamp (data[0..3]), then skip any other data present
199  size_t ix = 4;
200  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
201  if (msg->length < (ix + 12)) { return false; }
202  memcpy(d->accel_cal, &(msg->data[ix]), 12);
203  return true;
204 }
205 
215  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
216  if (!LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { return false; }
217 
218  // Skip timestamp (data[0..3]), then skip any other data present
219  size_t ix = 4;
220  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
221  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
222  if (msg->length < (ix + 12)) { return false; }
223  memcpy(d->gyro_raw, &(msg->data[ix]), 12);
224  return true;
225 }
226 
236  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
237  if (!LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { return false; }
238 
239  // Skip timestamp (data[0..3]), then skip any other data present
240  size_t ix = 4;
241  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
242  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
243  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
244  if (msg->length < (ix + 12)) { return false; }
245 
246  memcpy(d->gyro_cal, &(msg->data[ix]), 12);
247  return true;
248 }
249 
259  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
260  if (!LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { return false; }
261 
262  size_t ix = 4;
263  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
264  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
265  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
266  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
267  if (msg->length < (ix + 12)) { return false; }
268 
269  memcpy(d->gyro_aligned, &(msg->data[ix]), 12);
270  return true;
271 }
272 
282  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
283  if (!LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { return false; }
284 
285  size_t ix = 4;
286  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
287  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
288  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
289  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
290  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
291  if (msg->length < (ix + 12)) { return false; }
292 
293  memcpy(d->mag_raw, &(msg->data[ix]), 12);
294  return true;
295 }
296 
306  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
307  if (!LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { return false; }
308 
309  size_t ix = 4;
310  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
311  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
312  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
313  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
314  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
315  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
316  if (msg->length < (ix + 12)) { return false; }
317 
318  memcpy(d->mag_cal, &(msg->data[ix]), 12);
319  return true;
320 }
321 
331  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
332  if (!LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { return false; }
333 
334  size_t ix = 4;
335  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
336  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
337  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
338  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
339  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
340  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
341  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
342  if (msg->length < (ix + 12)) { return false; }
343 
344  memcpy(d->omega, &(msg->data[ix]), 12);
345  return true;
346 }
347 
357  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
358  if (!LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { return false; }
359 
360  size_t ix = 4;
361  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
362  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
363  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
364  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
365  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
366  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
367  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
368  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
369  if (msg->length < (ix + 16)) { return false; }
370 
371  memcpy(d->quaternion, &(msg->data[ix]), 16);
372  return true;
373 }
374 
384  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
385  if (!LPMS_HAS(d->present, LPMS_IMU_EULER)) { return false; }
386 
387  size_t ix = 4;
388  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
389  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
390  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
391  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
392  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
393  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
394  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
395  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
396  if (LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { ix += 16; }
397  if (msg->length < (ix + 12)) { return false; }
398 
399  memcpy(d->euler_angles, &(msg->data[ix]), 12);
400  return true;
401 }
402 
412  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
413  if (!LPMS_HAS(d->present, LPMS_IMU_ACCEL_LINEAR)) { return false; }
414 
415  size_t ix = 4;
416  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
417  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
418  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
419  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
420  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
421  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
422  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
423  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
424  if (LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { ix += 16; }
425  if (LPMS_HAS(d->present, LPMS_IMU_EULER)) { ix += 12; }
426  if (msg->length < (ix + 12)) { return false; }
427 
428  memcpy(d->accel_linear, &(msg->data[ix]), 12);
429  return true;
430 }
431 
441  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
442  if (!LPMS_HAS(d->present, LPMS_IMU_PRESSURE)) { return false; }
443 
444  size_t ix = 4;
445  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
446  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
447  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
448  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
449  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
450  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
451  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
452  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
453  if (LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { ix += 16; }
454  if (LPMS_HAS(d->present, LPMS_IMU_EULER)) { ix += 12; }
455  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_LINEAR)) { ix += 12; }
456  if (msg->length < (ix + 4)) { return false; }
457 
458  memcpy(&(d->pressure), &(msg->data[ix]), 4);
459  return true;
460 }
461 
471  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
472  if (!LPMS_HAS(d->present, LPMS_IMU_ALTITUDE)) { return false; }
473 
474  size_t ix = 4;
475  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
476  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
477  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
478  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
479  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
480  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
481  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
482  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
483  if (LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { ix += 16; }
484  if (LPMS_HAS(d->present, LPMS_IMU_EULER)) { ix += 12; }
485  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_LINEAR)) { ix += 12; }
486  if (LPMS_HAS(d->present, LPMS_IMU_PRESSURE)) { ix += 4; }
487  if (msg->length < (ix + 4)) { return false; }
488 
489  memcpy(&(d->altitude), &(msg->data[ix]), 4);
490  return true;
491 }
492 
502  if (!msg || !d || msg->command != LPMS_MSG_GET_IMUDATA) { return false; }
503  if (!LPMS_HAS(d->present, LPMS_IMU_TEMPERATURE)) { return false; }
504 
505  size_t ix = 4;
506  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_RAW)) { ix += 12; }
507  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_CAL)) { ix += 12; }
508  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_RAW)) { ix += 12; }
509  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_CAL)) { ix += 12; }
510  if (LPMS_HAS(d->present, LPMS_IMU_GYRO_ALIGN)) { ix += 12; }
511  if (LPMS_HAS(d->present, LPMS_IMU_MAG_RAW)) { ix += 12; }
512  if (LPMS_HAS(d->present, LPMS_IMU_MAG_CAL)) { ix += 12; }
513  if (LPMS_HAS(d->present, LPMS_IMU_OMEGA)) { ix += 12; }
514  if (LPMS_HAS(d->present, LPMS_IMU_QUATERNION)) { ix += 16; }
515  if (LPMS_HAS(d->present, LPMS_IMU_EULER)) { ix += 12; }
516  if (LPMS_HAS(d->present, LPMS_IMU_ACCEL_LINEAR)) { ix += 12; }
517  if (LPMS_HAS(d->present, LPMS_IMU_PRESSURE)) { ix += 4; }
518  if (LPMS_HAS(d->present, LPMS_IMU_ALTITUDE)) { ix += 4; }
519  if (msg->length < (ix + 4)) { return false; }
520 
521  memcpy(&(d->temperature), &(msg->data[ix]), 4);
522  return true;
523 }
bool lpms_imu_set_temperature(const lpms_message *msg, lpms_data *d)
Extract temperature from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:501
bool lpms_checksum(const lpms_message *msg, uint16_t *csum)
Calculate checksum for LPMS message packet.
Definition: LPMSMessages.c:135
bool lpms_imu_set_gyro_aligned(const lpms_message *msg, lpms_data *d)
Extract gyro_aligned from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:258
#define LPMS_START
Message prefix byte.
Definition: LPMSMessages.h:37
bool lpms_imu_set_mag_cal(const lpms_message *msg, lpms_data *d)
Extract mag_cal from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:305
bool lpms_imu_set_altitude(const lpms_message *msg, lpms_data *d)
Extract altitude from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:470
bool lpms_imu_set_euler_angles(const lpms_message *msg, lpms_data *d)
Extract euler_angles from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:383
#define LPMS_END2
Second message suffix byte.
Definition: LPMSMessages.h:39
bool lpms_to_bytes(const lpms_message *msg, uint8_t **out, size_t *len)
Convert message structure to flat array.
Definition: LPMSMessages.c:104
bool lpms_imu_set_gyro_raw(const lpms_message *msg, lpms_data *d)
Extract gyro_raw from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:214
bool lpms_imu_set_quaternion(const lpms_message *msg, lpms_data *d)
Extract quaternion from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:356
#define LPMS_END1
First message suffix byte.
Definition: LPMSMessages.h:38
bool lpms_imu_set_accel_raw(const lpms_message *msg, lpms_data *d)
Extract accel_raw from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:178
bool lpms_imu_set_timestamp(const lpms_message *msg, lpms_data *d)
Extract timestamp from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:161
bool lpms_imu_set_accel_cal(const lpms_message *msg, lpms_data *d)
Extract accel_cal from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:194
bool lpms_imu_set_pressure(const lpms_message *msg, lpms_data *d)
Extract pressure from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:440
bool lpms_imu_set_mag_raw(const lpms_message *msg, lpms_data *d)
Extract mag_raw from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:281
bool lpms_imu_set_gyro_cal(const lpms_message *msg, lpms_data *d)
Extract gyro_cal from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:235
bool lpms_from_bytes(const uint8_t *in, const size_t len, lpms_message *msg, size_t *pos)
Read bytes and populate message structure.
Definition: LPMSMessages.c:42
bool lpms_imu_set_accel_linear(const lpms_message *msg, lpms_data *d)
Extract accel_linear from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:411
bool lpms_imu_set_omega(const lpms_message *msg, lpms_data *d)
Extract omega from lpms_message into lpms_data, if available.
Definition: LPMSMessages.c:330
#define LPMS_IMU_MAG_RAW
mag_raw[] will contain data
Definition: LPMSTypes.h:105
#define LPMS_IMU_EULER
euler[] will contain data
Definition: LPMSTypes.h:109
#define LPMS_IMU_ACCEL_LINEAR
accel_linear[] will contain data
Definition: LPMSTypes.h:110
#define LPMS_IMU_OMEGA
omega[] will contain data
Definition: LPMSTypes.h:107
#define LPMS_IMU_ACCEL_CAL
accel_cal[] will contain data
Definition: LPMSTypes.h:101
#define LPMS_IMU_PRESSURE
pressure will contain data
Definition: LPMSTypes.h:111
#define LPMS_IMU_QUATERNION
quaternion[] will contain data
Definition: LPMSTypes.h:108
#define LPMS_IMU_MAG_CAL
mag_cal[] will contain data
Definition: LPMSTypes.h:106
#define LPMS_IMU_GYRO_ALIGN
gyro_align[] will contain data
Definition: LPMSTypes.h:104
#define LPMS_IMU_TEMPERATURE
temperature will contain data
Definition: LPMSTypes.h:113
#define LPMS_IMU_ALTITUDE
altitude will contain data
Definition: LPMSTypes.h:112
#define LPMS_HAS(x, y)
Definition: LPMSTypes.h:115
#define LPMS_IMU_GYRO_CAL
gyro_cal[] will contain data
Definition: LPMSTypes.h:103
#define LPMS_IMU_GYRO_RAW
gyro_raw[] will contain data
Definition: LPMSTypes.h:102
#define LPMS_IMU_ACCEL_RAW
accel_raw[] will contain data
Definition: LPMSTypes.h:100
#define LPMS_MSG_GET_IMUDATA
IMU data, as configured by LPMS_MSG_SET_OUTPUTS.
Definition: LPMSMessages.h:58
LPMS IMU data packet.
Definition: LPMSTypes.h:72
float euler_angles[3]
Orientation as Euler roll angles [X].
Definition: LPMSTypes.h:83
float altitude
Altitude [m].
Definition: LPMSTypes.h:86
float temperature
Temperature [Celsius].
Definition: LPMSTypes.h:87
float gyro_aligned[3]
Calibrated and aligned gyroscope values [X/s].
Definition: LPMSTypes.h:78
float mag_cal[3]
Calibrated magnetometer values [uT].
Definition: LPMSTypes.h:80
float gyro_raw[3]
Raw gyroscope values [X/s].
Definition: LPMSTypes.h:76
float accel_linear[3]
Linear acceleration (only) [g].
Definition: LPMSTypes.h:84
uint32_t timestamp
Counted in 0.002s increments.
Definition: LPMSTypes.h:73
float accel_cal[3]
Calibrated accelerometer values [g].
Definition: LPMSTypes.h:75
float gyro_cal[3]
Calibrated gyroscope values [X/s].
Definition: LPMSTypes.h:77
float mag_raw[3]
Raw magnetometer values [uT].
Definition: LPMSTypes.h:79
float quaternion[4]
Orientation in quaternion form.
Definition: LPMSTypes.h:82
float accel_raw[3]
Raw accelerometer values [g].
Definition: LPMSTypes.h:74
float omega[3]
Angular velocity [X/s].
Definition: LPMSTypes.h:81
uint32_t present
Bitmask indicating set/valid members.
Definition: LPMSTypes.h:88
float pressure
Atmospheric pressure [kPa].
Definition: LPMSTypes.h:85
Represent LPMS message.
Definition: LPMSTypes.h:48
uint16_t length
Length of data, in bytes.
Definition: LPMSTypes.h:51
uint16_t checksum
Sum of all preceding message bytes.
Definition: LPMSTypes.h:52
uint8_t * data
Pointer to data array.
Definition: LPMSTypes.h:53
uint16_t id
Source/Destination Sensor ID.
Definition: LPMSTypes.h:49
uint16_t command
Message type.
Definition: LPMSTypes.h:50