Ubuntu环境下ArduPilot SITL仿真测试全流程解析
1. 环境准备与依赖安装
在Ubuntu系统上搭建ArduPilot SITL仿真环境,首先需要配置好基础环境。我推荐使用Ubuntu 18.04或20.04 LTS版本,这两个版本在社区支持度和软件兼容性方面表现最好。如果你用的是虚拟机,建议分配至少4GB内存和20GB磁盘空间,不然编译时可能会卡顿。
安装前先更新软件源,虽然国内用户可能会觉得慢,但这一步很重要,能避免很多依赖问题。我通常会用阿里云或清华的镜像源来加速,具体操作是在终端里输入:
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo apt-get update
接下来安装MAVProxy,这是SITL仿真的核心组件,负责地面站和飞控之间的通信。原始文章提到了两种安装方式,我这里强烈推荐用Python3的方案,毕竟Python2已经停止维护了。实测下来,用pip3安装最稳妥:
sudo apt-get install python3-dev python3-opencv python3-wxgtk4.0 python3-pip python3-matplotlib python3-lxml python3-pygame
pip3 install PyYAML MAVProxy --user
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
source ~/.bashrc
有时候会遇到wxPython包装不上的情况,这时候可以试试手动下载deb包安装。我在一台新装的Ubuntu 20.04上就遇到过这问题,折腾了半天才发现是缺少底层依赖。
装完MAVProxy后,还需要一些辅助工具,比如screen和git,这些在后续的仿真中都会用到:
sudo apt-get install screen git vim
2. 获取ArduPilot源码
环境准备好后,就要获取ArduPilot的源代码了。原始文章提到git clone经常因为网络问题失败,这点我深有体会。国内用户最好用镜像源或者代理(注:此处仅指网络代理,非敏感技术),但注意不要用那些来路不明的软件。
创建一个专门的工作目录是个好习惯,这样不会把系统搞乱:
mkdir -p ~/ardupilot_project
cd ~/ardupilot_project
git clone https://gitee.com/mirrors/ardupilot.git
如果你已经在外网克隆了仓库,转移到Linux时可能会遇到换行符问题。Windows用的是\r\n,Linux用的是\n,所以会出现“/usr/bin/env: python3\r: 没有那个文件或目录”这种错误。解决方法是用vim打开文件,执行:set ff=unix然后保存。
还有文件权限问题,Windows拷贝过来的文件默认没有执行权限,需要递归授权:
sudo chmod -R 755 ardupilot
接着初始化子模块,这是很多人会漏掉的关键步骤:
cd ardupilot
git submodule update --init --recursive
这个过程可能会比较慢,取决于你的网络状况。我建议在晚上睡觉前开始下载,第二天早上应该就差不多了。
3. 环境配置与编译准备
代码下载完后,需要设置一些环境变量。把以下内容添加到~/.bashrc文件末尾:
export PATH=$PATH:~/ardupilot_project/ardupilot/Tools/autotest
export PATH=$PATH:~/.local/bin
然后执行source ~/.bashrc让配置生效。验证一下是否设置成功,可以输入sim_后按Tab键,如果能自动补全为sim_vehicle.py,说明路径设置正确。
编译前还需要安装一些依赖库,ArduPilot提供了一个很方便的脚本:
cd ~/ardupilot_project/ardupilot
Tools/environment_install/install-prereqs-ubuntu.sh -y
这个脚本会自动安装编译需要的所有依赖,包括编译器、工具链和各种库文件。整个过程大概需要10-20分钟,取决于你的网速和机器性能。
有时候会因为网络问题中断,多试几次就好。我在帮学员配置环境时,遇到过最极端的情况是重试了5次才成功,所以耐心很重要。
4. 解决编译错误
第一次运行SITL时,很可能会遇到编译错误。原始文章提到的C++结构体初始化问题确实很常见,这是因为ArduPilot代码中有些地方用了C风格的初始化方式,而C++编译器对此要求更严格。
具体来说,在AP_Logger_Backend.cpp文件的578行左右,有这样的代码:
log_VER pkt{
LOG_PACKET_HEADER_INIT(LOG_VER_MSG),
time_us : AP_HAL::micros64(),
board_type : fwver.board_type,
board_subtype: fwver.board_subtype,
major: fwver.major,
minor: fwver.minor,
patch: fwver.patch,
fw_type: fwver.fw_type,
git_hash: fwver.fw_hash,
build_type: fwver.vehicle_type,
};
但查看log_VER结构体的定义,会发现还有fw_string和_APJ_BOARD_ID两个成员没有被初始化:
struct PACKED log_VER {
LOG_PACKET_HEADER;
uint64_t time_us;
uint8_t board_type;
uint16_t board_subtype;
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t fw_type;
uint32_t git_hash;
char fw_string[64];
uint16_t _APJ_BOARD_ID;
uint8_t build_type;
};
解决方法很简单,在初始化时给这两个成员赋默认值即可:
log_VER pkt{
LOG_PACKET_HEADER_INIT(LOG_VER_MSG),
time_us : AP_HAL::micros64(),
board_type : fwver.board_type,
board_subtype: fwver.board_subtype,
major: fwver.major,
minor: fwver.minor,
patch: fwver.patch,
fw_type: fwver.fw_type,
git_hash: fwver.fw_hash,
"", // 给fw_string赋空值
0, // 给_APJ_BOARD_ID赋0
build_type: fwver.vehicle_type,
};
修改后保存文件,重新编译就可以了。这个问题在新版本的ArduPilot中可能已经被修复,但如果你用的是较旧的版本或者特定的commit,还是可能会遇到。
5. 运行SITL仿真
编译问题解决后,就可以开始运行仿真了。进入ardupilot目录,启动Copter仿真:
cd ~/ardupilot_project/ardupilot
sim_vehicle.py -v ArduCopter --map --console
第一次运行会先编译一些组件,可能需要几分钟时间。成功启动后,你应该能看到三个窗口:MAVProxy控制台、地图窗口和飞行数据窗口。
如果只有控制台窗口,没有地图和飞行数据显示,很可能是MAVProxy的依赖包有问题。试试用pip2重新安装相关组件:
sudo -H pip2 install --upgrade MAVProxy pymavlink future lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
这里用pip2是因为MAVProxy的一些组件还没有完全兼容Python3。虽然原始文章提到怕Python3和ROS冲突,但实测在纯SITL环境下用Python3是没问题的。
仿真启动后,你可以在MAVProxy控制台中输入命令来控制无人机。比如输入arm throttle解锁电机,takeoff 10起飞到10米高度。这些命令和真实飞控的操作是一样的。
6. 常见问题排查
在仿真过程中,可能会遇到各种奇怪的问题。我总结了几种常见的情况和解决方法:
地图不显示:这通常是因为wxPython或者matplotlib的问题。试着重新安装这些包:
pip3 install -U wxPython matplotlib
控制无响应:检查是否有多个MAVProxy实例在运行,用ps aux | grep mavproxy查看,如果有的话用kill命令结束掉。
帧率过低:仿真运行很卡的话,可以尝试关闭图形界面,用--no-mavproxy参数启动,然后用QGroundControl连接仿真。
端口占用:如果提示端口已被占用,可以指定其他端口号:
sim_vehicle.py -v ArduCopter --map --console --out=127.0.0.1:14550
有时候重启电脑能解决很多莫名其妙的问题,特别是USB设备相关的异常。
7. 进阶使用技巧
基本仿真能运行后,可以尝试一些更高级的用法。比如使用不同的机型:
sim_vehicle.py -v ArduPlane --map --console # 固定翼仿真
sim_vehicle.py -v APMrover2 --map --console # rover仿真
还可以添加参数来模拟不同的环境条件,比如风速、重力异常等:
sim_vehicle.py -v ArduCopter --map --console --add-param=SIM_WIND_SPD=5
这些参数可以在仿真运行时动态调整,对测试控制算法的鲁棒性很有帮助。
另一个有用的技巧是使用多个实例进行多机仿真。先启动一个实例:
sim_vehicle.py -v ArduCopter --instance 1 --out=127.0.0.1:14550
然后在另一个终端启动第二个实例:
sim_vehicle.py -v ArduCopter --instance 2 --out=127.0.0.1:14551
这样就能同时运行两个无人机,测试多机协同算法了。
8. 与地面站配合使用
SITL仿真最好配合地面站软件使用,这样能看到更直观的飞行数据。我常用的是QGroundControl,安装很简单:
sudo usermod -a -G dialout $USER
sudo apt-get remove modemmanager -y
wget https://d176tv9ibo4jno.cloudfront.net/latest/QGroundControl.AppImage
chmod +x QGroundControl.AppImage
启动QGroundControl后,它会自动连接到SITL仿真。你可以在里面看到详细的任务规划、飞行参数和传感器数据。
如果连接不上,检查一下MAVProxy的输出配置。确保有--out=udp:127.0.0.1:14550这样的参数,这是QGroundControl默认监听的端口。
在地面站里可以设置航点任务,模拟自动飞行。这是我最喜欢的功能,可以在不出门的情况下测试复杂的飞行任务。
记得定期更新代码,ArduPilot社区很活跃,几乎每天都有新的改进和bug修复:
cd ~/ardupilot_project/ardupilot
git pull
git submodule update --recursive
更新后可能需要重新编译,因为有些修改涉及到底层代码的变动。
更多推荐


所有评论(0)