前言:
众所周知,不同的Ubuntu版本能安装的ROS版本是不一样的,小版本的区别(例如Melodic和noetic等等)暂且不提,其中最让人头疼的就是ROS1和ROS2大版本对于Ubuntu版本的要求区别:Ubuntu22.04只能安装ROS2的各个版本,如果想使用ROS1只能在Ubuntu20.04及以下版本安装。
所以一般来说使用ROS的用户都会选择安装Ubuntu20.04(ROS1和ROS2都支持),但是Ubuntu22.04对于一些驱动的支持又进行了很好的优化,如果安装了Ubuntu22.04还想使用ROS1,那么通过Docker安装ROS就成为了最好的选择。并且通过Docker安装ROS可以实现很好的隔离,甚至多个ROS版本共存也可以。
(其实小鱼大佬在鱼香ROS中有一键安装docker和通过docker安装ROS的指令:小鱼的一键安装系列,但是很多人用这个指令的时候连docker咋用还没搞清楚,还有可能因为例如镜像源等等问题在拉取镜像等步骤上,而且完全不了解一键安装的各个指令到底是干啥的,后面想根据自己的需求对容器做一些设置也不知道咋改,所以还是建议跟着教程看一看到底怎么实现的,对于每个参数都有详细的介绍)
通过Docker安装ROS首先得知道Docker怎么用,建议先通过我的前置教程安装docker并了解一下docker和一些基本的使用:Ubuntu 安装 docker及基础使用教程(包含显卡驱动设置)——小白专属避坑指南
一、拉取镜像
sudo docker pull osrf/ros:noetic-desktop-full
本教程以ROS-noetic版本为例,其他版本自行更换对应的镜像名称。
(一般ROS镜像命名都是
osrf/ros:版本号-desktop-full
)
其他常用版本:
osrf/ros:melodic-desktop-full
- ROS Melodic 桌面全功能版
osrf/ros:kinetic-desktop-full
- ROS Kinetic 桌面全功能版
osrf/ros:humble-desktop-full
- ROS2 Humble 桌面全功能版
osrf/ros:foxy-desktop-full
- ROS2 Foxy 桌面全功能版
(不需要全功能版可以把-full删掉)
二、创建容器
2.1. docker run创建
sudo docker run -dit \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
--name=your_name \
-v /dev:/dev \
-v /home/your_username:/home/your_username \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=unix$DISPLAY \
-w /home/your_username \
osrf/ros:noetic-desktop-full
xxx这里可以跟一些容器启动后想运行的命令(如果有命令上一行最后别忘了加换行符)
# 可选参数:
--privileged \
--net=host \
--restart=xxx \
参数说明:(\表示换行符)【更换your_name和your_username为自己的】
-dit
:-d:在后台运行容器、-it: 交互式运行容器,分配一个伪终端。--gpus all
: 将所有可用的 GPU 硬件设备分配给容器(从Docker19.03开始,–gpus 选项可以直接处理GPU分配,不再需要设置NVIDIA_VISIBLE_DEVICES 环境变量)-e NVIDIA_DRIVER_CAPABILITIES=all
:设置环境变量,允许容器内的所有 NVIDIA 驱动功能。--name=your_name
:为容器指定一个名称-v /dev:/dev
:将宿主机的 /dev 设备目录挂载到容器的 /dev 目录,允许容器访问宿主机的所有设备。(可以解决USB无法挂载问题)(也可以单独选择只挂载某些设备例如:声卡/dev/snd等等)-v /home/your_username:/home/your_username
:将宿主机的用户目录挂载到容器的同名目录,这样容器可以访问宿主机用户的文件。-v /tmp/.X11-unix:/tmp/.X11-unix
:将宿主机的 X11 sockets 目录挂载到容器,允许容器访问宿主机的图形用户界面会话。-e DISPLAY=unix$DISPLAY
:设置环境变量 DISPLAY,使其与宿主机的显示环境变量相同,对于图形应用程序来说是必要的。-w /home/your_username
:设置容器内的工作目录。osrf/ros:noetic-desktop-full
:镜像名称或者ID(改成自己对应的版本)
可选参数:
--privileged
:给予容器root权限,可以执行一些需要高级权限的操作(例如: 访问宿主机的所有设备节点(如/dev下的设备文件)、修改或加载内核模块、 访问宿主机的某些受保护的文件等等)。这会造成潜在的安全风险。因为容器内的进程可以直接影响到主机系统,如果恶意进程获得了容器的控制权,可能会对主机系统造成严重的损害,但是一般只是用来学习做实验的普通用户不太需要担心安全问题。--net=host
:让容器与宿主机的网络以host模式连接,host模式下,容器没有自己独立的网络空间,容器将直接使用宿主机的网络接口(此时与外部网络通信时无需做端口映射)。默认为桥接网络:每个容器有一个自己的独立IP地址。--restart=xxx
:no
:默认策略,在容器退出时不重启容器on-failure
:在容器非正常退出时,才会重启容器on-failure:n
:容器非正常退出时重启容器,并指定重启次数(不指定次数会一直重启直到启动成功)always
:只要容器退出就重启容器unless-stopped
:在容器退出时总是重启容器,除非它被手动停止或 Docker 本身被停止
三、使用容器
Docker用户权限问题:
默认情况下,需要使用sudo权限来运行Docker命令,通过将用户添加到Docker用户组,可以在无需sudo的情况下运行Docker命令。
(如果当前用户没有加入Docker用户组并且没有sudo权限的话,会报错:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock:
)
添加方法如下:
# Way1:将指定用户username加入到docker组
sudo gpasswd -a username docker
# Way2:将当前用户加入到docker组
sudo gpasswd -a $USER docker
newgrp docker #切换到docker组
3.1 通过命令运行【不推荐】
① 配置访问宿主机的 X11 服务器
说明:docker容器中打开gazebo等可视化页面需要访问宿主机的 X11 服务器。而X11服务默认只允许『来自本地的用户』启动的图形程序将图形显示在当前屏幕上。所以需要给docker添加访问权限(否则会报错No protocol specified),有以下几种方法:
# Way1:允许所有本地连接访问 X11 服务器
xhost +local: >> /dev/null
# Way2:单独给 docker 访问 X11 服务器的权限
xhost +local:docker
# Way3:单独给 docker 中的某个容器访问 X11 服务器的权限
xhost +local:`docker inspect --format='{{ .Config.Hostname }}' $containerId` # $containerId替换为容器ID
【注意:这个命令的效果是临时的,它将持续到 X11 服务器重启或
xhost -local:
命令被执行来撤销这个设置。最好每次都输入一下这个命令】
② 启动容器
sudo docker start 容器id/名称 #(noetic)
③ 进入容器
sudo docker exec -it noetic /bin/bash
# (输入 exit 可以退出容器)
④ source ros路径
source /opt/ros/noetic/setup.bash
# 每个终端都要输入这个命令source一下,或者:(如下)
# 添加到容器的.bashrc可避免每次都要输入【推荐】
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
注意:要根据自己的ros版本修改这个路径,例如humble版本:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
⑤ 测试ros是否运行成功
roscore
3.2 一键启动【推荐】
① 创建一个文件夹用于存放启动命令,然后cd进入
以
~/.docker/setup
文件夹为例
cd ~/.docker/setup
② 创建启动文件并编辑内容
这步操作是允许用户只使用容器名对容器进行操作,省去输入docker的原生指令
sudo nano your_name # 名称可以自定义,推荐和容器同名(noetic)
文件中输入以下内容并保存:
xhost +local:docker
echo "请输入指令控制[your_name]容器: 启动(s) 重启(r) 进入(e) 关闭(c):"
read choose
case $choose in
s) docker start [your_name];;
r) docker restart [your_name];;
e) docker exec -it [your_name] /bin/bash;;
c) docker stop noetic;;
esac
newgrp docker
说明:
- 其中
xhost +local:docker
是给docker添加X11访问权限,也可以改为xhost +local: >> /dev/null
表示允许所有本地用户连接到 X11 - 其中
docker xxx
是对应docker启动/重启/进入容器/关命令,可以根据docker的指令添加一些其他的命令,例如删除容器等等 esac
是用来结束 case 语句的,别给删了。newgrp docker
表示将当前shell会话的用户组切换到docker组,可以不使用sudo运行docker指令(需要确保你的用户账户已经被添加到docker组,前文中的【Docker用户权限问题】有提到)。
注意: 修改
[your_name]
为你的自定义名称。
③ 赋予文件可执行权限
sudo chmod +x 文件名(your_name)
④ 在~/.bashrc 中添加该文件所在路径
echo 'export PATH=$PATH:/home/your_username/.docker/setup' >> ~/.bashrc
⑤ 使用
设置好后任意终端中输入
容器名(noetic)
即可进入容器,进入容器后先一次性设置一下ROS的source:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
最后退出(输入
exit
)重新进入容器即可正常使用ros
其他注意事项:
进入ROS容器后先
sudo apt-get update
更新一下源,否则可能无法在容器内通过
apt install
安装其他包
版权归原作者 littlewells 所有, 如有侵权,请联系我们删除。