| 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 Ln200UartSensor.hpp | ||
| 10 | /// @brief Class to read out LN-200 Sensors | ||
| 11 | /// @author M. Senger (st166640@stud.uni-stuttgart.de) | ||
| 12 | /// @date 2025-03-18 | ||
| 13 | |||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #include <memory> | ||
| 17 | #include "util/Container/ScrollingBuffer.hpp" | ||
| 18 | |||
| 19 | #include "uart/sensors/sensors.hpp" | ||
| 20 | |||
| 21 | namespace NAV::vendor::ln | ||
| 22 | { | ||
| 23 | /// @brief Class to read out LN-200 Sensors | ||
| 24 | /// @details The class is used to read out the LN-200 IMU via UART with 2000 | ||
| 25 | /// @note The UART interface is configured to 2Mbit/s, 8N1 set by the IMU Uart interface microcontroller. | ||
| 26 | /// The following commands are needed to set up the UART interface: | ||
| 27 | /// sudo usermod -a -G dialout "username" | ||
| 28 | /// sudo dmesg | grep -i tty -> find connected device | ||
| 29 | /// stty -F /dev/"device" -raw 2000000 cs8 -cstopb -parenb | ||
| 30 | /// | ||
| 31 | /// Message content mapping: | ||
| 32 | /// - Word Index 0: X_VEL - X Delta Velocity | ||
| 33 | /// - Word Index 1: Y_VEL - Y Delta Velocity | ||
| 34 | /// - Word Index 2: Z_VEL - Z Delta Velocity | ||
| 35 | /// - Word Index 3: X_ANG - X Delta Angle | ||
| 36 | /// - Word Index 4: Y_ANG - Y Delta Angle | ||
| 37 | /// - Word Index 5: Z_ANG - Z Delta Angle | ||
| 38 | /// - Word Index 6: STATUS - IMU Status Summary Word | ||
| 39 | /// - Word Index 7: MUX_ID - Mode Bit/MUX ID | ||
| 40 | /// - Word Index 8: MUX_DATA - Mux Data Word | ||
| 41 | /// - Word Index 9: X_RAW_COUNT - X Raw Gyro Counts | ||
| 42 | /// - Word Index 10: Y_RAW_COUNT - Y Raw Gyro Counts | ||
| 43 | /// - Word Index 11: Z_RAW_COUNT - Z Raw Gyro Counts | ||
| 44 | /// - Word Index 12: INTERNAL_CHECK_SUM - Internal Check Sum | ||
| 45 | /// - Word Index 13: EXTERNAL_CHECK_SUM - External Check Sum | ||
| 46 | class Ln200UartSensor | ||
| 47 | { | ||
| 48 | public: | ||
| 49 | /// @brief Constructor | ||
| 50 | /// @param[in] name Name of the Parent Node | ||
| 51 | explicit Ln200UartSensor(std::string name); | ||
| 52 | |||
| 53 | /// @brief Default constructor | ||
| 54 |
3/6✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 114 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 114 times.
✗ Branch 9 not taken.
|
114 | Ln200UartSensor() = default; |
| 55 | /// @brief Destructor | ||
| 56 | 114 | ~Ln200UartSensor() = default; | |
| 57 | /// @brief Copy constructor | ||
| 58 | Ln200UartSensor(const Ln200UartSensor&) = delete; | ||
| 59 | /// @brief Move constructor | ||
| 60 | Ln200UartSensor(Ln200UartSensor&&) = delete; | ||
| 61 | /// @brief Copy assignment operator | ||
| 62 | Ln200UartSensor& operator=(const Ln200UartSensor&) = delete; | ||
| 63 | /// @brief Move assignment operator | ||
| 64 | Ln200UartSensor& operator=(Ln200UartSensor&&) = delete; | ||
| 65 | /// @brief Arrow operator overload | ||
| 66 | ✗ | uart::sensors::UartSensor* operator->() { return &_sensor; }; | |
| 67 | |||
| 68 | /// @brief Collects data bytes and searches for packages inside of them | ||
| 69 | /// @param[in] dataByte The next data byte | ||
| 70 | /// @return nullptr if no packet found yet, otherwise a pointer to the packet | ||
| 71 | std::unique_ptr<uart::protocol::Packet> findPacket(uint8_t dataByte); | ||
| 72 | |||
| 73 | private: | ||
| 74 | /// Name of the Parent Node | ||
| 75 | const std::string _name; | ||
| 76 | |||
| 77 | /// UartSensor object which handles the UART interface | ||
| 78 | uart::sensors::UartSensor _sensor{ ENDIANNESS, | ||
| 79 | packetFinderFunction, | ||
| 80 | this, | ||
| 81 | packetTypeFunction, | ||
| 82 | checksumFunction, | ||
| 83 | isErrorFunction, | ||
| 84 | isResponseFunction, | ||
| 85 | PACKET_HEADER_LENGTH }; | ||
| 86 | |||
| 87 | /// @brief Function which is called to find packets in the provided data buffer | ||
| 88 | /// @param[in] data Raw data buffer which has potential packets inside | ||
| 89 | /// @param[in] timestamp Timestamp then the data in the buffer was received | ||
| 90 | /// @param[in] dispatchPacket Function to call when a complete packet was found | ||
| 91 | /// @param[in] dispatchPacketUserData User data to forward to the dispatchPacket function | ||
| 92 | /// @param[in] userData User data provided when regisering this function. Should contain the sensor object | ||
| 93 | static void packetFinderFunction(const std::vector<uint8_t>& data, | ||
| 94 | const uart::xplat::TimeStamp& timestamp, | ||
| 95 | uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void* dispatchPacketUserData, | ||
| 96 | void* userData); | ||
| 97 | |||
| 98 | /// @brief Function which is called to determine the packet type (ascii/binary) | ||
| 99 | /// @param[in] packet Packet to check the type of | ||
| 100 | /// @return The type of the packet | ||
| 101 | static uart::protocol::Packet::Type packetTypeFunction(const uart::protocol::Packet& packet); | ||
| 102 | |||
| 103 | /// @brief Function which is called to verify packet integrity | ||
| 104 | /// @param[in] packet Packet to calculate the checksum for | ||
| 105 | /// @return True if the packet is fault free | ||
| 106 | static bool checksumFunction(const uart::protocol::Packet& packet); | ||
| 107 | |||
| 108 | /// @brief Function which determines, if the packet is an Error Packet | ||
| 109 | /// @param[in] packet The packet to check | ||
| 110 | static bool isErrorFunction(const uart::protocol::Packet& packet); | ||
| 111 | |||
| 112 | /// @brief Function which determines, if the packet is a Response | ||
| 113 | /// @param[in] packet The packet to check | ||
| 114 | static bool isResponseFunction(const uart::protocol::Packet& packet); | ||
| 115 | |||
| 116 | static constexpr uart::Endianness ENDIANNESS = uart::Endianness::ENDIAN_LITTLE; ///< Endianess of the sensor | ||
| 117 | static constexpr size_t PACKET_HEADER_LENGTH = 0; ///< Length of the packet header | ||
| 118 | static constexpr size_t MAX_SIZE_ASCII_PACKET = 256; ///< Maximum size of a ascii packet before resetting it | ||
| 119 | |||
| 120 | /// Operational states of the LN-200 UART sensor node. | ||
| 121 | enum class State : uint8_t | ||
| 122 | { | ||
| 123 | Idle, ///< Sensor is idle. | ||
| 124 | Receiving ///< Sensor is receiving data. | ||
| 125 | }; | ||
| 126 | |||
| 127 | /// Internal state of the sensor. | ||
| 128 | State _state = State::Idle; | ||
| 129 | |||
| 130 | /// Buffer to accumulate bits of the current frame. | ||
| 131 | ScrollingBuffer<bool> _bitBuffer; | ||
| 132 | |||
| 133 | /// Sliding window buffer to detect flags. | ||
| 134 | ScrollingBuffer<bool> _flagWindow; | ||
| 135 | |||
| 136 | /// Flag to detect the start of a frame. | ||
| 137 | bool _wasIdle = false; | ||
| 138 | |||
| 139 | /// Counter for bit insertion. | ||
| 140 | int _consecutiveOnes = 0; | ||
| 141 | |||
| 142 | /// Used for correlating raw data with where the packet was found for the end user. | ||
| 143 | size_t _runningDataIndex{ 0 }; | ||
| 144 | }; | ||
| 145 | |||
| 146 | } // namespace NAV::vendor::ln | ||
| 147 |