请输入
菜单

微空 AI 智能无人机教程 4 - 双目视觉里程计 (VIO) 部署运行

1. 本章目标

本章将在机载电脑(树莓派 5)上部署 OpenVINS 双目视觉惯性里程计(VIO),使无人机能够在无 GPS 的室内或复杂环境中获取精准的三维空间坐标。

部署完成后,VIO 输出的位姿定位数据将通过 MAVROS 回传给飞控 EKF(Extended Kalman Filter,扩展卡尔曼滤波器),替代传统的光流传感器,作为主要的位置估算源,从而实现无人机高精度的室内自主定位悬停与飞行任务。

完成本章的部署与测试后,MVD35 应达到以下状态:

  • VIO 算法运行稳定:OpenVINS 在树莓派 5 上能够以 30Hz 的帧率流畅、稳定地输出位姿估算数据。
  • 飞控 EKF 融合 VIO 数据正常:位姿数据通过 MAVROS 稳定回传至飞控,EKF 将外部视觉定位(External Vision)融合为主要位置估算源。
  • 自主定位悬停精准:在定点模式下,无人机能够完全依靠视觉里程计实现稳定的室内定位悬停,水平及高度漂移极小。

2. 前期准备

2.1 硬件准备

  • MVD35 智能版(完成前置教程的软件配置)
  • 遥控器(加装 TRS 高频头)
  • USB 数据线
  • 电脑与良好的网络条件

2.2 软件准备

2.3 VIO 工作原理与系统架构

VIO(Visual-Inertial Odometry,视觉惯性里程计)通过融合高频的惯性测量单元(IMU)数据与低频的相机图像来实时估计飞行器的三维位姿(位置和姿态)。
相比于依赖地面纹理且只能测量二维位移的传统“光流+测距”方案,VIO 能够提供完整的六自由度(6-DoF)位姿估计,定位精度更高,且不受低纹理地面、沙地或积水环境的影响,是室内无 GPS 自主飞行的核心技术。

本教程使用 OpenVINS 作为 VIO 算法框架。它是由特拉华大学开发的开源轻量化 VIO 系统,支持多相机配置、IMU 在线标定,并且在树莓派 5 平台上有较好的实时运行效率。

MVD35 VIO 系统数据流向:

1. 传感器数据采集

  • 图像输入:机载 D430 深度相机采集双目红外图像,以 30Hz 速率传输给树莓派。
  • 惯性数据输入:飞控发布 200Hz IMU 角速度和加速度数据,由 MAVROS 节点实时传输给树莓派。

2. 状态解算与位姿发布(OpenVINS)

  • 树莓派上运行的 OpenVINS 节点订阅双目图像与 IMU 话题,通过 MSCKF 算法进行滑窗状态估计,实时解算出位姿数据。
  • 解算完成后,OpenVINS 直接将位姿数据发布到 /mavros/vision_pose/pose 话题,由 MAVROS 回传至飞控。

3. 飞控 EKF 融合定位

  • 飞控 EKF 融合外部视觉定位数据,为飞行控制算法提供稳定的位置、速度和姿态估计,从而使无人机在定点模式下实现精准悬停。

ℹ️ MVD35 直接使用飞控内置的高质量 IMU 作为惯性源(由 MAVROS 以 200Hz 发布),省去了相机模组额外集成 IMU 的硬件成本,且飞控 IMU 经过物理防震设计,更加适用于无人机飞行场景。

3. OpenVINS 编译与验证

3.1 编译安装 ceres-solver

Ceres Solver 是由 Google 开发的高性能开源非线性最小二乘问题求解器。在 OpenVINS 中,用于进行滑动窗口中的状态估计和外参在线标定等核心优化计算。

ℹ️ 为什么需要从源码编译安装?
Ubuntu 24.04 官方源提供的 Ceres 版本为 2.2.0,与 ROS 2 Jazzy 环境下的 Eigen 等库存在接口或版本兼容问题。为确保 OpenVINS 的编译和运行稳定性,本教程选择从源码编译并安装经过兼容性测试的 2.0.0 版本。

3.1.1 确认系统核心组件

  • 运行以下命令确认系统版本、Python 和 CMake 等工具已就绪:
bash 复制代码
lsb_release -a
python3 --version
cmake --version
opencv_version
  • 输出结果如下:
bash 复制代码
Release:    24.04
Codename:   noble
python3:    3.12.3
cmake:      3.28.3
opencv4:    4.6.0

3.1.2 安装依赖库

bash 复制代码
sudo apt-get install cmake libgoogle-glog-dev libgflags-dev libatlas-base-dev libeigen3-dev libsuitesparse-dev -y

3.1.3 下载源代码

  • 创建工作空间并拉取 2.0.0 版本源代码
