19f1be884cb09.png

*来源: 第一届3D视觉创新应用竞赛 | 参赛者:** 徐冠宇 *

*相机型号: Astra Pro | 支持设备:** Zora P1 开发板、KUKA R2700 六轴机械臂 *

*开发环境: Armbian (Zora P1) / Windows + VS2017 | 核心库:** OpenNI2 SDK、Open3D、numpy *

*源代码:** https://github.com/3DCVdeveloper/RobotV_Guidance*


一、项目亮点速览 ✨

想象一下:工厂流水线上,鞋底随意丢在传送带上,角度各异、位置随机——没有人工干预,机械臂却能自动"看"到鞋底、精准定位、然后稳稳地沿着鞋底边缘涂上一圈胶水 🎯

这不是科幻电影,而是本项目的真实目标!

基于点云的视觉引导系统,核心能力是:无论待引导物体以何种位姿摆放(只要在机械臂行程范围内),视觉系统都能定位到该物体,并引导机械臂按需要的轨迹完成工艺流程。

典型应用场景: 鞋底涂胶、汽车玻璃涂胶、零件装配等需要精确轨迹引导的工业现场。

六大核心能力一览:

核心能力 技术实现 效果
📷 点云采集 Astra Pro 深度相机 + OpenNI2 SDK 3mm@1m 精度
🎯 相机标定 张正友算法 + 70%角点筛选策略 重投影误差降低 57%
🤝 手眼标定 Umeyama 刚性变换算法 无标定板也能完成
🔍 点云匹配 FPFH + RANSAC + ICP 三级联调 精配准重合率 ≥ 90%
🛤️ 轨迹引导 模板轨迹 + 基坐标系偏移 实际引导精度 ~5mm
🔧 跨平台部署 OpenNI2 + Open3D 跨平台特性 支持 Armbian / Ubuntu / Android / Windows

二、背景与意义 🌍

2.1 行业痛点

近年来,随着机器视觉和工业机器人越来越广泛地投入使用,"机器换人"的趋势日趋明显 🏭

传统方案 痛点
纯工业机器人 只能完成重复性工作,缺乏柔性,无法应对任意位姿的工件
2D 视觉引导 缺乏深度信息,难以满足六自由度的引导要求
工业级 3D 相机 精度高(0.2mm@1m)但价格昂贵,中小工厂难以承受

💡 突破口: 消费级深度相机(如 Astra Pro,3mm@1m)虽然精度不及工业级,但结合巧妙的算法设计,完全能满足工业现场 cm 级引导需求!

2.2 应用场景

应用领域 具体场景
👟 鞋底涂胶 鞋底轮廓轨迹引导,替代人工涂胶
🚗 汽车玻璃涂胶 车窗/挡风玻璃密封胶轨迹引导
🔩 零件装配 扩展引导能力,实现零件抓取与装配
📦 无序分拣 配合夹爪实现散乱工件的识别与分拣

2.3 市场潜力

轨迹引导已广泛应用于汽车、制鞋等各个领域。随着柔性制造需求的爆发,基于 3D 点云 的视觉引导系统将成为智能工厂的核心基础设施之一,未来市场潜力巨大 📈


三、系统硬件架构 🛠️

3.1 硬件全家福

编号 设备 型号 / 规格 角色
1 点云相机 Astra Pro(奥比中光) 采集 RGB-D 数据
2 开发板 Zora P1(奥比中光) 点云采集 + 匹配计算
3 工业机器人 KUKA KR 210 R2700 extra 引导执行机构
4 引导设备 M8 螺栓(条件有限,代替胶枪) 模拟涂胶末端
5 待引导物品 鞋垫 轨迹引导目标

⚠️ 开发板替代方案: Zora P1 也可用普通 PC 替代;机械臂也可替换为其他六轴工业机器人;引导设备有条件时可换为真实胶枪。

3.2 核心硬件参数

Astra Pro 深度相机:

参数 规格
成像原理 单目结构光(激光散斑)
工作范围 0.6m ~ 8m
深度精度 3mm @ 1m
分辨率 640 × 480
限制 MX400 芯片导致无法导出出厂相机参数 ⚠️

Zora P1 开发板:

