0.4.1
Loading...
Searching...
No Matches
KvhUartSensor.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 "KvhUartSensor.hpp"
10
11#include "KvhUtilities.hpp"
12#include "util/Logger.hpp"
13
15 : _name(std::move(name)), _buffer(uart::sensors::UartSensor::DefaultReadBufferSize)
16{
18}
19
30
32{
33 if (_eState == SM_IDLE)
34 {
35 if (ui8Data == ((HEADER_FMT_A >> 24U) & 0xFFU))
36 // || ui8Data == ((HEADER_FMT_B >> 24U) & 0xFFU)
37 // || ui8Data == ((HEADER_FMT_C >> 24U) & 0xFFU)
38 // || ui8Data == ((HEADER_FMT_XBIT >> 24U) & 0xFFU)
39 // || ui8Data == ((HEADER_FMT_XBIT2 >> 24U) & 0xFFU))
40 {
41 _eState = SM_H1;
42 }
43 }
44 else if (_eState == SM_H1)
45 {
46 if (ui8Data == ((HEADER_FMT_A >> 16U) & 0xFFU))
47 {
48 _eState = SM_H2;
49 }
50 else
51 {
53 }
54 }
55 else if (_eState == SM_H2)
56 {
57 if (ui8Data == ((HEADER_FMT_A >> 8U) & 0xFFU))
58 {
59 _eState = SM_H3;
60 }
61 else if (ui8Data == ((HEADER_FMT_XBIT >> 8U) & 0xFFU))
62 {
63 _eState = SM_X3;
64 }
65 else
66 {
68 }
69 }
70 else if (_eState == SM_H3)
71 {
72 if (ui8Data == (HEADER_FMT_A & 0xFFU))
73 {
75 return HeaderType::FMT_A;
76 }
77 if (ui8Data == (HEADER_FMT_B & 0xFFU))
78 {
80 return HeaderType::FMT_B;
81 }
82 if (ui8Data == (HEADER_FMT_C & 0xFFU))
83 {
85 return HeaderType::FMT_C;
86 }
87
89 }
90 else if (_eState == SM_X3)
91 {
92 if (ui8Data == (HEADER_FMT_XBIT & 0xFFU))
93 {
96 }
97 if (ui8Data == (HEADER_FMT_XBIT2 & 0xFFU))
98 {
101 }
102
104 }
105 else
106 {
108 }
109
111}
112
113std::unique_ptr<uart::protocol::Packet> NAV::vendor::kvh::KvhUartSensor::findPacket(uint8_t dataByte)
114{
115 if (_buffer.size() == _buffer.capacity())
116 {
117 // Buffer is full
119 LOG_ERROR("{}: Discarding current packet, because buffer is full.", _name);
120 }
121
122 auto binaryPacketType = bFindImuHeader(dataByte);
123 if (binaryPacketType != HeaderType::FMT_UNKNOWN)
124 {
126 _packetType = binaryPacketType;
128 uint32_t header{};
129 switch (binaryPacketType)
130 {
132 header = uart::stoh(HEADER_FMT_A, ENDIANNESS);
133 break;
135 header = uart::stoh(HEADER_FMT_B, ENDIANNESS);
136 break;
138 header = uart::stoh(HEADER_FMT_C, ENDIANNESS);
139 break;
141 header = uart::stoh(HEADER_FMT_XBIT, ENDIANNESS);
142 break;
144 header = uart::stoh(HEADER_FMT_XBIT2, ENDIANNESS);
145 break;
146 default:
147 break;
148 }
149 _buffer.resize(4);
150 memcpy(_buffer.data(), &header, 4);
151
152 return nullptr;
153 }
154
156 {
159 _buffer.push_back(dataByte);
160 }
162 {
163 _buffer.push_back(dataByte);
164
165 if ((_packetType == HeaderType::FMT_A && _buffer.size() == 36)
166 || (_packetType == HeaderType::FMT_B && _buffer.size() == 40)
167 || (_packetType == HeaderType::FMT_C && _buffer.size() == 38)
168 || (_packetType == HeaderType::FMT_XBIT && _buffer.size() == 11)
169 || (_packetType == HeaderType::FMT_XBIT2 && _buffer.size() == 13))
170 {
171 // We have a possible binary packet!
172 auto p = std::make_unique<uart::protocol::Packet>(_buffer, &_sensor);
173
174 if (p->isValid())
175 {
176 // We have a valid binary packet!!!.
177 LOG_DATA("{}: Valid binary packet: Type={}, Length={}", _name, fmt::underlying(_packetType), _buffer.size());
179 return p;
180 }
181 // Invalid packet!
182 LOG_DEBUG("{}: Invalid binary packet: Type={}, Length={}", _name, fmt::underlying(_packetType), _buffer.size());
184 }
185 if (_buffer.size() >= 40)
186 {
188 }
189 }
191 {
192 _buffer.push_back(dataByte);
193
194 if (dataByte == ASCII_ESCAPE_CHAR)
195 {
197 }
198 else if (dataByte == ASCII_END_CHAR_1)
199 {
200 _asciiEndChar1Found = true;
201 }
202 else if (_asciiEndChar1Found)
203 {
204 if (dataByte == ASCII_END_CHAR_2)
205 {
206 // We have a possible data packet
207 auto p = std::make_unique<uart::protocol::Packet>(_buffer, &_sensor);
208
209 if (p->isValid())
210 {
211 // We have a valid ascii packet!!!.
212 LOG_DATA("{}: Valid ascii packet: {}", _name, p->datastr().substr(0, p->getRawDataLength() - 2));
214 return p;
215 }
216 // Invalid packet!
217 LOG_ERROR("{}: Invalid ascii packet: {}", _name, p->datastr());
218 }
219
221 }
222
223 if (_buffer.size() >= MAX_SIZE_ASCII_PACKET)
224 {
225 LOG_ERROR("{}: Buffer exceeded the Maximum Ascii Packet Size", _name);
227 }
228 }
229
230 return nullptr;
231}
232
233void NAV::vendor::kvh::KvhUartSensor::packetFinderFunction(const std::vector<uint8_t>& data, const uart::xplat::TimeStamp& timestamp, uart::sensors::UartSensor::ValidPacketFoundHandler dispatchPacket, void* dispatchPacketUserData, void* userData)
234{
235 auto* sensor = static_cast<KvhUartSensor*>(userData);
236
237 for (size_t i = 0; i < data.size(); i++, sensor->_runningDataIndex++)
238 {
239 auto packetPointer = sensor->findPacket(data.at(i));
240
241 if (packetPointer != nullptr)
242 {
243 uart::protocol::Packet packet = *packetPointer;
244 dispatchPacket(dispatchPacketUserData, packet, sensor->_runningDataIndex, timestamp);
245 }
246 }
247}
248
249uart::protocol::Packet::Type NAV::vendor::kvh::KvhUartSensor::packetTypeFunction(const uart::protocol::Packet& packet)
250{
251 if (packet.getRawDataLength() < 1)
252 {
253 LOG_CRITICAL("Packet does not contain any data.");
254 }
255
256 // Check for carriage return and line feed
257 if (packet.getRawData().at(packet.getRawDataLength() - 2) == uart::CARRIAGE_RETURN
258 && packet.getRawData().at(packet.getRawDataLength() - 1) == uart::LINE_FEED)
259 {
260 return uart::protocol::Packet::Type::TYPE_ASCII;
261 }
262
263 uint32_t data_zero{};
264 memcpy(&data_zero, packet.getRawData().data(), sizeof(uint32_t));
265 data_zero = uart::stoh(data_zero, ENDIANNESS);
266
267 if (data_zero == HEADER_FMT_A || data_zero == HEADER_FMT_B || data_zero == HEADER_FMT_C)
268 {
269 return uart::protocol::Packet::Type::TYPE_BINARY;
270 }
271
272 return uart::protocol::Packet::Type::TYPE_UNKNOWN;
273}
274
275bool NAV::vendor::kvh::KvhUartSensor::checksumFunction(const uart::protocol::Packet& packet)
276{
277 // minumum binary packet is 9 bytes
278 if (packet.getRawDataLength() < 1)
279 {
280 return false;
281 }
282
283 if (packet.type() == uart::protocol::Packet::Type::TYPE_ASCII)
284 {
285 // Ascii does not have a checksum
286 return true;
287 }
288
289 if (packet.type() == uart::protocol::Packet::Type::TYPE_BINARY)
290 {
291 uint32_t checksumCalc = kvh::ui32CalcImuCRC(packet.getRawData());
292
293 uint32_t checksumPacket = 0;
294 memcpy(&checksumPacket, packet.getRawData().data() + packet.getRawDataLength() - sizeof(uint32_t), sizeof(uint32_t));
295 checksumPacket = uart::stoh(checksumPacket, ENDIANNESS);
296
297 return checksumPacket == checksumCalc;
298 }
299
300 LOG_CRITICAL("Can't calculate checksum of packet with unknown type");
301 return false;
302}
303
304bool NAV::vendor::kvh::KvhUartSensor::isErrorFunction([[maybe_unused]] const uart::protocol::Packet& packet)
305{
306 return false;
307}
308
309bool NAV::vendor::kvh::KvhUartSensor::isResponseFunction([[maybe_unused]] const uart::protocol::Packet& packet)
310{
311 return false;
312}
Class to read out KVH Sensors.
Helper Functions to work with Kvh 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 constexpr uint32_t HEADER_FMT_XBIT2
Header Format X Bit 2.
HeaderType _packetType
Current packet type determined by the header.
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.
static constexpr uint32_t HEADER_FMT_A
Header Format A.
static constexpr uint32_t HEADER_FMT_B
Header Format B.
std::unique_ptr< uart::protocol::Packet > findPacket(uint8_t dataByte)
Collects data bytes and searches for packages inside of them.
static bool checksumFunction(const uart::protocol::Packet &packet)
Function which is called to verify packet integrity.
bool _asciiEndChar1Found
Flag if the first ascii end character was found.
const std::string _name
Name of the Parent Node.
static constexpr uart::Endianness ENDIANNESS
Endianess of the sensor.
void resetTracking()
Resets the current message tracking.
std::vector< uint8_t > _buffer
Buffer to collect messages till they are complete.
uart::sensors::UartSensor _sensor
UartSensor object which handles the UART interface.
static constexpr uint8_t ASCII_END_CHAR_1
First Ascii End character.
bool _currentlyBuildingBinaryPacket
Flag if currently a binary packet is built.
HeaderType
Possible Header Types.
static uart::protocol::Packet::Type packetTypeFunction(const uart::protocol::Packet &packet)
Function which is called to determine the packet type (ascii/binary)
static constexpr uint32_t HEADER_FMT_C
Header Format C.
static bool isErrorFunction(const uart::protocol::Packet &packet)
Function which determines, if the packet is an Error Packet.
static constexpr uint32_t HEADER_FMT_XBIT
Header Format X Bit.
static constexpr uint8_t ASCII_END_CHAR_2
Second Ascii End character.
KvhUartSensor(std::string name)
Constructor.
static constexpr size_t MAX_SIZE_ASCII_PACKET
Maximum size of a ascii packet before resetting it.
static constexpr uint8_t ASCII_ESCAPE_CHAR
Ascii Escape charater.
TagState _eState
Current state of the header building process.
HeaderType bFindImuHeader(uint8_t ui8Data)
Function which finds the header from the provided data.
bool _currentlyBuildingAsciiPacket
Flag if currently a ascii packet is built.
KvhUartSensor()=default
Default constructor.
static bool isResponseFunction(const uart::protocol::Packet &packet)
Function which determines, if the packet is a Response.
uint32_t ui32CalcImuCRC(const std::vector< uint8_t > &rawData)
Calculates the checksum of the provided rawData 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