Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instead of templating on NodeT, use rclcpp::node_interfaces::NodeInterfaces instead #698

Open
methylDragon opened this issue Jun 29, 2024 · 0 comments · May be fixed by #714
Open

Instead of templating on NodeT, use rclcpp::node_interfaces::NodeInterfaces instead #698

methylDragon opened this issue Jun 29, 2024 · 0 comments · May be fixed by #714
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@methylDragon
Copy link

methylDragon commented Jun 29, 2024

Feature request

Feature description

tf2_ros currently has an established pattern of templating on a NodeT to support taking in arbitrary node-like types (e.g. Node, LifecycleNode, etc.)

For example:

template<typename NodeT = rclcpp::Node::SharedPtr>
Buffer(
rclcpp::Clock::SharedPtr clock,
tf2::Duration cache_time = tf2::Duration(tf2::BUFFER_CORE_DEFAULT_CACHE_TIME),
NodeT && node = NodeT(),
const rclcpp::QoS & qos = rclcpp::ServicesQoS())
: BufferCore(cache_time), clock_(clock), timer_interface_(nullptr)

This pattern of templating on NodeT, however, means that a lot of business logic needs to be moved into a template function in the header, resulting in the need to recompile any dependents of tf2_ros if any business logic changes.

Instead, as per this ROSCon 2023 lightning talk, it would be better to defer that templating logic to the rclcpp::node_interfaces::NodeInterfaces (ros2/rclcpp#2041) class instead so that the logic can be moved to a .cpp source file to avoid this recompilation.

Additionally:

  • It would serve as better documentation, since the interfaces that are needed will be visible directly in the header.
  • Template instantiation of the NodeInterfaces class can be shared across different classes that use it instead of instantiating different versions of constructors of each class in the case of NodeT

That is, instead of:

// Templated!!
template<typename NodeT = rclcpp::Node::SharedPtr>
Buffer(
  rclcpp::Clock::SharedPtr clock,
  tf2::Duration cache_time = tf2::Duration(tf2::BUFFER_CORE_DEFAULT_CACHE_TIME),
  NodeT && node = NodeT(),
  const rclcpp::QoS & qos = rclcpp::ServicesQoS())
: BufferCore(cache_time), clock_(clock), timer_interface_(nullptr)

We do something like:

// NOT templated!
Buffer(
  rclcpp::Clock::SharedPtr clock,
  tf2::Duration cache_time,
  NodeInterfaces<
    NodeBaseInterface, NodeLoggingInterface, NodeServicesInterface
  > interfaces,
 ...) : interfaces_(std::move(interfaces)), ...

This would rely on the NodeInterfaces class to aggregate the node interfaces we need, and we can store/copy that interfaces object in the tf2_ros class instead (as it is copyable).

Implementation considerations

I see a couple of classes to apply the NodeInterfaces pattern to:

  • Buffer
  • TransformBroadcaster
  • StaticTransformBroadcaster
  • TransformListener

(And technically anything that takes in multiple node interfaces)

  • A new, non-templated constructor that takes rclcpp::node_interfaces::NodeInterfaces should be implemented and used to house the logic in a source file
    • Note: NodeInterfaces can only take in a non-pointer NodeT, so any downstream usages must dereference any node-pointers they have to pass to it.
  • Classes with this constructor should copy the NodeInterfaces object (which will compose all shared_ptrs to the interfaces it uses), instead of copying the individual interfaces one by one.
  • We will still need templated constructor overloads for some types (since they default construct NodeT sometimes) that call the non-templated constructor
  • Once classes are moved to use NodeInterfaces, many template functions will no longer need to be templated, and should have their logic be moved to source files as much as possible.

I'm unsure how many tf2_ros dependents in ros2.repos will get affected, changes might ripple out a little bit, but I think the re-compilation tradeoff is worth it.

@methylDragon methylDragon added enhancement New feature or request good first issue Good for newcomers labels Jun 29, 2024
@sloretz sloretz added the help wanted Extra attention is needed label Jul 12, 2024
@CursedRock17 CursedRock17 linked a pull request Oct 12, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants