
一句话概括: 用 Astra Pro 深度相机 + 轮式编码器,让仓库机器人在未知环境中边走边建图、秒速重定位,还能自动绕开动态障碍物——关键是,不用 IMU 也不会飞飘!
*来源: 第二届 3D 视觉创新应用竞赛 | 作者:** 胡明豪 *
*硬件平台:** Astra Pro 深度相机 + NVIDIA TX2 + 轮式编码器 *
*GitHub:** RobotV_Storage-robot*
📌 一、项目亮点速览
| 🔥 核心能力 | 🛠️ 技术实现 | 💡 亮点解读 |
|---|---|---|
| 🚫 禁用 IMU,告别"飞飘" | 轮式编码器替代 IMU 作为前端位移估计 | 比惯性测量更稳,比纯视觉更准 |
| 🏗️ 半稠密点云建图 | RGB-D 点云 + OctoMap 八叉树增量拼接 | 大规模场景实时性好,栅格地图随时可用 |
| 📍 任意地点重定位 | 加载已有姿态图 + 回环检测 | 关机再开机,秒回世界坐标 |
| 🏃 动态障碍物检测 | 借鉴 RTAB-Map 点云分割算法 | 仓库里飞奔的叉车?轻松绕开! |
| 🧭 可配置回环策略 | mapping / location 双模式切换 | 建图时全量回环,定位时只匹配关键帧 |
| ⚡ 灵活部署 | ROS 模块化 launch 启动 | 一键启动建图 / 定位 |
🌍 二、背景与意义
2.1 仓库自动化的"最后一公里"
现代仓储物流行业正经历一场自动化革命 📦。AGV(自动导引车)和移动机器人需要在未知或半未知的仓库环境中完成以下任务:
- 🗺️ 自主建图:第一次进入仓库,边走边构建环境地图
- 📍 精确定位:在已有地图中快速确定自身位置
- 🏃 动态避障:检测并绕过移动的叉车、行人等障碍物
- 🧭 路径规划:基于栅格地图规划最优行驶路线
2.2 传统方案的痛点
| 😱 痛点 | 🔍 原因分析 |
|---|---|
| IMU 积分漂移严重 | 长时间运行后姿态估计偏差累积,轨迹"飞飘" |
| 纯视觉里程计不稳定 | 光照变化、纹理缺失场景下容易跟丢 |
| 稠密建图算力吃紧 | 全像素点云拼接对嵌入式平台(TX2)压力过大 |
| 重定位困难 | 缺乏回环检测或姿态图优化,关机后丢失全局坐标 |
2.3 本方案的解决思路
核心洞察: 仓库小车的轮式编码器能提供比 IMU 更稳定的位移估计,Astra Pro 的深度信息能直接生成半稠密点云——把两者结合,既稳又准!
🛠️ 三、系统硬件架构
3.1 硬件组成一览

| 🔧 设备 | 📋 型号 / 规格 | 🎯 功能 |
|---|---|---|
| 📷 深度相机 | Astra Pro(单目结构光) | RGB + Depth 数据采集,640×480@30fps |
| 💻 计算平台 | NVIDIA TX2 | 运行 VINS-Fusion 算法 + OctoMap 建图 |
| 🔄 位移传感器 | 轮式编码器 | 提供精确的前后 / 旋转位移估计 |
| 🦾 执行机构 | 5 自由度机械臂 + 气动夹爪 | 抓取 & 搬运(部分场景) |
| ⚡ 电源系统 | 电控柜 + 锂电池 | 整车供电 |
3.2 Astra Pro 相机参数
| 参数 | 规格 |
|---|---|
| 成像技术 | 单目结构光 |
| 深度范围 | 0.6m ~ 8m |
| RGB 分辨率 | 640 × 480 |
| Depth 分辨率 | 640 × 480 |
| 帧率 | 30 fps(固定) |
| 深度单位 | 毫米(代码中需 ×0.001 转为米) |
⚠️ 踩坑提醒: Astra Pro 的 RGB 相机没有出厂内参,需要用 ROS
camera_calibration包手动标定!标定结果示例见astrapro.yaml。
3.3 轮式编码器
- 提供小车前进/后退位移 + 旋转角度
- 替代 IMU 作为 VINS 前端位姿估计输入
- 优势:无积分漂移,长时间运行稳定
🎬 四、系统整体流程
[配图说明] Image Prompt: Clean flowchart diagram showing the complete VSLAM pipeline, 16:9 aspect ratio. Left to right flow: Astra Pro camera (RGB+Depth) → Wheel Encoder data → VINS-Fusion Frontend (feature tracking + pose estimation) → Sliding Window Optimization → Loop Closure Detection → Pose Graph Optimization → OctoMap 3D Mapping → Grid Map Generation → Navigation (move_base). Each stage in a rounded rectangle box with icons. Hand-drawn vector style with arrows showing data flow.
4.1 从"看见"到"建图"的完整链路