bash 复制代码
mkdir -p ~/vio && cd ~/vio
git clone --branch=ceres-2.0.0 https://github.com/Minderring/ceres-solver.git

3.1.4 创建编译环境

bash 复制代码
cd ceres-solver/
mkdir build && cd build
cmake ..

3.1.5 编译 ceres-solver

bash 复制代码
make

3.1.6 安装 ceres-solver

bash 复制代码
sudo make install

3.1.7 验证 ceres-solver 安装版本

bash 复制代码
grep -E "CERES_VERSION_(MAJOR|MINOR|REVISION)" /usr/local/include/ceres/version.h

ℹ️ 输出以下内容表示安装版本为 2.0.0,Ceres-Solver 安装成功。
#define CERES_VERSION_MAJOR 2
#define CERES_VERSION_MINOR 0
#define CERES_VERSION_REVISION 0

3.2 编译 OpenVINS

3.2.1 安装依赖库

复制代码
sudo apt-get install ros-jazzy-ros2bag ros-jazzy-rosbag2* libeigen3-dev libboost-all-dev -y
sudo cp -r /usr/include/eigen3/Eigen /usr/include/

3.2.2 设置交换内存

ℹ️ 为什么需要设置交换内存?
由于选用的机载电脑为树莓派5 4G RAM 版本,在运行编译任务时容易因内存不足导致编译中断。通过设置交换内存,可以有效缓解内存压力,确保编译过程的稳定性。

  • 分配并启用 4GB 交换内存
复制代码
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
  • 检查内存及交换内存使用情况
复制代码
htop

ℹ️ htop 命令可以实时查看系统中各进程的资源使用情况,包含 CPU、内存等。图中 MemSwp 分别表示物理内存和交换内存的使用情况。

3.2.3 下载源代码

  • 创建工作空间并拉取 micoair-mvd35 分支源代码
复制代码
mkdir -p ~/vio/openvins_ws/src/ && cd ~/vio/openvins_ws/src/
git clone --branch=micoair-mvd35 https://github.com/Minderring/open_vins.git

ℹ️ micoair-mvd35 分支是微空在官方 OpenVINS 基础上针对 MVD35 平台适配和优化后的版本。

3.2.4 编译 OpenVINS

复制代码
cd ~/vio/openvins_ws/
MAKEFLAGS="-j1" colcon build --parallel-workers 1 --cmake-args -DCMAKE_BUILD_TYPE=Release --packages-select ov_core ov_init ov_msckf

ℹ️ 编译过程中可在另一个终端通过 htop 查看系统资源使用情况,确认不会因内存不足导致编译中断。
ℹ️ 编译结果显示 Summary: 3 packages finished,则表示编译成功。日志中的 stderr 输出为第三方依赖库(Eigen、Boost、Python)与较新版本 GCC 之间的兼容性警告,不影响 VIO 运行功能。

3.2.5 配置终端环境

复制代码
echo "source ~/vio/openvins_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc

3.3 运行 ROSBAG 数据集验证

3.3.1 下载数据包

3.3.2 上传数据包到机载电脑

  • 将下载好的 ROSBAG2 数据包上传到树莓派 /home/micoair/vio 目录下

3.3.3 启动 OpenVINS 并回放数据集验证

  • 终端 1: 启动 OpenVINS
复制代码
ros2 launch ov_msckf subscribe.launch.py config:=euroc_mav
  • 终端 2: 回放数据集
复制代码
ros2 bag play ~/vio/V1_01_easy.db3

ℹ️ 终端日志输出能看到 OpenVINS 实时运行情况、位置及轨迹长度信息等,最后定位位置回到原点附近 p_IinG = -0.617,-0.069,0.081 ,轨迹长度 dist = 57.31 (meters) 与数据集实际 58m 非常接近,表明 OpenVINS 在树莓派 5 上运行效果良好。

3.4 真机验证

通过 ROSBAG 数据集验证后,接下来将 D430 双目相机和飞控 IMU 的实时数据接入 OpenVINS,验证其在真机上的运行效果。

3.4.1 监测系统状态

bash 复制代码
htop

ℹ️ 实时查看系统资源使用情况,确认 OpenVINS 资源负载在正常范围内。

3.4.2 启动相机节点

bash 复制代码
ros2 launch realsense2_camera mvd35_d430_launch.py

ℹ️ 启动节点后能看到双目启动的信息及 RealSense Node Is Up! 标识,则说明相机启动成功。

3.4.3 启动 MAVROS 节点

bash 复制代码
ros2 launch mavros apm.launch

ℹ️ 启动节点后,能看到 MAVROS 的日志输出,包括 飞控固件版本、飞控型号 等信息,表示 MAVROS 已成功连接到飞控。

