前言

GeoFlow-SLAM目标是足式机器人(Legged Robotics),利用紧耦合RGBD、IMU和腿部里程计(Legged Odometry,Legged Encoders),在动态场景下的追踪重建

着重解决高频剧烈运动带来的图像模糊足端触地冲击导致的IMU数据噪声,以及常见的弱纹理环境(如白墙、长走廊)

开源地址:https://github.com/HorizonRobotics/GeoFlowSlam

请添加图片描述
请添加图片描述

GeoFlow-SLAM

主要工作

  • A dual-stream optical flow tracking incorporating map points and pose information,双流光流跟踪
  • A pose initialization method based on IMU/Legged Odometry, Perspective-n-Point (PnP), and Generalized Iterative Closest Point (GICP), 位姿初始化基于IMU/步态里程计、PnP 与 GICP
  • A novel optimization framework that tightly integrates depth-to-map and GICP geometric consistency,深度和 GICP 紧耦合
  • collected datasets using legged robotics,采集了双足机器人数据集

整体架构

在这里插入图片描述
GeoFlow-SLAM 系统由三部分构成:

  • 特征提取与跟踪(Feature Extraction)
  • IMU/腿式/PnP/GICP 里程计(Odometry)
  • 视觉-深度-IMU 融合建图(Visual-Depth-IMU Integration Mapping)

首先,对RGBD输入提取深度特征与 FAST、ORB 特征,对IMU 和腿部编码器的数据分别进行 IMU预积分、腿部预积分。

随后,IMU预积分、腿部预积分结果进入IMU/腿部里程计确定初始位姿,深度特征进行GICP获得初始位姿估计、ORB特征的进行PnP

接着,采用双流光流并结合上面的结果信息对 ORB 特征进行跟踪。计算深度、重投影以及回环检测残差

最后,在紧耦合的视觉-深度-IMU 因子图中进行单帧、局部关键帧和全局关键帧优化,实现地图构建与位姿估计。

特征提取与跟踪

从深度图中提取深度平面特征,在 GICP 算法中用于获得初始位姿估计;从RGB图像中提取 Oriented FAST 与 Rotated BRIEF(ORB)特征。

采用双流光流与 PnP进行特征跟踪。

IMU 与腿式编码器进行预积分

IMU/腿式/PnP/GICP 里程计

优先用腿式与 IMU 里程计进行位姿预测;否则通过在连续帧间求解 PnP 问题来确定初始位姿

来自 IMU/腿式或 PnP 的初始位姿随后用 GICP 算法进一步精化

采用深度到地图的配准与视觉地图点的重投影(the depth-to-map registration and the reprojection of visual map points)来生成观测残差

视觉-深度-IMU 融合建图

该模块包括单帧优化、局部关键帧优化和全局关键帧优化。

单帧位姿优化与局部BA模块:视觉重投影残差、深度到地图残差以及 IMU/腿部/ GICP 位姿约束紧耦合。

单帧位姿优化仅关注当前相邻帧位姿估计;局部 BA 估计局部关键帧的位姿及相应的视觉地图点

当检测到回环时,对整体关键帧位姿和点云地图进行全局优化

双流光流跟踪

传统光流通常假设运动小且连续。在快速运动时收敛缓慢且计算量大。

为了解决这些问题,提出了利用先验地图点(ORB 特征的对应地图点)和位姿来增强快速运动下的特征跟踪鲁棒性的双流光流跟踪方法

在这里插入图片描述

PipeLine:

  1. 对于有效的地图点(绿色的⭐),利用先验的地图点+位姿重投影到当前帧,生成重投影点(🔵)
  2. 基于当前帧的重投影点做光流微调(🔵->虚线🟢),即先用几何预测位置,再用光流 refine(3D→2D),以处理 大位移
  3. 对上一帧中缺乏合格先验地图点(黄色⭐)的特征点(表示为🟡和🔴)进一步施加普通光流(2D → 2D)

