1. MK2机械臂项目概述
EEZYbotARM MK2是一款开源的三自由度桌面级机械臂,因其结构简单、成本低廉而成为机器人学入门的理想实验平台。这个看起来萌萌的机械臂,实际上包含了机器人学中最核心的运动学、动力学和控制原理。我在实验室花了三个月时间,从零开始完成了它的建模、轨迹规划和控制器设计全流程,期间踩过的坑和收获的经验值得系统梳理。
三自由度机械臂虽然结构简单,但完整实现其运动控制需要跨越四道技术关卡:首先是基于D-H参数法的运动学建模,这是所有后续工作的基础;其次是轨迹规划算法实现,让机械臂能平滑移动;然后是动力学建模,考虑质量、惯性等物理因素;最后是控制器设计,确保系统稳定运行。这个项目最实用的价值在于,它浓缩了工业机器人开发的完整流程,所有方法论都可以扩展应用到更复杂的六轴机械臂上。
2. 机械臂运动学建模
2.1 D-H参数表建立
机械臂运动学的本质是建立关节空间与笛卡尔空间的映射关系。对于MK2这类串联机械臂,Denavit-Hartenberg(D-H)参数法是最常用的建模方法。MK2的三个旋转关节分别对应底座旋转、肩部俯仰和肘部俯仰运动,其D-H参数表如下:
matlab复制% D-H参数表 [alpha a theta d]
L(1) = Link('d', 103.5, 'a', 0, 'alpha', pi/2);
L(2) = Link('d', 0, 'a', 105, 'alpha', 0);
L(3) = Link('d', 0, 'a', 155, 'alpha', 0);
robot = SerialLink(L, 'name', 'MK2');
这里每个Link对象包含四个关键参数:
alpha:连杆扭转角,决定z轴的旋转关系a:连杆长度,沿x轴的距离theta:关节角度(变量)d:连杆偏移,沿z轴的距离
特别要注意的是第一个关节的alpha=pi/2,这是因为底座关节的z轴与第二个关节的z轴呈90度夹角。参数表中的103.5mm、105mm和155mm分别对应机械臂的底座高度、上臂长度和前臂长度,这些物理尺寸需要精确测量。
2.2 正运动学计算
正运动学解决"给定关节角度,求末端位姿"的问题。使用Robotics Toolbox的fkine方法可以轻松计算:
matlab复制T = robot.fkine([pi/6 pi/4 0]); % 输入三个关节角度
disp(T.T) % 输出4x4齐次变换矩阵
齐次变换矩阵T包含了旋转和平移信息,其最后一列的前三个元素就是末端执行器在基坐标系下的(x,y,z)位置。在实际调试时,我习惯用plot方法可视化验证:
matlab复制robot.plot([pi/6 pi/4 0]);
这个可视化功能能快速验证模型是否正确——如果机械臂姿态明显不符合物理结构,说明D-H参数设置有误。
2.3 逆运动学求解
逆运动学是正运动学的逆过程,解决"给定末端位姿,求关节角度"的问题。对于三自由度机械臂,当末端执行器的姿态不重要时(即只关心位置),可以使用简化方法:
matlab复制T = transl(200, 50, 100); % 目标位置
q_sol = robot.ikine(T, 'mask', [1 1 1 0 0 0]);
mask参数[1 1 1 0 0 0]表示只考虑x、y、z三个平移自由度,忽略旋转自由度。逆解计算时需要注意:
- 多解问题:同一位置可能对应多组关节角度,需要通过关节限位筛选合理解
- 奇异点问题:当机械臂完全伸直时,雅可比矩阵秩亏损,会导致数值不稳定
- 无解情况:目标位置超出工作空间时无解
我在实践中发现,对于MK2这类非球形腕结构的机械臂,在肩关节附近容易出现奇异点,解决方案是引入阻尼最小二乘法:
matlab复制q_sol = robot.ikine(T, 'mask', [1 1 1 0 0 0], 'ilimit', 1000, 'tol', 1e-6);
3. 轨迹规划实现
3.1 关节空间轨迹规划
让机械臂平滑运动的关键是轨迹规划。五次多项式插值法能保证位置、速度和加速度的连续性,避免机械冲击:
matlab复制t = linspace(0, 5, 100); % 5秒轨迹
q_start = [0 0 0]; % 起始角度
q_end = [pi/2 pi/4 pi/6]; % 目标角度
[q, qd, qdd] = jtraj(q_start, q_end, t); % 生成轨迹
jtraj函数自动生成时间最优的轨迹,但实际应用中需要注意:
- 关节速度限制:MK2的舵机最大转速约60RPM,需检查qd是否超限
- 加速度突变:虽然理论连续,但实际电机响应可能有滞后
- 轨迹过冲:在起点和终点附近添加停顿可减少振动
3.2 笛卡尔空间轨迹规划
对于需要末端走直线的情况,可以先用ctraj生成笛卡尔空间轨迹,再转换为关节空间:
matlab复制T_start = robot.fkine(q_start);
T_end = robot.fkine(q_end);
Tc = ctraj(T_start, T_end, length(t)); % 笛卡尔轨迹
for i = 1:length(t)
q(i,:) = robot.ikine(Tc(:,:,i), 'mask', [1 1 1 0 0 0]);
end
这种方法虽然能保证末端直线运动,但计算量较大,且可能因奇异点导致中断。我的经验是:对精度要求不高时用关节空间规划,需要精确路径时再用笛卡尔空间规划。
4. 动力学建模与分析
4.1 拉格朗日动力学方程
机械臂动力学描述力矩与运动的关系,对于控制设计至关重要。使用Robotics Toolbox的rne函数可以自动计算所需力矩:
matlab复制tau = robot.rne(q, qd, qdd); % 计算关节力矩
这个函数背后是拉格朗日方程:
$$
\tau = M(q)\ddot{q} + C(q,\dot{q})\dot{q} + G(q)
$$
其中:
- $M(q)$:惯性矩阵
- $C(q,\dot{q})$:科里奥利力和向心力项
- $G(q)$:重力项
实际使用中最大的坑是单位问题:MATLAB默认使用kg和m,而MK2的尺寸是mm级,需要统一单位制:
matlab复制robot.links(1).m = 0.1; % kg
robot.links(1).r = [50 0 0]; % mm
robot.links(1).I = [1000 0 0; 0 1000 0; 0 0 1000]; % kg·mm²
4.2 动力学仿真分析
在Simulink中搭建动力学模型时,需要特别注意:
- 电机模型:加入转矩饱和限制(MK2的SG90舵机最大转矩约1.5kg·cm)
- 摩擦模型:加入库伦和粘性摩擦项,否则仿真结果过于理想
- 采样时间:建议≤1ms,否则数值积分误差明显
通过比较仿真和实际运动,我发现动力学模型中摩擦参数的准确性对预测结果影响很大,需要通过实验反复校准。
5. 控制器设计与实现
5.1 前馈+PD复合控制
单纯PD控制在机械臂动力学系统中表现不佳,前馈补偿能显著提升性能:
matlab复制% 前馈计算
tau_ff = robot.rne(q_desired, qd_desired, qdd_desired);
% PD反馈
tau_pd = Kp*(q_desired - q_actual) + Kd*(qd_desired - qd_actual);
% 总控制量
tau_total = tau_ff + tau_pd;
调参经验:
- 先调前馈增益(80%-100%)
- 再调D参数抑制振荡
- 最后调P参数减小稳态误差
- 各关节独立调试,避免耦合影响
5.2 三种控制器对比
在相同轨迹任务下测试三种控制器:
| 控制器类型 | 最大误差(rad) | 稳态误差(rad) | 抗干扰性 |
|---|---|---|---|
| 纯PD控制 | 0.15 | 0.02 | 差 |
| 前馈控制 | 0.08 | 0.005 | 中 |
| 前馈+PD | 0.05 | 0.001 | 好 |
实测表明,复合控制器的跟踪性能最优,特别是在高速运动时。但前馈控制对模型精度依赖较高,当负载变化时需要在线更新动力学参数。
6. 工程实践中的经验总结
6.1 常见问题排查
-
奇异点问题:当机械臂接近完全伸直状态时,尝试以下方案:
- 限制工作空间避开奇异区域
- 使用阻尼最小二乘逆解算法
- 在轨迹规划中增加中间点
-
轨迹抖动问题:
- 检查加速度是否连续
- 在Simulink中加入加速度限制模块
- 增加轨迹时间或降低最大速度
-
控制发散问题:
- 检查力矩输出是否超过电机上限
- 确认动力学参数单位一致性
- 逐步增大PD增益,避免激进调参
6.2 性能优化技巧
-
实时性优化:
- 预计算逆运动学表
- 使用C-MEX S函数替代MATLAB Function模块
- 减少Simulink模型中的代数环
-
精度提升方法:
- 在末端添加摄像头视觉反馈
- 使用卡尔曼滤波融合多传感器数据
- 定期校准关节零位
-
扩展性设计:
- 模块化代码结构,便于增加新自由度
- 预留ROS接口,方便升级到物理实验
- 设计参数配置文件,避免硬编码
这个项目让我深刻体会到理论到实践的鸿沟——教科书上的公式要变成稳定运行的系统,需要大量的工程调优和经验积累。最实用的建议是:在仿真阶段就尽可能考虑实际物理限制(如电机饱和、摩擦、延迟等),这样转移到实体机械臂时会顺利很多。完整代码和Simulink模型我已经整理成模块化的工具箱,欢迎交流使用心得。