3.4.4 启动 OpenVINS

bash 复制代码
ros2 launch ov_msckf subscribe.launch.py config:=mvd35

ℹ️ 在静止状态下启动节点后,OpenVINS 接收双目及 IMU 数据,完成初始化后进入 ZUPT(Zero velocity UPdaTe,零速更新)状态——系统检测到无人机静止时,利用零速约束抑制 IMU 漂移。当无人机开始移动后,ZUPT 状态自动解除,进入正常位姿输出模式。

3.4.5 验证位姿输出

ℹ️ 轻轻晃动无人机,使 ZUPT 状态解除,OpenVINS 开始稳定输出位姿数据。

  • 查看位姿输出频率
bash 复制代码
ros2 topic hz /mavros/vision_pose/pose
  • 查看位姿输出数据
bash 复制代码
ros2 topic echo /mavros/vision_pose/pose

ℹ️ /mavros/vision_pose/pose 话题以约 30Hz 频率稳定输出,数据与实际位姿一致,说明 OpenVINS 在真机上运行正常。

4. 飞控 EKF 融合 VIO 定位数据

设置飞控 EKF 以接受外部视觉定位数据,替代光流作为主要定位源。

4.1 修改遥数一体链路模式

VIO 启用后,OpenVINS 以 30Hz 频率向飞控回传位姿数据,显著增加了数传链路的带宽负载。为确保数据传输稳定,需将遥数一体数传切换为 high-speed 模式,并相应调整飞控串口波特率。

4.1.1 修改链路模式

  • 将高频头连接到电脑

  • 浏览器访问 微空助手网页版

  • 选择 高频头端口 -> 打开 配置数传 -> 点击 连接,连接到高频头

  • 打开 参数 界面 -> 速率模式 选择 高速 -> 点击 保存到设备 并断开连接

4.1.2 修改飞控数传串口波特率

  • 将飞控通过 USB 线连接到电脑

  • 连接到 MicoConfigurator 并修改对应串口波特率

  • 设置 -> 端口设置 -> 设置 SERIAL1 USART1 波特率115200
ini 复制代码
SERIAL1_BAUD        115: 115200
  • ⚠️ 重启飞控
  • 断开飞控与电脑的 USB 线连接,并重新通过数传连接到 MicoConfigurator

⚠️ 切换为 high-speed 模式后,通过数传连接 MicoConfigurator 时,波特率需选择 115200,否则无法正常通信。

  • 查看未启动 VIO 时的数传负载和链路质量

4.2 飞控 EKF 配置

1. VIO 类型与位置参数设置

  • 参数 -> VISO -> VISO_POS_X 设置为 0.09VISO_TYPE 设置为 1: MAVLink
ini 复制代码
VISO_POS_X    0.09
VISO_TYPE     1: MAVLink

2. 飞控时钟参数设置

  • 参数 -> BRD -> BRD_RTC_TYPES 设置为 2
ini 复制代码
BRD_RTC_TYPES    2

3. 飞控系统ID参数设置

  • 参数 -> SYSID -> SYSID_MYGCS 设置为 1
ini 复制代码
SYSID_MYGCS    1

4. 飞控 EKF 数据源设置

  • 设置 -> EKF

  • EK3_SRC1 水平位置源 设置为 6: ExternalNav垂直位置源 设置为 2: RangeFinder水平速度源 设置为 0: None垂直速度源 设置为 0: None偏航角源 设置为 6: ExternalNav

ini 复制代码
EK3_SRC1_POSXY     6: ExternalNav
EK3_SRC1_POSZ      2: RangeFinder
EK3_SRC1_VELXY     0: None
EK3_SRC1_VELZ      0: None
EK3_SRC1_YAW       6: ExternalNav
  • ⚠️ 重启生效

4.3 验证 VIO 数据融合

4.3.1 启动所有节点

  • 终端 1:监测系统状态
bash 复制代码
htop
  • 终端 2:启动相机节点
bash 复制代码
ros2 launch realsense2_camera mvd35_d430_launch.py
  • 终端 3:启动 MAVROS 节点
bash 复制代码
ros2 launch mavros apm.launch
  • 终端 4:启动 OpenVINS
bash 复制代码
ros2 launch ov_msckf subscribe.launch.py config:=mvd35
  • 轻微晃动无人机,查看 OpenVINS 位姿输出

4.3.2 验证 EKF 融合状态

  • 查看启动 VIO 后,遥数一体数传负载和链路质量

ℹ️ 数传链路接收速率占用带宽显著上升,由未启动 VIO 前的 1.5 KB/s 增加至 5.5 KB/s

  • 消息控制台 可以看到 VISION_POSITION_ESTIMATE 消息输出,数据及频率与树莓派上的输出一致

  • MicoConfigurator 底部消息栏可以看到 EKF3 已经融合了外部位置数据,并输出位置数据