事实上,在3D->2D这一步虽然有先验约束得到更优点位,但这样一个从更优点位开始的普通的光流,仍然没有直接解决模糊的问题,如果普通光流无法解决模糊,为何换个位置的普通光流就可以解决?有些缺乏说服力

3D 到 2D 的光流跟踪

第一路:使用来自里程计模块的 IMU/腿部里程计或 PnP、GICP 提供的初始位姿,将特征点的对应地图点 P(X,Y,Z)\mathbf{P}\left( {X, Y, Z}\right)P(X,Y,Z) 投影到当前帧 p′(x,y){p}^{\prime }\left( {x, y}\right)p(x,y) 上的特征点 p(x,y)p\left( {x, y}\right)p(x,y)

p′(x,y)=F(Twck−1P) {p}^{\prime }\left( {x, y}\right) = F\left( {{\mathbf{T}}_{w}^{{c}_{k - 1}}\mathbf{P}}\right) p(x,y)=F(Twck1P)

F(P)=(fXXZ+cxfYYZ+cy) F\left( \mathbf{P}\right) = \left( \begin{array}{l} {f}_{X}\frac{X}{Z} + {c}_{x} \\ {f}_{Y}\frac{Y}{Z} + {c}_{y} \end{array}\right) F(P)=(fXZX+cxfYZY+cy)
F(P)F\left( \mathbf{P}\right)F(P) 表示内参投影;Twck−1{\mathbf{T}}_{w}^{{c}_{k - 1}}Twck1 表示时刻 k−1k - 1k1 的相机位姿。

然后在当前帧上对投影像素 p′(x,y){p}^{\prime }\left( {x, y}\right)p(x,y) 进行 3D 到 2D 的光流跟踪。该方法天然滤除了不稳定特征,如动态不一致的特征。

2D 到 2D 的光流跟踪

不准确的初始位姿和三角化失败,导致ORB 特征常常缺乏有效对应的地图点

为此引入了第二路,在原始特征点上使用 2D 到 2D 的光流跟踪。

还计算了基础矩阵以识别并剔除外点,并配合内点掩码机制,防止在同一区域内不必要地包含跟踪点。

在这里插入图片描述

左图为 ORBSLAM3 ,右图为GeoFlow。绿色点表示特征点,红色点表示重投影到图像上的点。

Legged、PnP 与 GICP 里程计

无纹理、多足机器人的运动模式干扰 IMU ,导致错误估计初始位姿,此处提出了一种融合多足里程计、PnP 与 GICP 的初始位姿估计方法。

  • 若多足里程计数据可用,则优先用于位姿预测
  • 当 IMU 可用且在短时段内精度较高且计算较简单时,我们优先使用 IMU 进行初始位姿预测
  • 不满足IMU 使用条件时,基于成功跟踪的特征点计算本质矩阵以恢复帧间位姿,该方法不提供尺度信息,因此进一步基于深度进行 PnP 以获得更准确的初始位姿
    • 若 PnP 失败,则再用 GICP 细化初始位姿。
  • 若上述方法均失败,则基于匀速模型假设估计初始位姿。

非常工程化的方案

GICP 计算中使用 small_gicp,同时,将基于 GICP 的帧间相对位姿约束纳入因子图优化框架以进一步提升精度。

