0.5.1
Loading...
Searching...
No Matches
udpRecv.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 "udpRecv.hpp"
10
16
17#include "util/Assert.h"
19
20#include "util/Logger.hpp"
24
25#include <cstdint>
26#include <cstring>
27#include <memory>
28#include <boost/system/detail/error_code.hpp>
29
32{
33 LOG_TRACE("{}: called", name);
34
35 _onlyRealTime = true;
36 _hasConfig = true;
37 _guiConfigDefaultWindowSize = { 261, 95 };
38
40}
41
43{
44 LOG_TRACE("{}: called", nameId());
45}
46
48{
49 return "UdpRecv";
50}
51
52std::string NAV::UdpRecv::type() const
53{
54 return typeStatic();
55}
56
58{
59 return "Data Link";
60}
61
63{
64 ImGui::SetNextItemWidth(150 * gui::NodeEditorApplication::windowFontRatio());
65 if (ImGui::InputIntL(fmt::format("Port##{}", size_t(id)).c_str(), &_port, UdpUtil::PORT_LIMITS[0], UdpUtil::PORT_LIMITS[1]))
66 {
68 }
69 ImGui::SetNextItemWidth(150 * gui::NodeEditorApplication::windowFontRatio());
70 if (gui::widgets::EnumCombo(fmt::format("Output Type##{}", size_t(id)).c_str(), _outputType))
71 {
72 LOG_DEBUG("{}: Output Type changed to {}", nameId(), to_string(_outputType));
74 {
77 }
79 {
82 }
84 {
85 outputPins.at(OUTPUT_PORT_INDEX_NODE_DATA).dataIdentifier = { NAV::Pos::type() };
87 }
89 {
92 }
93
94 for (auto& link : outputPins.front().links)
95 {
96 if (auto* connectedPin = link.getConnectedPin())
97 {
98 outputPins.front().recreateLink(*connectedPin);
99 }
100 }
101
103 }
104}
105
107{
108 return true;
109}
110
112{
113 LOG_TRACE("{}: called", nameId());
114
115 json j;
116 j["port"] = _port;
117 j["outputType"] = _outputType;
118
119 return j;
120}
121
123{
124 LOG_TRACE("{}: called", nameId());
125 if (j.contains("port"))
126 {
127 j.at("port").get_to(_port);
128 }
129 if (j.contains("outputType"))
130 {
131 j.at("outputType").get_to(_outputType);
132
133 if (!outputPins.empty())
134 {
136 {
139 }
141 {
144 }
146 {
147 outputPins.at(OUTPUT_PORT_INDEX_NODE_DATA).dataIdentifier = { NAV::Pos::type() };
149 }
151 {
154 }
155 }
156 }
157}
158
160{
161 LOG_TRACE("{}: called", nameId());
162
163 try
164 {
165 _socket = boost::asio::ip::udp::socket(_io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), static_cast<uint16_t>(_port)));
166 }
167 catch (const std::exception& /* e */)
168 {
169 LOG_ERROR("{}: Port {} is already in use. Choose a different port for this instance.", nameId(), _port);
170 return false;
171 }
172
173 _running = true;
174
175 asyncReceive();
176
177 if (_isStartup)
178 {
179 _recvThread = std::thread([this]() {
180 _io_context.run();
181 });
182 }
183 else
184 {
185 _recvThread = std::thread([this]() {
186 _io_context.restart();
187 _io_context.run();
188 });
189 }
190
191 _isStartup = false;
192
193 return true;
194}
195
197{
198 _running = false;
199 _io_context.stop();
200 _recvThread.join();
201 _socket.close();
202
203 LOG_TRACE("{}: called", nameId());
204}
205
207{
208 _socket.async_receive_from(
210 [this](boost::system::error_code errorRcvd, std::size_t bytesRcvd) {
211 if ((!errorRcvd) && (bytesRcvd > 0))
212 {
213 UdpUtil::MessageType msgType{};
214 std::memcpy(&msgType, _charArray.data(), UdpUtil::Size::MSGTYPE);
215 LOG_DATA("{}: Received {} bytes (message type {})", nameId(), bytesRcvd, fmt::underlying(msgType));
216
217 int32_t gpsCycle{};
218 int32_t gpsWeek{};
219 double gpsTow{};
220
221 std::memcpy(&gpsCycle, _charArray.data() + UdpUtil::Offset::GPSCYCLE, UdpUtil::Size::GPSCYCLE);
222 std::memcpy(&gpsWeek, _charArray.data() + UdpUtil::Offset::GPSWEEK, UdpUtil::Size::GPSWEEK);
223 std::memcpy(&gpsTow, _charArray.data() + UdpUtil::Offset::GPSTOW, UdpUtil::Size::GPSTOW);
224
225 if (msgType == UdpUtil::MessageType::PosVelAtt)
226 {
228 {
229 LOG_ERROR("{}: Change output type to 'PosVelAtt'!", nameId());
230 return;
231 }
232 auto obs = std::make_shared<PosVelAtt>();
233
234 obs->insTime = InsTime(gpsCycle, gpsWeek, gpsTow);
235
236 // Position in LLA coordinates
237 Eigen::Vector3d posLLA{};
238 std::memcpy(posLLA.data(), _charArray.data() + UdpUtil::Offset::POS, UdpUtil::Size::POS);
239
240 // Velocity in local frame
241 Eigen::Vector3d vel_n{};
242 std::memcpy(vel_n.data(), _charArray.data() + UdpUtil::Offset::VEL, UdpUtil::Size::VEL);
243
244 // Attitude
245 Eigen::Quaterniond n_Quat_b{};
246 std::memcpy(&n_Quat_b.x(), _charArray.data() + UdpUtil::Offset::QUAT, UdpUtil::Size::QUAT);
247 std::memcpy(&n_Quat_b.y(), _charArray.data() + UdpUtil::Offset::QUAT + UdpUtil::Size::QUAT, UdpUtil::Size::QUAT);
248 std::memcpy(&n_Quat_b.z(), _charArray.data() + UdpUtil::Offset::QUAT + 2 * UdpUtil::Size::QUAT, UdpUtil::Size::QUAT);
249 std::memcpy(&n_Quat_b.w(), _charArray.data() + UdpUtil::Offset::QUAT + 3 * UdpUtil::Size::QUAT, UdpUtil::Size::QUAT);
250
251 obs->setPosVelAtt_n(posLLA, vel_n, n_Quat_b);
252
254 }
255 else if (msgType == UdpUtil::MessageType::PosVel)
256 {
258 {
259 LOG_ERROR("{}: Change output type to 'PosVel'!", nameId());
260 return;
261 }
262 auto obs = std::make_shared<PosVel>();
263
264 obs->insTime = InsTime(gpsCycle, gpsWeek, gpsTow);
265
266 // Position in LLA coordinates
267 Eigen::Vector3d posLLA{};
268 std::memcpy(posLLA.data(), _charArray.data() + UdpUtil::Offset::POS, UdpUtil::Size::POS);
269
270 // Velocity in local frame
271 Eigen::Vector3d vel_n{};
272 std::memcpy(vel_n.data(), _charArray.data() + UdpUtil::Offset::VEL, UdpUtil::Size::VEL);
273
274 obs->setPosVel_n(posLLA, vel_n);
275
277 }
278 else if (msgType == UdpUtil::MessageType::Pos)
279 {
281 {
282 LOG_ERROR("{}: Change output type to 'Pos'!", nameId());
283 return;
284 }
285 auto obs = std::make_shared<Pos>();
286
287 obs->insTime = InsTime(gpsCycle, gpsWeek, gpsTow);
288
289 // Position in LLA coordinates
290 Eigen::Vector3d posLLA{};
291 std::memcpy(posLLA.data(), _charArray.data() + UdpUtil::Offset::POS, UdpUtil::Size::POS);
292
293 obs->setPosition_lla(posLLA);
294
296 }
297 else if (msgType == UdpUtil::MessageType::GnssObs)
298 {
300 {
301 LOG_ERROR("{}: Change output type to 'GnssObs'!", nameId());
302 return;
303 }
304 auto gnssObs = std::make_shared<GnssObs>();
305 gnssObs->insTime = InsTime(gpsCycle, gpsWeek, gpsTow);
306
307 size_t byteSizeGnssData{};
308 std::memcpy(&byteSizeGnssData, _charArray.data() + UdpUtil::Offset::SIZE, UdpUtil::Size::SIZE);
309 size_t sizeGnssData = byteSizeGnssData / UdpUtil::Size::SINGLE_OBSERVATION_DATA;
311 "The UdpRecv node received a not dividable amount of bytes for the GnssObs data.");
312 LOG_DATA("{}: {} GNSS signals ({} bytes)", nameId(), sizeGnssData, byteSizeGnssData);
313 gnssObs->data.resize(sizeGnssData, GnssObs::ObservationData(SatSigId()));
314 std::memcpy(gnssObs->data.data(), _charArray.data() + UdpUtil::Offset::GNSSDATA, byteSizeGnssData);
315
317 }
318 else
319 {
320 LOG_ERROR("{}: Data type not receivable, yet.", nameId());
321 }
322 }
323 else
324 {
325 LOG_ERROR("{}: Error receiving the UDP network stream: {}, Received bytes: {}", nameId(), errorRcvd.what(), bytesRcvd);
326 }
327
328 if (_running)
329 {
330 asyncReceive();
331 }
332 });
333}
334
336{
337 switch (value)
338 {
340 return "PosVelAtt";
342 return "PosVel";
344 return "Pos";
346 return "GnssObs";
348 return "";
349 }
350 return "";
351}
Assertion helpers.
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Combo representing an enumeration.
Save/Load the Nodes.
nlohmann::json json
json namespace
GNSS Observation messages.
The class is responsible for all time-related tasks.
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_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Definition Logger.hpp:65
Position, Velocity and Attitude Storage Class.
Structs identifying a unique satellite.
Utility for the UDP Send and Receive nodes.
static std::string type()
Returns the type of the data class.
Definition GnssObs.hpp:151
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:522
std::vector< OutputPin > outputPins
List of output pins.
Definition Node.hpp:511
Node(std::string name)
Constructor.
Definition Node.cpp:29
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
void invokeCallbacks(size_t portIndex, const std::shared_ptr< const NodeData > &data)
Calls all registered callbacks on the specified output port.
Definition Node.cpp:179
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:525
static std::string type()
Returns the type of the data class.
Definition PosVelAtt.hpp:29
static std::string type()
Returns the type of the data class.
Definition PosVel.hpp:27
static std::string type()
Returns the type of the data class.
Definition Pos.hpp:36
static std::string category()
String representation of the Class Category.
Definition udpRecv.cpp:57
UdpRecv()
Default constructor.
Definition udpRecv.cpp:30
void asyncReceive()
Polls the next data.
Definition udpRecv.cpp:206
void guiConfig() override
ImGui config window which is shown on double click.
Definition udpRecv.cpp:62
UdpUtil::MessageType _outputType
The selected output type in the GUI.
Definition udpRecv.hpp:89
bool initialize() override
Initialize the node.
Definition udpRecv.cpp:159
~UdpRecv() override
Destructor.
Definition udpRecv.cpp:42
boost::asio::io_context _io_context
Asynchronous receive fct.
Definition udpRecv.hpp:92
bool _isStartup
Startup handler: used in 'initialize()' to differentiate between startup and re-initialization.
Definition udpRecv.hpp:104
std::array< char, UdpUtil::MAXIMUM_BYTES > _charArray
The array that contains the data from the UDP stream.
Definition udpRecv.hpp:110
bool resetNode() override
Resets the node. Moves the read cursor to the start.
Definition udpRecv.cpp:106
std::thread _recvThread
Receiver thread.
Definition udpRecv.hpp:99
bool _running
Flag that indicates the running data link.
Definition udpRecv.hpp:102
void restore(const json &j) override
Restores the node from a json object.
Definition udpRecv.cpp:122
static constexpr size_t OUTPUT_PORT_INDEX_NODE_DATA
Object (NodeData)
Definition udpRecv.hpp:74
json save() const override
Saves the node into a json object.
Definition udpRecv.cpp:111
std::string type() const override
String representation of the Class Type.
Definition udpRecv.cpp:52
boost::asio::ip::udp::socket _socket
Boost udp socket.
Definition udpRecv.hpp:94
static std::string typeStatic()
String representation of the Class Type.
Definition udpRecv.cpp:47
int _port
UDP port number.
Definition udpRecv.hpp:86
void deinitialize() override
Deinitialize the node.
Definition udpRecv.cpp:196
boost::asio::ip::udp::endpoint _sender_endpoint
Boost udp endpoint.
Definition udpRecv.hpp:96
static float windowFontRatio()
Ratio to multiply for GUI window elements.
ImGui extensions.
bool InputIntL(const char *label, int *v, int v_min, int v_max, int step, int step_fast, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'int'.
Definition imgui_ex.cpp:242
static constexpr size_t POS
Offset of the position.
Definition UdpUtil.hpp:75
static constexpr size_t GPSCYCLE
Offset of the GPS cycle.
Definition UdpUtil.hpp:69
static constexpr size_t GPSTOW
Offset of the GPS tow.
Definition UdpUtil.hpp:73
static constexpr size_t SIZE
Offset of the GNSS data size.
Definition UdpUtil.hpp:82
static constexpr size_t QUAT
Offset of the quaternion.
Definition UdpUtil.hpp:79
static constexpr size_t GNSSDATA
Offset of the GNSS data.
Definition UdpUtil.hpp:84
static constexpr size_t VEL
Offset of the velocity.
Definition UdpUtil.hpp:77
static constexpr size_t GPSWEEK
Offset of the GPS week.
Definition UdpUtil.hpp:71
static constexpr size_t GPSCYCLE
Size of a GPS cycle.
Definition UdpUtil.hpp:41
static constexpr size_t SIZE
Size of the size of a GNSS observation.
Definition UdpUtil.hpp:61
static constexpr size_t QUAT
Size of a Quaternion element.
Definition UdpUtil.hpp:51
static constexpr size_t SINGLE_OBSERVATION_DATA
Size of a single GNSS observation.
Definition UdpUtil.hpp:63
static constexpr size_t MSGTYPE
Size of the message type.
Definition UdpUtil.hpp:39
static constexpr size_t POS
Size of a Pos (LLA)
Definition UdpUtil.hpp:47
static constexpr size_t GPSTOW
Size of a GPS TOW.
Definition UdpUtil.hpp:45
static constexpr size_t GPSWEEK
Size of a GPS week.
Definition UdpUtil.hpp:43
static constexpr size_t VEL
Size of a Vel (NED)
Definition UdpUtil.hpp:49
static constexpr unsigned int MAXIMUM_BYTES
Network data stream maximum buffer size in [bytes] (Maximum payload size of a UDP package)
Definition UdpUtil.hpp:22
static constexpr std::array< int, 2 > PORT_LIMITS
Range a port can be in [0, 2^16-1].
Definition UdpUtil.hpp:24
MessageType
Enum specifying the type of the output message.
Definition UdpUtil.hpp:28
@ PosVel
Extract PosVel data.
Definition UdpUtil.hpp:30
@ GnssObs
Extract GnssObs data.
Definition UdpUtil.hpp:32
@ COUNT
Number of items in the enum.
Definition UdpUtil.hpp:33
@ PosVelAtt
Extract PosVelAtt data.
Definition UdpUtil.hpp:29
@ Pos
Extract Pos data.
Definition UdpUtil.hpp:31
void ApplyChanges()
Signals that there have been changes to the flow.
bool EnumCombo(const char *label, T &enumeration, size_t startIdx=0)
Combo representing an enumeration.
Definition EnumCombo.hpp:30
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
Stores the satellites observations.
Definition GnssObs.hpp:47
@ Flow
NodeData Trigger.
Definition Pin.hpp:52
Identifies a satellite signal (satellite frequency and number)
Asynchronous data link - receiver node.