37 #include <unordered_map>
39 #include <rclcpp/rclcpp.hpp>
44 #include <tf2_eigen/tf2_eigen.hpp>
45 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
51 #include <diagnostic_msgs/msg/diagnostic_array.hpp>
52 #include <diagnostic_msgs/msg/diagnostic_status.hpp>
53 #include <geometry_msgs/msg/pose_with_covariance_stamped.hpp>
54 #include <geometry_msgs/msg/quaternion.hpp>
55 #include <geometry_msgs/msg/twist_with_covariance.hpp>
56 #include <geometry_msgs/msg/twist_with_covariance_stamped.hpp>
57 #include <gps_msgs/msg/gps_fix.hpp>
58 #include <nav_msgs/msg/odometry.hpp>
59 #include <sensor_msgs/msg/imu.hpp>
60 #include <sensor_msgs/msg/nav_sat_fix.hpp>
61 #include <sensor_msgs/msg/time_reference.hpp>
63 #include <septentrio_gnss_driver/msg/aim_plus_status.hpp>
64 #include <septentrio_gnss_driver/msg/att_cov_euler.hpp>
65 #include <septentrio_gnss_driver/msg/att_euler.hpp>
66 #include <septentrio_gnss_driver/msg/base_vector_cart.hpp>
67 #include <septentrio_gnss_driver/msg/base_vector_geod.hpp>
68 #include <septentrio_gnss_driver/msg/block_header.hpp>
69 #include <septentrio_gnss_driver/msg/gal_auth_status.hpp>
70 #include <septentrio_gnss_driver/msg/meas_epoch.hpp>
71 #include <septentrio_gnss_driver/msg/meas_epoch_channel_type1.hpp>
72 #include <septentrio_gnss_driver/msg/meas_epoch_channel_type2.hpp>
73 #include <septentrio_gnss_driver/msg/pos_cov_cartesian.hpp>
74 #include <septentrio_gnss_driver/msg/pos_cov_geodetic.hpp>
75 #include <septentrio_gnss_driver/msg/pvt_cartesian.hpp>
76 #include <septentrio_gnss_driver/msg/pvt_geodetic.hpp>
77 #include <septentrio_gnss_driver/msg/receiver_time.hpp>
78 #include <septentrio_gnss_driver/msg/rf_band.hpp>
79 #include <septentrio_gnss_driver/msg/rf_status.hpp>
80 #include <septentrio_gnss_driver/msg/vector_info_cart.hpp>
81 #include <septentrio_gnss_driver/msg/vector_info_geod.hpp>
82 #include <septentrio_gnss_driver/msg/vel_cov_cartesian.hpp>
83 #include <septentrio_gnss_driver/msg/vel_cov_geodetic.hpp>
85 #include <nmea_msgs/msg/gpgga.hpp>
86 #include <nmea_msgs/msg/gpgsa.hpp>
87 #include <nmea_msgs/msg/gpgsv.hpp>
88 #include <nmea_msgs/msg/gprmc.hpp>
90 #include <septentrio_gnss_driver/msg/ext_sensor_meas.hpp>
91 #include <septentrio_gnss_driver/msg/imu_setup.hpp>
92 #include <septentrio_gnss_driver/msg/ins_nav_cart.hpp>
93 #include <septentrio_gnss_driver/msg/ins_nav_geod.hpp>
94 #include <septentrio_gnss_driver/msg/vel_sensor_setup.hpp>
171 return tsr.nanoseconds();
203 bool ok() {
return rclcpp::ok(); }
213 this->create_subscription<nav_msgs::msg::Odometry>(
215 rclcpp::QoS(rclcpp::KeepLast(1))
216 .durability_volatile()
219 std::placeholders::_1));
222 this->create_subscription<TwistWithCovarianceStampedMsg>(
224 rclcpp::QoS(rclcpp::KeepLast(1))
225 .durability_volatile()
228 std::placeholders::_1));
229 }
catch (
const std::runtime_error& ex)
232 std::string(ex.what()) +
".");
247 if ((!this->
param(name, tempVal, -1)) || (tempVal < 0))
264 template <
typename T>
265 bool param(
const std::string& name, T& val,
const T& defaultVal)
267 if (this->has_parameter(name))
268 this->undeclare_parameter(name);
272 val = this->declare_parameter<T>(name, defaultVal);
273 }
catch (std::runtime_error& e)
275 RCLCPP_WARN_STREAM(this->get_logger(), e.what());
291 RCLCPP_DEBUG_STREAM(this->get_logger(),
s);
294 RCLCPP_INFO_STREAM(this->get_logger(),
s);
297 RCLCPP_WARN_STREAM(this->get_logger(),
s);
300 RCLCPP_ERROR_STREAM(this->get_logger(),
s);
303 RCLCPP_FATAL_STREAM(this->get_logger(),
s);
321 template <
typename M>
333 typename rclcpp::Publisher<M>::SharedPtr ptr =
334 std::any_cast<typename rclcpp::Publisher<M>::SharedPtr>(it->second);
340 typename rclcpp::Publisher<M>::SharedPtr pub =
341 this->create_publisher<M>(
342 topic, rclcpp::QoS(rclcpp::KeepLast(
queueSize_))
343 .durability_volatile()
345 topicMap_.insert(std::make_pair(topic, pub));
357 if (std::isnan(loc.pose.pose.orientation.w))
366 geometry_msgs::msg::TransformStamped transformStamped;
368 transformStamped.header.stamp = loc.header.stamp;
369 transformStamped.header.frame_id = loc.header.frame_id;
370 transformStamped.child_frame_id = loc.child_frame_id;
371 transformStamped.transform.translation.x = loc.pose.pose.position.x;
372 transformStamped.transform.translation.y = loc.pose.pose.position.y;
373 transformStamped.transform.translation.z = loc.pose.pose.position.z;
374 transformStamped.transform.rotation.x = loc.pose.pose.orientation.x;
375 transformStamped.transform.rotation.y = loc.pose.pose.orientation.y;
376 transformStamped.transform.rotation.z = loc.pose.pose.orientation.z;
377 transformStamped.transform.rotation.w = loc.pose.pose.orientation.w;
381 geometry_msgs::msg::TransformStamped T_l_b;
391 RCLCPP_INFO_STREAM_THROTTLE(
392 this->get_logger(), *this->get_clock(), 10000,
393 ": No transform for insertion of local frame at t="
394 << std::to_string(currentStamp)
395 <<
". Exception: " << std::string(ex.what()));
402 RCLCPP_WARN_STREAM_THROTTLE(
403 this->get_logger(), *this->get_clock(), 10000,
404 ": No most recent transform for insertion of local frame. Exception: "
405 << std::string(ex.what()));
414 transformStamped.header.stamp = loc.header.stamp;
415 transformStamped.header.frame_id = loc.header.frame_id;
460 void callbackTwist(
const TwistWithCovarianceStampedMsg::ConstSharedPtr twist)
468 const geometry_msgs::msg::TwistWithCovariance& twist)
474 thread_local Eigen::Vector3d vel = Eigen::Vector3d::Zero();
475 thread_local Eigen::Vector3d var = Eigen::Vector3d::Zero();
476 thread_local uint64_t ctr = 0;
480 vel[0] += twist.twist.linear.x;
481 vel[1] += twist.twist.linear.y;
482 vel[2] += twist.twist.linear.z;
483 var[0] += twist.covariance[0];
484 var[1] += twist.covariance[7];
485 var[2] += twist.covariance[14];
488 if ((stamp - lastStamp) >= 495000000)
492 time_t epochSeconds = stamp / 1000000000;
493 struct tm* tm_temp = std::gmtime(&epochSeconds);
494 std::stringstream timeUtc;
495 timeUtc << std::setfill(
'0') << std::setw(2)
496 << std::to_string(tm_temp->tm_hour) << std::setw(2)
497 << std::to_string(tm_temp->tm_min) << std::setw(2)
498 << std::to_string(tm_temp->tm_sec) <<
"." << std::setw(3)
499 << std::to_string((stamp - (stamp / 1000000000) * 1000000000) /
514 else if (var[0] > 0.0)
519 std::to_string(var[0]) +
520 ". Ignoring measurement.");
525 std_x = std::to_string(1000000.0);
534 else if (var[1] > 0.0)
539 std::to_string(var[1]) +
540 ". Ignoring measurement.");
554 else if (var[2] > 0.0)
559 std::to_string(var[2]) +
560 ". Ignoring measurement.");
567 std::string velNmea =
"$PSSN,VSM," + timeUtc.str() +
"," + v_x +
"," +
568 v_y +
"," + std_x +
"," + std_y +
"," + v_z +
"," +
571 char crc = std::accumulate(velNmea.begin() + 1, velNmea.end(), 0,
572 [](
char sum,
char ch) { return sum ^ ch; });
574 std::stringstream crcss;
575 crcss << std::hex << static_cast<int32_t>(
crc);
577 velNmea +=
"*" + crcss.str() +
"\r\n";
580 vel = Eigen::Vector3d::Zero();
581 var = Eigen::Vector3d::Zero();
591 virtual void sendVelocity(
const std::string& velNmea) = 0;