node.cpp
Go to the documentation of this file.
1 //==============================================================================
2 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Flight Systems and Automatic Control group,
13 // TU Darmstadt, nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND
19 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
22 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //==============================================================================
29 
30 #include "ublox_gps/node.h"
31 #include <cmath>
32 #include <string>
33 #include <sstream>
34 
35 using namespace ublox_node;
36 
38 constexpr static int kResetWait = 10;
39 
40 //
41 // ublox_node namespace
42 //
43 uint8_t ublox_node::modelFromString(const std::string& model) {
44  std::string lower = model;
45  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
46  if(lower == "portable") {
47  return ublox_msgs::CfgNAV5::DYN_MODEL_PORTABLE;
48  } else if(lower == "stationary") {
49  return ublox_msgs::CfgNAV5::DYN_MODEL_STATIONARY;
50  } else if(lower == "pedestrian") {
51  return ublox_msgs::CfgNAV5::DYN_MODEL_PEDESTRIAN;
52  } else if(lower == "automotive") {
53  return ublox_msgs::CfgNAV5::DYN_MODEL_AUTOMOTIVE;
54  } else if(lower == "sea") {
55  return ublox_msgs::CfgNAV5::DYN_MODEL_SEA;
56  } else if(lower == "airborne1") {
57  return ublox_msgs::CfgNAV5::DYN_MODEL_AIRBORNE_1G;
58  } else if(lower == "airborne2") {
59  return ublox_msgs::CfgNAV5::DYN_MODEL_AIRBORNE_2G;
60  } else if(lower == "airborne4") {
61  return ublox_msgs::CfgNAV5::DYN_MODEL_AIRBORNE_4G;
62  } else if(lower == "wristwatch") {
63  return ublox_msgs::CfgNAV5::DYN_MODEL_WRIST_WATCH;
64  } else if(lower == "bike") {
65  return ublox_msgs::CfgNAV5::DYN_MODEL_BIKE;
66  }
67 
68  throw std::runtime_error("Invalid settings: " + lower +
69  " is not a valid dynamic model.");
70 }
71 
72 uint8_t ublox_node::fixModeFromString(const std::string& mode) {
73  std::string lower = mode;
74  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
75  if (lower == "2d") {
76  return ublox_msgs::CfgNAV5::FIX_MODE_2D_ONLY;
77  } else if (lower == "3d") {
78  return ublox_msgs::CfgNAV5::FIX_MODE_3D_ONLY;
79  } else if (lower == "auto") {
80  return ublox_msgs::CfgNAV5::FIX_MODE_AUTO;
81  }
82 
83  throw std::runtime_error("Invalid settings: " + mode +
84  " is not a valid fix mode.");
85 }
86 
87 //
88 // u-blox ROS Node
89 //
91  initialize();
92 }
93 
95  int ublox_version;
96  if (protocol_version_ < 14) {
97  components_.push_back(ComponentPtr(new UbloxFirmware6));
98  ublox_version = 6;
99  } else if (protocol_version_ >= 14 && protocol_version_ <= 15) {
100  components_.push_back(ComponentPtr(new UbloxFirmware7));
101  ublox_version = 7;
102  } else if (protocol_version_ > 15 && protocol_version_ <= 23) {
103  components_.push_back(ComponentPtr(new UbloxFirmware8));
104  ublox_version = 8;
105  } else {
106  components_.push_back(ComponentPtr(new UbloxFirmware9));
107  ublox_version = 9;
108  }
109 
110  ROS_INFO("U-Blox Firmware Version: %d", ublox_version);
111 }
112 
113 
114 void UbloxNode::addProductInterface(std::string product_category,
115  std::string ref_rov) {
116  if (product_category.compare("HPG") == 0 && ref_rov.compare("REF") == 0)
117  components_.push_back(ComponentPtr(new HpgRefProduct));
118  else if (product_category.compare("HPG") == 0 && ref_rov.compare("ROV") == 0)
119  components_.push_back(ComponentPtr(new HpgRovProduct));
120  else if (product_category.compare("HPG") == 0)
121  components_.push_back(ComponentPtr(new HpPosRecProduct));
122  else if (product_category.compare("HDG") == 0)
123  components_.push_back(ComponentPtr(new HpPosRecProduct));
124  else if (product_category.compare("TIM") == 0)
125  components_.push_back(ComponentPtr(new TimProduct));
126  else if (product_category.compare("ADR") == 0 ||
127  product_category.compare("UDR") == 0 ||
128  product_category.compare("LAP") == 0)
130  else if (product_category.compare("FTS") == 0)
131  components_.push_back(ComponentPtr(new FtsProduct));
132  else if(product_category.compare("SPG") != 0)
133  ROS_WARN("Product category %s %s from MonVER message not recognized %s",
134  product_category.c_str(), ref_rov.c_str(),
135  "options are HPG REF, HPG ROV, HPG #.#, HDG #.#, TIM, ADR, UDR, LAP, FTS, SPG");
136 }
137 
139  nh->param("device", device_, std::string("/dev/ttyACM0"));
140  nh->param("frame_id", frame_id, std::string("gps"));
141 
142  // Save configuration parameters
143  getRosUint("load/mask", load_.loadMask, 0);
144  getRosUint("load/device", load_.deviceMask, 0);
145  getRosUint("save/mask", save_.saveMask, 0);
146  getRosUint("save/device", save_.deviceMask, 0);
147 
148  // UART 1 params
149  getRosUint("uart1/baudrate", baudrate_, 9600);
150  getRosUint("uart1/in", uart_in_, ublox_msgs::CfgPRT::PROTO_UBX
151  | ublox_msgs::CfgPRT::PROTO_NMEA
152  | ublox_msgs::CfgPRT::PROTO_RTCM);
153  getRosUint("uart1/out", uart_out_, ublox_msgs::CfgPRT::PROTO_UBX);
154  // USB params
155  set_usb_ = false;
156  if (nh->hasParam("usb/in") || nh->hasParam("usb/out")) {
157  set_usb_ = true;
158  if(!getRosUint("usb/in", usb_in_)) {
159  throw std::runtime_error(std::string("usb/out is set, therefore ") +
160  "usb/in must be set");
161  }
162  if(!getRosUint("usb/out", usb_out_)) {
163  throw std::runtime_error(std::string("usb/in is set, therefore ") +
164  "usb/out must be set");
165  }
166  getRosUint("usb/tx_ready", usb_tx_, 0);
167  }
168  // Measurement rate params
169  nh->param("rate", rate_, 4.0); // in Hz
170  getRosUint("nav_rate", nav_rate, 1); // # of measurement rate cycles
171  // RTCM params
172  getRosUint("rtcm/ids", rtcm_ids); // RTCM output message IDs
173  getRosUint("rtcm/rates", rtcm_rates); // RTCM output message rates
174  // PPP: Advanced Setting
175  nh->param("enable_ppp", enable_ppp_, false);
176  // SBAS params, only for some devices
177  nh->param("sbas", enable_sbas_, false);
178  getRosUint("sbas/max", max_sbas_, 0); // Maximum number of SBAS channels
179  getRosUint("sbas/usage", sbas_usage_, 0);
180  nh->param("dynamic_model", dynamic_model_, std::string("portable"));
181  nh->param("fix_mode", fix_mode_, std::string("auto"));
182  getRosUint("dr_limit", dr_limit_, 0); // Dead reckoning limit
183 
184  if (enable_ppp_)
185  ROS_WARN("Warning: PPP is enabled - this is an expert setting.");
186 
187  checkMin(rate_, 0, "rate");
188 
189  if(rtcm_ids.size() != rtcm_rates.size())
190  throw std::runtime_error(std::string("Invalid settings: size of rtcm_ids") +
191  " must match size of rtcm_rates");
192 
195 
196  nh->param("dat/set", set_dat_, false);
197  if(set_dat_) {
198  std::vector<float> shift, rot;
199  if (!nh->getParam("dat/majA", cfg_dat_.majA)
200  || nh->getParam("dat/flat", cfg_dat_.flat)
201  || nh->getParam("dat/shift", shift)
202  || nh->getParam("dat/rot", rot)
203  || nh->getParam("dat/scale", cfg_dat_.scale))
204  throw std::runtime_error(std::string("dat/set is true, therefore ") +
205  "dat/majA, dat/flat, dat/shift, dat/rot, & dat/scale must be set");
206  if(shift.size() != 3 || rot.size() != 3)
207  throw std::runtime_error(std::string("size of dat/shift & dat/rot ") +
208  "must be 3");
209  checkRange(cfg_dat_.majA, 6300000.0, 6500000.0, "dat/majA");
210  checkRange(cfg_dat_.flat, 0.0, 500.0, "dat/flat");
211 
212  checkRange(shift, 0.0, 500.0, "dat/shift");
213  cfg_dat_.dX = shift[0];
214  cfg_dat_.dY = shift[1];
215  cfg_dat_.dZ = shift[2];
216 
217  checkRange(rot, -5000.0, 5000.0, "dat/rot");
218  cfg_dat_.rotX = rot[0];
219  cfg_dat_.rotY = rot[1];
220  cfg_dat_.rotZ = rot[2];
221 
222  checkRange(cfg_dat_.scale, 0.0, 50.0, "scale");
223  }
224 
225  // measurement period [ms]
226  meas_rate = 1000 / rate_;
227 
228  // activate/deactivate any config
229  nh->param("config_on_startup", config_on_startup_flag_, true);
230 
231  // raw data stream logging
233 }
234 
236  // Poll version message to keep UDP socket active
237  gps.poll(ublox_msgs::MonVER::CLASS_ID, ublox_msgs::MonVER::MESSAGE_ID);
238 }
239 
241  static std::vector<uint8_t> payload(1, 1);
242  if (enabled["aid_alm"])
244  if (enabled["aid_eph"])
246  if (enabled["aid_hui"])
248 
249  payload[0]++;
250  if (payload[0] > 32) {
251  payload[0] = 1;
252  }
253 }
254 
255 void UbloxNode::printInf(const ublox_msgs::Inf &m, uint8_t id) {
257  ROS_ERROR_STREAM("INF: " << std::string(m.str.begin(), m.str.end()));
258  else if (id == ublox_msgs::Message::INF::WARNING)
259  ROS_WARN_STREAM("INF: " << std::string(m.str.begin(), m.str.end()));
260  else if (id == ublox_msgs::Message::INF::DEBUG)
261  ROS_DEBUG_STREAM("INF: " << std::string(m.str.begin(), m.str.end()));
262  else
263  ROS_INFO_STREAM("INF: " << std::string(m.str.begin(), m.str.end()));
264 }
265 
267  ROS_DEBUG("Subscribing to U-Blox messages");
268  // subscribe messages
269  nh->param("publish/all", enabled["all"], false);
270  nh->param("inf/all", enabled["inf"], true);
271  nh->param("publish/nav/all", enabled["nav"], enabled["all"]);
272  nh->param("publish/rxm/all", enabled["rxm"], enabled["all"]);
273  nh->param("publish/aid/all", enabled["aid"], enabled["all"]);
274  nh->param("publish/mon/all", enabled["mon"], enabled["all"]);
275 
276  // Nav Messages
277  nh->param("publish/nav/status", enabled["nav_status"], enabled["nav"]);
278  if (enabled["nav_status"])
279  gps.subscribe<ublox_msgs::NavSTATUS>(boost::bind(
280  publish<ublox_msgs::NavSTATUS>, _1, "navstatus"), kSubscribeRate);
281 
282  nh->param("publish/nav/posecef", enabled["nav_posecef"], enabled["nav"]);
283  if (enabled["nav_posecef"])
284  gps.subscribe<ublox_msgs::NavPOSECEF>(boost::bind(
285  publish<ublox_msgs::NavPOSECEF>, _1, "navposecef"), kSubscribeRate);
286 
287  nh->param("publish/nav/clock", enabled["nav_clock"], enabled["nav"]);
288  if (enabled["nav_clock"])
289  gps.subscribe<ublox_msgs::NavCLOCK>(boost::bind(
290  publish<ublox_msgs::NavCLOCK>, _1, "navclock"), kSubscribeRate);
291 
292  nh->param("publish/nmea", enabled["nmea"], false);
293  if (enabled["nmea"])
294  gps.subscribe_nmea(boost::bind(publish_nmea, _1, "nmea"));
295 
296  // INF messages
297  nh->param("inf/debug", enabled["inf_debug"], false);
298  if (enabled["inf_debug"])
299  gps.subscribeId<ublox_msgs::Inf>(
300  boost::bind(&UbloxNode::printInf, this, _1,
303 
304  nh->param("inf/error", enabled["inf_error"], enabled["inf"]);
305  if (enabled["inf_error"])
306  gps.subscribeId<ublox_msgs::Inf>(
307  boost::bind(&UbloxNode::printInf, this, _1,
310 
311  nh->param("inf/notice", enabled["inf_notice"], enabled["inf"]);
312  if (enabled["inf_notice"])
313  gps.subscribeId<ublox_msgs::Inf>(
314  boost::bind(&UbloxNode::printInf, this, _1,
317 
318  nh->param("inf/test", enabled["inf_test"], enabled["inf"]);
319  if (enabled["inf_test"])
320  gps.subscribeId<ublox_msgs::Inf>(
321  boost::bind(&UbloxNode::printInf, this, _1,
324 
325  nh->param("inf/warning", enabled["inf_warning"], enabled["inf"]);
326  if (enabled["inf_warning"])
327  gps.subscribeId<ublox_msgs::Inf>(
328  boost::bind(&UbloxNode::printInf, this, _1,
331 
332  // AID messages
333  nh->param("publish/aid/alm", enabled["aid_alm"], enabled["aid"]);
334  if (enabled["aid_alm"])
335  gps.subscribe<ublox_msgs::AidALM>(boost::bind(
336  publish<ublox_msgs::AidALM>, _1, "aidalm"), kSubscribeRate);
337 
338  nh->param("publish/aid/eph", enabled["aid_eph"], enabled["aid"]);
339  if (enabled["aid_eph"])
340  gps.subscribe<ublox_msgs::AidEPH>(boost::bind(
341  publish<ublox_msgs::AidEPH>, _1, "aideph"), kSubscribeRate);
342 
343  nh->param("publish/aid/hui", enabled["aid_hui"], enabled["aid"]);
344  if (enabled["aid_hui"])
345  gps.subscribe<ublox_msgs::AidHUI>(boost::bind(
346  publish<ublox_msgs::AidHUI>, _1, "aidhui"), kSubscribeRate);
347 
348  for(int i = 0; i < components_.size(); i++)
349  components_[i]->subscribe();
350 }
351 
353  if (!nh->hasParam("diagnostic_period"))
354  nh->setParam("diagnostic_period", kDiagnosticPeriod);
355 
357  updater->setHardwareID("ublox");
358 
359  // configure diagnostic updater for frequency
360  freq_diag.reset(new FixDiagnostic(std::string("fix"), kFixFreqTol,
362  for(int i = 0; i < components_.size(); i++)
364 }
365 
366 
368  ublox_msgs::MonVER monVer;
369  if (!gps.poll(monVer))
370  throw std::runtime_error("Failed to poll MonVER & set relevant settings");
371 
372  ROS_DEBUG("%s, HW VER: %s", monVer.swVersion.c_array(),
373  monVer.hwVersion.c_array());
374  // Convert extension to vector of strings
375  std::vector<std::string> extension;
376  extension.reserve(monVer.extension.size());
377  for(std::size_t i = 0; i < monVer.extension.size(); ++i) {
378  ROS_DEBUG("%s", monVer.extension[i].field.c_array());
379  // Find the end of the string (null character)
380  unsigned char* end = std::find(monVer.extension[i].field.begin(),
381  monVer.extension[i].field.end(), '\0');
382  extension.push_back(std::string(monVer.extension[i].field.begin(), end));
383  }
384 
385  // Get the protocol version
386  for(std::size_t i = 0; i < extension.size(); ++i) {
387  std::size_t found = extension[i].find("PROTVER");
388  if (found != std::string::npos) {
389  protocol_version_ = ::atof(
390  extension[i].substr(8, extension[i].size()-8).c_str());
391  break;
392  }
393  }
394  if (protocol_version_ == 0)
395  ROS_WARN("Failed to parse MonVER and determine protocol version. %s",
396  "Defaulting to firmware version 6.");
398 
399  if(protocol_version_ < 18) {
400  // Final line contains supported GNSS delimited by ;
401  std::vector<std::string> strs;
402  if(extension.size() > 0)
403  boost::split(strs, extension[extension.size()-1], boost::is_any_of(";"));
404  for(size_t i = 0; i < strs.size(); i++)
405  supported.insert(strs[i]);
406  } else {
407  for(std::size_t i = 0; i < extension.size(); ++i) {
408  std::vector<std::string> strs;
409  // Up to 2nd to last line
410  if(i <= extension.size() - 2) {
411  boost::split(strs, extension[i], boost::is_any_of("="));
412  if(strs.size() > 1) {
413  if (strs[0].compare(std::string("FWVER")) == 0) {
414  if(strs[1].length() > 8)
415  addProductInterface(strs[1].substr(0, 3), strs[1].substr(8, 10));
416  else
417  addProductInterface(strs[1].substr(0, 3));
418  continue;
419  }
420  }
421  }
422  // Last 1-2 lines contain supported GNSS
423  if(i >= extension.size() - 2) {
424  boost::split(strs, extension[i], boost::is_any_of(";"));
425  for(size_t i = 0; i < strs.size(); i++)
426  supported.insert(strs[i]);
427  }
428  }
429  }
430 }
431 
433  try {
434  if (!gps.isInitialized())
435  throw std::runtime_error("Failed to initialize.");
436  if (load_.loadMask != 0) {
437  ROS_DEBUG("Loading u-blox configuration from memory. %u", load_.loadMask);
438  if (!gps.configure(load_))
439  throw std::runtime_error(std::string("Failed to load configuration ") +
440  "from memory");
441  if (load_.loadMask & load_.MASK_IO_PORT) {
442  ROS_DEBUG("Loaded I/O configuration from memory, resetting serial %s",
443  "communications.");
444  boost::posix_time::seconds wait(kResetWait);
445  gps.reset(wait);
446  if (!gps.isConfigured())
447  throw std::runtime_error(std::string("Failed to reset serial I/O") +
448  "after loading I/O configurations from device memory.");
449  }
450  }
451 
453  if (set_usb_) {
455  }
456  if (!gps.configRate(meas_rate, nav_rate)) {
457  std::stringstream ss;
458  ss << "Failed to set measurement rate to " << meas_rate
459  << "ms and navigation rate to " << nav_rate;
460  throw std::runtime_error(ss.str());
461  }
462  // If device doesn't have SBAS, will receive NACK (causes exception)
463  if(supportsGnss("SBAS")) {
465  throw std::runtime_error(std::string("Failed to ") +
466  ((enable_sbas_) ? "enable" : "disable") +
467  " SBAS.");
468  }
469  }
471  throw std::runtime_error(std::string("Failed to ") +
472  ((enable_ppp_) ? "enable" : "disable")
473  + " PPP.");
475  throw std::runtime_error("Failed to set model: " + dynamic_model_ + ".");
476  if (!gps.setFixMode(fmode_))
477  throw std::runtime_error("Failed to set fix mode: " + fix_mode_ + ".");
479  std::stringstream ss;
480  ss << "Failed to set dead reckoning limit: " << dr_limit_ << ".";
481  throw std::runtime_error(ss.str());
482  }
483  if (set_dat_ && !gps.configure(cfg_dat_))
484  throw std::runtime_error("Failed to set user-defined datum.");
485  // Configure each component
486  for (int i = 0; i < components_.size(); i++) {
487  if(!components_[i]->configureUblox())
488  return false;
489  }
490  }
491  if (save_.saveMask != 0) {
492  ROS_DEBUG("Saving the u-blox configuration, mask %u, device %u",
493  save_.saveMask, save_.deviceMask);
494  if(!gps.configure(save_))
495  ROS_ERROR("u-blox unable to save configuration to non-volatile memory");
496  }
497  } catch (std::exception& e) {
498  ROS_FATAL("Error configuring u-blox: %s", e.what());
499  return false;
500  }
501  return true;
502 }
503 
505  ublox_msgs::CfgINF msg;
506  // Subscribe to UBX INF messages
507  ublox_msgs::CfgINF_Block block;
508  block.protocolID = block.PROTOCOL_ID_UBX;
509  // Enable desired INF messages on each UBX port
510  uint8_t mask = (enabled["inf_error"] ? block.INF_MSG_ERROR : 0) |
511  (enabled["inf_warning"] ? block.INF_MSG_WARNING : 0) |
512  (enabled["inf_notice"] ? block.INF_MSG_NOTICE : 0) |
513  (enabled["inf_test"] ? block.INF_MSG_TEST : 0) |
514  (enabled["inf_debug"] ? block.INF_MSG_DEBUG : 0);
515  for (int i = 0; i < block.infMsgMask.size(); i++)
516  block.infMsgMask[i] = mask;
517 
518  msg.blocks.push_back(block);
519 
520  // IF NMEA is enabled
521  if (uart_in_ & ublox_msgs::CfgPRT::PROTO_NMEA) {
522  ublox_msgs::CfgINF_Block block;
523  block.protocolID = block.PROTOCOL_ID_NMEA;
524  // Enable desired INF messages on each NMEA port
525  for (int i = 0; i < block.infMsgMask.size(); i++)
526  block.infMsgMask[i] = mask;
527  msg.blocks.push_back(block);
528  }
529 
530  ROS_DEBUG("Configuring INF messages");
531  if (!gps.configure(msg))
532  ROS_WARN("Failed to configure INF messages");
533 }
534 
537 
538  boost::smatch match;
539  if (boost::regex_match(device_, match,
540  boost::regex("(tcp|udp)://(.+):(\\d+)"))) {
541  std::string proto(match[1]);
542  if (proto == "tcp") {
543  std::string host(match[2]);
544  std::string port(match[3]);
545  ROS_INFO("Connecting to %s://%s:%s ...", proto.c_str(), host.c_str(),
546  port.c_str());
547  gps.initializeTcp(host, port);
548  } else if (proto == "udp") {
549  std::string host(match[2]);
550  std::string port(match[3]);
551  ROS_INFO("Connecting to %s://%s:%s ...", proto.c_str(), host.c_str(),
552  port.c_str());
553  gps.initializeUdp(host, port);
554  } else {
555  throw std::runtime_error("Protocol '" + proto + "' is unsupported");
556  }
557  } else {
559  }
560 
561  // raw data stream logging
562  if (rawDataStreamPa_.isEnabled()) {
564  boost::bind(&RawDataStreamPa::ubloxCallback,&rawDataStreamPa_, _1, _2));
566  }
567 }
568 
570  // Params must be set before initializing IO
571  getRosParams();
572  initializeIo();
573  // Must process Mon VER before setting firmware/hardware params
574  processMonVer();
575  if(protocol_version_ <= 14) {
576  if(nh->param("raw_data", false))
577  components_.push_back(ComponentPtr(new RawDataProduct));
578  }
579  // Must set firmware & hardware params before initializing diagnostics
580  for (int i = 0; i < components_.size(); i++)
582  // Do this last
584 
585  if (configureUblox()) {
586  ROS_INFO("U-Blox configured successfully.");
587  // Subscribe to all U-Blox messages
588  subscribe();
589  // Configure INF messages (needs INF params, call after subscribing)
590  configureInf();
591 
592  ros::Timer keep_alive;
593  if (device_.substr(0, 6) == "udp://") {
594  // Setup timer to poll version message to keep UDP socket active
595  keep_alive = nh->createTimer(ros::Duration(kKeepAlivePeriod),
597  this);
598  }
599 
600  ros::Timer poller;
601  poller = nh->createTimer(ros::Duration(kPollDuration),
603  this);
604  poller.start();
605  ros::spin();
606  }
607  shutdown();
608 }
609 
611  if (gps.isInitialized()) {
612  gps.close();
613  ROS_INFO("Closed connection to %s.", device_.c_str());
614  }
615 }
616 
617 //
618 // U-Blox Firmware (all versions)
619 //
621  updater->add("fix", this, &UbloxFirmware::fixDiagnostic);
622  updater->force_update();
623 }
624 
625 //
626 // U-Blox Firmware Version 6
627 //
629 
631  // Fix Service type, used when publishing fix status messages
632  fix_status_service = sensor_msgs::NavSatStatus::SERVICE_GPS;
633 
634  nh->param("nmea/set", set_nmea_, false);
635  if (set_nmea_) {
636  bool compat, consider;
637 
638  if (!getRosUint("nmea/version", cfg_nmea_.version))
639  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
640  "true, therefore nmea/version must be set");
641  if (!getRosUint("nmea/num_sv", cfg_nmea_.numSV))
642  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
643  "true, therefore nmea/num_sv must be set");
644  if (!nh->getParam("nmea/compat", compat))
645  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
646  "true, therefore nmea/compat must be set");
647  if (!nh->getParam("nmea/consider", consider))
648  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
649  "true, therefore nmea/consider must be set");
650 
651  // set flags
652  cfg_nmea_.flags = compat ? cfg_nmea_.FLAGS_COMPAT : 0;
653  cfg_nmea_.flags |= consider ? cfg_nmea_.FLAGS_CONSIDER : 0;
654 
655  // set filter
656  bool temp;
657  nh->param("nmea/filter/pos", temp, false);
658  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_POS : 0;
659  nh->param("nmea/filter/msk_pos", temp, false);
660  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_MSK_POS : 0;
661  nh->param("nmea/filter/time", temp, false);
662  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TIME : 0;
663  nh->param("nmea/filter/date", temp, false);
664  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_DATE : 0;
665  nh->param("nmea/filter/sbas", temp, false);
666  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_SBAS_FILT : 0;
667  nh->param("nmea/filter/track", temp, false);
668  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TRACK : 0;
669  }
670 }
671 
673  ROS_WARN("ublox_version < 7, ignoring GNSS settings");
674 
675  if (set_nmea_ && !gps.configure(cfg_nmea_))
676  throw std::runtime_error("Failed to configure NMEA");
677 
678  return true;
679 }
680 
682  // Whether or not to publish Nav POS LLH (always subscribes)
683  nh->param("publish/nav/posllh", enabled["nav_posllh"], enabled["nav"]);
684  nh->param("publish/nav/sol", enabled["nav_sol"], enabled["nav"]);
685  nh->param("publish/nav/velned", enabled["nav_velned"], enabled["nav"]);
686 
687  // Always subscribes to these messages, but may not publish to ROS topic
688  // Subscribe to Nav POSLLH
689  gps.subscribe<ublox_msgs::NavPOSLLH>(boost::bind(
691  // Subscribe to Nav SOL
692  gps.subscribe<ublox_msgs::NavSOL>(boost::bind(
694  // Subscribe to Nav VELNED
695  gps.subscribe<ublox_msgs::NavVELNED>(boost::bind(
697 
698  // Subscribe to Nav SVINFO
699  nh->param("publish/nav/svinfo", enabled["nav_svinfo"], enabled["nav"]);
700  if (enabled["nav_svinfo"])
701  gps.subscribe<ublox_msgs::NavSVINFO>(boost::bind(
702  publish<ublox_msgs::NavSVINFO>, _1, "navsvinfo"),
704 
705  // Subscribe to Mon HW
706  nh->param("publish/mon_hw", enabled["mon_hw"], enabled["mon"]);
707  if (enabled["mon_hw"])
708  gps.subscribe<ublox_msgs::MonHW6>(boost::bind(
709  publish<ublox_msgs::MonHW6>, _1, "monhw"), kSubscribeRate);
710 }
711 
714  // Set the diagnostic level based on the fix status
715  if (last_nav_sol_.gpsFix == ublox_msgs::NavSOL::GPS_DEAD_RECKONING_ONLY) {
716  stat.level = diagnostic_msgs::DiagnosticStatus::WARN;
717  stat.message = "Dead reckoning only";
718  } else if (last_nav_sol_.gpsFix == ublox_msgs::NavSOL::GPS_2D_FIX) {
719  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
720  stat.message = "2D fix";
721  } else if (last_nav_sol_.gpsFix == ublox_msgs::NavSOL::GPS_3D_FIX) {
722  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
723  stat.message = "3D fix";
724  } else if (last_nav_sol_.gpsFix ==
725  ublox_msgs::NavSOL::GPS_GPS_DEAD_RECKONING_COMBINED) {
726  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
727  stat.message = "GPS and dead reckoning combined";
728  } else if (last_nav_sol_.gpsFix == ublox_msgs::NavSOL::GPS_TIME_ONLY_FIX) {
729  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
730  stat.message = "Time fix only";
731  }
732  // If fix is not ok (within DOP & Accuracy Masks), raise the diagnostic level
733  if (!(last_nav_sol_.flags & ublox_msgs::NavSOL::FLAGS_GPS_FIX_OK)) {
734  stat.level = diagnostic_msgs::DiagnosticStatus::WARN;
735  stat.message += ", fix not ok";
736  }
737  // Raise diagnostic level to error if no fix
738  if (last_nav_sol_.gpsFix == ublox_msgs::NavSOL::GPS_NO_FIX) {
739  stat.level = diagnostic_msgs::DiagnosticStatus::ERROR;
740  stat.message = "No fix";
741  }
742 
743  // Add last fix position
744  stat.add("iTOW [ms]", last_nav_pos_.iTOW);
745  stat.add("Latitude [deg]", last_nav_pos_.lat * 1e-7);
746  stat.add("Longitude [deg]", last_nav_pos_.lon * 1e-7);
747  stat.add("Altitude [m]", last_nav_pos_.height * 1e-3);
748  stat.add("Height above MSL [m]", last_nav_pos_.hMSL * 1e-3);
749  stat.add("Horizontal Accuracy [m]", last_nav_pos_.hAcc * 1e-3);
750  stat.add("Vertical Accuracy [m]", last_nav_pos_.vAcc * 1e-3);
751  stat.add("# SVs used", (int)last_nav_sol_.numSV);
752 }
753 
754 void UbloxFirmware6::callbackNavPosLlh(const ublox_msgs::NavPOSLLH& m) {
755  if(enabled["nav_posllh"]) {
756  static ros::Publisher publisher =
757  nh->advertise<ublox_msgs::NavPOSLLH>("navposllh", kROSQueueSize);
758  publisher.publish(m);
759  }
760 
761  // Position message
762  static ros::Publisher fixPublisher =
763  nh->advertise<sensor_msgs::NavSatFix>("fix", kROSQueueSize);
764  if (m.iTOW == last_nav_vel_.iTOW)
765  fix_.header.stamp = velocity_.header.stamp; // use last timestamp
766  else
767  fix_.header.stamp = ros::Time::now(); // new timestamp
768 
769  fix_.header.frame_id = frame_id;
770  fix_.latitude = m.lat * 1e-7;
771  fix_.longitude = m.lon * 1e-7;
772  fix_.altitude = m.height * 1e-3;
773 
774  if (last_nav_sol_.gpsFix >= last_nav_sol_.GPS_2D_FIX)
775  fix_.status.status = fix_.status.STATUS_FIX;
776  else
777  fix_.status.status = fix_.status.STATUS_NO_FIX;
778 
779  // Convert from mm to m
780  const double varH = pow(m.hAcc / 1000.0, 2);
781  const double varV = pow(m.vAcc / 1000.0, 2);
782 
783  fix_.position_covariance[0] = varH;
784  fix_.position_covariance[4] = varH;
785  fix_.position_covariance[8] = varV;
786  fix_.position_covariance_type =
787  sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
788 
789  fix_.status.service = fix_.status.SERVICE_GPS;
790  fixPublisher.publish(fix_);
791  last_nav_pos_ = m;
792  // update diagnostics
793  freq_diag->diagnostic->tick(fix_.header.stamp);
794  updater->update();
795 }
796 
797 void UbloxFirmware6::callbackNavVelNed(const ublox_msgs::NavVELNED& m) {
798  if(enabled["nav_velned"]) {
799  static ros::Publisher publisher =
800  nh->advertise<ublox_msgs::NavVELNED>("navvelned", kROSQueueSize);
801  publisher.publish(m);
802  }
803 
804  // Example geometry message
805  static ros::Publisher velocityPublisher =
806  nh->advertise<geometry_msgs::TwistWithCovarianceStamped>("fix_velocity",
807  kROSQueueSize);
808  if (m.iTOW == last_nav_pos_.iTOW)
809  velocity_.header.stamp = fix_.header.stamp; // same time as last navposllh
810  else
811  velocity_.header.stamp = ros::Time::now(); // create a new timestamp
812  velocity_.header.frame_id = frame_id;
813 
814  // convert to XYZ linear velocity
815  velocity_.twist.twist.linear.x = m.velE / 100.0;
816  velocity_.twist.twist.linear.y = m.velN / 100.0;
817  velocity_.twist.twist.linear.z = -m.velD / 100.0;
818 
819  const double varSpeed = pow(m.sAcc / 100.0, 2);
820 
821  const int cols = 6;
822  velocity_.twist.covariance[cols * 0 + 0] = varSpeed;
823  velocity_.twist.covariance[cols * 1 + 1] = varSpeed;
824  velocity_.twist.covariance[cols * 2 + 2] = varSpeed;
825  velocity_.twist.covariance[cols * 3 + 3] = -1; // angular rate unsupported
826 
827  velocityPublisher.publish(velocity_);
828  last_nav_vel_ = m;
829 }
830 
831 void UbloxFirmware6::callbackNavSol(const ublox_msgs::NavSOL& m) {
832  if(enabled["nav_sol"]) {
833  static ros::Publisher publisher =
834  nh->advertise<ublox_msgs::NavSOL>("navsol", kROSQueueSize);
835  publisher.publish(m);
836  }
837  last_nav_sol_ = m;
838 }
839 
840 //
841 // Ublox Firmware Version 7
842 //
844 
846  //
847  // GNSS configuration
848  //
849  // GNSS enable/disable
850  nh->param("gnss/gps", enable_gps_, true);
851  nh->param("gnss/glonass", enable_glonass_, false);
852  nh->param("gnss/qzss", enable_qzss_, false);
853  getRosUint("gnss/qzss_sig_cfg", qzss_sig_cfg_,
854  ublox_msgs::CfgGNSS_Block::SIG_CFG_QZSS_L1CA);
855  nh->param("gnss/sbas", enable_sbas_, false);
856 
857  if(enable_gps_ && !supportsGnss("GPS"))
858  ROS_WARN("gnss/gps is true, but GPS GNSS is not supported by this device");
859  if(enable_glonass_ && !supportsGnss("GLO"))
860  ROS_WARN("gnss/glonass is true, but GLONASS is not %s",
861  "supported by this device");
862  if(enable_qzss_ && !supportsGnss("QZSS"))
863  ROS_WARN("gnss/qzss is true, but QZSS is not supported by this device");
864  if(enable_sbas_ && !supportsGnss("SBAS"))
865  ROS_WARN("gnss/sbas is true, but SBAS is not supported by this device");
866 
867  if(nh->hasParam("gnss/galileo"))
868  ROS_WARN("ublox_version < 8, ignoring Galileo GNSS Settings");
869  if(nh->hasParam("gnss/beidou"))
870  ROS_WARN("ublox_version < 8, ignoring BeiDou Settings");
871  if(nh->hasParam("gnss/imes"))
872  ROS_WARN("ublox_version < 8, ignoring IMES GNSS Settings");
873 
874  // Fix Service type, used when publishing fix status messages
875  fix_status_service = sensor_msgs::NavSatStatus::SERVICE_GPS
876  + (enable_glonass_ ? 1 : 0) * sensor_msgs::NavSatStatus::SERVICE_GLONASS;
877 
878  //
879  // NMEA Configuration
880  //
881  nh->param("nmea/set", set_nmea_, false);
882  if (set_nmea_) {
883  bool compat, consider;
884 
885  if (!getRosUint("nmea/version", cfg_nmea_.nmeaVersion))
886  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
887  "true, therefore nmea/version must be set");
888  if (!getRosUint("nmea/num_sv", cfg_nmea_.numSV))
889  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
890  "true, therefore nmea/num_sv must be set");
891  if (!getRosUint("nmea/sv_numbering", cfg_nmea_.svNumbering))
892  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
893  "true, therefore nmea/sv_numbering must be set");
894  if (!nh->getParam("nmea/compat", compat))
895  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
896  "true, therefore nmea/compat must be set");
897  if (!nh->getParam("nmea/consider", consider))
898  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
899  "true, therefore nmea/consider must be set");
900 
901  // set flags
902  cfg_nmea_.flags = compat ? cfg_nmea_.FLAGS_COMPAT : 0;
903  cfg_nmea_.flags |= consider ? cfg_nmea_.FLAGS_CONSIDER : 0;
904  // set filter
905  bool temp;
906  nh->param("nmea/filter/pos", temp, false);
907  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_POS : 0;
908  nh->param("nmea/filter/msk_pos", temp, false);
909  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_MSK_POS : 0;
910  nh->param("nmea/filter/time", temp, false);
911  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TIME : 0;
912  nh->param("nmea/filter/date", temp, false);
913  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_DATE : 0;
914  nh->param("nmea/filter/gps_only", temp, false);
915  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_GPS_ONLY : 0;
916  nh->param("nmea/filter/track", temp, false);
917  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TRACK : 0;
918  // set gnssToFilter
919  nh->param("nmea/gnssToFilter/gps", temp, false);
920  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_GPS : 0;
921  nh->param("nmea/gnssToFilter/sbas", temp, false);
922  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_SBAS : 0;
923  nh->param("nmea/gnssToFilter/qzss", temp, false);
924  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_QZSS : 0;
925  nh->param("nmea/gnssToFilter/glonass", temp, false);
926  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_GLONASS : 0;
927 
928  getRosUint("nmea/main_talker_id", cfg_nmea_.mainTalkerId);
929  getRosUint("nmea/gsv_talker_id", cfg_nmea_.gsvTalkerId);
930  }
931 }
932 
935  ublox_msgs::CfgGNSS cfgGNSSRead;
936  if (gps.poll(cfgGNSSRead)) {
937  ROS_DEBUG("Read GNSS config.");
938  ROS_DEBUG("Num. tracking channels in hardware: %i", cfgGNSSRead.numTrkChHw);
939  ROS_DEBUG("Num. tracking channels to use: %i", cfgGNSSRead.numTrkChUse);
940  } else {
941  throw std::runtime_error("Failed to read the GNSS config.");
942  }
943 
944  ublox_msgs::CfgGNSS cfgGNSSWrite;
945  cfgGNSSWrite.numConfigBlocks = 1; // do services one by one
946  cfgGNSSWrite.numTrkChHw = cfgGNSSRead.numTrkChHw;
947  cfgGNSSWrite.numTrkChUse = cfgGNSSRead.numTrkChUse;
948  cfgGNSSWrite.msgVer = 0;
949 
950  // configure GLONASS
951  if(supportsGnss("GLO")) {
952  ublox_msgs::CfgGNSS_Block block;
953  block.gnssId = block.GNSS_ID_GLONASS;
954  block.resTrkCh = block.RES_TRK_CH_GLONASS;
955  block.maxTrkCh = block.MAX_TRK_CH_GLONASS;
956  block.flags = enable_glonass_ ? block.SIG_CFG_GLONASS_L1OF : 0;
957  cfgGNSSWrite.blocks.push_back(block);
958  if (!gps.configure(cfgGNSSWrite)) {
959  throw std::runtime_error(std::string("Failed to ") +
960  ((enable_glonass_) ? "enable" : "disable") +
961  " GLONASS.");
962  }
963  }
964 
965  if(supportsGnss("QZSS")) {
966  // configure QZSS
967  ublox_msgs::CfgGNSS_Block block;
968  block.gnssId = block.GNSS_ID_QZSS;
969  block.resTrkCh = block.RES_TRK_CH_QZSS;
970  block.maxTrkCh = block.MAX_TRK_CH_QZSS;
971  block.flags = enable_qzss_ ? qzss_sig_cfg_ : 0;
972  cfgGNSSWrite.blocks[0] = block;
973  if (!gps.configure(cfgGNSSWrite)) {
974  throw std::runtime_error(std::string("Failed to ") +
975  ((enable_glonass_) ? "enable" : "disable") +
976  " QZSS.");
977  }
978  }
979 
980  if(supportsGnss("SBAS")) {
981  // configure SBAS
982  ublox_msgs::CfgGNSS_Block block;
983  block.gnssId = block.GNSS_ID_SBAS;
984  block.resTrkCh = block.RES_TRK_CH_SBAS;
985  block.maxTrkCh = block.MAX_TRK_CH_SBAS;
986  block.flags = enable_sbas_ ? block.SIG_CFG_SBAS_L1CA : 0;
987  cfgGNSSWrite.blocks[0] = block;
988  if (!gps.configure(cfgGNSSWrite)) {
989  throw std::runtime_error(std::string("Failed to ") +
990  ((enable_sbas_) ? "enable" : "disable") +
991  " SBAS.");
992  }
993  }
994 
996  throw std::runtime_error("Failed to configure NMEA");
997 
998  return true;
999 }
1000 
1002  // Whether to publish Nav PVT messages to a ROS topic
1003  nh->param("publish/nav/pvt", enabled["nav_pvt"], enabled["nav"]);
1004  // Subscribe to Nav PVT (always does so since fix information is published
1005  // from this)
1006  gps.subscribe<ublox_msgs::NavPVT7>(boost::bind(
1008  kSubscribeRate);
1009 
1010  // Subscribe to Nav SVINFO
1011  nh->param("publish/nav/svinfo", enabled["nav_svinfo"], enabled["nav"]);
1012  if (enabled["nav_svinfo"])
1013  gps.subscribe<ublox_msgs::NavSVINFO>(boost::bind(
1014  publish<ublox_msgs::NavSVINFO>, _1, "navsvinfo"),
1016 
1017  // Subscribe to Mon HW
1018  nh->param("publish/mon_hw", enabled["mon_hw"], enabled["mon"]);
1019  if (enabled["mon_hw"])
1020  gps.subscribe<ublox_msgs::MonHW>(boost::bind(
1021  publish<ublox_msgs::MonHW>, _1, "monhw"), kSubscribeRate);
1022 }
1023 
1024 //
1025 // Ublox Version 8
1026 //
1028 
1030  // UPD SOS configuration
1031  nh->param("clear_bbr", clear_bbr_, false);
1032  gps.setSaveOnShutdown(nh->param("save_on_shutdown", false));
1033 
1034  // GNSS enable/disable
1035  nh->param("gnss/gps", enable_gps_, true);
1036  nh->param("gnss/galileo", enable_galileo_, false);
1037  nh->param("gnss/beidou", enable_beidou_, false);
1038  nh->param("gnss/imes", enable_imes_, false);
1039  nh->param("gnss/glonass", enable_glonass_, false);
1040  nh->param("gnss/qzss", enable_qzss_, false);
1041  nh->param("gnss/sbas", enable_sbas_, false);
1042  // QZSS Signal Configuration
1043  getRosUint("gnss/qzss_sig_cfg", qzss_sig_cfg_,
1044  ublox_msgs::CfgGNSS_Block::SIG_CFG_QZSS_L1CA);
1045 
1046  if (enable_gps_ && !supportsGnss("GPS"))
1047  ROS_WARN("gnss/gps is true, but GPS GNSS is not supported by %s",
1048  "this device");
1049  if (enable_glonass_ && !supportsGnss("GLO"))
1050  ROS_WARN("gnss/glonass is true, but GLONASS is not supported by %s",
1051  "this device");
1052  if (enable_galileo_ && !supportsGnss("GAL"))
1053  ROS_WARN("gnss/galileo is true, but Galileo GNSS is not supported %s",
1054  "by this device");
1055  if (enable_beidou_ && !supportsGnss("BDS"))
1056  ROS_WARN("gnss/beidou is true, but Beidou GNSS is not supported %s",
1057  "by this device");
1058  if (enable_imes_ && !supportsGnss("IMES"))
1059  ROS_WARN("gnss/imes is true, but IMES GNSS is not supported by %s",
1060  "this device");
1061  if (enable_qzss_ && !supportsGnss("QZSS"))
1062  ROS_WARN("gnss/qzss is true, but QZSS is not supported by this device");
1063  if (enable_sbas_ && !supportsGnss("SBAS"))
1064  ROS_WARN("gnss/sbas is true, but SBAS is not supported by this device");
1065 
1066  // Fix Service type, used when publishing fix status messages
1067  fix_status_service = sensor_msgs::NavSatStatus::SERVICE_GPS
1068  + (enable_glonass_ ? 1 : 0) * sensor_msgs::NavSatStatus::SERVICE_GLONASS
1069  + (enable_beidou_ ? 1 : 0) * sensor_msgs::NavSatStatus::SERVICE_COMPASS
1070  + (enable_galileo_ ? 1 : 0) * sensor_msgs::NavSatStatus::SERVICE_GALILEO;
1071 
1072  //
1073  // NMEA Configuration
1074  //
1075  nh->param("nmea/set", set_nmea_, false);
1076  if (set_nmea_) {
1077  bool compat, consider;
1078  cfg_nmea_.version = cfg_nmea_.VERSION; // message version
1079 
1080  // Verify that parameters are set
1081  if (!getRosUint("nmea/version", cfg_nmea_.nmeaVersion))
1082  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
1083  "true, therefore nmea/version must be set");
1084  if (!getRosUint("nmea/num_sv", cfg_nmea_.numSV))
1085  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
1086  "true, therefore nmea/num_sv must be set");
1087  if (!getRosUint("nmea/sv_numbering", cfg_nmea_.svNumbering))
1088  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
1089  "true, therefore nmea/sv_numbering must be set");
1090  if (!nh->getParam("nmea/compat", compat))
1091  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
1092  "true, therefore nmea/compat must be set");
1093  if (!nh->getParam("nmea/consider", consider))
1094  throw std::runtime_error(std::string("Invalid settings: nmea/set is ") +
1095  "true, therefore nmea/consider must be set");
1096 
1097  // set flags
1098  cfg_nmea_.flags = compat ? cfg_nmea_.FLAGS_COMPAT : 0;
1099  cfg_nmea_.flags |= consider ? cfg_nmea_.FLAGS_CONSIDER : 0;
1100  bool temp;
1101  nh->param("nmea/limit82", temp, false);
1102  cfg_nmea_.flags |= temp ? cfg_nmea_.FLAGS_LIMIT82 : 0;
1103  nh->param("nmea/high_prec", temp, false);
1104  cfg_nmea_.flags |= temp ? cfg_nmea_.FLAGS_HIGH_PREC : 0;
1105  // set filter
1106  nh->param("nmea/filter/pos", temp, false);
1107  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_POS : 0;
1108  nh->param("nmea/filter/msk_pos", temp, false);
1109  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_MSK_POS : 0;
1110  nh->param("nmea/filter/time", temp, false);
1111  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TIME : 0;
1112  nh->param("nmea/filter/date", temp, false);
1113  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_DATE : 0;
1114  nh->param("nmea/filter/gps_only", temp, false);
1115  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_GPS_ONLY : 0;
1116  nh->param("nmea/filter/track", temp, false);
1117  cfg_nmea_.filter |= temp ? cfg_nmea_.FILTER_TRACK : 0;
1118  // set gnssToFilter
1119  nh->param("nmea/gnssToFilter/gps", temp, false);
1120  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_GPS : 0;
1121  nh->param("nmea/gnssToFilter/sbas", temp, false);
1122  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_SBAS : 0;
1123  nh->param("nmea/gnssToFilter/qzss", temp, false);
1124  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_QZSS : 0;
1125  nh->param("nmea/gnssToFilter/glonass", temp, false);
1126  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_GLONASS : 0;
1127  nh->param("nmea/gnssToFilter/beidou", temp, false);
1128  cfg_nmea_.gnssToFilter |= temp ? cfg_nmea_.GNSS_TO_FILTER_BEIDOU : 0;
1129 
1130  getRosUint("nmea/main_talker_id", cfg_nmea_.mainTalkerId);
1131  getRosUint("nmea/gsv_talker_id", cfg_nmea_.gsvTalkerId);
1132 
1133  std::vector<uint8_t> bdsTalkerId;
1134  getRosUint("nmea/bds_talker_id", bdsTalkerId);
1135  if(bdsTalkerId.size() >= 2) {
1136  cfg_nmea_.bdsTalkerId[0] = bdsTalkerId[0];
1137  cfg_nmea_.bdsTalkerId[1] = bdsTalkerId[1];
1138  }
1139 
1140  }
1141 }
1142 
1143 
1145  if(clear_bbr_) {
1146  // clear flash memory
1147  if(!gps.clearBbr())
1148  ROS_ERROR("u-blox failed to clear flash memory");
1149  }
1150  //
1151  // Configure the GNSS, only if the configuration is different
1152  //
1153  // First, get the current GNSS configuration
1154  ublox_msgs::CfgGNSS cfg_gnss;
1155  if (gps.poll(cfg_gnss)) {
1156  ROS_DEBUG("Read GNSS config.");
1157  ROS_DEBUG("Num. tracking channels in hardware: %i", cfg_gnss.numTrkChHw);
1158  ROS_DEBUG("Num. tracking channels to use: %i", cfg_gnss.numTrkChUse);
1159  } else {
1160  throw std::runtime_error("Failed to read the GNSS config.");
1161  }
1162 
1163  // Then, check the configuration for each GNSS. If it is different, change it.
1164  bool correct = true;
1165  for (int i = 0; i < cfg_gnss.blocks.size(); i++) {
1166  ublox_msgs::CfgGNSS_Block block = cfg_gnss.blocks[i];
1167  if (block.gnssId == block.GNSS_ID_GPS
1168  && enable_gps_ != (block.flags & block.FLAGS_ENABLE)) {
1169  correct = false;
1170  cfg_gnss.blocks[i].flags =
1171  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_gps_;
1172  ROS_DEBUG("GPS Configuration is different");
1173  } else if (block.gnssId == block.GNSS_ID_SBAS
1174  && enable_sbas_ != (block.flags & block.FLAGS_ENABLE)) {
1175  correct = false;
1176  cfg_gnss.blocks[i].flags =
1177  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_sbas_;
1178  ROS_DEBUG("SBAS Configuration is different");
1179  } else if (block.gnssId == block.GNSS_ID_GALILEO
1180  && enable_galileo_ != (block.flags & block.FLAGS_ENABLE)) {
1181  correct = false;
1182  cfg_gnss.blocks[i].flags =
1183  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_galileo_;
1184  ROS_DEBUG("Galileo GNSS Configuration is different");
1185  } else if (block.gnssId == block.GNSS_ID_BEIDOU
1186  && enable_beidou_ != (block.flags & block.FLAGS_ENABLE)) {
1187  correct = false;
1188  cfg_gnss.blocks[i].flags =
1189  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_beidou_;
1190  ROS_DEBUG("BeiDou Configuration is different");
1191  } else if (block.gnssId == block.GNSS_ID_IMES
1192  && enable_imes_ != (block.flags & block.FLAGS_ENABLE)) {
1193  correct = false;
1194  cfg_gnss.blocks[i].flags =
1195  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_imes_;
1196  } else if (block.gnssId == block.GNSS_ID_QZSS
1197  && (enable_qzss_ != (block.flags & block.FLAGS_ENABLE)
1198  || (enable_qzss_
1199  && qzss_sig_cfg_ != (block.flags & block.FLAGS_SIG_CFG_MASK)))) {
1200  ROS_DEBUG("QZSS Configuration is different %u, %u",
1201  block.flags & block.FLAGS_ENABLE,
1202  enable_qzss_);
1203  correct = false;
1204  ROS_DEBUG("QZSS Configuration: %u", block.flags);
1205  cfg_gnss.blocks[i].flags =
1206  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_qzss_;
1207  ROS_DEBUG("QZSS Configuration: %u", cfg_gnss.blocks[i].flags);
1208  if (enable_qzss_)
1209  // Only change sig cfg if enabling
1210  cfg_gnss.blocks[i].flags |= qzss_sig_cfg_;
1211  } else if (block.gnssId == block.GNSS_ID_GLONASS
1212  && enable_glonass_ != (block.flags & block.FLAGS_ENABLE)) {
1213  correct = false;
1214  cfg_gnss.blocks[i].flags =
1215  (cfg_gnss.blocks[i].flags & ~block.FLAGS_ENABLE) | enable_glonass_;
1216  ROS_DEBUG("GLONASS Configuration is different");
1217  }
1218  }
1219 
1220  // If the GNSS is already configured correctly, do not re-configure GNSS
1221  // since this requires a cold reset
1222  if (correct)
1223  ROS_DEBUG("U-Blox GNSS configuration is correct. GNSS not re-configured.");
1224  else if (!gps.configGnss(cfg_gnss, boost::posix_time::seconds(15)))
1225  throw std::runtime_error(std::string("Failed to cold reset device ") +
1226  "after configuring GNSS");
1227 
1228  //
1229  // NMEA config
1230  //
1231  if (set_nmea_ && !gps.configure(cfg_nmea_))
1232  throw std::runtime_error("Failed to configure NMEA");
1233 
1234  return true;
1235 }
1236 
1238  // Whether to publish Nav PVT messages
1239  nh->param("publish/nav/pvt", enabled["nav_pvt"], enabled["nav"]);
1240  // Subscribe to Nav PVT
1241  gps.subscribe<ublox_msgs::NavPVT>(
1242  boost::bind(&UbloxFirmware7Plus::callbackNavPvt, this, _1), kSubscribeRate);
1243 
1244  // Subscribe to Nav SAT messages
1245  nh->param("publish/nav/sat", enabled["nav_sat"], enabled["nav"]);
1246  if (enabled["nav_sat"])
1247  gps.subscribe<ublox_msgs::NavSAT>(boost::bind(
1248  publish<ublox_msgs::NavSAT>, _1, "navsat"), kNavSvInfoSubscribeRate);
1249 
1250  // Subscribe to Mon HW
1251  nh->param("publish/mon/hw", enabled["mon_hw"], enabled["mon"]);
1252  if (enabled["mon_hw"])
1253  gps.subscribe<ublox_msgs::MonHW>(boost::bind(
1254  publish<ublox_msgs::MonHW>, _1, "monhw"), kSubscribeRate);
1255 
1256  // Subscribe to RTCM messages
1257  nh->param("publish/rxm/rtcm", enabled["rxm_rtcm"], enabled["rxm"]);
1258  if (enabled["rxm_rtcm"])
1259  gps.subscribe<ublox_msgs::RxmRTCM>(boost::bind(
1260  publish<ublox_msgs::RxmRTCM>, _1, "rxmrtcm"), kSubscribeRate);
1261 }
1262 
1263 //
1264 // Raw Data Products
1265 //
1267  // Defaults to true instead of to all
1268  nh->param("publish/rxm/all", enabled["rxm"], true);
1269 
1270  // Subscribe to RXM Raw
1271  nh->param("publish/rxm/raw", enabled["rxm_raw"], enabled["rxm"]);
1272  if (enabled["rxm_raw"])
1273  gps.subscribe<ublox_msgs::RxmRAW>(boost::bind(
1274  publish<ublox_msgs::RxmRAW>, _1, "rxmraw"), kSubscribeRate);
1275 
1276  // Subscribe to RXM SFRB
1277  nh->param("publish/rxm/sfrb", enabled["rxm_sfrb"], enabled["rxm"]);
1278  if (enabled["rxm_sfrb"])
1279  gps.subscribe<ublox_msgs::RxmSFRB>(boost::bind(
1280  publish<ublox_msgs::RxmSFRB>, _1, "rxmsfrb"), kSubscribeRate);
1281 
1282  // Subscribe to RXM EPH
1283  nh->param("publish/rxm/eph", enabled["rxm_eph"], enabled["rxm"]);
1284  if (enabled["rxm_eph"])
1285  gps.subscribe<ublox_msgs::RxmEPH>(boost::bind(
1286  publish<ublox_msgs::RxmEPH>, _1, "rxmeph"), kSubscribeRate);
1287 
1288  // Subscribe to RXM ALM
1289  nh->param("publish/rxm/almRaw", enabled["rxm_alm"], enabled["rxm"]);
1290  if (enabled["rxm_alm"])
1291  gps.subscribe<ublox_msgs::RxmALM>(boost::bind(
1292  publish<ublox_msgs::RxmALM>, _1, "rxmalm"), kSubscribeRate);
1293 }
1294 
1296  if (enabled["rxm_raw"])
1299  if (enabled["rxm_sfrb"])
1302  if (enabled["rxm_eph"])
1305  if (enabled["rxm_alm"])
1308 }
1309 
1310 AdrUdrProduct::AdrUdrProduct(float protocol_version)
1311  : protocol_version_(protocol_version)
1312 {}
1313 
1314 //
1315 // u-blox ADR devices, partially implemented
1316 //
1318  nh->param("use_adr", use_adr_, true);
1319  // Check the nav rate
1320  float nav_rate_hz = 1000 / (meas_rate * nav_rate);
1321  if(nav_rate_hz != 1)
1322  ROS_WARN("Nav Rate recommended to be 1 Hz");
1323 }
1324 
1327  throw std::runtime_error(std::string("Failed to ")
1328  + (use_adr_ ? "enable" : "disable") + "use_adr");
1329  return true;
1330 }
1331 
1333  nh->param("publish/esf/all", enabled["esf"], true);
1334 
1335  // Subscribe to NAV ATT messages
1336  nh->param("publish/nav/att", enabled["nav_att"], enabled["nav"]);
1337  if (enabled["nav_att"])
1338  gps.subscribe<ublox_msgs::NavATT>(boost::bind(
1339  publish<ublox_msgs::NavATT>, _1, "navatt"), kSubscribeRate);
1340 
1341  // Subscribe to ESF ALG messages
1342  nh->param("publish/esf/alg", enabled["esf_alg"], enabled["esf"]);
1343  if (enabled["esf_alg"])
1344  gps.subscribe<ublox_msgs::EsfALG>(boost::bind(
1345  publish<ublox_msgs::EsfALG>, _1, "esfalg"), kSubscribeRate);
1346 
1347  // Subscribe to ESF INS messages
1348  nh->param("publish/esf/ins", enabled["esf_ins"], enabled["esf"]);
1349  if (enabled["esf_ins"])
1350  gps.subscribe<ublox_msgs::EsfINS>(boost::bind(
1351  publish<ublox_msgs::EsfINS>, _1, "esfins"), kSubscribeRate);
1352 
1353  // Subscribe to ESF Meas messages
1354  nh->param("publish/esf/meas", enabled["esf_meas"], enabled["esf"]);
1355  if (enabled["esf_meas"])
1356  gps.subscribe<ublox_msgs::EsfMEAS>(boost::bind(
1357  publish<ublox_msgs::EsfMEAS>, _1, "esfmeas"), kSubscribeRate);
1358  // also publish sensor_msgs::Imu
1359  gps.subscribe<ublox_msgs::EsfMEAS>(boost::bind(
1361 
1362  // Subscribe to ESF Raw messages
1363  nh->param("publish/esf/raw", enabled["esf_raw"], enabled["esf"]);
1364  if (enabled["esf_raw"])
1365  gps.subscribe<ublox_msgs::EsfRAW>(boost::bind(
1366  publish<ublox_msgs::EsfRAW>, _1, "esfraw"), kSubscribeRate);
1367 
1368  // Subscribe to ESF Status messages
1369  nh->param("publish/esf/status", enabled["esf_status"], enabled["esf"]);
1370  if (enabled["esf_status"])
1371  gps.subscribe<ublox_msgs::EsfSTATUS>(boost::bind(
1372  publish<ublox_msgs::EsfSTATUS>, _1, "esfstatus"), kSubscribeRate);
1373 
1374  // Subscribe to HNR PVT messages
1375  nh->param("publish/hnr/pvt", enabled["hnr_pvt"], true);
1376  if (enabled["hnr_pvt"])
1377  gps.subscribe<ublox_msgs::HnrPVT>(boost::bind(
1378  publish<ublox_msgs::HnrPVT>, _1, "hnrpvt"), kSubscribeRate);
1379 }
1380 
1381 void AdrUdrProduct::callbackEsfMEAS(const ublox_msgs::EsfMEAS &m) {
1382  if (enabled["esf_meas"]) {
1383  static ros::Publisher imu_pub =
1384  nh->advertise<sensor_msgs::Imu>("imu_meas", kROSQueueSize);
1385  static ros::Publisher time_ref_pub =
1386  nh->advertise<sensor_msgs::TimeReference>("interrupt_time", kROSQueueSize);
1387 
1388  imu_.header.stamp = ros::Time::now();
1389  imu_.header.frame_id = frame_id;
1390 
1391  static const float rad_per_sec = pow(2, -12) * M_PI / 180.0F;
1392  static const float m_per_sec_sq = pow(2, -10);
1393  static const float deg_c = 1e-2;
1394 
1395  std::vector<uint32_t> imu_data = m.data;
1396  for (int i=0; i < imu_data.size(); i++){
1397  unsigned int data_type = imu_data[i] >> 24; //grab the last six bits of data
1398  int32_t data_value = static_cast<int32_t>(imu_data[i] << 8); //shift to extend sign from 24 to 32 bit integer
1399  data_value >>= 8;
1400 
1401  imu_.orientation_covariance[0] = -1;
1402  imu_.linear_acceleration_covariance[0] = -1;
1403  imu_.angular_velocity_covariance[0] = -1;
1404 
1405  if (data_type == 14) {
1406  imu_.angular_velocity.x = data_value * rad_per_sec;
1407  } else if (data_type == 16) {
1408  imu_.linear_acceleration.x = data_value * m_per_sec_sq;
1409  } else if (data_type == 13) {
1410  imu_.angular_velocity.y = data_value * rad_per_sec;
1411  } else if (data_type == 17) {
1412  imu_.linear_acceleration.y = data_value * m_per_sec_sq;
1413  } else if (data_type == 5) {
1414  imu_.angular_velocity.z = data_value * rad_per_sec;
1415  } else if (data_type == 18) {
1416  imu_.linear_acceleration.z = data_value * m_per_sec_sq;
1417  } else if (data_type == 12) {
1418  //ROS_INFO("Temperature in celsius: %f", data_value * deg_c);
1419  } else {
1420  // ROS_INFO("data_type: %u", data_type);
1421  // ROS_INFO("data_value: %u", data_value);
1422  }
1423 
1424  // create time ref message and put in the data
1425  //t_ref_.header.seq = m.risingEdgeCount;
1426  //t_ref_.header.stamp = ros::Time::now();
1427  //t_ref_.header.frame_id = frame_id;
1428 
1429  //t_ref_.time_ref = ros::Time((m.wnR * 604800 + m.towMsR / 1000), (m.towMsR % 1000) * 1000000 + m.towSubMsR);
1430 
1431  //std::ostringstream src;
1432  //src << "TIM" << int(m.ch);
1433  //t_ref_.source = src.str();
1434 
1435  t_ref_.header.stamp = ros::Time::now(); // create a new timestamp
1436  t_ref_.header.frame_id = frame_id;
1437 
1438  time_ref_pub.publish(t_ref_);
1439  imu_pub.publish(imu_);
1440  }
1441  }
1442 
1443  updater->force_update();
1444 }
1445 //
1446 // u-blox High Precision GNSS Reference Station
1447 //
1450  if(nav_rate * meas_rate != 1000)
1451  ROS_WARN("For HPG Ref devices, nav_rate should be exactly 1 Hz.");
1452 
1453  if(!getRosUint("tmode3", tmode3_))
1454  throw std::runtime_error("Invalid settings: TMODE3 must be set");
1455 
1456  if(tmode3_ == ublox_msgs::CfgTMODE3::FLAGS_MODE_FIXED) {
1457  if(!nh->getParam("arp/position", arp_position_))
1458  throw std::runtime_error(std::string("Invalid settings: arp/position ")
1459  + "must be set if TMODE3 is fixed");
1460  if(!getRosInt("arp/position_hp", arp_position_hp_))
1461  throw std::runtime_error(std::string("Invalid settings: arp/position_hp ")
1462  + "must be set if TMODE3 is fixed");
1463  if(!nh->getParam("arp/acc", fixed_pos_acc_))
1464  throw std::runtime_error(std::string("Invalid settings: arp/acc ")
1465  + "must be set if TMODE3 is fixed");
1466  if(!nh->getParam("arp/lla_flag", lla_flag_)) {
1467  ROS_WARN("arp/lla_flag param not set, assuming ARP coordinates are %s",
1468  "in ECEF");
1469  lla_flag_ = false;
1470  }
1471  } else if(tmode3_ == ublox_msgs::CfgTMODE3::FLAGS_MODE_SURVEY_IN) {
1472  nh->param("sv_in/reset", svin_reset_, true);
1473  if(!getRosUint("sv_in/min_dur", sv_in_min_dur_))
1474  throw std::runtime_error(std::string("Invalid settings: sv_in/min_dur ")
1475  + "must be set if TMODE3 is survey-in");
1476  if(!nh->getParam("sv_in/acc_lim", sv_in_acc_lim_))
1477  throw std::runtime_error(std::string("Invalid settings: sv_in/acc_lim ")
1478  + "must be set if TMODE3 is survey-in");
1479  } else if(tmode3_ != ublox_msgs::CfgTMODE3::FLAGS_MODE_DISABLED) {
1480  throw std::runtime_error(std::string("tmode3 param invalid. See CfgTMODE3")
1481  + " flag constants for possible values.");
1482  }
1483  }
1484 }
1485 
1487  // Configure TMODE3
1488  if(tmode3_ == ublox_msgs::CfgTMODE3::FLAGS_MODE_DISABLED) {
1489  if(!gps.disableTmode3())
1490  throw std::runtime_error("Failed to disable TMODE3.");
1491  mode_ = DISABLED;
1492  } else if(tmode3_ == ublox_msgs::CfgTMODE3::FLAGS_MODE_FIXED) {
1494  fixed_pos_acc_))
1495  throw std::runtime_error("Failed to set TMODE3 to fixed.");
1497  throw std::runtime_error("Failed to set RTCM rates");
1498  mode_ = FIXED;
1499  } else if(tmode3_ == ublox_msgs::CfgTMODE3::FLAGS_MODE_SURVEY_IN) {
1500  if(!svin_reset_) {
1501  ublox_msgs::NavSVIN nav_svin;
1502  if(!gps.poll(nav_svin))
1503  throw std::runtime_error(std::string("Failed to poll NavSVIN while") +
1504  " configuring survey-in");
1505  // Don't reset survey-in if it's already active
1506  if(nav_svin.active) {
1507  mode_ = SURVEY_IN;
1508  return true;
1509  }
1510  // Don't reset survey-in if it already has a valid value
1511  if(nav_svin.valid) {
1512  setTimeMode();
1513  return true;
1514  }
1515  ublox_msgs::NavPVT nav_pvt;
1516  if(!gps.poll(nav_pvt))
1517  throw std::runtime_error(std::string("Failed to poll NavPVT while") +
1518  " configuring survey-in");
1519  // Don't reset survey in if in time mode with a good fix
1520  if (nav_pvt.fixType == nav_pvt.FIX_TYPE_TIME_ONLY
1521  && nav_pvt.flags & nav_pvt.FLAGS_GNSS_FIX_OK) {
1522  setTimeMode();
1523  return true;
1524  }
1525  }
1526  // Reset the Survey In
1527  // For Survey in, meas rate must be at least 1 Hz
1528  uint16_t meas_rate_temp = meas_rate < 1000 ? meas_rate : 1000; // [ms]
1529  // If measurement period isn't a factor of 1000, set to default
1530  if(1000 % meas_rate_temp != 0)
1531  meas_rate_temp = kDefaultMeasPeriod;
1532  // Set nav rate to 1 Hz during survey in
1533  if(!gps.configRate(meas_rate_temp, (int) 1000 / meas_rate_temp))
1534  throw std::runtime_error(std::string("Failed to set nav rate to 1 Hz") +
1535  "before setting TMODE3 to survey-in.");
1536  // As recommended in the documentation, first disable, then set to survey in
1537  if(!gps.disableTmode3())
1538  ROS_ERROR("Failed to disable TMODE3 before setting to survey-in.");
1539  else
1540  mode_ = DISABLED;
1541  // Set to Survey in mode
1543  throw std::runtime_error("Failed to set TMODE3 to survey-in.");
1544  mode_ = SURVEY_IN;
1545  }
1546  return true;
1547 }
1548 
1550  // Whether to publish Nav Survey-In messages
1551  nh->param("publish/nav/svin", enabled["nav_svin"], enabled["nav"]);
1552  // Subscribe to Nav Survey-In
1553  gps.subscribe<ublox_msgs::NavSVIN>(boost::bind(
1555 }
1556 
1557 void HpgRefProduct::callbackNavSvIn(ublox_msgs::NavSVIN m) {
1558  if(enabled["nav_svin"]) {
1559  static ros::Publisher publisher =
1560  nh->advertise<ublox_msgs::NavSVIN>("navsvin", kROSQueueSize);
1561  publisher.publish(m);
1562  }
1563 
1564  last_nav_svin_ = m;
1565 
1566  if(!m.active && m.valid && mode_ == SURVEY_IN) {
1567  setTimeMode();
1568  }
1569 
1570  updater->update();
1571 }
1572 
1574  ROS_INFO("Setting mode (internal state) to Time Mode");
1575  mode_ = TIME;
1576 
1577  // Set the Measurement & nav rate to user config
1578  // (survey-in sets nav_rate to 1 Hz regardless of user setting)
1580  ROS_ERROR("Failed to set measurement rate to %d ms %s %d", meas_rate,
1581  "navigation rate to ", nav_rate);
1582  // Enable the RTCM out messages
1584  ROS_ERROR("Failed to configure RTCM IDs");
1585  return false;
1586  }
1587  return true;
1588 }
1589 
1591  updater->add("TMODE3", this, &HpgRefProduct::tmode3Diagnostics);
1592  updater->force_update();
1593 }
1594 
1597  if (mode_ == INIT) {
1598  stat.level = diagnostic_msgs::DiagnosticStatus::WARN;
1599  stat.message = "Not configured";
1600  } else if (mode_ == DISABLED){
1601  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1602  stat.message = "Disabled";
1603  } else if (mode_ == SURVEY_IN) {
1604  if (!last_nav_svin_.active && !last_nav_svin_.valid) {
1605  stat.level = diagnostic_msgs::DiagnosticStatus::ERROR;
1606  stat.message = "Survey-In inactive and invalid";
1607  } else if (last_nav_svin_.active && !last_nav_svin_.valid) {
1608  stat.level = diagnostic_msgs::DiagnosticStatus::WARN;
1609  stat.message = "Survey-In active but invalid";
1610  } else if (!last_nav_svin_.active && last_nav_svin_.valid) {
1611  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1612  stat.message = "Survey-In complete";
1613  } else if (last_nav_svin_.active && last_nav_svin_.valid) {
1614  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1615  stat.message = "Survey-In active and valid";
1616  }
1617 
1618  stat.add("iTOW [ms]", last_nav_svin_.iTOW);
1619  stat.add("Duration [s]", last_nav_svin_.dur);
1620  stat.add("# observations", last_nav_svin_.obs);
1621  stat.add("Mean X [m]", last_nav_svin_.meanX * 1e-2);
1622  stat.add("Mean Y [m]", last_nav_svin_.meanY * 1e-2);
1623  stat.add("Mean Z [m]", last_nav_svin_.meanZ * 1e-2);
1624  stat.add("Mean X HP [m]", last_nav_svin_.meanXHP * 1e-4);
1625  stat.add("Mean Y HP [m]", last_nav_svin_.meanYHP * 1e-4);
1626  stat.add("Mean Z HP [m]", last_nav_svin_.meanZHP * 1e-4);
1627  stat.add("Mean Accuracy [m]", last_nav_svin_.meanAcc * 1e-4);
1628  } else if(mode_ == FIXED) {
1629  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1630  stat.message = "Fixed Position";
1631  } else if(mode_ == TIME) {
1632  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1633  stat.message = "Time";
1634  }
1635 }
1636 
1637 //
1638 // U-Blox High Precision GNSS Rover
1639 //
1641  // default to float, see CfgDGNSS message for details
1642  getRosUint("dgnss_mode", dgnss_mode_,
1643  ublox_msgs::CfgDGNSS::DGNSS_MODE_RTK_FIXED);
1644 }
1645 
1647  // Configure the DGNSS
1648  if(!gps.setDgnss(dgnss_mode_))
1649  throw std::runtime_error(std::string("Failed to Configure DGNSS"));
1650  return true;
1651 }
1652 
1654  // Whether to publish Nav Relative Position NED
1655  nh->param("publish/nav/relposned", enabled["nav_relposned"], enabled["nav"]);
1656  // Subscribe to Nav Relative Position NED messages (also updates diagnostics)
1657  gps.subscribe<ublox_msgs::NavRELPOSNED>(boost::bind(
1659 }
1660 
1662  freq_rtcm_ = UbloxTopicDiagnostic(std::string("rxmrtcm"),
1665  updater->add("Carrier Phase Solution", this,
1667  updater->force_update();
1668 }
1669 
1672  uint32_t carr_soln = last_rel_pos_.flags & last_rel_pos_.FLAGS_CARR_SOLN_MASK;
1673  stat.add("iTOW", last_rel_pos_.iTOW);
1674  if (carr_soln & last_rel_pos_.FLAGS_CARR_SOLN_NONE ||
1675  !(last_rel_pos_.flags & last_rel_pos_.FLAGS_DIFF_SOLN &&
1676  last_rel_pos_.flags & last_rel_pos_.FLAGS_REL_POS_VALID)) {
1677  stat.level = diagnostic_msgs::DiagnosticStatus::ERROR;
1678  stat.message = "None";
1679  } else {
1680  if (carr_soln & last_rel_pos_.FLAGS_CARR_SOLN_FLOAT) {
1681  stat.level = diagnostic_msgs::DiagnosticStatus::WARN;
1682  stat.message = "Float";
1683  } else if (carr_soln & last_rel_pos_.FLAGS_CARR_SOLN_FIXED) {
1684  stat.level = diagnostic_msgs::DiagnosticStatus::OK;
1685  stat.message = "Fixed";
1686  }
1687  stat.add("Ref Station ID", last_rel_pos_.refStationId);
1688 
1689  double rel_pos_n = (last_rel_pos_.relPosN
1690  + (last_rel_pos_.relPosHPN * 1e-2)) * 1e-2;
1691  double rel_pos_e = (last_rel_pos_.relPosE
1692  + (last_rel_pos_.relPosHPE * 1e-2)) * 1e-2;
1693  double rel_pos_d = (last_rel_pos_.relPosD
1694  + (last_rel_pos_.relPosHPD * 1e-2)) * 1e-2;
1695  stat.add("Relative Position N [m]", rel_pos_n);
1696  stat.add("Relative Accuracy N [m]", last_rel_pos_.accN * 1e-4);
1697  stat.add("Relative Position E [m]", rel_pos_e);
1698  stat.add("Relative Accuracy E [m]", last_rel_pos_.accE * 1e-4);
1699  stat.add("Relative Position D [m]", rel_pos_d);
1700  stat.add("Relative Accuracy D [m]", last_rel_pos_.accD * 1e-4);
1701  }
1702 }
1703 
1704 void HpgRovProduct::callbackNavRelPosNed(const ublox_msgs::NavRELPOSNED &m) {
1705  if (enabled["nav_relposned"]) {
1706  static ros::Publisher publisher =
1707  nh->advertise<ublox_msgs::NavRELPOSNED>("navrelposned", kROSQueueSize);
1708  publisher.publish(m);
1709  }
1710 
1711  last_rel_pos_ = m;
1712  updater->update();
1713 }
1714 
1715 //
1716 // U-Blox High Precision Positioning Receiver
1717 //
1719  // Subscribe to Nav High Precision Position ECEF
1720  nh->param("publish/nav/hpposecef", enabled["nav_hpposecef"], enabled["nav"]);
1721  if (enabled["nav_hpposecef"])
1722  gps.subscribe<ublox_msgs::NavHPPOSECEF>(boost::bind(
1723  publish<ublox_msgs::NavHPPOSECEF>, _1, "navhpposecef"), kSubscribeRate);
1724 
1725  // Whether to publish the NavSatFix info from Nav High Precision Position LLH
1726  nh->param("publish/nav/hp_fix", enabled["nav_hpfix"], enabled["nav"]);
1727 
1728  // Whether to publish the NavSatFix info from Nav High Precision Position LLH
1729  nh->param("publish/nav/hpposllh", enabled["nav_hpposllh"], enabled["nav"]);
1730 
1731  // Subscribe to Nav High Precision Position LLH
1732  if (enabled["nav_hpposllh"] || enabled["nav_hpfix"])
1733  gps.subscribe<ublox_msgs::NavHPPOSLLH>(boost::bind(
1735 
1736  // Whether to publish Nav Relative Position NED
1737  nh->param("publish/nav/relposned", enabled["nav_relposned"], enabled["nav"]);
1738  // Subscribe to Nav Relative Position NED messages (also updates diagnostics)
1739  gps.subscribe<ublox_msgs::NavRELPOSNED9>(boost::bind(
1741 
1742  // Whether to publish the Heading info from Nav Relative Position NED
1743  nh->param("publish/nav/heading", enabled["nav_heading"], enabled["nav"]);
1744 }
1745 
1746 void HpPosRecProduct::callbackNavHpPosLlh(const ublox_msgs::NavHPPOSLLH& m) {
1747  if (enabled["nav_hpposllh"]) {
1748  static ros::Publisher publisher =
1749  nh->advertise<ublox_msgs::NavHPPOSLLH>("navhpposllh", kROSQueueSize);
1750  publisher.publish(m);
1751  }
1752 
1753  if (enabled["nav_hpfix"]) {
1754  sensor_msgs::NavSatFix fix_msg;
1755  static ros::Publisher fixPublisher =
1756  nh->advertise<sensor_msgs::NavSatFix>("hp_fix", kROSQueueSize);
1757 
1758  fix_msg.header.stamp = ros::Time::now();
1759  fix_msg.header.frame_id = frame_id;
1760  fix_msg.latitude = m.lat * 1e-7 + m.latHp * 1e-9;
1761  fix_msg.longitude = m.lon * 1e-7 + m.lonHp * 1e-9;
1762  fix_msg.altitude = m.height * 1e-3 + m.heightHp * 1e-4;
1763 
1764  if (m.invalid_llh) {
1765  fix_msg.status.status = fix_msg.status.STATUS_NO_FIX;
1766  } else {
1767  fix_msg.status.status = fix_msg.status.STATUS_FIX;
1768  }
1769 
1770  // Convert from mm to m
1771  const double varH = pow(m.hAcc / 10000.0, 2);
1772  const double varV = pow(m.vAcc / 10000.0, 2);
1773 
1774  fix_msg.position_covariance[0] = varH;
1775  fix_msg.position_covariance[4] = varH;
1776  fix_msg.position_covariance[8] = varV;
1777  fix_msg.position_covariance_type =
1778  sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
1779 
1780  fix_msg.status.service = fix_msg.status.SERVICE_GPS;
1781  fixPublisher.publish(fix_msg);
1782  }
1783 }
1784 
1785 void HpPosRecProduct::callbackNavRelPosNed(const ublox_msgs::NavRELPOSNED9 &m) {
1786  if (enabled["nav_relposned"]) {
1787  static ros::Publisher publisher =
1788  nh->advertise<ublox_msgs::NavRELPOSNED9>("navrelposned", kROSQueueSize);
1789  publisher.publish(m);
1790  }
1791 
1792  if (enabled["nav_heading"]) {
1793  static ros::Publisher imu_pub =
1794  nh->advertise<sensor_msgs::Imu>("navheading", kROSQueueSize);
1795 
1796  imu_.header.stamp = ros::Time::now();
1797  imu_.header.frame_id = frame_id;
1798 
1799  imu_.linear_acceleration_covariance[0] = -1;
1800  imu_.angular_velocity_covariance[0] = -1;
1801 
1802  // Transform angle since ublox is representing heading as NED but ROS uses ENU as convention (REP-103).
1803  double heading = M_PI_2 - (static_cast<double>(m.relPosHeading) * 1e-5 / 180.0 * M_PI);
1804  tf::Quaternion orientation;
1805  orientation.setRPY(0, 0, heading);
1806  imu_.orientation.x = orientation[0];
1807  imu_.orientation.y = orientation[1];
1808  imu_.orientation.z = orientation[2];
1809  imu_.orientation.w = orientation[3];
1810  imu_.orientation_covariance[0] = 1000.0;
1811  imu_.orientation_covariance[4] = 1000.0;
1812  imu_.orientation_covariance[8] = 1000.0;
1813  // When heading is reported to be valid, use accuracy reported in 1e-5 deg units
1814  if (m.flags & ublox_msgs::NavRELPOSNED9::FLAGS_REL_POS_HEAD_VALID)
1815  {
1816  imu_.orientation_covariance[8] = pow(m.accHeading * 1e-5 / 180.0 * M_PI, 2);
1817  }
1818 
1819  imu_pub.publish(imu_);
1820  }
1821 
1822  last_rel_pos_ = m;
1823  updater->update();
1824 }
1825 
1826 //
1827 // U-Blox Time Sync Products, partially implemented.
1828 //
1830 }
1831 
1833  uint8_t r = 1;
1834  // Configure the reciever
1835  if(!gps.setUTCtime())
1836  throw std::runtime_error(std::string("Failed to Configure TIM Product to UTC Time"));
1837 
1838  if(!gps.setTimtm2(r))
1839  throw std::runtime_error(std::string("Failed to Configure TIM Product"));
1840 
1841  return true;
1842 }
1843 
1845  ROS_INFO("TIM is Enabled: %u", enabled["tim"]);
1846  ROS_INFO("TIM-TM2 is Enabled: %u", enabled["tim_tm2"]);
1847  // Subscribe to TIM-TM2 messages (Time mark messages)
1848  nh->param("publish/tim/tm2", enabled["tim_tm2"], enabled["tim"]);
1849 
1850  gps.subscribe<ublox_msgs::TimTM2>(boost::bind(
1852 
1853  ROS_INFO("Subscribed to TIM-TM2 messages on topic tim/tm2");
1854 
1855  // Subscribe to SFRBX messages
1856  nh->param("publish/rxm/sfrb", enabled["rxm_sfrb"], enabled["rxm"]);
1857  if (enabled["rxm_sfrb"])
1858  gps.subscribe<ublox_msgs::RxmSFRBX>(boost::bind(
1859  publish<ublox_msgs::RxmSFRBX>, _1, "rxmsfrb"), kSubscribeRate);
1860 
1861  // Subscribe to RawX messages
1862  nh->param("publish/rxm/raw", enabled["rxm_raw"], enabled["rxm"]);
1863  if (enabled["rxm_raw"])
1864  gps.subscribe<ublox_msgs::RxmRAWX>(boost::bind(
1865  publish<ublox_msgs::RxmRAWX>, _1, "rxmraw"), kSubscribeRate);
1866 }
1867 
1868 void TimProduct::callbackTimTM2(const ublox_msgs::TimTM2 &m) {
1869 
1870  if (enabled["tim_tm2"]) {
1871  static ros::Publisher publisher =
1872  nh->advertise<ublox_msgs::TimTM2>("timtm2", kROSQueueSize);
1873  static ros::Publisher time_ref_pub =
1874  nh->advertise<sensor_msgs::TimeReference>("interrupt_time", kROSQueueSize);
1875 
1876  // create time ref message and put in the data
1877  t_ref_.header.seq = m.risingEdgeCount;
1878  t_ref_.header.stamp = ros::Time::now();
1879  t_ref_.header.frame_id = frame_id;
1880 
1881  t_ref_.time_ref = ros::Time((m.wnR * 604800 + m.towMsR / 1000), (m.towMsR % 1000) * 1000000 + m.towSubMsR);
1882 
1883  std::ostringstream src;
1884  src << "TIM" << int(m.ch);
1885  t_ref_.source = src.str();
1886 
1887  t_ref_.header.stamp = ros::Time::now(); // create a new timestamp
1888  t_ref_.header.frame_id = frame_id;
1889 
1890  publisher.publish(m);
1891  time_ref_pub.publish(t_ref_);
1892  }
1893 
1894  updater->force_update();
1895 }
1896 
1898  updater->force_update();
1899 }
1900 
1901 void rtcmCallback(const rtcm_msgs::Message::ConstPtr &msg) {
1902  gps.sendRtcm(msg->message);
1903 }
1904 
1905 int main(int argc, char** argv) {
1906  ros::init(argc, argv, "ublox_gps");
1907  nh.reset(new ros::NodeHandle("~"));
1908  ros::Subscriber subRtcm = nh->subscribe("/rtcm", 10, rtcmCallback);
1909  nh->param("debug", ublox_gps::debug, 1);
1910  if(ublox_gps::debug) {
1914 
1915  }
1916  UbloxNode node;
1917  return 0;
1918 }
ublox_node::HpgRovProduct::kRtcmFreqMin
constexpr static double kRtcmFreqMin
Diagnostic updater: RTCM topic frequency min [Hz].
Definition: node.h:1294
ublox_node::HpgRovProduct::kRtcmFreqTol
constexpr static double kRtcmFreqTol
Diagnostic updater: RTCM topic frequency tolerance [%].
Definition: node.h:1298
ublox_node::HpgRefProduct::SURVEY_IN
@ SURVEY_IN
Survey-In mode.
Definition: node.h:1282
ublox_node::kDefaultMeasPeriod
constexpr static uint16_t kDefaultMeasPeriod
Default measurement period for HPG devices.
Definition: node.h:93
ublox_node::HpgRefProduct::sv_in_acc_lim_
float sv_in_acc_lim_
Survey in accuracy limit [m].
Definition: node.h:1275
ublox_node::HpPosRecProduct
Definition: node.h:1354
ublox_gps::Gps::isInitialized
bool isInitialized() const
Definition: gps.h:373
ublox_node::ComponentPtr
boost::shared_ptr< ComponentInterface > ComponentPtr
Definition: node.h:484
ublox_node::AdrUdrProduct::AdrUdrProduct
AdrUdrProduct(float protocol_version)
Definition: node.cpp:1310
ublox_gps::Gps::reset
void reset(const boost::posix_time::time_duration &wait)
Reset I/O communications.
Definition: gps.cpp:296
ublox_node::HpgRovProduct::dgnss_mode_
uint8_t dgnss_mode_
The DGNSS mode.
Definition: node.h:1348
ublox_node::UbloxFirmware6::fixDiagnostic
void fixDiagnostic(diagnostic_updater::DiagnosticStatusWrapper &stat)
Updates fix diagnostic from NavPOSLLH, NavVELNED, and NavSOL messages.
Definition: node.cpp:712
ublox_node::UbloxNode::kFixFreqWindow
constexpr static double kFixFreqWindow
Window [num messages] for Fix Frequency Diagnostic.
Definition: node.h:513
msg
msg
ros::Publisher
ublox_node::UbloxNode::fmode_
uint8_t fmode_
Set from fix mode string.
Definition: node.h:631
ublox_msgs::Message::INF::DEBUG
static const uint8_t DEBUG
ublox_node::UbloxNode::load_
ublox_msgs::CfgCFG load_
Parameters to load from non-volatile memory during configuration.
Definition: node.h:664
ublox_node::supportsGnss
bool supportsGnss(std::string gnss)
Definition: node.h:446
ublox_gps::Gps::configRtcm
bool configRtcm(std::vector< uint8_t > ids, std::vector< uint8_t > rates)
Configure the RTCM messages with the given IDs to the set rate.
Definition: gps.cpp:428
ublox_node::RawDataProduct::kRtcmFreqTol
static constexpr double kRtcmFreqTol
Definition: node.h:1061
ublox_node::FtsProduct
Implements functions for FTS products. Currently unimplemented.
Definition: node.h:1148
ublox_node::HpgRefProduct::svin_reset_
bool svin_reset_
Whether to always reset the survey-in during configuration.
Definition: node.h:1269
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
ublox_node::UbloxNode::usb_out_
uint16_t usb_out_
USB out protocol (see CfgPRT message for constants)
Definition: node.h:646
ublox_node::RawDataProduct::subscribe
void subscribe()
Subscribe to Raw Data Product messages and set up ROS publishers.
Definition: node.cpp:1266
boost::shared_ptr
ublox_node::UbloxFirmware9
Implements functions for firmware version 9. For now it simply re-uses the firmware version 8 class b...
Definition: node.h:1053
ublox_node::UbloxNode::set_dat_
bool set_dat_
If true, set configure the User-Defined Datum.
Definition: node.h:650
ublox_node::TimProduct::getRosParams
void getRosParams()
Get the Time Sync parameters.
Definition: node.cpp:1829
ublox_node::UbloxFirmware7::configureUblox
bool configureUblox()
Configure GNSS individually. Only configures GLONASS.
Definition: node.cpp:933
diagnostic_updater::DiagnosticStatusWrapper::add
void add(const std::string &key, const bool &b)
ublox_node::HpgRefProduct::FIXED
@ FIXED
Fixed mode (should switch to time mode almost immediately)
Definition: node.h:1280
ublox_node::HpgRefProduct::lla_flag_
bool lla_flag_
True if coordinates are in LLA, false if ECEF.
Definition: node.h:1251
ublox_node::UbloxFirmware7::subscribe
void subscribe()
Subscribe to messages which are not generic to all firmware.
Definition: node.cpp:1001
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
ublox_node::UbloxFirmware6::UbloxFirmware6
UbloxFirmware6()
Definition: node.cpp:628
ublox_node::UbloxFirmware8::UbloxFirmware8
UbloxFirmware8()
Definition: node.cpp:1027
ublox_node::HpgRefProduct::getRosParams
void getRosParams()
Get the ROS parameters specific to the Reference Station configuration.
Definition: node.cpp:1448
ublox_node::modelFromString
uint8_t modelFromString(const std::string &model)
Determine dynamic model from human-readable string.
Definition: node.cpp:43
ublox_node::UbloxNode::pollMessages
void pollMessages(const ros::TimerEvent &event)
Poll messages from the U-Blox device.
Definition: node.cpp:240
ublox_gps::Gps::setTimtm2
bool setTimtm2(uint8_t rate)
Enable or disable TIM-TM2 (time mark message).
Definition: gps.cpp:623
tf::Quaternion::setRPY
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
ublox_gps::Gps::setSaveOnShutdown
void setSaveOnShutdown(bool save_on_shutdown)
If called, when the node shuts down, it will send a command to save the flash memory.
Definition: gps.h:83
ublox_gps::Gps::configGnss
bool configGnss(ublox_msgs::CfgGNSS gnss, const boost::posix_time::time_duration &wait)
Configure the GNSS, cold reset the device, and reset the I/O.
Definition: gps.cpp:321
ublox_node::UbloxNode::cfg_dat_
ublox_msgs::CfgDAT cfg_dat_
User-defined Datum.
Definition: node.h:652
ublox_msgs::Message::AID::EPH
static const uint8_t EPH
ublox_node::UbloxNode::kKeepAlivePeriod
constexpr static double kKeepAlivePeriod
How often (in seconds) to send keep-alive message.
Definition: node.h:504
ublox_gps::Gps::clearBbr
bool clearBbr()
Send a message to the receiver to delete the BBR data stored in flash.
Definition: gps.cpp:350
ublox_node::UbloxNode::dmodel_
uint8_t dmodel_
Set from dynamic model string.
Definition: node.h:629
ublox_node::config_on_startup_flag_
bool config_on_startup_flag_
Flag for enabling configuration on startup.
Definition: node.h:129
ublox_node::UbloxNode::addFirmwareInterface
void addFirmwareInterface()
Add the interface for firmware specific configuration, subscribers, & diagnostics....
Definition: node.cpp:94
ublox_node::UbloxNode::enable_ppp_
bool enable_ppp_
Whether or not to enable PPP (advanced setting)
Definition: node.h:656
ublox_node::UbloxNode::configureInf
void configureInf()
Configure INF messages, call after subscribe.
Definition: node.cpp:504
ublox_node::HpPosRecProduct::imu_
sensor_msgs::Imu imu_
Definition: node.h:1375
ublox_node::HpgRefProduct
Implements functions for High Precision GNSS Reference station devices.
Definition: node.h:1181
ublox_msgs::Class::AID
static const uint8_t AID
diagnostic_updater::Updater
ublox_node::getRosInt
bool getRosInt(const std::string &key, I &u)
Get a integer (size 8 or 16) value from the parameter server.
Definition: node.h:370
ublox_node::fix_status_service
int fix_status_service
Definition: node.h:119
ublox_node::UbloxFirmware7::cfg_nmea_
ublox_msgs::CfgNMEA7 cfg_nmea_
Used to configure NMEA (if set_nmea_)
Definition: node.h:995
ublox_node::HpgRefProduct::TIME
@ TIME
Time mode, after survey-in or after configuring fixed mode.
Definition: node.h:1283
ublox_gps::Gps::configUsb
bool configUsb(uint16_t tx_ready, uint16_t in_proto_mask, uint16_t out_proto_mask)
Configure the USB Port.
Definition: gps.cpp:401
ublox_node::RawDataStreamPa::ubloxCallback
void ubloxCallback(const unsigned char *data, const std::size_t size)
Callback function which handles raw data.
Definition: raw_data_pa.cpp:136
ublox_node::UbloxFirmware8::clear_bbr_
bool clear_bbr_
Whether to clear the flash memory during configuration.
Definition: node.h:1045
ublox_gps::Gps::setDynamicModel
bool setDynamicModel(uint8_t model)
Set the device dynamic model.
Definition: gps.cpp:514
ublox_node::UbloxFirmware6::fix_
sensor_msgs::NavSatFix fix_
The last NavSatFix based on last_nav_pos_.
Definition: node.h:757
ublox_node::HpgRovProduct
Implements functions for High Precision GNSS Rover devices.
Definition: node.h:1290
wait
void wait(int seconds)
ublox_node::HpgRefProduct::setTimeMode
bool setTimeMode()
Set the device mode to time mode (internal state variable).
Definition: node.cpp:1573
ublox_node::UbloxNode::enable_sbas_
bool enable_sbas_
Whether or not to enable SBAS.
Definition: node.h:654
ublox_node::HpPosRecProduct::last_rel_pos_
ublox_msgs::NavRELPOSNED9 last_rel_pos_
Last relative position (used for diagnostic updater)
Definition: node.h:1378
ublox_gps::Gps::setFixMode
bool setFixMode(uint8_t mode)
Set the device fix mode.
Definition: gps.cpp:523
ublox_node::HpgRefProduct::mode_
enum ublox_node::HpgRefProduct::@0 mode_
Status of device time mode.
ros::console::set_logger_level
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
ublox_node::HpgRefProduct::tmode3Diagnostics
void tmode3Diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Update the TMODE3 diagnostics.
Definition: node.cpp:1595
ublox_node::AdrUdrProduct::configureUblox
bool configureUblox()
Configure ADR/UDR settings.
Definition: node.cpp:1325
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
ublox_node::UbloxFirmware6::last_nav_pos_
ublox_msgs::NavPOSLLH last_nav_pos_
The last received navigation position.
Definition: node.h:751
ublox_msgs::Message::AID::HUI
static const uint8_t HUI
ublox_gps::Gps::setUseAdr
bool setUseAdr(bool enable, float protocol_version)
Enable or disable ADR (automotive dead reckoning).
Definition: gps.cpp:559
ublox_gps::Gps::configTmode3Fixed
bool configTmode3Fixed(bool lla_flag, std::vector< float > arp_position, std::vector< int8_t > arp_position_hp, float fixed_pos_acc)
Set the TMODE3 settings to fixed.
Definition: gps.cpp:449
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ublox_node::HpgRovProduct::initializeRosDiagnostics
void initializeRosDiagnostics()
Add diagnostic updaters for rover GNSS status, including status of RTCM messages.
Definition: node.cpp:1661
ublox_node::getRosUint
bool getRosUint(const std::string &key, U &u)
Get a unsigned integer value from the parameter server.
Definition: node.h:316
ublox_node::RawDataStreamPa::initialize
void initialize(void)
Initializes raw data streams If storing to file is enabled, the filename is created and the correspon...
Definition: raw_data_pa.cpp:77
ublox_node::UbloxNode::dr_limit_
uint8_t dr_limit_
Dead reckoning limit parameter.
Definition: node.h:662
ublox_node::UbloxNode::initialize
void initialize()
Initialize the U-Blox node. Configure the U-Blox and subscribe to messages.
Definition: node.cpp:569
ublox_node::UbloxFirmware7Plus< ublox_msgs::NavPVT7 >::enable_glonass_
bool enable_glonass_
Whether or not to enable GLONASS.
Definition: node.h:955
ublox_node::UbloxFirmware8::enable_beidou_
bool enable_beidou_
Whether or not to enable the BeiDuo GNSS.
Definition: node.h:1037
ublox_node::RawDataStreamPa::getRosParams
void getRosParams(void)
Get the raw data stream parameters.
Definition: raw_data_pa.cpp:57
ublox_node::UbloxFirmware6::set_nmea_
bool set_nmea_
Whether or not to configure the NMEA settings.
Definition: node.h:764
ublox_node::UbloxFirmware8::enable_galileo_
bool enable_galileo_
Whether or not to enable the Galileo GNSS.
Definition: node.h:1035
ublox_node::UbloxNode::keepAlive
void keepAlive(const ros::TimerEvent &event)
Poll version message from the U-Blox device to keep socket active.
Definition: node.cpp:235
ublox_node::UbloxFirmware7Plus< ublox_msgs::NavPVT7 >::enable_sbas_
bool enable_sbas_
Whether or not to enable SBAS.
Definition: node.h:959
ublox_node::UbloxNode::kFixFreqTol
constexpr static double kFixFreqTol
Tolerance for Fix topic frequency as percentage of target frequency.
Definition: node.h:511
ublox_node::UbloxNode::usb_in_
uint16_t usb_in_
USB in protocol (see CfgPRT message for constants)
Definition: node.h:644
ublox_node::HpgRefProduct::arp_position_
std::vector< float > arp_position_
Antenna Reference Point Position [m] or [deg].
Definition: node.h:1254
ublox_node::AdrUdrProduct::getRosParams
void getRosParams()
Get the ADR/UDR parameters.
Definition: node.cpp:1317
ublox_node::FixDiagnostic
Topic diagnostics for fix / fix_velocity messages.
Definition: node.h:188
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
ublox_node::UbloxNode
This class represents u-blox ROS node for all firmware and product versions.
Definition: node.h:501
ublox_node::AdrUdrProduct::t_ref_
sensor_msgs::TimeReference t_ref_
Definition: node.h:1138
ublox_node::TimProduct::initializeRosDiagnostics
void initializeRosDiagnostics()
Adds diagnostic updaters for Time Sync status.
Definition: node.cpp:1897
ublox_node::UbloxFirmware6::configureUblox
bool configureUblox()
Prints a warning, GNSS configuration not available in this version.
Definition: node.cpp:672
ublox_node::UbloxFirmware::fixDiagnostic
virtual void fixDiagnostic(diagnostic_updater::DiagnosticStatusWrapper &stat)=0
Handle to send fix status to ROS diagnostics.
ros::console::levels::Debug
Debug
ublox_node::UbloxNode::getRosParams
void getRosParams()
Get the node parameters from the ROS Parameter Server.
Definition: node.cpp:138
ublox_node::HpgRovProduct::carrierPhaseDiagnostics
void carrierPhaseDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Update the rover diagnostics, including the carrier phase solution status (float or fixed).
Definition: node.cpp:1670
ublox_node::UbloxNode::processMonVer
void processMonVer()
Process the MonVer message and add firmware and product components.
Definition: node.cpp:367
ublox_node::UbloxNode::configureUblox
bool configureUblox()
Configure the device based on ROS parameters.
Definition: node.cpp:432
ublox_node::AdrUdrProduct
Implements functions for Automotive Dead Reckoning (ADR) and Untethered Dead Reckoning (UDR) Devices.
Definition: node.h:1096
ublox_node::AdrUdrProduct::protocol_version_
float protocol_version_
Definition: node.h:1134
ublox_node::HpgRefProduct::sv_in_min_dur_
uint32_t sv_in_min_dur_
Measurement period used during Survey-In [s].
Definition: node.h:1272
ublox_node::UbloxFirmware7Plus< ublox_msgs::NavPVT7 >::qzss_sig_cfg_
uint32_t qzss_sig_cfg_
The QZSS Signal configuration, see CfgGNSS message.
Definition: node.h:961
ublox_node::UbloxFirmware6::last_nav_vel_
ublox_msgs::NavVELNED last_nav_vel_
The last received navigation velocity.
Definition: node.h:753
ublox_msgs::Message::INF::NOTICE
static const uint8_t NOTICE
ublox_node::UbloxFirmware6::last_nav_sol_
ublox_msgs::NavSOL last_nav_sol_
The last received num SVs used.
Definition: node.h:755
ublox_node::UbloxFirmware6::velocity_
geometry_msgs::TwistWithCovarianceStamped velocity_
The last Twist based on last_nav_vel_.
Definition: node.h:759
node.h
ublox_node::UbloxFirmware6
Implements functions for firmware version 6.
Definition: node.h:697
ublox_gps::Gps::initializeUdp
void initializeUdp(std::string host, std::string port)
Initialize UDP I/O.
Definition: gps.cpp:249
ublox_node::UbloxFirmware8::set_nmea_
bool set_nmea_
Whether or not to configure the NMEA settings.
Definition: node.h:1041
ROS_DEBUG
#define ROS_DEBUG(...)
ublox_node::HpgRefProduct::configureUblox
bool configureUblox()
Configure the u-blox Reference Station settings.
Definition: node.cpp:1486
ublox_node::UbloxFirmware6::callbackNavVelNed
void callbackNavVelNed(const ublox_msgs::NavVELNED &m)
Update the last known velocity.
Definition: node.cpp:797
ublox_node::HpgRovProduct::kRtcmFreqWindow
constexpr static int kRtcmFreqWindow
Diagnostic updater: RTCM topic frequency window [num messages].
Definition: node.h:1300
ublox_node::UbloxFirmware7::UbloxFirmware7
UbloxFirmware7()
Definition: node.cpp:843
ublox_node::UbloxNode::subscribe
void subscribe()
Subscribe to all requested u-blox messages.
Definition: node.cpp:266
ublox_node::HpgRovProduct::configureUblox
bool configureUblox()
Configure rover settings.
Definition: node.cpp:1646
ublox_gps::Gps::initializeTcp
void initializeTcp(std::string host, std::string port)
Initialize TCP I/O.
Definition: gps.cpp:213
ublox_gps::Gps::setDeadReckonLimit
bool setDeadReckonLimit(uint8_t limit)
Set the dead reckoning time limit.
Definition: gps.cpp:532
ublox_node::UbloxFirmware6::getRosParams
void getRosParams()
Sets the fix status service type to GPS.
Definition: node.cpp:630
ublox_node::UbloxNode::components_
std::vector< boost::shared_ptr< ComponentInterface > > components_
The u-blox node components.
Definition: node.h:617
ublox_node::rtcm_ids
std::vector< uint8_t > rtcm_ids
IDs of RTCM out messages to configure.
Definition: node.h:125
ublox_node::UbloxFirmware6::callbackNavSol
void callbackNavSol(const ublox_msgs::NavSOL &m)
Update the number of SVs used for the fix.
Definition: node.cpp:831
ublox_node::UbloxFirmware8::subscribe
void subscribe()
Subscribe to u-blox messages which are not generic to all firmware versions.
Definition: node.cpp:1237
ublox_node::UbloxFirmware8::enable_imes_
bool enable_imes_
Whether or not to enable the IMES GNSS.
Definition: node.h:1039
ublox_node::kNavSvInfoSubscribeRate
constexpr static uint32_t kNavSvInfoSubscribeRate
Subscribe Rate for u-blox SV Info messages.
Definition: node.h:97
ublox_node::HpgRovProduct::kRtcmFreqMax
constexpr static double kRtcmFreqMax
Diagnostic updater: RTCM topic frequency max [Hz].
Definition: node.h:1296
ublox_node::UbloxFirmware7Plus::callbackNavPvt
void callbackNavPvt(const NavPVT &m)
Publish a NavSatFix and TwistWithCovarianceStamped messages.
Definition: node.h:787
ublox_node::TimProduct::configureUblox
bool configureUblox()
Configure Time Sync settings.
Definition: node.cpp:1832
ublox_node::UbloxNode::baudrate_
uint32_t baudrate_
UART1 baudrate.
Definition: node.h:633
ublox_node::UbloxFirmware7
Implements functions for firmware version 7.
Definition: node.h:967
ublox_node::UbloxNode::rawDataStreamPa_
RawDataStreamPa rawDataStreamPa_
raw data stream logging
Definition: node.h:671
ublox_gps::Gps::sendRtcm
bool sendRtcm(const std::vector< uint8_t > &message)
Send rtcm correction message.
Definition: gps.cpp:571
ublox_node::UbloxNode::save_
ublox_msgs::CfgCFG save_
Parameters to save to non-volatile memory after configuration.
Definition: node.h:666
ublox_node::meas_rate
uint16_t meas_rate
The measurement [ms], see CfgRate.msg.
Definition: node.h:121
ublox_node::HpPosRecProduct::callbackNavRelPosNed
void callbackNavRelPosNed(const ublox_msgs::NavRELPOSNED9 &m)
Set the last received message and call rover diagnostic updater.
Definition: node.cpp:1785
ublox_node::checkMin
void checkMin(V val, T min, std::string name)
Check that the parameter is above the minimum.
Definition: node.h:265
ROS_WARN
#define ROS_WARN(...)
ublox_node::HpgRovProduct::freq_rtcm_
UbloxTopicDiagnostic freq_rtcm_
The RTCM topic frequency diagnostic updater.
Definition: node.h:1351
ublox_node::UbloxNode::set_usb_
bool set_usb_
Whether to configure the USB port.
Definition: node.h:642
ublox_node::RawDataProduct::freq_diagnostics_
std::vector< boost::shared_ptr< UbloxTopicDiagnostic > > freq_diagnostics_
Topic diagnostic updaters.
Definition: node.h:1089
ublox_node::TimProduct::t_ref_
sensor_msgs::TimeReference t_ref_
Definition: node.h:1418
ublox_node::UbloxFirmware7Plus< ublox_msgs::NavPVT7 >::enable_gps_
bool enable_gps_
Whether or not to enable GPS.
Definition: node.h:953
ublox_node::checkRange
void checkRange(V val, T min, T max, std::string name)
Check that the parameter is in the range.
Definition: node.h:282
ublox_node
ros::TimerEvent
ublox_node::UbloxFirmware::initializeRosDiagnostics
void initializeRosDiagnostics()
Add the fix diagnostics to the updater.
Definition: node.cpp:620
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
ublox_gps::Gps::setUTCtime
bool setUTCtime()
Configure the U-Blox to UTC time.
Definition: gps.cpp:615
ublox_gps::Gps::setPpp
bool setPpp(bool enable, float protocol_version)
Enable or disable PPP (precise-point-positioning).
Definition: gps.cpp:541
ublox_node::nh
boost::shared_ptr< ros::NodeHandle > nh
Node Handle for GPS node.
Definition: node.h:103
ROS_FATAL
#define ROS_FATAL(...)
ublox_gps::Gps::disableTmode3
bool disableTmode3()
Set the TMODE3 settings to disabled. Should only be called for High Precision GNSS devices,...
Definition: gps.cpp:496
ublox_gps::Gps::subscribe
void subscribe(typename CallbackHandler_< T >::Callback callback, unsigned int rate)
Configure the U-Blox send rate of the message & subscribe to the given message.
Definition: gps.h:503
ublox_node::UbloxFirmware7Plus< ublox_msgs::NavPVT7 >::enable_qzss_
bool enable_qzss_
Whether or not to enable QZSS.
Definition: node.h:957
ublox_node::UbloxFirmware8::configureUblox
bool configureUblox()
Configure settings specific to firmware 8 based on ROS parameters.
Definition: node.cpp:1144
ublox_node::UbloxNode::fix_mode_
std::string fix_mode_
Fix mode type.
Definition: node.h:627
ublox_node::kROSQueueSize
constexpr static uint32_t kROSQueueSize
Queue size for ROS publishers.
Definition: node.h:91
ublox_node::HpgRefProduct::fixed_pos_acc_
float fixed_pos_acc_
Fixed Position Accuracy [m].
Definition: node.h:1260
ublox_gps::Gps::initializeSerial
void initializeSerial(std::string port, unsigned int baudrate, uint16_t uart_in, uint16_t uart_out)
Initialize the Serial I/O port.
Definition: gps.cpp:108
ublox_node::HpgRefProduct::callbackNavSvIn
void callbackNavSvIn(ublox_msgs::NavSVIN m)
Update the last received NavSVIN message and call diagnostic updater.
Definition: node.cpp:1557
ublox_gps::Gps::isConfigured
bool isConfigured() const
Definition: gps.h:374
ublox_node::AdrUdrProduct::subscribe
void subscribe()
Subscribe to ADR/UDR messages.
Definition: node.cpp:1332
ublox_node::rtcm_rates
std::vector< uint8_t > rtcm_rates
Rates of RTCM out messages. Size must be the same as rtcm_ids.
Definition: node.h:127
ublox_node::UbloxNode::rate_
double rate_
The measurement rate in Hz.
Definition: node.h:648
ublox_gps::Gps::subscribe_nmea
void subscribe_nmea(boost::function< void(const std::string &)> callback)
Subscribe to the given Ublox message.
Definition: gps.h:351
ublox_node::UbloxFirmware7::getRosParams
void getRosParams()
Get the parameters specific to firmware version 7.
Definition: node.cpp:845
ublox_node::HpgRefProduct::initializeRosDiagnostics
void initializeRosDiagnostics()
Add diagnostic updaters for the TMODE3 status.
Definition: node.cpp:1590
ublox_node::UbloxNode::dynamic_model_
std::string dynamic_model_
dynamic model type
Definition: node.h:625
ublox_node::UbloxNode::sbas_usage_
uint8_t sbas_usage_
SBAS Usage parameter (see CfgSBAS message)
Definition: node.h:658
ublox_gps::Gps::configTmode3SurveyIn
bool configTmode3SurveyIn(unsigned int svin_min_dur, float svin_acc_limit)
Set the TMODE3 settings to survey-in.
Definition: gps.cpp:485
ublox_node::HpPosRecProduct::subscribe
void subscribe()
Subscribe to Rover messages, such as NavRELPOSNED.
Definition: node.cpp:1718
ublox_node::RawDataProduct
Implements functions for Raw Data products.
Definition: node.h:1059
ublox_node::HpgRefProduct::arp_position_hp_
std::vector< int8_t > arp_position_hp_
Antenna Reference Point Position High Precision [0.1 mm] or [deg * 1e-9].
Definition: node.h:1257
ros::console::notifyLoggerLevelsChanged
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
ros::Time
ublox_node::frame_id
std::string frame_id
The ROS frame ID of this device.
Definition: node.h:116
ublox_gps::Gps::setConfigOnStartup
void setConfigOnStartup(const bool config_on_startup)
Set the internal flag for enabling or disabling the initial configurations.
Definition: gps.h:91
ublox_gps::Gps::poll
bool poll(ConfigT &message, const std::vector< uint8_t > &payload=std::vector< uint8_t >(), const boost::posix_time::time_duration &timeout=default_timeout_)
Definition: gps.h:521
ublox_msgs::Message::INF::WARNING
static const uint8_t WARNING
ublox_node::UbloxNode::UbloxNode
UbloxNode()
Initialize and run the u-blox node.
Definition: node.cpp:90
ublox_node::HpgRefProduct::tmode3_
uint8_t tmode3_
TMODE3 to set, such as disabled, survey-in, fixed.
Definition: node.h:1246
ublox_node::gps
ublox_gps::Gps gps
Handles communication with the U-Blox Device.
Definition: node.h:106
ublox_node::UbloxNode::uart_in_
uint16_t uart_in_
UART in protocol (see CfgPRT message for constants)
Definition: node.h:635
ublox_msgs::Message::AID::ALM
static const uint8_t ALM
ublox_node::UbloxFirmware8
Implements functions for firmware version 8.
Definition: node.h:1003
ublox_gps::Gps::configSbas
bool configSbas(bool enable, uint8_t usage, uint8_t max_sbas)
Configure the SBAS settings.
Definition: gps.cpp:439
length
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
kResetWait
constexpr static int kResetWait
How long to wait during I/O reset [s].
Definition: node.cpp:38
rtcmCallback
void rtcmCallback(const rtcm_msgs::Message::ConstPtr &msg)
Definition: node.cpp:1901
ublox_node::UbloxNode::uart_out_
uint16_t uart_out_
UART out protocol (see CfgPRT message for constants)
Definition: node.h:637
ublox_node::enabled
std::map< std::string, bool > enabled
Whether or not to publish the given ublox message.
Definition: node.h:114
ublox_node::TimProduct
Implements functions for Time Sync products.
Definition: node.h:1385
ublox_node::UbloxNode::kTimeStampStatusMin
constexpr static double kTimeStampStatusMin
Minimum Time Stamp Status for fix frequency diagnostic.
Definition: node.h:515
ROS_ERROR
#define ROS_ERROR(...)
ublox_node::HpgRefProduct::last_nav_svin_
ublox_msgs::NavSVIN last_nav_svin_
The last received Nav SVIN message.
Definition: node.h:1243
ublox_node::UbloxFirmware6::subscribe
void subscribe()
Subscribe to NavPVT, RxmRAW, and RxmSFRB messages.
Definition: node.cpp:681
ublox_node::UbloxTopicDiagnostic
Topic diagnostics for u-blox messages.
Definition: node.h:133
ublox_node::HpgRovProduct::callbackNavRelPosNed
void callbackNavRelPosNed(const ublox_msgs::NavRELPOSNED &m)
Set the last received message and call rover diagnostic updater.
Definition: node.cpp:1704
ublox_node::UbloxNode::kDiagnosticPeriod
constexpr static float kDiagnosticPeriod
[s] 5Hz diagnostic period
Definition: node.h:509
ublox_node::UbloxNode::max_sbas_
uint8_t max_sbas_
Max SBAS parameter (see CfgSBAS message)
Definition: node.h:660
ublox_node::HpgRefProduct::subscribe
void subscribe()
Subscribe to u-blox Reference Station messages.
Definition: node.cpp:1549
ublox_node::UbloxFirmware7::set_nmea_
bool set_nmea_
Whether or not to Configure the NMEA settings.
Definition: node.h:997
ublox_node::nav_rate
uint16_t nav_rate
Navigation rate in measurement cycles, see CfgRate.msg.
Definition: node.h:123
ublox_node::HpPosRecProduct::callbackNavHpPosLlh
void callbackNavHpPosLlh(const ublox_msgs::NavHPPOSLLH &m)
Publish a sensor_msgs/NavSatFix message upon receiving a HPPOSLLH UBX message.
Definition: node.cpp:1746
ublox_node::AdrUdrProduct::callbackEsfMEAS
void callbackEsfMEAS(const ublox_msgs::EsfMEAS &m)
Definition: node.cpp:1381
ublox_node::RawDataProduct::kRtcmFreqWindow
static constexpr int kRtcmFreqWindow
Definition: node.h:1062
ublox_node::UbloxFirmware6::callbackNavPosLlh
void callbackNavPosLlh(const ublox_msgs::NavPOSLLH &m)
Publish the fix and call the fix diagnostic updater.
Definition: node.cpp:754
diagnostic_updater::DiagnosticStatusWrapper
ublox_node::UbloxNode::device_
std::string device_
Device port.
Definition: node.h:623
ublox_gps::Gps::setDgnss
bool setDgnss(uint8_t mode)
Set the DGNSS mode (see CfgDGNSS message for details).
Definition: gps.cpp:552
ublox_gps::Gps::setRawDataCallback
void setRawDataCallback(const Worker::Callback &callback)
Set the callback function which handles raw data.
Definition: gps.cpp:610
ublox_node::HpgRefProduct::INIT
@ INIT
Initialization mode (before configuration)
Definition: node.h:1279
ros::spin
ROSCPP_DECL void spin()
ublox_node::AdrUdrProduct::imu_
sensor_msgs::Imu imu_
Definition: node.h:1137
ublox_gps::Gps::subscribeId
void subscribeId(typename CallbackHandler_< T >::Callback callback, unsigned int message_id)
Subscribe to the message with the given ID. This is used for messages which have the same format but ...
Definition: gps.h:515
ublox_node::fixModeFromString
uint8_t fixModeFromString(const std::string &mode)
Determine fix mode from human-readable string.
Definition: node.cpp:72
lower
lower
ublox_node::RawDataProduct::initializeRosDiagnostics
void initializeRosDiagnostics()
Adds frequency diagnostics for RTCM topics.
Definition: node.cpp:1295
ublox_gps::Gps::configure
bool configure(const ConfigT &message, bool wait=true)
Send the given configuration message.
Definition: gps.h:535
ROSCONSOLE_DEFAULT_NAME
#define ROSCONSOLE_DEFAULT_NAME
ublox_node::supported
std::set< std::string > supported
Which GNSS are supported by the device.
Definition: node.h:108
main
int main(int argc, char **argv)
Definition: node.cpp:1905
ublox_node::UbloxNode::initializeRosDiagnostics
void initializeRosDiagnostics()
Initialize the diagnostic updater and add the fix diagnostic.
Definition: node.cpp:352
ublox_node::UbloxFirmware8::cfg_nmea_
ublox_msgs::CfgNMEA cfg_nmea_
Desired NMEA configuration.
Definition: node.h:1043
ublox_node::HpgRovProduct::getRosParams
void getRosParams()
Get the ROS parameters specific to the Rover configuration.
Definition: node.cpp:1640
ros::Timer::start
void start()
ublox_node::HpgRovProduct::last_rel_pos_
ublox_msgs::NavRELPOSNED last_rel_pos_
Last relative position (used for diagnostic updater)
Definition: node.h:1344
ROS_INFO
#define ROS_INFO(...)
ublox_node::freq_diag
boost::shared_ptr< FixDiagnostic > freq_diag
fix frequency diagnostic updater
Definition: node.h:227
ublox_node::RawDataStreamPa::isEnabled
bool isEnabled(void)
Returns the if raw data streaming is enabled.
Definition: raw_data_pa.cpp:67
ublox_node::kSubscribeRate
constexpr static uint32_t kSubscribeRate
Default subscribe Rate to u-blox messages [Hz].
Definition: node.h:95
ublox_node::AdrUdrProduct::use_adr_
bool use_adr_
Whether or not to enable dead reckoning.
Definition: node.h:1133
ublox_node::TimProduct::subscribe
void subscribe()
Subscribe to Time Sync messages.
Definition: node.cpp:1844
ublox_node::UbloxNode::kPollDuration
constexpr static double kPollDuration
How often (in seconds) to call poll messages.
Definition: node.h:506
ublox_node::UbloxNode::protocol_version_
float protocol_version_
Determined From Mon VER.
Definition: node.h:620
ros::Duration
ublox_msgs::Message::INF::TEST
static const uint8_t TEST
ublox_node::updater
boost::shared_ptr< diagnostic_updater::Updater > updater
ROS diagnostic updater.
Definition: node.h:101
ublox_msgs::Message::INF::ERROR
static const uint8_t ERROR
ros::Timer
ublox_gps::Gps::close
void close()
Closes the I/O port, and initiates save on shutdown procedure if enabled.
Definition: gps.cpp:285
ublox_gps::Gps::configRate
bool configRate(uint16_t meas_rate, uint16_t nav_rate)
Configure the device navigation and measurement rate settings.
Definition: gps.cpp:417
ublox_node::HpgRovProduct::subscribe
void subscribe()
Subscribe to Rover messages, such as NavRELPOSNED.
Definition: node.cpp:1653
ublox_node::UbloxNode::addProductInterface
void addProductInterface(std::string product_category, std::string ref_rov="")
Add the interface which is used for product category configuration, subscribers, & diagnostics.
Definition: node.cpp:114
tf::Quaternion
ublox_node::TimProduct::callbackTimTM2
void callbackTimTM2(const ublox_msgs::TimTM2 &m)
Definition: node.cpp:1868
ublox_node::publish_nmea
void publish_nmea(const std::string &sentence, const std::string &topic)
Definition: node.h:431
ublox_gps::debug
int debug
Used to determine which debug messages to display.
Definition: async_worker.h:45
ublox_node::UbloxNode::shutdown
void shutdown()
Shutdown the node. Closes the serial port.
Definition: node.cpp:610
ros::NodeHandle
ros::Subscriber
ublox_node::UbloxFirmware6::cfg_nmea_
ublox_msgs::CfgNMEA6 cfg_nmea_
Used to configure NMEA (if set_nmea_) filled with ROS parameters.
Definition: node.h:762
ublox_node::HpgRefProduct::DISABLED
@ DISABLED
Time mode disabled.
Definition: node.h:1281
ublox_node::UbloxNode::printInf
void printInf(const ublox_msgs::Inf &m, uint8_t id)
Print an INF message to the ROS console.
Definition: node.cpp:255
ublox_node::UbloxNode::initializeIo
void initializeIo()
Initialize the I/O handling.
Definition: node.cpp:535
ros::Time::now
static Time now()
ublox_node::UbloxNode::usb_tx_
uint16_t usb_tx_
USB TX Ready Pin configuration (see CfgPRT message for constants)
Definition: node.h:639
ublox_node::UbloxFirmware8::getRosParams
void getRosParams()
Get the ROS parameters specific to firmware version 8.
Definition: node.cpp:1029


ublox_gps
Author(s): Johannes Meyer
autogenerated on Wed Dec 7 2022 03:47:53