4.2 建图模式 vs 定位模式
| 模式 | 配置参数 | 回环策略 | 适用场景 |
|---|---|---|---|
| 🏗️ Mapping | AGV_MODEL=mapping |
与所有关键帧回环 | 首次进入未知环境 |
| 📍 Location | AGV_MODEL=location |
仅与已加载姿态图关键帧回环 | 已有地图,快速重定位 |
🔬 五、核心算法详解
5.1 VINS-Fusion 前端:特征跟踪

VINS-Fusion 的前端负责从连续图像帧中跟踪特征点,核心流程如下:
- FAST 角点检测:每帧提取角点作为特征
- BRIEF 描述子计算:用预定义的随机点对模式生成二进制描述子
- 光流追踪:KLT 光流将特征从前一帧追踪到当前帧
- 深度相机处理:利用 Astra Pro 的深度信息,将 2D 特征反投影为 3D 点
关键代码(feature_tracker.cpp 核心逻辑):
// 1. FAST 角点检测
cv::FAST(image, new_features, fast_threshold, true);
// 2. KLT 光流追踪
std::vector<uchar> status;
cv::calcOpticalFlowPyrLK(prev_img, cur_img, prev_pts, cur_pts, status, err);
// 3. 深度信息关联:将 2D 特征点映射到 3D
for (auto &pt : cur_pts) {
float depth = depth_image.at<float>(pt.y, pt.x);
if (depth > 0) {
Eigen::Vector3d point_3d = camera_model->projectPixelTo3D(pt, depth);
points_3d.push_back(point_3d);
}
}
5.2 轮式编码器替代 IMU:告别"飞飘"
这是本项目的最大创新点之一 🏆
问题:为什么 IMU 会飞飘?
VINS-Fusion 原本设计为视觉-惯性融合(VIO),使用 IMU 的加速度计和陀螺仪数据作为运动先验。但在实际测试中:
| 现象 | 原因 |
|---|---|
| 轨迹突然"飞走" | IMU 零漂 + 积分误差累积 |
| 静止时仍在漂移 | 陀螺仪 bias 估计不准确 |
| 增加迭代次数有改善但仍不稳定 | 优化问题在某些场景下非凸 |
解决方案:轮式编码器上场!
// 伪代码:轮式编码器数据接入前端
void EncoderCallback(const nav_msgs::Odometry::ConstPtr& odom) {
// 获取编码器测量的位移和旋转
double dx = odom->pose.pose.position.x - last_x;
double dy = odom->pose.pose.position.y - last_y;
double dyaw = getYaw(odom->pose.pose.orientation) - last_yaw;
// 直接作为前端位姿估计输入(替代 IMU 积分结果)
Eigen::Vector3d encoder_t(dx, dy, 0);
Eigen::Matrix3d encoder_R = Eigen::AngleAxisd(dyaw, Eigen::Vector3d::UnitZ()).toRotationMatrix();
// 送入 VINS 估计器
estimator->inputEncoder(encoder_t, encoder_R, odom->header.stamp.toSec());
}
💡 核心优势: 轮式编码器的位移测量是相对增量,不会像 IMU 那样产生累积漂移。在小车匀速行驶时,编码器精度可达厘米级甚至毫米级!
5.3 关键帧管理 & 回环检测

