ROS docker使用显卡驱动rviz gazebo,以及接入外设和雷达
由于我的电脑装ubuntu22.04系统,想使用ros noetic开发,使用鱼香ros一键安装docker安装。但是启动dockek中rviz无法使用显卡驱动,usb相机端口不显示,网口雷达无法使用等问题
一、ROS docker安装后运行rviz报错,或者能启动rviz但是显示OPENGL llvmpipe
显示OPENGL llvmpipe虽然也能启动rviz,但是没有使用显卡加速(核显也没有用)强行cpu软件渲染,会导致很卡。这其中主要原因是容器无法访问主机的GPU资源
解决方法
这里参考这位博主的方法实测可以解决
https://blog.csdn.net/GritYearner/article/details/133679403
这里总结步骤为
1、主机安装nvidia显卡驱动,可以在ubuntu software updater中的附加驱动选择和是的驱动安装 ,安全快捷
安装完毕,重启电脑测试 nvidia-smi 出现类似如下打印,表示驱动正常。
2、 安装NVIDIA Container Runtime和 nvidia-docker2
配置存储库 并更新
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/stable/deb/nvidia-container-toolkit.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 \&& \sudo apt-get update
安装nvidia-docker2
sudo apt-get install -y nvidia-docker2
使用nvidia-ctk命令配置container runtime
sudo nvidia-ctk runtime configure --runtime=docker
重启docker系统:
sudo systemctl restart docker
运行nvidia cuda 容器进行测试:
以ubuntu22为例(拉取的镜像会在运行后删除)
sudo docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
出现类似如上的打印,表示docker可以调用主机的显卡。
3. 创建新容器
使用如下指令重新创建容器,
sudo docker run -dit \--gpus all \-e NVIDIA_DRIVER_CAPABILITIES=all \--name=noetic_docker \--network=host \--privileged \-v /dev/bus/usb:/dev/bus/usb \-v /home/gxl:/home/gxl \-v /tmp/.X11-unix:/tmp/.X11-unix \-v /dev/dri:/dev/dri \--device=/dev/snd \--device=/dev/dri/renderD128 \-e DISPLAY=unix$DISPLAY \-w /home/gxl \fishros2/ros:noetic-desktop-full
其中把/home/gxl 换成你自己的用户名
-name=noetic_docker换成你自己的容器名
fishros2/ros:noetic-desktop-full 换成你自己的镜像名,例如是fishros2/ros:melodic-desktop-full
相比鱼香ros的原安装命令 增加了如下命令允许docker使用宿主机的显卡资源
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all
容器直接复用宿主机的网络,不经过 Docker 的虚拟网桥(bridge)
--network=host
把宿主机(Host)上的 /dev/bus/usb 目录挂载到容器中的相同路径 /dev/bus/usb,实现 USB 总线设备的共享。
-v /dev/bus/usb:/dev/bus/usb
构建常用指令
如果需要构建构建类似鱼香ros的快捷启动关闭指令,可以在~/.fishros/bin路径下创建一个新的文件 在里面模仿鱼香ros启动
cd ~/.fishros/bin
sudo touch noetic_docker
vi noetic_docker
xhost +local: >> /dev/null
echo "请输入指令控制neotic_docker: 重启(r) 进入(e) 启动(s) 关闭(c) 删除(d) 测试(t):"
read choose
case $choose in
s) docker start noetic_docker;;
r) docker restart noetic_docker;;
e) docker exec -it noetic_docker /bin/bash;;
c) docker stop noetic_docker;;
d) docker stop noetic_docker && docker rm noetic_docker && sudo rm -rf /home/gxl/.fishros/bin/noetic_docker;;
t) docker exec -it noetic_docker /bin/bash -c "source /ros_entrypoint.sh && roscore";;
esac
newgrp docker
noetic_docker这个名字换成你自己的容器名称
二、容器直接复用宿主机的网络连接雷达
主要是在创建容器时候加入–network=host 这个参数,如果安装上文中的方法创建容器,那么已经包含这个操作
三、容器读取摄像头等usb口设备
创建容器时加入如下参数,-v /dev/bus/usb:/dev/bus/usb
-v /dev/bus/usb:/dev/bus/usb
是 Docker 命令中的一个 挂载参数,意思是:
把宿主机的 /dev/bus/usb 设备目录挂载到容器的同路径下。这样让容器可以访问 USB 设备,比如:
相机(如 RealSense、工业相机)
USB 串口设备
激光雷达
USB dongle(加密狗)
USB硬盘等
四、将已有的docker容器重新创建新容器
如果机器现在已经有了容器,并且容器中已经编译或者保存了很多数据和依赖,此时有需要增加主机网络、gpu渲染或者读取usb口设备。此时创建新容器又不想丢弃已有容器内的数据,可以将已有容器打包成镜像,再 基于这个镜像创建新容器
1. 将已有容器打包成镜像
假设你已有容器叫 my_running_container:
执行
docker commit my_running_container my_custom_image:latest
这条命令的作用是:
把 my_running_container 容器的当前状态打包成一个新镜像
命名为 my_custom_image:latest
例如
docker commit noetic_docker noetic_docker_udapte:latest
此时把之前已有的noetic_docker 打包为noetic_docker_udapte
2. 用这个镜像创建新容器
使用指令重新创建容器
sudo docker run -dit \--gpus all \-e NVIDIA_DRIVER_CAPABILITIES=all \--name=noetic_docker \--network=host \--privileged \-v /dev/bus/usb:/dev/bus/usb \-v /home/gxl:/home/gxl \-v /tmp/.X11-unix:/tmp/.X11-unix \-v /dev/dri:/dev/dri \--device=/dev/snd \--device=/dev/dri/renderD128 \-e DISPLAY=unix$DISPLAY \-w /home/gxl \noetic_docker_udapte
可选:保存成 .tar 文件(打包分发用)
docker save -o my_image.tar my_custom_image:latest
传给其他机器后:
docker load -i my_image.tar