Docker与ROS

date
May 7, 2022
Property
slug
DockerLoveROS
status
Published
tags
工程经验
summary
如何在Docker下使用ROS
type
Post

Docker下ROS的安装

目前虽然有了小鱼的fishros.com可以非常方便快速的安装ROS,但是在实际的部署中,要是有基于Docker的ROS可以非常方便快速的部署,同时也可以避免每个人不同的环境部署问题,在我觉得Docker对于工程部署落地具有挺大的意义。

Docker基础镜像的安装

这里选用了Ubuntu18.04、Cuda10.2作为其基础镜像,原因还是因为18是目前算是资料最多的,Cuda10.2是目前支持各类Pytorch最多的。

iamge的制作

Dockerfile的制作
#!/bin/bash
ARG CUDA="10.2"
ARG SYSTEM="18.04"

FROM nvidia/cuda:${CUDA}-devel-ubuntu${SYSTEM}

RUN apt-key del 7fa2af80

RUN apt update; exit 0

# 需要安装tzdata,不然安装ROS会出现报错
RUN apt-get install -y tzdata 

RUN apt install git -y && \
    apt install wget

RUN apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/3bf863cc.pub

RUN wget -qO - https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub | apt-key add -

RUN apt update

CMD echo 'source /etc/profile' >> ~/.bashrc

# 安装相关库
RUN apt-get update && \
    apt-get install -y \
    build-essential \
    libgl1-mesa-dev \
    libglew-dev \
    libsdl2-dev \
    libsdl2-image-dev \
    libglm-dev \
    libfreetype6-dev \
    libglfw3-dev \
    libglfw3 \
    libglu1-mesa-dev \
    freeglut3-dev \
    vim

# conda安装
RUN wget -q https://repo.anaconda.com/miniconda/Miniconda3-py37_4.8.3-Linux-x86_64.sh && \
    sh ./Miniconda3-py37_4.8.3-Linux-x86_64.sh -b -p /opt/conda && \
    rm ./Miniconda3-py37_4.8.3-Linux-x86_64.sh && \
    export PATH=$PATH:/opt/conda/bin && \
    conda install conda-build

ENV PATH $PATH:/opt/conda/envs/env/bin:/opt/conda/bin

CMD source ~/.bashrc

CMD ["/bin/bash"]
setup_dev.bash文件
#!/bin/bash

u18_cuda102_gcc7_docker() {
  echo "starting U18_Cuda102_GCC7 docker"
  xhost +local:docker;
  docker run -it -d \
    --runtime=nvidia \
    --name="U18_Cuda102_GCC7_dev" \
    -v /etc/localtime:/etc/localtime:ro \
    -v /dev/input:/dev/input \
		# 文件挂载的位置要设置成为自己的位置
    -v "/media/henry/HenryDataDisk/MyDockerFiles/PaperDataset:$HOME/docker_shared" \
    -v "$U18_Cuda102_GCC7_GIT:$HOME/paper_code" \
    --shm-size=6G \
    --workdir $HOME/ \
    --net=host \
    --add-host U18_Cuda102_GCC7_dev:127.0.0.1 \
    --hostname=U18_Cuda102_GCC7_dev \
    --privileged=true \
    --env=DISPLAY \
    --env=XDG_RUNTIME_DIR \
    --env=QT_X11_NO_MITSHM=1 \
    --device=/dev/dri:/dev/dri \
    -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
    -v /etc/localtime:/etc/localtime:ro \
    $U18_Cuda102_GCC7_DOCKER

    u18_cuda102_gcc7_docker_attach;
}

u18_cuda102_gcc7_go(){
  docker exec -it -e "COLUMNS=$COLUMNS" -e "LINES=$LINES" U18_Cuda102_GCC7_dev /bin/bash
}

u18_cuda102_gcc7_docker_attach() {
  docker exec -it -e "COLUMNS=$COLUMNS" -e "LINES=$LINES" U18_Cuda102_GCC7_dev /bin/bash
}
按照如下的步骤执行
  • Dockerfile文件目录下启动终端并执行:
    • docker build -t u18_cuda102_gcc7:latest .
  • 等image构建完成,开始依次在终端中执行如下:
    • export U18_Cuda102_GCC7_DOCKER=u18_cuda102_gcc7:latest
      export U18_Cuda102_GCC7_GIT=/home/henry/DockerEnvSetup/U18_Cuda102_GCC7  # update
      source $U18_Cuda102_GCC7_GIT/docker/setup_dev.bash
  • 在终端中启动镜像:
    • u18_cuda102_gcc7_docker
  • 在启动镜像之后,要初始化conda,运行如下:
    • conda init
      source ~/.bashrc