关键帧(KeyFrame)是 VINS 系统的核心数据结构,每个关键帧包含:
| 字段 | 类型 | 说明 |
|---|---|---|
time_stamp |
double |
时间戳 |
vio_T_w_i / vio_R_w_i |
Vector3d / Matrix3d |
VIO 估计的位姿 |
T_w_i / R_w_i |
Vector3d / Matrix3d |
优化后的全局位姿 |
point_3d |
vector<cv::Point3f> |
3D 点云 |
point_2d_uv |
vector<cv::Point2f> |
图像平面坐标 |
brief_descriptors |
vector<BRIEF::bitset> |
BRIEF 描述子 |
loop_info |
Matrix<double, 8, 1> |
回环相对位姿(t + q + yaw) |
回环检测流程(简化伪代码):
输入:当前关键帧 cur_kf
输出:是否检测到回环 + 相对位姿
1. 从词袋模型中检索候选关键帧 candidates[]
2. 对 cur_kf 和每个 candidate 做 BRIEF 描述子匹配
3. 用 RANSAC 剔除误匹配 → 得到 inliers
4. 若 inliers ≥ MIN_LOOP_NUM:
a. 用 PnP-RANSAC 求解候选帧 → 当前帧的相对位姿
b. 检查几何一致性(yaw < 30°, 位移 < 20m)
c. 通过 → 建立回环约束
5. 将回环信息推入优化队列
关键代码(keyframe.cpp — findConnection 函数核心逻辑):
// Step 1: BRIEF 描述子匹配
searchByBRIEFDes(matched_2d_old, matched_2d_old_norm, status,
old_kf->brief_descriptors, old_kf->keypoints, old_kf->keypoints_norm);
// Step 2: RANSAC 剔除误匹配
FundmantalMatrixRANSAC(matched_2d_cur_norm, matched_2d_old_norm, status);
// Step 3: PnP-RANSAC 求解相对位姿
PnPRANSAC(matched_2d_old_norm, matched_3d, status, PnP_T_old, PnP_R_old);
// Step 4: 几何一致性检查
relative_t = PnP_R_old.transpose() * (origin_vio_T - PnP_T_old);
relative_yaw = normalizeAngle(R2ypr(origin_vio_R).x() - R2ypr(PnP_R_old).x());
if (abs(relative_yaw) < 30.0 && relative_t.norm() < 20.0) {
has_loop = true;
loop_info << relative_t.x(), relative_t.y(), relative_t.z(),
relative_q.w(), relative_q.x(), relative_q.y(), relative_q.z(),
relative_yaw;
}
5.4 姿态图优化(Pose Graph Optimization)
当检测到回环后,系统需要对整个轨迹进行全局优化,消除累积漂移。
4-DoF 优化(无 IMU 模式)
由于禁用了 IMU,系统只优化 x、y、z 平移 + yaw 旋转(4 自由度),pitch 和 roll 不可观测:
// 优化的代价函数(简化)
// 只优化 x, y, z, yaw —— pitch 和 roll 由相机安装方式确定
for (auto &kf : keyframelist) {
// 回环约束
if (kf->has_loop) {
Vector3d loop_t = kf->getLoopRelativeT();
Quaterniond loop_q = kf->getLoopRelativeQ();
// 将回环约束加入优化问题
problem.AddResidualBlock(
new CeresPoseGraphFactor(loop_t, loop_q, /*只优化x,y,z,yaw*/)
);
}
}
ceres::Solve(options, &problem, &summary);
漂移补偿逻辑
当检测到跨序列回环时,系统会一次性补偿整个序列的漂移:
// 跨序列回环:将整个序列的位姿整体平移+旋转
if (old_kf->sequence != cur_kf->sequence && sequence_loop[cur_kf->sequence] == 0) {
w_r_vio = shift_r; // 累积旋转漂移
w_t_vio = shift_t; // 累积平移漂移
// 遍历该序列所有关键帧,统一补偿
for (auto &kf : keyframelist) {
if (kf->sequence == cur_kf->sequence) {
Vector3d P; Matrix3d R;
kf->getVioPose(P, R);
P = w_r_vio * P + w_t_vio;
R = w_r_vio * R;
kf->updateVioPose(P, R);
}
}
sequence_loop[cur_kf->sequence] = 1; // 标记该序列已补偿
}
5.5 OctoMap 八叉树建图

