最近需要折腾ROS,而ROS对Archlinux的支持可不是一般的差。曾经尝试过使用ROS官方上的安装方式[1]安装ROS Desktop,结果用yay安装了半天,不是网络错误就是依赖无法解析。于是想到了使用Docker部署ROS Desktop。
一开始还打算使用一个Ubuntu Docker镜像,然后再在里面慢慢搭建ROS的,结果一看ROS Wiki文档[2],好家伙,原来早就做好这种镜像了,还有带NVIDIA CUDA加速的。于是一步一步按照教程来就好啦。不过除了官方的文档,我们还需要做些优化才能很好地利用各种features。
准备安装
首先我们需要在主机上安装NVIDIA为各发行版打包好的Docker镜像。对于NVIDIA支持的各发行版,可使用软件包管理器安装nvidia-docker2
软件包。而对于Archlinux,可从AUR安装:
yay -S nvidia-docker
还需安装libglvnd软件包:
sudo pacman -S libglvnd
自定义Docker镜像
创建一个文件夹my_ros_image
并进入,创建Dockerfile
文件:
mkdir my_ros_image & cd my_ros_image
touch Dockerfile
编辑Dockerfile文件,以定制我们的Docker镜像:
FROM osrf/ros:melodic-desktop-full
# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES \
${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES \
${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
FROM后面的是要基于哪个包定制镜像。这里我们使用的是ROS Melodic版本的,全部的镜像可以参照https://hub.docker.com/r/osrf/ros/tags?page=1&ordering=last_updated。最新的版本是noetic-desktop-full,相应地替换为osrf/ros:noetic-desktop-full即可基于Noetic制作镜像。
然后进入Dockerfile的文件夹,开始拉取和制作镜像:(别忘了第二行命令后面的点,表示在当前目录建立Docker镜像)
cd my_ros_image/
sudo docker build -t my_ros_image_melodic .
启动镜像
编写以下脚本启动镜像。
#!/bin/bash
XAUTH=/tmp/.docker.xauth
if [ ! -f $XAUTH ]
then
xauth_list=$(xauth nlist :0 | sed -e 's/^..../ffff/')
if [ ! -z "$xauth_list" ]
then
echo $xauth_list | xauth -f $XAUTH nmerge -
else
touch $XAUTH
fi
chmod a+r $XAUTH
fi
docker run -it \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--env="XAUTHORITY=$XAUTH" \
--volume="$XAUTH:$XAUTH" \
--runtime=nvidia \
my_melodic_image \
bash
给这个脚本赋予相应的权限:
chmod a+x ./start.sh
然后执行,即可启动一个ROS容器。
测试镜像
简单地,先启动这个容器,就会进入到这个容器的命令行界面。然后在容器内执行:
roscore > /dev/null & rosrun rviz rviz
如出现图形化界面,即启动成功。
其他技巧
在两个shell内执行命令
调试ROS的时候,我们可能需要不止两个shell,而若直接attach到容器,实际上访问的是一个shell。要启动另外一个容器里的shell,只需让容器再启动一个bash就可以了:
sudo docker exec -it CONTAINER_ID bash
CONTAINER_ID
在每次容器启动时都不一样,你可能需要通过sudo docker ps
来获取其ID。
Bash:命令找不到(Command not found)
默认情况下ROS的环境是由Docker建立的,在容器启动时即告诉容器里的系统应该如何初始化。所以直接启动bash是不会初始化ROS环境的。要使bash打开时初始化,仿照官方的ROS安装教程[3],需要在容器里执行:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
那么bash启动时即自动初始化ROS环境,即可解决命令找不到的错误了。但是这对于Docker镜像的更改只是临时的,请查看下一小节永久保存镜像。
永久保存镜像
有时候我们对镜像进行了修改,而Docker镜像一旦退出,其状态就不可保存,一切将恢复成原来的样子。若需要保存镜像,我们需要执行:
sudo docker commit CONTAINER_ID my_ros_image_noetic
CONTAINER_ID
在每次容器启动时都不一样,你可能需要通过sudo docker ps
来获取其ID。my_ros_image_noetic替换成你的镜像名称。
映射主机目录
很简单,在启动脚本文件里加上一行:--volume /主机目录:/镜像目录
即可,要注意处理好目录权限问题。
脚注和参考链接
[1] ROS Wiki 的方法是:使用yay从AUR仓库安装ros-version-desktop。链接:http://wiki.ros.org/melodic/Installation/ArchLinux
[2] ROS Hardware Acceleration:http://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration#nvidia-docker2
[3] ROS安装教程-配置环境http://wiki.ros.org/noetic/Installation/Ubuntu#noetic.2FInstallation.2FDebEnvironment.Environment_setup