干机器人这行久了你会发现,SCARA是那种“看着简单,用起来真香”的机型。四自由度SCARA机器人,名字听着专业,说白了就是RRPR结构:前两个旋转关节控制末端在平面里的位置,第三个移动关节管上下插拔,末端再带一个旋转轴摆正工具姿态。电子产品装配、螺丝锁付、贴标、小件搬运,哪儿都有它的身影。而要做运动学、动力学分析,MATLAB建模与仿真基本是绕不开的一站:既能快速验证算法,又能在做实物之前把轨迹规划和力矩校核跑明白。这篇文章把我从零开始搭SCARA模型、写运动学正逆解、推动力学方程、再到在MATLAB里跑通完整仿真的过程全部整理出来,参数、代码思路、踩坑点都在里面。适合正在做课程设计、毕业设计,或者刚接触机器人仿真的工程师参考。
1. 项目整体思路与模型参数准备
1.1 SCARA机器人的结构特点与自由度分配
SCARA的全称是Selective Compliance Assembly Robot Arm,中文常叫“选择顺应性装配机器人手臂”。它的结构特点是水平方向刚性足、垂直方向有柔性,这是它名字里“选择性顺应”的来源。四自由度具体分解为:关节1和关节2是绕着竖直轴旋转的转动副,负责把末端工具送到桌面上任意一个点;关节3是沿着竖直方向移动的移动副,负责升降动作,比如把螺丝刀压下去;关节4是末端绕竖直轴旋转的转动副,负责调整工具的姿态角。所以SCARA能做的任务,基本就是“平面内定位 + 垂直方向插拔 + 末端旋转摆姿态”,对装配类场景特别对口。
我刚接触这类机器人时也觉得四自由度比较少,后来在产线上看了几台实际设备才明白:自由度少恰恰是优点。结构上比六轴简单,刚性好,重复定位精度更容易做高,而且控制器不用处理复杂的姿态解算,调试快很多。工程上做方案选型,不是自由度越多越好,而是够用就好。
1.2 建模方案选型:为什么用D-H法和拉格朗日方程
做SCARA运动学建模,最标准的方法是Denavit-Hartenberg参数法,也就是D-H法。D-H法的思路是在每个关节处固连一个坐标系,然后用四个参数描述相邻坐标系之间的变换关系,把这些变换矩阵按顺序乘起来,就得到末端相对基坐标系的位姿。相比直接在笛卡尔空间里硬推几何关系,D-H法最大的优势是统一规范,而且可以直接套用现成的MATLAB工具箱,做完SCARA以后换六轴、换直角坐标机器人,思路完全一致。
动力学建模我选的是拉格朗日方程法。拉格朗日法从能量角度出发,写出系统的动能和势能,再对广义坐标求导得到动力学方程。它和牛顿欧拉法比,推导过程更系统,中间每一步的能量项都有明确的物理意义,适合边推边核对。牛顿欧拉法是纯递推计算,编程效率高,但作为建模学习,我建议先把拉格朗日法跑通,理解M矩阵、科氏力项、重力项是怎么来的,后面再看牛顿欧拉法会轻松很多。
1.3 仿真参数设置
本文的整套建模思路不依赖具体型号,但为了后面数值计算不悬空,我参考常见的桌面型SCARA机器人给出一组参数。底座高度d1取0.3m;大臂长度a1取0.4m,质量m1取8kg,质心在连杆1坐标系下约(0.2m, 0, 0);小臂长度a2取0.35m,质量m2取5kg,质心约(0.175m, 0, 0);垂直移动关节的行程d3取0~0.3m,负载部分质量m3加末端工具质量m4合计3kg;末端绕竖直轴的转动惯量Izz4取0.02kg·m²。需要说明的是,这些参数是从工程实践中选出来的合理量级,真做企业项目时必须以CAD模型或厂家手册为准,但用来搭建模框架和仿真流程完全够用。
这里有一个必须强调的点:动力学仿真对质量、质心、惯量这些参数非常敏感。很多人在运动学仿真跑得好好的,一到动力学就算飞了,原因往往是随手填了参数,没有注意到质心位置或者转动惯量缺了一项。我习惯先列一张参数表,名字、符号、数值、单位全部写清楚,然后再往下写代码。
2. 运动学建模:从D-H表到工作空间验证
2.1 正运动学推导与齐次变换矩阵
根据上一节的坐标系约定,SCARA的标准D-H参数表可以写成下面这样:
- 关节1:θ1,d1=0.3,a1=0.4,α1=0
- 关节2:θ2,d2=0,a2=0.35,α2=0
- 关节3:θ3=0,d3=变量,a3=0,α3=0
- 关节4:θ4,d4=0.1,a4=0,α4=0
所以关节旋转变量是q1、q2、q4,移动变量是d3。相邻坐标系的齐次变换矩阵为: T01 = RotZ(q1) * TransZ(d1) * TransX(a1), T12 = RotZ(q2) * TransX(a2), T23 = TransZ(d3), T34 = RotZ(q4) * TransZ(d4)。
把四个矩阵乘起来得到末端位姿。从结构上就能提前判断几个重要结果:末端在水平面的x、y坐标只与q1、q2和杆长a1、a2有关,表达式为x = a1 * cos(q1) + a2 * cos(q1 + q2),y = a1 * sin(q1) + a2 * sin(q1 + q2)。末端高度z由d1、d3、d4决定,而末端姿态角是q1 + q2 + q4。这个形式很简单,但推导过程中建议自己用符号运算展开一次,然后代入特殊角度检查:比如q1=q2=0时,末端应该落在坐标(a1+a2, 0)处,如果计算结果不是这样,说明D-H表方向有问题。
2.2 逆运动学解析解推导与多解处理
逆运动学是给末端位姿求关节变量。SCARA之所以讨喜,很大程度上是因为它的逆解有封闭解析解,不需要像六轴那样做数值迭代。从平面几何关系出发,已知末端x和y,可以先求q2。对x、y的表达式分别平方求和就可以得到cos(q2) = (x² + y² - a1² - a2²) / (2 * a1 * a2)。为了防止浮点误差导致cos值略超出[-1,1],代码里必须做限幅处理。然后q2 = atan2(±sqrt(1 - cos_q2²), cos_q2),这里正负号对应两种臂型,也就是常说的“肘部在左还是右”。
得到q2以后,q1可以用atan2直接求出:q1 = atan2(y, x) - atan2(a2 * sin(q2), a1 + a2 * cos(q2))。q3由末端高度z反推:d3 = d1 + d4 - z。末端姿态角φ则满足φ = q1 + q2 + q4,所以q4 = φ - q1 - q2。逆解推导到这里,你会发现大部分工作其实是高中数学里的三角形边角关系,加上坐标系方向搞清楚,整条链路就通了。
多解怎么选?工程上常见的做法是先把所有解析解代入关节限位范围过滤一遍,去掉超出物理限位的解,然后在剩余解里选择离当前关节位置最近的一组。对SCARA的平面定位来说,q2的正负号决定了机械臂是“内弯”还是“外翻”,有些工况会明确要求只能走某一种臂型,选解逻辑要提前写死。
2.3 工作空间分析与MATLAB可视化
工作空间分析是建模后第一个应该做的验证。用蒙特卡洛法非常简单:在关节限位内随机采样几万组q1、q2,代入正运动学公式把末端x、y画出来。SCARA的平面工作空间是内半径取决于|a1 - a2|、外半径取决于a1 + a2的圆环,再叠加上关节限位的扇形约束。
MATLAB代码大致长这样:
N = 30000; q1 = rand(N,1)*(q1lim(2)-q1lim(1))+q1lim(1); q2 = rand(N,1)*(q2lim(2)-q2lim(1))+q2lim(1); x = a1*cos(q1) + a2*cos(q1+q2); y = a1*sin(q1) + a2*sin(q1+q2); plot(x,y,'.') axis equal这一段代码虽然短,但作用很大。很多人在后面做轨迹规划时,目标点随便一拍就超出了工作空间,导致逆解出现NaN,根源就是没先做工作空间校核。我建议把工作空间散点图保存下来,作为后续所有仿真验证的基础图。
3. 动力学建模:拉格朗日方程到力矩计算
3.1 拉格朗日方程的基本流程
动力学要回答的问题是:让机器人沿着给定的轨迹运动,每个关节需要输出多大的力矩。拉格朗日法的起点是拉格朗日函数L = T - V,其中T是系统总动能,V是系统总势能。动力学方程写作τ = d/dt(∂L/∂q̇) - ∂L/∂q,展开整理后可以得到机器人动力学方程的标准形式:τ = M(q)q̈ + C(q, q̇)q̇ + g(q),M是惯性矩阵,C是科氏力和离心力相关项,g是重力项。
对SCARA来说,这个方程有个极大的简化:因为前两个旋转轴和末端旋转轴都沿着竖直方向,重力方向与这些轴垂直,所以重力势能对q1、q2、q4求偏导都是零,重力项只剩下第三个移动关节上的分量,也就是要支撑小臂、移动轴、末端工具和负载的总重量。这个结论在实际项目中很重要,SCARA选电机时,J1、J2主要考虑惯量匹配,J3则必须额外核算垂直方向的推力。
3.2 惯性矩阵与科氏项的计算
惯性矩阵M(q)需要把四个连杆的动能全部写出来再整理系数。以我用的参数为例,把连杆1、连杆2、移动关节加末端工具看成质点系,并把每个连杆绕自身质心的旋转动能计入,整理后M矩阵的主要非零项大致为:
M11 = Izz1 + Izz2 + m1r1² + m2a1² + m2r2² + m3a1² + ...(其中带d3交叉项的也可以进一步合并);M12 = Izz2 + m2a1r2cos(q2) + ...;M22 = Izz2 + m2r2² + ...;M33 = m3 + m4,这是个常数;M44 = Izz4。写成矩阵后,关节1和关节2的等效惯量会随q2变化,所以实际调试时会发现J1带动大臂小臂的响应特性在不同姿态下不一样,这就是M矩阵随位形变化导致的。
科氏项C(q, q̇)q̇来源于M矩阵对时间的导数。可以用Christoffel符号统一计算,公式是c_k = Σ_{i,j}(1/2)*(∂M_kj/∂q_i + ∂M_ki/∂q_j - ∂M_ij/∂q_k)q̇_iq̇_j。手动展开容易漏项,我习惯先用MATLAB符号工具箱把M矩阵写出来,再用符号求导自动生成C矩阵,然后把符号表达式转成可调用的函数,效率和准确率都高很多。
3.3 一个具体的力矩计算实例
以J2为例,假设机械臂在做水平面内的圆弧插补,某一瞬时q1=0.2rad,q2=0.6rad,q̇1=0.5rad/s,q̇2=0.3rad/s,q̈1=0.8rad/s²,q̈2=0.6rad/s²。为了估算J2电机需要的峰值力矩,需要把M矩阵第二行、科氏项第二项都算出来。简化估算时,可以把J2的等效惯量写为I2_eff = Izz2 + m2r2² + m3a2² + ...,这一项往往比静止惯量要大不少。计算出来的力矩如果超过电机额定力矩,就要考虑加大减速比或改轨迹。
动力学仿真最大的误区是只看最后输出的力矩曲线,不看数值合理性。我拿到一条力矩曲线,第一步会先检查零位附近的力矩是否符合常识,再检查加减速段力矩是否随加速度按比例变化。如果加速段力矩方向和加速度方向相反,大概率是某个符号填反了。
3.4 动力学模型如何用于控制
动力学模型不只是用来算力矩,它更大的价值是做基于模型的控制。最典型的应用是计算力矩控制:τ = M(q)(q̈_des + Kpe + Kd*ė) + C(q, q̇)*q̇ + g(q),其中e是位置误差,ė是速度误差。这样做的好处是系统非线性和耦合项全部被前馈补偿掉,剩余部分近似解耦的线性系统,控制器参数好整。
做这类控制仿真时,动力学模型准确性会直接影响控制性能。我试过在Simulink里把模型参数故意加20%误差,结果位置跟踪误差明显变大,这让我们在项目中对参数辨识重视了很多。对仿真阶段来说,先用名义参数跑通算法,再逐步加入参数不确定性和干扰,是比较稳妥的推进方式。
4. MATLAB仿真实现:从工具箱到完整闭环
4.1 用Robotics Toolbox快速搭建模型
MATLAB的Robotics System Toolbox和Peter Corke的Robotics Toolbox都能用来建SCARA模型。我这里以Robotics Toolbox为例,它用起来直观,适合教学和快速验证。用SerialLink建立模型:
L1 = Link([0 0.3 0.4 0], 'standard'); % theta d a alpha L2 = Link([0 0 0.35 0], 'standard'); L3 = Link([0 0 0 0], 'standard', 'prismatic'); % 移动关节 L4 = Link([0 0.1 0 0], 'standard'); L3.qlim = [0 0.3]; scara = SerialLink([L1 L2 L3 L4], 'name', 'SCARA');这一段代码有好几个细节值得注意。第一,Link的四个参数顺序是theta、d、a、alpha,写反了坐标变换就乱了;第二,移动关节要显式指定'prismatic',并且它对应的变量会放在q向量的第三位;第三,虽然移动关节的D-H表中theta固定为0,但生成Link对象时第一个参数可以写0,实际关节变量由q提供,别被绕晕。模型建好之后可以用scara.teach()拖动关节角度,实时观察末端的位姿变化,这是检查D-H表是否正确的第一道关口。
如果公司项目更偏向工业级开发,我建议同时看一下官方的rigidBodyTree接口。它和SerialLink的API完全不一样,建树结构再加关节更接近现代机器人软件设计的风格。两者结果应该一致,但不要在同一个工程里混用,否则会把自己绕晕。
4.2 轨迹规划与仿真动画
运动学模型跑通后,下一步是验证轨迹规划。常用方法是从初始关节位形运动到目标位形,用五次多项式保证位置、速度、加速度连续:
t = linspace(0, 2, 200); q0 = [0 0 0.1 0]; qf = [pi/3 -pi/6 0.2 pi/4]; [q, qd, qdd] = jtraj(q0, qf, t); scara.plot(q, 'trail', 'r');这里我踩过一个坑:用jtraj生成轨迹后直接拿最后一帧去做逆解或者动力学计算,中间过程的结果没看。实际上jtraj返回的q、qd、qdd三条曲线都要先画出来检查,确认速度曲线是平滑的、加速度曲线没有突变,再继续往下走。还要检查轨迹上的每个点是否都在关节限位和速度限位以内,SCARA的关节1在高速搬运时角速度很高,经常是限位没超但速度先超了。
4.3 动力学仿真与计算力矩控制
工具箱里用rne函数可以做逆动力学,直接算出给定运动下各关节的驱动力矩:
tau = scara.rne(q, qd, qdd, gravity);注意gravity向量要按工具箱约定设置,通常写成[0 0 -9.81]。很多人动力学符号不对就是栽在重力方向上,结果重力项正负号整个反了。输出力矩曲线后,重点关注两个部位:移动关节J3的力矩是否始终有向上的托举力,以及J1、J2在高速反向时的力矩峰值是否合理。
要搭完整的计算力矩控制仿真,我建议用Simulink:一是从MATLAB Function写动力学模型,二是用PID控制器做外环,三是把机器人本身搭成非线性仿真模块。这样能直接看到带模型前馈和纯PID之间的跟踪误差差异。我实测下来,计算力矩控制在快速轨迹下明显优于纯PID,但前提是模型参数准。
4.4 仿真结果分析与调参方向
仿真结束不能只看几张图就收工,我习惯做三件事。第一,检查工作空间和轨迹的匹配度,看轨迹有没有超出可达范围;第二,检查关节力矩是否超过电机额定值,以及力矩曲线的尖峰出现在什么位置,如果是加减速段顶到上限,就适当延长过渡时间或改用S形速度规划;第三,对比不同控制参数下的跟踪误差曲线,确认稳定性和响应速度的平衡点。
一个实用的调参技巧是先让机器人空载运行,把联合仿真模型里的负载质量设为零,跑通以后再逐步加入负载。这样做的好处是问题和现象能分离:空载都发散,那一定是模型或者控制器写错了;空载稳、加载才发散,那大概率要检查负载参数和重力补偿的分配。
5. 常见问题与排查技巧实录
D-H参数表坐标系定义混乱
SCARA的D-H表写错是八字没一撇的高频问题,症状也很明显:用fkine算出的末端位置和手算对不上,或者teach拖动时连杆方向乱飞。解决的办法是画一遍坐标系草图,一个关节一个关节地核对z轴方向和x轴方向,然后用特殊角度验证。比如把q1和q2设为零,末端必须在x轴正方向a1+a2处。一套D-H表只要有任何一个α或a符号反了,结果就整个错位,所以建立后第一件事就是做正解验证。
角度单位不统一导致结果漂移
MATLAB的sin、cos、atan2全都默认弧度,但项目里工艺工程师给你的参数经常是角度。我在仿真代码里吃过一次亏:q1初始角度写的是45,实际当成了弧度45,差了快3圈,轨迹直接画飞。所以我的习惯是函数入口处统一转弧度,输出显示时统一转角度,并在变量名后缀注明_unit,比如qh_rad、qh_deg。仿真代码短还好排查,一长起来单位问题能坑一下午。
逆解多解选择不当引发抖动
SCARA同一个平面目标点对应两种臂型,如果控制程序在相邻控制周期里切换了臂型,末端位置可能变化不大,但关节速度会瞬间跳变,产生抖动。解决方法是按“当前关节位置最接近”的准则选解,并且在选解后计算一次新的末端位置,确认没有坐标跳变。奇异位形也要留意,当q2接近0度也就是大小臂完全展开时,逆解到q1的分母接近零,数值会变得极不稳定,工程上要设一个奇异阈值,进入奇异区域后改用阻尼最小二乘。
动力学仿真发散或曲线异常尖峰
动力学仿真发散,先查数值求解步长。我用ode45做连续轨迹仿真时遇到过RelTol默认精度不够导致力矩爆炸的情况,把RelTol调到1e-8、MaxStep设小之后问题就消失了。另外要注意M矩阵是否奇异,SCARA虽然构型简单,但在某些极限位形下等效惯量过小,数值上接近奇异,也容易出尖峰。给仿真模型加合理的力矩饱和限幅,一方面更接近真实电机,另一方面也能避免数值无限增长。
6. 从这次建模得到的实操体会
整套走下来,我最大的感受是建模顺序不能乱:先把D-H表和正运动学验证扎实,再做逆解和工作空间分析,最后才碰动力学。运动学错了,动力学推导再漂亮也白搭。第二个体会是符号推导和数值验证要配合用,用MATLAB符号工具箱把M、C、g表达式推出来,再代入具体数值检查正负号,可以有效减少推导错误。最后一点,仿真结果一定要跟物理直觉对照,SCARA在重力方向很特殊,J3一直要有支撑力矩,如果算出来J3力矩为零甚至是负的,那别急着调参数,先回头检查坐标系方向和重力方向。