Skip to content
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

[ROS] Add Official Docker image for ROS2 #1381

Merged
merged 48 commits into from
Jun 6, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
8e1766c
Start docs for ROS 2 by duplicating those from ROS 1
ruffsl Nov 28, 2018
5fb5991
Update lichening information to reflect ROS 2
ruffsl Nov 28, 2018
d70ba62
Update intro
ruffsl Nov 29, 2018
f7bd0f2
Update example dockerfile and compose file
ruffsl Nov 29, 2018
66a3f10
Remove redundant walk through and skip to compose
ruffsl Nov 29, 2018
725cd24
Cleanup dockerfile example
ruffsl Nov 30, 2018
36501f9
Make dockerfile example a multistage build
ruffsl Nov 30, 2018
92406af
Create an install and build example
ruffsl Dec 13, 2018
bdd6d7d
Update body and links
ruffsl Dec 13, 2018
a7ed044
Update logo
ruffsl Dec 13, 2018
702f14d
Add security example
ruffsl Dec 14, 2018
3a66e1a
Add warnings about networking with ROS2/DDS
ruffsl Dec 14, 2018
db9791a
Fix compose file
ruffsl Dec 14, 2018
c1c457d
Fix Spelling
ruffsl Dec 14, 2018
b03d7d9
Remove duplicate files before merge
ruffsl Dec 15, 2018
40f09e8
Remove duplicate files before merge
ruffsl Dec 15, 2018
eb9d43c
Move changes for merge
ruffsl Dec 15, 2018
f4edbfb
Rewording to just reference latest ros release
ruffsl Dec 15, 2018
199e0a5
Fix markdown for CI
ruffsl Dec 15, 2018
347e32d
Provide sros2 cli in example and fix keystore permissions
ruffsl Dec 15, 2018
bbeff28
Fix Spelling
ruffsl Jun 27, 2019
332a6e8
Update example to use latest LTS tag
ruffsl Jun 27, 2019
3d1f775
Hold off on sros example
ruffsl Jun 27, 2019
8398e71
Update docs link to point to index.ros.org
ruffsl Jun 27, 2019
edb64bb
Merge branch 'master' into ros2
ruffsl Nov 27, 2019
a62f77d
Update Dockerfile build example
ruffsl Nov 27, 2019
e71b10d
Add links to target support reps
ruffsl Nov 27, 2019
1a14579
Update metrics
ruffsl Nov 27, 2019
a1c20bd
Add minimal ros1_bridge example
ruffsl Nov 27, 2019
32e1ffe
Fix Formatting
ruffsl Nov 27, 2019
6d09179
Update More Resources
ruffsl Apr 28, 2020
2cd312f
Dont split up ros version tokens for SEO
ruffsl Apr 28, 2020
966f6ae
Keep ros org landing page as main link
ruffsl Apr 28, 2020
f685e28
Update size given no-install-recommends changes
ruffsl Apr 28, 2020
379df84
Spell check
ruffsl Apr 28, 2020
66047eb
Update examples
ruffsl Apr 28, 2020
b4f8a13
Fix logging for python node
ruffsl Apr 28, 2020
23bf362
Link external license resources like other images
ruffsl Apr 28, 2020
cc17087
Stage changes to build example
ruffsl Apr 30, 2020
2316f47
Update example
ruffsl Apr 30, 2020
522d608
Add links to tools
ruffsl May 21, 2020
50a2c27
Link to relevent reps on variants
ruffsl May 21, 2020
dd187b9
Simplify example
ruffsl May 22, 2020
957be64
Update explanation of example
ruffsl May 22, 2020
2f8fd67
Fix markdown linter
ruffsl May 22, 2020
38e4286
Update tags to foxy and noetic
ruffsl May 22, 2020
c305016
Correct vcstool link
ruffsl May 26, 2020
cf84c67
Nit fix grammar
ruffsl May 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ros2/README-short.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The Robot Operating System (ROS) is an open source project for building robot applications.
325 changes: 325 additions & 0 deletions ros2/README.md

Large diffs are not rendered by default.

