Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
base_footprint_publisher.hpp
1 // Copyright (c) 2023 Open Navigation LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BASE_FOOTPRINT_PUBLISHER_HPP_
16 #define BASE_FOOTPRINT_PUBLISHER_HPP_
17 
18 #include <string>
19 #include <memory>
20 
21 #include "rclcpp/rclcpp.hpp"
22 #include "tf2_msgs/msg/tf_message.hpp"
23 #include "geometry_msgs/msg/transform_stamped.hpp"
24 #include "tf2_ros/create_timer_ros.hpp"
25 #include "tf2_ros/transform_listener.hpp"
26 #include "tf2_ros/transform_broadcaster.hpp"
27 #include "tf2_ros/buffer.hpp"
28 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
29 #include "tf2/utils.hpp"
30 
31 namespace nav2_util
32 {
33 
39 class BaseFootprintPublisherListener : public tf2_ros::TransformListener
40 {
41 public:
42  BaseFootprintPublisherListener(tf2::BufferCore & buffer, bool spin_thread, rclcpp::Node & node)
43  : tf2_ros::TransformListener(buffer, spin_thread)
44  {
45  node.declare_parameter(
46  "base_link_frame", rclcpp::ParameterValue(std::string("base_link")));
47  node.declare_parameter(
48  "base_footprint_frame", rclcpp::ParameterValue(std::string("base_footprint")));
49  base_link_frame_ = node.get_parameter("base_link_frame").as_string();
50  base_footprint_frame_ = node.get_parameter("base_footprint_frame").as_string();
51  tf_broadcaster_ = std::make_shared<tf2_ros::TransformBroadcaster>(node);
52  }
53 
57  void subscription_callback(tf2_msgs::msg::TFMessage::ConstSharedPtr msg, bool is_static) override
58  {
59  TransformListener::subscription_callback(msg, is_static);
60 
61  if (is_static) {
62  return;
63  }
64 
65  for (unsigned int i = 0; i != msg->transforms.size(); i++) {
66  auto & t = msg->transforms[i];
67  if (t.child_frame_id == base_link_frame_) {
68  geometry_msgs::msg::TransformStamped transform;
69  transform.header.stamp = t.header.stamp;
70  transform.header.frame_id = base_link_frame_;
71  transform.child_frame_id = base_footprint_frame_;
72 
73  // Project to Z-zero
74  transform.transform.translation = t.transform.translation;
75  transform.transform.translation.z = 0.0;
76 
77  // Remove Roll and Pitch
78  tf2::Quaternion q;
79  q.setRPY(0, 0, tf2::getYaw(t.transform.rotation));
80  q.normalize();
81  transform.transform.rotation.x = q.x();
82  transform.transform.rotation.y = q.y();
83  transform.transform.rotation.z = q.z();
84  transform.transform.rotation.w = q.w();
85 
86  tf_broadcaster_->sendTransform(transform);
87  return;
88  }
89  }
90  }
91 
92 protected:
93  std::shared_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
94  std::string base_link_frame_, base_footprint_frame_;
95 };
96 
103 class BaseFootprintPublisher : public rclcpp::Node
104 {
105 public:
109  explicit BaseFootprintPublisher(const rclcpp::NodeOptions & options = rclcpp::NodeOptions())
110  : Node("base_footprint_publisher", options)
111  {
112  RCLCPP_INFO(get_logger(), "Creating base footprint publisher");
113  tf_buffer_ = std::make_shared<tf2_ros::Buffer>(get_clock());
114  auto timer_interface = std::make_shared<tf2_ros::CreateTimerROS>(
115  get_node_base_interface(),
116  get_node_timers_interface());
117  tf_buffer_->setCreateTimerInterface(timer_interface);
118  listener_publisher_ = std::make_shared<BaseFootprintPublisherListener>(
119  *tf_buffer_, true, *this);
120  }
121 
122 protected:
123  std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
124  std::shared_ptr<BaseFootprintPublisherListener> listener_publisher_;
125 };
126 
127 } // end namespace nav2_util
128 
129 #endif // BASE_FOOTPRINT_PUBLISHER_HPP_
A TF2 listener that overrides the subscription callback to inject base footprint publisher removing Z...
void subscription_callback(tf2_msgs::msg::TFMessage::ConstSharedPtr msg, bool is_static) override
Overrides TF2 subscription callback to inject base footprint publisher.
Republishes the base_link frame as base_footprint stripping away the Z, Roll, and Pitch of the full 3...
BaseFootprintPublisher(const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
A constructor.