44#include < chrono>
55#include < memory>
66#include < string>
7+ #include < cmath>
78
89#include " rclcpp/rclcpp.hpp"
910#include " geometry_msgs/msg/pose_stamped.hpp"
1011#include " geometry_msgs/msg/transform_stamped.hpp"
1112
1213#include " tf2/LinearMath/Quaternion.h"
14+ #include < tf2_geometry_msgs/tf2_geometry_msgs.hpp>
1315#include " tf2_ros/transform_broadcaster.h"
1416#include " tf2_ros/buffer.h"
17+ #include " tf2/utils.h"
1518
1619#include " novatel_oem7_msgs/msg/bestutm.hpp"
1720#include " novatel_oem7_msgs/msg/inspva.hpp"
@@ -28,26 +31,38 @@ class CurrentPoseFromTf : public rclcpp::Node
2831 this ->declare_parameter <float >(" x_coord_offset" , -697237.0 );
2932 this ->declare_parameter <float >(" y_coord_offset" , -5285644.0 );
3033 this ->declare_parameter <float >(" z_coord_exact_height" , 1.9 );
34+ this ->declare_parameter <float >(" z_coord_offset_plus" , -10.0 );
3135 this ->declare_parameter <std::string>(" frame_id" , " map" );
3236 this ->declare_parameter <std::string>(" child_frame_id" , " lexus3/base_link" );
37+ // z_coord_ref_switch can be exact / zero_based / orig / orig_offset
38+ // exact: the Z coorindinate is always z_coord_exact_height param (must be set in this launch)
39+ // zero_based: Z coordinate starts from 0 and relative
40+ // orig: the original Z provided by the sensor
41+ // orig_offset: the original Z plus a fixed offset
3342 this ->declare_parameter <std::string>(" z_coord_ref_switch" , " orig" );
3443 this ->declare_parameter <std::string>(" pose_topic_pub" , " lexus3/gps/nova/current_pose" );
3544 this ->declare_parameter <std::string>(" utm_topic_sub" , " lexus3/gps/nova/bestutm" );
3645 this ->declare_parameter <std::string>(" inspva_topic_sub" , " lexus3/gps/nova/inspva" );
46+ this ->declare_parameter <bool >(" debug_publish" , false );
3747
3848 this ->get_parameter (" x_coord_offset" , m_x_coord_offset_);
3949 this ->get_parameter (" y_coord_offset" , m_y_coord_offset_);
4050 this ->get_parameter (" z_coord_exact_height" , m_z_coord_exact_height_);
51+ this ->get_parameter (" z_coord_offset_plus" , m_z_coord_orig_offset_);
4152 this ->get_parameter (" frame_id" , m_frame_id_);
4253 this ->get_parameter (" child_frame_id" , m_child_frame_id_);
4354 this ->get_parameter (" z_coord_ref_switch" , m_z_coord_ref_switch_);
4455 this ->get_parameter (" pose_topic_pub" , m_pose_topic_);
4556 this ->get_parameter (" utm_topic_sub" , m_utm_topic_);
4657 this ->get_parameter (" inspva_topic_sub" , m_inspva_topic_);
58+ this ->get_parameter (" debug_publish" , debug_pub);
4759
4860 m_pose_pub_ = this ->create_publisher <geometry_msgs::msg::PoseStamped>(m_pose_topic_, 10 );
4961 // additional publisher for translated pose
50- m_pose_pub2_ = this ->create_publisher <geometry_msgs::msg::PoseStamped>(" current_pose2" , 10 ); // TODO: this is only temporary
62+ if (debug_pub)
63+ {
64+ m_pose_pub_debug_ = this ->create_publisher <geometry_msgs::msg::PoseStamped>(" current_pose_debug_original" , 10 ); // TODO: this is only temporary
65+ }
5166 m_utm_sub_ = this ->create_subscription <novatel_oem7_msgs::msg::BESTUTM >(m_utm_topic_, 10 , std::bind (&CurrentPoseFromTf::utm_callback, this , _1));
5267 m_inspva_sub_ = this ->create_subscription <novatel_oem7_msgs::msg::INSPVA >(m_inspva_topic_, 10 , std::bind (&CurrentPoseFromTf::inspva_callback, this , _1));
5368 m_tfBroadcaster_ = std::make_shared<tf2_ros::TransformBroadcaster>(this );
@@ -60,17 +75,29 @@ class CurrentPoseFromTf : public rclcpp::Node
6075 {
6176 RCLCPP_INFO_STREAM (this ->get_logger (), " nova exact height (z): " << m_z_coord_exact_height_);
6277 }
63- else
78+ else if (m_z_coord_ref_switch_.compare (" zero_based" ) == 0 )
79+ {
80+ RCLCPP_INFO_STREAM (this ->get_logger (), " nova zero based height (z)" );
81+ }
82+ else if (m_z_coord_ref_switch_.compare (" orig" ) == 0 )
6483 {
6584 RCLCPP_INFO_STREAM (this ->get_logger (), " nova original height (z)" );
6685 }
86+ else
87+ {
88+ RCLCPP_INFO_STREAM (this ->get_logger (), " nova orig offset height (z): " << m_z_coord_orig_offset_);
89+ }
6790 }
6891
6992private:
7093 // Callback function for the subscriber novatel_oem7_msgs
7194 void utm_callback (const novatel_oem7_msgs::msg::BESTUTM ::SharedPtr msg)
7295 {
73-
96+ if (first_run_z_coord)
97+ {
98+ m_z_coord_start_ = msg->height ;
99+ first_run_z_coord = false ;
100+ }
74101 // create current pose
75102 m_currentPose.header .stamp = msg->header .stamp ;
76103 m_currentPose.header .frame_id = m_frame_id_;
@@ -84,9 +111,17 @@ class CurrentPoseFromTf : public rclcpp::Node
84111 {
85112 m_currentPose.pose .position .z = m_z_coord_exact_height_;
86113 }
114+ else if (m_z_coord_ref_switch_.compare (" zero_based" ) == 0 )
115+ {
116+ m_currentPose.pose .position .z = msg->height - m_z_coord_start_;
117+ }
118+ else if (m_z_coord_ref_switch_.compare (" orig" ) == 0 )
119+ {
120+ m_currentPose.pose .position .z = msg->height ;
121+ }
87122 else
88123 {
89- m_currentPose.pose .position .z = msg->height ; // original height
124+ m_currentPose.pose .position .z = msg->height + m_z_coord_orig_offset_;
90125 }
91126
92127 geometry_msgs::msg::TransformStamped transformStamped;
@@ -108,13 +143,25 @@ class CurrentPoseFromTf : public rclcpp::Node
108143 // Publish tf
109144 m_tfBroadcaster_->sendTransform (transformStamped);
110145 // Publish the current pose
111- m_pose_pub_->publish (m_currentPose);
112146 // Publish a translated copy of the current pose on current_pose2
113147 geometry_msgs::msg::PoseStamped translated_pose = m_currentPose;
114- // Apply translation: x = x - 1.5, y = y + 0.2
115- translated_pose.pose .position .x = translated_pose.pose .position .x - 1.585 ;
116- translated_pose.pose .position .y = translated_pose.pose .position .y + 0.2755 ;
117- m_pose_pub2_->publish (translated_pose);
148+ // Apply translation in the pose local frame.
149+ const double yaw = tf2::getYaw (translated_pose.pose .orientation );
150+
151+ constexpr double offset_x = -1.585 ; // local forward/backward
152+ constexpr double offset_y = 0.2755 ; // local left/right
153+
154+ translated_pose.pose .position .x += offset_x * std::cos (yaw) - offset_y * std::sin (yaw);
155+ translated_pose.pose .position .y += offset_x * std::sin (yaw) + offset_y * std::cos (yaw);
156+
157+ // // Apply translation: x = x - 1.5, y = y + 0.2 Faulty logic
158+ // translated_pose.pose.position.x = translated_pose.pose.position.x - 1.585;
159+ // translated_pose.pose.position.y = translated_pose.pose.position.y + 0.2755;
160+ if (debug_pub)
161+ {
162+ m_pose_pub_debug_->publish (m_currentPose);
163+ }
164+ m_pose_pub_->publish (translated_pose);
118165 }
119166
120167 void inspva_callback (const novatel_oem7_msgs::msg::INSPVA ::SharedPtr msg)
@@ -136,7 +183,7 @@ class CurrentPoseFromTf : public rclcpp::Node
136183 }
137184
138185 rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr m_pose_pub_;
139- rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr m_pose_pub2_ ;
186+ rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr m_pose_pub_debug_ ;
140187 rclcpp::Subscription<novatel_oem7_msgs::msg::BESTUTM >::SharedPtr m_utm_sub_;
141188 rclcpp::Subscription<novatel_oem7_msgs::msg::INSPVA >::SharedPtr m_inspva_sub_;
142189 std::shared_ptr<tf2_ros::TransformBroadcaster> m_tfBroadcaster_;
@@ -148,9 +195,13 @@ class CurrentPoseFromTf : public rclcpp::Node
148195 double m_x_coord_offset_ = 0.0 ;
149196 double m_y_coord_offset_ = 0.0 ;
150197 double m_z_coord_exact_height_ = 1.9 ;
198+ double m_z_coord_start_ = 0.0 ;
199+ double m_z_coord_orig_offset_ = 0.0 ;
151200 std::string m_pose_topic_ = " /lexus3/gps/nova/current_pose" ;
152201 std::string m_utm_topic_ = " /lexus3/nova/bestutm" ;
153202 std::string m_inspva_topic_ = " /lexus3/nova/inspva" ;
203+ bool debug_pub = false ;
204+ bool first_run_z_coord = true ;
154205};
155206
156207int main (int argc, char **argv)
0 commit comments