参数 规格
内存 2GB
存储 16GB
网络 板载 WiFi
操作系统 Armbian(默认)/ Ubuntu / Android
特点 奥比中光专为 3D 视觉定制,高度适配 Astra 系列相机

KUKA KR 210 R2700 extra:

参数 规格
轴数 6 轴
负载 210kg
臂展 2700mm
通讯 EthernetKRL(Windows)/ PROFINET(Linux)

3.3 系统拓扑

19f1c106e310e.png

数据流: Astra Pro 通过 USB 将深度帧发送给 Zora P1 → C++ 程序将深度图转为点云并保存 → Python 程序执行点云匹配 → 输出偏移量 → 人工通过示教器写入机械臂基坐标系


四、系统整体流程 🎬

4.1 从"看到"到"涂到"的完整链路

整个视觉引导过程可拆解为 六步闭环:

19f1c32df80ec.png

4.2 核心思路:相对测量 + 坐标系偏移

本项目的核心创新在于 化"绝对定位"为"相对测量":

传统思路 本方案思路
直接测量物体在世界坐标系中的绝对位姿 先建立模板位姿,再计算当前位姿相对于模板的变换
对点云精度要求极高 利用相对关系,降低对单点精度的依赖
精度受相机精度限制严重 精度满足 cm 级工业引导需求

两个核心过程:

  1. 定位过程 → 将"定位问题"转化为"点云匹配问题"
  1. 引导过程 → 将"引导问题"转化为"模板轨迹 + 基坐标系偏移"

五、核心算法详解 🔬

5.1 相机标定 —— 在受限条件下"榨干"精度

问题背景

Astra Pro 由于 MX400 芯片的限制,无法导出出厂相机参数(内参 & 外参)。而内参和外参直接关系到:

  • 深度图 → 点云的三维坐标转换
  • 深度图与彩色图的对齐(D2C)

工业级标定需要:碳纤维标定板 + 红外光源 + 遮住激光器。但普通开发者通常不具备这些条件 😭

创新方案:70% 角点筛选策略

本项目用代码生成高分辨率棋盘格图像 → 打印到纸上 → 贴到平板上,自制标定板!

核心思路:先用所有角点标定一次 → 筛除重投影误差最大的 30% 角点 → 用剩余 70% 的"优质角点"重新标定

# 标定流程伪代码
# Step 1: 采集20个姿态的棋盘格图像(彩色+红外)
collect_chessboard_images(n_poses=20)

# Step 2: 执行第一次标定(使用所有角点)
result_all = calibrate_camera(use_all_corners=True)
errors_all = compute_reprojection_errors(result_all)

# Step 3: 筛选 —— 保留重投影误差最小的70%角点
threshold = np.percentile(errors_all, 30)  # 取30%分位数
good_mask = errors_all < threshold

# Step 4: 用筛选后的角点执行第二次标定
result_filtered = calibrate_camera(use_corners=good_mask)
errors_filtered = compute_reprojection_errors(result_filtered)

标定效果对比:

指标 使用所有角点 筛除30%后
RGB 相机重投影误差 0.217 0.145 ✅
IR 相机重投影误差 1.168 0.482 ✅
双目相机重投影误差 0.906 0.387 ✅
彩色图与深度图对齐 偏差明显 对齐精准 ✅

📖 参考算法: Zhang, Z. "A Flexible New Technique for Camera Calibration", PAMI 2000


5.2 手眼标定 —— 没有标定板也能搞定 🤝

传统方法的困境

工业上"眼在手外"的标准手眼标定流程:

  1. 把标定板固定在机械臂末端
  1. 机械臂带着标定板运动多个姿态
  1. 外部相机拍摄每个姿态的标定板图像
  1. 建立闭环运动链方程:AX = XB
  • A 与相机相关,B 与机械臂相关
  • X 为手眼矩阵(相机坐标系 → 机械臂基坐标系)

但问题是: 没有红外光源 + 没有高精度标定板 → 红外图像中角点检测误差大 → 传统方法直接"趴窝" 💥

创新方案:4 顶点 Umeyama 法

核心洞察: 不需要标定板!只要有一个已知形状的物体(如包装盒),就能完成手眼标定!

步骤:

步骤 操作 说明
① 用深度相机扫描包装盒,获取点云 提取 4 个顶点在 相机坐标系下的坐标
② 将机械臂 TCP 做到螺栓末端 切换为 TCP 坐标系
③ 用螺栓末端逐一触碰 4 个顶点 记录 4 个顶点在 机械臂基坐标系下的坐标
④ 用 Umeyama 算法求解两组 3D 点的刚性变换 得到相机坐标系 → 机械臂基坐标系的 4×4 变换矩阵

核心代码(手眼标定):

# main1_handeye.py —— 使用 Umeyama 算法求解手眼变换
import numpy as np
from utils_my import umeyama, executeTransform

# 4个顶点在【点云相机坐标系】下的坐标 (mm)
pt3d_camera = np.array([
    [75.428, 197.790, 956.0],
    [70.142,  81.053, 889.0],
    [-153.098, 89.047, 891.0],
    [-142.923, 210.181, 959.0],
])

# 4个顶点在【机械臂基坐标系】下的坐标 (mm)
pt3d_robot = np.array([
    [1670.39, -213.59, 833.06],
    [1817.12, -213.59, 833.06],
    [1814.45,   -1.25, 833.06],
    [1667.49,   -1.25, 833.06],
])

# Umeyama 算法:计算两组 3D 点之间的刚性变换
cam2base_mtx4x4 = umeyama(pt3d_camera, pt3d_robot)

print("点云相机坐标系 → 机械臂基坐标系的变换矩阵:")
print(cam2base_mtx4x4)

标定结果(变换矩阵):

[[-0.03975, -0.86912, -0.49300, 2321.88],
 [-0.99913,  0.04094,  0.00838, -158.66],
 [ 0.01290,  0.49290, -0.86999, 1565.96],
 [ 0.00000,  0.00000,  0.00000,    1.00]]

📖 Umeyama 算法: Shinji Umeyama, "Least-squares estimation of transformation parameters between point patterns", PAMI 1991


5.3 点云匹配 —— FPFP + RANSAC + ICP 三级联调 🎯

这是整个系统的 算法核心!

5.3.1 为什么不用 ICP 直接配准?

ICP(Iterative Closest Point)精配准效果好,但有一个致命弱点:对初值极其敏感,容易陷入局部最优。

而本项目的预设前提是 —— 待引导物体以任意位姿摆放!直接用 ICP = 看运气 🎲

5.3.2 三级联调策略

19f1c378136e3.png

5.3.3 FPFH 特征 —— 为什么选它?

特性 说明
🔄 平移不变性 特征描述子不受物体平移影响
🔄 旋转不变性 特征描述子不受物体旋转影响
🛡️ 抗噪性强 归一化后离散为 11 等分直方图,对噪声鲁棒
⚡ 实现简单 相比 SHOT 等描述子,实现成本低

关键细节 —— 法线方向统一:

由于 FPFP 依赖法线信息,而法线方向具有二义性(正反两面都有可能),需要指定一个朝向点来统一法线方向。

# utils_my.py —— 法线方向统一
def changeNormalDirection(pcd, ref_point):
    """
    根据参考点调整点云法线方向,使所有法线指向同一侧
    ref_point: 参考点(通常取质心再偏移一定距离)
    """
    points = pointCloudToNdarray(pcd)
    normals = points[:, 3:6]
    
    # 计算法线与"点→参考点"向量的夹角
    vec2 = points[:, 0:3] - ref_point
    vec2 = vec2 / np.linalg.norm(vec2, axis=1, keepdims=True)
    theta_cos = np.sum(normals * vec2, axis=1, keepdims=True)
    
    # 将夹角 > 90° 的法线反转
    theta_cos_int = (theta_cos >= 0).astype(np.int) * 2 - 1
    normals = theta_cos_int * normals
    
    return ndarrayToPointCloud(np.hstack([points[:, 0:3], normals]))

5.3.4 完整匹配代码解读

# main2_pointcloud_match.py —— 点云匹配核心流程

# ========== ① 读取点云并转换到机械臂基坐标系 ==========
pcd_model = o3d.io.read_point_cloud("model.ply")   # 模板点云(零位)
pcd_guide = o3d.io.read_point_cloud("guide_1.ply") # 引导点云(当前位姿)

# 应用手眼标定矩阵:相机坐标系 → 机械臂基坐标系
pcd_model.transform(cam2base_mtx4x4)
pcd_guide.transform(cam2base_mtx4x4)

