0.3.0
Loading...
Searching...
No Matches
EmlidUartSensor.cpp
Go to the documentation of this file.
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#include "EmlidUartSensor.hpp"
10
11#include "EmlidUtilities.hpp"
12#include "util/Logger.hpp"
13
15 : _name(std::move(name)), _buffer(uart::sensors::UartSensor::DefaultReadBufferSize)
16{
18}
19
37
38std::unique_ptr<uart::protocol::Packet> NAV::vendor::emlid::EmlidUartSensor::findPacket(uint8_t dataByte)
39{
40 if (_buffer.size() == _buffer.capacity())
41 {
42 // Buffer is full
44 LOG_ERROR("{}: Discarding current packet, because buffer is full.", _name);
45 }
46
48 {
49 // This byte must be the start char
50 if (dataByte == BINARY_SYNC_CHAR_1)
51 {
54 _buffer.push_back(dataByte);
55 }
56 else if (dataByte == ASCII_START_CHAR)
57 {
60 _buffer.push_back(dataByte);
61 }
62 }
64 {
65 _buffer.push_back(dataByte);
66
68 {
69 // This byte must be the second sync char
70 if (dataByte == BINARY_SYNC_CHAR_2)
71 {
73 }
74 else
75 {
77 }
78 }
79 else if (!_binaryMsgIdFound)
80 {
81 // This byte must be the message id
82 _binaryMsgIdFound = true;
83 _binaryMsgId = dataByte;
84 }
86 {
88 _binaryPayloadLength = static_cast<uint16_t>(dataByte);
89 }
91 {
93 _binaryPayloadLength |= static_cast<uint16_t>(static_cast<uint16_t>(dataByte) << 8U);
96 LOG_DATA("{}: Binary packet: Id={:0x}, payload length={}", _name, _binaryMsgId, _binaryPayloadLength);
97 }
98 else
99 {
100 // We are currently collecting data for our packet.
102
104 {
105 // We have a possible binary packet!
106 auto p = std::make_unique<uart::protocol::Packet>(_buffer, &_sensor);
107
108 if (p->isValid())
109 {
110 // We have a valid binary packet!!!.
112 return p;
113 }
114 // Invalid packet!
115 LOG_DEBUG("{}: Invalid binary packet: Id={:0x}, payload length={}", _name, _binaryMsgId, _binaryPayloadLength);
117 }
118 }
119 }
121 {
122 _buffer.push_back(dataByte);
123
124 if (dataByte == ASCII_ESCAPE_CHAR)
125 {
127 }
128 else if (dataByte == ASCII_END_CHAR_1)
129 {
130 _asciiEndChar1Found = true;
131 }
132 else if (_asciiEndChar1Found)
133 {
134 if (dataByte == ASCII_END_CHAR_2)
135 {
136 // We have a possible data packet
137 auto p = std::make_unique<uart::protocol::Packet>(_buffer, &_sensor);
138
139 if (p->isValid())
140 {
141 // We have a valid ascii packet!!!.
142 LOG_DATA("{}: Valid ascii packet: {}", _name, p->datastr().substr(0, p->getRawDataLength() - 2));
144 return p;
145 }
146 // Invalid packet!
147 LOG_ERROR("Invalid ascii packet: {}", p->datastr());
148 }
149
151 }
152 }
153
154 return nullptr;
155}
156
157void NAV::vendor::emlid::EmlidUartSensor::packetFinderFunction(const std::vector<uint8_t>& data, const uart::xplat::TimeStamp& timestamp, uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void* dispatchPacketUserData, void* userData)
158{
159 auto* sensor = static_cast<EmlidUartSensor*>(userData);
160
161 for (size_t i = 0; i < data.size(); i++, sensor->_runningDataIndex++)
162 {
163 auto packetPointer = sensor->findPacket(data.at(i));
164
165 if (packetPointer != nullptr)
166 {
167 uart::protocol::Packet packet = *packetPointer;
168 dispatchPacket(dispatchPacketUserData, packet, sensor->_runningDataIndex, timestamp);
169 }
170 }
171}
172
173uart::protocol::Packet::Type NAV::vendor::emlid::EmlidUartSensor::packetTypeFunction(const uart::protocol::Packet& packet)
174{
175 if (packet.getRawDataLength() < 1)
176 {
177 LOG_CRITICAL("Packet does not contain any data.");
178 }
179
180 if (packet.getRawData().at(0) == '$')
181 {
182 return uart::protocol::Packet::Type::TYPE_ASCII;
183 }
184 if (packet.getRawData().at(0) == BINARY_SYNC_CHAR_1)
185 {
186 if (packet.getRawData().at(1) == BINARY_SYNC_CHAR_2)
187 {
188 return uart::protocol::Packet::Type::TYPE_BINARY;
189 }
190 }
191
192 return uart::protocol::Packet::Type::TYPE_UNKNOWN;
193}
194
195bool NAV::vendor::emlid::EmlidUartSensor::checksumFunction(const uart::protocol::Packet& packet)
196{
197 if (packet.getRawDataLength() <= 8)
198 {
199 return false;
200 }
201
202 if (packet.type() == uart::protocol::Packet::Type::TYPE_ASCII)
203 {
204 return true;
205 }
206
207 if (packet.type() == uart::protocol::Packet::Type::TYPE_BINARY)
208 {
209 std::pair<uint8_t, uint8_t> checksum = emlid::checksumUBX(packet.getRawData());
210
211 return packet.getRawData().at(packet.getRawDataLength() - 2) == checksum.first
212 && packet.getRawData().at(packet.getRawDataLength() - 1) == checksum.second;
213 }
214
215 LOG_CRITICAL("Can't calculate checksum of packet with unknown type");
216 return false;
217}
218
219bool NAV::vendor::emlid::EmlidUartSensor::isErrorFunction([[maybe_unused]] const uart::protocol::Packet& packet)
220{
221 return false;
222}
223
224bool NAV::vendor::emlid::EmlidUartSensor::isResponseFunction([[maybe_unused]] const uart::protocol::Packet& packet)
225{
226 return false;
227}
Class to read out Emlid Sensors.
Helper Functions to work with Emlid Sensors.
Utility class for logging to console and file.
#define LOG_CRITICAL(...)
Critical Event, which causes the program to work entirely and throws an exception.
Definition Logger.hpp:75
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
Definition Logger.hpp:73
Abstract Uart Sensor Class.
static uart::protocol::Packet::Type packetTypeFunction(const uart::protocol::Packet &packet)
Function which is called to determine the packet type (ascii/binary)
bool _binaryPayloadLength1Found
Flag if the first byte of the payload length was found.
bool _binarySyncChar2Found
Flag if the second binary end character was found.
bool _binaryPayloadLength2Found
Flag if the second byte of the payload length was found.
bool _binaryMsgIdFound
Flag if the message id was found.
bool _currentlyBuildingAsciiPacket
Flag if currently a ascii packet is built.
static bool isErrorFunction(const uart::protocol::Packet &packet)
Function which determines, if the packet is an Error Packet.
static constexpr uint8_t ASCII_END_CHAR_1
First Ascii End character.
static bool isResponseFunction(const uart::protocol::Packet &packet)
Function which determines, if the packet is a Response.
std::vector< uint8_t > _buffer
Buffer to collect messages till they are complete.
void resetTracking()
Resets the current message tracking.
static constexpr uart::Endianness ENDIANNESS
Endianess of the sensor.
static constexpr uint8_t BINARY_SYNC_CHAR_2
E - Second sync character which begins a new binary message.
static bool checksumFunction(const uart::protocol::Packet &packet)
Function which is called to verify packet integrity.
uint16_t _binaryPayloadLength
Payload length of the current packet.
const std::string _name
Name of the Parent Node.
EmlidUartSensor()=default
Default constructor.
static constexpr uint8_t ASCII_START_CHAR
Ascii character which begins a new ascii message.
size_t _numOfBytesRemainingForCompletePacket
Amount of bytes remaining for a complete packet.
static constexpr uint8_t ASCII_ESCAPE_CHAR
Ascii Escape charater.
uart::sensors::UartSensor _sensor
UartSensor object which handles the UART interface.
std::unique_ptr< uart::protocol::Packet > findPacket(uint8_t dataByte)
Collects data bytes and searches for packages inside of them.
static constexpr uint8_t ASCII_END_CHAR_2
Second Ascii End character.
uint8_t _binaryMsgId
Message id of the current packet.
static void packetFinderFunction(const std::vector< uint8_t > &data, const uart::xplat::TimeStamp &timestamp, uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void *dispatchPacketUserData, void *userData)
Function which is called to find packets in the provided data buffer.
EmlidUartSensor(std::string name)
Constructor.
bool _asciiEndChar1Found
Flag if the first ascii end character was found.
static constexpr uint8_t BINARY_SYNC_CHAR_1
R - First sync character which begins a new binary message.
bool _currentlyBuildingBinaryPacket
Flag if currently a binary packet is built.
std::pair< uint8_t, uint8_t > checksumUBX(const std::vector< uint8_t > &data)
Calculates the two UBX checksums for the provided data vector.
void move(std::vector< T > &v, size_t sourceIdx, size_t targetIdx)
Moves an element within a vector to a new position.
Definition Vector.hpp:27