Path: blob/master/libraries/AP_ExternalAHRS/AP_ExternalAHRS_SBG.h
6351 views
/*1Copyright (C) 2025 Kraus Hamdani Aerospace Inc. All rights reserved.23This program is free software: you can redistribute it and/or modify4it under the terms of the GNU General Public License as published by5the Free Software Foundation, either version 3 of the License, or6(at your option) any later version.78This program is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11GNU General Public License for more details.1213You should have received a copy of the GNU General Public License14along with this program. If not, see <http://www.gnu.org/licenses/>.15*/16/*17support for serial connected SBG INS system18*/1920#pragma once2122#include "AP_ExternalAHRS_config.h"2324#if AP_EXTERNAL_AHRS_SBG_ENABLED2526#include "AP_ExternalAHRS_backend.h"27#include "AP_ExternalAHRS_SBG_structs.h"2829class AP_ExternalAHRS_SBG : public AP_ExternalAHRS_backend {3031public:32AP_ExternalAHRS_SBG(AP_ExternalAHRS *frontend, AP_ExternalAHRS::state_t &state);3334// get serial port number, -1 for not enabled35int8_t get_port(void) const override { return (uart == nullptr) ? -1 : port_num; }3637// accessors for AP_AHRS38bool healthy(void) const override { return last_received_ms > 0 && (AP_HAL::millis() - last_received_ms < 500); }39bool initialised(void) const override { return setup_complete; };40bool pre_arm_check(char *failure_msg, uint8_t failure_msg_len) const override;4142void get_filter_status(nav_filter_status &status) const override;4344// TODO: implement this45bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar) const override { return false; };4647// check for new data48void update() override { }4950// Get model/type name51const char* get_name() const override { return "SBG"; }5253protected:5455uint8_t num_gps_sensors(void) const override {56return 1;57}5859private:6061static constexpr uint8_t SBG_PACKET_SYNC1 = 0xFF;62static constexpr uint8_t SBG_PACKET_SYNC2 = 0x5A;63static constexpr uint8_t SBG_PACKET_ETX = 0x33;64static constexpr uint16_t SBG_PACKET_PAYLOAD_SIZE_MAX = 100; // real sbgCom limit is 4086 but the largest packet we parse is SbgLogEkfNavData=72 bytes65static constexpr uint16_t SBG_PACKET_OVERHEAD = 9; // sync1, sync2, id, class, lenLSB, lenMSB, crcLSB, crcMSB, etx6667struct Cached {68struct {69AP_ExternalAHRS::gps_data_message_t gps_data;70AP_ExternalAHRS::mag_data_message_t mag_data;71AP_ExternalAHRS::baro_data_message_t baro_data;72AP_ExternalAHRS::ins_data_message_t ins_data;73AP_ExternalAHRS::airspeed_data_message_t airspeed_data;7475float baro_height;7677uint32_t gps_ms;78uint32_t mag_ms;79uint32_t baro_ms;80uint32_t ins_ms;81uint32_t airspeed_ms;82} sensors;8384struct {85SbgLogUtcData sbgLogUtcData;86SbgLogGpsVel sbgLogGpsVel;87SbgLogGpsPos sbgLogGpsPos;88SbgLogImuData sbgLogImuData;89SbgLogFastImuData sbgLogFastImuData;90SbgEComLogImuShort sbgEComLogImuShort;91SbgLogEkfEulerData sbgLogEkfEulerData;92SbgLogEkfQuatData sbgLogEkfQuatData;93SbgLogEkfNavData sbgLogEkfNavData; // biggest msg we care about, 72 bytes94SbgLogAirData sbgLogAirData;95SbgLogMag sbgLogMag;96SbgEComDeviceInfo sbgEComDeviceInfo;97} sbg;98} cached;99100struct PACKED sbgMessage {101102uint8_t msgid = 0;103uint8_t msgclass = 0;104uint16_t len = 0;105uint8_t data[SBG_PACKET_PAYLOAD_SIZE_MAX];106107sbgMessage() {};108109sbgMessage(const uint8_t msgClass_, const uint8_t msgId_) {110msgid = msgId_;111msgclass = msgClass_;112};113114sbgMessage(const uint8_t msgClass_, const uint8_t msgId_, const uint8_t* payload, const uint16_t payload_len) {115msgid = msgId_;116msgclass = msgClass_;117118if (payload_len > 0 && payload_len <= sizeof(data)) {119memcpy(&data, payload, payload_len);120len = payload_len;121}122};123};124125enum class SBG_PACKET_PARSE_STATE : uint8_t {126SYNC1,127SYNC2,128MSG,129CLASS,130LEN1,131LEN2,132DATA,133CRC1,134CRC2,135ETX,136DROP_THIS_PACKET137};138139140struct SBG_PACKET_INBOUND_STATE {141SBG_PACKET_PARSE_STATE parser;142uint16_t data_count;143uint16_t crc;144sbgMessage msg;145uint16_t data_count_skip; // if we are parsing for a packet larger than we can accept, just stop parsing and wait for this many bytes to pass on by146} _inbound_state;147148void handle_msg(const sbgMessage &msg);149static bool parse_byte(const uint8_t data, sbgMessage &msg, SBG_PACKET_INBOUND_STATE &inbound_state);150void update_thread();151bool check_uart();152static uint16_t calcCRC(const void *pBuffer, uint16_t bufferSize);153static bool send_sbgMessage(AP_HAL::UARTDriver *_uart, const sbgMessage &msg);154static void safe_copy_msg_to_object(uint8_t* dest, const uint16_t dest_len, const uint8_t* src, const uint16_t src_len);155static bool SbgEkfStatus_is_fullNav(const uint32_t ekfStatus);156157static AP_GPS_FixType SbgGpsPosStatus_to_GpsFixType(const uint32_t gpsPosStatus);158159uint32_t send_MagData_ms;160uint32_t send_AirData_ms;161uint32_t send_mag_error_last_ms;162uint32_t send_air_error_last_ms;163static bool send_MagData(AP_HAL::UARTDriver *_uart);164static bool send_AirData(AP_HAL::UARTDriver *_uart);165166AP_HAL::UARTDriver *uart;167int8_t port_num;168uint32_t baudrate;169bool setup_complete;170uint32_t version_check_ms;171uint32_t last_received_ms;172};173174#endif // AP_EXTERNAL_AHRS_SBG_ENABLED175176177178