第四节:机械臂传感器与标定

各位同学,今天我们来聊聊机械臂上的那些传感器,以及怎么把它们“对齐”。

说实话,做移动平台和机械臂联合建图,最头疼的往往不是算法本身,而是传感器数据到底准不准。我见过太多项目,算法跑得飞起,结果一上真机就崩——十有八九是标定没做好。

4.1 关节角度编码器

先说说最基础的。每个关节里都有个编码器,它告诉你关节转了多少度。听起来简单吧?但这里坑不少。

编码器类型:

  • 式编码器:一上电就知道当前位置。我习惯用这种,省心。
  • 增量式编码器:需要找零位。每次开机都得回零,麻烦。

精度问题:

编码器本身精度通常很高,但别忘了传动机构。减速器、皮带、齿轮——这些都会引入误差。我在项目中遇到过,编码器读数转了10度,实际关节只动了9.8度。嗯,0.2度的误差,在末端可能就是几毫米的偏差。

关键点:编码器读数 ≠ 真实关节角度。一定要做传动误差补偿。

数据接口:

常见的接口有SSI、BiSS、EnDat。我个人推荐BiSS,速度快,抗干扰好。但如果你用ROS,很多驱动只支持SSI,那就得加个转换板。

// 伪代码:读取编码器数据
float read_joint_angle(int joint_id) {
    uint32_t raw = read_encoder_raw(joint_id);
    float angle = raw * ENCODER_RESOLUTION;  // 分辨率转换
    angle += transmission_compensation(angle); // 传动误差补偿
    return angle;
}

小技巧:编码器数据最好用硬件滤波,别在软件里做太多平滑。延迟大了,控制就完了。

4.2 力矩传感器

力矩传感器,说白了就是测关节用了多大力。这东西在协作机器人上很常见,但建图时也有用。

为什么建图需要力矩?

你想想看,机械臂在移动平台上,平台一动,机械臂的关节就会受到惯性力。如果不知道这个力,你很难区分是平台运动导致的,还是机械臂自己运动导致的。

力矩传感器类型:

  • 关节力矩传感器:装在关节输出端,直接测力矩。精度高,但贵。
  • 电流估算:通过电机电流估算力矩。便宜,但精度差。我曾经试过,误差能到30%。

注意:力矩传感器有温漂。开机后先预热10分钟,等温度稳定了再标定。我吃过这个亏,冷机标定完,干半小时活数据就飘了。

标定方法:

  1. 挂已知重量的砝码,记录传感器读数
  2. 做线性拟合,得到转换系数
  3. 考虑重力补偿——机械臂姿态不同,重力分量也不同
// 力矩传感器标定示例
// 挂1kg砝码,记录不同姿态下的读数
struct CalibData {
    float pitch, roll;  // 关节姿态
    float raw_torque;   // 原始读数
};

// 拟合得到:真实力矩 = a * raw + b
float calibrate_torque(float raw, float pitch, float roll) {
    float gravity_comp = compute_gravity_comp(pitch, roll);
    return a * raw + b + gravity_comp;
}

4.3 手眼标定

终于到重点了。手眼标定,就是搞清楚相机和机械臂之间的坐标变换关系。

有两种情况:

  • Eye-in-Hand:相机装在机械臂末端。相机跟着机械臂动。
  • Eye-to-Hand:相机固定安装,看着机械臂工作。

我个人更常用Eye-in-Hand。为什么?因为移动平台本身就在动,相机跟着机械臂走,视野更灵活。但标定也更麻烦。

4.3.1 Eye-in-Hand 标定

核心思想:让机械臂带着相机,从不同角度拍同一个标定板。然后解方程:

AX = XB

这个方程看着简单,但解起来挺绕。A是机械臂两次运动的变换,B是相机两次观测的变换,X就是我们要找的手眼变换矩阵。

我曾经用OpenCV的calibrateHandEye函数,但发现结果总是不稳定。后来自己写了个优化器,用Levenberg-Marquardt迭代求解,效果好多了。

// 使用OpenCV进行手眼标定
cv::Mat R_cam2gripper, t_cam2gripper;
cv::calibrateHandEye(
    R_gripper2base,   // 机械臂末端到基座的旋转
    t_gripper2base,   // 机械臂末端到基座的平移
    R_target2cam,     // 标定板到相机的旋转
    t_target2cam,     // 标定板到相机的平移
    R_cam2gripper,    // 输出:相机到末端的旋转
    t_cam2gripper,    // 输出:相机到末端的平移
    cv::CALIB_HAND_EYE_TSAI
);

避坑指南:标定时机械臂的运动幅度要大。只做小范围运动,解算出来的矩阵误差会很大。我一般让机械臂走一个“8”字形轨迹,覆盖整个工作空间。

4.3.2 Eye-to-Hand 标定

这个相对简单。相机固定,机械臂带着标定板动。方程变成:

AX = ZB

多了一个Z,是标定板到机械臂基座的变换。这个Z其实可以通过机械臂正运动学算出来。

嗯,这里要注意:Eye-to-Hand标定对相机安装位置有要求。相机最好能完整看到机械臂的工作空间。我见过有人把相机装在天花板上,结果机械臂一抬起来就出视野了。

4.3.3 标定精度验证

标定完怎么知道准不准?我的做法是:

  1. 让机械臂末端碰一个固定点
  2. 用相机观测这个点
  3. 计算两者之间的误差

如果误差在1-2毫米以内,就算合格。超过5毫米,重新标定吧。

经验之谈:标定板别用太小的。A4纸大小的棋盘格就挺好。太小了,相机远一点就识别不到角点了。

4.4 本章知识体系

下面这张图,是我自己整理的传感器与标定知识结构。你看一眼,心里就有谱了。

机械臂传感器与标定知识体系 关节角度编码器 • 式 vs 增量式 • 传动误差补偿 • 接口:SSI/BiSS/EnDat • 硬件滤波 • 分辨率与精度 力矩传感器 • 关节力矩传感器 • 电流估算法 • 温漂与预热 • 重力补偿 • 砝码标定法 手眼标定 • Eye-in-Hand • Eye-to-Hand • AX=XB 求解 • OpenCV实现 • 精度验证 标定质量决定建图精度 —— 别在这步省时间

你看,这三个模块其实是环环相扣的。编码器给角度,力矩传感器给力,手眼标定把相机和机械臂对齐。少了任何一个,联合建图都做不好。

总结一句话:传感器是机械臂的“眼睛”和“触觉”,标定就是给它们配眼镜。度数不对,看啥都是模糊的。

好了,这一节就到这里。内容不少,但都是干货。你回去把标定流程走一遍,遇到问题再来问我。