4.4 VIO 定位移动测试

确认 EKF 融合状态正常后,保持 4.3 节中所有节点运行,进行手持移动测试。

测试步骤:

  1. MicoConfigurator 消息控制台中观察 VISION_POSITION_ESTIMATELOCAL_POSITION_NED 消息。
  2. 手持无人机在房间内缓慢、平稳地沿各方向移动,观察 LOCAL_POSITION_NED 中的 x、y、z 值是否跟随实际运动同步变化。
  3. 将无人机移回起始位置,观察坐标是否回到接近零点,以此判断定位漂移程度。

完成后检查:

VISION_POSITION_ESTIMATE 消息持续稳定输出,频率约 30Hz。
LOCAL_POSITION_NED 数据(飞控 EKF 融合 VIO 后的定位结果)跟随实际运动实时变化:

  • 向机头方向移动 → x 增大
  • 向右侧移动 → y 增大
  • 向上抬高 → z 减小(NED 坐标系 z 轴朝下)
    ✅ 回到起始位置后,坐标值接近零点,无明显累积漂移。

常见问题:

  • ⚠️ LOCAL_POSITION_NED 无数据变化:EKF 来源参数配置错误,重新检查 EK3_SRC1 参数。
  • ⚠️ 位姿方向与实际运动相反:相机-IMU 外参标定有误,需重新标定或检查坐标系配置。
  • ⚠️ 短距离移动后位姿快速漂移:环境视觉特征不足(纯白墙壁、单一纹理),更换至纹理丰富的环境重新测试。

5. VIO 定位飞行测试

⚠️ 安全警告:首次飞行测试务必在开阔安全的室内环境中进行,建议由有飞行经验的操作员完成。飞行全程始终保持一个模式通道为 Stabilize,如发现位姿漂移或跳变,立即切回 Stabilize 模式手动降落

5.1 飞行前检查

  • ✅ 4.4 节手持移动测试通过,定位方向正确、无明显漂移。
  • ✅ 遥控器已配置 Stabilize 模式(手动接管)和 Loiter 模式(VIO 定位飞行)。
  • ✅ 飞行场地纹理丰富、光照稳定无频闪。
  • ✅ 电池电量充足,螺旋桨安装牢固。

5.2 飞行操作

1. 启动所有节点

按照 4.3 节的方式依次启动 RealSense → MAVROS → OpenVINS,确认 EKF 融合状态正常。

2. 起飞

  • Stabilize 模式下解锁起飞,确认飞行姿态正常。
  • 在低高度(0.5~1m)稳定悬停后,切换至 Loiter 模式
  • 松开摇杆,观察无人机是否能保持位置不漂移。

3. 定位验证

  • 缓慢推动方向摇杆,验证位置控制响应。
  • 松开摇杆后,无人机应能在新位置保持悬停。

4. 降落

  • 切回 Stabilize 模式,缓慢降低油门平稳着地。
  • 落地后上锁并断开电池。

完成后检查:

  • ✅ Loiter 模式下无人机能稳定悬停,水平漂移小。
  • ✅ 推杆后松开,无人机能在新位置保持定点。
  • ✅ 飞行全程 OpenVINS 未出现跟踪丢失或位姿跳变。

常见问题:

  • ⚠️ 切换模式后突然漂移或加速:VISO_DELAY_MS 设置不当,根据飞行日志调整。
  • ⚠️ 飞行中 VIO 跟踪丢失:环境特征不足或光照突变,避免对着纯白墙壁或窗户飞行。
  • ⚠️ 起飞后高度不稳:检查 EK3_SRC1_POSZ 是否正确设置为 2: RangeFinder

附录

1. 常见问题排查

现象 可能原因 解决方案
OpenVINS 无法初始化 初始化阶段运动不足 启动后轻轻晃动无人机几秒钟
VIO 位姿快速漂移 标定参数不准确 重新进行相机和 IMU-Camera 标定
VIO 位姿跳变 视觉特征不足或光照突变 确保环境有纹理,避免对着纯白墙壁
飞控不使用 VIO 数据 EKF 来源配置错误 检查 EK3_SRC 或 EKF2_EV 参数
飞行中位置漂移 DELAY_MS 设置不当 根据日志分析调整延迟补偿值
快速运动时定位丢失 运动模糊导致特征跟踪失败 降低飞行速度,或提高相机曝光速度
OpenVINS 编译 OOM 树莓派内存不足 增加 4GB swap 空间后重试

2. 参考资源

上一个
微空 AI 智能无人机教程 3 - 机载电脑环境配置
下一个
微空助手下载和使用说明
最近修改: 2026-07-11Powered by