diff --git a/c/include/libsbp/cpp/message_traits.h b/c/include/libsbp/cpp/message_traits.h index dbe88518b1..85a3d2d97b 100644 --- a/c/include/libsbp/cpp/message_traits.h +++ b/c/include/libsbp/cpp/message_traits.h @@ -3527,6 +3527,39 @@ struct MessageTraits { } }; +template <> +struct MessageTraits { + static constexpr sbp_msg_type_t id = SbpMsgImuComp; + static constexpr const char *name = "MSG_IMU_COMP"; + static const sbp_msg_imu_comp_t &get(const sbp_msg_t &msg) { + return msg.imu_comp; + } + static sbp_msg_imu_comp_t &get(sbp_msg_t &msg) { return msg.imu_comp; } + static void to_sbp_msg(const sbp_msg_imu_comp_t &msg, sbp_msg_t *sbp_msg) { + sbp_msg->imu_comp = msg; + } + static sbp_msg_t to_sbp_msg(const sbp_msg_imu_comp_t &msg) { + sbp_msg_t sbp_msg; + sbp_msg.imu_comp = msg; + return sbp_msg; + } + static s8 send(sbp_state_t *state, u16 sender_id, + const sbp_msg_imu_comp_t &msg, sbp_write_fn_t write) { + return sbp_msg_imu_comp_send(state, sender_id, &msg, write); + } + static s8 encode(uint8_t *buf, uint8_t len, uint8_t *n_written, + const sbp_msg_imu_comp_t &msg) { + return sbp_msg_imu_comp_encode(buf, len, n_written, &msg); + } + static s8 decode(const uint8_t *buf, uint8_t len, uint8_t *n_read, + sbp_msg_imu_comp_t *msg) { + return sbp_msg_imu_comp_decode(buf, len, n_read, msg); + } + static size_t encoded_len(const sbp_msg_imu_comp_t &msg) { + return sbp_msg_imu_comp_encoded_len(&msg); + } +}; + template <> struct MessageTraits { static constexpr sbp_msg_type_t id = SbpMsgImuRaw; diff --git a/c/include/libsbp/imu.h b/c/include/libsbp/imu.h index 56a867b9b4..ccb7f849a4 100644 --- a/c/include/libsbp/imu.h +++ b/c/include/libsbp/imu.h @@ -18,6 +18,7 @@ #ifndef LIBSBP_IMU_MESSAGES_H #define LIBSBP_IMU_MESSAGES_H #include +#include #include #endif /* LIBSBP_IMU_MESSAGES_H */ diff --git a/c/include/libsbp/imu/MSG_IMU_COMP.h b/c/include/libsbp/imu/MSG_IMU_COMP.h new file mode 100644 index 0000000000..7cee9ad134 --- /dev/null +++ b/c/include/libsbp/imu/MSG_IMU_COMP.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015-2021 Swift Navigation Inc. + * Contact: https://support.swiftnav.com + * + * This source is subject to the license found in the file 'LICENSE' which must + * be distributed together with this source. All other rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + */ + +/***************************************************************************** + * Automatically generated from yaml/swiftnav/sbp/imu.yaml + * with generate.py. Please do not hand edit! + *****************************************************************************/ + +#ifndef LIBSBP_IMU_MSG_IMU_COMP_H +#define LIBSBP_IMU_MSG_IMU_COMP_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * + * SBP_MSG_IMU_COMP + * + *****************************************************************************/ +/** Compensated IMU data + * + * Data from the Inertial Measurement Unit, containing accelerometer and + * gyroscope readings compensated for estimated errors and constant physical + * effects. The output is valid for inertially referenced center of navigation + * (IMU body frame) represented in vehicle body frame. + */ +typedef struct { + /** + * Microseconds since reference epoch [microseconds] + */ + u64 time; + + /** + * Contains the applied compensation parameters and time synchronization mode + */ + u16 flags; + + /** + * Compensated acceleration X axis [1e-6 m/s^2] + */ + s32 acc_comp_x; + + /** + * Compensated acceleration Y axis [1e-6 m/s^2] + */ + s32 acc_comp_y; + + /** + * Compensated acceleration Z axis [1e-6 m/s^2] + */ + s32 acc_comp_z; + + /** + * Compensated angular rate X axis [1e-6 deg/s] + */ + s32 gyr_comp_x; + + /** + * Compensated angular rate Y axis [1e-6 deg/s] + */ + s32 gyr_comp_y; + + /** + * Compensated angular rate Z axis [1e-6 deg/s] + */ + s32 gyr_comp_z; +} sbp_msg_imu_comp_t; + +/** + * Get encoded size of an instance of sbp_msg_imu_comp_t + * + * @param msg sbp_msg_imu_comp_t instance + * @return Length of on-wire representation + */ +static inline size_t sbp_msg_imu_comp_encoded_len( + const sbp_msg_imu_comp_t *msg) { + (void)msg; + return SBP_MSG_IMU_COMP_ENCODED_LEN; +} + +/** + * Encode an instance of sbp_msg_imu_comp_t to wire representation + * + * This function encodes the given instance in to the user provided buffer. The + * buffer provided to this function must be large enough to store the encoded + * message otherwise it will return SBP_ENCODE_ERROR without writing anything to + * the buffer. + * + * Specify the length of the destination buffer in the \p len parameter. If + * non-null the number of bytes written to the buffer will be returned in \p + * n_written. + * + * @param buf Destination buffer + * @param len Length of \p buf + * @param n_written If not null, on success will be set to the number of bytes + * written to \p buf + * @param msg Instance of sbp_msg_imu_comp_t to encode + * @return SBP_OK on success, or other libsbp error code + */ +SBP_EXPORT s8 sbp_msg_imu_comp_encode(uint8_t *buf, uint8_t len, + uint8_t *n_written, + const sbp_msg_imu_comp_t *msg); + +/** + * Decode an instance of sbp_msg_imu_comp_t from wire representation + * + * This function decodes the wire representation of a sbp_msg_imu_comp_t message + * to the given instance. The caller must specify the length of the buffer in + * the \p len parameter. If non-null the number of bytes read from the buffer + * will be returned in \p n_read. + * + * @param buf Wire representation of the sbp_msg_imu_comp_t instance + * @param len Length of \p buf + * @param n_read If not null, on success will be set to the number of bytes read + * from \p buf + * @param msg Destination + * @return SBP_OK on success, or other libsbp error code + */ +SBP_EXPORT s8 sbp_msg_imu_comp_decode(const uint8_t *buf, uint8_t len, + uint8_t *n_read, sbp_msg_imu_comp_t *msg); +/** + * Send an instance of sbp_msg_imu_comp_t with the given write function + * + * An equivalent of #sbp_message_send which operates specifically on + * sbp_msg_imu_comp_t + * + * The given message will be encoded to wire representation and passed in to the + * given write function callback. The write callback will be called several + * times for each invocation of this function. + * + * @param s SBP state + * @param sender_id SBP sender id + * @param msg Message to send + * @param write Write function + * @return SBP_OK on success, or other libsbp error code + */ +SBP_EXPORT s8 sbp_msg_imu_comp_send(sbp_state_t *s, u16 sender_id, + const sbp_msg_imu_comp_t *msg, + sbp_write_fn_t write); + +/** + * Compare two instances of sbp_msg_imu_comp_t + * + * The two instances will be compared and a value returned consistent with the + * return codes of comparison functions from the C standard library + * + * 0 will be returned if \p a and \p b are considered equal + * A value less than 0 will be returned if \p a is considered to be less than \p + * b A value greater than 0 will be returned if \p b is considered to be greater + * than \p b + * + * @param a sbp_msg_imu_comp_t instance + * @param b sbp_msg_imu_comp_t instance + * @return 0, <0, >0 + */ +SBP_EXPORT int sbp_msg_imu_comp_cmp(const sbp_msg_imu_comp_t *a, + const sbp_msg_imu_comp_t *b); + +#ifdef __cplusplus +} + +static inline bool operator==(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) == 0; +} + +static inline bool operator!=(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) != 0; +} + +static inline bool operator<(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) < 0; +} + +static inline bool operator<=(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) <= 0; +} + +static inline bool operator>(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) > 0; +} + +static inline bool operator>=(const sbp_msg_imu_comp_t &lhs, + const sbp_msg_imu_comp_t &rhs) { + return sbp_msg_imu_comp_cmp(&lhs, &rhs) >= 0; +} + +#endif // ifdef __cplusplus + +#endif /* LIBSBP_IMU_MSG_IMU_COMP_H */ diff --git a/c/include/libsbp/imu_macros.h b/c/include/libsbp/imu_macros.h index 134fa546fe..70ba7cd714 100644 --- a/c/include/libsbp/imu_macros.h +++ b/c/include/libsbp/imu_macros.h @@ -129,4 +129,97 @@ */ #define SBP_MSG_IMU_AUX_ENCODED_LEN 4u +#define SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_MASK (0x1u) +#define SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_SHIFT (6u) +#define SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_SHIFT) & \ + SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_MASK)) +#define SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_SET(flags, val) \ + do { \ + (flags) = (u16)( \ + (flags & (~(SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_MASK \ + << SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_MASK)) \ + << (SBP_IMU_COMP_GYROSCOPEERRORSCOMPENSATED_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_MASK (0x1u) +#define SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_SHIFT (5u) +#define SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_SHIFT) & \ + SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_MASK)) +#define SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_SET(flags, val) \ + do { \ + (flags) = (u16)( \ + (flags & (~(SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_MASK \ + << SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_MASK)) \ + << (SBP_IMU_COMP_ACCELEROMETERERRORSCOMPENSATED_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_MASK (0x1u) +#define SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_SHIFT (4u) +#define SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_SHIFT) & \ + SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_MASK)) +#define SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_SET(flags, val) \ + do { \ + (flags) = \ + (u16)((flags & (~(SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_MASK \ + << SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_MASK)) \ + << (SBP_IMU_COMP_CORIOLISEFFECTCOMPENSATED_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_MASK (0x1u) +#define SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_SHIFT (3u) +#define SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_SHIFT) & \ + SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_MASK)) +#define SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_SET(flags, val) \ + do { \ + (flags) = (u16)( \ + (flags & (~(SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_MASK \ + << SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_MASK)) \ + << (SBP_IMU_COMP_EARTHRORATIONRATECOMPENSATED_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_MASK (0x1u) +#define SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_SHIFT (2u) +#define SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_SHIFT) & \ + SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_MASK)) +#define SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_SET(flags, val) \ + do { \ + (flags) = \ + (u16)((flags & (~(SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_MASK \ + << SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_MASK)) \ + << (SBP_IMU_COMP_EARTHGRAVITYCOMPENSATED_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_TIME_STATUS_MASK (0x3u) +#define SBP_IMU_COMP_TIME_STATUS_SHIFT (0u) +#define SBP_IMU_COMP_TIME_STATUS_GET(flags) \ + ((u16)((u16)((flags) >> SBP_IMU_COMP_TIME_STATUS_SHIFT) & \ + SBP_IMU_COMP_TIME_STATUS_MASK)) +#define SBP_IMU_COMP_TIME_STATUS_SET(flags, val) \ + do { \ + (flags) = (u16)((flags & (~(SBP_IMU_COMP_TIME_STATUS_MASK \ + << SBP_IMU_COMP_TIME_STATUS_SHIFT))) | \ + (((val) & (SBP_IMU_COMP_TIME_STATUS_MASK)) \ + << (SBP_IMU_COMP_TIME_STATUS_SHIFT))); \ + } while (0) + +#define SBP_IMU_COMP_TIME_STATUS_REFERENCE_EPOCH_IS_START_OF_CURRENT_GPS_WEEK \ + (0) +#define SBP_IMU_COMP_TIME_STATUS_REFERENCE_EPOCH_IS_TIME_OF_SYSTEM_STARTUP (1) +#define SBP_IMU_COMP_TIME_STATUS_REFERENCE_EPOCH_IS_UNKNOWN (2) +#define SBP_IMU_COMP_TIME_STATUS_REFERENCE_EPOCH_IS_LAST_PPS (3) +/** + * Encoded length of sbp_msg_imu_comp_t + */ +#define SBP_MSG_IMU_COMP_ENCODED_LEN 34u + #endif /* LIBSBP_IMU_MACROS_H */ diff --git a/c/include/libsbp/sbp_msg.h b/c/include/libsbp/sbp_msg.h index c8c510256f..754aeb8e79 100644 --- a/c/include/libsbp/sbp_msg.h +++ b/c/include/libsbp/sbp_msg.h @@ -157,6 +157,7 @@ typedef union { sbp_msg_heartbeat_t heartbeat; sbp_msg_iar_state_t iar_state; sbp_msg_imu_aux_t imu_aux; + sbp_msg_imu_comp_t imu_comp; sbp_msg_imu_raw_t imu_raw; sbp_msg_init_base_dep_t init_base_dep; sbp_msg_ins_status_t ins_status; @@ -587,6 +588,8 @@ static inline s8 sbp_message_encode(uint8_t *buf, uint8_t len, return sbp_msg_iar_state_encode(buf, len, n_written, &msg->iar_state); case SbpMsgImuAux: return sbp_msg_imu_aux_encode(buf, len, n_written, &msg->imu_aux); + case SbpMsgImuComp: + return sbp_msg_imu_comp_encode(buf, len, n_written, &msg->imu_comp); case SbpMsgImuRaw: return sbp_msg_imu_raw_encode(buf, len, n_written, &msg->imu_raw); case SbpMsgInitBaseDep: @@ -1257,6 +1260,8 @@ static inline s8 sbp_message_decode(const uint8_t *buf, uint8_t len, return sbp_msg_iar_state_decode(buf, len, n_read, &msg->iar_state); case SbpMsgImuAux: return sbp_msg_imu_aux_decode(buf, len, n_read, &msg->imu_aux); + case SbpMsgImuComp: + return sbp_msg_imu_comp_decode(buf, len, n_read, &msg->imu_comp); case SbpMsgImuRaw: return sbp_msg_imu_raw_decode(buf, len, n_read, &msg->imu_raw); case SbpMsgInitBaseDep: @@ -1861,6 +1866,8 @@ static inline size_t sbp_message_encoded_len(sbp_msg_type_t msg_type, return sbp_msg_iar_state_encoded_len(&msg->iar_state); case SbpMsgImuAux: return sbp_msg_imu_aux_encoded_len(&msg->imu_aux); + case SbpMsgImuComp: + return sbp_msg_imu_comp_encoded_len(&msg->imu_comp); case SbpMsgImuRaw: return sbp_msg_imu_raw_encoded_len(&msg->imu_raw); case SbpMsgInitBaseDep: @@ -2452,6 +2459,8 @@ static inline int sbp_message_cmp(sbp_msg_type_t msg_type, const sbp_msg_t *a, return sbp_msg_iar_state_cmp(&a->iar_state, &b->iar_state); case SbpMsgImuAux: return sbp_msg_imu_aux_cmp(&a->imu_aux, &b->imu_aux); + case SbpMsgImuComp: + return sbp_msg_imu_comp_cmp(&a->imu_comp, &b->imu_comp); case SbpMsgImuRaw: return sbp_msg_imu_raw_cmp(&a->imu_raw, &b->imu_raw); case SbpMsgInitBaseDep: diff --git a/c/include/libsbp/sbp_msg_type.h b/c/include/libsbp/sbp_msg_type.h index 906bdce08c..a098bfc013 100644 --- a/c/include/libsbp/sbp_msg_type.h +++ b/c/include/libsbp/sbp_msg_type.h @@ -148,6 +148,7 @@ typedef enum { SbpMsgHeartbeat = 0xFFFF, SbpMsgIarState = 0x0019, SbpMsgImuAux = 0x0901, + SbpMsgImuComp = 0x0905, SbpMsgImuRaw = 0x0900, SbpMsgInitBaseDep = 0x0023, SbpMsgInsStatus = 0xFF03, @@ -489,6 +490,8 @@ static inline const char *sbp_msg_type_to_string(sbp_msg_type_t msg_type) { return "MSG_IAR_STATE"; case SbpMsgImuAux: return "MSG_IMU_AUX"; + case SbpMsgImuComp: + return "MSG_IMU_COMP"; case SbpMsgImuRaw: return "MSG_IMU_RAW"; case SbpMsgInitBaseDep: diff --git a/c/src/imu.c b/c/src/imu.c index 95aeed2b82..4610a2d3b2 100644 --- a/c/src/imu.c +++ b/c/src/imu.c @@ -247,3 +247,146 @@ int sbp_msg_imu_aux_cmp(const sbp_msg_imu_aux_t *a, ret = sbp_u8_cmp(&a->imu_conf, &b->imu_conf); return ret; } + +bool sbp_msg_imu_comp_encode_internal(sbp_encode_ctx_t *ctx, + const sbp_msg_imu_comp_t *msg) { + if (!sbp_u64_encode(ctx, &msg->time)) { + return false; + } + if (!sbp_u16_encode(ctx, &msg->flags)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->acc_comp_x)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->acc_comp_y)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->acc_comp_z)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->gyr_comp_x)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->gyr_comp_y)) { + return false; + } + if (!sbp_s32_encode(ctx, &msg->gyr_comp_z)) { + return false; + } + return true; +} + +s8 sbp_msg_imu_comp_encode(uint8_t *buf, uint8_t len, uint8_t *n_written, + const sbp_msg_imu_comp_t *msg) { + sbp_encode_ctx_t ctx; + ctx.buf = buf; + ctx.buf_len = len; + ctx.offset = 0; + if (!sbp_msg_imu_comp_encode_internal(&ctx, msg)) { + return SBP_ENCODE_ERROR; + } + if (n_written != NULL) { + *n_written = (uint8_t)ctx.offset; + } + return SBP_OK; +} + +bool sbp_msg_imu_comp_decode_internal(sbp_decode_ctx_t *ctx, + sbp_msg_imu_comp_t *msg) { + if (!sbp_u64_decode(ctx, &msg->time)) { + return false; + } + if (!sbp_u16_decode(ctx, &msg->flags)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->acc_comp_x)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->acc_comp_y)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->acc_comp_z)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->gyr_comp_x)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->gyr_comp_y)) { + return false; + } + if (!sbp_s32_decode(ctx, &msg->gyr_comp_z)) { + return false; + } + return true; +} + +s8 sbp_msg_imu_comp_decode(const uint8_t *buf, uint8_t len, uint8_t *n_read, + sbp_msg_imu_comp_t *msg) { + sbp_decode_ctx_t ctx; + ctx.buf = buf; + ctx.buf_len = len; + ctx.offset = 0; + if (!sbp_msg_imu_comp_decode_internal(&ctx, msg)) { + return SBP_DECODE_ERROR; + } + if (n_read != NULL) { + *n_read = (uint8_t)ctx.offset; + } + return SBP_OK; +} + +s8 sbp_msg_imu_comp_send(sbp_state_t *s, u16 sender_id, + const sbp_msg_imu_comp_t *msg, sbp_write_fn_t write) { + uint8_t payload[SBP_MAX_PAYLOAD_LEN]; + uint8_t payload_len; + s8 ret = sbp_msg_imu_comp_encode(payload, sizeof(payload), &payload_len, msg); + if (ret != SBP_OK) { + return ret; + } + return sbp_internal_forward_payload(s, SbpMsgImuComp, sender_id, payload_len, + payload, write); +} + +int sbp_msg_imu_comp_cmp(const sbp_msg_imu_comp_t *a, + const sbp_msg_imu_comp_t *b) { + int ret = 0; + + ret = sbp_u64_cmp(&a->time, &b->time); + if (ret != 0) { + return ret; + } + + ret = sbp_u16_cmp(&a->flags, &b->flags); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->acc_comp_x, &b->acc_comp_x); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->acc_comp_y, &b->acc_comp_y); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->acc_comp_z, &b->acc_comp_z); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->gyr_comp_x, &b->gyr_comp_x); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->gyr_comp_y, &b->gyr_comp_y); + if (ret != 0) { + return ret; + } + + ret = sbp_s32_cmp(&a->gyr_comp_z, &b->gyr_comp_z); + return ret; +} diff --git a/c/src/include/libsbp/internal/imu.h b/c/src/include/libsbp/internal/imu.h index 257f7ace24..6e8c5fbd77 100644 --- a/c/src/include/libsbp/internal/imu.h +++ b/c/src/include/libsbp/internal/imu.h @@ -67,6 +67,26 @@ bool sbp_msg_imu_aux_encode_internal(sbp_encode_ctx_t *ctx, bool sbp_msg_imu_aux_decode_internal(sbp_decode_ctx_t *ctx, sbp_msg_imu_aux_t *msg); +/** + * Internal function to encode an SBP type to a buffer + * + * @param ctx Encode context + * @param msg SBP type instance + * @return true on success, false otherwise + */ +bool sbp_msg_imu_comp_encode_internal(sbp_encode_ctx_t *ctx, + const sbp_msg_imu_comp_t *msg); + +/** + * Internal function to decode an SBP type from a buffer + * + * @param ctx Decode context + * @param msg SBP type instance + * @return true on success, false otherwise + */ +bool sbp_msg_imu_comp_decode_internal(sbp_decode_ctx_t *ctx, + sbp_msg_imu_comp_t *msg); + #ifdef __cplusplus } #endif diff --git a/haskell/src/SwiftNav/SBP/Imu.hs b/haskell/src/SwiftNav/SBP/Imu.hs index 4bdc4aae66..1094f0bc19 100644 --- a/haskell/src/SwiftNav/SBP/Imu.hs +++ b/haskell/src/SwiftNav/SBP/Imu.hs @@ -127,3 +127,58 @@ instance Binary MsgImuAux where $(makeSBP 'msgImuAux ''MsgImuAux) $(makeJSON "_msgImuAux_" ''MsgImuAux) $(makeLenses ''MsgImuAux) + +msgImuComp :: Word16 +msgImuComp = 0x0905 + +-- | SBP class for message MSG_IMU_COMP (0x0905). +-- +-- Data from the Inertial Measurement Unit, containing accelerometer and +-- gyroscope readings compensated for estimated errors and constant physical +-- effects. The output is valid for inertially referenced center of +-- navigation (IMU body frame) represented in vehicle body frame. +data MsgImuComp = MsgImuComp + { _msgImuComp_time :: !Word64 + -- ^ Microseconds since reference epoch + , _msgImuComp_flags :: !Word16 + -- ^ Contains the applied compensation parameters and time synchronization + -- mode + , _msgImuComp_acc_comp_x :: !Int32 + -- ^ Compensated acceleration X axis + , _msgImuComp_acc_comp_y :: !Int32 + -- ^ Compensated acceleration Y axis + , _msgImuComp_acc_comp_z :: !Int32 + -- ^ Compensated acceleration Z axis + , _msgImuComp_gyr_comp_x :: !Int32 + -- ^ Compensated angular rate X axis + , _msgImuComp_gyr_comp_y :: !Int32 + -- ^ Compensated angular rate Y axis + , _msgImuComp_gyr_comp_z :: !Int32 + -- ^ Compensated angular rate Z axis + } deriving ( Show, Read, Eq ) + +instance Binary MsgImuComp where + get = do + _msgImuComp_time <- getWord64le + _msgImuComp_flags <- getWord16le + _msgImuComp_acc_comp_x <- (fromIntegral <$> getWord32le) + _msgImuComp_acc_comp_y <- (fromIntegral <$> getWord32le) + _msgImuComp_acc_comp_z <- (fromIntegral <$> getWord32le) + _msgImuComp_gyr_comp_x <- (fromIntegral <$> getWord32le) + _msgImuComp_gyr_comp_y <- (fromIntegral <$> getWord32le) + _msgImuComp_gyr_comp_z <- (fromIntegral <$> getWord32le) + pure MsgImuComp {..} + + put MsgImuComp {..} = do + putWord64le _msgImuComp_time + putWord16le _msgImuComp_flags + (putWord32le . fromIntegral) _msgImuComp_acc_comp_x + (putWord32le . fromIntegral) _msgImuComp_acc_comp_y + (putWord32le . fromIntegral) _msgImuComp_acc_comp_z + (putWord32le . fromIntegral) _msgImuComp_gyr_comp_x + (putWord32le . fromIntegral) _msgImuComp_gyr_comp_y + (putWord32le . fromIntegral) _msgImuComp_gyr_comp_z + +$(makeSBP 'msgImuComp ''MsgImuComp) +$(makeJSON "_msgImuComp_" ''MsgImuComp) +$(makeLenses ''MsgImuComp) diff --git a/haskell/src/SwiftNav/SBP/Msg.hs b/haskell/src/SwiftNav/SBP/Msg.hs index 0cbaebe6d4..e565872c14 100644 --- a/haskell/src/SwiftNav/SBP/Msg.hs +++ b/haskell/src/SwiftNav/SBP/Msg.hs @@ -156,6 +156,7 @@ data SBPMsg = | SBPMsgHeartbeat MsgHeartbeat Msg | SBPMsgIarState MsgIarState Msg | SBPMsgImuAux MsgImuAux Msg + | SBPMsgImuComp MsgImuComp Msg | SBPMsgImuRaw MsgImuRaw Msg | SBPMsgInitBaseDep MsgInitBaseDep Msg | SBPMsgInsStatus MsgInsStatus Msg @@ -407,6 +408,7 @@ instance Binary SBPMsg where | _msgSBPType == msgHeartbeat = SBPMsgHeartbeat (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgIarState = SBPMsgIarState (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgImuAux = SBPMsgImuAux (decode (fromStrict (unBytes _msgSBPPayload))) m + | _msgSBPType == msgImuComp = SBPMsgImuComp (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgImuRaw = SBPMsgImuRaw (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgInitBaseDep = SBPMsgInitBaseDep (decode (fromStrict (unBytes _msgSBPPayload))) m | _msgSBPType == msgInsStatus = SBPMsgInsStatus (decode (fromStrict (unBytes _msgSBPPayload))) m @@ -650,6 +652,7 @@ instance Binary SBPMsg where encoder (SBPMsgHeartbeat _ m) = put m encoder (SBPMsgIarState _ m) = put m encoder (SBPMsgImuAux _ m) = put m + encoder (SBPMsgImuComp _ m) = put m encoder (SBPMsgImuRaw _ m) = put m encoder (SBPMsgInitBaseDep _ m) = put m encoder (SBPMsgInsStatus _ m) = put m @@ -897,6 +900,7 @@ instance FromJSON SBPMsg where | msgType == msgHeartbeat = SBPMsgHeartbeat <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgIarState = SBPMsgIarState <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgImuAux = SBPMsgImuAux <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj + | msgType == msgImuComp = SBPMsgImuComp <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgImuRaw = SBPMsgImuRaw <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgInitBaseDep = SBPMsgInitBaseDep <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj | msgType == msgInsStatus = SBPMsgInsStatus <$> pure (decode (fromStrict (unBytes payload))) <*> parseJSON obj @@ -1145,6 +1149,7 @@ instance ToJSON SBPMsg where toJSON (SBPMsgHeartbeat n m) = toJSON n <<>> toJSON m toJSON (SBPMsgIarState n m) = toJSON n <<>> toJSON m toJSON (SBPMsgImuAux n m) = toJSON n <<>> toJSON m + toJSON (SBPMsgImuComp n m) = toJSON n <<>> toJSON m toJSON (SBPMsgImuRaw n m) = toJSON n <<>> toJSON m toJSON (SBPMsgInitBaseDep _ m) = toJSON m toJSON (SBPMsgInsStatus n m) = toJSON n <<>> toJSON m @@ -1387,6 +1392,7 @@ instance HasMsg SBPMsg where msg f (SBPMsgHeartbeat n m) = SBPMsgHeartbeat n <$> f m msg f (SBPMsgIarState n m) = SBPMsgIarState n <$> f m msg f (SBPMsgImuAux n m) = SBPMsgImuAux n <$> f m + msg f (SBPMsgImuComp n m) = SBPMsgImuComp n <$> f m msg f (SBPMsgImuRaw n m) = SBPMsgImuRaw n <$> f m msg f (SBPMsgInitBaseDep n m) = SBPMsgInitBaseDep n <$> f m msg f (SBPMsgInsStatus n m) = SBPMsgInsStatus n <$> f m diff --git a/java/src/com/swiftnav/sbp/client/MessageTable.java b/java/src/com/swiftnav/sbp/client/MessageTable.java index 048adecf9f..9a992a1ccb 100644 --- a/java/src/com/swiftnav/sbp/client/MessageTable.java +++ b/java/src/com/swiftnav/sbp/client/MessageTable.java @@ -46,6 +46,7 @@ import com.swiftnav.sbp.flash.MsgStmUniqueIdReq; import com.swiftnav.sbp.flash.MsgStmUniqueIdResp; import com.swiftnav.sbp.imu.MsgImuAux; +import com.swiftnav.sbp.imu.MsgImuComp; import com.swiftnav.sbp.imu.MsgImuRaw; import com.swiftnav.sbp.integrity.MsgAcknowledge; import com.swiftnav.sbp.integrity.MsgSsrFlagHighLevel; @@ -323,6 +324,8 @@ static SBPMessage dispatch(SBPMessage msg) throws SBPBinaryException { return new MsgImuRaw(msg); case MsgImuAux.TYPE: return new MsgImuAux(msg); + case MsgImuComp.TYPE: + return new MsgImuComp(msg); case MsgSsrFlagHighLevel.TYPE: return new MsgSsrFlagHighLevel(msg); case MsgSsrFlagSatellites.TYPE: diff --git a/java/src/com/swiftnav/sbp/imu/MsgImuComp.java b/java/src/com/swiftnav/sbp/imu/MsgImuComp.java new file mode 100644 index 0000000000..ae8c64286a --- /dev/null +++ b/java/src/com/swiftnav/sbp/imu/MsgImuComp.java @@ -0,0 +1,117 @@ +/* Copyright (C) 2015-2022 Swift Navigation Inc. + * Contact: https://support.swiftnav.com + * + * This source is subject to the license found in the file 'LICENSE' which must + * be distributed together with this source. All other rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.swiftnav.sbp.imu; + +// This file was auto-generated from yaml/swiftnav/sbp/imu.yaml by generate.py. +// Do not modify by hand! + + +import com.swiftnav.sbp.SBPBinaryException; +import com.swiftnav.sbp.SBPMessage; +import java.math.BigInteger; +import org.json.JSONObject; + +/** + * SBP class for message MSG_IMU_COMP (0x0905). + * + *

You can have MSG_IMU_COMP inherent its fields directly from an inherited SBP object, or + * construct it inline using a dict of its fields. + * + *

Data from the Inertial Measurement Unit, containing accelerometer and gyroscope readings + * compensated for estimated errors and constant physical effects. The output is valid for + * inertially referenced center of navigation (IMU body frame) represented in vehicle body frame. + */ +public class MsgImuComp extends SBPMessage { + public static final int TYPE = 0x0905; + + /** Microseconds since reference epoch */ + public BigInteger time; + + /** Contains the applied compensation parameters and time synchronization mode */ + public int flags; + + /** Compensated acceleration X axis */ + public int acc_comp_x; + + /** Compensated acceleration Y axis */ + public int acc_comp_y; + + /** Compensated acceleration Z axis */ + public int acc_comp_z; + + /** Compensated angular rate X axis */ + public int gyr_comp_x; + + /** Compensated angular rate Y axis */ + public int gyr_comp_y; + + /** Compensated angular rate Z axis */ + public int gyr_comp_z; + + public MsgImuComp(int sender) { + super(sender, TYPE); + } + + public MsgImuComp() { + super(TYPE); + } + + public MsgImuComp(SBPMessage msg) throws SBPBinaryException { + super(msg); + if (msg.type != TYPE) + throw new SBPBinaryException( + "Type mismatch for MsgImuComp, expected 2309, actual " + msg.type); + } + + @Override + protected void parse(Parser parser) throws SBPBinaryException { + /* Parse fields from binary */ + time = parser.getU64(); + flags = parser.getU16(); + acc_comp_x = parser.getS32(); + acc_comp_y = parser.getS32(); + acc_comp_z = parser.getS32(); + gyr_comp_x = parser.getS32(); + gyr_comp_y = parser.getS32(); + gyr_comp_z = parser.getS32(); + } + + @Override + protected void build(Builder builder) { + builder.putU64(time); + builder.putU16(flags); + builder.putS32(acc_comp_x); + builder.putS32(acc_comp_y); + builder.putS32(acc_comp_z); + builder.putS32(gyr_comp_x); + builder.putS32(gyr_comp_y); + builder.putS32(gyr_comp_z); + } + + @Override + public JSONObject toJSON() { + JSONObject obj = super.toJSON(); + obj.put("time", time); + obj.put("flags", flags); + obj.put("acc_comp_x", acc_comp_x); + obj.put("acc_comp_y", acc_comp_y); + obj.put("acc_comp_z", acc_comp_z); + obj.put("gyr_comp_x", gyr_comp_x); + obj.put("gyr_comp_y", gyr_comp_y); + obj.put("gyr_comp_z", gyr_comp_z); + return obj; + } + + @Override + public String getFriendlyName() { + return "IMU COMP"; + } +} diff --git a/javascript/sbp/imu.js b/javascript/sbp/imu.js index 2f5bba58a7..a1f0bfa9c9 100644 --- a/javascript/sbp/imu.js +++ b/javascript/sbp/imu.js @@ -115,9 +115,62 @@ MsgImuAux.prototype.fieldSpec.push(['imu_type', 'writeUInt8', 1]); MsgImuAux.prototype.fieldSpec.push(['temp', 'writeInt16LE', 2]); MsgImuAux.prototype.fieldSpec.push(['imu_conf', 'writeUInt8', 1]); +/** + * SBP class for message MSG_IMU_COMP (0x0905). + * + * Data from the Inertial Measurement Unit, containing accelerometer and gyroscope + * readings compensated for estimated errors and constant physical effects. The + * output is valid for inertially referenced center of navigation (IMU body frame) + * represented in vehicle body frame. + * + * Fields in the SBP payload (`sbp.payload`): + * @field time number (unsigned 64-bit int, 8 bytes) Microseconds since reference epoch + * @field flags number (unsigned 16-bit int, 2 bytes) Contains the applied compensation parameters and time synchronization mode + * @field acc_comp_x number (signed 32-bit int, 4 bytes) Compensated acceleration X axis + * @field acc_comp_y number (signed 32-bit int, 4 bytes) Compensated acceleration Y axis + * @field acc_comp_z number (signed 32-bit int, 4 bytes) Compensated acceleration Z axis + * @field gyr_comp_x number (signed 32-bit int, 4 bytes) Compensated angular rate X axis + * @field gyr_comp_y number (signed 32-bit int, 4 bytes) Compensated angular rate Y axis + * @field gyr_comp_z number (signed 32-bit int, 4 bytes) Compensated angular rate Z axis + * + * @param sbp An SBP object with a payload to be decoded. + */ +let MsgImuComp = function (sbp, fields) { + SBP.call(this, sbp); + this.messageType = "MSG_IMU_COMP"; + this.fields = (fields || this.parser.parse(sbp.payload)); + + return this; +}; +MsgImuComp.prototype = Object.create(SBP.prototype); +MsgImuComp.prototype.messageType = "MSG_IMU_COMP"; +MsgImuComp.prototype.msg_type = 0x0905; +MsgImuComp.prototype.constructor = MsgImuComp; +MsgImuComp.prototype.parser = new Parser() + .endianess('little') + .uint64('time') + .uint16('flags') + .int32('acc_comp_x') + .int32('acc_comp_y') + .int32('acc_comp_z') + .int32('gyr_comp_x') + .int32('gyr_comp_y') + .int32('gyr_comp_z'); +MsgImuComp.prototype.fieldSpec = []; +MsgImuComp.prototype.fieldSpec.push(['time', 'writeUInt64LE', 8]); +MsgImuComp.prototype.fieldSpec.push(['flags', 'writeUInt16LE', 2]); +MsgImuComp.prototype.fieldSpec.push(['acc_comp_x', 'writeInt32LE', 4]); +MsgImuComp.prototype.fieldSpec.push(['acc_comp_y', 'writeInt32LE', 4]); +MsgImuComp.prototype.fieldSpec.push(['acc_comp_z', 'writeInt32LE', 4]); +MsgImuComp.prototype.fieldSpec.push(['gyr_comp_x', 'writeInt32LE', 4]); +MsgImuComp.prototype.fieldSpec.push(['gyr_comp_y', 'writeInt32LE', 4]); +MsgImuComp.prototype.fieldSpec.push(['gyr_comp_z', 'writeInt32LE', 4]); + module.exports = { 0x0900: MsgImuRaw, MsgImuRaw: MsgImuRaw, 0x0901: MsgImuAux, MsgImuAux: MsgImuAux, + 0x0905: MsgImuComp, + MsgImuComp: MsgImuComp, } \ No newline at end of file diff --git a/jsonschema/MsgImuComp.json b/jsonschema/MsgImuComp.json new file mode 100644 index 0000000000..2033790408 --- /dev/null +++ b/jsonschema/MsgImuComp.json @@ -0,0 +1,38 @@ +{ + "copyright": [ + "Copyright (C) 2019-2021 Swift Navigation Inc.", + "Contact: https://support.swiftnav.com", + "", + "This source is subject to the license found in the file 'LICENSE' which must", + "be distributed together with this source. All other rights reserved.", + "", + "THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF ANY KIND,", + "EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED", + "WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE." + ], + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "#MsgImuComp", + "title":"MsgImuComp", + "description":"Data from the Inertial Measurement Unit, containing accelerometer and gyroscope readings compensated for estimated errors and constant physical effects. The output is valid for inertially referenced center of navigation (IMU body frame) represented in vehicle body frame.\n", + "type": "object", + "properties": { + "time": {"type": "integer"}, + "flags": {"type": "integer"}, + "acc_comp_x": {"type": "integer"}, + "acc_comp_y": {"type": "integer"}, + "acc_comp_z": {"type": "integer"}, + "gyr_comp_x": {"type": "integer"}, + "gyr_comp_y": {"type": "integer"}, + "gyr_comp_z": {"type": "integer"} + }, + "required": [ + "time", + "flags", + "acc_comp_x", + "acc_comp_y", + "acc_comp_z", + "gyr_comp_x", + "gyr_comp_y", + "gyr_comp_z" + ] +} \ No newline at end of file diff --git a/kaitai/ksy/imu.ksy b/kaitai/ksy/imu.ksy index b239205584..2493d2c367 100644 --- a/kaitai/ksy/imu.ksy +++ b/kaitai/ksy/imu.ksy @@ -85,4 +85,45 @@ types: doc: | IMU configuration type: u1 + + msg_imu_comp: + doc: | + Data from the Inertial Measurement Unit, containing accelerometer and + gyroscope readings compensated for estimated errors and constant + physical effects. The output is valid for inertially referenced center + of navigation (IMU body frame) represented in vehicle body frame. + seq: + - id: time + doc: | + Microseconds since reference epoch + type: u8 + - id: flags + doc: | + Contains the applied compensation parameters and time + synchronization mode + type: u2 + - id: acc_comp_x + doc: | + Compensated acceleration X axis + type: s4 + - id: acc_comp_y + doc: | + Compensated acceleration Y axis + type: s4 + - id: acc_comp_z + doc: | + Compensated acceleration Z axis + type: s4 + - id: gyr_comp_x + doc: | + Compensated angular rate X axis + type: s4 + - id: gyr_comp_y + doc: | + Compensated angular rate Y axis + type: s4 + - id: gyr_comp_z + doc: | + Compensated angular rate Z axis + type: s4 \ No newline at end of file diff --git a/kaitai/ksy/sbp.ksy b/kaitai/ksy/sbp.ksy index 93ea07c2dd..c1587bf620 100644 --- a/kaitai/ksy/sbp.ksy +++ b/kaitai/ksy/sbp.ksy @@ -95,6 +95,7 @@ enums: 2304: msg_imu_raw 2305: msg_imu_aux + 2309: msg_imu_comp 3001: msg_ssr_flag_high_level 3005: msg_ssr_flag_satellites @@ -378,6 +379,7 @@ types: 2304: imu::msg_imu_raw 2305: imu::msg_imu_aux + 2309: imu::msg_imu_comp 3001: integrity::msg_ssr_flag_high_level 3005: integrity::msg_ssr_flag_satellites diff --git a/kaitai/perl/KaitaiSbp/Imu.pm b/kaitai/perl/KaitaiSbp/Imu.pm index 8b6e65e96a..58d96d669d 100644 --- a/kaitai/perl/KaitaiSbp/Imu.pm +++ b/kaitai/perl/KaitaiSbp/Imu.pm @@ -166,4 +166,84 @@ sub imu_conf { return $self->{imu_conf}; } +######################################################################## +package Imu::MsgImuComp; + +our @ISA = 'IO::KaitaiStruct::Struct'; + +sub from_file { + my ($class, $filename) = @_; + my $fd; + + open($fd, '<', $filename) or return undef; + binmode($fd); + return new($class, IO::KaitaiStruct::Stream->new($fd)); +} + +sub new { + my ($class, $_io, $_parent, $_root) = @_; + my $self = IO::KaitaiStruct::Struct->new($_io); + + bless $self, $class; + $self->{_parent} = $_parent; + $self->{_root} = $_root || $self;; + + $self->_read(); + + return $self; +} + +sub _read { + my ($self) = @_; + + $self->{time} = $self->{_io}->read_u8le(); + $self->{flags} = $self->{_io}->read_u2le(); + $self->{acc_comp_x} = $self->{_io}->read_s4le(); + $self->{acc_comp_y} = $self->{_io}->read_s4le(); + $self->{acc_comp_z} = $self->{_io}->read_s4le(); + $self->{gyr_comp_x} = $self->{_io}->read_s4le(); + $self->{gyr_comp_y} = $self->{_io}->read_s4le(); + $self->{gyr_comp_z} = $self->{_io}->read_s4le(); +} + +sub time { + my ($self) = @_; + return $self->{time}; +} + +sub flags { + my ($self) = @_; + return $self->{flags}; +} + +sub acc_comp_x { + my ($self) = @_; + return $self->{acc_comp_x}; +} + +sub acc_comp_y { + my ($self) = @_; + return $self->{acc_comp_y}; +} + +sub acc_comp_z { + my ($self) = @_; + return $self->{acc_comp_z}; +} + +sub gyr_comp_x { + my ($self) = @_; + return $self->{gyr_comp_x}; +} + +sub gyr_comp_y { + my ($self) = @_; + return $self->{gyr_comp_y}; +} + +sub gyr_comp_z { + my ($self) = @_; + return $self->{gyr_comp_z}; +} + 1; diff --git a/kaitai/perl/KaitaiSbp/Sbp.pm b/kaitai/perl/KaitaiSbp/Sbp.pm index 444adedc19..0f3f1be210 100644 --- a/kaitai/perl/KaitaiSbp/Sbp.pm +++ b/kaitai/perl/KaitaiSbp/Sbp.pm @@ -233,6 +233,7 @@ our $MSG_IDS_MSG_IMU_AUX = 2305; our $MSG_IDS_MSG_MAG_RAW = 2306; our $MSG_IDS_MSG_ODOMETRY = 2307; our $MSG_IDS_MSG_WHEELTICK = 2308; +our $MSG_IDS_MSG_IMU_COMP = 2309; our $MSG_IDS_MSG_SSR_FLAG_HIGH_LEVEL = 3001; our $MSG_IDS_MSG_SSR_FLAG_SATELLITES = 3005; our $MSG_IDS_MSG_SSR_FLAG_TROPO_GRID_POINTS = 3011; @@ -826,6 +827,11 @@ sub _read { my $io__raw_payload = IO::KaitaiStruct::Stream->new($self->{_raw_payload}); $self->{payload} = Piksi::MsgCwResults->new($io__raw_payload, $self, $self->{_root}); } + elsif ($_on == 2309) { + $self->{_raw_payload} = $self->{_io}->read_bytes($self->length()); + my $io__raw_payload = IO::KaitaiStruct::Stream->new($self->{_raw_payload}); + $self->{payload} = Imu::MsgImuComp->new($io__raw_payload, $self, $self->{_root}); + } elsif ($_on == 165) { $self->{_raw_payload} = $self->{_io}->read_bytes($self->length()); my $io__raw_payload = IO::KaitaiStruct::Stream->new($self->{_raw_payload}); diff --git a/kaitai/perl/KaitaiSbp/Table.pm b/kaitai/perl/KaitaiSbp/Table.pm index b4cb0d3916..bc9314a6fc 100644 --- a/kaitai/perl/KaitaiSbp/Table.pm +++ b/kaitai/perl/KaitaiSbp/Table.pm @@ -89,6 +89,7 @@ our %TABLE = ( 2304 => sub{Imu::MsgImuRaw->new(@_)}, 2305 => sub{Imu::MsgImuAux->new(@_)}, + 2309 => sub{Imu::MsgImuComp->new(@_)}, 3001 => sub{Integrity::MsgSsrFlagHighLevel->new(@_)}, 3005 => sub{Integrity::MsgSsrFlagSatellites->new(@_)}, diff --git a/kaitai/python/kaitai_sbp/imu.py b/kaitai/python/kaitai_sbp/imu.py index 3cf35122b5..03abebf03c 100644 --- a/kaitai/python/kaitai_sbp/imu.py +++ b/kaitai/python/kaitai_sbp/imu.py @@ -64,4 +64,27 @@ def _read(self): self.imu_conf = self._io.read_u1() + class MsgImuComp(KaitaiStruct): + """Data from the Inertial Measurement Unit, containing accelerometer and + gyroscope readings compensated for estimated errors and constant + physical effects. The output is valid for inertially referenced center + of navigation (IMU body frame) represented in vehicle body frame. + """ + def __init__(self, _io, _parent=None, _root=None): + self._io = _io + self._parent = _parent + self._root = _root if _root else self + self._read() + + def _read(self): + self.time = self._io.read_u8le() + self.flags = self._io.read_u2le() + self.acc_comp_x = self._io.read_s4le() + self.acc_comp_y = self._io.read_s4le() + self.acc_comp_z = self._io.read_s4le() + self.gyr_comp_x = self._io.read_s4le() + self.gyr_comp_y = self._io.read_s4le() + self.gyr_comp_z = self._io.read_s4le() + + diff --git a/kaitai/python/kaitai_sbp/sbp.py b/kaitai/python/kaitai_sbp/sbp.py index 3a0adf2b4e..75d6ae8b82 100644 --- a/kaitai/python/kaitai_sbp/sbp.py +++ b/kaitai/python/kaitai_sbp/sbp.py @@ -226,6 +226,7 @@ class MsgIds(Enum): msg_mag_raw = 2306 msg_odometry = 2307 msg_wheeltick = 2308 + msg_imu_comp = 2309 msg_ssr_flag_high_level = 3001 msg_ssr_flag_satellites = 3005 msg_ssr_flag_tropo_grid_points = 3011 @@ -689,6 +690,10 @@ def _read(self): self._raw_payload = self._io.read_bytes(self.length) _io__raw_payload = KaitaiStream(BytesIO(self._raw_payload)) self.payload = Piksi.MsgCwResults(_io__raw_payload, self, self._root) + elif _on == 2309: + self._raw_payload = self._io.read_bytes(self.length) + _io__raw_payload = KaitaiStream(BytesIO(self._raw_payload)) + self.payload = Imu.MsgImuComp(_io__raw_payload, self, self._root) elif _on == 165: self._raw_payload = self._io.read_bytes(self.length) _io__raw_payload = KaitaiStream(BytesIO(self._raw_payload)) diff --git a/kaitai/python/kaitai_sbp/table.py b/kaitai/python/kaitai_sbp/table.py index d6fff9e27e..94f0aabfc9 100644 --- a/kaitai/python/kaitai_sbp/table.py +++ b/kaitai/python/kaitai_sbp/table.py @@ -83,6 +83,7 @@ 2304: Imu.MsgImuRaw, 2305: Imu.MsgImuAux, + 2309: Imu.MsgImuComp, 3001: Integrity.MsgSsrFlagHighLevel, 3005: Integrity.MsgSsrFlagSatellites, diff --git a/proto/imu.proto b/proto/imu.proto index 67eeac9b3f..ae1090b20d 100644 --- a/proto/imu.proto +++ b/proto/imu.proto @@ -54,4 +54,22 @@ message MsgImuAux { uint32 imu_type = 1; sint32 temp = 2; uint32 imu_conf = 3; +} + +/** Compensated IMU data + * + * Data from the Inertial Measurement Unit, containing accelerometer and + * gyroscope readings compensated for estimated errors and constant physical + * effects. The output is valid for inertially referenced center of + * navigation (IMU body frame) represented in vehicle body frame. + */ +message MsgImuComp { + uint64 time = 1; + uint32 flags = 2; + sint32 acc_comp_x = 3; + sint32 acc_comp_y = 4; + sint32 acc_comp_z = 5; + sint32 gyr_comp_x = 6; + sint32 gyr_comp_y = 7; + sint32 gyr_comp_z = 8; } \ No newline at end of file diff --git a/python/sbp/imu.py b/python/sbp/imu.py index be27d3c67c..6ec25e7ca6 100644 --- a/python/sbp/imu.py +++ b/python/sbp/imu.py @@ -271,8 +271,142 @@ def to_json_dict(self): d.update(j) return d +SBP_MSG_IMU_COMP = 0x0905 +class MsgImuComp(SBP): + """SBP class for message MSG_IMU_COMP (0x0905). + + You can have MSG_IMU_COMP inherit its fields directly + from an inherited SBP object, or construct it inline using a dict + of its fields. + + + Data from the Inertial Measurement Unit, containing accelerometer and + gyroscope readings compensated for estimated errors and constant physical + effects. The output is valid for inertially referenced center of navigation + (IMU body frame) represented in vehicle body frame. + + Parameters + ---------- + sbp : SBP + SBP parent object to inherit from. + time : int + Microseconds since reference epoch + flags : int + Contains the applied compensation parameters and time synchronization mode + acc_comp_x : int + Compensated acceleration X axis + acc_comp_y : int + Compensated acceleration Y axis + acc_comp_z : int + Compensated acceleration Z axis + gyr_comp_x : int + Compensated angular rate X axis + gyr_comp_y : int + Compensated angular rate Y axis + gyr_comp_z : int + Compensated angular rate Z axis + sender : int + Optional sender ID, defaults to SENDER_ID (see sbp/msg.py). + + """ + _parser = construct.Struct( + 'time' / construct.Int64ul, + 'flags' / construct.Int16ul, + 'acc_comp_x' / construct.Int32sl, + 'acc_comp_y' / construct.Int32sl, + 'acc_comp_z' / construct.Int32sl, + 'gyr_comp_x' / construct.Int32sl, + 'gyr_comp_y' / construct.Int32sl, + 'gyr_comp_z' / construct.Int32sl,) + __slots__ = [ + 'time', + 'flags', + 'acc_comp_x', + 'acc_comp_y', + 'acc_comp_z', + 'gyr_comp_x', + 'gyr_comp_y', + 'gyr_comp_z', + ] + + def __init__(self, sbp=None, **kwargs): + if sbp: + super( MsgImuComp, + self).__init__(sbp.msg_type, sbp.sender, sbp.length, + sbp.payload, sbp.crc) + self.from_binary(sbp.payload) + else: + super( MsgImuComp, self).__init__() + self.msg_type = SBP_MSG_IMU_COMP + self.sender = kwargs.pop('sender', SENDER_ID) + self.time = kwargs.pop('time') + self.flags = kwargs.pop('flags') + self.acc_comp_x = kwargs.pop('acc_comp_x') + self.acc_comp_y = kwargs.pop('acc_comp_y') + self.acc_comp_z = kwargs.pop('acc_comp_z') + self.gyr_comp_x = kwargs.pop('gyr_comp_x') + self.gyr_comp_y = kwargs.pop('gyr_comp_y') + self.gyr_comp_z = kwargs.pop('gyr_comp_z') + + def __repr__(self): + return fmt_repr(self) + + @staticmethod + def from_json(s): + """Given a JSON-encoded string s, build a message object. + + """ + d = json.loads(s) + return MsgImuComp.from_json_dict(d) + + @staticmethod + def from_json_dict(d): + sbp = SBP.from_json_dict(d) + return MsgImuComp(sbp, **d) + + + def from_binary(self, d): + """Given a binary payload d, update the appropriate payload fields of + the message. + + """ + p = MsgImuComp._parser.parse(d) + for n in self.__class__.__slots__: + setattr(self, n, getattr(p, n)) + + def to_binary(self): + """Produce a framed/packed SBP message. + + """ + c = containerize(exclude_fields(self)) + self.payload = MsgImuComp._parser.build(c) + return self.pack() + + def friendly_name(self): + """Produces friendly human-readable name for this message + + """ + return "IMU COMP" + + def into_buffer(self, buf, offset): + """Produce a framed/packed SBP message into the provided buffer and offset. + + """ + self.payload = containerize(exclude_fields(self)) + self.parser = MsgImuComp._parser + self.stream_payload.reset(buf, offset) + return self.pack_into(buf, offset, self._build_payload) + + def to_json_dict(self): + self.to_binary() + d = super( MsgImuComp, self).to_json_dict() + j = walk_json_dict(exclude_fields(self)) + d.update(j) + return d + msg_classes = { 0x0900: MsgImuRaw, 0x0901: MsgImuAux, + 0x0905: MsgImuComp, } \ No newline at end of file diff --git a/rust/sbp/src/messages/imu.rs b/rust/sbp/src/messages/imu.rs index e68788d100..bc3f69059c 100644 --- a/rust/sbp/src/messages/imu.rs +++ b/rust/sbp/src/messages/imu.rs @@ -14,6 +14,7 @@ //****************************************************************************/ //! Inertial Measurement Unit (IMU) messages. pub use msg_imu_aux::MsgImuAux; +pub use msg_imu_comp::MsgImuComp; pub use msg_imu_raw::MsgImuRaw; pub mod msg_imu_aux { @@ -302,6 +303,258 @@ pub mod msg_imu_aux { } } +pub mod msg_imu_comp { + #![allow(unused_imports)] + + use super::*; + use crate::messages::lib::*; + + /// Compensated IMU data + /// + /// Data from the Inertial Measurement Unit, containing accelerometer and + /// gyroscope readings compensated for estimated errors and constant physical + /// effects. The output is valid for inertially referenced center of + /// navigation (IMU body frame) represented in vehicle body frame. + /// + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Debug, PartialEq, Clone)] + pub struct MsgImuComp { + /// The message sender_id + #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))] + pub sender_id: Option, + /// Microseconds since reference epoch + #[cfg_attr(feature = "serde", serde(rename = "time"))] + pub time: u64, + /// Contains the applied compensation parameters and time synchronization + /// mode + #[cfg_attr(feature = "serde", serde(rename = "flags"))] + pub flags: u16, + /// Compensated acceleration X axis + #[cfg_attr(feature = "serde", serde(rename = "acc_comp_x"))] + pub acc_comp_x: i32, + /// Compensated acceleration Y axis + #[cfg_attr(feature = "serde", serde(rename = "acc_comp_y"))] + pub acc_comp_y: i32, + /// Compensated acceleration Z axis + #[cfg_attr(feature = "serde", serde(rename = "acc_comp_z"))] + pub acc_comp_z: i32, + /// Compensated angular rate X axis + #[cfg_attr(feature = "serde", serde(rename = "gyr_comp_x"))] + pub gyr_comp_x: i32, + /// Compensated angular rate Y axis + #[cfg_attr(feature = "serde", serde(rename = "gyr_comp_y"))] + pub gyr_comp_y: i32, + /// Compensated angular rate Z axis + #[cfg_attr(feature = "serde", serde(rename = "gyr_comp_z"))] + pub gyr_comp_z: i32, + } + + impl MsgImuComp { + /// Gets the `gyroscopeerrorscompensated` flag. + #[allow(clippy::identity_op)] + pub fn gyroscopeerrorscompensated(&self) -> bool { + ((self.flags >> 6) & 1) == 1 + } + + /// Sets the `gyroscopeerrorscompensated` flag. + pub fn set_gyroscopeerrorscompensated(&mut self, gyroscopeerrorscompensated: bool) { + self.flags ^= (!(gyroscopeerrorscompensated as u16)) & (1 << 6) + } + + /// Gets the `accelerometererrorscompensated` flag. + #[allow(clippy::identity_op)] + pub fn accelerometererrorscompensated(&self) -> bool { + ((self.flags >> 5) & 1) == 1 + } + + /// Sets the `accelerometererrorscompensated` flag. + pub fn set_accelerometererrorscompensated(&mut self, accelerometererrorscompensated: bool) { + self.flags ^= (!(accelerometererrorscompensated as u16)) & (1 << 5) + } + + /// Gets the `corioliseffectcompensated` flag. + #[allow(clippy::identity_op)] + pub fn corioliseffectcompensated(&self) -> bool { + ((self.flags >> 4) & 1) == 1 + } + + /// Sets the `corioliseffectcompensated` flag. + pub fn set_corioliseffectcompensated(&mut self, corioliseffectcompensated: bool) { + self.flags ^= (!(corioliseffectcompensated as u16)) & (1 << 4) + } + + /// Gets the `earthrorationratecompensated` flag. + #[allow(clippy::identity_op)] + pub fn earthrorationratecompensated(&self) -> bool { + ((self.flags >> 3) & 1) == 1 + } + + /// Sets the `earthrorationratecompensated` flag. + pub fn set_earthrorationratecompensated(&mut self, earthrorationratecompensated: bool) { + self.flags ^= (!(earthrorationratecompensated as u16)) & (1 << 3) + } + + /// Gets the `earthgravitycompensated` flag. + #[allow(clippy::identity_op)] + pub fn earthgravitycompensated(&self) -> bool { + ((self.flags >> 2) & 1) == 1 + } + + /// Sets the `earthgravitycompensated` flag. + pub fn set_earthgravitycompensated(&mut self, earthgravitycompensated: bool) { + self.flags ^= (!(earthgravitycompensated as u16)) & (1 << 2) + } + + /// Gets the [TimeStatus][self::TimeStatus] stored in the `flags` bitfield. + /// + /// Returns `Ok` if the bitrange contains a known `TimeStatus` variant. + /// Otherwise the value of the bitrange is returned as an `Err(u8)`. This may be because of a malformed message, + /// or because new variants of `TimeStatus` were added. + pub fn time_status(&self) -> Result { + get_bit_range!(self.flags, u16, u8, 1, 0).try_into() + } + + /// Set the bitrange corresponding to the [TimeStatus][TimeStatus] of the `flags` bitfield. + pub fn set_time_status(&mut self, time_status: TimeStatus) { + set_bit_range!(&mut self.flags, time_status, u16, u8, 1, 0); + } + } + + impl ConcreteMessage for MsgImuComp { + const MESSAGE_TYPE: u16 = 2309; + const MESSAGE_NAME: &'static str = "MSG_IMU_COMP"; + } + + impl SbpMessage for MsgImuComp { + fn message_name(&self) -> &'static str { + ::MESSAGE_NAME + } + fn message_type(&self) -> Option { + Some(::MESSAGE_TYPE) + } + fn sender_id(&self) -> Option { + self.sender_id + } + fn set_sender_id(&mut self, new_id: u16) { + self.sender_id = Some(new_id); + } + fn encoded_len(&self) -> usize { + WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN + } + fn is_valid(&self) -> bool { + true + } + fn into_valid_msg(self) -> Result { + Ok(self) + } + } + + impl FriendlyName for MsgImuComp { + fn friendly_name() -> &'static str { + "IMU COMP" + } + } + + impl TryFrom for MsgImuComp { + type Error = TryFromSbpError; + fn try_from(msg: Sbp) -> Result { + match msg { + Sbp::MsgImuComp(m) => Ok(m), + _ => Err(TryFromSbpError(msg)), + } + } + } + + impl WireFormat for MsgImuComp { + const MIN_LEN: usize = ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN + + ::MIN_LEN; + fn len(&self) -> usize { + WireFormat::len(&self.time) + + WireFormat::len(&self.flags) + + WireFormat::len(&self.acc_comp_x) + + WireFormat::len(&self.acc_comp_y) + + WireFormat::len(&self.acc_comp_z) + + WireFormat::len(&self.gyr_comp_x) + + WireFormat::len(&self.gyr_comp_y) + + WireFormat::len(&self.gyr_comp_z) + } + fn write(&self, buf: &mut B) { + WireFormat::write(&self.time, buf); + WireFormat::write(&self.flags, buf); + WireFormat::write(&self.acc_comp_x, buf); + WireFormat::write(&self.acc_comp_y, buf); + WireFormat::write(&self.acc_comp_z, buf); + WireFormat::write(&self.gyr_comp_x, buf); + WireFormat::write(&self.gyr_comp_y, buf); + WireFormat::write(&self.gyr_comp_z, buf); + } + fn parse_unchecked(buf: &mut B) -> Self { + MsgImuComp { + sender_id: None, + time: WireFormat::parse_unchecked(buf), + flags: WireFormat::parse_unchecked(buf), + acc_comp_x: WireFormat::parse_unchecked(buf), + acc_comp_y: WireFormat::parse_unchecked(buf), + acc_comp_z: WireFormat::parse_unchecked(buf), + gyr_comp_x: WireFormat::parse_unchecked(buf), + gyr_comp_y: WireFormat::parse_unchecked(buf), + gyr_comp_z: WireFormat::parse_unchecked(buf), + } + } + } + + /// Time status + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum TimeStatus { + /// Reference epoch is start of current GPS week + ReferenceEpochIsStartOfCurrentGpsWeek = 0, + + /// Reference epoch is time of system startup + ReferenceEpochIsTimeOfSystemStartup = 1, + + /// Reference epoch is unknown + ReferenceEpochIsUnknown = 2, + + /// Reference epoch is last PPS + ReferenceEpochIsLastPps = 3, + } + + impl std::fmt::Display for TimeStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek => { + f.write_str("Reference epoch is start of current GPS week") + } + TimeStatus::ReferenceEpochIsTimeOfSystemStartup => { + f.write_str("Reference epoch is time of system startup") + } + TimeStatus::ReferenceEpochIsUnknown => f.write_str("Reference epoch is unknown"), + TimeStatus::ReferenceEpochIsLastPps => f.write_str("Reference epoch is last PPS"), + } + } + } + + impl TryFrom for TimeStatus { + type Error = u8; + fn try_from(i: u8) -> Result { + match i { + 0 => Ok(TimeStatus::ReferenceEpochIsStartOfCurrentGpsWeek), + 1 => Ok(TimeStatus::ReferenceEpochIsTimeOfSystemStartup), + 2 => Ok(TimeStatus::ReferenceEpochIsUnknown), + 3 => Ok(TimeStatus::ReferenceEpochIsLastPps), + i => Err(i), + } + } + } +} + pub mod msg_imu_raw { #![allow(unused_imports)] diff --git a/rust/sbp/src/messages/mod.rs b/rust/sbp/src/messages/mod.rs index bad1920949..e4c86f0d22 100644 --- a/rust/sbp/src/messages/mod.rs +++ b/rust/sbp/src/messages/mod.rs @@ -77,6 +77,7 @@ use self::flash::msg_stm_flash_unlock_sector::MsgStmFlashUnlockSector; use self::flash::msg_stm_unique_id_req::MsgStmUniqueIdReq; use self::flash::msg_stm_unique_id_resp::MsgStmUniqueIdResp; use self::imu::msg_imu_aux::MsgImuAux; +use self::imu::msg_imu_comp::MsgImuComp; use self::imu::msg_imu_raw::MsgImuRaw; use self::integrity::msg_acknowledge::MsgAcknowledge; use self::integrity::msg_ssr_flag_high_level::MsgSsrFlagHighLevel; @@ -766,6 +767,8 @@ pub enum Sbp { MsgOdometry(MsgOdometry), /// Accumulated wheeltick count message MsgWheeltick(MsgWheeltick), + /// Compensated IMU data + MsgImuComp(MsgImuComp), /// High level integrity flags MsgSsrFlagHighLevel(MsgSsrFlagHighLevel), /// List of satellites which are faulty, per constellation @@ -1471,6 +1474,9 @@ impl<'de> serde::Deserialize<'de> for Sbp { Some(MsgWheeltick::MESSAGE_TYPE) => { serde_json::from_value::(value).map(Sbp::MsgWheeltick) } + Some(MsgImuComp::MESSAGE_TYPE) => { + serde_json::from_value::(value).map(Sbp::MsgImuComp) + } Some(MsgSsrFlagHighLevel::MESSAGE_TYPE) => { serde_json::from_value::(value).map(Sbp::MsgSsrFlagHighLevel) } @@ -2187,6 +2193,7 @@ impl Sbp { MsgMagRaw::MESSAGE_TYPE => MsgMagRaw::parse(&mut payload).map(Sbp::MsgMagRaw), MsgOdometry::MESSAGE_TYPE => MsgOdometry::parse(&mut payload).map(Sbp::MsgOdometry), MsgWheeltick::MESSAGE_TYPE => MsgWheeltick::parse(&mut payload).map(Sbp::MsgWheeltick), + MsgImuComp::MESSAGE_TYPE => MsgImuComp::parse(&mut payload).map(Sbp::MsgImuComp), MsgSsrFlagHighLevel::MESSAGE_TYPE => { MsgSsrFlagHighLevel::parse(&mut payload).map(Sbp::MsgSsrFlagHighLevel) } @@ -2543,6 +2550,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.message_name(), Sbp::MsgOdometry(msg) => msg.message_name(), Sbp::MsgWheeltick(msg) => msg.message_name(), + Sbp::MsgImuComp(msg) => msg.message_name(), Sbp::MsgSsrFlagHighLevel(msg) => msg.message_name(), Sbp::MsgSsrFlagSatellites(msg) => msg.message_name(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.message_name(), @@ -2788,6 +2796,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.message_type(), Sbp::MsgOdometry(msg) => msg.message_type(), Sbp::MsgWheeltick(msg) => msg.message_type(), + Sbp::MsgImuComp(msg) => msg.message_type(), Sbp::MsgSsrFlagHighLevel(msg) => msg.message_type(), Sbp::MsgSsrFlagSatellites(msg) => msg.message_type(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.message_type(), @@ -3033,6 +3042,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.sender_id(), Sbp::MsgOdometry(msg) => msg.sender_id(), Sbp::MsgWheeltick(msg) => msg.sender_id(), + Sbp::MsgImuComp(msg) => msg.sender_id(), Sbp::MsgSsrFlagHighLevel(msg) => msg.sender_id(), Sbp::MsgSsrFlagSatellites(msg) => msg.sender_id(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.sender_id(), @@ -3278,6 +3288,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.set_sender_id(new_id), Sbp::MsgOdometry(msg) => msg.set_sender_id(new_id), Sbp::MsgWheeltick(msg) => msg.set_sender_id(new_id), + Sbp::MsgImuComp(msg) => msg.set_sender_id(new_id), Sbp::MsgSsrFlagHighLevel(msg) => msg.set_sender_id(new_id), Sbp::MsgSsrFlagSatellites(msg) => msg.set_sender_id(new_id), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.set_sender_id(new_id), @@ -3523,6 +3534,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.encoded_len(), Sbp::MsgOdometry(msg) => msg.encoded_len(), Sbp::MsgWheeltick(msg) => msg.encoded_len(), + Sbp::MsgImuComp(msg) => msg.encoded_len(), Sbp::MsgSsrFlagHighLevel(msg) => msg.encoded_len(), Sbp::MsgSsrFlagSatellites(msg) => msg.encoded_len(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.encoded_len(), @@ -3771,6 +3783,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.gps_time(), Sbp::MsgOdometry(msg) => msg.gps_time(), Sbp::MsgWheeltick(msg) => msg.gps_time(), + Sbp::MsgImuComp(msg) => msg.gps_time(), Sbp::MsgSsrFlagHighLevel(msg) => msg.gps_time(), Sbp::MsgSsrFlagSatellites(msg) => msg.gps_time(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.gps_time(), @@ -4016,6 +4029,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.friendly_name(), Sbp::MsgOdometry(msg) => msg.friendly_name(), Sbp::MsgWheeltick(msg) => msg.friendly_name(), + Sbp::MsgImuComp(msg) => msg.friendly_name(), Sbp::MsgSsrFlagHighLevel(msg) => msg.friendly_name(), Sbp::MsgSsrFlagSatellites(msg) => msg.friendly_name(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.friendly_name(), @@ -4261,6 +4275,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => msg.is_valid(), Sbp::MsgOdometry(msg) => msg.is_valid(), Sbp::MsgWheeltick(msg) => msg.is_valid(), + Sbp::MsgImuComp(msg) => msg.is_valid(), Sbp::MsgSsrFlagHighLevel(msg) => msg.is_valid(), Sbp::MsgSsrFlagSatellites(msg) => msg.is_valid(), Sbp::MsgSsrFlagTropoGridPoints(msg) => msg.is_valid(), @@ -4567,6 +4582,7 @@ impl SbpMessage for Sbp { Sbp::MsgMagRaw(msg) => Ok(Sbp::MsgMagRaw(msg.into_valid_msg()?)), Sbp::MsgOdometry(msg) => Ok(Sbp::MsgOdometry(msg.into_valid_msg()?)), Sbp::MsgWheeltick(msg) => Ok(Sbp::MsgWheeltick(msg.into_valid_msg()?)), + Sbp::MsgImuComp(msg) => Ok(Sbp::MsgImuComp(msg.into_valid_msg()?)), Sbp::MsgSsrFlagHighLevel(msg) => Ok(Sbp::MsgSsrFlagHighLevel(msg.into_valid_msg()?)), Sbp::MsgSsrFlagSatellites(msg) => Ok(Sbp::MsgSsrFlagSatellites(msg.into_valid_msg()?)), Sbp::MsgSsrFlagTropoGridPoints(msg) => { @@ -4861,6 +4877,7 @@ impl WireFormat for Sbp { Sbp::MsgMagRaw(msg) => WireFormat::write(msg, buf), Sbp::MsgOdometry(msg) => WireFormat::write(msg, buf), Sbp::MsgWheeltick(msg) => WireFormat::write(msg, buf), + Sbp::MsgImuComp(msg) => WireFormat::write(msg, buf), Sbp::MsgSsrFlagHighLevel(msg) => WireFormat::write(msg, buf), Sbp::MsgSsrFlagSatellites(msg) => WireFormat::write(msg, buf), Sbp::MsgSsrFlagTropoGridPoints(msg) => WireFormat::write(msg, buf), @@ -5106,6 +5123,7 @@ impl WireFormat for Sbp { Sbp::MsgMagRaw(msg) => WireFormat::len(msg), Sbp::MsgOdometry(msg) => WireFormat::len(msg), Sbp::MsgWheeltick(msg) => WireFormat::len(msg), + Sbp::MsgImuComp(msg) => WireFormat::len(msg), Sbp::MsgSsrFlagHighLevel(msg) => WireFormat::len(msg), Sbp::MsgSsrFlagSatellites(msg) => WireFormat::len(msg), Sbp::MsgSsrFlagTropoGridPoints(msg) => WireFormat::len(msg), @@ -6290,6 +6308,12 @@ impl From for Sbp { } } +impl From for Sbp { + fn from(msg: MsgImuComp) -> Self { + Sbp::MsgImuComp(msg) + } +} + impl From for Sbp { fn from(msg: MsgSsrFlagHighLevel) -> Self { Sbp::MsgSsrFlagHighLevel(msg) diff --git a/sbpjson/elm/SbpJson.elm b/sbpjson/elm/SbpJson.elm index bcee891a1a..17b4fc6346 100644 --- a/sbpjson/elm/SbpJson.elm +++ b/sbpjson/elm/SbpJson.elm @@ -5,7 +5,7 @@ -- add these imports -- -- import Json.Decode exposing (decodeString)`); --- import SbpJson exposing (acqSvProfile, almanacCommonContent, boundsHeader, carrierPhase, codeBiasesContent, codePhaseBiasesSatSig, doppler, ecdsaSignature, ephemerisCommonContent, estimatedHorizontalErrorEllipse, gnssInputType, gnssCapb, gnssSignal, gpsTime, gpsTimeSEC, gridElement, gridElementNoStd, griddedCorrectionHeader, imuInputType, integritySSRHeader, latency, measurementState, msgAcknowledge, msgAcqResult, msgAcqSvProfile, msgAESCmacSignature, msgAgeCorrections, msgAlmanac, msgAlmanacGPS, msgAlmanacGlo, msgAngularRate, msgBasePosECEF, msgBasePosLLH, msgBaselineECEF, msgBaselineHeading, msgBaselineNED, msgBootloaderHandshakeReq, msgBootloaderHandshakeResp, msgBootloaderJumpToApp, msgCellModemStatus, msgCertificateChain, msgCommandOutput, msgCommandReq, msgCommandResp, msgCsacTelemetry, msgCsacTelemetryLabels, msgCwResults, msgCwStart, msgDeviceMonitor, msgDgnssStatus, msgDops, msgEcdsaCertificate, msgEcdsaSignature, msgEphemerisBds, msgEphemerisGPS, msgEphemerisGal, msgEphemerisGlo, msgEphemerisQzss, msgEphemerisSbas, msgEXTEvent, msgFileioConfigReq, msgFileioConfigResp, msgFileioReadDirReq, msgFileioReadDirResp, msgFileioReadReq, msgFileioReadResp, msgFileioRemove, msgFileioWriteReq, msgFileioWriteResp, msgFlashDone, msgFlashErase, msgFlashProgram, msgFlashReadReq, msgFlashReadResp, msgFrontEndGain, msgFwd, msgGPSTime, msgGPSTimeGnss, msgGloBiases, msgGnssCapb, msgGnssTimeOffset, msgGroupDelay, msgGroupMeta, msgHeartbeat, msgIarState, msgImuAux, msgImuRaw, msgInsStatus, msgInsUpdates, msgIono, msgLinuxCPUState, msgLinuxMemState, msgLinuxProcessFdCount, msgLinuxProcessFdSummary, msgLinuxProcessSocketCounts, msgLinuxProcessSocketQueues, msgLinuxSocketUsage, msgLinuxSysState, msgLog, msgM25FlashWriteStatus, msgMagRaw, msgMaskSatellite, msgMeasurementPoint, msgMeasurementState, msgNapDeviceDnaReq, msgNapDeviceDnaResp, msgNdbEvent, msgNetworkBandwidthUsage, msgNetworkStateReq, msgNetworkStateResp, msgObs, msgOdometry, msgOrientEuler, msgOrientQuat, msgOsr, msgPosECEF, msgPosECEFCov, msgPosECEFCovGnss, msgPosECEFGnss, msgPosLLH, msgPosLLHAcc, msgPosLLHCov, msgPosLLHCovGnss, msgPosLLHGnss, msgPoseRelative, msgPpsTime, msgProfilingResourceCounter, msgProfilingSystemInfo, msgProfilingThreadInfo, msgProtectionLevel, msgReferenceFrameParam, msgReset, msgResetFilters, msgSbasRaw, msgSensorAidEvent, msgSetTime, msgSettingsReadByIndexDone, msgSettingsReadByIndexReq, msgSettingsReadByIndexResp, msgSettingsReadReq, msgSettingsReadResp, msgSettingsRegister, msgSettingsRegisterResp, msgSettingsSave, msgSettingsWrite, msgSettingsWriteResp, msgSolnMeta, msgSpecan, msgSsrCodeBiases, msgSsrCodePhaseBiasesBounds, msgSsrFlagHighLevel, msgSsrFlagIonoGridPointSatLos, msgSsrFlagIonoGridPoints, msgSsrFlagIonoTileSatLos, msgSsrFlagSatellites, msgSsrFlagTropoGridPoints, msgSsrGriddedCorrection, msgSsrGriddedCorrectionBounds, msgSsrOrbitClock, msgSsrOrbitClockBounds, msgSsrOrbitClockBoundsDegradation, msgSsrPhaseBiases, msgSsrSatelliteApc, msgSsrStecCorrection, msgSsrTileDefinition, msgStartup, msgStatusJournal, msgStatusReport, msgStmFlashLockSector, msgStmFlashUnlockSector, msgStmUniqueIDReq, msgStmUniqueIDResp, msgSvAzEl, msgTelSv, msgThreadState, msgTrackingIq, msgTrackingState, msgUARTState, msgUserData, msgUTCLeapSecond, msgUTCTime, msgUTCTimeGnss, msgVelBody, msgVelCog, msgVelECEF, msgVelECEFCov, msgVelECEFCovGnss, msgVelECEFGnss, msgVelNED, msgVelNEDCov, msgVelNEDCovGnss, msgVelNEDGnss, msgWheeltick, networkUsage, observationHeader, odoInputType, orbitClockBound, orbitClockBoundDegradation, packedObsContent, packedOsrContent, period, phaseBiasesContent, resourceBucket, stecHeader, stecResidual, stecResidualNoStd, stecSatElement, stecSatElementIntegrity, satelliteAPC, solutionInputType, statusJournalItem, subSystemReport, svAzEl, svID, telemetrySV, trackingChannelCorrelation, trackingChannelState, troposphericDelayCorrection, troposphericDelayCorrectionNoStd, uartChannel, utcTime) +-- import SbpJson exposing (acqSvProfile, almanacCommonContent, boundsHeader, carrierPhase, codeBiasesContent, codePhaseBiasesSatSig, doppler, ecdsaSignature, ephemerisCommonContent, estimatedHorizontalErrorEllipse, gnssInputType, gnssCapb, gnssSignal, gpsTime, gpsTimeSEC, gridElement, gridElementNoStd, griddedCorrectionHeader, imuInputType, integritySSRHeader, latency, measurementState, msgAcknowledge, msgAcqResult, msgAcqSvProfile, msgAESCmacSignature, msgAgeCorrections, msgAlmanac, msgAlmanacGPS, msgAlmanacGlo, msgAngularRate, msgBasePosECEF, msgBasePosLLH, msgBaselineECEF, msgBaselineHeading, msgBaselineNED, msgBootloaderHandshakeReq, msgBootloaderHandshakeResp, msgBootloaderJumpToApp, msgCellModemStatus, msgCertificateChain, msgCommandOutput, msgCommandReq, msgCommandResp, msgCsacTelemetry, msgCsacTelemetryLabels, msgCwResults, msgCwStart, msgDeviceMonitor, msgDgnssStatus, msgDops, msgEcdsaCertificate, msgEcdsaSignature, msgEphemerisBds, msgEphemerisGPS, msgEphemerisGal, msgEphemerisGlo, msgEphemerisQzss, msgEphemerisSbas, msgEXTEvent, msgFileioConfigReq, msgFileioConfigResp, msgFileioReadDirReq, msgFileioReadDirResp, msgFileioReadReq, msgFileioReadResp, msgFileioRemove, msgFileioWriteReq, msgFileioWriteResp, msgFlashDone, msgFlashErase, msgFlashProgram, msgFlashReadReq, msgFlashReadResp, msgFrontEndGain, msgFwd, msgGPSTime, msgGPSTimeGnss, msgGloBiases, msgGnssCapb, msgGnssTimeOffset, msgGroupDelay, msgGroupMeta, msgHeartbeat, msgIarState, msgImuAux, msgImuComp, msgImuRaw, msgInsStatus, msgInsUpdates, msgIono, msgLinuxCPUState, msgLinuxMemState, msgLinuxProcessFdCount, msgLinuxProcessFdSummary, msgLinuxProcessSocketCounts, msgLinuxProcessSocketQueues, msgLinuxSocketUsage, msgLinuxSysState, msgLog, msgM25FlashWriteStatus, msgMagRaw, msgMaskSatellite, msgMeasurementPoint, msgMeasurementState, msgNapDeviceDnaReq, msgNapDeviceDnaResp, msgNdbEvent, msgNetworkBandwidthUsage, msgNetworkStateReq, msgNetworkStateResp, msgObs, msgOdometry, msgOrientEuler, msgOrientQuat, msgOsr, msgPosECEF, msgPosECEFCov, msgPosECEFCovGnss, msgPosECEFGnss, msgPosLLH, msgPosLLHAcc, msgPosLLHCov, msgPosLLHCovGnss, msgPosLLHGnss, msgPoseRelative, msgPpsTime, msgProfilingResourceCounter, msgProfilingSystemInfo, msgProfilingThreadInfo, msgProtectionLevel, msgReferenceFrameParam, msgReset, msgResetFilters, msgSbasRaw, msgSensorAidEvent, msgSetTime, msgSettingsReadByIndexDone, msgSettingsReadByIndexReq, msgSettingsReadByIndexResp, msgSettingsReadReq, msgSettingsReadResp, msgSettingsRegister, msgSettingsRegisterResp, msgSettingsSave, msgSettingsWrite, msgSettingsWriteResp, msgSolnMeta, msgSpecan, msgSsrCodeBiases, msgSsrCodePhaseBiasesBounds, msgSsrFlagHighLevel, msgSsrFlagIonoGridPointSatLos, msgSsrFlagIonoGridPoints, msgSsrFlagIonoTileSatLos, msgSsrFlagSatellites, msgSsrFlagTropoGridPoints, msgSsrGriddedCorrection, msgSsrGriddedCorrectionBounds, msgSsrOrbitClock, msgSsrOrbitClockBounds, msgSsrOrbitClockBoundsDegradation, msgSsrPhaseBiases, msgSsrSatelliteApc, msgSsrStecCorrection, msgSsrTileDefinition, msgStartup, msgStatusJournal, msgStatusReport, msgStmFlashLockSector, msgStmFlashUnlockSector, msgStmUniqueIDReq, msgStmUniqueIDResp, msgSvAzEl, msgTelSv, msgThreadState, msgTrackingIq, msgTrackingState, msgUARTState, msgUserData, msgUTCLeapSecond, msgUTCTime, msgUTCTimeGnss, msgVelBody, msgVelCog, msgVelECEF, msgVelECEFCov, msgVelECEFCovGnss, msgVelECEFGnss, msgVelNED, msgVelNEDCov, msgVelNEDCovGnss, msgVelNEDGnss, msgWheeltick, networkUsage, observationHeader, odoInputType, orbitClockBound, orbitClockBoundDegradation, packedObsContent, packedOsrContent, period, phaseBiasesContent, resourceBucket, stecHeader, stecResidual, stecResidualNoStd, stecSatElement, stecSatElementIntegrity, satelliteAPC, solutionInputType, statusJournalItem, subSystemReport, svAzEl, svID, telemetrySV, trackingChannelCorrelation, trackingChannelState, troposphericDelayCorrection, troposphericDelayCorrectionNoStd, uartChannel, utcTime) -- -- and you're off to the races with -- @@ -95,6 +95,7 @@ -- decodeString msgHeartbeat myJsonString -- decodeString msgIarState myJsonString -- decodeString msgImuAux myJsonString +-- decodeString msgImuComp myJsonString -- decodeString msgImuRaw myJsonString -- decodeString msgInsStatus myJsonString -- decodeString msgInsUpdates myJsonString @@ -490,6 +491,9 @@ module SbpJson exposing , MsgImuAux , msgImuAuxToString , msgImuAux + , MsgImuComp + , msgImuCompToString + , msgImuComp , MsgImuRaw , msgImuRawToString , msgImuRaw @@ -940,6 +944,7 @@ type alias GridElement = } {-| STEC residual (mean and standard deviation) for the given satellite at the grid point. -} + type alias STECResidual = { residual : Int , stddev : Int @@ -947,12 +952,14 @@ type alias STECResidual = } {-| A (Constellation ID, satellite ID) tuple that uniquely identifies a space vehicle. -} + type alias SvID = { constellation : Int , satID : Int } {-| Troposphere vertical delays (mean and standard deviation) at the grid point. -} + type alias TroposphericDelayCorrection = { hydro : Int , stddev : Int @@ -960,6 +967,7 @@ type alias TroposphericDelayCorrection = } {-| Contains one tropo delay, plus STEC residuals for each satellite at the grid point. -} + type alias GridElementNoStd = { index : Int , stecResiduals : Array STECResidualNoStd @@ -967,12 +975,14 @@ type alias GridElementNoStd = } {-| STEC residual for the given satellite at the grid point. -} + type alias STECResidualNoStd = { residual : Int , svID : SvID } {-| Troposphere vertical delays at the grid point. -} + type alias TroposphericDelayCorrectionNoStd = { hydro : Int , wet : Int @@ -1006,6 +1016,7 @@ type alias MsgAcqResult = } {-| Signal identifier containing constellation, band, and satellite identifier. -} + type alias GnssSignal = { code : Int , sat : Int @@ -1037,6 +1048,7 @@ type alias AcqSvProfile = } {-| Digital signature using AES-CMAC 128 algorithm used for data integrity. -} + type alias MsgAESCmacSignature = { certificateID : Array Int , flags : Int @@ -1201,6 +1213,7 @@ type alias MsgBootloaderHandshakeResp = } {-| The host initiates the bootloader to jump to the application. -} + type alias MsgBootloaderJumpToApp = { jump : Int } @@ -1317,6 +1330,7 @@ type alias MsgDops = } {-| A DER encoded x.509 ECDSA-256 certificate (using curve secp256r1). -} + type alias MsgEcdsaCertificate = { certificateBytes : Array Int , certificateID : Array Int @@ -1325,6 +1339,7 @@ type alias MsgEcdsaCertificate = } {-| An ECDSA-256 signature using SHA-256 as the message digest algorithm. -} + type alias MsgEcdsaSignature = { certificateID : Array Int , flags : Int @@ -1771,6 +1786,7 @@ type alias MsgGnssTimeOffset = } {-| Please see ICD-GPS-200 (30.3.3.3.1.1) for more details. -} + type alias MsgGroupDelay = { iscL1CA : Int , iscL2C : Int @@ -1820,6 +1836,22 @@ type alias MsgImuAux = , temp : Int } +{-| Data from the Inertial Measurement Unit, containing accelerometer and gyroscope readings +compensated for estimated errors and constant physical effects. The output is valid for +inertially referenced center of navigation (IMU body frame) represented in vehicle body +frame. +-} +type alias MsgImuComp = + { accCompX : Int + , accCompY : Int + , accCompZ : Int + , flags : Int + , gyrCompX : Int + , gyrCompY : Int + , gyrCompZ : Int + , time : Int + } + {-| Raw data from the Inertial Measurement Unit, containing accelerometer and gyroscope readings. The sense of the measurements are to be aligned with the indications on the device itself. Measurement units, which are specific to the device hardware and settings, @@ -1905,6 +1937,7 @@ type alias MsgLinuxMemState = } {-| Top 10 list of processes with a large number of open file descriptors. -} + type alias MsgLinuxProcessFdCount = { cmdline : String , fdCount : Int @@ -1913,12 +1946,14 @@ type alias MsgLinuxProcessFdCount = } {-| Summary of open file descriptors on the system. -} + type alias MsgLinuxProcessFdSummary = { mostOpened : String , sysFdCount : Int } {-| Top 10 list of processes with high socket counts. -} + type alias MsgLinuxProcessSocketCounts = { cmdline : String , index : Int @@ -1929,6 +1964,7 @@ type alias MsgLinuxProcessSocketCounts = } {-| Top 10 list of sockets with deep queues. -} + type alias MsgLinuxProcessSocketQueues = { addressOfLargest : String , cmdline : String @@ -1941,6 +1977,7 @@ type alias MsgLinuxProcessSocketQueues = } {-| Summaries the socket usage across the system. -} + type alias MsgLinuxSocketUsage = { avgQueueDepth : Int , maxQueueDepth : Int @@ -1949,6 +1986,7 @@ type alias MsgLinuxSocketUsage = } {-| This presents a summary of CPU and memory utilization, including a timestamp. -} + type alias MsgLinuxSysState = { flags : Int , memTotal : Int @@ -1976,6 +2014,7 @@ type alias MsgM25FlashWriteStatus = } {-| Raw data from the magnetometer. -} + type alias MsgMagRaw = { magX : Int , magY : Int @@ -2047,6 +2086,7 @@ type alias MsgNdbEvent = } {-| The bandwidth usage, a list of usage by interface. -} + type alias MsgNetworkBandwidthUsage = { interfaces : Array NetworkUsage } @@ -2090,6 +2130,7 @@ type alias MsgObs = } {-| Header of a GNSS observation message. -} + type alias ObservationHeader = { nObs : Int , t : GpsTime @@ -2192,12 +2233,14 @@ type alias MsgOrientQuat = } {-| The OSR message contains network corrections in an observation-like format. -} + type alias MsgOsr = { header : ObservationHeader , obs : Array PackedOsrContent } {-| Pseudorange and carrier phase network corrections for a satellite signal. -} + type alias PackedOsrContent = { flags : Int , ionoStd : Int @@ -2577,6 +2620,7 @@ type alias MsgReferenceFrameParam = } {-| This message from the host resets the Piksi back into the bootloader. -} + type alias MsgReset = { flags : Int } @@ -2727,6 +2771,7 @@ type alias SolutionInputType = } {-| Spectrum analyzer packet. -} + type alias MsgSpecan = { amplitudeRef : Float , amplitudeUnit : Float @@ -2916,6 +2961,7 @@ type alias MsgSsrGriddedCorrectionBounds = } {-| STEC polynomial and bounds for the given satellite. -} + type alias STECSatElementIntegrity = { stecBoundMu : Int , stecBoundMuDot : Int @@ -2959,6 +3005,7 @@ type alias MsgSsrOrbitClockBounds = } {-| Orbit and clock bound. -} + type alias OrbitClockBound = { clockBoundMu : Int , clockBoundSig : Int @@ -2980,6 +3027,7 @@ type alias MsgSsrOrbitClockBoundsDegradation = } {-| Orbit and clock bound degradation. -} + type alias OrbitClockBoundDegradation = { clockBoundMuDot : Int , clockBoundSigDot : Int @@ -3009,6 +3057,7 @@ type alias MsgSsrPhaseBiases = } {-| Phase biases are to be added to carrier phase measurements. -} + type alias PhaseBiasesContent = { bias : Int , code : Int @@ -3046,6 +3095,7 @@ type alias MsgSsrStecCorrection = } {-| STEC polynomial for the given satellite. -} + type alias STECSatElement = { stecCoeff : Array Int , stecQualityIndicator : Int @@ -3159,6 +3209,7 @@ type alias MsgSvAzEl = } {-| Satellite azimuth and elevation. -} + type alias SvAzEl = { az : Int , el : Int @@ -3166,6 +3217,7 @@ type alias SvAzEl = } {-| This message includes telemetry pertinent to satellite signals available to Starling. -} + type alias MsgTelSv = { nObs : Int , originFlags : Int @@ -3196,6 +3248,7 @@ type alias MsgThreadState = } {-| When enabled, a tracking channel can output the correlations at each update interval. -} + type alias MsgTrackingIq = { channel : Int , corrs : Array TrackingChannelCorrelation @@ -3203,6 +3256,7 @@ type alias MsgTrackingIq = } {-| Structure containing in-phase and quadrature correlation components. -} + type alias TrackingChannelCorrelation = { i : Int , q : Int @@ -3216,6 +3270,7 @@ type alias MsgTrackingState = } {-| Tracking channel state for a specific satellite signal and measured signal power. -} + type alias TrackingChannelState = { cn0 : Int , fcn : Int @@ -3851,6 +3906,9 @@ msgIarStateToString r = Jenc.encode 0 (encodeMsgIarState r) msgImuAuxToString : MsgImuAux -> String msgImuAuxToString r = Jenc.encode 0 (encodeMsgImuAux r) +msgImuCompToString : MsgImuComp -> String +msgImuCompToString r = Jenc.encode 0 (encodeMsgImuComp r) + msgImuRawToString : MsgImuRaw -> String msgImuRawToString r = Jenc.encode 0 (encodeMsgImuRaw r) @@ -5715,6 +5773,31 @@ encodeMsgImuAux x = , ("temp", Jenc.int x.temp) ] +msgImuComp : Jdec.Decoder MsgImuComp +msgImuComp = + Jpipe.decode MsgImuComp + |> Jpipe.required "acc_comp_x" Jdec.int + |> Jpipe.required "acc_comp_y" Jdec.int + |> Jpipe.required "acc_comp_z" Jdec.int + |> Jpipe.required "flags" Jdec.int + |> Jpipe.required "gyr_comp_x" Jdec.int + |> Jpipe.required "gyr_comp_y" Jdec.int + |> Jpipe.required "gyr_comp_z" Jdec.int + |> Jpipe.required "time" Jdec.int + +encodeMsgImuComp : MsgImuComp -> Jenc.Value +encodeMsgImuComp x = + Jenc.object + [ ("acc_comp_x", Jenc.int x.accCompX) + , ("acc_comp_y", Jenc.int x.accCompY) + , ("acc_comp_z", Jenc.int x.accCompZ) + , ("flags", Jenc.int x.flags) + , ("gyr_comp_x", Jenc.int x.gyrCompX) + , ("gyr_comp_y", Jenc.int x.gyrCompY) + , ("gyr_comp_z", Jenc.int x.gyrCompZ) + , ("time", Jenc.int x.time) + ] + msgImuRaw : Jdec.Decoder MsgImuRaw msgImuRaw = Jpipe.decode MsgImuRaw diff --git a/sbpjson/typescript/SbpJson.ts b/sbpjson/typescript/SbpJson.ts index 1915dcdbe8..21d23c70d5 100644 --- a/sbpjson/typescript/SbpJson.ts +++ b/sbpjson/typescript/SbpJson.ts @@ -1,6 +1,6 @@ // To parse this data: // -// import { Convert, AcqSvProfile, AlmanacCommonContent, BoundsHeader, CarrierPhase, CodeBiasesContent, CodePhaseBiasesSatSig, Doppler, ECDSASignature, EphemerisCommonContent, EstimatedHorizontalErrorEllipse, GNSSInputType, GnssCapb, GnssSignal, GpsTime, GpsTimeSEC, GridElement, GridElementNoStd, GriddedCorrectionHeader, IMUInputType, IntegritySSRHeader, Latency, MeasurementState, MsgAcknowledge, MsgAcqResult, MsgAcqSvProfile, MsgAESCmacSignature, MsgAgeCorrections, MsgAlmanacGPS, MsgAlmanacGlo, MsgAngularRate, MsgBasePosECEF, MsgBasePosLLH, MsgBaselineECEF, MsgBaselineHeading, MsgBaselineNED, MsgBootloaderHandshakeResp, MsgBootloaderJumpToApp, MsgCellModemStatus, MsgCertificateChain, MsgCommandOutput, MsgCommandReq, MsgCommandResp, MsgCsacTelemetry, MsgCsacTelemetryLabels, MsgDeviceMonitor, MsgDgnssStatus, MsgDops, MsgEcdsaCertificate, MsgEcdsaSignature, MsgEphemerisBds, MsgEphemerisGPS, MsgEphemerisGal, MsgEphemerisGlo, MsgEphemerisQzss, MsgEphemerisSbas, MsgEXTEvent, MsgFileioConfigReq, MsgFileioConfigResp, MsgFileioReadDirReq, MsgFileioReadDirResp, MsgFileioReadReq, MsgFileioReadResp, MsgFileioRemove, MsgFileioWriteReq, MsgFileioWriteResp, MsgFlashDone, MsgFlashErase, MsgFlashProgram, MsgFlashReadReq, MsgFlashReadResp, MsgFrontEndGain, MsgFwd, MsgGPSTime, MsgGPSTimeGnss, MsgGloBiases, MsgGnssCapb, MsgGnssTimeOffset, MsgGroupDelay, MsgGroupMeta, MsgHeartbeat, MsgIarState, MsgImuAux, MsgImuRaw, MsgInsStatus, MsgInsUpdates, MsgIono, MsgLinuxCPUState, MsgLinuxMemState, MsgLinuxProcessFdCount, MsgLinuxProcessFdSummary, MsgLinuxProcessSocketCounts, MsgLinuxProcessSocketQueues, MsgLinuxSocketUsage, MsgLinuxSysState, MsgLog, MsgM25FlashWriteStatus, MsgMagRaw, MsgMaskSatellite, MsgMeasurementPoint, MsgMeasurementState, MsgNapDeviceDnaResp, MsgNdbEvent, MsgNetworkBandwidthUsage, MsgNetworkStateResp, MsgObs, MsgOdometry, MsgOrientEuler, MsgOrientQuat, MsgOsr, MsgPosECEF, MsgPosECEFCov, MsgPosECEFCovGnss, MsgPosECEFGnss, MsgPosLLH, MsgPosLLHAcc, MsgPosLLHCov, MsgPosLLHCovGnss, MsgPosLLHGnss, MsgPoseRelative, MsgPpsTime, MsgProfilingResourceCounter, MsgProfilingSystemInfo, MsgProfilingThreadInfo, MsgProtectionLevel, MsgReferenceFrameParam, MsgReset, MsgResetFilters, MsgSbasRaw, MsgSensorAidEvent, MsgSettingsReadByIndexReq, MsgSettingsReadByIndexResp, MsgSettingsReadReq, MsgSettingsReadResp, MsgSettingsRegister, MsgSettingsRegisterResp, MsgSettingsWrite, MsgSettingsWriteResp, MsgSolnMeta, MsgSpecan, MsgSsrCodeBiases, MsgSsrCodePhaseBiasesBounds, MsgSsrFlagHighLevel, MsgSsrFlagIonoGridPointSatLos, MsgSsrFlagIonoGridPoints, MsgSsrFlagIonoTileSatLos, MsgSsrFlagSatellites, MsgSsrFlagTropoGridPoints, MsgSsrGriddedCorrection, MsgSsrGriddedCorrectionBounds, MsgSsrOrbitClock, MsgSsrOrbitClockBounds, MsgSsrOrbitClockBoundsDegradation, MsgSsrPhaseBiases, MsgSsrSatelliteApc, MsgSsrStecCorrection, MsgSsrTileDefinition, MsgStartup, MsgStatusJournal, MsgStatusReport, MsgStmFlashLockSector, MsgStmFlashUnlockSector, MsgStmUniqueIDResp, MsgSvAzEl, MsgTelSv, MsgThreadState, MsgTrackingIq, MsgTrackingState, MsgUARTState, MsgUserData, MsgUTCLeapSecond, MsgUTCTime, MsgUTCTimeGnss, MsgVelBody, MsgVelCog, MsgVelECEF, MsgVelECEFCov, MsgVelECEFCovGnss, MsgVelECEFGnss, MsgVelNED, MsgVelNEDCov, MsgVelNEDCovGnss, MsgVelNEDGnss, MsgWheeltick, NetworkUsage, ObservationHeader, OdoInputType, OrbitClockBound, OrbitClockBoundDegradation, PackedObsContent, PackedOsrContent, Period, PhaseBiasesContent, ResourceBucket, STECHeader, STECResidual, STECResidualNoStd, STECSatElement, STECSatElementIntegrity, SatelliteAPC, SolutionInputType, StatusJournalItem, SubSystemReport, SvAzEl, SvID, TelemetrySV, TrackingChannelCorrelation, TrackingChannelState, TroposphericDelayCorrection, TroposphericDelayCorrectionNoStd, UARTChannel, UTCTime } from "./file"; +// import { Convert, AcqSvProfile, AlmanacCommonContent, BoundsHeader, CarrierPhase, CodeBiasesContent, CodePhaseBiasesSatSig, Doppler, ECDSASignature, EphemerisCommonContent, EstimatedHorizontalErrorEllipse, GNSSInputType, GnssCapb, GnssSignal, GpsTime, GpsTimeSEC, GridElement, GridElementNoStd, GriddedCorrectionHeader, IMUInputType, IntegritySSRHeader, Latency, MeasurementState, MsgAcknowledge, MsgAcqResult, MsgAcqSvProfile, MsgAESCmacSignature, MsgAgeCorrections, MsgAlmanacGPS, MsgAlmanacGlo, MsgAngularRate, MsgBasePosECEF, MsgBasePosLLH, MsgBaselineECEF, MsgBaselineHeading, MsgBaselineNED, MsgBootloaderHandshakeResp, MsgBootloaderJumpToApp, MsgCellModemStatus, MsgCertificateChain, MsgCommandOutput, MsgCommandReq, MsgCommandResp, MsgCsacTelemetry, MsgCsacTelemetryLabels, MsgDeviceMonitor, MsgDgnssStatus, MsgDops, MsgEcdsaCertificate, MsgEcdsaSignature, MsgEphemerisBds, MsgEphemerisGPS, MsgEphemerisGal, MsgEphemerisGlo, MsgEphemerisQzss, MsgEphemerisSbas, MsgEXTEvent, MsgFileioConfigReq, MsgFileioConfigResp, MsgFileioReadDirReq, MsgFileioReadDirResp, MsgFileioReadReq, MsgFileioReadResp, MsgFileioRemove, MsgFileioWriteReq, MsgFileioWriteResp, MsgFlashDone, MsgFlashErase, MsgFlashProgram, MsgFlashReadReq, MsgFlashReadResp, MsgFrontEndGain, MsgFwd, MsgGPSTime, MsgGPSTimeGnss, MsgGloBiases, MsgGnssCapb, MsgGnssTimeOffset, MsgGroupDelay, MsgGroupMeta, MsgHeartbeat, MsgIarState, MsgImuAux, MsgImuComp, MsgImuRaw, MsgInsStatus, MsgInsUpdates, MsgIono, MsgLinuxCPUState, MsgLinuxMemState, MsgLinuxProcessFdCount, MsgLinuxProcessFdSummary, MsgLinuxProcessSocketCounts, MsgLinuxProcessSocketQueues, MsgLinuxSocketUsage, MsgLinuxSysState, MsgLog, MsgM25FlashWriteStatus, MsgMagRaw, MsgMaskSatellite, MsgMeasurementPoint, MsgMeasurementState, MsgNapDeviceDnaResp, MsgNdbEvent, MsgNetworkBandwidthUsage, MsgNetworkStateResp, MsgObs, MsgOdometry, MsgOrientEuler, MsgOrientQuat, MsgOsr, MsgPosECEF, MsgPosECEFCov, MsgPosECEFCovGnss, MsgPosECEFGnss, MsgPosLLH, MsgPosLLHAcc, MsgPosLLHCov, MsgPosLLHCovGnss, MsgPosLLHGnss, MsgPoseRelative, MsgPpsTime, MsgProfilingResourceCounter, MsgProfilingSystemInfo, MsgProfilingThreadInfo, MsgProtectionLevel, MsgReferenceFrameParam, MsgReset, MsgResetFilters, MsgSbasRaw, MsgSensorAidEvent, MsgSettingsReadByIndexReq, MsgSettingsReadByIndexResp, MsgSettingsReadReq, MsgSettingsReadResp, MsgSettingsRegister, MsgSettingsRegisterResp, MsgSettingsWrite, MsgSettingsWriteResp, MsgSolnMeta, MsgSpecan, MsgSsrCodeBiases, MsgSsrCodePhaseBiasesBounds, MsgSsrFlagHighLevel, MsgSsrFlagIonoGridPointSatLos, MsgSsrFlagIonoGridPoints, MsgSsrFlagIonoTileSatLos, MsgSsrFlagSatellites, MsgSsrFlagTropoGridPoints, MsgSsrGriddedCorrection, MsgSsrGriddedCorrectionBounds, MsgSsrOrbitClock, MsgSsrOrbitClockBounds, MsgSsrOrbitClockBoundsDegradation, MsgSsrPhaseBiases, MsgSsrSatelliteApc, MsgSsrStecCorrection, MsgSsrTileDefinition, MsgStartup, MsgStatusJournal, MsgStatusReport, MsgStmFlashLockSector, MsgStmFlashUnlockSector, MsgStmUniqueIDResp, MsgSvAzEl, MsgTelSv, MsgThreadState, MsgTrackingIq, MsgTrackingState, MsgUARTState, MsgUserData, MsgUTCLeapSecond, MsgUTCTime, MsgUTCTimeGnss, MsgVelBody, MsgVelCog, MsgVelECEF, MsgVelECEFCov, MsgVelECEFCovGnss, MsgVelECEFGnss, MsgVelNED, MsgVelNEDCov, MsgVelNEDCovGnss, MsgVelNEDGnss, MsgWheeltick, NetworkUsage, ObservationHeader, OdoInputType, OrbitClockBound, OrbitClockBoundDegradation, PackedObsContent, PackedOsrContent, Period, PhaseBiasesContent, ResourceBucket, STECHeader, STECResidual, STECResidualNoStd, STECSatElement, STECSatElementIntegrity, SatelliteAPC, SolutionInputType, StatusJournalItem, SubSystemReport, SvAzEl, SvID, TelemetrySV, TrackingChannelCorrelation, TrackingChannelState, TroposphericDelayCorrection, TroposphericDelayCorrectionNoStd, UARTChannel, UTCTime } from "./file"; // // const acqSvProfile = Convert.toAcqSvProfile(json); // const almanacCommonContent = Convert.toAlmanacCommonContent(json); @@ -88,6 +88,7 @@ // const msgHeartbeat = Convert.toMsgHeartbeat(json); // const msgIarState = Convert.toMsgIarState(json); // const msgImuAux = Convert.toMsgImuAux(json); +// const msgImuComp = Convert.toMsgImuComp(json); // const msgImuRaw = Convert.toMsgImuRaw(json); // const msgInsStatus = Convert.toMsgInsStatus(json); // const msgInsUpdates = Convert.toMsgInsUpdates(json); @@ -1282,6 +1283,24 @@ export interface MsgImuAux { [property: string]: any; } +/** + * Data from the Inertial Measurement Unit, containing accelerometer and gyroscope readings + * compensated for estimated errors and constant physical effects. The output is valid for + * inertially referenced center of navigation (IMU body frame) represented in vehicle body + * frame. + */ +export interface MsgImuComp { + acc_comp_x: number; + acc_comp_y: number; + acc_comp_z: number; + flags: number; + gyr_comp_x: number; + gyr_comp_y: number; + gyr_comp_z: number; + time: number; + [property: string]: any; +} + /** * Raw data from the Inertial Measurement Unit, containing accelerometer and gyroscope * readings. The sense of the measurements are to be aligned with the indications on the @@ -4008,6 +4027,14 @@ export class Convert { return JSON.stringify(uncast(value, r("MsgImuAux")), null, 2); } + public static toMsgImuComp(json: string): MsgImuComp { + return cast(JSON.parse(json), r("MsgImuComp")); + } + + public static msgImuCompToJson(value: MsgImuComp): string { + return JSON.stringify(uncast(value, r("MsgImuComp")), null, 2); + } + public static toMsgImuRaw(json: string): MsgImuRaw { return cast(JSON.parse(json), r("MsgImuRaw")); } @@ -5770,6 +5797,16 @@ const typeMap: any = { { json: "imu_type", js: "imu_type", typ: 0 }, { json: "temp", js: "temp", typ: 0 }, ], "any"), + "MsgImuComp": o([ + { json: "acc_comp_x", js: "acc_comp_x", typ: 0 }, + { json: "acc_comp_y", js: "acc_comp_y", typ: 0 }, + { json: "acc_comp_z", js: "acc_comp_z", typ: 0 }, + { json: "flags", js: "flags", typ: 0 }, + { json: "gyr_comp_x", js: "gyr_comp_x", typ: 0 }, + { json: "gyr_comp_y", js: "gyr_comp_y", typ: 0 }, + { json: "gyr_comp_z", js: "gyr_comp_z", typ: 0 }, + { json: "time", js: "time", typ: 0 }, + ], "any"), "MsgImuRaw": o([ { json: "acc_x", js: "acc_x", typ: 0 }, { json: "acc_y", js: "acc_y", typ: 0 },