ros-controls / ros2_control

Generic and simple controls framework for ROS 2
https://control.ros.org
Apache License 2.0
501 stars 298 forks source link

controller_manager as component node #330

Open tylerjw opened 3 years ago

tylerjw commented 3 years ago

Component nodes enable using intra-process communication which can greatly reduce latency in control systems that run on the same machine by running the nodes in the same process. Here is the official documentation on it.

If possible it would be nice if the controller_manager was a component node. This would not prevent running it in a stand-alone process as it is now. This could either be done by maintaining both the current standalone node implementation and a component node version or by changing existing launch files to load the controller_manager component node into it's own component_container with no other nodes.

In theory, this should be a simple change (and I'm happy to help make it happen) as the basic change is removing the main in favor of an entry-point function (most of the boilerplate is provided by macros) and building the controller_manager as a shared library. In practice, this might be more complex depending on how the current implementation interacts with ROS2 executors and spinning (there is some nuance in adapting code that uses some of these features).

I'm happy to help make this change. I've been working on moveit_servo recently which uses component nodes. Here is one of the launch files to show how it is launched: https://github.com/ros-planning/moveit2/blob/main/moveit_ros/moveit_servo/launch/servo_teleop.launch.py. Here is the teleop demo node that translates messages from the joystick package (xbox controller) and moveit_servo: https://github.com/ros-planning/moveit2/blob/main/moveit_ros/moveit_servo/src/teleop_demo/joystick_servo_example.cpp. You can look at the CMakeLists.txt in that package to see examples of the cmake needed to build component nodes.

This is all assuming that ros2_control is basically a single node controller_manager that loads various controllers via plubinlib. If my understanding is wrong I apologize, please point me to any architecture diagrams or launch-file examples on how to use ros2_control as that'd make it easier for me to understand (and therefore help with adapting ros2_control to use component nodes).

bmagyar commented 3 years ago

I think this'd be a much desired improvement and would fit well with our Foxy version. Indeed, controller_manager is a single node, however controllers are their own nodes and multithreading really depends on the executor. I think it is worth giving a try to the component approach, it is partially why we opted to use nodes in the first place. I'd say let's see a PR whenever you have a bit of time.

What about the executor/spinning-related issues you mentioned? Are there any common pitfalls one should be aware of?

Karsten1987 commented 3 years ago

Just a few things I'd like to have clarified before digging too deep into coding.

All that is to say, I am a big fan of leveraging intra-process as much as possible. I just want to highlight that we might have to deal with some more details here and anticipated. A while ago, I started to write down some thoughts about it: https://github.com/ros-controls/roadmap/blob/master/design_drafts/controller_components.md That design doc might be obsolete or at least outdated now, but captures the overall idea I had in mind back then.

tylerjw commented 3 years ago

Thank you for the detailed replies. My takeaway is that we generally need the issues with the executors to settle down and some support for RT execution/spinning before this becomes a real possibility.

I'm happy to help where I can if there are things I can do. When I said build as a shared library I meant the main node that loads the controllers, I didn't realize the overlap between it and the component manager node. I understand now why the current component container is not adequate for the current needs.

I'll close this issue if you'd like as further progress seems blocked by requirements upstream of this ros2_control and we can revisit it later. Thank you again for sharing all the details you've collected about this.

destogl commented 3 years ago

@tylerjw thanks for the initiative!

I would not close the issue, but just put it on low-priority for now since we need some other things to solve, e.g., #277.

Still, I think there it is worth investigating this and make a proof-of-concept implementation. So if you like to test it, please go for it and just ask what we can support you. The ContrtollerManager starts a node, but the executor is provided by ros2_control_node.cpp.

Considering everything above, maybe a custom component container is needed.

For starters, would be sufficient to rewrite ros2_control_node, or do you have to change the interface of the ControllerManager?