0.5.1
Loading...
Searching...
No Matches
Ln200Sensor.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 "Ln200Sensor.hpp"
10
13
14#include "util/Logger.hpp"
17
19
33
35{
36 LOG_TRACE("{}: called", nameId());
37}
38
40{
41 return "Ln200Sensor";
42}
43
44std::string NAV::Ln200Sensor::type() const
45{
46 return typeStatic();
47}
48
50{
51 return "Data Provider";
52}
53
55{
56 if (ImGui::InputTextWithHint("SensorPort", "/dev/ttyUSB0", &_sensorPort))
57 {
58 LOG_DEBUG("{}: SensorPort changed to {}", nameId(), _sensorPort);
61 }
62 ImGui::SameLine();
63 gui::widgets::HelpMarker("COM port where the sensor is attached to\n"
64 "- \"COM1\" (Windows format for physical and virtual (USB) serial port)\n"
65 "- \"/dev/ttyS1\" (Linux format for physical serial port)\n"
66 "- \"/dev/ttyUSB0\" (Linux format for virtual (USB) serial port)\n"
67 "- \"/dev/tty.usbserial-FTXXXXXX\" (Mac OS X format for virtual (USB) serial port)\n"
68 "- \"/dev/ttyS0\" (CYGWIN format. Usually the Windows COM port number minus 1. This would connect to COM1)");
69
71}
72
73[[nodiscard]] json NAV::Ln200Sensor::save() const
74{
75 LOG_TRACE("{}: called", nameId());
76
77 json j;
78
79 j["UartSensor"] = UartSensor::save();
80 j["Imu"] = Imu::save();
81
82 return j;
83}
84
86{
87 LOG_TRACE("{}: called", nameId());
88
89 if (j.contains("UartSensor"))
90 {
91 UartSensor::restore(j.at("UartSensor"));
92 }
93 if (j.contains("Imu"))
94 {
95 Imu::restore(j.at("Imu"));
96 }
97}
98
100{
101 return true;
102}
103
105{
106 LOG_TRACE("{}: called", nameId());
107
108 // connect to the sensor
109 try
110 {
112
113 LOG_DEBUG("{} connected on port {} with baudrate {}", nameId(), _sensorPort, sensorBaudrate());
114 }
115 catch (...)
116 {
117 LOG_ERROR("{} could not connect", nameId());
118 return false;
119 }
120
121 _sensor->registerAsyncPacketReceivedHandler(this, binaryAsyncMessageReceived);
122
123 return true;
124}
125
127{
128 LOG_TRACE("{}: called", nameId());
129
130 if (!isInitialized())
131 {
132 return;
133 }
134
135 if (_sensor->isConnected())
136 {
137 try
138 {
139 _sensor->unregisterAsyncPacketReceivedHandler();
140 }
141 catch (...) // NOLINT(bugprone-empty-catch)
142 {}
143 LOG_TRACE("{}: Disconnecting...", nameId());
144 _sensor->disconnect();
145 LOG_TRACE("{}: Disconnected", nameId());
146 }
147}
148
149void NAV::Ln200Sensor::binaryAsyncMessageReceived(void* userData, uart::protocol::Packet& p, size_t /* index */)
150{
151 auto* lnSensor = static_cast<Ln200Sensor*>(userData);
152
153 if (p.type() == uart::protocol::Packet::Type::TYPE_BINARY)
154 {
155 auto obs = std::make_shared<ImuObsWDelta>(lnSensor->_imuPos);
156
157 // Lambda for reversing bits in a uint16_t
158 auto reverseBits = [](uint16_t& word) {
159 word = static_cast<uint16_t>(((word & 0x5555) << 1) | ((word & 0xAAAA) >> 1)); // Swap adjacent bits
160 word = static_cast<uint16_t>(((word & 0x3333) << 2) | ((word & 0xCCCC) >> 2)); // Swap pairs of bits
161 word = static_cast<uint16_t>(((word & 0x0F0F) << 4) | ((word & 0xF0F0) >> 4)); // Swap nibbles
162 word = static_cast<uint16_t>(((word & 0x00FF) << 8) | ((word & 0xFF00) >> 8)); // Swap bytes
163 };
164
165 const std::vector<uint8_t>& bytes = p.getRawData();
166 std::array<uint16_t, 14> rawWords{}; // Temporary storage for raw words
167 std::array<double, 12> processedWords{}; // Storage of processed data words
168
169 // Extract exactly 14 words (each 16 bits in little-endian order)
170 for (uint8_t i = 0; i < 14; ++i)
171 {
172 uint8_t index = i * 2;
173 uint16_t word = static_cast<uint16_t>(bytes[index + 1]) | static_cast<uint16_t>(static_cast<uint16_t>(bytes[index]) << 8);
174 reverseBits(word);
175 rawWords.at(i) = word;
176 }
177
178 // TODO: Check internal validity
179 // The last word is a checksum:
180 // uint16_t checksum = rawWords[12];
181
182 // TODO: Process IMU status
183 // uint16_t imuStatus = rawWords[6];
184
185 // TODO: Implement the conversion of the mux word based on the mux id
186 // The 8th word (index 7) is the multiplexer ID and the 9th word (index 8) is mux data
187 // uint16_t muxId = rawWords[7];
188 // uint16_t muxDataWordRaw = rawWords[8];
189
190 // Convert the mux word based on the mux id
191 // double muxDataWord = 0.0;
192 // if (muxId == 8 || muxId == 13) // 8: Temperature conversion, 13: Voltage conversion
193 // {
194 // muxDataWord = static_cast<double>(muxDataWordRaw) * 0.1;
195 // }
196 // else // 17: IMU failure and all other cases
197 // {
198 // muxDataWord = muxDataWordRaw;
199 // }
200
201 // Processing velocity
202 for (uint8_t i = 0; i < 3; ++i)
203 {
204 processedWords.at(i) = static_cast<int16_t>(rawWords.at(i)) * (1.0 / 16384.0);
205 }
206 // Processing angles
207 for (uint8_t i = 3; i < 6; ++i)
208 {
209 processedWords.at(i) = static_cast<int16_t>(rawWords.at(i)) * (1.0 / 262144.0);
210 }
211 double dVelX = processedWords[0];
212 double dVelY = processedWords[1];
213 double dVelZ = processedWords[2];
214 double dAngleX = processedWords[3];
215 double dAngleY = processedWords[4];
216 double dAngleZ = processedWords[5];
217 double accelX = processedWords[0] * FREQ;
218 double accelY = processedWords[1] * FREQ;
219 double accelZ = processedWords[2] * FREQ;
220 double angleRateX = processedWords[3] * FREQ;
221 double angleRateY = processedWords[4] * FREQ;
222 double angleRateZ = processedWords[5] * FREQ;
223
224 obs->dtime = 1.0 / FREQ;
225 obs->dvel = { dVelX, dVelY, dVelZ };
226 obs->dtheta = { dAngleX, dAngleY, dAngleZ };
227 obs->p_acceleration = { accelX, accelY, accelZ };
228 obs->p_angularRate = { angleRateX, angleRateY, angleRateZ };
229
230 LOG_DATA("DATA({}): {}", lnSensor->name, obs->temperature.value());
231
232 // Calls all the callbacks
233 if (InsTime currentTime = util::time::GetCurrentInsTime();
234 !currentTime.empty())
235 {
236 obs->insTime = currentTime;
237 }
238 lnSensor->invokeCallbacks(OUTPUT_PORT_INDEX_LN_OBS, obs);
239 }
240 else if (p.type() == uart::protocol::Packet::Type::TYPE_ASCII)
241 {
242 LOG_WARN("{}: Received an ASCII Async message: {}", lnSensor->name, p.datastr());
243 }
244}
Save/Load the Nodes.
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Data storage class for one VectorNavImu observation.
Litton LN-200 IMU Sensor.
Class to read out LN-200 Sensors.
Utility class for logging to console and file.
#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
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
Definition Logger.hpp:71
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Definition Logger.hpp:65
Keeps track of the current real/simulation time.
static std::string type()
Returns the type of the data class.
json save() const override
Saves the node into a json object.
Definition Imu.cpp:93
void restore(const json &j) override
Restores the node from a json object.
Definition Imu.cpp:104
void guiConfig() override
ImGui config window which is shown on double click.
Definition Imu.cpp:55
Imu(const Imu &)=delete
Copy constructor.
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
constexpr bool empty() const
Checks if the Time object has a value.
Definition InsTime.hpp:1089
json save() const override
Saves the node into a json object.
static std::string typeStatic()
String representation of the Class Type.
static std::string category()
String representation of the Class Category.
void restore(const json &j) override
Restores the node from a json object.
Ln200Sensor()
Default constructor.
vendor::ln::Ln200UartSensor _sensor
Sensor Object.
void guiConfig() override
ImGui config window which is shown on double click.
std::string type() const override
String representation of the Class Type.
bool resetNode() override
Resets the node. It is guaranteed that the node is initialized when this is called.
static constexpr size_t OUTPUT_PORT_INDEX_LN_OBS
Flow (ImuObs)
void deinitialize() override
Deinitialize the node.
~Ln200Sensor() override
Destructor.
bool initialize() override
Initialize the node.
static constexpr uint8_t FREQ
IMU data frequency in Hz.
static void binaryAsyncMessageReceived(void *userData, uart::protocol::Packet &p, size_t index)
Callback handler for notifications of new asynchronous data packets received.
bool isInitialized() const
Checks if the node is initialized.
Definition Node.cpp:574
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
Definition Node.cpp:465
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:522
OutputPin * CreateOutputPin(const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier, OutputPin::PinData data=static_cast< void * >(nullptr), int idx=-1)
Create an Output Pin object.
Definition Node.cpp:278
std::string nameId() const
Node name and id.
Definition Node.cpp:323
std::string name
Name of the Node.
Definition Node.hpp:507
bool _onlyRealTime
Whether the node can run in post-processing or only real-time.
Definition Node.hpp:531
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:525
static int baudrate2Selection(Baudrate baud)
Returns the guiSelection for the given baudrate.
int _selectedBaudrate
Baudrate for the sensor.
@ BAUDRATE_2000000
Baudrate with 2000000 symbols per second [Baud].
std::string _sensorPort
void restore(const json &j)
Restores the node from a json object.
Baudrate sensorBaudrate() const
Returns the Baudrate for the element Selected by the GUI.
json save() const
Saves the node into a json object.
void ApplyChanges()
Signals that there have been changes to the flow.
void HelpMarker(const char *desc, const char *symbol="(?)")
Text Help Marker, e.g. '(?)', with Tooltip.
@ Flow
NodeData Trigger.
Definition Pin.hpp:52