在实际代码中,我们可以找到实现细节,tracking.cc,TrackWithMotionModelICP :

  ORBmatcher matcher(0.9, true);

  // Update last frame pose according to its reference keyframe
  // Create "visual odometry" points if in Localization Mode
  UpdateLastFrame();
  bool bICP = false;
  int bEnableOdom = mPSettings->enableRobotOdom() && !mlQueueOdomData.empty();
  // 给ICP提供一个初始位姿
  Eigen::Vector3f dpos =
      mpImuPreintegratedFromLastKF->GetUpdatedDeltaPosition();
  if (mpAtlas->isImuInitialized() &&
      (mCurrentFrame.mnId > mnLastRelocFrameId + mnFramesToResetIMU)) {
    PredictStateIMU();
  } else {
    if (!EstimatePoseByOF()) {
      mCurrentFrame.SetPose(mVelocity * mLastFrame.GetPose());
    }
  }

  if (bEnableOdom) {
    PredictStateOdom();
  }
  string icp_method = mPSettings->getICPMethod();
  if (icp_method == "GICP")
    bICP = PredictStateICP();
  else if (icp_method == "NDT")
    bICP = PredictStateNDT();
  else
    bICP = PredictStateICP();
  fill(mCurrentFrame.mvpMapPoints.begin(), mCurrentFrame.mvpMapPoints.end(),
       static_cast<MapPoint*>(NULL));
  int th;

  • 如果 IMU 已初始化,走 PredictStateIMU
  • 否则先走 EstimatePoseByOF,也就是 LK 光流 + PnP 得到粗位姿。
  • 如果有腿部 odom,再走 PredictStateOdom
  • 如果开了 ICP/NDT,再走 PredictStateICP/NDT 用深度点云把粗 pose 再修一遍。

这一步的输出是“当前帧一个可用的初始位姿”。

视觉、深度与 IMU 的紧耦合

构建如下因子图以在局部窗口内优化关键帧位姿和视觉特征点,包括:

  • 视觉重投影残差因子(visual reprojection residual factors)
  • 深度到地图的点-面残差因子(depth-to-map point-to-plane residual factors)
  • GICP 相对位姿残差因子(GICP relative pose residual factors)
  • IMU 预积分因子(IMU pre-integration factors)

关键帧的深度平面特征点被拼接成局部地图。

对于当前关键帧的每个平面特征点,在将点投影到局部地图后对其 k 个最近点云进行平面拟合,得到点-面残差

随后使用 GICP 约束帧间位姿

若 IMU 预积分与多足里程计或匀速假设显著偏离(表明 IMU 积分发散),我们会自适应地引入多足里程计约束以改善位姿估计。

在这里插入图片描述
之后,利用优化得到的相机位姿重建更精确的局部深度图

为保证系统实时性,仅在有效视觉观测不足时才将深度到地图约束(depth-to-map constraints)添加到帧节点

在单帧优化中,遵循 ORB-SLAM,通过在相邻帧之间构建约束来进行优化,包括 IMU 预积分、GICP 相对位姿、视觉重投影和深度到地图约束。

r1=min⁡X∑(i,j)∈Fρ(∥rv(pci,X)∥∑v2) {r}_{1} = \mathop{\min }\limits_{X}\mathop{\sum }\limits_{{\left( {i, j}\right) \in F}}\rho \left( {\begin{Vmatrix}{r}_{v}\left( {p}^{{c}_{i}}, X\right) \end{Vmatrix}}_{{\sum }_{v}}^{2}\right) r1=Xmin(i,j)Fρ( rv(pci,X) v2)

r2=min⁡X∑i∈Fρ(∥rimu(zbibi+1,X)∥∑bibi+12) {r}_{2} = \mathop{\min }\limits_{X}\mathop{\sum }\limits_{{i \in F}}\rho \left( {\begin{Vmatrix}{r}_{imu}\left( {z}_{{b}_{i}{b}_{i + 1}}, X\right) \end{Vmatrix}}_{{\sum }_{{b}_{i}{b}_{i} + 1}}^{2}\right) r2=XminiFρ( rimu(zbibi+1,X) bibi+12)

r3=min⁡X∑(i,j)∈Fρ(∥ricp(Icjci,X)∥∑icp2) {r}_{3} = \mathop{\min }\limits_{X}\mathop{\sum }\limits_{{\left( {i, j}\right) \in F}}\rho \left( {\begin{Vmatrix}{r}_{icp}\left( {I}_{{c}_{j}}^{{c}_{i}}, X\right) \end{Vmatrix}}_{{\sum }_{icp}}^{2}\right) r3=Xmin(i,j)Fρ( ricp(Icjci,X) icp2)