265 changes: 265 additions & 0 deletions ros2/content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# What is [ROS 2](https://index.ros.org/doc/ros2)?
ruffsl marked this conversation as resolved.
Show resolved Hide resolved

The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms, and with powerful developer tools, ROS has what you need for your next robotics project. And it's all open source. ROS 2 is the next-generation ROS: building upon modern middleware for decentralized discovery, message serialization, and secure transport with quality of service enabling high performance, low latency, language agnostic distributed computing for robotic systems.

> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System)

[%%LOGO%%](https://index.ros.org/doc/ros2)
ruffsl marked this conversation as resolved.
Show resolved Hide resolved

# How to use this image

## Creating a `Dockerfile` to install ROS 2 packages

To create your own ROS 2 docker images and install custom packages, here's a simple example of installing the C++ and Python client library demos using the official released Debian packages via apt-get.

```dockerfile
FROM %%IMAGE%%:ros-core

# install ros packages for installed release
RUN apt-get update && apt-get install -y \
ros-${ROS_DISTRO}-demo-nodes-cpp \
ros-${ROS_DISTRO}-demo-nodes-py && \
rm -rf /var/lib/apt/lists/*

# run ros packge launch file
CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"]
```

Note: all ROS 2 images include a default entrypoint that sources the ROS environment setup before exiting the configured command, in this case the demo packages launch file. You can then build and run the Docker image like so:

```console
$ docker build -t my/ros2:app .
$ docker run -it --rm my/ros2:app
[INFO] [launch]: process[talker-1]: started with pid [813]
[INFO] [launch]: process[listener-2]: started with pid [814]
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [listener]: I heard: [Hello World: 1]
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [listener]: I heard: [Hello World: 2]
...
```

## Creating a `Dockerfile` to build ROS 2 packages

To create your own ROS 2 docker images and build custom packages, here's a simple example of installing a package's build dependencies, compiling it from source, and installing the resulting build artifacts into a final multi-stage image layer.

```dockerfile
FROM %%IMAGE%%:ros-base

# install ros build tools
RUN apt-get update && apt-get install -y \
python3-colcon-common-extensions && \
rm -rf /var/lib/apt/lists/*

# clone ros package repo
ENV ROS2_WS /opt/ros2_ws
RUN mkdir -p $ROS2_WS/src
WORKDIR $ROS2_WS
RUN git -C src clone \
-b $ROS_DISTRO \
https://github.com/ros2/demos.git

# install ros package dependencies
RUN apt-get update && \
rosdep update && \
rosdep install -y \
--from-paths \
src/demos/demo_nodes_cpp \
--ignore-src && \
rm -rf /var/lib/apt/lists/*

# build ros package source
RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
colcon build \
--packages-select \
demo_nodes_cpp \
--cmake-args \
-DCMAKE_BUILD_TYPE=Release

# copy ros package install via multi-stage
FROM %%IMAGE%%:ros-core
ENV ROS2_WS /opt/ros2_ws
COPY --from=0 $ROS2_WS/install $ROS2_WS/install
ruffsl marked this conversation as resolved.
Show resolved Hide resolved

# source ros package from entrypoint
RUN sed --in-place --expression \
'$isource "$ROS2_WS/install/setup.bash"' \
/ros2_entrypoint.sh

# run ros packge launch file
CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"]
```

Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the `demo_nodes_cpp` package, one among many in the demo git repo that was cloned. To install the dependencies and build all the packages in the source workspace, merely change the scope by setting `--from-paths src/` and dropping the `--packages-select` arguments.

```
REPOSITORY TAG IMAGE ID CREATED SIZE
my/ros2 app-multi-stage 66c8112b2fb6 4 seconds ago 775MB
my/ros2 app-single-stage 6b500239d0d6 2 minutes ago 797MB
```

For this particular package, using a multi-stage build didn't shrink the final image by much, but for more complex applications, segmenting build setup from the runtime can help keep image sizes down. Additionally, doing so can also prepare you for releasing your package to the community, helping to reconcile dependency discrepancies you may have otherwise forgotten to declare in your `package.xml` manifest.

## Deployment use cases

This dockerized image of ROS 2 is intended to provide a simplified and consistent platform to build and deploy distributed robotic applications. Built from the [official Ubuntu image](https://hub.docker.com/_/ubuntu/) and ROS's official Debian packages, it includes recent supported releases for quick access and download. This provides roboticists in research and industry with an easy way to develop, reuse and ship software for autonomous actions and task planning, control dynamics, localization and mapping, swarm behavior, as well as general system integration.

Developing such complex systems with cutting edge implementations of newly published algorithms remains challenging, as repeatability and reproducibility of robotic software can fall to the wayside in the race to innovate. With the added difficulty in coding, tuning and deploying multiple software components that span across many engineering disciplines, a more collaborative approach becomes attractive. However, the technical difficulties in sharing and maintaining a collection of software over multiple robots and platforms has for a while exceeded time and effort than many smaller labs and businesses could afford.

With the advancements and standardization of software containers, roboticists are primed to acquire a host of improved developer tooling for building and shipping software. To help alleviate the growing pains and technical challenges of adopting new practices, we have focused on providing an official resource for using ROS with these new technologies.

## Deployment suggestions

The available tags include supported distros along with a hierarchy tags based off the most common meta-package dependencies, designed to have a small footprint and simple configuration:

- `ros-core`: barebone ROS 2 install
- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`)

The rest of the common meta-packages such as `desktop` and `ros1-bridge` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros2/). These meta-packages include graphical dependencies and hook a host of other large packages such as X11, X server, etc. So in the interest of keep the official images lean and secure, the desktop packages are just be hosted with OSRF's profile.

### Volumes

ROS uses the `~/.ros/` directory for storing logs, and debugging info. If you wish to persist these files beyond the lifecycle of the containers which produced them, the `~/.ros/` folder can be mounted to an external volume on the host, or a derived image can specify volumes to be managed by the Docker engine. By default, the container runs as the `root` user, so `/root/.ros/` would be the full path to these files.

For example, if one wishes to use their own `.ros` folder that already resides in their local home directory, with a username of `ubuntu`, we can simple launch the container with an additional volume argument:

```console
$ docker run -v "/home/ubuntu/.ros/:/root/.ros/" %%IMAGE%%
```

### Devices

Some application may require device access for acquiring images from connected cameras, control input from human interface device, or GPUS for hardware acceleration. This can be done using the [`--device`](https://docs.docker.com/reference/run/) run argument to mount the device inside the container, providing processes inside hardware access.

### Networks

ROS 2 allows for peer-to-peer networking of processes (potentially distributed across machines) that are loosely coupled using the ROS communication infrastructure. ROS implements several different styles of communication, including synchronous RPC-style communication over services, asynchronous streaming of typed data over topics, combinations of both prior via request/reply and status/feedback over actions, and run-time settings via configuration over parameters. To abide by the best practice of [one process per container](https://docs.docker.com/articles/dockerfile_best-practices/), Docker networks can be used to string together several running ROS processes. For further details see the Deployment example further below.

Alternatively, more permissive network setting can be use to share all host network interfaces with the container, such as [`host` network driver](https://docs.docker.com/network/host/), simplifying connectivity with external network participants. Be aware however that this removes the networking namespace separation between containers, and can affect the ability of DDS participants communicate between containers, as documented [here](https://community.rti.com/kb/how-use-rti-connext-dds-communicate-across-docker-containers-using-host-driver).

## Deployment example

### Docker Compose

In this example we'll demonstrate using [`docker-compose`](https://docs.docker.com/compose/) to spawn a pair of message publisher and subscriber nodes in seperate containers connected through shared software defined network.

> Create the directory `~/ros2_demos` and add the first `Dockerfile` example from above. In the same directory, also create file `docker-compose.yml` with the following that runs a C++ publisher with a Python subscriber:

```yaml
version: '3'

services:
talker:
build: ./Dockerfile
command: ros2 run demo_nodes_cpp talker

listener:
build: ./Dockerfile
command: ros2 run demo_nodes_py listener
```

> Use docker-copose inside the same directory to launch our ROS nodes. Given the containers created derive from the same docker compose project, they will coexist on shared project network:

```console
$ docker-compose up -d
```

> Notice that a new network named `ros2_demos` has been created, as can be shown further with:
ruffsl marked this conversation as resolved.
Show resolved Hide resolved

```console
$ docker network inspect ros2_demos
```

> We can monitor the logged output of each container, such as the listener node like so:

```console
$ docker-compose logs listener
```

> Finally, we can stop and remove all the relevant containers using docker-compose from the same directory:

```console
$ docker-compose stop
$ docker-compose rm
```

> Note: the auto-generated network, `ros2_demos`, will persist until you explicitly remove it using `docker-compose down`.


### Securing ROS 2

Lets build upon the example above by adding authenticated encryption to the message transport. This is done by leveraging [Secure DDS](https://www.omg.org/spec/DDS-SECURITY). We'll use the same ROS 2 docker image to bootstrap the PKI, CAs, and Digitally Signed files.

> Create a script at `~/ros2_demos/keystore/bootstrap_keystore.bash` to bootstrap a keystore and add entries for each node:

``` shell
#!/usr/bin/env bash
# Bootstrap ROS 2 keystore
ros2 security create_keystore ./
ros2 security create_key ./ talker
ros2 security create_key ./ listener
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
```

> Create a enforcement file at `~/ros2_demos/config.env` to configure ROS 2 Security:


``` shell
# Configure ROS 2 Security
ROS_SECURITY_NODE_DIRECTORY=/keystore
ROS_SECURITY_STRATEGY=Enforce
ROS_SECURITY_ENABLE=true
ROS_DOMAIN_ID=0
```

> Use a temporary container to run the keystore bootstraping script in the keystore directory:


```console
$ docker run -it --rm \
--env-file ./config.env \
--volume ./keystore:/keystore:rw \
--workdir /keystore \
ros2 bash bootstrap_keystore.bash
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
```

> Now modify the original `docker-compose.yml` to use the configured environment and respective keystore entries:

```yaml
version: '3'

services:
talker:
build: ./Dockerfile
environment:
- ./config.env
volumes:
- ./keystore/talker:/keystore:ro
command: ros2 run demo_nodes_cpp talker

listener:
build: ./Dockerfile
environment:
- ./config.env
volumes:
- ./keystore/listener:/keystore:ro
command: ros2 run demo_nodes_py listener
```

> Now simply startup docker-compose as before:

``` command
$ docker-compose up
```

Note: So far this has only added authenticated encryption, i.e. only participants with public certificates signed by a trusted CA may join the domain. To enable access control within the secure domain, i.e. restrict which and how topics may be used by participants, more such details can be found [here](https://github.com/ros2/sros2/).

# More Resources

[ROS.org](http://www.ros.org/): Main ROS website
[Docs](https://docs.ros2.org/): Core Documentation
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
[Index](https://index.ros.org/doc/ros2/): Package Index
[Design](https://design.ros2.org/): Design Articles
[ROS Answers](https://answers.ros.org/questions/): Ask questions. Get answers
[Forums](https://discourse.ros.org/): Hear the latest discussions
[Blog](http://www.ros.org/news/): Stay up-to-date
[OSRF](https://www.osrfoundation.org/): Open Source Robotics Foundation
1 change: 1 addition & 0 deletions ros2/github-repo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/osrf/docker_images
3 changes: 3 additions & 0 deletions ros2/license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
The core of ROS 2 is licensed under the Apache License 2.0. This is a very permissive open license that allows for modification, distribution, commercial use, patent use, and private use in open and closed source products. You can find more about the license from the [Apache License](https://www.apache.org/licenses) website or Opensource.org [Apache License 2.0](https://opensource.org/licenses/Apache-2.0) page.

While the core parts of ROS 2 are licensed under the Apache 2.0 license, other licenses are commonly used in the community packages, such as the [BSD 3-Clause](https://opensource.org/licenses/BSD-3-Clause) license, the [GPL](https://opensource.org/licenses/gpl-license) license, the [MIT](https://opensource.org/licenses/MIT) license, and even proprietary licenses. Each package in the ROS ecosystem is required to specify a license, so that it is easy for you to quickly identify if a package will meet your licensing needs.
Binary file added ros2/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ros2/maintainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[the Open Source Robotics Foundation](%%GITHUB-REPO%%)