# ros-jazzy-composition **Repository Path**: openkylin/ros-jazzy-composition ## Basic Information - **Project Name**: ros-jazzy-composition - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: openkylin/nile - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-29 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## What Is This? This demo provides examples of three different ways to use the **rclcpp_components** API to compose multiple nodes in a single process. This ROS 2 package consists of the following demo applications: 1. `dlopen_composition` 2. `linktime_composition` 3. `manual_composition` ## Build Run the commands below to build the ROS 2 package: ```bash colcon build --packages-up-to composition ``` ## Run ### Manual Composition Running `manual_composition` compiles an executable that runs the following 4 components: - **Talker**: A ROS 2 component that publishes a string - **Listener**: A ROS 2 component that prints the received string from **Talker** - **Server**: A ROS 2 component that adds two integers and outputs its result to **Client** - **Client**: A ROS 2 component that sends two integers to **Server** and prints the received result from **Server** ```bash ros2 run composition manual_composition ``` ### DlOpen Composition This runs `dlopen_composition` which is an alternative to run-time composition by creating a generic container process and explicitly passing the libraries to load without using ROS interfaces. The process will open each library and create one instance of each “rclcpp::Node” class in the library. ```bash ros2 run composition dlopen_composition `ros2 pkg prefix composition`/lib/libtalker_component.so `ros2 pkg prefix composition`/lib/liblistener_component.so ``` ### Linktime Composition (not supported on Windows) Similar to previous, this runs `linktime_composition` which **links all classes from libraries** that are registered under the **library_path** with the **linker**. ```bash ros2 run composition linktime_composition ``` ### Composition Using Launch Actions Rather than using the command line tool to run each composition, we can **automate this action** with `ros2 launch` functionality: ```bash ros2 launch composition composition_demo_launch.py ``` ## Verify ### Manual Composition When executed correctly, strings should be printed to terminal similar to what is shown below: ```bash [INFO] [1674528188.026468320] [talker]: Publishing: 'Hello World: 1' [INFO] [1674528188.027043857] [listener]: I heard: [Hello World: 1] [INFO] [1674528189.026414368] [talker]: Publishing: 'Hello World: 2' [INFO] [1674528189.026742015] [listener]: I heard: [Hello World: 2] [INFO] [1674528189.032512995] [Server]: Incoming request: [a: 2, b: 3] [INFO] [1674528189.032815843] [Client]: Got result: [5] [INFO] [1674528190.026455807] [talker]: Publishing: 'Hello World: 3' [INFO] [1674528190.026795770] [listener]: I heard: [Hello World: 3] [INFO] [1674528191.026457639] [talker]: Publishing: 'Hello World: 4' [INFO] [1674528191.026801926] [listener]: I heard: [Hello World: 4] [INFO] [1674528191.032377264] [Server]: Incoming request: [a: 2, b: 3] [INFO] [1674528191.032604427] [Client]: Got result: [5] [INFO] [1674528192.026428269] [talker]: Publishing: 'Hello World: 5' [INFO] [1674528192.026537974] [listener]: I heard: [Hello World: 5] [INFO] [1674528193.026437034] [talker]: Publishing: 'Hello World: 6' [INFO] [1674528193.026767708] [listener]: I heard: [Hello World: 6] [INFO] [1674528193.032377748] [Server]: Incoming request: [a: 2, b: 3] [INFO] [1674528193.032603036] [Client]: Got result: [5] #... ``` :warning: > Note that manually-composed components **will not be reflected in the `ros2 component list`** command line tool output. ### DlOpen Composition When executed correctly, strings should be printed to terminal similar to what is shown below: ```bash INFO] [1674529118.496557668] [dlopen_composition]: Load library /opt/ros/rolling/lib/libtalker_component.so [INFO] [1674529118.496774575] [dlopen_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674529118.503388909] [dlopen_composition]: Load library /opt/ros/rolling/lib/liblistener_component.so [INFO] [1674529118.503739855] [dlopen_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674529119.503505873] [talker]: Publishing: 'Hello World: 1' [INFO] [1674529119.503770137] [listener]: I heard: [Hello World: 1] [INFO] [1674529120.503572362] [talker]: Publishing: 'Hello World: 2' [INFO] [1674529120.503888374] [listener]: I heard: [Hello World: 2] [INFO] [1674529121.503503459] [talker]: Publishing: 'Hello World: 3' [INFO] [1674529121.503628269] [listener]: I heard: [Hello World: 3] [INFO] [1674529122.503557862] [talker]: Publishing: 'Hello World: 4' [INFO] [1674529122.503894772] [listener]: I heard: [Hello World: 4] [INFO] [1674529123.503574524] [talker]: Publishing: 'Hello World: 5' [INFO] [1674529123.503884894] [listener]: I heard: [Hello World: 5] #... ``` :warning: > Note that dlopen-composed components **will not be reflected in the `ros2 component list`** command line tool output. ### Linktime Composition When executed correctly, strings should be printed to terminal similar to what is shown below: ```bash [INFO] [1674528568.091949637] [linktime_composition]: Load library [INFO] [1674528568.091995119] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674528568.098833910] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674528568.100669644] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674528568.102665704] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate [INFO] [1674528569.104717098] [talker]: Publishing: 'Hello World: 1' [INFO] [1674528569.105206993] [listener]: I heard: [Hello World: 1] [INFO] [1674528570.099206827] [Server]: Incoming request: [a: 2, b: 3] [INFO] [1674528570.099376432] [Client]: Got result: [5] [INFO] [1674528570.104656875] [talker]: Publishing: 'Hello World: 2' [INFO] [1674528570.105069514] [listener]: I heard: [Hello World: 2] [INFO] [1674528571.104710545] [talker]: Publishing: 'Hello World: 3' [INFO] [1674528571.105150094] [listener]: I heard: [Hello World: 3] [INFO] [1674528572.099350955] [Server]: Incoming request: [a: 2, b: 3] [INFO] [1674528572.099628903] [Client]: Got result: [5] [INFO] [1674528572.104631322] [talker]: Publishing: 'Hello World: 4' [INFO] [1674528572.104911174] [listener]: I heard: [Hello World: 4] [INFO] [1674528573.104596009] [talker]: Publishing: 'Hello World: 5' [INFO] [1674528573.104751214] [listener]: I heard: [Hello World: 5] #... ``` :warning: > Note that linktime-composed components **will not be reflected in the `ros2 component list`** command line tool output. ### Composition Using Launch Actions When executed correctly, strings should be printed to terminal similar to what is shown below: ```bash [INFO] [launch]: All log files can be found below /root/.ros/log/2024-05-04-23-37-06-363020-d8ff93e471d7-9387 [INFO] [launch]: Default logging verbosity is set to INFO [INFO] [component_container-1]: process started with pid [9402] [component_container-1] [INFO] [1714865826.695090046] [my_container]: Load Library: /opt/ros/jazzy/lib/libtalker_component.so [component_container-1] [INFO] [1714865826.696388047] [my_container]: Found class: rclcpp_components::NodeFactoryTemplate [component_container-1] [INFO] [1714865826.696435882] [my_container]: Instantiate class: rclcpp_components::NodeFactoryTemplate [INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/talker' in container '/my_container' [component_container-1] [INFO] [1714865826.702958710] [my_container]: Load Library: /opt/ros/jazzy/lib/liblistener_component.so [component_container-1] [INFO] [1714865826.703401061] [my_container]: Found class: rclcpp_components::NodeFactoryTemplate [component_container-1] [INFO] [1714865826.703414344] [my_container]: Instantiate class: rclcpp_components::NodeFactoryTemplate [INFO] [launch_ros.actions.load_composable_nodes]: Loaded node '/listener' in container '/my_container' [component_container-1] [INFO] [1714865827.701941449] [talker]: Publishing: 'Hello World: 1' [component_container-1] [INFO] [1714865827.702047599] [listener]: I heard: [Hello World: 1] [component_container-1] [INFO] [1714865828.701984118] [talker]: Publishing: 'Hello World: 2' [component_container-1] [INFO] [1714865828.702154523] [listener]: I heard: [Hello World: 2] [component_container-1] [INFO] [1714865829.702004471] [talker]: Publishing: 'Hello World: 3' [component_container-1] [INFO] [1714865829.702176059] [listener]: I heard: [Hello World: 3] [component_container-1] [INFO] [1714865830.701876733] [talker]: Publishing: 'Hello World: 4' [component_container-1] [INFO] [1714865830.701965546] [listener]: I heard: [Hello World: 4] [component_container-1] [INFO] [1714865831.701885355] [talker]: Publishing: 'Hello World: 5' [component_container-1] [INFO] [1714865831.701984823] [listener]: I heard: [Hello World: 5] ``` ## FAQ `Q`: Why use node composition? `A`: Node composition avoids the overhead of marshalling and unmarshaling messages by allowing nodes to be instantiated within the same process. ## References 1. [Composing multiple nodes in a single process](https://docs.ros.org/en/rolling/Tutorials/Intermediate/Composition.html) 2. [About Composition](https://docs.ros.org/en/rolling/Concepts/About-Composition.html#about-composition)