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