微空科技
文档目录
文章目录

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

本章目标

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

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

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

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

前期准备

硬件准备

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

软件准备

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 经过物理防震设计,更加适用于无人机飞行场景。

OpenVINS 编译与验证

编译安装 ceres-solver

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

ℹ️ 为什么需要从源码编译安装?

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

1. 确认系统核心组件

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

2. 安装依赖库

sudo apt-get install cmake libgoogle-glog-dev libgflags-dev libatlas-base-dev libeigen3-dev libsuitesparse-dev -y

3. 下载源代码

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

4. 创建编译环境

cd ceres-solver/
mkdir build && cd build
cmake ..

5. 编译 ceres-solver

make

6. 安装 ceres-solver

sudo make install

7. 验证 ceres-solver 安装版本

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

编译 OpenVINS

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/

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. 下载源代码

  • 创建工作空间并拉取 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 平台适配和优化后的版本。

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 运行功能。

5. 配置终端环境

echo "source ~/vio/openvins_ws/install/setup.bash" >> ~/.bashrc
source ~/.bashrc

运行 ROSBAG 数据集验证

1. 下载数据包

2. 上传数据包到机载电脑

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

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 上运行效果良好。

真机验证

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

1. 监测系统状态

htop

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

2. 启动相机节点

ros2 launch realsense2_camera mvd35_d430_launch.py

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

3. 启动 MAVROS 节点

ros2 launch mavros apm.launch

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

4. 启动 OpenVINS

ros2 launch ov_msckf subscribe.launch.py config:=mvd35

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

5. 验证位姿输出

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

  • 查看位姿输出频率
ros2 topic hz /mavros/vision_pose/pose

  • 查看位姿输出数据
ros2 topic echo /mavros/vision_pose/pose

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

飞控 EKF 融合 VIO 定位数据

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

修改遥数一体链路模式

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

1. 修改链路模式

  • 将高频头连接到电脑

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

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

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

2. 修改飞控数传串口波特率

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

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

  • 设置 -> 端口设置 -> 设置 SERIAL1 USART1 波特率115200
SERIAL1_BAUD        115: 115200
  • ⚠️ 重启飞控

  • 断开飞控与电脑的 USB 线连接,并重新通过数传连接到 MicoConfigurator

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

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

更新补充中……

飞控 EKF 配置

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

  • 参数 -> VISO

    • VISO_POS_X 设置为 0.09
    • VISO_TYPE 设置为 1: MAVLink
VISO_POS_X    0.09
VISO_TYPE     1: MAVLink

2. 飞控时钟参数设置

  • 参数 -> BRD

    • BRD_RTC_TYPES 设置为 2
BRD_RTC_TYPES    2

3. 飞控系统ID参数设置

  • 参数 -> SYSID

    • SYSID_MYGCS 设置为 1
SYSID_MYGCS    1

4. 飞控 EKF 数据源设置

  • 设置 -> EKF -> 设置 EK3_SRC1 相关参数

    • 水平位置源 设置为 6: ExternalNav
    • 垂直位置源 设置为 2: RangeFinder
    • 水平速度源 设置为 0: None
    • 垂直速度源 设置为 0: None
    • 偏航角源 设置为 6: ExternalNav
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

更新补充中……

  • ⚠️ 重启生效

验证 VIO 数据融合

1. 启动所有节点

  • 终端 1:监测系统状态
htop
  • 终端 2:启动相机节点
ros2 launch realsense2_camera mvd35_d430_launch.py
  • 终端 3:启动 MAVROS 节点
ros2 launch mavros apm.launch
  • 终端 4:启动 OpenVINS
ros2 launch ov_msckf subscribe.launch.py config:=mvd35

  • 轻微晃动无人机,查看 OpenVINS 位姿输出

2. 验证 EKF 融合状态

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

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

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

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

更新补充中……

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 外参标定有误,需重新标定或检查坐标系配置。

⚠️ 短距离移动后位姿快速漂移:环境视觉特征不足(纯白墙壁、单一纹理),更换至纹理丰富的环境重新测试。

VIO 定位飞行测试

⚠️ 安全警告

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

飞行前检查

✅ 4.4 节手持移动测试通过,定位方向正确、无明显漂移。

✅ 遥控器已配置 Stabilize 模式(手动接管)和 Loiter 模式(VIO 定位飞行)。

✅ 飞行场地纹理丰富、光照稳定无频闪。

✅ 电池电量充足,螺旋桨安装牢固。

飞行操作

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


附录

常见问题排查

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

参考资源