#pragma once #include "SIM_config.h" #if AP_SIM_GPS_TRIMBLE_ENABLED #include "SIM_GPS.h" namespace SITL { class DCOL_Parser { // The DCOL parser is used by Trimble GSOF devices. // It's used for doing configuration. // https://receiverhelp.trimble.com/oem-gnss/API_DataCollectorFormatPackets.html public: // Feed data in to the DCOL parser. // If the data reaches a parse state that needs to write ACK/NACK back out, // the function returns true with a populated data_out value. // Otherwise, it returns false waiting for more data. bool dcol_parse(const char data_in); static constexpr uint8_t STX = 0x02; static constexpr uint8_t ETX = 0x03; // Receiver status code enum class Status : uint8_t { OK = 0x00, }; // https://receiverhelp.trimble.com/oem-gnss/API_DataCollectorFormatPackets.html enum class Command_Response : uint8_t { ACK = 0x06, NACK = 0x15, }; // https://receiverhelp.trimble.com/oem-gnss/ICD_Command64h_AppFile_Output.html#Frequenc enum class Output_Rate : uint8_t { OFF = 0, FREQ_10_HZ = 1, FREQ_50_HZ = 15, FREQ_100_HZ = 16, }; // https://receiverhelp.trimble.com/oem-gnss/ICD_ApplicationFilePackets.html?tocpath=API%20Documentation%7CCommand%20and%20report%20packets%7CApplication%20file%20packets%7C_____0 enum class Packet_Type : uint8_t { COMMAND_APPFILE = 0x64, }; // https://receiverhelp.trimble.com/oem-gnss/ICD_Pkt_Command64h_APPFILE.html enum class Appfile_Record_Type : uint8_t { SERIAL_PORT_BAUD_RATE_FORMAT = 0x02, OUTPUT_MESSAGE = 0x07, }; // https://receiverhelp.trimble.com/oem-gnss/ICD_Command64h_AppFile_Output.html#Output enum class Output_Msg_Msg_Type : uint8_t { GSOF = 10, }; // https://receiverhelp.trimble.com/oem-gnss/ICD_Command64h_AppFile_Output.html#Output2 enum class Gsof_Msg_Record_Type : uint8_t { POSITION_TIME = 1, LLH = 2, VELOCITY_DATA = 8, PDOP_INFO = 9, POSITION_SIGMA_INFO = 12, }; protected: // https://receiverhelp.trimble.com/oem-gnss/API_DataCollectorFormatPacketStructure.html static constexpr uint8_t MAX_PAYLOAD_SIZE = 255; // GSOF supports this many different packet types. // Only a fraction are supported by the simulator. // Waste some RAM and allocate arrays for the whole set. // https://receiverhelp.trimble.com/oem-gnss/ICD_Command64h_AppFile_Output.html#Output2 static constexpr uint8_t MAX_CHANNEL_NUM = 70; // Rates of dynamically enabled channels. // Assume factory behavior of no enabled channels. // Each channel can send data out at its own rate. Output_Rate channel_rates[MAX_CHANNEL_NUM] = {Output_Rate::OFF}; // Last publish time of dynamically enabled channels. uint32_t last_publish_ms[MAX_CHANNEL_NUM]; static uint32_t RateToPeriodMs(const Output_Rate rate); private: // Internal parser implementation state enum class Parse_State { WAITING_ON_STX, WAITING_ON_STATUS, WAITING_ON_PACKET_TYPE, WAITING_ON_LENGTH, WAITING_ON_PACKET_DATA, WAITING_ON_CSUM, WAITING_ON_ETX, }; bool valid_csum(); bool parse_payload(); // https://receiverhelp.trimble.com/oem-gnss/ICD_Pkt_Command64h_APPFILE.html bool parse_cmd_appfile(); // states for currently parsing packet Status status; Parse_State parse_state = {Parse_State::WAITING_ON_STX}; Packet_Type packet_type; // This is the length in the header. uint8_t expected_payload_length; // This is the increasing tally of bytes per packet. uint8_t cur_payload_idx; // This is the expected packet checksum in the trailer. uint8_t expected_csum; // The application file record transmission number uint8_t appfile_trans_num; uint8_t payload[MAX_PAYLOAD_SIZE]; // Clear all parser state/flags for handling a fresh packet. void reset(); }; class GPS_Trimble : public GPS_Backend, public DCOL_Parser { public: CLASS_NO_COPY(GPS_Trimble); using GPS_Backend::GPS_Backend; // GPS_Backend overrides void publish(const GPS_Data *d) override; void update_read() override; private: void send_gsof(const uint8_t *buf, const uint16_t size); // These packing utilities for GSOF perform a type-safe floating point byteswap. // They return integer types because returning floating points would involve an extra copy. uint64_t gsof_pack_double(const double& src) WARN_IF_UNUSED; uint32_t gsof_pack_float(const float& src) WARN_IF_UNUSED; }; }; #endif // AP_SIM_GPS_TRIMBLE_ENABLED