XTDrone仿真平台在Docker下的ROS-Noetic环境配置指南
1. 为什么选择Docker+ROS Noetic来跑XTDrone?
如果你和我一样,是个喜欢折腾无人机仿真的开发者,肯定对XTDrone不陌生。它是一个基于PX4和ROS的无人机仿真平台,功能强大,社区也活跃。但官方文档和大多数教程,都默认你在Ubuntu 18.04上使用ROS Melodic。这就有个问题:现在新买的电脑,或者想用更新的系统特性,装的往往是Ubuntu 20.04或22.04,对应的ROS版本是Noetic。直接在Noetic上装XTDrone,就像让新零件去适配老机器,各种依赖冲突、编译错误能让你怀疑人生。
我当初就踩了这个坑,折腾了好几天,环境都没配利索。后来一想,为什么不把问题隔离起来呢?于是想到了Docker。用Docker容器来封装一个纯净的ROS Noetic环境,就像给XTDrone准备了一个专属的、与世隔绝的“小房间”。在这个房间里,所有依赖都是为它量身定制的,不会和宿主机上其他软件打架。而且,Docker镜像可以随时打包、分发、回滚,今天配好了环境,明天换台电脑,一条命令就能恢复,再也不用重复“配环境-报错-重装系统”的噩梦循环了。
所以,这篇指南的核心思路就是:在Docker容器里,搭建一个ROS Noetic环境,然后在这个“干净”的环境里,搞定XTDrone的所有依赖和编译。 这样,你既能用上更新的ROS Noetic,又能完美运行XTDrone。实测下来,这套方案非常稳定,我已经用它跑通了多个仿真场景。下面,我就把每一步的操作细节、可能遇到的坑以及我的解决办法,毫无保留地分享给你。
2. 准备工作:宿主机环境与Docker基础配置
在开始构建我们的“仿真小房间”之前,得先确保“地基”是稳固的。这里的地基就是你的宿主机(也就是你真正的电脑系统)和Docker本身。
首先,宿主机系统。我强烈推荐使用Ubuntu 20.04或22.04 LTS版本,它们对Docker和NVIDIA显卡驱动的支持最好。如果你是Windows或macOS用户,虽然也能通过Docker Desktop运行,但在图形显示(GUI)和GPU直通上会遇到更多麻烦,这篇指南主要针对Linux环境。确保你的系统已经更新到最新:sudo apt update && sudo apt upgrade -y。
其次,安装Docker。如果你的系统还没有Docker,可以去官网按照指南安装。安装完成后,一个非常重要的步骤是将你的用户加入docker用户组,这样以后运行Docker命令就不需要每次都加sudo了,会方便很多。命令是:sudo usermod -aG docker $USER。执行后,你需要完全退出当前终端会话并重新登录,这个改动才会生效。你可以运行 docker ps 测试一下,如果不报权限错误,就说明成功了。
第三,NVIDIA Docker支持。因为XTDrone的Gazebo仿真需要3D图形渲染,用上GPU能大幅提升流畅度。所以我们需要安装NVIDIA Container Toolkit。先确保宿主机已经安装了合适的NVIDIA驱动(可以通过 nvidia-smi 命令检查)。然后,添加NVIDIA的仓库并安装工具包:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt update && sudo apt install -y nvidia-container-toolkit
sudo systemctl restart docker
安装完成后,可以用 docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi 来测试。如果能看到和宿主机一样的GPU信息输出,恭喜你,Docker已经能调用你的显卡了。
最后,解决图形显示问题。Docker容器默认是看不到宿主机的图形界面的,但Gazebo和Rviz都需要GUI。这里我们用 -v /tmp/.X11-unix:/tmp/.X11-unix 和 -e DISPLAY 这两个参数把宿主机的显示服务“共享”给容器。为了安全起见,在宿主机上先运行 xhost +local: (注意,这会在当前会话降低X服务器的访问控制,仅用于开发环境)。这样,准备工作就完成了。
3. 拉取与启动ROS Noetic基础镜像
地基打好,我们就可以开始盖房子了。第一步是获取一个已经装好ROS Noetic的“毛坯房”——也就是Docker镜像。从头构建一个ROS镜像很耗时,好在社区里有现成的优秀镜像。我试过好几个,最后发现fishros2/ros:noetic-desktop-full这个镜像非常靠谱,它基于Ubuntu 20.04,预装了完整的ROS Noetic桌面版、Gazebo11以及很多常用工具,省去了我们大量基础安装的时间。
我们用下面这条命令来拉取并启动容器。这条命令看起来有点长,但每个参数都有用,我拆开给你解释:
sudo docker run -dit \
--gpus all \
--name=ros-noetic-xtdrone \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=$DISPLAY \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-e NVIDIA_VISIBLE_DEVICES=all \
-v /dev/dri:/dev/dri \
--device=/dev/dri/renderD128 \
-v /home/$USER/xtdrone_ws:/root/xtdrone_ws \
-w /root \
fishros2/ros:noetic-desktop-full \
/bin/bash
-dit:d让容器在后台运行,i保持标准输入打开,t分配一个伪终端。这样容器就像个后台服务,我们又能随时进去操作。--gpus all:把宿主机的所有GPU都透传给容器,这是之前安装NVIDIA Container Toolkit后的成果。--name:给容器起个名字,方便后续管理,比如ros-noetic-xtdrone。-v /tmp/.X11-unix:/tmp/.X11-unix和-e DISPLAY=$DISPLAY:这对组合拳把宿主机的图形界面共享给容器。-e NVIDIA_DRIVER_CAPABILITIES=all和-e NVIDIA_VISIBLE_DEVICES=all:设置NVIDIA环境变量,确保容器内能完整使用GPU的计算和图形能力。-v /dev/dri:/dev/dri和--device=/dev/dri/renderD128:这两行是为了更好的硬件加速渲染,特别是针对Intel集成显卡,能提升Gazebo的启动速度和运行性能。-v /home/$USER/xtdrone_ws:/root/xtdrone_ws:这是一个非常关键的映射。我们把宿主机的一个目录(比如/home/你的用户名/xtdrone_ws)挂载到容器内的/root/xtdrone_ws。这样,所有在容器里这个目录下的代码和编译产物,都会实际保存在宿主机上。即使容器被删除,你的工作成果也不会丢失。强烈建议你使用这个映射。-w /root:设置容器启动后的初始工作目录。- 最后是指定镜像和启动命令。
命令运行后,容器就在后台启动了。我们可以用 docker exec -it ros-noetic-xtdrone /bin/bash 进入容器。进去后,先来个经典测试:运行 roscore。如果看到ROS master启动的日志,没有报错,就说明ROS Noetic环境基本正常。你也可以运行 rosversion -d 确认一下版本是noetic。
4. 容器内环境深度配置:从Anaconda到Catkin工作空间
进入容器,我们相当于来到了一个全新的Ubuntu系统。虽然ROS基础环境有了,但要跑XTDrone,还需要安装不少“家具”和“电器”。
首先安装Anaconda。XTDrone的一些Python脚本对库版本有要求,用Anaconda管理Python环境会更干净。我们下载一个比较稳定的版本(比如2022.05)来安装:
cd /root
wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh
bash Anaconda3-2022.05-Linux-x86_64.sh
安装过程中,会问你把Anaconda安装到哪里,直接回车用默认的/root/anaconda3就行。还会问你是否初始化conda,选择yes。安装完成后,退出当前终端并重新进入容器,或者执行 source /root/.bashrc,这样conda命令才能生效。你可以用 conda --version 验证一下。
接下来,创建并配置Catkin工作空间。Catkin是ROS的构建系统,我们的XTDrone代码最终要在这里编译。
mkdir -p /root/catkin_ws/src
cd /root/catkin_ws
catkin init
catkin build
在编译之前,我们需要安装一堆系统依赖和Python包。这里我整理了一个比较全的列表,可以一次性安装,避免后续编译时缺这少那:
apt update && apt install -y \
aptitude ninja-build exiftool protobuf-compiler \
libeigen3-dev genromfs xmlstarlet \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
python3-pip gawk python3-catkin-tools vim git wget
Python包的管理是个容易出问题的地方。为了加速下载,我们先换一下pip源(用国内镜像):
mkdir -p ~/.pip
echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple" > ~/.pip/pip.conf
然后安装XTDrone和PX4编译所需的Python包。注意,有些包需要指定版本,比如pyulog:
pip3 install --upgrade setuptools pip
pip3 install numpy pandas jinja2 pysserial cerberus pyulog==0.7.0 toml pyquaternion empy pyyaml
pip3 install packaging pyargparse kconfiglib jsonschema future catkin_pkg rospkg
这里有个小技巧:如果某个包安装特别慢或者失败,可以临时换源试试,比如 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名。完成这些后,再回到/root/catkin_ws目录下执行一次catkin build,应该能顺利通过。这步成功,说明我们的Catkin工作空间和基础Python环境已经就绪了。
5. 安装与适配Gazebo和MAVROS
XTDrone的仿真视觉靠Gazebo,与飞控的通信靠MAVROS,这两者是仿真平台的核心桥梁。
关于Gazebo。我们使用的fishros2/ros:noetic-desktop-full镜像已经自带了Gazebo 11。官方XTDrone教程可能基于更老的Gazebo 9,但经过我的测试,Gazebo 11完全兼容,而且性能更好,所以我们不需要降级。不过,我们需要安装一些ROS和Gazebo交互的插件包:
apt install -y \
ros-noetic-gazebo-ros-pkgs \
ros-noetic-gazebo-ros-control \
ros-noetic-moveit-msgs \
ros-noetic-object-recognition-msgs \
ros-noetic-octomap-msgs \
ros-noetic-camera-info-manager \
ros-noetic-control-toolbox \
ros-noetic-polled-camera \
ros-noetic-controller-manager \
ros-noetic-transmission-interface \
ros-noetic-joint-limits-interface
安装完成后,可以简单测试一下:新开一个终端,在宿主机运行 xhost + (确保容器有显示权限),然后在容器内运行 gazebo --verbose。如果能看到Gazebo的空场景窗口弹出来,并且没有报错,说明Gazebo和图形显示都配置成功了。
接下来是MAVROS。它是ROS节点和PX4飞控(或SITL仿真器)之间的通信枢纽。安装很简单:
apt install -y ros-noetic-mavros ros-noetic-mavros-extras
光安装软件包还不够,MAVROS需要地理信息数据库才能进行精确的地理位置计算。官方提供了一个脚本自动下载:
wget https://gitee.com/robin_shaun/XTDrone/raw/master/sitl_config/mavros/install_geographiclib_datasets.sh
chmod +x install_geographiclib_datasets.sh
sudo ./install_geographiclib_datasets.sh
注意这个脚本需要sudo权限,因为它会把数据安装到系统目录。运行时间可能稍长,因为它要下载大约几百MB的数据,请耐心等待完成。完成后,MAVROS的准备工作就做好了。
6. 核心步骤:PX4 Firmware与XTDrone源码的编译与整合
这是整个配置过程中最核心、也最容易出错的一步。我们需要两套代码:PX4官方固件(Firmware)和XTDrone团队提供的适配代码与模型。
第一步,获取并配置PX4 Firmware。 我们使用PX4 v1.13.2这个与XTDrone兼容的版本。
cd /root
git clone https://github.com/PX4/PX4-Autopilot.git
mv PX4-Autopilot PX4_Firmware
cd PX4_Firmware
git checkout v1.13.2
git submodule update --init --recursive
切换分支和更新子模块会下载大量代码,请保持网络通畅。完成后,运行PX4提供的环境设置脚本(跳过仿真工具安装,因为我们在容器里用ROS的Gazebo):
bash ./Tools/setup/ubuntu.sh --no-sim-tools
然后尝试编译PX4的SITL(软件在环)目标:
make px4_sitl_default gazebo
如果编译成功,你会看到终端开始输出PX4的启动日志,并尝试启动Gazebo。先按Ctrl+C终止它。这步编译是为了验证PX4源码本身在容器环境里是否能正常构建。
第二步,获取XTDrone源码并整合。 XTDrone的代码提供了针对PX4的启动文件、世界文件、Gazebo插件和模型,这是让PX4 SITL和ROS、Gazebo联动起来的关键。
cd /root
git clone https://gitee.com/robin_shaun/XTDrone.git
cd XTDrone
git checkout 1_13_2
git submodule update --init --recursive
现在,开始关键的整合操作。我们需要把XTDrone里的配置文件,复制到PX4 Firmware的对应目录下覆盖或补充:
# 复制启动脚本
cp -r /root/XTDrone/sitl_config/init.d-posix/* /root/PX4_Firmware/ROMFS/px4fmu_common/init.d-posix/
# 复制ROS启动文件
cp -r /root/XTDrone/sitl_config/launch/* /root/PX4_Firmware/launch/
# 复制Gazebo世界文件
cp /root/XTDrone/sitl_config/worlds/* /root/PX4_Firmware/Tools/sitl_gazebo/worlds/
# 复制自定义的Gazebo插件(如云台、风场插件)
cp /root/XTDrone/sitl_config/gazebo_plugin/gimbal_controller/gazebo_gimbal_controller_plugin.cpp /root/PX4_Firmware/Tools/sitl_gazebo/src/
cp /root/XTDrone/sitl_config/gazebo_plugin/gimbal_controller/gazebo_gimbal_controller_plugin.hh /root/PX4_Firmware/Tools/sitl_gazebo/include/
cp /root/XTDrone/sitl_config/gazebo_plugin/wind_plugin/gazebo_ros_wind_plugin_xtdrone.cpp /root/PX4_Firmware/Tools/sitl_gazebo/src/
cp /root/XTDrone/sitl_config/gazebo_plugin/wind_plugin/gazebo_ros_wind_plugin_xtdrone.h /root/PX4_Firmware/Tools/sitl_gazebo/include/
# 复制关键的CMakeLists.txt,确保插件被编译
cp /root/XTDrone/sitl_config/CMakeLists.txt /root/PX4_Firmware/Tools/sitl_gazebo/
# 复制仿真模型(无人机、传感器等)
cp -r /root/XTDrone/sitl_config/models/* /root/PX4_Firmware/Tools/sitl_gazebo/models/
第三步,处理模型冲突。 这里有个经典的坑。如果宿主机之前运行过Gazebo,可能在~/.gazebo/models/目录下缓存了一些模型。如果这些模型和XTDrone提供的模型重名,会导致Gazebo加载错模型而崩溃。保险起见,我们检查并删除可能冲突的:
cd ~/.gazebo/models/
rm -rf stereo_camera/ 3d_lidar/ 3d_gpu_lidar/ hokuyo_lidar/ 2>/dev/null || true
2>/dev/null || true的意思是,如果文件不存在,忽略错误继续执行。
第四步,重新编译并解决编译错误。 复制完所有文件后,必须重新编译PX4,因为CMakeLists.txt和源代码都改了。
cd /root/PX4_Firmware
rm -rf build/ # 清除旧的编译缓存
make px4_sitl_default gazebo
在编译过程中,你很可能会遇到一个关于typhoon_h480模型的错误,提示会覆盖一个.sdf文件。这是因为XTDrone的模型目录里既有模板文件.jinja,又有生成好的.sdf文件,而PX4的编译脚本希望只从.jinja生成。解决方法很简单,把现成的.sdf文件备份一下:
mv /root/PX4_Firmware/Tools/sitl_gazebo/models/typhoon_h480/typhoon_h480.sdf /root/PX4_Firmware/Tools/sitl_gazebo/models/typhoon_h480/typhoon_h480.sdf.bak
然后再次运行 make px4_sitl_default gazebo。这次编译应该能顺利完成了。当编译结束,Gazebo窗口弹出,里面有一个默认的无人机模型(通常是Iris),并且PX4的终端在不停地打印日志,那就意味着PX4 SITL与Gazebo的联动成功了!这是里程碑式的一步。
7. 编译XTDrone的ROS功能包与最终环境变量设置
PX4和Gazebo跑通了,现在要把ROS这边最后的拼图完成——编译XTDrone的ROS功能包。
首先,我们需要把XTDrone中提供的ROS包(主要是对gazebo_ros_pkgs的一些修改或扩展)复制到我们的Catkin工作空间:
cp -r /root/XTDrone/sitl_config/gazebo_ros_pkgs /root/catkin_ws/src/
然后,进入工作空间进行编译。由于我们之前已经安装好了所有依赖,这次编译应该比较顺利:
cd /root/catkin_ws
catkin build
编译过程会处理gazebo_ros_pkgs以及它依赖的所有ROS包。请耐心等待,直到看到[100%]的完成提示,并且没有红色错误信息。
最后,也是最关键的一步:设置环境变量。 我们需要让系统知道PX4 Firmware和ROS工作空间的位置。编辑容器内的/root/.bashrc文件,在末尾添加以下几行:
source /root/catkin_ws/devel/setup.bash
source /root/PX4_Firmware/Tools/setup_gazebo.bash /root/PX4_Firmware/ /root/PX4_Firmware/build/px4_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:/root/PX4_Firmware
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:/root/PX4_Firmware/Tools/sitl_gazebo
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/root/PX4_Firmware/Tools/sitl_gazebo/models
- 第一行:激活我们刚刚编译的Catkin工作空间。
- 第二行:激活PX4提供的Gazebo环境设置脚本,它设置了Gazebo查找模型和插件的路径。
- 第三、四行:将PX4的固件目录和Gazebo插件目录加入到ROS的包搜索路径中,这样
roslaunch命令才能找到PX4提供的启动文件。 - 第五行:确保Gazebo能找到PX4和XTDrone提供的所有仿真模型。
添加完成后,执行 source /root/.bashrc 让配置立即生效。现在,让我们进行终极测试:
在一个终端(Terminal 1)里,启动PX4 SITL与Gazebo:
cd /root/PX4_Firmware
roslaunch px4 mavros_posix_sitl.launch
你应该看到Gazebo启动,加载一个世界(可能是空的,也可能有地面),并且PX4开始初始化。在另一个终端(Terminal 2)里,进入容器,尝试运行一个XTDrone的示例脚本(假设你想运行一个多机仿真):
cd /root/XTDrone
python3 multirotor_communication.py iris 0
如果一切顺利,你将在Gazebo中看到无人机,并且脚本能够通过MAVROS与仿真中的飞控通信。至此,整个XTDrone仿真平台在Docker下的ROS-Noetic环境就全部配置完成了。这个环境封装在容器里,独立且纯净。你可以随时用docker commit命令将这个配置好的容器保存为新的镜像,以后在任何支持Docker的机器上,瞬间就能复现这个完整的仿真开发环境。
更多推荐
所有评论(0)