ROS docker在安装主机显卡驱动后,rviz等可视化工具报错

问题描述

宿主机为ubuntu20.04,使用鱼香ros一键安装melodic版本的docker ros,未安装nvidia显卡驱动前正常使用melodic版的ros:
宿主机安装nvidia显卡驱动后,docker中的ros无法使用rviz等可视化工具,有如下报错:

rviz:RenderSystem:error creating render window:OGRE EXCEPTION(3:RenderingAPIException)
Unable to create a suitable GLXContext in GLXContext:GLXContext at /build/ogre-1.9-B6Q
kmW/ogre-1.9-1.9.0+dfsg1/RenderSystems/GL/src/GLX/OgreGLXContext.cpp (line 61)
ERROR][1689942254.7944979441:Unable to create the rendering window after 100 tries
INFO][1689942254.794503168]:Stereo is NOT SUPPORTED
terminate called after throwing an instance of 'std:logic_error
what():
basic_string::_M_construct null not valid
在这里插入图片描述
在后续使用中发现,在Ubuntu22中创建ros-noetic的容器,即使宿主机安装了显卡驱动,docker里面的ros在使用rviz等工具不会报错,但是输入nvidia-smi会提示找不到命令,且运行rviz显示的llvmpipe请添加图片描述

问题分析

参考这篇文章
ubuntu20.04安装NVIDIA驱动后docker中rviz,pcl_viewer等涉及到访问宿主机界面的程序不可用
这篇文章认为问题原因是宿主机和容器中opengl版本不一致,在docker中安装对应宿主机的显卡驱动版本后问题解决,本人经过尝试后问题还是没解决,驱动装好后rviz仍然报错,最后参考这篇文章成功解决。
在docker容器中使用nvidia显卡渲染rviz2界面
就是当前容器没法使用宿主机的gpu资源

解决方法

安装NVIDIA Container Runtime和nvidia-docker2使得容器能够访问和使用宿主机的GPU资源,仍然使用fishros2/ros:melodic-desktop-full镜像,修改构建容器docker run指令,加入 gpu设置 使得docker可以使用宿主机的GPU资源,重新构建容器。

1.宿主机安装显卡驱动

参考方法:

使用nvidia-smi测试驱动是否可用:
在这里插入图片描述

2. 安装NVIDIA Container Runtime和 nvidia-docker2

请添加图片描述

官网介绍

NVIDIA Container Toolkit使用户能够构建和运行GPU加速的容器。该工具包包括一个容器运行库和实用程序,用于自动配置容器以利用NVIDIA GPU。

配置存储库 并更新
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 容器进行测试:

ubuntu20.04 可以使用下面指令进行测试,docker会自动从nvidia/cuda拉取11.0.3-base-ubuntu20.04镜像,并创建一个运行一次即删除的容器

sudo docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi

其他版本ubuntu,可以从docker hub上搜索nvidia/cuda
请添加图片描述

以ubuntu22为例

sudo docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
测试结果:
  • ubuntu20
    在这里插入图片描述

  • ubuntu22
    请添加图片描述

3. 创建新容器

使用docker run命令 创建新容器

使用fishros2/ros:melodic-desktop-full镜像创建新的容器,fishros2/ros:melodic-desktop-full鱼香ros一键安装中选择melodic版本的ros容器使用的镜像
在这里插入图片描述
这里可以继续使用该镜像创建新容器,使用如下命令:

sudo docker run  -dit \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
--name=melodic_docker2 \
-v /home/yearner:/home/yearner \
-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/yearner fishros2/ros:melodic-desktop-full

其中:

  • -v:是把宿主机的目录挂载到容器中,/home/用户名 需要换成自己的用户名
  • --name:是容器名称,修改为自己的,需要记住后面还要用到

相比鱼香ros的原安装命令 增加了如下命令允许docker使用宿主机的显卡资源

--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \

下面的操作全部仿照鱼香ros一键安装的指令

运行docker 写入ROS的环境变量
docker exec -it melodic_docker2 /bin/bash -c "echo -e '
source /opt/ros/melodic/setup.bash' >> ~/.bashrc"
构建常用指令

这步操作是允许用户只使用容器名对容器进行操作,省去输入docker的原生指令

cd ~/.fishros/bin
sudo touch melodic_docker2
vi melodic_docker2
xhost +local: >> /dev/null
echo "请输入指令控制melodic_docker2: 重启(r) 进入(e) 启动(s) 关闭(c) 删除(d) 测试(t):"
read choose
case $choose in
s) docker start melodic_docker2;;
r) docker restart melodic_docker2;;
e) docker exec -it melodic_docker2 /bin/bash;;
c) docker stop melodic_docker2;;
d) docker stop melodic_docker2 && docker rm melodic_docker2 && sudo rm -rf /home/yearner/.fishros/bin/melodic_docker2;;
t) docker exec -it melodic_docker2  /bin/bash -c "source /ros_entrypoint.sh && roscore";;
esac
newgrp docker

melodic_docker2是容器名,更换成自己的容器名
输入:wq!强制保存,右键该文件点击属性,将权限中勾选允许文件作为程序执行

终端中输入容器名 即可正常使用容器
在这里插入图片描述

这样不用在容器中安装显卡驱动也可以直接查看到显卡的驱动信息
在这里插入图片描述

如果当前容器你已经使用了一段时间,安装了很多必要的ros、python的库和包,不想再重新开荒,个人使用经验:容器中的ros相比系统中直接安装的ros少了一些依赖库,可以将现有的容器打包成镜像,然后通过上述的操作重新构建容器,这样新构建的容器只比原容器多了可以访问宿主机的gpu

4.将已有的docker容器保存为镜像,利用该镜像创建新容器

通过docker exportdocker import 命令

导出容器
docker export 容器id > 压缩包名.tar

容器id 可以通过docker ps -a查看
在这里插入图片描述
在这里插入图片描述
会在当前目录下生成一个压缩包既为该容器的快照
请添加图片描述

导入容器

可以使用 docker import 从容器快照文件中再导入为镜像

cat  ros-melodic-docker.tar | docker import - test/ros:melodic-desktop-full

test/ros:melodic-desktop-full,test为作者 ros 为镜像名 melodic-desktop-full为标签

使用docker image ls查看系统里的镜像,快照已经恢复为镜像,大小发生相比原生fishros2/ros的镜像大了好多
在这里插入图片描述

使用恢复的镜像通过docker run命令创建新容器
sudo docker run  -dit \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
--name=melodic_docker2 \
-v /home/yearner:/home/yearner \
-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/yearner test/ros:melodic-desktop-full

直接改使用的镜像名会产生如下报错:

docker: Error response from daemon: No command specified.
See ‘docker run --help’.

在这里插入图片描述
运行导入的镜像创建容器,必须要带command
具体的command 可以通过docker ps --no-trunc命令在导出容器的时候查看
或者使用docker ps -a
在这里插入图片描述

command命令为/bin/bash
在docker run 命令 镜像名后面加上/bin/bash即可,成功

在这里插入图片描述

参考资料

创建docker容器报错:Error response from daemon: No command specified
Docker -从入门到实践
docker-菜鸟教程
Ubuntu下 NVIDIA Container Runtime 安装与使用
ubuntu20.04安装NVIDIA-docker

演示视频

来源:B站up主:每天都要笑得超甜
解决ubuntu20.04 安装docker ros melodic 无法打开rviz和gazebo 问题

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值