-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Writing a Composable Node (C++) Tutorial #4106
Merged
clalancette
merged 7 commits into
ros2:rolling
from
DLu:how_to_make_a_node_a_component2
Feb 16, 2024
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
64b2eaa
Writing a Composable Node (C++) Tutorial
DLu 684bc5a
Update Writing-a-Composable-Node.rst
DLu 5d50ea7
Apply suggestions from code review
DLu 55b1dcc
Add Package.xml note
DLu ec37066
white space
DLu 605d1a7
Add links to demos
DLu 3958cb6
Apply suggestions from code review
DLu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
170 changes: 170 additions & 0 deletions
170
source/Tutorials/Intermediate/Writing-a-Composable-Node.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
Writing a Composable Node (C++) | ||
=============================== | ||
|
||
.. contents:: Table of Contents | ||
:depth: 2 | ||
:local: | ||
|
||
Starting Place | ||
-------------- | ||
|
||
Let's assume that you have a regular ``rclcpp::Node`` executable that you want to run in the same process as other nodes to enable more efficient communication. | ||
|
||
We'll start from having a class that directly inherits from ``Node``, and that also has a main method defined. | ||
|
||
.. code-block:: c++ | ||
|
||
namespace palomino | ||
{ | ||
class VincentDriver : public rclcpp::Node | ||
{ | ||
// ... | ||
}; | ||
} | ||
|
||
int main(int argc, char * argv[]) | ||
{ | ||
rclcpp::init(argc, argv); | ||
rclcpp::spin(std::make_shared<palomino::VincentDriver>()); | ||
rclcpp::shutdown(); | ||
return 0; | ||
} | ||
|
||
This will typically be compiled as an executable in your Cmake. | ||
|
||
.. code-block:: cmake | ||
|
||
# ... | ||
add_executable(vincent_driver src/vincent_driver.cpp) | ||
# ... | ||
install(TARGETS vincent_driver | ||
DESTINATION lib/${PROJECT_NAME} | ||
) | ||
|
||
Code Updates | ||
------------ | ||
|
||
Add the Package Dependency | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
Your `package.xml <https://github.com/ros2/demos/tree/{REPOS_FILE_BRANCH}/composition/package.xml>`__ should have a dependency on ``rclcpp_components``, a la | ||
|
||
.. code-block:: xml | ||
|
||
<depend>rclcpp_components</depend> | ||
|
||
Alternatively, you can independently add a ``build_depend/exec_depend``. | ||
|
||
Class Definition | ||
^^^^^^^^^^^^^^^^ | ||
|
||
The only change to your class definition that you may have to do is ensure that `the constructor for the class <https://github.com/ros2/demos/tree/{REPOS_FILE_BRANCH}/composition/src/talker_component.cpp>`__ takes a ``NodeOptions`` argument. | ||
|
||
.. code-block:: c++ | ||
|
||
VincentDriver(const rclcpp::NodeOptions & options) : Node("vincent_driver", options) | ||
{ | ||
// ... | ||
} | ||
|
||
No More Main Method | ||
^^^^^^^^^^^^^^^^^^^ | ||
|
||
Replace your main method with a ``pluginlib``-style macro invocation. | ||
|
||
.. code-block:: c++ | ||
|
||
#include <rclcpp_components/register_node_macro.hpp> | ||
RCLCPP_COMPONENTS_REGISTER_NODE(palomino::VincentDriver) | ||
|
||
.. caution:: | ||
If the main method you are replacing contains a ``MultiThreadedExecutor``, be sure to make note and ensure that your container node is multithreaded. | ||
See section below. | ||
|
||
CMake Changes | ||
^^^^^^^^^^^^^ | ||
First, add ``rclcpp_components`` as a dependency in your CMakeLists.txt with: | ||
|
||
.. code-block:: cmake | ||
|
||
find_package(rclcpp_components REQUIRED) | ||
DLu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Second, we're going to replace our ``add_executable`` with a ``add_library`` with a new target name. | ||
|
||
.. code-block:: cmake | ||
|
||
add_library(vincent_driver_component src/vincent_driver.cpp) | ||
|
||
Third, replace other build commands that used the old target to act on the new target. | ||
i.e. ``ament_target_dependencies(vincent_driver ...)`` becomes ``ament_target_dependencies(vincent_driver_component ...)`` | ||
|
||
Fourth, add a new command to declare your component. | ||
|
||
.. code-block:: cmake | ||
|
||
rclcpp_components_register_node( | ||
vincent_driver_component | ||
PLUGIN "palomino::VincentDriver" | ||
EXECUTABLE vincent_driver | ||
) | ||
|
||
Fifth and finally, change any installation commands in the CMake that operated on the old target to install the library version instead. | ||
For instance, do not install either target into ``lib/${PROJECT_NAME}``. | ||
Replace with the library installation. | ||
|
||
.. code-block:: cmake | ||
|
||
ament_export_targets(export_vincent_driver_component) | ||
install(TARGETS vincent_driver_component | ||
EXPORT export_vincent_driver_component | ||
ARCHIVE DESTINATION lib | ||
LIBRARY DESTINATION lib | ||
RUNTIME DESTINATION bin | ||
) | ||
|
||
|
||
Running Your Node | ||
----------------- | ||
|
||
See the :doc:`Composition tutorial <Composition>` for an in-depth look at composing nodes. | ||
The quick and dirty version is that if you had the following in your Python launch file, | ||
|
||
.. code-block:: python | ||
|
||
from launch_ros.actions import Node | ||
|
||
# .. | ||
|
||
ld.add_action(Node( | ||
package='palomino', | ||
executable='vincent_driver', | ||
# .. | ||
)) | ||
|
||
you can replace it with | ||
|
||
.. code-block:: python | ||
|
||
from launch_ros.actions import ComposableNodeContainer | ||
from launch_ros.descriptions import ComposableNode | ||
|
||
# .. | ||
ld.add_action(ComposableNodeContainer( | ||
name='a_buncha_nodes', | ||
namespace='', | ||
package='rclcpp_components', | ||
executable='component_container', | ||
composable_node_descriptions=[ | ||
ComposableNode( | ||
package='palomino', | ||
plugin='palomino::VincentDriver', | ||
name='vincent_driver', | ||
# .. | ||
extra_arguments=[{'use_intra_process_comms': True}], | ||
), | ||
] | ||
)) | ||
|
||
.. caution:: | ||
|
||
If you need multi-threading, instead of setting your executable to ``component_container``, set it to ``component_container_mt`` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on the fence about this one. I know the change targets
rolling
, but I think I'd prefer not to change the Dashing stuff at this point. So I'll suggest just removing this for now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only found this because I found it via grep when looking for an existing tutorial. I'm not tied to it, but if someone else stumbles on this page and wants to follow through with this, then I figure the extra link will be helpful.