ros2 / ros2/geometry2

Cannot run the tf_listener without creating a transform_listener_impl node

Open
#361 0 comments 3 reactions 1 assignee View on GitHub

@clalancette is already working on this.

Since Jan 7, 2021.

Dominant language
C++
Stars
153
Forks
256
Avg merge
3d 23h
Merged PRs (30d)
14

Description

Bug report

Required Info:

  • Operating System:
    Ubuntu20.04
  • Installation type:
    binaries
  • Version or commit hash:
    0.13.9
  • DDS implementation:
    Fast-RTPS
  • Client library (if applicable):
    rclcpp
Steps to reproduce issue

Brief: Is there any way or options to run the node without creating the transform_listener_impl node?

  • The case of tf_listener_(tf_buffer_)

When I launch a node that contains TransformListener with the following code, every tf functions work correctly but the extra node is created.

class TFTest : public rclcpp::Node
{
private:
  tf2_ros::Buffer tf_buffer_;
  tf2_ros::TransformListener tf_listener_;

public:
  TFTest() : Node("tf_test_node"), tf_buffer_(this->get_clock()), tf_listener_(tf_buffer_) {}
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<TFTest>());
  rclcpp::shutdown();
  return 0;
}

In this case, ros2 node list shows as below.

/tf_test_node
/transform_listener_impl_559f930c13e8

When I do this in a large project, it creates so many impl nodes. I want to remove them (although it is not a serious problem).

  • The case of tf_listener_(tf_buffer_, this, true)

To run without the /transform_listener_impl node being created, the TransformListener can receive the node on the constructor here and create subscribers using the given node. So I changed the initialization from tf_listener_(tf_buffer_) to tf_listener_(tf_buffer_, this, true). However, the node died with the following message.

terminate called after throwing an instance of 'std::runtime_error'
  what():  Node has already been added to an executor.

This is because the transform listener adds the received node in the executor here when the third arg spin_thread = true (which is a default value).

  • The case of tf_listener_(tf_buffer_, this, false)

Then I set spin_thread = false for the transform listener. However, in this case, when I write lookupTransform("a", "b", requested_time, timeout), it doesn't wait for the timeout and failed in most cases. I looked into the lookupTransform code and found that the canTransformreturns false immediately here, which should wait for a given timeout, since there is no dedicated thread for the tf listener. This is reasonable since it cannot update tf in the while loop waiting for the timeout.

I can't think of a good solution. Is there any way or options to run the node without creating the transform_listener_impl node?

Expected behavior

We can launch the node without creating the transform_listener_impl node and run the lookupTransform with a timeout correctly.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.