r4=min⁡X∑(i,j)∈Fρ(∥rl(dci,X)∥∑l2) {r}_{4} = \mathop{\min }\limits_{X}\mathop{\sum }\limits_{{\left( {i, j}\right) \in F}}\rho \left( {\begin{Vmatrix}{r}_{l}\left( {d}^{{c}_{i}}, X\right) \end{Vmatrix}}_{{\sum }_{l}}^{2}\right) r4=Xmin(i,j)Fρ( rl(dci,X) l2)

  • r1,r2{r}_{1},{r}_{2}r1,r2 表示视觉重投影与 IMU 预积分残差因子;

  • r3,r4{r}_{3},{r}_{4}r3,r4 分别指代 GICP 相对位姿和深度到地图的点到平面残差

  • pci{p}^{{c}_{i}}pci 表示对第 iii 帧的视觉观测

  • zbibi+1{z}_{{b}_{i}{b}_{i + 1}}zbibi+1 表示预积分观测

  • Icjci{I}_{{c}_{j}}^{{c}_{i}}Icjci 表示第 iii 帧与第 jjj 帧之间的 GICP 相对位姿

  • dci{d}^{{c}_{i}}dci 定义为第 iii 帧的深度到地图观测

  • ρ\rhoρ 是一个用于增强优化步骤稳定性并减轻异常值影响的核心函数

  • 在局部 BA 中,XXX 表示关键帧的 IMU 状态 xxx 与视觉地图点 PPP

  • 在单帧优化中,XXX仅表示相邻帧的 IMU 状态。

残差 来源 作用
r1r_1r1 图像 约束像素一致性
r2r_2r2 IMU 提供运动先验
r3r_3r3 GICP 提供点云几何位姿
r4r_4r4 深度 提供结构约束

从深度图中提取特征

从点云中提取平面特征点以节省计算资源

首先,通过计算每个点的垂直角 αi{\alpha }_{i}αi 与水平角 θi{\theta }_{i}θi 将点云分割为二维矩阵 pi=(xi,yi,zi,){p}_{i} = \left( {{x}_{i},{y}_{i},{z}_{i},}\right)pi=(xi,yi,zi,)

αi=arctan⁡(yixi) {\alpha }_{i} = \arctan \left( \frac{{y}_{i}}{{x}_{i}}\right) αi=arctan(xiyi)

θi=arctan⁡(zixi) {\theta }_{i} = \arctan \left( \frac{{z}_{i}}{{x}_{i}}\right) θi=arctan(xizi)
随后,利用这些角度对检测范围进行等分,将点云划分为 M×NM \times NM×N 个单元

在每个单元内,计算所有点的几何中心并定义局部平滑度以提取平面特征,较低的平滑度值意味着平面特征平坦

深度到地图(Depth-to-map)残差

深度残差通过将采样的平面点云匹配到最近的子地图生成。局部建图线程识别出与当前帧在时空上达到指定接近度的关键帧。随后,利用这些关键帧的位姿及其对应的平面特征点构建子地图。

来自平面点到局部地图的点到平面残差 rl{r}_{l}rl 构建为:

rl(dci,X)=(nw)T(P′−q plane w)=JX+ω {r}_{l}\left( {{d}^{{c}_{i}}, X}\right) = {\left( {n}^{w}\right) }^{T}\left( {{P}^{\prime } - {q}_{\text{ plane }}^{w}}\right) = {JX} + \omega rl(dci,X)=(nw)T(Pq plane w)=JX+ω

误差 = 法向量 ⋅ ( 点 − 平面上一点 ),乘法向量将距离投影到固定方向
= 一阶线性化 + 噪声
点到平面的距离作为误差

J=∂rl∂X=∂rl∂P′∂P′∂X=(nw)T[I,−P′∧] J = \frac{\partial {r}_{l}}{\partial X} = \frac{\partial {r}_{l}}{\partial {P}^{\prime }}\frac{\partial {P}^{\prime }}{\partial X} = {\left( {n}^{w}\right) }^{T}\left\lbrack {I, - {P}^{\prime \land }}\right\rbrack J=Xrl=PrlXP=(nw)T[I,P]