核心思路
传统点云拼接的问题:每帧点云都累加 → 内存爆炸 💥
OctoMap 的解决方案:用八叉树分区存储 → 相同区域只保留最新状态
建图流程
// 1. 接收当前帧的 RGB-D 点云
void OctomapCallback(const sensor_msgs::PointCloud2::ConstPtr& cloud_msg) {
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::fromROSMsg(*cloud_msg, *cloud);
// 2. 获取当前相机位姿
Eigen::Isometry3d camera_pose = getCurrentCameraPose();
// 3. 将点云变换到世界坐标系
pcl::transformPointCloud(*cloud, *cloud_world, camera_pose.inverse());
// 4. 插入 OctoMap(内部自动处理遮挡和更新)
for (auto &pt : cloud_world->points) {
octomap->updateNode(pt.x, pt.y, pt.z, true); // 标记为 occupied
}
// 5. 发布栅格地图供导航使用
publishGridMap();
}
栅格地图生成
OctoMap 输出的是三维体素地图,而 move_base 导航需要二维栅格地图。系统通过 grid_mapper 模块完成转换:
// grid_mapper.cpp:基于射线投射的栅格更新
void GridMapper::updateMap(Vector3d pointWorld, Vector3d PG_T) {
// 从传感器位置 PG_T 到观测点 pointWorld 发射"射线"
double angle = atan2(pointWorld[1] - PG_T[1], pointWorld[0] - PG_T[0]);
double z = sqrt((pointWorld[0]-PG_T[0])^2 + (pointWorld[1]-PG_T[1])^2);
// 沿射线遍历每个栅格
for (double r = 0; r < z + cell_size; r += inc_step) {
Eigen::Vector2d p_w(r * cos(angle) + PG_T[0], r * sin(angle) + PG_T[1]);
updateGrid(p_w, laserInvModel(r, z, cell_size));
}
}
// 激光逆测量模型
double GridMapper::laserInvModel(double r, double R, double cell_size) {
if (r < R - 0.5 * cell_size) return P_free_; // 射线经过 → 空闲
if (r > R + 0.5 * cell_size) return P_prior_; // 超出范围 → 先验
return P_occ_; // 在观测点附近 → 占用
}
栅格地图参数说明:
| 参数 | 值 | 说明 |
|---|---|---|
| 地图尺寸 | 1500 × 500 cells | 覆盖 75m × 25m 区域 |
| 栅格分辨率 | 0.05m(5cm) | 兼顾精度与内存 |
| 原点偏移 | (750, 250) | 地图中心对齐世界原点 |
| 占用概率 | P_occ = 0.6 | 观测到物体时的概率 |
| 空闲概率 | P_free = 0.4 | 射线经过的空区域 |
| 先验概率 | P_prior = 0.5 | 未观测区域 |
5.6 动态障碍物检测
仓库环境中有大量动态物体(叉车、行人、其他 AGV),静态地图无法处理这些情况。本方案借鉴 RTAB-Map 的点云分割算法:
// 伪代码:动态障碍检测
void DetectDynamicObstacles(pcl::PointCloud<pcl::PointXYZRGB>::Ptr current_cloud,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr map_cloud) {
// 1. 将当前帧点云与地图点云做 ICP 对齐
pcl::IterativeClosestPoint<pcl::PointXYZRGB, pcl::PointXYZRGB> icp;
icp.setInputSource(current_cloud);
icp.setInputTarget(map_cloud);
icp.align(*aligned_cloud);
// 2. 计算残差:残差大的点 = 动态物体
for (int i = 0; i < current_cloud->size(); i++) {
double distance = (current_cloud->points[i].x - map_cloud->points[i].x)^2 + ...;
if (distance > dynamic_threshold) {
dynamic_obstacles.push_back(current_cloud->points[i]);
}
}
// 3. 将动态障碍发布到 navigation stack
publishDynamicObstacles(dynamic_obstacles);
}
5.7 KCF 目标跟踪(主动跟随模式)