# ========== ② 直通滤波器裁剪 —— 只保留鞋垫区域 ==========
# 按 Z 轴范围过滤,去除地面和无关物体
pcd_model = filterByAxis(pcd_model, axis='z', threshold=900,  if_reserve_greater=True)
pcd_model = filterByAxis(pcd_model, axis='z', threshold=1500, if_reserve_greater=False)

# ========== ③ 转换到"以点云质心为原点"的坐标系 ==========
# ⭐ 关键优化:避免旋转误差被 2m 弦长放大!
transToCentroid = np.eye(4)
transToCentroid[0:3, 3] = np.array([1756.52, -180.01, 933.09])
pcd_model.transform(inv(transToCentroid))
pcd_guide.transform(inv(transToCentroid))

# ========== ④ 计算法线 + FPFP 特征 ==========
def calcNormalAndFpfh(pcd, radius_normal, radius_feature):
    pcd.estimate_normals(
        search_param=o3d.geometry.KDTreeSearchParamHybrid(
            radius=radius_normal, max_nn=30))
    # 统一法线方向,指向质心下方 1000mm 处
    pcd = changeNormalDirection(pcd, pcd.get_center() - [0, 0, 1000])
    pcd_fpfh = o3d.registration.compute_fpfh_feature(
        pcd, o3d.geometry.KDTreeSearchParamHybrid(
            radius=radius_feature, max_nn=100))
    return pcd, pcd_fpfh

voxel_size = 15  # 点间距约 1.5mm
pcd_model, model_fpfh = calcNormalAndFpfh(pcd_model, voxel_size*2, voxel_size*5)
pcd_guide, guide_fpfh = calcNormalAndFpfh(pcd_guide, voxel_size*2, voxel_size*5)

# ========== ⑤ RANSAC + FPFP 粗配准 ==========
reg_ransac = o3d.registration.registration_ransac_based_on_feature_matching(
    pcd_model, pcd_guide,
    model_fpfh, guide_fpfh,
    distance_threshold=voxel_size * 1.5,
    estimation_method=o3d.registration.TransformationEstimationPointToPoint(False),
    ransac_n=4,
    checkers=[
        o3d.registration.CorrespondenceCheckerBasedOnDistance(voxel_size * 1.5),
        o3d.registration.CorrespondenceCheckerBasedOnEdgeLength(0.9),
        o3d.registration.CorrespondenceCheckerBasedOnNormal(0.5),
    ],
    criteria=o3d.registration.RANSACConvergenceCriteria(4000000, 500)
)

# ========== ⑥ Point-to-Point ICP 精配准 ==========
reg_p2p = o3d.registration.registration_icp(
    pcd_model, pcd_guide,
    voxel_size * 1.5,
    reg_ransac.transformation,  # 粗配准结果作为初值
    o3d.registration.TransformationEstimationPointToPoint()
)

# ========== ⑦ 计算最终偏移量 ==========
# ⭐ 核心公式:T_final = inv(T1) × T_icp × T1
# 将配准结果从"质心坐标系"变换回"机械臂基坐标系"
T_final = inv(transToCentroid) @ reg_p2p.transformation @ transToCentroid

# 分解为欧拉角 + 平移向量,返回给机械臂
euler_deg, translation = separateTransformMatrixToEulerDegT(T_final)
print(f"偏移量 —— 欧拉角(°): {euler_deg}, 平移(mm): {translation}")

5.3.5 关键优化:为什么要在质心坐标系做配准?

这是一个极其精妙的设计! 💎

鞋垫距离机械臂基坐标系原点约 2 米。旋转角度的微小误差,经过 2m 弦长的放大,会对结果造成巨大影响:

$2000 times tan(1°) = 34.9 text{ mm}$

也就是说,1° 的角度偏差 = 35mm 的位置偏差!😱

解决方案: 先把点云平移到质心为原点的局部坐标系做配准,消除旋转中心远离原点带来的放大效应,然后再把结果变换回去。

$text{最终偏移量} = text{inv}(T_1) times T_{text{ICP}} times T_1$

其中 $T_1$ 是基坐标系 → 质心坐标系的变换矩阵。


5.4 引导策略 —— 模板轨迹 + 坐标系偏移 🛤️

模板轨迹设计