残差对“位姿”的导数
P′=Tcwp plane c {P}^{\prime } = {T}_{c}^{w}{p}_{\text{ plane }}^{c} P=Tcwp plane c
变换到世界坐标系

  • nw{\mathbf{n}}^{w}nw 表示世界坐标系中平面的法向量
    • q plane w{q}_{\text{ plane }}^{w}q plane w 表示世界坐标系中平面的中心点
  • p plane c{p}_{\text{ plane }}^{c}p plane c 表示相机坐标系中的平面特征点
  • Tcw{T}_{c}^{w}Tcw 表示从相机坐标系到世界坐标系的位姿变换矩阵
  • ω\omegaω 是点到平面的观测噪声。

实验

对比实验

在宇树的Go2 四足机器人与 G1 人形机器人上进行了验证

在这里插入图片描述
六个测试序列,其中机器人狗四个,人形机器人两个:

在这里插入图片描述

  • Seq1 室内办公室
  • Seq2 无纹理走廊环境
  • Seq3 地下停车场,光线较暗且有反光。
  • Seq4 广场,地面纹理重复
  • Seq5 室内办公室
  • Seq6 室外

Seq1-4 在 Go2 机器狗上,Seq5-6 在 G1 人形机器人上

与 VINS 系列(VINS-RGBD(RGBD+IMU)和 S-VIO(RGBD+IMU))及 ORB-SLAM3 进行对比:

在这里插入图片描述
在这里插入图片描述

性能对比,在比ORB-SLAM3引入额外观测的前提下,每帧处理约 20-30ms

在这里插入图片描述

优势分析

性能归因于三大因素:

  • 鲁棒位姿初始化:受腿式机器人运动特性的影响,IMU 数据常常存在误差。如图所示,Seq1-6 中的原始 IMU 数据严重畸变,四足机器人最大加速度达 40  m/s2{40}\mathrm{\;m}/{\mathrm{s}}^{2}40m/s2,人形机器人为 20  m/s2{20}\mathrm{\;m}/{\mathrm{s}}^{2}20m/s2

在这里插入图片描述

  • 双流光流跟踪:腿式机器人的独特运动特性常导致图像模糊,严重影响特征跟踪的鲁棒性。但双流光流方法利用先验地图点与位姿信息,即使当前图像模糊也能有效跟踪特征
  • 紧耦合深度约束:在无纹理环境中,视觉特征点稀少,位姿估计困难。通过耦合深度到地图和 GICP 约束,提升了精度与鲁棒性

TABLE III. EVALUATION RESULT ON OPENLOROS DATASET. THE BEST RESULT IS HIGHLIGHTED IN BOLD AND SYMBOL \ INDICATES FAILURE.

VINS-Mono VINS-RGBD ORBSLAM3 S-VIO VID-SLAM DDIO-VIO GeoFlow-SLAM
Home1-1 1.0760 0.4520 0.9290 0.4020 0.3820 0.4060 0.4575
Home1-2 0.5420 0.3790 \ 0.3160 0.3620 0.3470 0.3775
Office1-1 0.2310 0.1010 0.0680 0.1010 0.0670 0.0780 0.0577
Office1-2 0.2890 0.1240 0.1230 0.0990 0.1080 0.0700 0.0700
Office1-3 0.1550 0.1540 \ 0.1510 0.0220 0.1040 0.0291
Office1-4 0.3920 0.1860 0.2530 0.1640 0.1290 0.1440 0.1554
Office1-5 0.2380 0.2390 \ 0.2120 0.2090 0.2140 0.2000

总结

GeoFlow-SLAM,相比于学术的创新,更偏向于工程落地

  • 双流光流跟踪与先验地图点和位姿信息结合的方法,增强了高速运动场景下的特征跟踪。
  • 结合 IMU/腿式里程计、帧间 PnP 与 GICP 的位姿初始化方法,即使在无 IMU 数据情况下也能保证可靠的位姿估计。
  • 紧耦合几何 GICP 约束,在视觉无纹理环境中显著提升了性能。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