在docker运行ros及其可视化
文章目录
- 一、背景
- 二、创建镜像
- 1. 拉取 镜像
- 2. 允许本地机器上的用户或进程连接到 X server
- 3. 创建容器
- 3. 1 简单创建docker (不含gpu)
- 3. 2 创建调用主机的N卡docker
- 4. 显示rviz和gazebo
- 4.1 启动多个terminal
- 三、配置环境保存
一、背景
工作原因安装的ubuntu22.04,由于ros1与环境冲突,为了不影响项目,因此选择在docker中搭建ros1环境,从而与本地环境隔离,但会引入docker中无法可视化的问题,而ros常需与rviz及gazebo可视化界面配合开发,以下提供可视化的解决方案。
二、创建镜像
1. 拉取 镜像
docker pull osrf/ros:noetic-desktop-full
相关版本镜像按需选择:
镜像标签 🏷️ | 适用的Ubuntu版本 | Docker Pull 命令 |
---|---|---|
noetic-desktop-full | Ubuntu 20.04 | docker pull osrf/ros:noetic-desktop-full |
melodic-desktop-full | Ubuntu 18.04 | docker pull osrf/ros:melodic-desktop-full |
kinetic-desktop-full | Ubuntu 16.04 | docker pull osrf/ros:kinetic-desktop-full |
humble-desktop-full | Ubuntu 22.04 | docker pull osrf/ros:humble-desktop-full |
foxy-desktop-full | Ubuntu 20.04 | docker pull osrf/ros:foxy-desktop-full |
更多选择: osrf/ros 或 fishros2 docker
2. 允许本地机器上的用户或进程连接到 X server
xhost +local:docker
3. 创建容器
3. 1 简单创建docker (不含gpu)
docker run -it --network host --volume=/tmp/.X11-unix:/tmp/.X11-unix --device=/dev/dri:/dev/dri --device=/dev/snd --env="DISPLAY=$DISPLAY" --env="QT_X11_NO_MITSHM=1" --name=docker_ubuntu20.04 osrf/ros:noetic-desktop-full
参数说明:
- docker run:Docker命令,用于运行一个新的容器实例。
-it:这是两个选项的组合。
- -i(交互式):保持标准输入(stdin)打开,允许你与容器进行交互。
- -t(伪终端):为容器分配一个伪终端(pseudo-TTY),这样你可以像在普通终端中一样与容器交互。
--network host:设置容器的网络模式为宿主机的网络模式。这意味着容器将使用宿主机的网络栈,容器中的应用程序可以直接使用宿主机的IP地址和端口。
--volume=/tmp/.X11-unix:/tmp/.X11-unix:将宿主机的X11 Unix套接字目录挂载到容器内的相同路径。X11使用这个套接字进行客户端(容器内的图形应用)和服务器(宿主机X11服务器)之间的通信。这样容器内的图形应用就可以通过这个套接字与宿主的X11服务器通信,从而显示窗口。
--device=/dev/dri:/dev/dri:将宿主机的Direct Rendering Infrastructure(DRI)设备挂载到容器内。DRI用于直接访问图形硬件,允许容器内的应用程序使用宿主机的GPU进行硬件加速渲染。这对于运行3D图形应用(如RViz)非常重要。
--device=/dev/snd:将宿主机的声卡设备挂载到容器内。这样容器内的应用程序就可以播放声音。
--env="DISPLAY=$DISPLAY":设置环境变量DISPLAY,其值为宿主的DISPLAY环境变量的值。这个环境变量告诉X11客户端(容器内的图形应用)如何连接到X11服务器。通常,DISPLAY的值类似于:0或:1,表示使用哪个显示。
--env=“QT_X11_NO_MITSHM=1”:设置环境变量QT_X11_NO_MITSHM=1。这是Qt库的一个环境变量,用于禁用MIT-SHM(共享内存)扩展。在某些系统上,使用共享内存可能会导致X11连接问题,设置这个变量可以避免此类问题。
--name=docker_ubuntu20.04:为容器指定一个名称,这里是docker_ubuntu20.04。这样你可以通过名称来管理容器(例如,启动、停止、删除等)。
osrf/ros:noetic-desktop-full:要运行的Docker镜像的名称和标签。
3. 2 创建调用主机的N卡docker
3.2.1 配置仓库和GPG密钥
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
3.2.2 更新软件包列表并安装工具包
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
# 重启 Docker服务
sudo systemctl restart docker
3.2.3 创建 docker
# 法1
XSOCK=/tmp/.X11-unix && XAUTH=/tmp/.docker.xauth
touch $XAUTH && xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -it --rm --gpus all --network host --privileged -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 -e XAUTHORITY=$XAUTH -e NVIDIA_DRIVER_CAPABILITIES=all -e NVIDIA_VISIBLE_DEVICES=all -e __GLX_VENDOR_LIBRARY_NAME=nvidia -v $XSOCK:$XSOCK:rw -v $XAUTH:$XAUTH:rw -v /dev:/dev -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v /dev/dri:/dev/dri -v /home/$USER/gene/ubuntu20:/home/rosuser/workspace --name ros-noetic-container osrf/ros:noetic-desktop-full bash# ----------------------------------------------------------------------------------------# 法2
docker run -it --rm --gpus all --network host --privileged -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 -e XAUTHORITY=/tmp/.docker.xauth -e NVIDIA_DRIVER_CAPABILITIES=all -e NVIDIA_VISIBLE_DEVICES=all -e __GLX_VENDOR_LIBRARY_NAME=nvidia -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v /tmp/.docker.xauth:/tmp/.docker.xauth:rw -v /dev:/dev -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v /dev/dri:/dev/dri -v /home/lucas/project/docker/ubuntu20:/home/rosuser/workspace --workdir /home/rosuser/workspace --name ros-noetic-container osrf/ros:noetic-desktop-full bash
参数说明:
- --rm: 当容器退出时自动删除容器。
- --gpus all: 允许容器使用所有可用的GPU。这需要Docker已经配置了NVIDIA Container Toolkit;
- --network host: 将容器使用宿主机的网络栈。容器将共享宿主机的IP地址和网络端口,不需要进行端口映射
- --privileged: 给容器完全的权限,包括访问所有设备。这通常用于需要访问硬件设备(如USB、GPU等)的容器
- 环境变量设置(-e)
- -e DISPLAY=$DISPLAY: 将宿主机的DISPLAY环境变量传递给容器,这样容器内的图形应用程序可以显示在宿主机的屏幕上。
- -e QT_X11_NO_MITSHM=1: 设置QT库不使用共享内存,避免在Docker容器中运行QT应用程序时出现的问题
- -e XAUTHORITY=$XAUTH: 设置X11认证文件的位置,通常与-v X A U T H : XAUTH: XAUTH:XAUTH:rw一起使用来允许容器通过X11认证
- -e NVIDIA_DRIVER_CAPABILITIES=all: 设置NVIDIA驱动程序的能力,这里设置为所有能力,包括图形和计算
- -e NVIDIA_VISIBLE_DEVICES=all: 使容器可以看到所有NVIDIA GPU设备
- -e __GLX_VENDOR_LIBRARY_NAME=nvidia: 设置GLX供应商库为NVIDIA,这样容器内的OpenGL应用程序将使用NVIDIA的GLX库
- 卷挂载(-v):
- -v $XSOCK:$XSOCK:rw: 将宿主机的X11套接字目录挂载到容器内,可读写。X11套接字用于图形显示。
- -v $XAUTH:$XAUTH:rw: 将X11认证文件挂载到容器内,可读写。
- -v /dev:/dev: 将宿主机的/dev目录挂载到容器内,这样容器可以访问宿主机的设备文件。这通常与–privileged一起使用,以便容器可以直接访问硬件设备。
- -v /tmp/.X11-unix:/tmp/.X11-unix:rw: 挂载X11 Unix域套接字,这是另一种X11通信方式。
- -v /dev/dri:/dev/dri: 挂载Direct Rendering Infrastructure设备,用于硬件加速的图形显示。
- -v /home/$USER/gene/ubuntu20:/home/rosuser/workspace: 将宿主机的目录
/home/$USER/gene/ubuntu20
挂载到容器内的/home/rosuser/workspace
目录,这样可以在容器内访问宿主机上的文件- –workdir /home/rosuser/workspace: 使用-w或–workdir 参数来设置docker 默认工作目录;
4. 显示rviz和gazebo
4.1 启动多个terminal
docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES06280a754827 osrf/ros:noetic-desktop-full "/ros_entrypoint.sh …" 3 seconds ago Up 2 seconds ros-noetic-container#
# docker exec -it [container_id] bash
docker exec -it 06280a754827 bash# 或 docker exec -it [container_name] bash
docker exec -it ros-noetic-container bash
三、配置环境保存
参看 docker 学习命令整理 之 14. 保存docker新配置及发布。