Skip to content

Commit

Permalink
Added README.md for composition (#598)
Browse files Browse the repository at this point in the history
* ➕ 📘 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
cardboardcode authored Feb 7, 2023
1 parent 570964e commit c17d5fa
Showing 1 changed file with 157 additions and 0 deletions.
157 changes: 157 additions & 0 deletions composition/README.md
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)

0 comments on commit c17d5fa

Please sign in to comment.