将机械臂的引导轨迹简化为 P1 ~ P9 共 9 个点(P9 与 P1 重合),覆盖鞋垫的完整轮廓:

P1 ─→ P2 ─→ P3 ─→ P4 ─→ P5 ─→ P6 ─→ P7 ─→ P8 ─→ P9(=P1)

偏移量应用

点云匹配输出的 4×4 变换矩阵,本质上是当前位姿相对于模板位姿的 刚性变换。将其分解为欧拉角 + 平移向量后,直接在机械臂示教器上修改基坐标系的偏移量,机械臂就会自动沿修正后的轨迹运动 ✅

实际引导精度: 约 5mm,完全满足工业现场 cm 级引导需求 🎯


5.5 深度图转点云 —— C++ 底层实现

// main.cpp —— 将 Astra Pro 深度帧转换为 PLY 点云文件
void convertDepthToPointCloudAndSavePly(
    const uint16_t* pDepth, int width, int height, const char* ply_filename)
{
    FILE* fp = fopen(ply_filename, "w");
    
    // PLY 文件头
    fprintf(fp, "plynformat ascii 1.0n");
    fprintf(fp, "element vertex %dn", valid_count);
    fprintf(fp, "property float xnproperty float ynproperty float zn");
    fprintf(fp, "end_headern");
    
    // 遍历每个像素,将深度值转换为 3D 坐标
    for (int v = 0; v < height; ++v) {
        for (int u = 0; u < width; ++u) {
            uint16_t depth = pDepth[v * width + u];
            if (depth <= 0 || depth < MIN_DISTANCE || depth > MAX_DISTANCE)
                continue;
            
            // 反投影公式:depth → (x, y, z)
            float tx = (u - u0) / fdx;  // 利用标定出的内参
            float ty = (v - v0) / fdy;
            float world_x = depth * tx;
            float world_y = depth * ty;
            float world_z = depth;  // 深度值即 Z 坐标
            
            fprintf(fp, "%f %f %fn", world_x, world_y, world_z);
        }
    }
    fclose(fp);
}

六、测试结果分析 📊

6.1 实验设计

  • 模板点云: 鞋垫,共 8927 个点
  • 点间距: 1.5mm ~ 3mm(这是评价配准精度的天然"尺子")
  • 实验次数: 12 组,覆盖平移、旋转(含 180° 大角度翻转)等各方位姿
  • 评价指标:
  • 重合率(Fitness): 配准后两点云重合部分占比
  • 内点残差(Inlier RMSE): 配准后对应点间距离均方根误差

6.2 测试结果汇总

指标 初始状态 粗配准(RANSAC+FPFH) 精配准(ICP)
平均重合率 0.25 0.73 ✅ 0.95 ✅
最低重合率 — 0.33 0.90
平均内点残差 — 1.60 1.33 ✅
最高内点残差 — 1.78 1.46

📌 关键结论: 内点残差均值 1.33mm,而鞋垫点云的点间距本身就达 1.5~3mm,说明精配准结果 基本达到了现有条件下的理论极限!

6.3 典型实验结果可视化

12 组实验数据均以 红(模板)/ 黑(引导) 双色点云叠加显示,直观展示配准效果:

实验 初始重合率 粗配准重合率 精配准重合率 精配准内点残差
数据 1(大旋转) 0.50 0.93 0.98 1.28
数据 2(大倾斜) 0.09 0.89 0.97 1.32
数据 3(旋转 180°) 0.40 0.43 0.96 1.33
数据 4 0.29 0.78 0.96 1.38
数据 5 0.20 0.82 0.93 1.37
数据 6 0.56 0.84 0.98 1.24
数据 7 0.55 0.87 0.96 1.25
数据 8 0.28 0.79 0.95 1.37
数据 9 0.03 0.83 0.96 1.30
数据 10 0.02 0.79 0.90 1.46
数据 11 0.10 0.49 0.91 1.45
数据 12 0.07 0.33 0.98 1.26
19f1c3abee9ee.png

🏆 12 次实验全部引导成功! 即使面对 180° 翻转的极端情况,系统依然能准确定位并引导机械臂完成轨迹跟踪。


七、产品化路径 🏭

7.1 当前状态