系统还包含一个主动跟随功能,使用 KCF(Kernelized Correlation Filter) 跟踪算法:
// kcftracker.cpp:KCF 跟踪器核心
// 1. 初始化:在首帧中框选目标
tracker.init(selected_roi, first_frame);
// 2. 每一帧更新目标位置
cv::Rect new_roi = tracker.update(current_frame);
// 3. 根据目标位置计算控制指令
double target_cx = new_roi.x + new_roi.width / 2.0;
double image_cx = current_frame.cols / 2.0;
double angular_error = (target_cx - image_cx) / image_cx;
// 4. 发布速度指令
geometry_msgs::Twist cmd;
cmd.linear.x = forward_speed;
cmd.angular.z = -angular_error * kp; // P 控制器
cmd_vel_pub.publish(cmd);
KCF 算法特点:
| 特性 | 说明 |
|---|---|
| 🏎️ 速度极快 | 基于 FFT 的核相关滤波,CPU 实时运行 |
| 📐 HOG 特征 | 对光照变化鲁棒 |
| 🔄 多尺度 | 支持目标尺寸变化(scale_step = 1.05) |
| 🎯 亚像素精度 | 二次插值实现峰值精确定位 |
📊 六、性能指标
6.1 建图精度
| 指标 | 数值 | 说明 |
|---|---|---|
| 回环检测最小匹配点数 | 可配置(默认 50+) | MIN_LOOP_NUM 参数 |
| 位姿图优化频率 | 后台线程异步执行 | 不阻塞前端 |
| 栅格地图分辨率 | 5cm | 满足 AGV 导航需求 |
| 点云拼接方式 | 增量式(OctoMap) | 内存可控 |
6.2 系统帧率
| 模块 | 帧率 | 平台 |
|---|---|---|
| Astra Pro 数据采集 | 30 FPS | 硬件固定 |
| 特征跟踪 + 位姿估计 | ~25-30 FPS | TX2 |
| OctoMap 更新 | ~15-20 FPS | TX2 |
| KCF 跟踪 | ~50+ FPS | TX2 |
6.3 重定位性能
| 场景 | 重定位时间 | 精度 |
|---|---|---|
| 同位置启动 | < 1s | 厘米级 |
| 异地启动(需回环) | 2-5s | 依赖环境特征丰富度 |
🛠️ 七、技术栈总览
| 类别 | 技术选型 | 版本 / 说明 |
|---|---|---|
| 🐧 操作系统 | Ubuntu | 16.04 / 18.04 |
| 🤖 机器人框架 | ROS | Kinetic / Melodic |
| 📷 相机驱动 | OpenNI2 + libuvc_ros | Astra Pro 适配 |
| 🔬 视觉算法 | VINS-Fusion(改造版) | 禁用 IMU,接入编码器 |
| 🌳 建图库 | OctoMap | 八叉树体素地图 |
| 🧭 导航库 | move_base | A* / Dijkstra 路径规划 |
| 📐 线性代数 | Eigen | 矩阵运算 |
| 🖼️ 图像处理 | OpenCV | 2.4.8 |
| ☁️ 点云处理 | PCL | 1.7 |
| 📈 优化库 | Ceres Solver | 姿态图优化 |
| 📦 编译系统 | CMake | ≥ 2.8.3 |
💡 八、技术创新亮点
| 🏆 创新点 | 📝 说明 | 🎯 解决的问题 |
|---|---|---|
| 🔄 轮式编码器替代 IMU | 禁用 IMU,用编码器数据作为前端位移估计 | 彻底消除飞飘问题 |
| 🗺️ OctoMap 增量建图 | 只发布当前帧点云,后端异步拼接 | 大规模场景下实时性好 |
| 📍 双模式切换 | mapping / location 两种 launch 配置 | 建图和定位灵活切换 |
| 🏃 动态障碍检测 | 借鉴 RTAB-Map 点云分割 | 仓库动态环境安全导航 |
| 🔧 4-DoF 优化 | 只优化 x, y, z, yaw | 无 IMU 时依然鲁棒 |
与传统方案对比
| 对比项 | 传统 VINS-Fusion(IMU) | 本方案(编码器) |
|---|---|---|
| 静止时轨迹稳定性 | ❌ 容易飞飘 | ✅ 稳定不动 |
| 长时间运行漂移 | ❌ 累积严重 | ✅ 编码器无积分漂移 |
| 回环校正效果 | ⚠️ 依赖 IMU bias 估计 | ✅ 直接补偿平移+偏航 |
| 嵌入式平台适配 | ⚠️ 算力要求高 | ✅ TX2 流畅运行 |
🧩 九、踩坑与解决方案
9.1 已解决的问题
| 😱 问题 | 🔍 原因 | ✅ 解决方案 |
|---|---|---|
| IMU 导致轨迹飞飘 | 零漂 + 积分累积 | 禁用 IMU,使用轮式编码器 |
| RGB 相机无内参 | Astra Pro SDK 不提供 | 用 camera_calibration 标定 |
| 深度单位不匹配 | Astra 输出毫米,代码期望米 | 读取后 ×0.001 转换 |
| RGB 与 Depth 时间戳不同步 | 硬件限制,最大差 ~20ms | 使用 ApproximateTimeSynchronizer |
| TX2 内存不足 | 稠密点云全量保存 | 改用 OctoMap 增量式 |
| KCF 转角大时目标丢失 | 图像平面投影后目标出界 | 限制最大转角,增加重检测逻辑 |
9.2 已知局限
| ⚠️ 局限 | 📝 说明 | 🛠️ 改进方向 |
|---|---|---|
| 室外效果差 | 结构光受阳光干扰 | 改用 ToF 或双目方案 |
| 只测试了 Astra Pro | 其他相机未验证 | 扩展支持 Realsense 等 |
| KCF 跟踪不够鲁棒 | 遮挡 / 快速运动下易丢失 | 融合 YOLO 检测做重检测 |
| TX2 算力瓶颈 | 大场景建图帧率下降 | 升级到 Orin Nano |
🚀 十、如何使用
10.1 环境依赖
# Ubuntu 16.04 + ROS Kinetic
sudo apt install ros-kinetic-desktop-full
sudo apt install ros-kinetic-cv-bridge ros-kinetic-image-transport
sudo apt install ros-kinetic-opencv3 ros-kinetic-pcl-ros
# Ceres Solver
git clone https://ceres-solver.googlesource.com/ceres-solver
cd ceres-solver && mkdir build && cd build
cmake .. && make -j4 && sudo make install
# OctoMap
sudo apt install ros-kinetic-octomap ros-kinetic-octomap-msgs
10.2 编译
cd ~/catkin_ws/src
git clone https://github.com/3DCVdeveloper/RobotV_Storage-robot.git
cd ..
catkin_make
source devel/setup.bash
10.3 运行 —— 建图模式
# Terminal 1: 启动 VINS-Fusion(建图模式)
roslaunch vins vins_astrapro_map.launch
# Terminal 2: 启动回环融合
rosrun loop_fusion loop_fusion_node
~/catkin_ws/src/RobotV_Storage-robot/config/astrapro/realsense_depth_imu_config_astrapro.yaml
# Terminal 3: 启动 OctoMap 建图服务
roslaunch octomap_service your_octomap.launch
# Terminal 4: 启动 RViz 可视化
roslaunch vins vins_rviz.launch
10.4 运行 —— 定位模式
# Terminal 1: 启动定位节点
roslaunch loop_fusion loop_fusion_astrapro_location.launch
# Terminal 2: 启动 VINS 节点(加载已有姿态图)
rosrun vins vins_node
~/catkin_ws/src/RobotV_Storage-robot/config/astrapro/realsense_depth_imu_config_astrapro_location.yaml
# Terminal 3: RViz 可视化
roslaunch vins vins_rviz.launch
10.5 保存地图
# 保存 OctoMap 点云地图
rosservice call /octomap_save "map.bt"
# 保存栅格地图(由 grid_mapper 提供)
# 地图自动保存为 map.png + map.yaml
🌟 十一、总结与展望
核心贡献
- 🔄 轮式编码器替代 IMU —— 从根本上解决了 VINS 在嵌入式平台上的飞飘问题
- 🗺️ OctoMap 增量建图 —— 大规模场景下实时性好,栅格地图直接用于导航
- 📍 任意地点重定位 —— 加载已有姿态图,秒级恢复全局坐标
- 🏃 动态障碍感知 —— 仓库动态环境下的安全导航保障
- 🔧 工程化适配 —— 完整的 ROS launch 配置、双模式切换、参数化 yaml 配置
未来方向
| 🚀 方向 | 🎯 目标 |
|---|---|
| ⚡ 硬件升级 | TX2 → Orin Nano,提升建图帧率 |
| 🧠 语义建图 | 融合深度学习目标检测,给地图加标签(货架、通道、障碍) |
| 📱 多机协同 | 多台 AGV 共享地图,协同建图 |
| 🎯 更鲁棒的跟踪 | KCF + YOLO 融合,解决遮挡和快速运动 |
| 🌐 多传感器融合 | 编码器 + 视觉 + IMU 三模融合,自适应切换 |
🌟 写在最后: 这个项目最让人佩服的地方在于——它解决了一个真实的工程痛点。IMU 飞飘不是什么新鲜话题,但真正在嵌入式平台上用轮式编码器干净利落地替代掉 IMU,还把整个建图-定位-导航链路跑通,是需要扎实功力的。对于仓储物流场景,这套方案提供了低成本、高鲁棒性的 VSLAM 解决思路,值得每一位做移动机器人的同学参考!🏆
相关资源:
- 📖 VINS-Fusion 原版: https://github.com/HKUST-Aerial-Robotics/VINS-Fusion
- 📖 RGB-D 适配参考: https://github.com/ManiiXu/VINS-Fusion-RGBD
- 📖 OctoMap 文档: http://octomap.github.io