-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added README.md for composition (#598)
* ➕ 📘 Added slightly elaborated README.md under composition ROS2 package. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Elaborated further Run and Verify instructions. Yet to include proper explainations for Run sub-sections. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Elaborated further Manual Composition section. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Elaborated fully README.md in composition ROS2 package. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Updated README.md further. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 🔥 Updated based on feedback. Removed link to Reference Life Cycle Node. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Updated to fix minor typo. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Updated based on feedback to improve phrasing and formating. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Removed bold from all headers. Signed-off-by: Bey Hao Yun <[email protected]> * 🔨 Updated based on feedback to correct phrasing. Signed-off-by: Bey Hao Yun <[email protected]> --------- Signed-off-by: Bey Hao Yun <[email protected]>
- Loading branch information
1 parent
570964e
commit c17d5fa
Showing
1 changed file
with
157 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
## 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 | ||
|
||
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<composition::Talker> | ||
[INFO] [1674529118.503388909] [dlopen_composition]: Load library /opt/ros/rolling/lib/liblistener_component.so | ||
[INFO] [1674529118.503739855] [dlopen_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate<composition::Listener> | ||
[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<composition::Client> | ||
[INFO] [1674528568.098833910] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate<composition::Listener> | ||
[INFO] [1674528568.100669644] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate<composition::Server> | ||
[INFO] [1674528568.102665704] [linktime_composition]: Instantiate class rclcpp_components::NodeFactoryTemplate<composition::Talker> | ||
[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. | ||
|
||
## 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) |