@@ -93,6 +93,18 @@ class TransformListener
9393 TF2_ROS_PUBLIC
9494 explicit TransformListener (tf2::BufferCore & buffer, bool spin_thread = true );
9595
96+ /* * \brief Simplified constructor for transform listener with static_only option.
97+ *
98+ * This constructor will create a new ROS 2 node under the hood.
99+ * If you already have access to a ROS 2 node and you want to associate the TransformListener
100+ * to it, then it's recommended to use one of the other constructors.
101+ */
102+ TF2_ROS_PUBLIC
103+ explicit TransformListener (
104+ tf2::BufferCore & buffer,
105+ bool spin_thread,
106+ bool static_only);
107+
96108 /* * \brief Node constructor */
97109 template <class NodeT , class AllocatorT = std::allocator<void >>
98110 TransformListener (
@@ -118,6 +130,31 @@ class TransformListener
118130 static_options)
119131 {}
120132
133+ /* * \brief Node constructor with static_only option */
134+ template <class NodeT , class AllocatorT = std::allocator<void >>
135+ TransformListener (
136+ tf2::BufferCore & buffer,
137+ NodeT && node,
138+ bool spin_thread,
139+ const rclcpp::QoS & qos,
140+ const rclcpp::QoS & static_qos,
141+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options,
142+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options,
143+ bool static_only)
144+ : TransformListener(
145+ buffer,
146+ node->get_node_base_interface (),
147+ node->get_node_logging_interface(),
148+ node->get_node_parameters_interface(),
149+ node->get_node_topics_interface(),
150+ spin_thread,
151+ qos,
152+ static_qos,
153+ options,
154+ static_options,
155+ static_only)
156+ {}
157+
121158 /* * \brief Node interface constructor */
122159 template <class AllocatorT = std::allocator<void >>
123160 TransformListener (
@@ -147,6 +184,35 @@ class TransformListener
147184 static_options);
148185 }
149186
187+ /* * \brief Node interface constructor with static_only option */
188+ template <class AllocatorT = std::allocator<void >>
189+ TransformListener (
190+ tf2::BufferCore & buffer,
191+ rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
192+ rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
193+ rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
194+ rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
195+ bool spin_thread,
196+ const rclcpp::QoS & qos,
197+ const rclcpp::QoS & static_qos,
198+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options,
199+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options,
200+ bool static_only)
201+ : buffer_(buffer)
202+ {
203+ init (
204+ node_base,
205+ node_logging,
206+ node_parameters,
207+ node_topics,
208+ spin_thread,
209+ qos,
210+ static_qos,
211+ options,
212+ static_options,
213+ static_only);
214+ }
215+
150216 TF2_ROS_PUBLIC
151217 virtual ~TransformListener ();
152218
@@ -165,7 +231,8 @@ class TransformListener
165231 const rclcpp::QoS & qos,
166232 const rclcpp::QoS & static_qos,
167233 const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options,
168- const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options)
234+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options,
235+ bool static_only = false )
169236 {
170237 spin_thread_ = spin_thread;
171238 node_base_interface_ = node_base;
@@ -181,14 +248,19 @@ class TransformListener
181248 // Create new callback group for message_subscription of tf and tf_static
182249 callback_group_ = node_base_interface_->create_callback_group (
183250 rclcpp::CallbackGroupType::MutuallyExclusive, false );
184- // Duplicate to modify option of subscription
185- rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> tf_options = options;
251+
252+ if (!static_only) {
253+ // Duplicate to modify subscription options
254+ rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> tf_options = options;
255+ tf_options.callback_group = callback_group_;
256+
257+ message_subscription_tf_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
258+ node_parameters, node_topics, " /tf" , qos, std::move (cb), tf_options);
259+ }
260+
186261 rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> tf_static_options = static_options;
187- tf_options.callback_group = callback_group_;
188262 tf_static_options.callback_group = callback_group_;
189263
190- message_subscription_tf_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
191- node_parameters, node_topics, " /tf" , qos, std::move (cb), tf_options);
192264 message_subscription_tf_static_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
193265 node_parameters,
194266 node_topics,
@@ -204,8 +276,10 @@ class TransformListener
204276 // Tell the buffer we have a dedicated thread to enable timeouts
205277 buffer_.setUsingDedicatedThread (true );
206278 } else {
207- message_subscription_tf_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
208- node_parameters, node_topics, " /tf" , qos, std::move (cb), options);
279+ if (!static_only) {
280+ message_subscription_tf_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
281+ node_parameters, node_topics, " /tf" , qos, std::move (cb), options);
282+ }
209283 message_subscription_tf_static_ = rclcpp::create_subscription<tf2_msgs::msg::TFMessage>(
210284 node_parameters,
211285 node_topics,
@@ -231,6 +305,78 @@ class TransformListener
231305 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface_ {nullptr };
232306 rclcpp::CallbackGroup::SharedPtr callback_group_{nullptr };
233307};
308+
309+ /* * \brief Convenience class for subscribing to static-only transforms
310+ *
311+ * While users can achieve the same thing with a normal TransformListener, the number of parameters that must be
312+ * provided is unwieldy.
313+ */
314+ class StaticTransformListener : public TransformListener
315+ {
316+ public:
317+ /* * \brief Simplified constructor for a static transform listener
318+ * \see the simplified TransformListener documentation
319+ */
320+ TF2_ROS_PUBLIC
321+ explicit StaticTransformListener (tf2::BufferCore & buffer, bool spin_thread = true )
322+ : TransformListener(buffer, spin_thread, true )
323+ {
324+ }
325+
326+ /* * \brief Node constructor */
327+ template <class NodeT , class AllocatorT = std::allocator<void >>
328+ StaticTransformListener (
329+ tf2::BufferCore & buffer,
330+ NodeT && node,
331+ bool spin_thread = true ,
332+ const rclcpp::QoS & static_qos = StaticListenerQoS(),
333+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options =
334+ detail::get_default_transform_listener_static_sub_options<AllocatorT>())
335+ : TransformListener(
336+ buffer,
337+ node,
338+ spin_thread,
339+ rclcpp::QoS (1 ),
340+ static_qos,
341+ rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>(),
342+ static_options,
343+ true)
344+ {
345+ }
346+
347+ /* * \brief Node interface constructor */
348+ template <class AllocatorT = std::allocator<void >>
349+ StaticTransformListener (
350+ tf2::BufferCore & buffer,
351+ rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
352+ rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
353+ rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
354+ rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
355+ bool spin_thread = true ,
356+ const rclcpp::QoS & static_qos = StaticListenerQoS(),
357+ const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & static_options =
358+ detail::get_default_transform_listener_static_sub_options<AllocatorT>())
359+ : TransformListener(
360+ buffer,
361+ node_base,
362+ node_logging,
363+ node_parameters,
364+ node_topics,
365+ spin_thread,
366+ rclcpp::QoS (1 ),
367+ static_qos,
368+ rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>(),
369+ static_options,
370+ true)
371+ {
372+ }
373+
374+ TF2_ROS_PUBLIC
375+ virtual ~StaticTransformListener ()
376+ {
377+ }
378+ };
379+
234380} // namespace tf2_ros
235381
236382#endif // TF2_ROS__TRANSFORM_LISTENER_HPP_
0 commit comments