| 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 KvhUartSensor.hpp | ||
| 10 | /// @brief Class to read out KVH Sensors | ||
| 11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
| 12 | /// @date 2020-07-28 | ||
| 13 | |||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #include <memory> | ||
| 17 | |||
| 18 | #include "uart/sensors/sensors.hpp" | ||
| 19 | |||
| 20 | namespace NAV::vendor::kvh | ||
| 21 | { | ||
| 22 | /// @brief Class to read out KVH Sensors | ||
| 23 | class KvhUartSensor | ||
| 24 | { | ||
| 25 | public: | ||
| 26 | /// @brief Constructor | ||
| 27 | /// @param[in] name Name of the Parent Node | ||
| 28 | explicit KvhUartSensor(std::string name); | ||
| 29 | |||
| 30 | /// @brief Default constructor | ||
| 31 |
1/2✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
|
114 | KvhUartSensor() = default; |
| 32 | /// @brief Destructor | ||
| 33 | 228 | ~KvhUartSensor() = default; | |
| 34 | /// @brief Copy constructor | ||
| 35 | KvhUartSensor(const KvhUartSensor&) = delete; | ||
| 36 | /// @brief Move constructor | ||
| 37 | KvhUartSensor(KvhUartSensor&&) = delete; | ||
| 38 | /// @brief Copy assignment operator | ||
| 39 | KvhUartSensor& operator=(const KvhUartSensor&) = delete; | ||
| 40 | /// @brief Move assignment operator | ||
| 41 | KvhUartSensor& operator=(KvhUartSensor&&) = 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 uint32_t HEADER_FMT_A = 0xFE81FF55; ///< Header Format A | ||
| 51 | static constexpr uint32_t HEADER_FMT_B = 0xFE81FF56; ///< Header Format B | ||
| 52 | static constexpr uint32_t HEADER_FMT_C = 0xFE81FF57; ///< Header Format C | ||
| 53 | static constexpr uint32_t HEADER_FMT_XBIT = 0xFE8100AA; ///< Header Format X Bit | ||
| 54 | static constexpr uint32_t HEADER_FMT_XBIT2 = 0xFE8100AB; ///< Header Format X Bit 2 | ||
| 55 | |||
| 56 | static constexpr uart::Endianness ENDIANNESS = uart::Endianness::ENDIAN_BIG; ///< Endianess of the sensor | ||
| 57 | |||
| 58 | private: | ||
| 59 | /// Name of the Parent Node | ||
| 60 | const std::string _name; | ||
| 61 | |||
| 62 | /// UartSensor object which handles the UART interface | ||
| 63 | uart::sensors::UartSensor _sensor{ ENDIANNESS, | ||
| 64 | packetFinderFunction, | ||
| 65 | this, | ||
| 66 | packetTypeFunction, | ||
| 67 | checksumFunction, | ||
| 68 | isErrorFunction, | ||
| 69 | isResponseFunction, | ||
| 70 | PACKET_HEADER_LENGTH }; | ||
| 71 | |||
| 72 | /// @brief Function which is called to find packets in the provided data buffer | ||
| 73 | /// @param[in] data Raw data buffer which has potential packets inside | ||
| 74 | /// @param[in] timestamp Timestamp then the data in the buffer was received | ||
| 75 | /// @param[in] dispatchPacket Function to call when a complete packet was found | ||
| 76 | /// @param[in] dispatchPacketUserData User data to forward to the dispatchPacket function | ||
| 77 | /// @param[in] userData User data provided when regisering this function. Should contain the sensor object | ||
| 78 | static void packetFinderFunction(const std::vector<uint8_t>& data, | ||
| 79 | const uart::xplat::TimeStamp& timestamp, | ||
| 80 | uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void* dispatchPacketUserData, | ||
| 81 | void* userData); | ||
| 82 | |||
| 83 | /// @brief Function which is called to determine the packet type (ascii/binary) | ||
| 84 | /// @param[in] packet Packet to check the type of | ||
| 85 | /// @return The type of the packet | ||
| 86 | static uart::protocol::Packet::Type packetTypeFunction(const uart::protocol::Packet& packet); | ||
| 87 | |||
| 88 | /// @brief Function which is called to verify packet integrity | ||
| 89 | /// @param[in] packet Packet to calculate the checksum for | ||
| 90 | /// @return True if the packet is fault free | ||
| 91 | static bool checksumFunction(const uart::protocol::Packet& packet); | ||
| 92 | |||
| 93 | /// @brief Function which determines, if the packet is an Error Packet | ||
| 94 | /// @param[in] packet The packet to check | ||
| 95 | static bool isErrorFunction(const uart::protocol::Packet& packet); | ||
| 96 | |||
| 97 | /// @brief Function which determines, if the packet is a Response | ||
| 98 | /// @param[in] packet The packet to check | ||
| 99 | static bool isResponseFunction(const uart::protocol::Packet& packet); | ||
| 100 | |||
| 101 | static constexpr size_t PACKET_HEADER_LENGTH = 0; ///< Length of the packet header | ||
| 102 | |||
| 103 | static constexpr uint8_t ASCII_END_CHAR_1 = '\r'; ///< First Ascii End character | ||
| 104 | static constexpr uint8_t ASCII_END_CHAR_2 = '\n'; ///< Second Ascii End character | ||
| 105 | static constexpr uint8_t ASCII_ESCAPE_CHAR = '\0'; ///< Ascii Escape charater | ||
| 106 | static constexpr size_t MAX_SIZE_ASCII_PACKET = 256; ///< Maximum size of a ascii packet before resetting it | ||
| 107 | |||
| 108 | bool _currentlyBuildingAsciiPacket{ false }; ///< Flag if currently a ascii packet is built | ||
| 109 | bool _currentlyBuildingBinaryPacket{ false }; ///< Flag if currently a binary packet is built | ||
| 110 | |||
| 111 | bool _asciiEndChar1Found{ false }; ///< Flag if the first ascii end character was found | ||
| 112 | |||
| 113 | /// @brief Possible states in the header building process | ||
| 114 | enum TagState : uint8_t | ||
| 115 | { | ||
| 116 | SM_H1, ///< H1 | ||
| 117 | SM_H2, ///< H2 | ||
| 118 | SM_H3, ///< H3 | ||
| 119 | SM_X3, ///< X3 | ||
| 120 | SM_IDLE, ///< IDLE | ||
| 121 | }; | ||
| 122 | |||
| 123 | /// Current state of the header building process | ||
| 124 | TagState _eState = SM_IDLE; | ||
| 125 | |||
| 126 | /// @brief Possible Header Types | ||
| 127 | enum HeaderType : uint8_t | ||
| 128 | { | ||
| 129 | FMT_A, ///< Use header A | ||
| 130 | FMT_B, ///< Use header B | ||
| 131 | FMT_C, ///< Use header C | ||
| 132 | FMT_XBIT, ///< Format XBIT | ||
| 133 | FMT_XBIT2, ///< Format XBIT2 | ||
| 134 | FMT_UNKNOWN, ///< Unknown format | ||
| 135 | }; | ||
| 136 | |||
| 137 | /// @brief Current packet type determined by the header | ||
| 138 | HeaderType _packetType = HeaderType::FMT_UNKNOWN; | ||
| 139 | |||
| 140 | /// @brief Function which finds the header from the provided data | ||
| 141 | /// @param[in] ui8Data Byte to construct the header from | ||
| 142 | /// @return Header type if found or unkown | ||
| 143 | HeaderType bFindImuHeader(uint8_t ui8Data); | ||
| 144 | |||
| 145 | /// Buffer to collect messages till they are complete | ||
| 146 | std::vector<uint8_t> _buffer; | ||
| 147 | |||
| 148 | /// Used for correlating raw data with where the packet was found for the end user. | ||
| 149 | size_t _runningDataIndex{ 0 }; | ||
| 150 | |||
| 151 | /// @brief Resets the current message tracking | ||
| 152 | void resetTracking(); | ||
| 153 | }; | ||
| 154 | |||
| 155 | } // namespace NAV::vendor::kvh | ||
| 156 |