项目 状态
引导精度 ~5mm ✅(满足 cm 级需求)
开发板 → 机械臂通讯 ❌ 未完成(受限于 KUKA EthernetKRL 仅支持 Windows)
引导方式 手动通过示教器写入偏移量

7.2 通讯方案

机械臂品牌 Linux 通讯方案 说明
KUKA PROFINET + 扩展板卡 EthernetKRL 仅支持 Windows
UR(优傲) TCP Socket ✅ 最简单,几行代码搞定
其他 ROS-Industrial 通用工业机器人 ROS 接口

💡 好消息: 如果是 UR 等原生支持 TCP 通讯的机械臂,只需写一个简单的 Socket 程序,不需要额外硬件,在 Linux 下轻松实现 🎉

7.3 扩展方向

方向 说明
🔧 零件抓取 原理与轨迹引导共通,换用夹爪即可
🔩 零件装配 在抓取基础上增加位姿匹配
📱 移动端部署 Zora P1 支持 Android,可实现手持式引导

八、技术栈总览 🛠️

层级 技术选型 用途
硬件 Astra Pro RGB-D 数据采集
硬件 Zora P1 边缘计算
硬件 KUKA KR 210 R2700 六轴工业机械臂
SDK OpenNI2 SDK 深度流获取 + 点云生成
SDK Astra SDK 彩色流 + 红外流获取
点云处理 Open3D 点云配准 + 法线估计 + FPFP
数值计算 numpy 矩阵运算 + Umeyama 算法
可视化 Open3D Visualizer 点云配准效果查看
编译 CMake + GCC C++ 程序构建
标定 OpenCV 棋盘格角点检测
部署 Armbian Linux Zora P1 运行环境

九、技术创新亮点 💡

9.1 四大核心创新

创新点 解决的问题 技术方案
📷 相机标定优化 无红外光源、无高精度标定板 70% 角点筛选 + 二次标定
🤝 手眼标定创新 无法使用传统标定板方法 4 顶点 Umeyama 刚性变换
🎯 点云匹配策略 任意位姿 + 精度有限 FPFP + RANSAC + ICP 三级联调
⚡ 质心坐标系优化 旋转误差被 2m 弦长放大 T1 变换 + 配准 + inv(T1) 还原

9.2 与传统方案对比

维度 工业级方案 本方案(消费级)
相机精度 0.2mm @ 1m 3mm @ 1m
标定设备 碳纤维板 + 红外光源 打印棋盘格 + 普通光照
手眼标定 标定板 + 多姿态运动 4 顶点 + Umeyama
引导精度 mm 级 cm 级(~5mm) ✅
成本 数万元 数千元 💰
适用场景 高精度装配 涂胶、分拣、装配(扩展)

🏆 核心结论: 用消费级硬件 + 精巧算法,实现了接近工业级应用要求的引导精度,为中小制造企业的"机器换人"提供了 低成本可行方案!


十、踩坑与解决方案 🧩

10.1 已知 Bug 记录

Bug 原因 解决方案
⚠️ SDK 路径错误 install.sh 自动生成的环境变量路径含 Include,实际为 include 手动修改 .bashrc 和 OpenNIDevEnvironment
⚠️ 彩色图镜像 OrbbecViewer 中彩色流无论是否勾选"镜像"都输出镜像图 已知问题,深度图和红外图正常
⚠️ 无法导出参数 Astra Pro 的 MX400 芯片限制 自行标定解决

10.2 硬件性能限制

限制 影响 建议
Zora P1 仅 2GB 内存 编译大型库(如 Open3D)可能 OOM 增加 swap 或换用 PC
Astra Pro 精度 3mm@1m 无法做高精度装配 满足涂胶等 cm 级需求 ✅
KUKA EthernetKRL 仅 Windows Linux 下无法直接通讯 使用 PROFINET 或换用 UR 机械臂

10.3 开发建议

💡 致奥比中光生态建设: 1. 硬件层面: 提供更多配套传感器、显示屏、移动电源等(参考树莓派生态模式) 2. 软件层面: 提供 PCL、Open3D 等常用库的 预编译包(ARM 平台编译耗时极长);补充 Zora P1 板载 GPIO 的示例文档 3. 降低门槛: 让普通开发者能快速上手,是生态繁荣的关键 🌱


十一、部署与运行指南 🚀

11.1 环境准备(Zora P1 / Armbian)

