From 8e1766ce3eaad6cca5a21eda1c97fc1e4191b622 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Wed, 28 Nov 2018 02:05:57 -0800 Subject: [PATCH 01/47] Start docs for ROS 2 by duplicating those from ROS 1 --- ros2/README-short.txt | 1 + ros2/README.md | 325 ++++++++++++++++++++++++++++++++++++++++++ ros2/content.md | 242 +++++++++++++++++++++++++++++++ ros2/github-repo | 1 + ros2/license.md | 3 + ros2/logo.png | Bin 0 -> 7197 bytes ros2/maintainer.md | 1 + 7 files changed, 573 insertions(+) create mode 100644 ros2/README-short.txt create mode 100644 ros2/README.md create mode 100644 ros2/content.md create mode 100644 ros2/github-repo create mode 100644 ros2/license.md create mode 100644 ros2/logo.png create mode 100644 ros2/maintainer.md diff --git a/ros2/README-short.txt b/ros2/README-short.txt new file mode 100644 index 000000000000..c59ed8f6c183 --- /dev/null +++ b/ros2/README-short.txt @@ -0,0 +1 @@ +The Robot Operating System (ROS) is an open source project for building robot applications. diff --git a/ros2/README.md b/ros2/README.md new file mode 100644 index 000000000000..0ff58b3d4fda --- /dev/null +++ b/ros2/README.md @@ -0,0 +1,325 @@ + + +# Supported tags and respective `Dockerfile` links + +- [`indigo-ros-core`, `indigo-ros-core-trusty` (*ros/indigo/ubuntu/trusty/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/ros-core/Dockerfile) +- [`indigo-ros-base`, `indigo-ros-base-trusty`, `indigo` (*ros/indigo/ubuntu/trusty/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/ros-base/Dockerfile) +- [`indigo-robot`, `indigo-robot-trusty` (*ros/indigo/ubuntu/trusty/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/robot/Dockerfile) +- [`indigo-perception`, `indigo-perception-trusty` (*ros/indigo/ubuntu/trusty/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/perception/Dockerfile) +- [`kinetic-ros-core`, `kinetic-ros-core-xenial` (*ros/kinetic/ubuntu/xenial/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/ros-core/Dockerfile) +- [`kinetic-ros-base`, `kinetic-ros-base-xenial`, `kinetic` (*ros/kinetic/ubuntu/xenial/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/ros-base/Dockerfile) +- [`kinetic-robot`, `kinetic-robot-xenial` (*ros/kinetic/ubuntu/xenial/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/robot/Dockerfile) +- [`kinetic-perception`, `kinetic-perception-xenial` (*ros/kinetic/ubuntu/xenial/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/perception/Dockerfile) +- [`lunar-ros-core`, `lunar-ros-core-xenial` (*ros/lunar/ubuntu/xenial/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/ros-core/Dockerfile) +- [`lunar-ros-base`, `lunar-ros-base-xenial`, `lunar` (*ros/lunar/ubuntu/xenial/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/ros-base/Dockerfile) +- [`lunar-robot`, `lunar-robot-xenial` (*ros/lunar/ubuntu/xenial/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/robot/Dockerfile) +- [`lunar-perception`, `lunar-perception-xenial` (*ros/lunar/ubuntu/xenial/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/perception/Dockerfile) +- [`lunar-ros-core-stretch` (*ros/lunar/debian/stretch/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/ros-core/Dockerfile) +- [`lunar-ros-base-stretch` (*ros/lunar/debian/stretch/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/ros-base/Dockerfile) +- [`lunar-robot-stretch` (*ros/lunar/debian/stretch/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/robot/Dockerfile) +- [`lunar-perception-stretch` (*ros/lunar/debian/stretch/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/perception/Dockerfile) +- [`melodic-ros-core`, `melodic-ros-core-bionic` (*ros/melodic/ubuntu/bionic/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/ros-core/Dockerfile) +- [`melodic-ros-base`, `melodic-ros-base-bionic`, `melodic`, `latest` (*ros/melodic/ubuntu/bionic/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/ros-base/Dockerfile) +- [`melodic-robot`, `melodic-robot-bionic` (*ros/melodic/ubuntu/bionic/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/robot/Dockerfile) +- [`melodic-perception`, `melodic-perception-bionic` (*ros/melodic/ubuntu/bionic/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/perception/Dockerfile) +- [`melodic-ros-core-stretch` (*ros/melodic/debian/stretch/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/ros-core/Dockerfile) +- [`melodic-ros-base-stretch` (*ros/melodic/debian/stretch/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/ros-base/Dockerfile) +- [`melodic-robot-stretch` (*ros/melodic/debian/stretch/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/robot/Dockerfile) +- [`melodic-perception-stretch` (*ros/melodic/debian/stretch/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/perception/Dockerfile) + +# Quick reference + +- **Where to get help**: + [the Docker Community Forums](https://forums.docker.com/), [the Docker Community Slack](https://blog.docker.com/2016/11/introducing-docker-community-directory-docker-community-slack/), or [Stack Overflow](https://stackoverflow.com/search?tab=newest&q=docker) + +- **Where to file issues**: + [https://github.com/osrf/docker_images/issues](https://github.com/osrf/docker_images/issues) + +- **Maintained by**: + [the Open Source Robotics Foundation](https://github.com/osrf/docker_images) + +- **Supported architectures**: ([more info](https://github.com/docker-library/official-images#architectures-other-than-amd64)) + [`amd64`](https://hub.docker.com/r/amd64/ros/), [`arm32v7`](https://hub.docker.com/r/arm32v7/ros/), [`arm64v8`](https://hub.docker.com/r/arm64v8/ros/) + +- **Published image artifact details**: + [repo-info repo's `repos/ros/` directory](https://github.com/docker-library/repo-info/blob/master/repos/ros) ([history](https://github.com/docker-library/repo-info/commits/master/repos/ros)) + (image metadata, transfer size, etc) + +- **Image updates**: + [official-images PRs with label `library/ros`](https://github.com/docker-library/official-images/pulls?q=label%3Alibrary%2Fros) + [official-images repo's `library/ros` file](https://github.com/docker-library/official-images/blob/master/library/ros) ([history](https://github.com/docker-library/official-images/commits/master/library/ros)) + +- **Source of this description**: + [docs repo's `ros/` directory](https://github.com/docker-library/docs/tree/master/ros) ([history](https://github.com/docker-library/docs/commits/master/ros)) + +- **Supported Docker versions**: + [the latest release](https://github.com/docker/docker-ce/releases/latest) (down to 1.6 on a best-effort basis) + +# What is [ROS](http://www.ros.org/)? + +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. + +> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) + +[![logo](https://raw.githubusercontent.com/docker-library/docs/0074e9dac72a35e5058f356885121aa82572682f/ros/logo.png)](http://www.ros.org/) + +# How to use this image + +## Create a `Dockerfile` in your ROS app project + +```dockerfile +FROM ros:indigo +# place here your application's setup specifics +CMD [ "roslaunch", "my-ros-app my-ros-app.launch" ] +``` + +You can then build and run the Docker image: + +```console +$ docker build -t my-ros-app . +$ docker run -it --rm --name my-running-app my-ros-app +``` + +## Deployment use cases + +This dockerized image of ROS 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 install +- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) +- `robot`: basic install for robots +- `perception`: basic install for perception tasks + +The rest of the common meta-packages such as `desktop` and `desktop-full` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros/). 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/" ros +``` + +### 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 + +The ROS runtime "graph" is a peer-to-peer network 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 data over topics, and storage of data on a Parameter Server. 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 about [ROS NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup) wik article, or see the Deployment example below. + +## Deployment example + +If we want our all ROS nodes to easily talk to each other, we'll can use a virtual network to connect the separate containers. In this short example, we'll create a virtual network, spin up a new container running `roscore` advertised as the `master` service on the new network, then spawn a message publisher and subscriber process as services on the same network. + +### Build image + +> Build a ROS image that includes ROS tutorials using this `Dockerfile:` + +```dockerfile +FROM ros:indigo-ros-base +# install ros tutorials packages +RUN apt-get update && apt-get install -y \ + ros-indigo-ros-tutorials \ + ros-indigo-common-tutorials \ + && rm -rf /var/lib/apt/lists/ +``` + +> Then to build the image from within the same directory: + +```console +$ docker build --tag ros:ros-tutorials . +``` + +#### Create network + +> To create a new network `foo`, we use the network command: + + docker network create foo + +> Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We'll use this make sure our ROS nodes can find and connect to our ROS `master`. + +#### Run services + +> To create a container for the ROS master and advertise it's service: + +```console +$ docker run -it --rm \ + --net foo \ + --name master \ + ros:ros-tutorials \ + roscore +``` + +> Now you can see that master is running and is ready manage our other ROS nodes. To add our `talker` node, we'll need to point the relevant environment variable to the master service: + +```console +$ docker run -it --rm \ + --net foo \ + --name talker \ + --env ROS_HOSTNAME=talker \ + --env ROS_MASTER_URI=http://master:11311 \ + ros:ros-tutorials \ + rosrun roscpp_tutorials talker +``` + +> Then in another terminal, run the `listener` node similarly: + +```console +$ docker run -it --rm \ + --net foo \ + --name listener \ + --env ROS_HOSTNAME=listener \ + --env ROS_MASTER_URI=http://master:11311 \ + ros:ros-tutorials \ + rosrun roscpp_tutorials listener +``` + +> Alright! You should see `listener` is now echoing each message the `talker` broadcasting. You can then list the containers and see something like this: + +```console +$ docker service ls +SERVICE ID NAME NETWORK CONTAINER +67ce73355e67 listener foo a62019123321 +917ee622d295 master foo f6ab9155fdbe +7f5a4748fb8d talker foo e0da2ee7570a +``` + +> And for the services: + +```console +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a62019123321 ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp listener +e0da2ee7570a ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp talker +f6ab9155fdbe ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp master +``` + +#### Introspection + +> Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are: + +```console +$ docker exec -it master bash +$ source /ros_entrypoint.sh +``` + +> If we then use `rostopic` to list published message topics, we should see something like this: + +```console +$ rostopic list +/chatter +/rosout +/rosout_agg +``` + +#### Tear down + +> To tear down the structure we've made, we just need to stop the containers and the services. We can stop and remove the containers using `Ctrl^C` where we launched the containers or using the stop command with the names we gave them: + +```console +$ docker stop master talker listener +$ docker rm master talker listener +``` + +### Compose + +Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. + +> Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: + +```yaml +version: '2' +services: + master: + build: . + container_name: master + command: + - roscore + + talker: + build: . + container_name: talker + environment: + - "ROS_HOSTNAME=talker" + - "ROS_MASTER_URI=http://master:11311" + command: rosrun roscpp_tutorials talker + + listener: + build: . + container_name: listener + environment: + - "ROS_HOSTNAME=listener" + - "ROS_MASTER_URI=http://master:11311" + command: rosrun roscpp_tutorials listener +``` + +> Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: + +```console +$ docker-compose up -d +``` + +> Notice that a new network named `rostutorials_default` has now been created, you can inspect it further with: + +```console +$ docker network inspect rostutorials_default +``` + +> We can monitor the logged output of each service, such as the listener node like so: + +```console +$ docker-compose logs listener +``` + +> Finally, we can stop and remove all the relevant containers using docker-copose from the same directory: + +```console +$ docker-compose stop +$ docker-compose rm +``` + +> Note: the auto-generated network, `rostutorials_default`, will persist over the life of the docker engine or until you explicitly remove it using [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\. + +# More Resources + +[ROS.org](http://www.ros.org/): Main ROS website +[Wiki](http://wiki.ros.org/): Find tutorials and learn more +[ROS Answers](http://answers.ros.org/questions/): Ask questions. Get answers +[Blog](http://www.ros.org/news/): Stay up-to-date +[OSRF](http://www.osrfoundation.org/): Open Source Robotics Foundation + +# License + +The core of ROS is licensed under the standard three-clause BSD license. This is a very permissive open license that allows for reuse in commercial and closed source products. You can find more about the BSD license from the Opensource.org [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) page and Wikipedia's [BSD Licenses](http://en.wikipedia.org/wiki/BSD_licenses) entry. + +While the core parts of ROS are licensed under the BSD license, other licenses are commonly used in the community packages, such as the [Apache 2.0](http://opensource.org/licenses/Apache-2.0) license, the [GPL](http://opensource.org/licenses/gpl-license) license, the [MIT](http://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. + +As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained). + +Some additional license information which was able to be auto-detected might be found in [the `repo-info` repository's `ros/` directory](https://github.com/docker-library/repo-info/tree/master/repos/ros). + +As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. diff --git a/ros2/content.md b/ros2/content.md new file mode 100644 index 000000000000..35a4a7d48b2e --- /dev/null +++ b/ros2/content.md @@ -0,0 +1,242 @@ +# What is [ROS](http://www.ros.org/)? + +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. + +> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) + +[%%LOGO%%](http://www.ros.org/) + +# How to use this image + +## Create a `Dockerfile` in your ROS app project + +```dockerfile +FROM %%IMAGE%%:indigo +# place here your application's setup specifics +CMD [ "roslaunch", "my-ros-app my-ros-app.launch" ] +``` + +You can then build and run the Docker image: + +```console +$ docker build -t my-ros-app . +$ docker run -it --rm --name my-running-app my-ros-app +``` + +## Deployment use cases + +This dockerized image of ROS 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 install +- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) +- `robot`: basic install for robots +- `perception`: basic install for perception tasks + +The rest of the common meta-packages such as `desktop` and `desktop-full` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros/). 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 + +The ROS runtime "graph" is a peer-to-peer network 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 data over topics, and storage of data on a Parameter Server. 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 about [ROS NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup) wik article, or see the Deployment example below. + +## Deployment example + +If we want our all ROS nodes to easily talk to each other, we'll can use a virtual network to connect the separate containers. In this short example, we'll create a virtual network, spin up a new container running `roscore` advertised as the `master` service on the new network, then spawn a message publisher and subscriber process as services on the same network. + +### Build image + +> Build a ROS image that includes ROS tutorials using this `Dockerfile:` + +```dockerfile +FROM %%IMAGE%%:indigo-ros-base +# install ros tutorials packages +RUN apt-get update && apt-get install -y \ + ros-indigo-ros-tutorials \ + ros-indigo-common-tutorials \ + && rm -rf /var/lib/apt/lists/ +``` + +> Then to build the image from within the same directory: + +```console +$ docker build --tag %%IMAGE%%:ros-tutorials . +``` + +#### Create network + +> To create a new network `foo`, we use the network command: + + docker network create foo + +> Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We'll use this make sure our ROS nodes can find and connect to our ROS `master`. + +#### Run services + +> To create a container for the ROS master and advertise it's service: + +```console +$ docker run -it --rm \ + --net foo \ + --name master \ + %%IMAGE%%:ros-tutorials \ + roscore +``` + +> Now you can see that master is running and is ready manage our other ROS nodes. To add our `talker` node, we'll need to point the relevant environment variable to the master service: + +```console +$ docker run -it --rm \ + --net foo \ + --name talker \ + --env ROS_HOSTNAME=talker \ + --env ROS_MASTER_URI=http://master:11311 \ + %%IMAGE%%:ros-tutorials \ + rosrun roscpp_tutorials talker +``` + +> Then in another terminal, run the `listener` node similarly: + +```console +$ docker run -it --rm \ + --net foo \ + --name listener \ + --env ROS_HOSTNAME=listener \ + --env ROS_MASTER_URI=http://master:11311 \ + %%IMAGE%%:ros-tutorials \ + rosrun roscpp_tutorials listener +``` + +> Alright! You should see `listener` is now echoing each message the `talker` broadcasting. You can then list the containers and see something like this: + +```console +$ docker service ls +SERVICE ID NAME NETWORK CONTAINER +67ce73355e67 listener foo a62019123321 +917ee622d295 master foo f6ab9155fdbe +7f5a4748fb8d talker foo e0da2ee7570a +``` + +> And for the services: + +```console +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a62019123321 ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp listener +e0da2ee7570a ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp talker +f6ab9155fdbe ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp master +``` + +#### Introspection + +> Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are: + +```console +$ docker exec -it master bash +$ source /ros_entrypoint.sh +``` + +> If we then use `rostopic` to list published message topics, we should see something like this: + +```console +$ rostopic list +/chatter +/rosout +/rosout_agg +``` + +#### Tear down + +> To tear down the structure we've made, we just need to stop the containers and the services. We can stop and remove the containers using `Ctrl^C` where we launched the containers or using the stop command with the names we gave them: + +```console +$ docker stop master talker listener +$ docker rm master talker listener +``` + +### Compose + +Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. + +> Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: + +```yaml +version: '2' +services: + master: + build: . + container_name: master + command: + - roscore + + talker: + build: . + container_name: talker + environment: + - "ROS_HOSTNAME=talker" + - "ROS_MASTER_URI=http://master:11311" + command: rosrun roscpp_tutorials talker + + listener: + build: . + container_name: listener + environment: + - "ROS_HOSTNAME=listener" + - "ROS_MASTER_URI=http://master:11311" + command: rosrun roscpp_tutorials listener +``` + +> Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: + +```console +$ docker-compose up -d +``` + +> Notice that a new network named `rostutorials_default` has now been created, you can inspect it further with: + +```console +$ docker network inspect rostutorials_default +``` + +> We can monitor the logged output of each service, such as the listener node like so: + +```console +$ docker-compose logs listener +``` + +> Finally, we can stop and remove all the relevant containers using docker-copose from the same directory: + +```console +$ docker-compose stop +$ docker-compose rm +``` + +> Note: the auto-generated network, `rostutorials_default`, will persist over the life of the docker engine or until you explicitly remove it using [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\. + +# More Resources + +[ROS.org](http://www.ros.org/): Main ROS website +[Wiki](http://wiki.ros.org/): Find tutorials and learn more +[ROS Answers](http://answers.ros.org/questions/): Ask questions. Get answers +[Blog](http://www.ros.org/news/): Stay up-to-date +[OSRF](http://www.osrfoundation.org/): Open Source Robotics Foundation diff --git a/ros2/github-repo b/ros2/github-repo new file mode 100644 index 000000000000..7b29247ab4b4 --- /dev/null +++ b/ros2/github-repo @@ -0,0 +1 @@ +https://github.com/osrf/docker_images diff --git a/ros2/license.md b/ros2/license.md new file mode 100644 index 000000000000..aa8b87126e6d --- /dev/null +++ b/ros2/license.md @@ -0,0 +1,3 @@ +The core of ROS is licensed under the standard three-clause BSD license. This is a very permissive open license that allows for reuse in commercial and closed source products. You can find more about the BSD license from the Opensource.org [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) page and Wikipedia's [BSD Licenses](http://en.wikipedia.org/wiki/BSD_licenses) entry. + +While the core parts of ROS are licensed under the BSD license, other licenses are commonly used in the community packages, such as the [Apache 2.0](http://opensource.org/licenses/Apache-2.0) license, the [GPL](http://opensource.org/licenses/gpl-license) license, the [MIT](http://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. diff --git a/ros2/logo.png b/ros2/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..637cc37dede2ae075f19c886622096185399ab87 GIT binary patch literal 7197 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 xvw){K=*4ZXg+{J^=w)aDH Date: Wed, 28 Nov 2018 02:07:12 -0800 Subject: [PATCH 02/47] Update lichening information to reflect ROS 2 --- ros2/license.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ros2/license.md b/ros2/license.md index aa8b87126e6d..6d10681baea5 100644 --- a/ros2/license.md +++ b/ros2/license.md @@ -1,3 +1,3 @@ -The core of ROS is licensed under the standard three-clause BSD license. This is a very permissive open license that allows for reuse in commercial and closed source products. You can find more about the BSD license from the Opensource.org [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) page and Wikipedia's [BSD Licenses](http://en.wikipedia.org/wiki/BSD_licenses) entry. +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 are licensed under the BSD license, other licenses are commonly used in the community packages, such as the [Apache 2.0](http://opensource.org/licenses/Apache-2.0) license, the [GPL](http://opensource.org/licenses/gpl-license) license, the [MIT](http://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. +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. From d70ba62bbb83a684d30ab6f3c9c6151c31ba1a69 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 29 Nov 2018 01:14:39 -0800 Subject: [PATCH 03/47] Update intro --- ros2/content.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 35a4a7d48b2e..77db383f9a74 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -1,10 +1,10 @@ -# What is [ROS](http://www.ros.org/)? +# What is [ROS 2](https://index.ros.org/doc/ros2)? -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. +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%%](http://www.ros.org/) +[%%LOGO%%](https://index.ros.org/doc/ros2) # How to use this image @@ -25,7 +25,7 @@ $ docker run -it --rm --name my-running-app my-ros-app ## Deployment use cases -This dockerized image of ROS 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. +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. @@ -35,12 +35,10 @@ With the advancements and standardization of software containers, roboticists ar 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 install +- `ros-core`: barebone ROS 2 install - `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) -- `robot`: basic install for robots -- `perception`: basic install for perception tasks -The rest of the common meta-packages such as `desktop` and `desktop-full` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros/). 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. +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 From f7bd0f2cc827c63522a48ec4035282c80e18535c Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 29 Nov 2018 01:18:43 -0800 Subject: [PATCH 04/47] Update example dockerfile and compose file --- ros2/content.md | 107 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 77db383f9a74..6e0be8cfe94e 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -8,19 +8,61 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h # How to use this image -## Create a `Dockerfile` in your ROS app project +## Creating a `Dockerfile` to build your ROS 2 packages ```dockerfile -FROM %%IMAGE%%:indigo -# place here your application's setup specifics -CMD [ "roslaunch", "my-ros-app my-ros-app.launch" ] +FROM %%IMAGE%% + +# install ros build tools +RUN apt-get update && apt-get install -y --no-install-recommends \ + git \ + python3-colcon-common-extensions \ + python3-rosdep \ + python3-vcstool && \ + 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 +ENV ROSDISTRO_INDEX_URL https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml +RUN apt-get update && \ + rosdep init && \ + 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 \ + --symlink-install \ + --packages-select \ + demo_nodes_cpp \ + --cmake-args \ + -DCMAKE_BUILD_TYPE=Release + +# source ros package install +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" ] ``` You can then build and run the Docker image: ```console -$ docker build -t my-ros-app . -$ docker run -it --rm --name my-running-app my-ros-app +$ docker build -t my/ros2:app . +$ docker run -it --rm my/ros2:app ``` ## Deployment use cases @@ -64,14 +106,14 @@ If we want our all ROS nodes to easily talk to each other, we'll can use a virtu ### Build image -> Build a ROS image that includes ROS tutorials using this `Dockerfile:` +> Create a `Dockerfile` that installs ROS 2 demos: ```dockerfile -FROM %%IMAGE%%:indigo-ros-base -# install ros tutorials packages +FROM %%IMAGE%% +# install ros 2 demo packages RUN apt-get update && apt-get install -y \ - ros-indigo-ros-tutorials \ - ros-indigo-common-tutorials \ + ros-${ROS_DISTRO}-demo-nodes-cpp \ + ros-${ROS_DISTRO}-demo-nodes-py \ && rm -rf /var/lib/apt/lists/ ``` @@ -179,29 +221,36 @@ Now that you have an appreciation for bootstrapping a distributed ROS example ma > Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: ```yaml -version: '2' +version: '3' + services: - master: - build: . - container_name: master - command: - - roscore - talker: - build: . - container_name: talker + image: ros2:my_demo environment: - - "ROS_HOSTNAME=talker" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials talker - + - "ROS_DOMAIN_ID=0" + - "ROS_SECURITY_ROOT_DIRECTORY=/keystore" + - "ROS_SECURITY_ENABLE=true" + - "ROS_SECURITY_STRATEGY=Enforce" + volumes: + - talker_keystore:/keystore:ro + command: ros2 run demo_nodes_cpp talker + listener: - build: . - container_name: listener + image: ros2:my_demo environment: - - "ROS_HOSTNAME=listener" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials listener + - "ROS_DOMAIN_ID=0" + - "ROS_SECURITY_ROOT_DIRECTORY=/keystore" + - "ROS_SECURITY_ENABLE=true" + - "ROS_SECURITY_STRATEGY=Enforce" + volumes: + - listener_keystore:/keystore:ro + command: ros2 run demo_nodes_py listener + +volumes: + talker_keystore: + external: true + listener_keystore: + external: true ``` > Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: From 66a3f109c70fe86ee034cd0d238c56b12eee5cb9 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 29 Nov 2018 01:20:32 -0800 Subject: [PATCH 05/47] Remove redundant walk through and skip to compose --- ros2/content.md | 83 ++----------------------------------------------- 1 file changed, 2 insertions(+), 81 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 6e0be8cfe94e..aecc36b6d258 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -120,101 +120,22 @@ RUN apt-get update && apt-get install -y \ > Then to build the image from within the same directory: ```console -$ docker build --tag %%IMAGE%%:ros-tutorials . +$ docker build --tag %%IMAGE%%:my_demo . ``` -#### Create network - -> To create a new network `foo`, we use the network command: - - docker network create foo - -> Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We'll use this make sure our ROS nodes can find and connect to our ROS `master`. - -#### Run services - -> To create a container for the ROS master and advertise it's service: ```console -$ docker run -it --rm \ - --net foo \ - --name master \ - %%IMAGE%%:ros-tutorials \ - roscore +$ docker ``` -> Now you can see that master is running and is ready manage our other ROS nodes. To add our `talker` node, we'll need to point the relevant environment variable to the master service: - -```console -$ docker run -it --rm \ - --net foo \ - --name talker \ - --env ROS_HOSTNAME=talker \ - --env ROS_MASTER_URI=http://master:11311 \ - %%IMAGE%%:ros-tutorials \ - rosrun roscpp_tutorials talker -``` -> Then in another terminal, run the `listener` node similarly: -```console -$ docker run -it --rm \ - --net foo \ - --name listener \ - --env ROS_HOSTNAME=listener \ - --env ROS_MASTER_URI=http://master:11311 \ - %%IMAGE%%:ros-tutorials \ - rosrun roscpp_tutorials listener -``` -> Alright! You should see `listener` is now echoing each message the `talker` broadcasting. You can then list the containers and see something like this: -```console -$ docker service ls -SERVICE ID NAME NETWORK CONTAINER -67ce73355e67 listener foo a62019123321 -917ee622d295 master foo f6ab9155fdbe -7f5a4748fb8d talker foo e0da2ee7570a -``` -> And for the services: -```console -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a62019123321 ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp listener -e0da2ee7570a ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp talker -f6ab9155fdbe ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp master -``` -#### Introspection - -> Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are: - -```console -$ docker exec -it master bash -$ source /ros_entrypoint.sh -``` - -> If we then use `rostopic` to list published message topics, we should see something like this: - -```console -$ rostopic list -/chatter -/rosout -/rosout_agg -``` - -#### Tear down - -> To tear down the structure we've made, we just need to stop the containers and the services. We can stop and remove the containers using `Ctrl^C` where we launched the containers or using the stop command with the names we gave them: - -```console -$ docker stop master talker listener -$ docker rm master talker listener -``` -### Compose Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. From 725cd24776447db8965caa81f18ce67092554a2f Mon Sep 17 00:00:00 2001 From: ruffsl Date: Sat, 1 Dec 2018 00:43:38 +0700 Subject: [PATCH 06/47] Cleanup dockerfile example --- ros2/content.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index aecc36b6d258..3026ac669e9b 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -15,10 +15,7 @@ FROM %%IMAGE%% # install ros build tools RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - python3-colcon-common-extensions \ - python3-rosdep \ - python3-vcstool && \ + python3-colcon-common-extensions && \ rm -rf /var/lib/apt/lists/* # clone ros package repo @@ -30,9 +27,7 @@ RUN git -C src clone \ https://github.com/ros2/demos.git # install ros package dependencies -ENV ROSDISTRO_INDEX_URL https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml RUN apt-get update && \ - rosdep init && \ rosdep update && \ rosdep install -y \ --from-paths \ @@ -55,7 +50,7 @@ RUN sed --in-place --expression \ /ros2_entrypoint.sh # run ros packge launch file -CMD [ "ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py" ] +CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` You can then build and run the Docker image: @@ -63,6 +58,13 @@ You can then build and run the Docker image: ```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] +... ``` ## Deployment use cases From 36501f9fa5517fd4fb99fcd15d1c624829123a21 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Sat, 1 Dec 2018 02:13:42 +0700 Subject: [PATCH 07/47] Make dockerfile example a multistage build --- ros2/content.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 3026ac669e9b..2b902956d73a 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -11,7 +11,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h ## Creating a `Dockerfile` to build your ROS 2 packages ```dockerfile -FROM %%IMAGE%% +FROM %%IMAGE%%:ros-base # install ros build tools RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -38,12 +38,15 @@ RUN apt-get update && \ # build ros package source RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ - --symlink-install \ --packages-select \ demo_nodes_cpp \ --cmake-args \ -DCMAKE_BUILD_TYPE=Release +FROM %%IMAGE%%:ros-core +ENV ROS2_WS /opt/ros2_ws +COPY --from=0 $ROS2_WS/install $ROS2_WS/install + # source ros package install RUN sed --in-place --expression \ '$isource "$ROS2_WS/install/setup.bash"' \ @@ -67,6 +70,12 @@ $ docker run -it --rm my/ros2:app ... ``` +``` +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 +``` + ## 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. From 92406af27e097aa76b7ca415b72a720cb4c009ef Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 13 Dec 2018 13:49:26 -0800 Subject: [PATCH 08/47] Create an install and build example --- ros2/content.md | 55 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 2b902956d73a..f149cb9108be 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -8,13 +8,45 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h # How to use this image -## Creating a `Dockerfile` to build your ROS 2 packages +## 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++ 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 && \ + 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 --no-install-recommends \ +RUN apt-get update && apt-get install -y \ python3-colcon-common-extensions && \ rm -rf /var/lib/apt/lists/* @@ -43,11 +75,12 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ --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 -# source ros package install +# source ros package from entrypoint RUN sed --in-place --expression \ '$isource "$ROS2_WS/install/setup.bash"' \ /ros2_entrypoint.sh @@ -56,19 +89,7 @@ RUN sed --in-place --expression \ CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` -You can then build and run the Docker image: - -```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] -... -``` +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 @@ -76,6 +97,8 @@ my/ros2 app-multi-stage 66c8112b2fb6 4 seconds ago 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. From bdd6d7dff29f64ad6ce244689c5b8232e0eab560 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 13 Dec 2018 14:24:11 -0800 Subject: [PATCH 09/47] Update body and links --- ros2/content.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index f149cb9108be..6e0deba743a2 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -132,7 +132,7 @@ Some application may require device access for acquiring images from connected c ### Networks -The ROS runtime "graph" is a peer-to-peer network 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 data over topics, and storage of data on a Parameter Server. 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 about [ROS NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup) wik article, or see the Deployment example below. +The ROS runtime "graph" is a peer-to-peer network 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 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 below. ## Deployment example @@ -238,7 +238,10 @@ $ docker-compose rm # More Resources [ROS.org](http://www.ros.org/): Main ROS website -[Wiki](http://wiki.ros.org/): Find tutorials and learn more -[ROS Answers](http://answers.ros.org/questions/): Ask questions. Get answers +[Docs](https://docs.ros2.org/): Core Documentation +[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](http://www.osrfoundation.org/): Open Source Robotics Foundation +[OSRF](https://www.osrfoundation.org/): Open Source Robotics Foundation From a7ed044a883e7852d1a9db8ba6f33f0d45689e2c Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 13 Dec 2018 14:50:13 -0800 Subject: [PATCH 10/47] Update logo --- ros2/logo.png | Bin 7197 -> 21254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ros2/logo.png b/ros2/logo.png index 637cc37dede2ae075f19c886622096185399ab87..befbfe8bca33700bfabbebba23141968fec5f830 100644 GIT binary patch literal 21254 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 literal 7197 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 xvw){K=*4ZXg+{J^=w)aDH Date: Thu, 13 Dec 2018 22:13:56 -0800 Subject: [PATCH 11/47] Add security example --- ros2/content.md | 134 ++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 6e0deba743a2..4cafe072115d 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -10,14 +10,15 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h ## 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++ client library demos using the official released Debian packages via apt-get. +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-cpp \ + ros-${ROS_DISTRO}-demo-nodes-py && \ rm -rf /var/lib/apt/lists/* # run ros packge launch file @@ -136,104 +137,117 @@ The ROS runtime "graph" is a peer-to-peer network of processes (potentially dist ## Deployment example -If we want our all ROS nodes to easily talk to each other, we'll can use a virtual network to connect the separate containers. In this short example, we'll create a virtual network, spin up a new container running `roscore` advertised as the `master` service on the new network, then spawn a message publisher and subscriber process as services on the same network. +### Docker Compose -### Build image +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 a `Dockerfile` that installs ROS 2 demos: +> 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: -```dockerfile -FROM %%IMAGE%% -# install ros 2 demo packages -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/ +```yaml +version: '3' + +services: + talker: + build: ./Dockerfile + command: ros2 run demo_nodes_cpp talker + + listener: + build: ./Dockerfile + command: ros2 run demo_nodes_py listener ``` -> Then to build the image from within the same directory: +> 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 build --tag %%IMAGE%%:my_demo . +$ docker-compose up -d +``` + +> Notice that a new network named `ros2_demos` has been created, as can be shown further with: + +```console +$ docker network inspect ros2_demos ``` +> We can monitor the logged output of each container, such as the listener node like so: ```console -$ docker +$ 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 +``` +> Create a enforcement file at `~/ros2_demos/config.env` to configure ROS 2 Security: -Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. -> Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: +``` 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 +``` + +> Now modify the original `docker-compose.yml` to use the configured environment and respective keystore entries: ```yaml version: '3' services: talker: - image: ros2:my_demo - environment: - - "ROS_DOMAIN_ID=0" - - "ROS_SECURITY_ROOT_DIRECTORY=/keystore" - - "ROS_SECURITY_ENABLE=true" - - "ROS_SECURITY_STRATEGY=Enforce" + build: ./Dockerfile + environment: ./config.env volumes: - - talker_keystore:/keystore:ro + - ./keystore/talker:/keystore:ro command: ros2 run demo_nodes_cpp talker listener: - image: ros2:my_demo - environment: - - "ROS_DOMAIN_ID=0" - - "ROS_SECURITY_ROOT_DIRECTORY=/keystore" - - "ROS_SECURITY_ENABLE=true" - - "ROS_SECURITY_STRATEGY=Enforce" + build: ./Dockerfile + environment: ./config.env volumes: - - listener_keystore:/keystore:ro + - ./keystore/listener:/keystore:ro command: ros2 run demo_nodes_py listener - -volumes: - talker_keystore: - external: true - listener_keystore: - external: true -``` - -> Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: - -```console -$ docker-compose up -d ``` -> Notice that a new network named `rostutorials_default` has now been created, you can inspect it further with: +> Now simply startup docker-compose as before: -```console -$ docker network inspect rostutorials_default -``` - -> We can monitor the logged output of each service, such as the listener node like so: - -```console -$ docker-compose logs listener -``` - -> Finally, we can stop and remove all the relevant containers using docker-copose from the same directory: - -```console -$ docker-compose stop -$ docker-compose rm +``` command +$ docker-compose up ``` -> Note: the auto-generated network, `rostutorials_default`, will persist over the life of the docker engine or until you explicitly remove it using [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\. +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 From 3a66e1a83f3876e4267faf3ca4890b39f24c175b Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 13 Dec 2018 22:40:28 -0800 Subject: [PATCH 12/47] Add warnings about networking with ROS2/DDS --- ros2/content.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ros2/content.md b/ros2/content.md index 4cafe072115d..37463276ed41 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -133,7 +133,9 @@ Some application may require device access for acquiring images from connected c ### Networks -The ROS runtime "graph" is a peer-to-peer network 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 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 below. +The ROS runtime "graph" is a peer-to-peer network 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 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, 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 From db9791a86c27db19d9098bd8bd175eea0f2b6420 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 13 Dec 2018 22:41:15 -0800 Subject: [PATCH 13/47] Fix compose file --- ros2/content.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 37463276ed41..27ef5474504c 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -133,9 +133,9 @@ Some application may require device access for acquiring images from connected c ### Networks -The ROS runtime "graph" is a peer-to-peer network 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 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. +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, 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). +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 @@ -230,14 +230,16 @@ version: '3' services: talker: build: ./Dockerfile - environment: ./config.env + environment: + - ./config.env volumes: - ./keystore/talker:/keystore:ro command: ros2 run demo_nodes_cpp talker listener: build: ./Dockerfile - environment: ./config.env + environment: + - ./config.env volumes: - ./keystore/listener:/keystore:ro command: ros2 run demo_nodes_py listener From c1c457d27ce2c468d3236bc518fd8404abdcf412 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 00:00:29 -0800 Subject: [PATCH 14/47] Fix Spelling --- ros2/content.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ros2/content.md b/ros2/content.md index 27ef5474504c..e35d4d9c7252 100644 --- a/ros2/content.md +++ b/ros2/content.md @@ -21,7 +21,7 @@ RUN apt-get update && apt-get install -y \ ros-${ROS_DISTRO}-demo-nodes-py && \ rm -rf /var/lib/apt/lists/* -# run ros packge launch file +# run ros package launch file CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` @@ -86,7 +86,7 @@ RUN sed --in-place --expression \ '$isource "$ROS2_WS/install/setup.bash"' \ /ros2_entrypoint.sh -# run ros packge launch file +# run ros package launch file CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` @@ -141,7 +141,7 @@ Alternatively, more permissive network setting can be use to share all host netw ### 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. +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 separate 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: @@ -158,7 +158,7 @@ services: 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: +> Use docker-compose 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 @@ -211,7 +211,7 @@ ROS_SECURITY_ENABLE=true ROS_DOMAIN_ID=0 ``` -> Use a temporary container to run the keystore bootstraping script in the keystore directory: +> Use a temporary container to run the keystore bootstrapping script in the keystore directory: ```console From b03d7d94cd75cb161a3443ca1dd85f6518507ebd Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 19:30:31 -0800 Subject: [PATCH 15/47] Remove duplicate files before merge --- ros2/README-short.txt | 1 - ros2/README.md | 325 ------------------------------------------ ros2/github-repo | 1 - ros2/logo.png | Bin 21254 -> 0 bytes ros2/maintainer.md | 1 - 5 files changed, 328 deletions(-) delete mode 100644 ros2/README-short.txt delete mode 100644 ros2/README.md delete mode 100644 ros2/github-repo delete mode 100644 ros2/logo.png delete mode 100644 ros2/maintainer.md diff --git a/ros2/README-short.txt b/ros2/README-short.txt deleted file mode 100644 index c59ed8f6c183..000000000000 --- a/ros2/README-short.txt +++ /dev/null @@ -1 +0,0 @@ -The Robot Operating System (ROS) is an open source project for building robot applications. diff --git a/ros2/README.md b/ros2/README.md deleted file mode 100644 index 0ff58b3d4fda..000000000000 --- a/ros2/README.md +++ /dev/null @@ -1,325 +0,0 @@ - - -# Supported tags and respective `Dockerfile` links - -- [`indigo-ros-core`, `indigo-ros-core-trusty` (*ros/indigo/ubuntu/trusty/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/ros-core/Dockerfile) -- [`indigo-ros-base`, `indigo-ros-base-trusty`, `indigo` (*ros/indigo/ubuntu/trusty/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/ros-base/Dockerfile) -- [`indigo-robot`, `indigo-robot-trusty` (*ros/indigo/ubuntu/trusty/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/robot/Dockerfile) -- [`indigo-perception`, `indigo-perception-trusty` (*ros/indigo/ubuntu/trusty/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/indigo/ubuntu/trusty/perception/Dockerfile) -- [`kinetic-ros-core`, `kinetic-ros-core-xenial` (*ros/kinetic/ubuntu/xenial/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/ros-core/Dockerfile) -- [`kinetic-ros-base`, `kinetic-ros-base-xenial`, `kinetic` (*ros/kinetic/ubuntu/xenial/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/ros-base/Dockerfile) -- [`kinetic-robot`, `kinetic-robot-xenial` (*ros/kinetic/ubuntu/xenial/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/robot/Dockerfile) -- [`kinetic-perception`, `kinetic-perception-xenial` (*ros/kinetic/ubuntu/xenial/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/kinetic/ubuntu/xenial/perception/Dockerfile) -- [`lunar-ros-core`, `lunar-ros-core-xenial` (*ros/lunar/ubuntu/xenial/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/ros-core/Dockerfile) -- [`lunar-ros-base`, `lunar-ros-base-xenial`, `lunar` (*ros/lunar/ubuntu/xenial/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/ros-base/Dockerfile) -- [`lunar-robot`, `lunar-robot-xenial` (*ros/lunar/ubuntu/xenial/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/robot/Dockerfile) -- [`lunar-perception`, `lunar-perception-xenial` (*ros/lunar/ubuntu/xenial/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/ubuntu/xenial/perception/Dockerfile) -- [`lunar-ros-core-stretch` (*ros/lunar/debian/stretch/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/ros-core/Dockerfile) -- [`lunar-ros-base-stretch` (*ros/lunar/debian/stretch/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/ros-base/Dockerfile) -- [`lunar-robot-stretch` (*ros/lunar/debian/stretch/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/robot/Dockerfile) -- [`lunar-perception-stretch` (*ros/lunar/debian/stretch/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/lunar/debian/stretch/perception/Dockerfile) -- [`melodic-ros-core`, `melodic-ros-core-bionic` (*ros/melodic/ubuntu/bionic/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/ros-core/Dockerfile) -- [`melodic-ros-base`, `melodic-ros-base-bionic`, `melodic`, `latest` (*ros/melodic/ubuntu/bionic/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/ros-base/Dockerfile) -- [`melodic-robot`, `melodic-robot-bionic` (*ros/melodic/ubuntu/bionic/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/robot/Dockerfile) -- [`melodic-perception`, `melodic-perception-bionic` (*ros/melodic/ubuntu/bionic/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/ubuntu/bionic/perception/Dockerfile) -- [`melodic-ros-core-stretch` (*ros/melodic/debian/stretch/ros-core/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/ros-core/Dockerfile) -- [`melodic-ros-base-stretch` (*ros/melodic/debian/stretch/ros-base/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/ros-base/Dockerfile) -- [`melodic-robot-stretch` (*ros/melodic/debian/stretch/robot/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/robot/Dockerfile) -- [`melodic-perception-stretch` (*ros/melodic/debian/stretch/perception/Dockerfile*)](https://github.com/osrf/docker_images/blob/49d22242e02e9c541a9e85b657e1785617b6f470/ros/melodic/debian/stretch/perception/Dockerfile) - -# Quick reference - -- **Where to get help**: - [the Docker Community Forums](https://forums.docker.com/), [the Docker Community Slack](https://blog.docker.com/2016/11/introducing-docker-community-directory-docker-community-slack/), or [Stack Overflow](https://stackoverflow.com/search?tab=newest&q=docker) - -- **Where to file issues**: - [https://github.com/osrf/docker_images/issues](https://github.com/osrf/docker_images/issues) - -- **Maintained by**: - [the Open Source Robotics Foundation](https://github.com/osrf/docker_images) - -- **Supported architectures**: ([more info](https://github.com/docker-library/official-images#architectures-other-than-amd64)) - [`amd64`](https://hub.docker.com/r/amd64/ros/), [`arm32v7`](https://hub.docker.com/r/arm32v7/ros/), [`arm64v8`](https://hub.docker.com/r/arm64v8/ros/) - -- **Published image artifact details**: - [repo-info repo's `repos/ros/` directory](https://github.com/docker-library/repo-info/blob/master/repos/ros) ([history](https://github.com/docker-library/repo-info/commits/master/repos/ros)) - (image metadata, transfer size, etc) - -- **Image updates**: - [official-images PRs with label `library/ros`](https://github.com/docker-library/official-images/pulls?q=label%3Alibrary%2Fros) - [official-images repo's `library/ros` file](https://github.com/docker-library/official-images/blob/master/library/ros) ([history](https://github.com/docker-library/official-images/commits/master/library/ros)) - -- **Source of this description**: - [docs repo's `ros/` directory](https://github.com/docker-library/docs/tree/master/ros) ([history](https://github.com/docker-library/docs/commits/master/ros)) - -- **Supported Docker versions**: - [the latest release](https://github.com/docker/docker-ce/releases/latest) (down to 1.6 on a best-effort basis) - -# What is [ROS](http://www.ros.org/)? - -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. - -> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) - -[![logo](https://raw.githubusercontent.com/docker-library/docs/0074e9dac72a35e5058f356885121aa82572682f/ros/logo.png)](http://www.ros.org/) - -# How to use this image - -## Create a `Dockerfile` in your ROS app project - -```dockerfile -FROM ros:indigo -# place here your application's setup specifics -CMD [ "roslaunch", "my-ros-app my-ros-app.launch" ] -``` - -You can then build and run the Docker image: - -```console -$ docker build -t my-ros-app . -$ docker run -it --rm --name my-running-app my-ros-app -``` - -## Deployment use cases - -This dockerized image of ROS 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 install -- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) -- `robot`: basic install for robots -- `perception`: basic install for perception tasks - -The rest of the common meta-packages such as `desktop` and `desktop-full` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros/). 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/" ros -``` - -### 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 - -The ROS runtime "graph" is a peer-to-peer network 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 data over topics, and storage of data on a Parameter Server. 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 about [ROS NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup) wik article, or see the Deployment example below. - -## Deployment example - -If we want our all ROS nodes to easily talk to each other, we'll can use a virtual network to connect the separate containers. In this short example, we'll create a virtual network, spin up a new container running `roscore` advertised as the `master` service on the new network, then spawn a message publisher and subscriber process as services on the same network. - -### Build image - -> Build a ROS image that includes ROS tutorials using this `Dockerfile:` - -```dockerfile -FROM ros:indigo-ros-base -# install ros tutorials packages -RUN apt-get update && apt-get install -y \ - ros-indigo-ros-tutorials \ - ros-indigo-common-tutorials \ - && rm -rf /var/lib/apt/lists/ -``` - -> Then to build the image from within the same directory: - -```console -$ docker build --tag ros:ros-tutorials . -``` - -#### Create network - -> To create a new network `foo`, we use the network command: - - docker network create foo - -> Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We'll use this make sure our ROS nodes can find and connect to our ROS `master`. - -#### Run services - -> To create a container for the ROS master and advertise it's service: - -```console -$ docker run -it --rm \ - --net foo \ - --name master \ - ros:ros-tutorials \ - roscore -``` - -> Now you can see that master is running and is ready manage our other ROS nodes. To add our `talker` node, we'll need to point the relevant environment variable to the master service: - -```console -$ docker run -it --rm \ - --net foo \ - --name talker \ - --env ROS_HOSTNAME=talker \ - --env ROS_MASTER_URI=http://master:11311 \ - ros:ros-tutorials \ - rosrun roscpp_tutorials talker -``` - -> Then in another terminal, run the `listener` node similarly: - -```console -$ docker run -it --rm \ - --net foo \ - --name listener \ - --env ROS_HOSTNAME=listener \ - --env ROS_MASTER_URI=http://master:11311 \ - ros:ros-tutorials \ - rosrun roscpp_tutorials listener -``` - -> Alright! You should see `listener` is now echoing each message the `talker` broadcasting. You can then list the containers and see something like this: - -```console -$ docker service ls -SERVICE ID NAME NETWORK CONTAINER -67ce73355e67 listener foo a62019123321 -917ee622d295 master foo f6ab9155fdbe -7f5a4748fb8d talker foo e0da2ee7570a -``` - -> And for the services: - -```console -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a62019123321 ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp listener -e0da2ee7570a ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp talker -f6ab9155fdbe ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp master -``` - -#### Introspection - -> Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are: - -```console -$ docker exec -it master bash -$ source /ros_entrypoint.sh -``` - -> If we then use `rostopic` to list published message topics, we should see something like this: - -```console -$ rostopic list -/chatter -/rosout -/rosout_agg -``` - -#### Tear down - -> To tear down the structure we've made, we just need to stop the containers and the services. We can stop and remove the containers using `Ctrl^C` where we launched the containers or using the stop command with the names we gave them: - -```console -$ docker stop master talker listener -$ docker rm master talker listener -``` - -### Compose - -Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. - -> Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: - -```yaml -version: '2' -services: - master: - build: . - container_name: master - command: - - roscore - - talker: - build: . - container_name: talker - environment: - - "ROS_HOSTNAME=talker" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials talker - - listener: - build: . - container_name: listener - environment: - - "ROS_HOSTNAME=listener" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials listener -``` - -> Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: - -```console -$ docker-compose up -d -``` - -> Notice that a new network named `rostutorials_default` has now been created, you can inspect it further with: - -```console -$ docker network inspect rostutorials_default -``` - -> We can monitor the logged output of each service, such as the listener node like so: - -```console -$ docker-compose logs listener -``` - -> Finally, we can stop and remove all the relevant containers using docker-copose from the same directory: - -```console -$ docker-compose stop -$ docker-compose rm -``` - -> Note: the auto-generated network, `rostutorials_default`, will persist over the life of the docker engine or until you explicitly remove it using [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\. - -# More Resources - -[ROS.org](http://www.ros.org/): Main ROS website -[Wiki](http://wiki.ros.org/): Find tutorials and learn more -[ROS Answers](http://answers.ros.org/questions/): Ask questions. Get answers -[Blog](http://www.ros.org/news/): Stay up-to-date -[OSRF](http://www.osrfoundation.org/): Open Source Robotics Foundation - -# License - -The core of ROS is licensed under the standard three-clause BSD license. This is a very permissive open license that allows for reuse in commercial and closed source products. You can find more about the BSD license from the Opensource.org [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) page and Wikipedia's [BSD Licenses](http://en.wikipedia.org/wiki/BSD_licenses) entry. - -While the core parts of ROS are licensed under the BSD license, other licenses are commonly used in the community packages, such as the [Apache 2.0](http://opensource.org/licenses/Apache-2.0) license, the [GPL](http://opensource.org/licenses/gpl-license) license, the [MIT](http://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. - -As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained). - -Some additional license information which was able to be auto-detected might be found in [the `repo-info` repository's `ros/` directory](https://github.com/docker-library/repo-info/tree/master/repos/ros). - -As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. diff --git a/ros2/github-repo b/ros2/github-repo deleted file mode 100644 index 7b29247ab4b4..000000000000 --- a/ros2/github-repo +++ /dev/null @@ -1 +0,0 @@ -https://github.com/osrf/docker_images diff --git a/ros2/logo.png b/ros2/logo.png deleted file mode 100644 index befbfe8bca33700bfabbebba23141968fec5f830..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21254 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 diff --git a/ros2/maintainer.md b/ros2/maintainer.md deleted file mode 100644 index 90db8c7f2308..000000000000 --- a/ros2/maintainer.md +++ /dev/null @@ -1 +0,0 @@ -[the Open Source Robotics Foundation](%%GITHUB-REPO%%) From 40f09e881102075806a08d3ffba87124c37cf263 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 19:32:49 -0800 Subject: [PATCH 16/47] Remove duplicate files before merge --- ros/content.md | 242 ------------------------------------------------- ros/license.md | 3 - 2 files changed, 245 deletions(-) delete mode 100644 ros/content.md delete mode 100644 ros/license.md diff --git a/ros/content.md b/ros/content.md deleted file mode 100644 index 35a4a7d48b2e..000000000000 --- a/ros/content.md +++ /dev/null @@ -1,242 +0,0 @@ -# What is [ROS](http://www.ros.org/)? - -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. - -> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) - -[%%LOGO%%](http://www.ros.org/) - -# How to use this image - -## Create a `Dockerfile` in your ROS app project - -```dockerfile -FROM %%IMAGE%%:indigo -# place here your application's setup specifics -CMD [ "roslaunch", "my-ros-app my-ros-app.launch" ] -``` - -You can then build and run the Docker image: - -```console -$ docker build -t my-ros-app . -$ docker run -it --rm --name my-running-app my-ros-app -``` - -## Deployment use cases - -This dockerized image of ROS 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 install -- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) -- `robot`: basic install for robots -- `perception`: basic install for perception tasks - -The rest of the common meta-packages such as `desktop` and `desktop-full` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros/). 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 - -The ROS runtime "graph" is a peer-to-peer network 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 data over topics, and storage of data on a Parameter Server. 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 about [ROS NetworkSetup](http://wiki.ros.org/ROS/NetworkSetup) wik article, or see the Deployment example below. - -## Deployment example - -If we want our all ROS nodes to easily talk to each other, we'll can use a virtual network to connect the separate containers. In this short example, we'll create a virtual network, spin up a new container running `roscore` advertised as the `master` service on the new network, then spawn a message publisher and subscriber process as services on the same network. - -### Build image - -> Build a ROS image that includes ROS tutorials using this `Dockerfile:` - -```dockerfile -FROM %%IMAGE%%:indigo-ros-base -# install ros tutorials packages -RUN apt-get update && apt-get install -y \ - ros-indigo-ros-tutorials \ - ros-indigo-common-tutorials \ - && rm -rf /var/lib/apt/lists/ -``` - -> Then to build the image from within the same directory: - -```console -$ docker build --tag %%IMAGE%%:ros-tutorials . -``` - -#### Create network - -> To create a new network `foo`, we use the network command: - - docker network create foo - -> Now that we have a network, we can create services. Services advertise there location on the network, making it easy to resolve the location/address of the service specific container. We'll use this make sure our ROS nodes can find and connect to our ROS `master`. - -#### Run services - -> To create a container for the ROS master and advertise it's service: - -```console -$ docker run -it --rm \ - --net foo \ - --name master \ - %%IMAGE%%:ros-tutorials \ - roscore -``` - -> Now you can see that master is running and is ready manage our other ROS nodes. To add our `talker` node, we'll need to point the relevant environment variable to the master service: - -```console -$ docker run -it --rm \ - --net foo \ - --name talker \ - --env ROS_HOSTNAME=talker \ - --env ROS_MASTER_URI=http://master:11311 \ - %%IMAGE%%:ros-tutorials \ - rosrun roscpp_tutorials talker -``` - -> Then in another terminal, run the `listener` node similarly: - -```console -$ docker run -it --rm \ - --net foo \ - --name listener \ - --env ROS_HOSTNAME=listener \ - --env ROS_MASTER_URI=http://master:11311 \ - %%IMAGE%%:ros-tutorials \ - rosrun roscpp_tutorials listener -``` - -> Alright! You should see `listener` is now echoing each message the `talker` broadcasting. You can then list the containers and see something like this: - -```console -$ docker service ls -SERVICE ID NAME NETWORK CONTAINER -67ce73355e67 listener foo a62019123321 -917ee622d295 master foo f6ab9155fdbe -7f5a4748fb8d talker foo e0da2ee7570a -``` - -> And for the services: - -```console -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -a62019123321 ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp listener -e0da2ee7570a ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp talker -f6ab9155fdbe ros:ros-tutorials "/ros_entrypoint.sh About a minute ago Up About a minute 11311/tcp master -``` - -#### Introspection - -> Ok, now that we see the two nodes are communicating, let get inside one of the containers and do some introspection what exactly the topics are: - -```console -$ docker exec -it master bash -$ source /ros_entrypoint.sh -``` - -> If we then use `rostopic` to list published message topics, we should see something like this: - -```console -$ rostopic list -/chatter -/rosout -/rosout_agg -``` - -#### Tear down - -> To tear down the structure we've made, we just need to stop the containers and the services. We can stop and remove the containers using `Ctrl^C` where we launched the containers or using the stop command with the names we gave them: - -```console -$ docker stop master talker listener -$ docker rm master talker listener -``` - -### Compose - -Now that you have an appreciation for bootstrapping a distributed ROS example manually, lets try and automate it using [`docker-compose`](https://docs.docker.com/compose/)\. - -> Start by making a folder named `rostutorials` and moving the Dockerfile we used earlier inside this directory. Then create a yaml file named `docker-compose.yml` in the same directory and paste the following inside: - -```yaml -version: '2' -services: - master: - build: . - container_name: master - command: - - roscore - - talker: - build: . - container_name: talker - environment: - - "ROS_HOSTNAME=talker" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials talker - - listener: - build: . - container_name: listener - environment: - - "ROS_HOSTNAME=listener" - - "ROS_MASTER_URI=http://master:11311" - command: rosrun roscpp_tutorials listener -``` - -> Now from inside the same folder, use docker-copose to launch our ROS nodes and specify that they coexist on their own network: - -```console -$ docker-compose up -d -``` - -> Notice that a new network named `rostutorials_default` has now been created, you can inspect it further with: - -```console -$ docker network inspect rostutorials_default -``` - -> We can monitor the logged output of each service, such as the listener node like so: - -```console -$ docker-compose logs listener -``` - -> Finally, we can stop and remove all the relevant containers using docker-copose from the same directory: - -```console -$ docker-compose stop -$ docker-compose rm -``` - -> Note: the auto-generated network, `rostutorials_default`, will persist over the life of the docker engine or until you explicitly remove it using [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\. - -# More Resources - -[ROS.org](http://www.ros.org/): Main ROS website -[Wiki](http://wiki.ros.org/): Find tutorials and learn more -[ROS Answers](http://answers.ros.org/questions/): Ask questions. Get answers -[Blog](http://www.ros.org/news/): Stay up-to-date -[OSRF](http://www.osrfoundation.org/): Open Source Robotics Foundation diff --git a/ros/license.md b/ros/license.md deleted file mode 100644 index aa8b87126e6d..000000000000 --- a/ros/license.md +++ /dev/null @@ -1,3 +0,0 @@ -The core of ROS is licensed under the standard three-clause BSD license. This is a very permissive open license that allows for reuse in commercial and closed source products. You can find more about the BSD license from the Opensource.org [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) page and Wikipedia's [BSD Licenses](http://en.wikipedia.org/wiki/BSD_licenses) entry. - -While the core parts of ROS are licensed under the BSD license, other licenses are commonly used in the community packages, such as the [Apache 2.0](http://opensource.org/licenses/Apache-2.0) license, the [GPL](http://opensource.org/licenses/gpl-license) license, the [MIT](http://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. From eb9d43c53ca69f0718c65a525f97ae30213f3676 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 19:33:38 -0800 Subject: [PATCH 17/47] Move changes for merge --- {ros2 => ros}/content.md | 0 {ros2 => ros}/license.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {ros2 => ros}/content.md (100%) rename {ros2 => ros}/license.md (100%) diff --git a/ros2/content.md b/ros/content.md similarity index 100% rename from ros2/content.md rename to ros/content.md diff --git a/ros2/license.md b/ros/license.md similarity index 100% rename from ros2/license.md rename to ros/license.md From f4edbfb077e9f0b387ddf28ecc1f505ab102ca42 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 21:33:56 -0800 Subject: [PATCH 18/47] Rewording to just reference latest ros release --- ros/content.md | 68 +++++++++++++++++++++++++------------------------- ros/license.md | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/ros/content.md b/ros/content.md index e35d4d9c7252..00dcdc531965 100644 --- a/ros/content.md +++ b/ros/content.md @@ -1,6 +1,6 @@ -# What is [ROS 2](https://index.ros.org/doc/ros2)? +# What is [ROS](https://index.ros.org/doc/ros2)? -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. +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. > [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) @@ -8,12 +8,12 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h # How to use this image -## Creating a `Dockerfile` to install ROS 2 packages +## Creating a `Dockerfile` to install ROS 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. +To create your own ROS 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 +FROM %%IMAGE%%:crystal # install ros packages for installed release RUN apt-get update && apt-get install -y \ @@ -25,11 +25,11 @@ RUN apt-get update && apt-get install -y \ 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: +Note: all ROS 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 +$ docker build -t my/ros:app . +$ docker run -it --rm my/ros: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' @@ -39,12 +39,12 @@ $ docker run -it --rm my/ros2:app ... ``` -## Creating a `Dockerfile` to build ROS 2 packages +## Creating a `Dockerfile` to build ROS 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. +To create your own ROS 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 +FROM %%IMAGE%%:crystal-ros-base # install ros build tools RUN apt-get update && apt-get install -y \ @@ -52,9 +52,9 @@ RUN apt-get update && apt-get install -y \ 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 +ENV ROS_WS /opt/ros_ws +RUN mkdir -p $ROS_WS/src +WORKDIR $ROS_WS RUN git -C src clone \ -b $ROS_DISTRO \ https://github.com/ros2/demos.git @@ -77,14 +77,14 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ -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 +FROM %%IMAGE%%:crystal-ros-core +ENV ROS_WS /opt/ros_ws +COPY --from=0 $ROS_WS/install $ROS_WS/install # source ros package from entrypoint RUN sed --in-place --expression \ - '$isource "$ROS2_WS/install/setup.bash"' \ - /ros2_entrypoint.sh + '$isource "$ROS_WS/install/setup.bash"' \ + /ros_entrypoint.sh # run ros package launch file CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] @@ -94,15 +94,15 @@ Note: `--from-paths` and `--packages-select` are set here as so to only install ``` 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 +my/ros app-multi-stage 66c8112b2fb6 4 seconds ago 775MB +my/ros 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. +This dockerized image of ROS 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. @@ -115,7 +115,7 @@ The available tags include supported distros along with a hierarchy tags based o - `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. +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/ros/). 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 @@ -133,7 +133,7 @@ Some application may require device access for acquiring images from connected c ### 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. +ROS 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). @@ -143,7 +143,7 @@ Alternatively, more permissive network setting can be use to share all host netw 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 separate 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: +> Create the directory `~/ros_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' @@ -164,10 +164,10 @@ services: $ docker-compose up -d ``` -> Notice that a new network named `ros2_demos` has been created, as can be shown further with: +> Notice that a new network named `ros_demos` has been created, as can be shown further with: ```console -$ docker network inspect ros2_demos +$ docker network inspect ros_demos ``` > We can monitor the logged output of each container, such as the listener node like so: @@ -183,28 +183,28 @@ $ docker-compose stop $ docker-compose rm ``` -> Note: the auto-generated network, `ros2_demos`, will persist until you explicitly remove it using `docker-compose down`. +> Note: the auto-generated network, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`. -### Securing ROS 2 +### Securing ROS -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. +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 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: +> Create a script at `~/ros_demos/keystore/bootstrap_keystore.bash` to bootstrap a keystore and add entries for each node: ``` shell #!/usr/bin/env bash -# Bootstrap ROS 2 keystore +# Bootstrap ROS keystore ros2 security create_keystore ./ ros2 security create_key ./ talker ros2 security create_key ./ listener ``` -> Create a enforcement file at `~/ros2_demos/config.env` to configure ROS 2 Security: +> Create a enforcement file at `~/ros_demos/config.env` to configure ROS Security: ``` shell -# Configure ROS 2 Security +# Configure ROS Security ROS_SECURITY_NODE_DIRECTORY=/keystore ROS_SECURITY_STRATEGY=Enforce ROS_SECURITY_ENABLE=true diff --git a/ros/license.md b/ros/license.md index 6d10681baea5..1a4907e6ace4 100644 --- a/ros/license.md +++ b/ros/license.md @@ -1,3 +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. +The core of ROS 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. +While the core parts of ROS 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. From 199e0a5292353fe12e3fa11cd044282a07e534f4 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 21:50:10 -0800 Subject: [PATCH 19/47] Fix markdown for CI --- ros/content.md | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/ros/content.md b/ros/content.md index 00dcdc531965..e7d6985a492d 100644 --- a/ros/content.md +++ b/ros/content.md @@ -10,7 +10,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h ## Creating a `Dockerfile` to install ROS packages -To create your own ROS 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. +To create your own ROS 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%%:crystal @@ -41,7 +41,7 @@ $ docker run -it --rm my/ros:app ## Creating a `Dockerfile` to build ROS packages -To create your own ROS 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. +To create your own ROS 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%%:crystal-ros-base @@ -92,11 +92,9 @@ 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/ros app-multi-stage 66c8112b2fb6 4 seconds ago 775MB -my/ros app-single-stage 6b500239d0d6 2 minutes ago 797MB -``` + REPOSITORY TAG IMAGE ID CREATED SIZE + my/ros app-multi-stage 66c8112b2fb6 4 seconds ago 775MB + my/ros 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. @@ -185,14 +183,13 @@ $ docker-compose rm > Note: the auto-generated network, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`. - ### Securing ROS 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 docker image to bootstrap the PKI, CAs, and Digitally Signed files. > Create a script at `~/ros_demos/keystore/bootstrap_keystore.bash` to bootstrap a keystore and add entries for each node: -``` shell +```shell #!/usr/bin/env bash # Bootstrap ROS keystore ros2 security create_keystore ./ @@ -202,8 +199,7 @@ ros2 security create_key ./ listener > Create a enforcement file at `~/ros_demos/config.env` to configure ROS Security: - -``` shell +```shell # Configure ROS Security ROS_SECURITY_NODE_DIRECTORY=/keystore ROS_SECURITY_STRATEGY=Enforce @@ -213,7 +209,6 @@ ROS_DOMAIN_ID=0 > Use a temporary container to run the keystore bootstrapping script in the keystore directory: - ```console $ docker run -it --rm \ --env-file ./config.env \ @@ -247,11 +242,11 @@ services: > Now simply startup docker-compose as before: -``` command +```console $ 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/). +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 From 347e32d659b74d01e66be89af87a80982baeec16 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Fri, 14 Dec 2018 22:39:16 -0800 Subject: [PATCH 20/47] Provide sros2 cli in example and fix keystore permissions --- ros/content.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index e7d6985a492d..a990876f7b4a 100644 --- a/ros/content.md +++ b/ros/content.md @@ -10,7 +10,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h ## Creating a `Dockerfile` to install ROS packages -To create your own ROS 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. +To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos and security CLI using the official released Debian packages via apt-get. ```dockerfile FROM %%IMAGE%%:crystal @@ -18,7 +18,8 @@ FROM %%IMAGE%%:crystal # 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 && \ + ros-${ROS_DISTRO}-demo-nodes-py \ + ros-${ROS_DISTRO}-sros2 && \ rm -rf /var/lib/apt/lists/* # run ros package launch file @@ -195,6 +196,7 @@ Lets build upon the example above by adding authenticated encryption to the mess ros2 security create_keystore ./ ros2 security create_key ./ talker ros2 security create_key ./ listener +chown -R $(stat -c '%u:%g' ./) ./ ``` > Create a enforcement file at `~/ros_demos/config.env` to configure ROS Security: From bbeff28ad071164c3c83a596d3e98247789e43fe Mon Sep 17 00:00:00 2001 From: Ruffin Date: Thu, 27 Jun 2019 15:56:55 -0700 Subject: [PATCH 21/47] Fix Spelling --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index a990876f7b4a..d705abd2e565 100644 --- a/ros/content.md +++ b/ros/content.md @@ -26,7 +26,7 @@ RUN apt-get update && apt-get install -y \ CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` -Note: all ROS 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: +Note: all ROS images include a default entrypoint that sources the ROS environment setup before executing 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/ros:app . From 332a6e89e1f0b9e32b326714b585ff7f65b9dda6 Mon Sep 17 00:00:00 2001 From: Ruffin Date: Thu, 27 Jun 2019 16:03:11 -0700 Subject: [PATCH 22/47] Update example to use latest LTS tag --- ros/content.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ros/content.md b/ros/content.md index d705abd2e565..568587cc270d 100644 --- a/ros/content.md +++ b/ros/content.md @@ -13,7 +13,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos and security CLI using the official released Debian packages via apt-get. ```dockerfile -FROM %%IMAGE%%:crystal +FROM %%IMAGE%%:dashing # install ros packages for installed release RUN apt-get update && apt-get install -y \ @@ -45,7 +45,7 @@ $ docker run -it --rm my/ros:app To create your own ROS 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%%:crystal-ros-base +FROM %%IMAGE%%:dashing-ros-base # install ros build tools RUN apt-get update && apt-get install -y \ @@ -78,7 +78,7 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ -DCMAKE_BUILD_TYPE=Release # copy ros package install via multi-stage -FROM %%IMAGE%%:crystal-ros-core +FROM %%IMAGE%%:dashing-ros-core ENV ROS_WS /opt/ros_ws COPY --from=0 $ROS_WS/install $ROS_WS/install From 3d1f775b5c27de5b6b0071e7ade57f9622fa30b3 Mon Sep 17 00:00:00 2001 From: Ruffin Date: Thu, 27 Jun 2019 16:15:36 -0700 Subject: [PATCH 23/47] Hold off on sros example As much of the keystore tooling is being refactored and subject to change --- ros/content.md | 69 +------------------------------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/ros/content.md b/ros/content.md index 568587cc270d..9319c1853854 100644 --- a/ros/content.md +++ b/ros/content.md @@ -18,8 +18,7 @@ FROM %%IMAGE%%:dashing # 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 \ - ros-${ROS_DISTRO}-sros2 && \ + ros-${ROS_DISTRO}-demo-nodes-py && \ rm -rf /var/lib/apt/lists/* # run ros package launch file @@ -184,72 +183,6 @@ $ docker-compose rm > Note: the auto-generated network, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`. -### Securing ROS - -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 docker image to bootstrap the PKI, CAs, and Digitally Signed files. - -> Create a script at `~/ros_demos/keystore/bootstrap_keystore.bash` to bootstrap a keystore and add entries for each node: - -```shell -#!/usr/bin/env bash -# Bootstrap ROS keystore -ros2 security create_keystore ./ -ros2 security create_key ./ talker -ros2 security create_key ./ listener -chown -R $(stat -c '%u:%g' ./) ./ -``` - -> Create a enforcement file at `~/ros_demos/config.env` to configure ROS Security: - -```shell -# Configure ROS 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 bootstrapping 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 -``` - -> 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: - -```console -$ 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 From 8398e71355e7494ca64122ebe7062b01ec64829e Mon Sep 17 00:00:00 2001 From: Ruffin Date: Thu, 27 Jun 2019 16:22:00 -0700 Subject: [PATCH 24/47] Update docs link to point to index.ros.org --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index 9319c1853854..de55e94675fb 100644 --- a/ros/content.md +++ b/ros/content.md @@ -186,7 +186,7 @@ $ docker-compose rm # More Resources [ROS.org](http://www.ros.org/): Main ROS website -[Docs](https://docs.ros2.org/): Core Documentation +[Docs](https://index.ros.org/doc/ros2/): Core Documentation [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 From a62f77dc1af282d4ac3f626727761f90b801557e Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 26 Nov 2019 17:31:54 -0800 Subject: [PATCH 25/47] Update Dockerfile build example --- ros/content.md | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/ros/content.md b/ros/content.md index ec1496ef48d2..91d113d33e3a 100644 --- a/ros/content.md +++ b/ros/content.md @@ -15,13 +15,13 @@ To create your own ROS docker images and install custom packages, here's a simpl ```dockerfile FROM %%IMAGE%%:dashing -# install ros packages for installed release +# install ros package 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 package launch file +# launch ros package CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` @@ -44,14 +44,9 @@ $ docker run -it --rm my/ros:app To create your own ROS 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%%:dashing-ros-base +FROM %%IMAGE%%:dashing-ros-base AS builder -# 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 +# clone package source ENV ROS_WS /opt/ros_ws RUN mkdir -p $ROS_WS/src WORKDIR $ROS_WS @@ -59,34 +54,35 @@ RUN git -C src clone \ -b $ROS_DISTRO \ https://github.com/ros2/demos.git -# install ros package dependencies -RUN apt-get update && \ - rosdep update && \ +# install package dependencies +RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ + 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 +# build package workspace RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ --packages-select \ demo_nodes_cpp \ - --cmake-args \ - -DCMAKE_BUILD_TYPE=Release + --mixin release + +# create new multi-stage +FROM %%IMAGE%%:dashing-ros-core AS runner -# copy ros package install via multi-stage -FROM %%IMAGE%%:dashing-ros-core +# copy package install ENV ROS_WS /opt/ros_ws -COPY --from=0 $ROS_WS/install $ROS_WS/install +COPY --from=builder $ROS_WS/install $ROS_WS/install -# source ros package from entrypoint +# source entrypoint setup RUN sed --in-place --expression \ '$isource "$ROS_WS/install/setup.bash"' \ /ros_entrypoint.sh -# run ros package launch file +# run launch file CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` From e71b10d3e6fba71f08cebbee7685f6390dc9a436 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 26 Nov 2019 17:46:32 -0800 Subject: [PATCH 26/47] Add links to target support reps --- ros/content.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ros/content.md b/ros/content.md index 91d113d33e3a..4cb724f7561b 100644 --- a/ros/content.md +++ b/ros/content.md @@ -102,6 +102,8 @@ Developing such complex systems with cutting edge implementations of newly publi 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. +For a complete listing of supported architecture and base images for each ROS Distribution Release, please read the official REP on target platforms for either [ROS 1](https://www.ros.org/reps/rep-0003.html) or for [ROS 2](https://www.ros.org/reps/rep-2000.html). + ## 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: From 1a14579709f45a4ab8677875254b7b14c40aa056 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 26 Nov 2019 18:14:44 -0800 Subject: [PATCH 27/47] Update metrics --- ros/content.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ros/content.md b/ros/content.md index 4cb724f7561b..cf1098c857ff 100644 --- a/ros/content.md +++ b/ros/content.md @@ -88,9 +88,9 @@ 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/ros app-multi-stage 66c8112b2fb6 4 seconds ago 775MB - my/ros app-single-stage 6b500239d0d6 2 minutes ago 797MB + REPOSITORY TAG IMAGE ID CREATED SIZE + my/ros runner 66c8112b2fb6 2 seconds ago 818MB + my/ros builder 6b500239d0d6 9 seconds ago 867MB 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. From a1c20bd640124604bec8be7103fb8d5ccad990de Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 26 Nov 2019 18:51:44 -0800 Subject: [PATCH 28/47] Add minimal ros1_bridge example --- ros/content.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/ros/content.md b/ros/content.md index cf1098c857ff..de00bbf89dc3 100644 --- a/ros/content.md +++ b/ros/content.md @@ -181,6 +181,49 @@ $ docker-compose rm > Note: the auto-generated network, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`. +### ROS 1 Bridge + +To ease ROS 2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS 2 package that provides bidirectional communication between ROS 1 and ROS 2. As a minimal example, given the ROS 2 Dockerfile above, we'll create the ROS 1 equivalent bellow, and name the Dockerfile appropriately. + + +```dockerfile +FROM ros:melodic + +# install ros package +RUN apt-get update && apt-get install -y \ + ros-${ROS_DISTRO}-ros-tutorials \ + ros-${ROS_DISTRO}-common-tutorials && \ + rm -rf /var/lib/apt/lists/* + +# launch ros package +CMD ["roslaunch", "roscpp_tutorials", "talker_listener.launch"] +``` + +The compose file bellow spawns services for both talker listener demos while connecting the two via a dynamic bridge. You may then view the log output from both pairs of talker and listener nodes cross talking over the `/chatter` topic. + +```yaml +version: '3' + +services: + ros1: + build: + context: . + dockerfile: ros1.Dockerfile + + ros2: + build: + context: . + dockerfile: ros2.Dockerfile + + bridge: + image: osrf/ros:dashing-ros1-bridge + environment: + - "ROS_HOSTNAME=bridge" + - "ROS_MASTER_URI=http://ros1:11311" + command: ros2 run ros1_bridge dynamic_bridge + +``` + # More Resources [ROS.org](http://www.ros.org/): Main ROS website From 32e1ffe1a7a976f30b6f4a981d5af498d35489a3 Mon Sep 17 00:00:00 2001 From: Ruffin Date: Wed, 27 Nov 2019 12:48:52 -0800 Subject: [PATCH 29/47] Fix Formatting --- ros/content.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index de00bbf89dc3..a8baf11feae7 100644 --- a/ros/content.md +++ b/ros/content.md @@ -185,7 +185,6 @@ $ docker-compose rm To ease ROS 2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS 2 package that provides bidirectional communication between ROS 1 and ROS 2. As a minimal example, given the ROS 2 Dockerfile above, we'll create the ROS 1 equivalent bellow, and name the Dockerfile appropriately. - ```dockerfile FROM ros:melodic @@ -221,7 +220,6 @@ services: - "ROS_HOSTNAME=bridge" - "ROS_MASTER_URI=http://ros1:11311" command: ros2 run ros1_bridge dynamic_bridge - ``` # More Resources From 6d09179854033de0cc43bbf426832b327c6575f5 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 13:06:07 -0700 Subject: [PATCH 30/47] Update More Resources --- ros/content.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ros/content.md b/ros/content.md index a8baf11feae7..0e624c614763 100644 --- a/ros/content.md +++ b/ros/content.md @@ -225,10 +225,17 @@ services: # More Resources [ROS.org](http://www.ros.org/): Main ROS website -[Docs](https://index.ros.org/doc/ros2/): Core Documentation -[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 +[Q&A](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 +[Packages](https://index.ros.org/packages/): Discover indexed packages [OSRF](https://www.osrfoundation.org/): Open Source Robotics Foundation + +## ROS 2 + +[Index](https://index.ros.org/doc/ros2/): ROS 2 Documentation +[Design](https://design.ros2.org/): ROS 2 Design Articles + +## ROS 1 + +[Wiki](http://wiki.ros.org/Documentation): ROS 1 Documentation From 2cd312f7bcb94f1059227d4b434f8e18ac9d84ba Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 13:26:38 -0700 Subject: [PATCH 31/47] Dont split up ros version tokens for SEO most users seach for ros2 when looking for ros2 docs. also avoids conflating ros2 with ros1 --- ros/content.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ros/content.md b/ros/content.md index 0e624c614763..6484c5f97380 100644 --- a/ros/content.md +++ b/ros/content.md @@ -102,13 +102,13 @@ Developing such complex systems with cutting edge implementations of newly publi 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. -For a complete listing of supported architecture and base images for each ROS Distribution Release, please read the official REP on target platforms for either [ROS 1](https://www.ros.org/reps/rep-0003.html) or for [ROS 2](https://www.ros.org/reps/rep-2000.html). +For a complete listing of supported architecture and base images for each ROS Distribution Release, please read the official REP on target platforms for either [ROS1](https://www.ros.org/reps/rep-0003.html) or for [ROS2](https://www.ros.org/reps/rep-2000.html). ## 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-core`: barebone ROS 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/ros/). 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. @@ -181,9 +181,9 @@ $ docker-compose rm > Note: the auto-generated network, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`. -### ROS 1 Bridge +### ROS1 Bridge -To ease ROS 2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS 2 package that provides bidirectional communication between ROS 1 and ROS 2. As a minimal example, given the ROS 2 Dockerfile above, we'll create the ROS 1 equivalent bellow, and name the Dockerfile appropriately. +To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent bellow, and name the Dockerfile appropriately. ```dockerfile FROM ros:melodic @@ -231,11 +231,11 @@ services: [Packages](https://index.ros.org/packages/): Discover indexed packages [OSRF](https://www.osrfoundation.org/): Open Source Robotics Foundation -## ROS 2 +## ROS2 -[Index](https://index.ros.org/doc/ros2/): ROS 2 Documentation -[Design](https://design.ros2.org/): ROS 2 Design Articles +[Index](https://index.ros.org/doc/ros2/): ROS2 Documentation +[Design](https://design.ros2.org/): ROS2 Design Articles -## ROS 1 +## ROS1 -[Wiki](http://wiki.ros.org/Documentation): ROS 1 Documentation +[Wiki](http://wiki.ros.org/Documentation): ROS1 Documentation From 966f6ae9412ede3710effaaac87e07d677b6a834 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 13:30:25 -0700 Subject: [PATCH 32/47] Keep ros org landing page as main link --- ros/content.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index 6484c5f97380..bc68309a99f8 100644 --- a/ros/content.md +++ b/ros/content.md @@ -1,10 +1,10 @@ -# What is [ROS](https://index.ros.org/doc/ros2)? +# What is [ROS](https://www.ros.org/)? 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. > [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) -[%%LOGO%%](https://index.ros.org/doc/ros2) +[%%LOGO%%](https://www.ros.org/) # How to use this image From f685e2833fce31d610618e7acdaeafbacef2ffbd Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 13:34:13 -0700 Subject: [PATCH 33/47] Update size given no-install-recommends changes --- ros/content.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index bc68309a99f8..cdd999f40f7d 100644 --- a/ros/content.md +++ b/ros/content.md @@ -89,8 +89,8 @@ 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/ros runner 66c8112b2fb6 2 seconds ago 818MB - my/ros builder 6b500239d0d6 9 seconds ago 867MB + my/ros runner 66c8112b2fb6 2 seconds ago 654MB + my/ros builder 6b500239d0d6 9 seconds ago 859MB 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. From 379df849badb678d1b5714153913f4cb46f89c16 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 13:36:19 -0700 Subject: [PATCH 34/47] Spell check --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index cdd999f40f7d..42c91398ad31 100644 --- a/ros/content.md +++ b/ros/content.md @@ -183,7 +183,7 @@ $ docker-compose rm ### ROS1 Bridge -To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent bellow, and name the Dockerfile appropriately. +To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent below, and name the Dockerfile appropriately. ```dockerfile FROM ros:melodic From 66047eb35ddebd762aa29f2bce2c6e2cf678a6a4 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 14:57:26 -0700 Subject: [PATCH 35/47] Update examples --- ros/content.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/ros/content.md b/ros/content.md index 42c91398ad31..530aa7afd46b 100644 --- a/ros/content.md +++ b/ros/content.md @@ -44,7 +44,8 @@ $ docker run -it --rm my/ros:app To create your own ROS 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%%:dashing-ros-base AS builder +ARG ROS_TAG=%%IMAGE%%:foxy +FROM $ROS_TAG-ros-base AS builder # clone package source ENV ROS_WS /opt/ros_ws @@ -60,6 +61,7 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ rosdep install -y \ --from-paths \ src/demos/demo_nodes_cpp \ + src/demos/demo_nodes_py \ --ignore-src && \ rm -rf /var/lib/apt/lists/* @@ -68,10 +70,11 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ --packages-select \ demo_nodes_cpp \ + demo_nodes_py \ --mixin release # create new multi-stage -FROM %%IMAGE%%:dashing-ros-core AS runner +FROM $ROS_TAG-ros-core AS runner # copy package install ENV ROS_WS /opt/ros_ws @@ -86,13 +89,15 @@ RUN sed --in-place --expression \ 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. +Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the demo C++ and Python packages, 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. + +For these particular packages, the tag used for the runner image consequently includes the necessary runtime dependencies for the talker and listener examples, however such may not always be the case. For example, starting a container from the runner image with the command `ros2 launch demo_nodes_cpp add_two_ints.launch.py` will fail, as that depends on `example_interfaces` package that are not installed here. Additionally, in interests of keeping `ros-core` tag minimal in image size, developer tools such as `rosdep` and `colcon` are not shipped in `ros_core`, but in `ros-base` instead. REPOSITORY TAG IMAGE ID CREATED SIZE my/ros runner 66c8112b2fb6 2 seconds ago 654MB my/ros builder 6b500239d0d6 9 seconds ago 859MB -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. +Although using a multi-stage build didn't shrink the final image by much, 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 runtime vs development dependency discrepancies you may have otherwise forgotten to declare in your `package.xml` manifest. ## Deployment use cases @@ -108,7 +113,7 @@ For a complete listing of supported architecture and base images for each ROS Di 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 install +- `ros-core`: minimal ROS 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/ros/). 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. @@ -146,11 +151,11 @@ version: '3' services: talker: - build: ./Dockerfile + build: ./ command: ros2 run demo_nodes_cpp talker listener: - build: ./Dockerfile + build: ./ command: ros2 run demo_nodes_py listener ``` @@ -206,12 +211,12 @@ version: '3' services: ros1: build: - context: . + context: ./ dockerfile: ros1.Dockerfile ros2: build: - context: . + context: ./ dockerfile: ros2.Dockerfile bridge: From b4f8a1387c009dc6228d91f8ce30b23f1941bf21 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 14:58:09 -0700 Subject: [PATCH 36/47] Fix logging for python node https://tarunlalwani.com/post/why-delayed-output-python-docker/ --- ros/content.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ros/content.md b/ros/content.md index 530aa7afd46b..545439a610ec 100644 --- a/ros/content.md +++ b/ros/content.md @@ -156,6 +156,8 @@ services: listener: build: ./ + environment: + - "PYTHONUNBUFFERED=1" command: ros2 run demo_nodes_py listener ``` From 23bf362b2369c36acefb18fa7d85559fe1cf72aa Mon Sep 17 00:00:00 2001 From: ruffsl Date: Tue, 28 Apr 2020 15:05:41 -0700 Subject: [PATCH 37/47] Link external license resources like other images https://github.com/docker-library/docs/blob/master/ubuntu/license.md --- ros/license.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ros/license.md b/ros/license.md index 1a4907e6ace4..d15542ebd2c4 100644 --- a/ros/license.md +++ b/ros/license.md @@ -1,3 +1 @@ -The core of ROS 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 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. +View [package index](https://index.ros.org/packages/) for license information on software contained in this image. From cc17087d20d8b9d8c8ab147afd8341b60233ed69 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Wed, 29 Apr 2020 23:23:30 -0700 Subject: [PATCH 38/47] Stage changes to build example Story for rosdep with runner multidtage not yet ready or convincing. Demo example for development and caching workflow instead. --- ros/content.md | 79 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/ros/content.md b/ros/content.md index 545439a610ec..74939b3688eb 100644 --- a/ros/content.md +++ b/ros/content.md @@ -10,7 +10,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h ## Creating a `Dockerfile` to install ROS packages -To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos and security CLI using the official released Debian packages via apt-get. +To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos using the official released Debian packages via apt-get. ```dockerfile FROM %%IMAGE%%:dashing @@ -44,45 +44,66 @@ $ docker run -it --rm my/ros:app To create your own ROS 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 -ARG ROS_TAG=%%IMAGE%%:foxy -FROM $ROS_TAG-ros-base AS builder - -# clone package source -ENV ROS_WS /opt/ros_ws -RUN mkdir -p $ROS_WS/src -WORKDIR $ROS_WS -RUN git -C src clone \ - -b $ROS_DISTRO \ - https://github.com/ros2/demos.git - -# install package dependencies +ARG FROM_IMAGE=%%IMAGE%%:foxy +ARG OVERLAY_WS=/opt/ros/overlay_ws + +# multi-stage for caching +FROM $FROM_IMAGE AS cache + +# copy overlay source +ARG OVERLAY_WS +WORKDIR $OVERLAY_WS/src +RUN echo "\ +repositories: \n\ + ros2/demos: \n\ + type: git \n\ + url: https://github.com/ros2/demos.git \n\ + version: ${ROS_DISTRO} \n\ +" > ../overlay.repos +RUN vcs import ./ < ../overlay.repos \ + && find ./ -name ".git" | xargs rm -rf + +# copy manifests for caching +WORKDIR /opt +RUN mkdir -p /tmp/opt \ + && find ./ -name "package.xml" | \ + xargs cp --parents -t /tmp/opt \ + && find ./ -name "COLCON_IGNORE" | \ + xargs cp --parents -t /tmp/opt || true + +# multi-stage for building +FROM $FROM_IMAGE AS build + +# copy overlay manifests +ARG OVERLAY_WS +WORKDIR $OVERLAY_WS +COPY --from=cache /tmp/$OVERLAY_WS/src ./src + +# install overlay dependencies RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ - apt-get update && rosdep update && \ - rosdep install -y \ + apt-get update && rosdep install -y \ --from-paths \ - src/demos/demo_nodes_cpp \ - src/demos/demo_nodes_py \ - --ignore-src && \ - rm -rf /var/lib/apt/lists/* + src/ros2/demos/demo_nodes_cpp \ + src/ros2/demos/demo_nodes_py \ + --ignore-src \ + && rm -rf /var/lib/apt/lists/* + +# copy overlay source +COPY --from=cache $OVERLAY_WS/src ./src -# build package workspace +# build overlay source +ARG OVERLAY_MIXINS="release" RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ --packages-select \ demo_nodes_cpp \ demo_nodes_py \ - --mixin release - -# create new multi-stage -FROM $ROS_TAG-ros-core AS runner - -# copy package install -ENV ROS_WS /opt/ros_ws -COPY --from=builder $ROS_WS/install $ROS_WS/install + --mixin $OVERLAY_MIXINS # source entrypoint setup +ENV OVERLAY_WS $OVERLAY_WS RUN sed --in-place --expression \ - '$isource "$ROS_WS/install/setup.bash"' \ + '$isource "$OVERLAY_WS/install/setup.bash"' \ /ros_entrypoint.sh # run launch file From 2316f47c7a5fd869ed096d5e1df75cd6978f8eee Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 30 Apr 2020 15:41:34 -0700 Subject: [PATCH 39/47] Update example --- ros/content.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/ros/content.md b/ros/content.md index 74939b3688eb..081a389aaad6 100644 --- a/ros/content.md +++ b/ros/content.md @@ -48,9 +48,9 @@ ARG FROM_IMAGE=%%IMAGE%%:foxy ARG OVERLAY_WS=/opt/ros/overlay_ws # multi-stage for caching -FROM $FROM_IMAGE AS cache +FROM $FROM_IMAGE AS cacher -# copy overlay source +# clone overlay source ARG OVERLAY_WS WORKDIR $OVERLAY_WS/src RUN echo "\ @@ -60,26 +60,24 @@ repositories: \n\ url: https://github.com/ros2/demos.git \n\ version: ${ROS_DISTRO} \n\ " > ../overlay.repos -RUN vcs import ./ < ../overlay.repos \ - && find ./ -name ".git" | xargs rm -rf +RUN vcs import ./ < ../overlay.repos && \ + find ./ -name ".git" | xargs rm -rf # copy manifests for caching WORKDIR /opt -RUN mkdir -p /tmp/opt \ - && find ./ -name "package.xml" | \ - xargs cp --parents -t /tmp/opt \ - && find ./ -name "COLCON_IGNORE" | \ +RUN mkdir -p /tmp/opt && \ + find ./ -name "package.xml" | \ + xargs cp --parents -t /tmp/opt && \ + find ./ -name "COLCON_IGNORE" | \ xargs cp --parents -t /tmp/opt || true # multi-stage for building -FROM $FROM_IMAGE AS build +FROM $FROM_IMAGE AS builder -# copy overlay manifests +# install overlay dependencies ARG OVERLAY_WS WORKDIR $OVERLAY_WS -COPY --from=cache /tmp/$OVERLAY_WS/src ./src - -# install overlay dependencies +COPY --from=cacher /tmp/$OVERLAY_WS/src ./src RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ apt-get update && rosdep install -y \ --from-paths \ @@ -88,10 +86,8 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ --ignore-src \ && rm -rf /var/lib/apt/lists/* -# copy overlay source -COPY --from=cache $OVERLAY_WS/src ./src - # build overlay source +COPY --from=cacher $OVERLAY_WS/src ./src ARG OVERLAY_MIXINS="release" RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ From 522d608d39c9016f4ac72f4fec507b56215e65a1 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 16:48:52 -0700 Subject: [PATCH 40/47] Add links to tools --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index 081a389aaad6..1065ab89fd73 100644 --- a/ros/content.md +++ b/ros/content.md @@ -108,7 +108,7 @@ 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 C++ and Python packages, 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. -For these particular packages, the tag used for the runner image consequently includes the necessary runtime dependencies for the talker and listener examples, however such may not always be the case. For example, starting a container from the runner image with the command `ros2 launch demo_nodes_cpp add_two_ints.launch.py` will fail, as that depends on `example_interfaces` package that are not installed here. Additionally, in interests of keeping `ros-core` tag minimal in image size, developer tools such as `rosdep` and `colcon` are not shipped in `ros_core`, but in `ros-base` instead. +For these particular packages, the tag used for the runner image consequently includes the necessary runtime dependencies for the talker and listener examples, however such may not always be the case. For example, starting a container from the runner image with the command `ros2 launch demo_nodes_cpp add_two_ints.launch.py` will fail, as that depends on `example_interfaces` package that are not installed here. Additionally, in interests of keeping `ros-core` tag minimal in image size, developer tools such as [`rosdep`](https://github.com/ros-infrastructure/rosdep), [`colcon`](https://colcon.readthedocs.io/en/released/) and [`vcstools`](https://github.com/vcstools/vcstools) are not shipped in `ros_core`, but in `ros-base` instead. REPOSITORY TAG IMAGE ID CREATED SIZE my/ros runner 66c8112b2fb6 2 seconds ago 654MB From 50a2c27fdbd5beba435ff1a98967e6f87c15a1e4 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 16:51:46 -0700 Subject: [PATCH 41/47] Link to relevent reps on variants --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index 1065ab89fd73..76b1be925e59 100644 --- a/ros/content.md +++ b/ros/content.md @@ -133,7 +133,7 @@ The available tags include supported distros along with a hierarchy tags based o - `ros-core`: minimal ROS 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/ros/). 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. +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/ros/). 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. For a extensive list of available variants, please read the official REP on target platforms for either [ROS1](https://ros.org/reps/rep-0150.html) or for [ROS2](https://www.ros.org/reps/rep-2001.html). ### Volumes From dd187b97919b0d2bdf5a99b8f41a67b2c3920b30 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 18:41:32 -0700 Subject: [PATCH 42/47] Simplify example no need to demo cleaning of ephemeral .git files to improve determinism --- ros/content.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index 76b1be925e59..e2aa635c18a4 100644 --- a/ros/content.md +++ b/ros/content.md @@ -60,8 +60,7 @@ repositories: \n\ url: https://github.com/ros2/demos.git \n\ version: ${ROS_DISTRO} \n\ " > ../overlay.repos -RUN vcs import ./ < ../overlay.repos && \ - find ./ -name ".git" | xargs rm -rf +RUN vcs import ./ < ../overlay.repos # copy manifests for caching WORKDIR /opt From 957be64edf3274c78707f48a5f895fec60b10298 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 18:42:42 -0700 Subject: [PATCH 43/47] Update explanation of example --- ros/content.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ros/content.md b/ros/content.md index e2aa635c18a4..49502adb8919 100644 --- a/ros/content.md +++ b/ros/content.md @@ -105,15 +105,11 @@ RUN sed --in-place --expression \ 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 C++ and Python packages, 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. - -For these particular packages, the tag used for the runner image consequently includes the necessary runtime dependencies for the talker and listener examples, however such may not always be the case. For example, starting a container from the runner image with the command `ros2 launch demo_nodes_cpp add_two_ints.launch.py` will fail, as that depends on `example_interfaces` package that are not installed here. Additionally, in interests of keeping `ros-core` tag minimal in image size, developer tools such as [`rosdep`](https://github.com/ros-infrastructure/rosdep), [`colcon`](https://colcon.readthedocs.io/en/released/) and [`vcstools`](https://github.com/vcstools/vcstools) are not shipped in `ros_core`, but in `ros-base` instead. +The example above starts by using [`vcstools`](https://github.com/vcstools/vcstools) to clone source repos of interest into the cacher stage. One could similarly `COPY` code from the local build context into the source directory as well. Package manifest files are then cached in a temporary directory where the following builder stage may copy from to install necessary dependencies with [`rosdep`](https://github.com/ros-infrastructure/rosdep). This is done prior copying the rest of the source files to preserve the multi stage build cache, given unaltered manifests do not altered declared dependencies, saving time and bandwidth. The overlay is then built using [`colcon`](https://colcon.readthedocs.io/en/released/), the entrypoint updated to source the workspace, and the default command set to launch the demo. - REPOSITORY TAG IMAGE ID CREATED SIZE - my/ros runner 66c8112b2fb6 2 seconds ago 654MB - my/ros builder 6b500239d0d6 9 seconds ago 859MB +Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the demo C++ and Python packages, 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. -Although using a multi-stage build didn't shrink the final image by much, 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 runtime vs development dependency discrepancies you may have otherwise forgotten to declare in your `package.xml` manifest. +For more advance examples such as daisy chaining multiple overlay workspaces to improve caching of docker image build layers, using tools such as ccache to accelerate compilation with colcon, or using buildkit to save build time and bandwidth even when dependencies change, the provided `Dockerfile`s in the [Navigation2](https://github.com/ros-planning/navigation2) repo are excellent resources. ## Deployment use cases @@ -132,6 +128,8 @@ The available tags include supported distros along with a hierarchy tags based o - `ros-core`: minimal ROS install - `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) +In the interest of keeping `ros-core` tag minimal in image size, developer tools such as `rosdep`, `colcon` and `vcstools` are not shipped in `ros_core`, but in `ros-base` instead. + 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/ros/). 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. For a extensive list of available variants, please read the official REP on target platforms for either [ROS1](https://ros.org/reps/rep-0150.html) or for [ROS2](https://www.ros.org/reps/rep-2001.html). ### Volumes From 2f8fd67e8e4d12aaeab11d819db7f2ed8ce1b72e Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 18:44:36 -0700 Subject: [PATCH 44/47] Fix markdown linter --- ros/content.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ros/content.md b/ros/content.md index 49502adb8919..edee4b3f0115 100644 --- a/ros/content.md +++ b/ros/content.md @@ -109,7 +109,7 @@ The example above starts by using [`vcstools`](https://github.com/vcstools/vcsto Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the demo C++ and Python packages, 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. -For more advance examples such as daisy chaining multiple overlay workspaces to improve caching of docker image build layers, using tools such as ccache to accelerate compilation with colcon, or using buildkit to save build time and bandwidth even when dependencies change, the provided `Dockerfile`s in the [Navigation2](https://github.com/ros-planning/navigation2) repo are excellent resources. +For more advance examples such as daisy chaining multiple overlay workspaces to improve caching of docker image build layers, using tools such as ccache to accelerate compilation with colcon, or using buildkit to save build time and bandwidth even when dependencies change, the project `Dockerfile`s in the ROS2 [Navigation2](https://github.com/ros-planning/navigation2) repo are excellent resources. ## Deployment use cases @@ -204,7 +204,7 @@ $ docker-compose rm ### ROS1 Bridge -To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent below, and name the Dockerfile appropriately. ++To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent below, and name the Dockerfile appropriately. ```dockerfile FROM ros:melodic @@ -255,8 +255,8 @@ services: ## ROS2 [Index](https://index.ros.org/doc/ros2/): ROS2 Documentation -[Design](https://design.ros2.org/): ROS2 Design Articles +[Design](https://design.ros2.org/): ROS2 Design Articles ## ROS1 -[Wiki](http://wiki.ros.org/Documentation): ROS1 Documentation +[Wiki](http://wiki.ros.org/Documentation): ROS1 Documentation From 38e428668a41fb5048a322b6e7bcad42f1fc7880 Mon Sep 17 00:00:00 2001 From: ruffsl Date: Thu, 21 May 2020 18:53:42 -0700 Subject: [PATCH 45/47] Update tags to foxy and noetic --- ros/content.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ros/content.md b/ros/content.md index edee4b3f0115..e587caf58fc0 100644 --- a/ros/content.md +++ b/ros/content.md @@ -13,7 +13,7 @@ The Robot Operating System (ROS) is a set of software libraries and tools that h To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos using the official released Debian packages via apt-get. ```dockerfile -FROM %%IMAGE%%:dashing +FROM %%IMAGE%%:foxy # install ros package RUN apt-get update && apt-get install -y \ @@ -207,7 +207,7 @@ $ docker-compose rm +To ease ROS2 migration, [`ros1_bridge`](https://index.ros.org/p/ros1_bridge/github-ros2-ros1_bridge) is a ROS2 package that provides bidirectional communication between ROS1 and ROS2. As a minimal example, given the ROS2 Dockerfile above, we'll create the ROS1 equivalent below, and name the Dockerfile appropriately. ```dockerfile -FROM ros:melodic +FROM %%IMAGE%%:noetic # install ros package RUN apt-get update && apt-get install -y \ @@ -236,7 +236,7 @@ services: dockerfile: ros2.Dockerfile bridge: - image: osrf/ros:dashing-ros1-bridge + image: osrf/ros:foxy-ros1-bridge environment: - "ROS_HOSTNAME=bridge" - "ROS_MASTER_URI=http://ros1:11311" From c30501601474826b44a5584f291eb0a67378e9a4 Mon Sep 17 00:00:00 2001 From: Ruffin Date: Tue, 26 May 2020 16:43:21 -0700 Subject: [PATCH 46/47] Correct vcstool link Co-authored-by: Mikael Arguedas --- ros/content.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros/content.md b/ros/content.md index e587caf58fc0..7d61d0375e6e 100644 --- a/ros/content.md +++ b/ros/content.md @@ -105,7 +105,7 @@ RUN sed --in-place --expression \ CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] ``` -The example above starts by using [`vcstools`](https://github.com/vcstools/vcstools) to clone source repos of interest into the cacher stage. One could similarly `COPY` code from the local build context into the source directory as well. Package manifest files are then cached in a temporary directory where the following builder stage may copy from to install necessary dependencies with [`rosdep`](https://github.com/ros-infrastructure/rosdep). This is done prior copying the rest of the source files to preserve the multi stage build cache, given unaltered manifests do not altered declared dependencies, saving time and bandwidth. The overlay is then built using [`colcon`](https://colcon.readthedocs.io/en/released/), the entrypoint updated to source the workspace, and the default command set to launch the demo. +The example above starts by using [`vcstool`](https://github.com/dirk-thomas/vcstool) to clone source repos of interest into the cacher stage. One could similarly `COPY` code from the local build context into the source directory as well. Package manifest files are then cached in a temporary directory where the following builder stage may copy from to install necessary dependencies with [`rosdep`](https://github.com/ros-infrastructure/rosdep). This is done prior copying the rest of the source files to preserve the multi stage build cache, given unaltered manifests do not altered declared dependencies, saving time and bandwidth. The overlay is then built using [`colcon`](https://colcon.readthedocs.io/en/released/), the entrypoint updated to source the workspace, and the default command set to launch the demo. Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the demo C++ and Python packages, 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. From cf84c67da5faa0293b2fbff60e8b2f1ddd455b42 Mon Sep 17 00:00:00 2001 From: Ruffin Date: Tue, 26 May 2020 16:45:56 -0700 Subject: [PATCH 47/47] Nit fix grammar Co-authored-by: Mikael Arguedas --- ros/content.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ros/content.md b/ros/content.md index 7d61d0375e6e..c48211eb4e5d 100644 --- a/ros/content.md +++ b/ros/content.md @@ -119,7 +119,7 @@ Developing such complex systems with cutting edge implementations of newly publi 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. -For a complete listing of supported architecture and base images for each ROS Distribution Release, please read the official REP on target platforms for either [ROS1](https://www.ros.org/reps/rep-0003.html) or for [ROS2](https://www.ros.org/reps/rep-2000.html). +For a complete listing of supported architectures and base images for each ROS Distribution Release, please read the official REP on target platforms for either [ROS1](https://www.ros.org/reps/rep-0003.html) or for [ROS2](https://www.ros.org/reps/rep-2000.html). ## Deployment suggestions @@ -150,7 +150,7 @@ Some application may require device access for acquiring images from connected c ROS 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). +Alternatively, more permissive network setting can be used 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 to 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