ROS的安装

  • 在ROS安装前要保证安装tzdata,不知道为什么不这样做在安装过程中总是会卡在这一步
    • apt-get install -y tzdata 
  • 因为在添加源的时候会出现lsb_release: not found,所以要先执行如下
    • apt-get update && apt-get install -y lsb-release && apt-get clean all
    • 如果出现:
      • E: Malformed entry 1 in list file /etc/apt/sources.list.d/ros-latest.list (Component)
        E: The list of sources could not be read.
    • 依次执行:
      • rm /etc/apt/sources.list.d/ros-latest.list 
        apt-get update && apt-get install -y lsb-release && apt-get clean all
  • 设置软件源,个人还是比较推崇直接用官方国外源,之前用国内源出现一些很奇怪不好解决的问题:
    • 国外源:
      • sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
    • 国内源:
      • sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
  • 设置密钥:
    • apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654
  • 安装:
    • apt-get update
      apt-get install ros-melodic-desktop-full
      apt-get install ros-melodic-rqt*
  • 初始化rosdep:
    • rosdep init
      rosdep update
  • 安装rosinstall:
    • apt-get install python-rosinstall
  • 加载环境变量设置文件:
    • source /opt/ros/melodic/setup.bash
  • 创建并初始化工作目录
    • ROS使用一个名为catkin的ROS专用构建系统。为了使用它,用户需要创建并初始化,catkin工作目录,如下所示。除非用户创建新的工作目录,否则此设置只需设置一次。
      mkdir -p ~/catkin_ws/src
      cd ~/catkin_ws/src
      catkin_init_workspace
      目前,只有src目录和CMakeLists.txt文件在catkin工作目录中,使用catkin_make命令来构建。
      cd ~/catkin_ws/
      catkin_make
  • 设置环境变量
    • sudo apt install net-tools
      gedit ~/.bashrc
      在其后面粘贴如下:
      其中的ip如下获得:
      notion image
      # Set ROS melodic
      source /opt/ros/melodic/setup.bash
      source ~/catkin_ws/devel/setup.bash
       
      # Set ROS Network
      #ifconfig
      export ROS_HOSTNAME=192.168.89.135
      export ROS_MASTER_URI=http://${ROS_HOSTNAME}:11311
       
      # Set ROS alias command
      alias cw='cd ~/catkin_ws'
      alias cs='cd ~/catkin_ws/src'
      alias cm='cd ~/catkin_ws && catkin_make'
  • 使用vscode使用docker container连接,为了后面的开发和多个终端的开启,接着在非docker的终端中运行:
    • xhost +
      使得可以x11可以被调用可视化。
      然后开始跑小乌龟测试:
      roscore
      rosrun turtlesim turtlesim_node
      rosrun turtlesim turtle_teleop_key
      测试Rviz可视化
      roscore
      rosrun rviz rviz
      安装完成!
      在使用中可能需要安装这包:
      pip install rospkg
      镜像的保存:
      docker commit -a 'lintheyoung' -m 'u18_cuda102_gcc7_ros-rviz' cecf24068fe6 u18_cuda102_ros:last

Docker中ROS的通讯

Abstract

notion image

Detail

还是使用docker去做通讯的测试:
# pull对应ubuntu16-18的镜像
docker pull ros:kinetic
docker pull ros:melodic

# 查看images
docker images
在主机启动ROS:
# 先ifconfig查看主机(非Docker)的ip
ifconfig
notion image
其中的11311端口是固定的:
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.1
roscore
在Docker_0中启动:
先要查看刚才pull下来的ROS各个版本的images:
docker images
主要是查看后面的ID(圆圈):
notion image
后面对应启动即可:
notion image
# docker ros:kinetic start
docker run -it a3c5711abb29

# net-tools install
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.3

# topic publish start
rostopic pub -r 10 /chatter std_msgs/String "this is ros:kinetic"
同理启动另一个Docker:
# docker ros:melodic start
docker run -it cc08986d42e5

# net-tools install
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.4

# topic listen start
rostopic echo /chatter

# return
>> data: "this is ros:kinetic"
在同个Master下都可以查看收发:
notion image
时延小于0.5ms
notion image

References:

ROS多个Docker通信
?完全消除开发环境/运行时对应用程序的依赖非常困难。 ROS某些应用程序依赖于特定的版本或软件包。 (例如,旋律依赖) 使用docker,您可以消除上述情况,并且应用程序提供商不必担心系统。 ?开发环境和运行时对于每个应用程序都是免费的,并且使用docker易于理解界面。 使用多个泊坞窗启动ROS节点,并检查是否可以进行通信。 使用多个泊坞窗启动ROS2节点,并检查是否可以进行通信。 使用多个泊坞窗启动ROS / ROS2节点,并检查是否可以使用ros1_bridge在ROS / ROS2之间进行通信。 (*)ROS rosmaster将在主机上运行。所有其他ROS / ROS2节点都与docker一起运行。 主机Linux:Ubuntu16.04.5 LTS Docker:18.09.0,构建4d60db4 主机Linux ROS版本:动态 省略了主机Linux ROS和docker本身的安装设置。 (如果您使用Google,则可以) [概述] [步骤] 1-1。在主机Linux 上启动roscore 1-2。罗斯:从Kinecit docker 开始发布者 1-3。ROS:用旋律docker 启动子程序 (当然)我能够确认ROS节点之间可以进行Pub / Sub通信。 [概述] 2-1。ros2:充气桌面通过docker 启动发布者 2-2。ros2:弹性桌面通过docker 启动订户 在ROS2节点上可以在docker之间进行通信。 [概述] 3-1。在主机Linux 上启动roscore 3-2。ROS:使用旋律docker 启动发布者 3-3。docker ros2:bouncy-ros1-bridge start 3-4。ros2:以有弹性的桌面docker 启动订阅者 我能够使用ROS桥确认docker之间的ROS / ROS2通信。 使用 ,可以使用docker轻松完成ROS分布式开发。
ROS多个Docker通信

© Lin Deyang 2022 - 2025