| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
| 2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
| 3 | // the University of Stuttgart, Germany. | ||
| 4 | // | ||
| 5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
| 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| 7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
| 8 | |||
| 9 | /// @file EmlidUartSensor.hpp | ||
| 10 | /// @brief Class to read out Emlid Sensors | ||
| 11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
| 12 | /// @date 2020-07-22 | ||
| 13 | |||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #include <memory> | ||
| 17 | |||
| 18 | #include "uart/sensors/sensors.hpp" | ||
| 19 | |||
| 20 | namespace NAV::vendor::emlid | ||
| 21 | { | ||
| 22 | /// @brief Class to read out Emlid Sensors | ||
| 23 | class EmlidUartSensor | ||
| 24 | { | ||
| 25 | public: | ||
| 26 | /// @brief Constructor | ||
| 27 | /// @param[in] name Name of the Parent Node | ||
| 28 | explicit EmlidUartSensor(std::string name); | ||
| 29 | |||
| 30 | /// @brief Default constructor | ||
| 31 | EmlidUartSensor() = default; | ||
| 32 | /// @brief Destructor | ||
| 33 | 228 | ~EmlidUartSensor() = default; | |
| 34 | /// @brief Copy constructor | ||
| 35 | EmlidUartSensor(const EmlidUartSensor&) = delete; | ||
| 36 | /// @brief Move constructor | ||
| 37 | EmlidUartSensor(EmlidUartSensor&&) = delete; | ||
| 38 | /// @brief Copy assignment operator | ||
| 39 | EmlidUartSensor& operator=(const EmlidUartSensor&) = delete; | ||
| 40 | /// @brief Move assignment operator | ||
| 41 | EmlidUartSensor& operator=(EmlidUartSensor&&) = delete; | ||
| 42 | /// @brief Arrow operator overload | ||
| 43 | ✗ | uart::sensors::UartSensor* operator->() { return &_sensor; }; | |
| 44 | |||
| 45 | /// @brief Collects data bytes and searches for packages inside of them | ||
| 46 | /// @param[in] dataByte The next data byte | ||
| 47 | /// @return nullptr if no packet found yet, otherwise a pointer to the packet | ||
| 48 | std::unique_ptr<uart::protocol::Packet> findPacket(uint8_t dataByte); | ||
| 49 | |||
| 50 | static constexpr uint8_t BINARY_SYNC_CHAR_1 = 0x82; ///< R - First sync character which begins a new binary message | ||
| 51 | static constexpr uint8_t BINARY_SYNC_CHAR_2 = 0x45; ///< E - Second sync character which begins a new binary message | ||
| 52 | static constexpr uint8_t ASCII_START_CHAR = '$'; ///< Ascii character which begins a new ascii message | ||
| 53 | |||
| 54 | private: | ||
| 55 | /// Name of the Parent Node | ||
| 56 | const std::string _name; | ||
| 57 | |||
| 58 | /// UartSensor object which handles the UART interface | ||
| 59 | uart::sensors::UartSensor _sensor{ ENDIANNESS, | ||
| 60 | packetFinderFunction, | ||
| 61 | this, | ||
| 62 | packetTypeFunction, | ||
| 63 | checksumFunction, | ||
| 64 | isErrorFunction, | ||
| 65 | isResponseFunction, | ||
| 66 | PACKET_HEADER_LENGTH }; | ||
| 67 | |||
| 68 | /// @brief Function which is called to find packets in the provided data buffer | ||
| 69 | /// @param[in] data Raw data buffer which has potential packets inside | ||
| 70 | /// @param[in] timestamp Timestamp then the data in the buffer was received | ||
| 71 | /// @param[in] dispatchPacket Function to call when a complete packet was found | ||
| 72 | /// @param[in] dispatchPacketUserData User data to forward to the dispatchPacket function | ||
| 73 | /// @param[in] userData User data provided when regisering this function. Should contain the sensor object | ||
| 74 | static void packetFinderFunction(const std::vector<uint8_t>& data, | ||
| 75 | const uart::xplat::TimeStamp& timestamp, | ||
| 76 | uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void* dispatchPacketUserData, | ||
| 77 | void* userData); | ||
| 78 | |||
| 79 | /// @brief Function which is called to determine the packet type (ascii/binary) | ||
| 80 | /// @param[in] packet Packet to check the type of | ||
| 81 | /// @return The type of the packet | ||
| 82 | static uart::protocol::Packet::Type packetTypeFunction(const uart::protocol::Packet& packet); | ||
| 83 | |||
| 84 | /// @brief Function which is called to verify packet integrity | ||
| 85 | /// @param[in] packet Packet to calculate the checksum for | ||
| 86 | /// @return True if the packet is fault free | ||
| 87 | static bool checksumFunction(const uart::protocol::Packet& packet); | ||
| 88 | |||
| 89 | /// @brief Function which determines, if the packet is an Error Packet | ||
| 90 | /// @param[in] packet The packet to check | ||
| 91 | static bool isErrorFunction(const uart::protocol::Packet& packet); | ||
| 92 | |||
| 93 | /// @brief Function which determines, if the packet is a Response | ||
| 94 | /// @param[in] packet The packet to check | ||
| 95 | static bool isResponseFunction(const uart::protocol::Packet& packet); | ||
| 96 | |||
| 97 | static constexpr uart::Endianness ENDIANNESS = uart::Endianness::ENDIAN_LITTLE; ///< Endianess of the sensor | ||
| 98 | static constexpr size_t PACKET_HEADER_LENGTH = 2; ///< Length of the header of each packet | ||
| 99 | static constexpr uint8_t ASCII_END_CHAR_1 = '\r'; ///< First Ascii End character | ||
| 100 | static constexpr uint8_t ASCII_END_CHAR_2 = '\n'; ///< Second Ascii End character | ||
| 101 | static constexpr uint8_t ASCII_ESCAPE_CHAR = '\0'; ///< Ascii Escape charater | ||
| 102 | |||
| 103 | bool _currentlyBuildingAsciiPacket{ false }; ///< Flag if currently a ascii packet is built | ||
| 104 | bool _currentlyBuildingBinaryPacket{ false }; ///< Flag if currently a binary packet is built | ||
| 105 | |||
| 106 | bool _asciiEndChar1Found{ false }; ///< Flag if the first ascii end character was found | ||
| 107 | bool _binarySyncChar2Found{ false }; ///< Flag if the second binary end character was found | ||
| 108 | bool _binaryMsgIdFound{ false }; ///< Flag if the message id was found | ||
| 109 | bool _binaryPayloadLength1Found{ false }; ///< Flag if the first byte of the payload length was found | ||
| 110 | bool _binaryPayloadLength2Found{ false }; ///< Flag if the second byte of the payload length was found | ||
| 111 | |||
| 112 | /// Message id of the current packet | ||
| 113 | uint8_t _binaryMsgId{ 0 }; | ||
| 114 | /// Payload length of the current packet | ||
| 115 | uint16_t _binaryPayloadLength{ 0 }; | ||
| 116 | |||
| 117 | /// Buffer to collect messages till they are complete | ||
| 118 | std::vector<uint8_t> _buffer; | ||
| 119 | |||
| 120 | /// Used for correlating raw data with where the packet was found for the end user. | ||
| 121 | size_t _runningDataIndex{ 0 }; | ||
| 122 | /// Amount of bytes remaining for a complete packet | ||
| 123 | size_t _numOfBytesRemainingForCompletePacket{ 0 }; | ||
| 124 | |||
| 125 | /// @brief Resets the current message tracking | ||
| 126 | void resetTracking(); | ||
| 127 | }; | ||
| 128 | |||
| 129 | } // namespace NAV::vendor::emlid | ||
| 130 |