io.hpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // © Copyright 2020, Septentrio NV/SA.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 1. Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // 3. Neither the name of the copyright holder nor the names of its
14 // contributors may be used to endorse or promote products derived
15 // from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 // *****************************************************************************
30 
31 #pragma once
32 
33 // C++
34 #include <thread>
35 
36 // Linux
37 #include <linux/input.h>
38 #include <linux/serial.h>
39 
40 // Boost
41 #include <boost/asio.hpp>
42 #include <boost/asio/deadline_timer.hpp>
43 #include <boost/lambda/bind.hpp>
44 #include <boost/lambda/lambda.hpp>
45 
46 // pcap
47 #include <pcap.h>
48 
49 // ROSaic
50 #ifdef ROS2
52 #endif
53 #ifdef ROS1
55 #endif
57 
59 const static std::array<uint32_t, 21> baudrates = {
60  1200, 2400, 4800, 9600, 19200, 38400, 57600,
61  115200, 230400, 460800, 500000, 576000, 921600, 1000000,
62  1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000};
63 
64 namespace io {
65 
66  class UdpClient
67  {
68  public:
69  UdpClient(ROSaicNodeBase* node, int16_t port, TelegramQueue* telegramQueue) :
70  node_(node), running_(true), port_(port), telegramQueue_(telegramQueue)
71  {
72  connect();
74  std::thread(boost::bind(&UdpClient::runWatchdog, this));
75  }
76 
78  {
79  running_ = false;
80 
81  node_->log(log_level::INFO, "UDP client shutting down threads");
82  ioContext_.stop();
83  ioThread_.join();
84  watchdogThread_.join();
85  node_->log(log_level::INFO, " UDP client threads stopped");
86  }
87 
88  private:
89  void connect()
90  {
91  socket_ = std::make_unique<boost::asio::ip::udp::socket>(
92  ioContext_,
93  boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port_));
94 
95  asyncReceive();
96 
97  ioThread_ = std::thread(boost::bind(&UdpClient::runIoContext, this));
98 
100  "Listening on UDP port " + std::to_string(port_));
101  }
102 
104 
105  {
106  socket_->async_receive_from(
107  boost::asio::buffer(buffer_, MAX_UDP_PACKET_SIZE), eP_,
108  boost::bind(&UdpClient::handleReceive, this,
109  boost::asio::placeholders::error,
110  boost::asio::placeholders::bytes_transferred));
111  }
112 
113  void handleReceive(const boost::system::error_code& error,
114  size_t bytes_recvd)
115  {
116  Timestamp stamp = node_->getTime();
117  size_t idx = 0;
118 
119  if (!error && (bytes_recvd > 0))
120  {
121  while ((bytes_recvd - idx) > 2)
122  {
123  auto telegram = std::make_shared<Telegram>();
124  telegram->stamp = stamp;
125  /*node_->log(log_level::DEBUG,
126  "Buffer: " + std::string(telegram->message.begin(),
127  telegram->message.end()));*/
128  if (buffer_[idx] == SYNC_BYTE_1)
129  {
130  if (buffer_[idx + 1] == SBF_SYNC_BYTE_2)
131  {
132  if ((bytes_recvd - idx) > SBF_HEADER_SIZE)
133  {
135  &buffer_[idx + 6]);
136  telegram->message.assign(&buffer_[idx],
137  &buffer_[idx + length]);
138  if (crc::isValid(telegram->message))
139  {
140  telegram->type = telegram_type::SBF;
141  telegramQueue_->push(telegram);
142  } else
143  node_->log(
145  "AsyncManager crc failed for SBF " +
146  std::to_string(parsing_utilities::getId(
147  telegram->message)) +
148  ".");
149 
150  idx += length;
151  }
152 
153  } else if ((buffer_[idx + 1] == NMEA_SYNC_BYTE_2) &&
154  (buffer_[idx + 2] == NMEA_SYNC_BYTE_3))
155  {
156  size_t idx_end = findNmeaEnd(idx, bytes_recvd);
157  telegram->message.assign(&buffer_[idx],
158  &buffer_[idx_end + 1]);
159  telegram->type = telegram_type::NMEA;
160  telegramQueue_->push(telegram);
161  idx = idx_end + 1;
162 
163  } else if ((buffer_[idx + 1] == NMEA_INS_SYNC_BYTE_2) &&
164  (buffer_[idx + 2] == NMEA_INS_SYNC_BYTE_3))
165  {
166  size_t idx_end = findNmeaEnd(idx, bytes_recvd);
167  telegram->message.assign(&buffer_[idx],
168  &buffer_[idx_end + 1]);
169  telegram->type = telegram_type::NMEA_INS;
170  telegramQueue_->push(telegram);
171  idx = idx_end + 1;
172  } else
173  {
175  "head: " +
176  std::string(std::string(
177  telegram->message.begin(),
178  telegram->message.begin() + 2)));
179  }
180  } else
181  {
182  node_->log(log_level::DEBUG, "UDP msg resync.");
183  ++idx;
184  }
185  }
186  } else
187  {
189  "UDP client receive error: " + error.message());
190  }
191 
192  asyncReceive();
193  }
194 
196  {
197  ioContext_.run();
198  node_->log(log_level::INFO, "UDP client ioContext terminated.");
199  }
200 
201  void runWatchdog()
202  {
203  while (running_)
204  {
205  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
206 
207  if (running_ && ioContext_.stopped())
208  {
210  "UDP client connection lost. Trying to reconnect.");
211  ioContext_.restart();
212  ioThread_.join();
213  connect();
214  }
215  }
216  }
217 
218  private:
219  size_t findNmeaEnd(size_t idx, size_t bytes_recvd)
220  {
221  size_t idx_end = idx + 2;
222 
223  while (idx_end < bytes_recvd)
224  {
225  if ((buffer_[idx_end] == LF) && (buffer_[idx_end - 1] == CR))
226  break;
227 
228  ++idx_end;
229  }
230  return idx_end;
231  }
234  std::atomic<bool> running_;
235  int16_t port_;
236  boost::asio::io_context ioContext_;
237  std::thread ioThread_;
238  std::thread watchdogThread_;
239  boost::asio::ip::udp::endpoint eP_;
240  std::unique_ptr<boost::asio::ip::udp::socket> socket_;
241  std::array<uint8_t, MAX_UDP_PACKET_SIZE> buffer_;
243  };
244 
245  class TcpIo
246  {
247  public:
249  std::shared_ptr<boost::asio::io_context> ioContext) :
250  node_(node), ioContext_(ioContext), deadline_(*ioContext_)
251  {
253 
254  deadline_.expires_at(boost::posix_time::pos_infin);
255  checkDeadline();
256  }
257 
258  ~TcpIo() { stream_->close(); }
259 
260  void close()
261  {
262  deadline_.cancel();
263  stream_->close();
264  }
265 
266  void setPort(const std::string& port) { port_ = port; }
267 
268  [[nodiscard]] bool connect()
269  {
270  boost::asio::ip::tcp::resolver::results_type endpoints;
271 
272  try
273  {
274  boost::asio::ip::tcp::resolver resolver(*ioContext_);
275  endpoints =
276  resolver.resolve(node_->settings()->device_tcp_ip, port_);
277  } catch (const std::runtime_error& e)
278  {
280  "Could not resolve " + node_->settings()->device_tcp_ip +
281  " on port " + port_ + ": " + e.what());
282  return false;
283  }
284 
285  stream_ = std::make_unique<boost::asio::ip::tcp::socket>(*ioContext_);
286 
287  node_->log(log_level::INFO, "Connecting to tcp://" +
288  node_->settings()->device_tcp_ip + ":" +
289  port_ + "...");
290 
291  try
292  {
293  boost::system::error_code ec = connectInternal(endpoints);
294  while (node_->ok() && ec)
295  {
297  "TCP connection to " +
298  endpoints.begin()
299  ->endpoint()
300  .address()
301  .to_string() +
302  " on port " +
303  std::to_string(
304  endpoints.begin()->endpoint().port()) +
305  " failed: " + ec.message() + ". Retrying ...");
306  using namespace std::chrono_literals;
307  std::this_thread::sleep_for(1s);
308  ec = connectInternal(endpoints);
309  }
310  if (ec)
311  return false;
312 
313  } catch (const std::runtime_error& e)
314  {
316  "Could not connect to " + endpoints.begin()->host_name() +
317  ": " + endpoints.begin()->service_name() + ": " +
318  e.what());
319  return false;
320  }
321 
322  deadline_.expires_at(boost::posix_time::pos_infin);
323  stream_->set_option(boost::asio::ip::tcp::no_delay(true));
324  node_->log(log_level::INFO, "Connected to " +
325  endpoints.begin()->host_name() + ":" +
326  endpoints.begin()->service_name() + ".");
327  return true;
328  }
329 
330  private:
331  boost::system::error_code connectInternal(
332  const boost::asio::ip::tcp::resolver::results_type& endpoints)
333  {
334  boost::system::error_code ec;
335  deadline_.expires_from_now(boost::posix_time::seconds(10));
336  ec = boost::asio::error::would_block;
337  boost::asio::async_connect(*stream_, endpoints,
338  boost::lambda::var(ec) = boost::lambda::_1);
339  do
340  ioContext_->run_one();
341  while (node_->ok() && (ec == boost::asio::error::would_block));
342  return ec;
343  }
344 
346  {
347  if (deadline_.expires_at() <=
348  boost::asio::deadline_timer::traits_type::now())
349  {
350  boost::system::error_code ignored_ec;
351  stream_->close(ignored_ec);
352 
353  deadline_.expires_at(boost::posix_time::pos_infin);
354  }
355  deadline_.async_wait(boost::lambda::bind(&TcpIo::checkDeadline, this));
356  }
357 
359  std::shared_ptr<boost::asio::io_context> ioContext_;
360  boost::asio::deadline_timer deadline_;
361 
362  std::string port_;
363 
364  public:
365  std::unique_ptr<boost::asio::ip::tcp::socket> stream_;
366  };
367 
368  class SerialIo
369  {
370  public:
372  std::shared_ptr<boost::asio::io_context> ioContext) :
373  node_(node), ioContext_(ioContext),
374  flowcontrol_(node->settings()->hw_flow_control),
375  baudrate_(node->settings()->baudrate)
376  {
377  stream_ = std::make_unique<boost::asio::serial_port>(*ioContext_);
378  }
379 
380  ~SerialIo() { stream_->close(); }
381 
382  void close() { stream_->close(); }
383 
384  [[nodiscard]] bool connect()
385  {
386  if (stream_->is_open())
387  {
388  stream_->close();
389  }
390 
391  bool opened = false;
392 
393  while (!opened && node_->ok())
394  {
395  try
396  {
398  "Connecting serially to device " +
399  node_->settings()->device +
400  ", targeted baudrate: " +
401  std::to_string(node_->settings()->baudrate));
402  stream_->open(node_->settings()->device);
403  opened = true;
404  } catch (const boost::system::system_error& err)
405  {
406  node_->log(log_level::ERROR, "Could not open serial port " +
407  node_->settings()->device +
408  ". Error: " + err.what() +
409  ". Will retry every second.");
410 
411  using namespace std::chrono_literals;
412  std::this_thread::sleep_for(1s);
413  }
414  }
415  if (!opened)
416  return false;
417 
418  // No Parity, 8bits data, 1 stop Bit
419  stream_->set_option(boost::asio::serial_port_base::baud_rate(baudrate_));
420  stream_->set_option(boost::asio::serial_port_base::parity(
421  boost::asio::serial_port_base::parity::none));
422  stream_->set_option(boost::asio::serial_port_base::character_size(8));
423  stream_->set_option(boost::asio::serial_port_base::stop_bits(
424  boost::asio::serial_port_base::stop_bits::one));
425 
426  // Hardware flow control settings
427  if (flowcontrol_ == "RTS|CTS")
428  {
429  stream_->set_option(boost::asio::serial_port_base::flow_control(
430  boost::asio::serial_port_base::flow_control::hardware));
431  } else
432  {
433  stream_->set_option(boost::asio::serial_port_base::flow_control(
434  boost::asio::serial_port_base::flow_control::none));
435  }
436 
437  // Set low latency
438  int fd = stream_->native_handle();
439  struct serial_struct serialInfo;
440  ioctl(fd, TIOCGSERIAL, &serialInfo);
441  serialInfo.flags |= ASYNC_LOW_LATENCY;
442  ioctl(fd, TIOCSSERIAL, &serialInfo);
443 
444  return setBaudrate();
445  }
446 
447  [[nodiscard]] bool setBaudrate()
448  {
449  // Setting the baudrate, incrementally..
451  "Gradually increasing the baudrate to the desired value...");
452  boost::asio::serial_port_base::baud_rate current_baudrate;
453  node_->log(log_level::DEBUG, "Initiated current_baudrate object...");
454  try
455  {
456  stream_->get_option(current_baudrate); // Note that this sets
457  // current_baudrate.value()
458  // often to 115200, since by
459  // default, all Rx COM ports,
460  // at least for mosaic Rxs, are set to a baudrate of 115200 baud,
461  // using 8 data-bits, no parity and 1 stop-bit.
462  } catch (boost::system::system_error& e)
463  {
464 
465  node_->log(log_level::ERROR, "get_option failed due to " +
466  static_cast<std::string>(e.what()));
467  node_->log(log_level::INFO, "Additional info about error is " +
468  static_cast<std::string>(e.what()));
469  /*
470  boost::system::error_code e_loop;
471  do // Caution: Might cause infinite loop..
472  {
473  stream_->get_option(current_baudrate, e_loop);
474  } while(e_loop);
475  */
476  return false;
477  }
478  // Gradually increase the baudrate to the desired value
479  // The desired baudrate can be lower or larger than the
480  // current baudrate; the for loop takes care of both scenarios.
482  "Current baudrate is " +
483  std::to_string(current_baudrate.value()));
484  for (uint8_t i = 0; i < baudrates.size(); i++)
485  {
486  if (current_baudrate.value() == baudrate_)
487  {
488  break; // Break if the desired baudrate has been reached.
489  }
490  if (current_baudrate.value() >= baudrates[i] &&
491  baudrate_ > baudrates[i])
492  {
493  continue;
494  }
495  // Increment until Baudrate[i] matches current_baudrate.
496  try
497  {
498  stream_->set_option(
499  boost::asio::serial_port_base::baud_rate(baudrates[i]));
500  } catch (boost::system::system_error& e)
501  {
502 
504  "set_option failed due to " +
505  static_cast<std::string>(e.what()));
507  "Additional info about error is " +
508  static_cast<std::string>(e.what()));
509  return false;
510  }
511  using namespace std::chrono_literals;
512  std::this_thread::sleep_for(500ms);
513 
514  try
515  {
516  stream_->get_option(current_baudrate);
517  } catch (boost::system::system_error& e)
518  {
519 
521  "get_option failed due to " +
522  static_cast<std::string>(e.what()));
524  "Additional info about error is " +
525  static_cast<std::string>(e.what()));
526  /*
527  boost::system::error_code e_loop;
528  do // Caution: Might cause infinite loop..
529  {
530  stream_->get_option(current_baudrate, e_loop);
531  } while(e_loop);
532  */
533  return false;
534  }
536  "Set ASIO baudrate to " +
537  std::to_string(current_baudrate.value()));
538  }
540  "Set ASIO baudrate to " +
541  std::to_string(current_baudrate.value()) +
542  ", leaving InitializeSerial() method");
543 
544  // clear io
545  ::tcflush(stream_->native_handle(), TCIOFLUSH);
546 
547  return true;
548  }
549 
550  private:
552  std::shared_ptr<boost::asio::io_context> ioContext_;
553  std::string flowcontrol_;
554  uint32_t baudrate_;
555 
556  public:
557  std::unique_ptr<boost::asio::serial_port> stream_;
558  };
559 
560  class SbfFileIo
561  {
562  public:
564  std::shared_ptr<boost::asio::io_context> ioContext) :
565  node_(node), ioContext_(ioContext)
566  {
567  }
568 
569  ~SbfFileIo() { stream_->close(); }
570 
571  void close() { stream_->close(); }
572 
573  [[nodiscard]] bool connect()
574  {
575  node_->log(log_level::INFO, "Opening SBF file stream" +
576  node_->settings()->device + "...");
577 
578  int fd = open(node_->settings()->device.c_str(), O_RDONLY);
579  if (fd == -1)
580  {
581  node_->log(log_level::ERROR, "open SBF file failed.");
582  return false;
583  }
584 
585  try
586  {
587  stream_ = std::make_unique<boost::asio::posix::stream_descriptor>(
588  *ioContext_);
589  stream_->assign(fd);
590 
591  } catch (std::runtime_error& e)
592  {
593  node_->log(log_level::ERROR, "assigning SBF file failed due to " +
594  static_cast<std::string>(e.what()));
595  return false;
596  }
597  return true;
598  }
599 
600  private:
602  std::shared_ptr<boost::asio::io_context> ioContext_;
603 
604  public:
605  std::unique_ptr<boost::asio::posix::stream_descriptor> stream_;
606  };
607 
609  {
610  public:
612  std::shared_ptr<boost::asio::io_context> ioContext) :
613  node_(node), ioContext_(ioContext)
614  {
615  }
616 
618  {
619  pcap_close(pcap_);
620  stream_->close();
621  }
622 
623  void close()
624  {
625  pcap_close(pcap_);
626  stream_->close();
627  }
628 
629  [[nodiscard]] bool connect()
630  {
631  try
632  {
633  node_->log(log_level::INFO, "Opening pcap file stream" +
634  node_->settings()->device + "...");
635 
636  stream_ = std::make_unique<boost::asio::posix::stream_descriptor>(
637  *ioContext_);
638 
639  pcap_ = pcap_open_offline(node_->settings()->device.c_str(),
640  errBuff_.data());
641  stream_->assign(pcap_get_selectable_fd(pcap_));
642 
643  } catch (std::runtime_error& e)
644  {
645  node_->log(log_level::ERROR, "assigning PCAP file failed due to " +
646  static_cast<std::string>(e.what()));
647  return false;
648  }
649  return true;
650  }
651 
652  private:
654  std::shared_ptr<boost::asio::io_context> ioContext_;
655  std::array<char, 100> errBuff_;
656  pcap_t* pcap_;
657 
658  public:
659  std::unique_ptr<boost::asio::posix::stream_descriptor> stream_;
660  };
661 } // namespace io
io::PcapFileIo::connect
bool connect()
Definition: io.hpp:629
io::UdpClient
Definition: io.hpp:66
crc::isValid
bool isValid(const std::vector< uint8_t > &message)
Validates whether the calculated CRC of the SBF block at hand matches the CRC field of the streamed S...
Definition: crc.cpp:71
Timestamp
uint64_t Timestamp
Definition: typedefs.hpp:101
io::TcpIo::ioContext_
std::shared_ptr< boost::asio::io_context > ioContext_
Definition: io.hpp:359
NMEA_INS_SYNC_BYTE_3
static const uint8_t NMEA_INS_SYNC_BYTE_3
0x4E is ASCII for N - 3rd byte to indicate NMEA-type ASCII message
Definition: telegram.hpp:59
ConcurrentQueue< std::shared_ptr< Telegram > >
io::UdpClient::port_
int16_t port_
Definition: io.hpp:235
io::TcpIo::connect
bool connect()
Definition: io.hpp:268
io::UdpClient::socket_
std::unique_ptr< boost::asio::ip::udp::socket > socket_
Definition: io.hpp:240
telegram_type::NMEA_INS
@ NMEA_INS
Definition: telegram.hpp:101
ROSaicNodeBase::log
void log(log_level::LogLevel logLevel, const std::string &s) const
Log function to provide abstraction of ROS loggers.
Definition: typedefs.hpp:286
s
XmlRpcServer s
io::SerialIo::~SerialIo
~SerialIo()
Definition: io.hpp:380
io::TcpIo::deadline_
boost::asio::deadline_timer deadline_
Definition: io.hpp:360
io::TcpIo::close
void close()
Definition: io.hpp:260
io::UdpClient::runIoContext
void runIoContext()
Definition: io.hpp:195
SYNC_BYTE_1
static const uint8_t SYNC_BYTE_1
0x24 is ASCII for $ - 1st byte in each message
Definition: telegram.hpp:49
io::TcpIo::TcpIo
TcpIo(ROSaicNodeBase *node, std::shared_ptr< boost::asio::io_context > ioContext)
Definition: io.hpp:248
io::PcapFileIo::ioContext_
std::shared_ptr< boost::asio::io_context > ioContext_
Definition: io.hpp:654
io::SerialIo::SerialIo
SerialIo(ROSaicNodeBase *node, std::shared_ptr< boost::asio::io_context > ioContext)
Definition: io.hpp:371
io::TcpIo::stream_
std::unique_ptr< boost::asio::ip::tcp::socket > stream_
Definition: io.hpp:365
io::SbfFileIo::close
void close()
Definition: io.hpp:571
io::SbfFileIo::ioContext_
std::shared_ptr< boost::asio::io_context > ioContext_
Definition: io.hpp:602
ROSaicNodeBase::ok
bool ok()
Definition: typedefs.hpp:203
telegram.hpp
io::UdpClient::watchdogThread_
std::thread watchdogThread_
Definition: io.hpp:238
telegram_type::NMEA
@ NMEA
Definition: telegram.hpp:100
io::SerialIo::setBaudrate
bool setBaudrate()
Definition: io.hpp:447
ROSaicNodeBase
This class is the base class for abstraction.
Definition: typedefs.hpp:192
io::UdpClient::ioThread_
std::thread ioThread_
Definition: io.hpp:237
io::UdpClient::~UdpClient
~UdpClient()
Definition: io.hpp:77
Settings::baudrate
uint32_t baudrate
Baudrate.
Definition: settings.hpp:183
io::UdpClient::running_
std::atomic< bool > running_
Definition: io.hpp:234
io::UdpClient::connect
void connect()
Definition: io.hpp:89
io::SbfFileIo::SbfFileIo
SbfFileIo(ROSaicNodeBase *node, std::shared_ptr< boost::asio::io_context > ioContext)
Definition: io.hpp:563
io::SerialIo
Definition: io.hpp:368
parsing_utilities::parseUInt16
uint16_t parseUInt16(const uint8_t *buffer)
Converts a 2-byte-buffer into an unsigned 16-bit integer.
Definition: parsing_utilities.cpp:166
baudrates
const static std::array< uint32_t, 21 > baudrates
Possible baudrates for the Rx.
Definition: io.hpp:59
SBF_SYNC_BYTE_2
static const uint8_t SBF_SYNC_BYTE_2
0x40 is ASCII for @ - 2nd byte to indicate SBF block
Definition: telegram.hpp:51
io::UdpClient::telegramQueue_
TelegramQueue * telegramQueue_
Definition: io.hpp:242
io::PcapFileIo::node_
ROSaicNodeBase * node_
Definition: io.hpp:653
io::PcapFileIo::stream_
std::unique_ptr< boost::asio::posix::stream_descriptor > stream_
Definition: io.hpp:659
io::SbfFileIo::connect
bool connect()
Definition: io.hpp:573
io::SerialIo::stream_
std::unique_ptr< boost::asio::serial_port > stream_
Definition: io.hpp:557
ROSaicNodeBase::settings
const Settings * settings() const
Definition: typedefs.hpp:205
io::SerialIo::flowcontrol_
std::string flowcontrol_
Definition: io.hpp:553
io
Definition: async_manager.hpp:83
io::UdpClient::node_
ROSaicNodeBase * node_
Pointer to the node.
Definition: io.hpp:233
io::TcpIo::~TcpIo
~TcpIo()
Definition: io.hpp:258
ConcurrentQueue::push
void push(const T &input) noexcept
Definition: telegram.hpp:186
io::UdpClient::handleReceive
void handleReceive(const boost::system::error_code &error, size_t bytes_recvd)
Definition: io.hpp:113
parsing_utilities::getId
uint16_t getId(const std::vector< uint8_t > &message)
Get the ID of the SBF message.
Definition: parsing_utilities.cpp:310
Settings::device_tcp_port
std::string device_tcp_port
TCP port.
Definition: settings.hpp:160
io::SbfFileIo::~SbfFileIo
~SbfFileIo()
Definition: io.hpp:569
io::UdpClient::buffer_
std::array< uint8_t, MAX_UDP_PACKET_SIZE > buffer_
Definition: io.hpp:241
typedefs.hpp
io::UdpClient::runWatchdog
void runWatchdog()
Definition: io.hpp:201
io::SbfFileIo::node_
ROSaicNodeBase * node_
Definition: io.hpp:601
io::SerialIo::connect
bool connect()
Definition: io.hpp:384
io::PcapFileIo::close
void close()
Definition: io.hpp:623
io::TcpIo
Definition: io.hpp:245
SBF_HEADER_SIZE
static const uint16_t SBF_HEADER_SIZE
Definition: telegram.hpp:91
io::SerialIo::close
void close()
Definition: io.hpp:382
io::SerialIo::baudrate_
uint32_t baudrate_
Definition: io.hpp:554
log_level::ERROR
@ ERROR
Definition: typedefs.hpp:183
io::PcapFileIo::errBuff_
std::array< char, 100 > errBuff_
Definition: io.hpp:655
io::SerialIo::ioContext_
std::shared_ptr< boost::asio::io_context > ioContext_
Definition: io.hpp:552
settings
Definition: settings_helpers.hpp:41
ROSaicNodeBase::getTime
Timestamp getTime() const
Gets current timestamp.
Definition: typedefs.hpp:314
Settings::device_tcp_ip
std::string device_tcp_ip
TCP IP.
Definition: settings.hpp:158
io::UdpClient::eP_
boost::asio::ip::udp::endpoint eP_
Definition: io.hpp:239
io::TcpIo::checkDeadline
void checkDeadline()
Definition: io.hpp:345
io::PcapFileIo::~PcapFileIo
~PcapFileIo()
Definition: io.hpp:617
log_level::DEBUG
@ DEBUG
Definition: typedefs.hpp:180
io::TcpIo::port_
std::string port_
Definition: io.hpp:362
io::TcpIo::setPort
void setPort(const std::string &port)
Definition: io.hpp:266
NMEA_SYNC_BYTE_2
static const uint8_t NMEA_SYNC_BYTE_2
0x47 is ASCII for G - 2nd byte to indicate NMEA-type ASCII message
Definition: telegram.hpp:53
io::UdpClient::asyncReceive
void asyncReceive()
Definition: io.hpp:103
NMEA_INS_SYNC_BYTE_2
static const uint8_t NMEA_INS_SYNC_BYTE_2
0x49 is ASCII for I - 2nd byte to indicate INS NMEA-type ASCII message
Definition: telegram.hpp:57
telegram_type::SBF
@ SBF
Definition: telegram.hpp:99
io::PcapFileIo::PcapFileIo
PcapFileIo(ROSaicNodeBase *node, std::shared_ptr< boost::asio::io_context > ioContext)
Definition: io.hpp:611
typedefs_ros1.hpp
io::TcpIo::connectInternal
boost::system::error_code connectInternal(const boost::asio::ip::tcp::resolver::results_type &endpoints)
Definition: io.hpp:331
CR
static const uint8_t CR
0x0D is ASCII for "Carriage Return", i.e. "Enter"
Definition: telegram.hpp:70
length
TF2SIMD_FORCE_INLINE tf2Scalar length(const Quaternion &q)
io::SbfFileIo::stream_
std::unique_ptr< boost::asio::posix::stream_descriptor > stream_
Definition: io.hpp:605
io::TcpIo::node_
ROSaicNodeBase * node_
Definition: io.hpp:358
NMEA_SYNC_BYTE_3
static const uint8_t NMEA_SYNC_BYTE_3
0x50 is ASCII for P - 3rd byte to indicate NMEA-type ASCII message
Definition: telegram.hpp:55
Settings::device
std::string device
Device.
Definition: settings.hpp:154
io::UdpClient::ioContext_
boost::asio::io_context ioContext_
Definition: io.hpp:236
io::SbfFileIo
Definition: io.hpp:560
io::UdpClient::findNmeaEnd
size_t findNmeaEnd(size_t idx, size_t bytes_recvd)
Definition: io.hpp:219
io::PcapFileIo::pcap_
pcap_t * pcap_
Definition: io.hpp:656
io::UdpClient::UdpClient
UdpClient(ROSaicNodeBase *node, int16_t port, TelegramQueue *telegramQueue)
Definition: io.hpp:69
log_level::INFO
@ INFO
Definition: typedefs.hpp:181
io::SerialIo::node_
ROSaicNodeBase * node_
Definition: io.hpp:551
LF
static const uint8_t LF
0x0A is ASCII for "Line Feed", i.e. "New Line"
Definition: telegram.hpp:72
io::PcapFileIo
Definition: io.hpp:608
MAX_UDP_PACKET_SIZE
static const uint16_t MAX_UDP_PACKET_SIZE
Definition: telegram.hpp:93


septentrio_gnss_driver
Author(s): Tibor Dome, Thomas Emter
autogenerated on Sat May 10 2025 03:03:10