# ===== 安装依赖 =====
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install g++ python python3-pip libusb-1.0-0-dev 
    libudev-dev openjdk-8-jdk freeglut3-dev doxygen graphviz

# ===== 安装 Astra SDK =====
cd ~/Desktop/SDK/AstraSDK-v2.1.1-*/install
sudo sh ./install.sh
# 修改 ~/.bashrc,添加环境变量(注意路径不要带 install/)
export ASTRA_SDK_INCLUDE=.../include
export ASTRA_SDK_LIB=.../lib

# ===== 安装 OpenNI2 SDK =====
cd ~/Desktop/SDK/OpenNI-Linux-Arm64-2.3.0.65
sudo ./install.sh
# 修改 OpenNIDevEnvironment(Include → include)
source OpenNIDevEnvironment

# ===== 安装 Python 依赖 =====
pip3 install setuptools Cython wheel
pip3 install numpy  # 或从 apt 安装:sudo apt-get install python3-numpy

# ===== 编译安装 Open3D(耗时较长)=====
git clone --recursive https://github.com/intel-isl/Open3D
cd Open3D && mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_CUDA_MODULE=OFF 
      -DBUILD_GUI=OFF -DBUILD_TENSORFLOW_OPS=OFF 
      -DBUILD_PYTORCH_OPS=OFF ..
make -j$(nproc)
make install-pip-package

11.2 运行步骤

# ===== Step 1: 采集点云 =====
cd ~/Desktop/SDK/OpenNI-Linux-Arm64-*/Samples/SimpleRead
make
./Bin/Arm64-Release/SimpleRead
# → 输出:model.ply(模板点云)/ guide_1.ply ~ guide_12.ply(引导点云)

# ===== Step 2: 执行点云匹配 =====
cd /path/to/RobotV_Guidance
python3 main1_handeye.py        # 手眼标定(一次性)
python3 main2_pointcloud_match.py  # 点云匹配 + 输出偏移量

# ===== Step 3: 将偏移量写入机械臂 =====
# 在 KUKA 示教器上手动输入基坐标系偏移量
# 或(产品化后)通过 TCP/PROFINET 自动通讯

十二、总结与展望 🌟

12.1 核心贡献

贡献 说明
🎯 低成本方案 消费级硬件实现工业级引导效果,为中小企业"机器换人"提供可行路径
🔧 算法创新 70% 角点筛选标定 + 4 顶点手眼标定 + FPFP+RANSAC+ICP 三级联调
⚡ 精妙优化 质心坐标系变换策略,消除旋转误差放大效应
📐 完整闭环 从相机标定 → 手眼标定 → 点云匹配 → 轨迹引导,端到端实现
🔓 跨平台 基于 OpenNI2 + Open3D,支持 Armbian / Ubuntu / Android / Windows

12.2 未来方向

方向 目标
📡 实时通讯 实现开发板与机械臂的自动 TCP/PROFINET 通讯
⚡ GPU 加速 利用 Zora P1 的 GPU 加速点云处理
🎨 更多引导模式 零件抓取、零件装配、无序分拣
📱 移动端部署 Android 版本,实现手持式视觉引导
🧠 深度学习融合 用神经网络替代传统特征匹配,提升鲁棒性

🌟 写在最后: 这个项目最打动人的地方,不在于用了多高大上的硬件,而在于 用极有限的资源,通过精巧的算法设计,解决了实际的工业问题。从自制标定板到 4 顶点手眼标定,从 FPFH 特征匹配到质心坐标系优化 —— 每一个环节都体现了作者扎实的工程能力和算法功底。如果你正在寻找一个低成本、可落地的 3D 视觉引导方案,这套系统绝对值得深入研究!🏆


相关资源:

  • 📖 相机标定算法: Zhang, Z. "A Flexible New Technique for Camera Calibration", PAMI 2000
  • 📖 Umeyama 算法: "Least-squares estimation of transformation parameters between point patterns", PAMI 1991
  • 📖 FPFH 算法: "Fast Point Feature Histograms (FPFH) for 3D Registration", ICRA 2009
  • 📖 RANSAC 算法: "Random Sample Consensus", ACM 1981
  • 📖 ICP 算法: "A Method for Registration of 3D Shapes", PAMI 1992

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注