ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SCARA机械臂运动学建模与多模式轨迹规划仿真实战

SCARA机械臂运动学建模与多模式轨迹规划仿真实战 简介机器人运动学是机械臂控制与轨迹规划的理论基石正逆运动学求解决定了末端执行器能否精准到达目标位姿。SCARA机器人由于结构解耦、逆解存在解析式是理解运动学建模与关节空间/笛卡尔空间规划的理想对象。借助MATLAB机器人工具箱完成DH参数建模、正逆运动学验证再结合CoppeliaSim构建可视化仿真环境能够将算法与虚拟样机联动提前发现坐标系对齐、多解选择、轨迹平滑等问题。该技术路线覆盖三次多项式插值、LSPB抛物线过渡线性插值以及笛卡尔空间直线插补等典型方法广泛适用于工业机器人方案预演、点胶与装配路径规划、教学科研和离线调试。这套实现以SCARA为切入点完整演示从运动学建模到多模式轨迹规划、再到联合仿真的闭环流程为机器人控制开发提供了可复用的实践参考。 做机器人项目这几年SCARA算是我接触最多的机械臂结构之一。这类臂在3C电子装配、贴片、点胶和搬运场景里出镜率极高核心优势就是结构刚性好、末端刚度大、上下料速度快。这次分享的项目是我把一套完整的SCARA机械臂运动学建模与多模式轨迹规划算法在MATLAB机器人工具箱和CoppeliaSim仿真平台上完整串起来的过程。项目覆盖了DH参数建模、正逆运动学求解、关节空间三种插值轨迹、笛卡尔空间直线轨迹以及MATLAB与CoppeliaSim联合仿真的可视化验证整个系统是可以直接跑通的。先说清楚这个项目能解决什么问题。很多时候我们做机械臂控制算法在MATLAB里算得好好的一到实物或者仿真环境就各种对不上关节角度符号反了、坐标系对不齐、轨迹点跳变这些都是常见坑。这套系统用MATLAB机器人工具箱完成运动学建模和轨迹规划再通过RemoteAPI把计算好的关节序列送到CoppeliaSim里驱动可视化模型既验证了算法的正确性又把“算法-可视化-仿真”这条链路完整打通了。对正在做机械臂轨迹规划课题的学生、刚入门机器人学想动手验证理论的工程师以及需要做方案预演的研发人员都有直接的参考价值。1. 项目概述与整体方案选型1.1 为什么选择SCARA机械臂SCARASelective Compliance Assembly Robot Arm即选择性顺应装配机械臂它的结构特点是三个旋转关节轴线平行一个移动关节轴线垂直于旋转面。这个构型带来的直接好处是水平方向柔顺、垂直方向刚硬非常适合插拔、装配类动作。和六轴臂相比SCARA的逆运动学求解极其简单因为是平面几何问题为主可以推导出解析解完全不需要迭代逼近这使得轨迹规划和控制都可以做得很实时。选SCARA做这个项目还有个实际原因四自由度的系统在可视化、调试、参数分析上的复杂度刚刚好。六轴臂的逆解可能有多组解、奇异位形也更复杂对初学者不友好SCARA在绝大多数工作空间内是单解或者少量多解能让我们把注意力集中在轨迹规划和仿真联调本身而不是陷在解的筛选里。同时SCARA在工业场景里应用极广做出来的算法直接有工业迁移价值。1.2 技术栈搭配MATLAB工具箱 CoppeliaSimMATLAB这边用的是Peter Corke的Robotics Toolbox这几乎是机器人学教学和科研的事实标准工具箱。它提供了SerialLink、DH参数建模、fkine、ikine、jtraj、trapezoidal等一整套函数能极大缩短运动学和轨迹规划的编码时间。CoppeliaSim以前叫V-REP则是目前非常灵活的机器人仿真平台支持Lua/Python/C/MATLAB等多种远程API场景编辑能力强模型导入方便。选这两个工具组合而不是直接在MATLAB里画图了事原因是纯MATLAB的3D可视化比较简陋关节模型不够直观也不方便观察机械臂在物理空间中的干涉情况。CoppeliaSim提供了物理引擎可以加载URDF或直接用内置模型搭建机械臂并高仿真地展示运动过程。MATLAB负责“大脑”CoppeliaSim负责“身体”两者通过RemoteAPI通信这个架构非常接近真实机器人系统的“上位机下位机”结构做完这套仿真再去做实物控制思路是完全连贯的。1.3 系统整体工作流程完整的工作流程是先在MATLAB里用DH参数定义SCARA模型完成正运动学验证再走逆运动学把笛卡尔目标点映射回关节空间。轨迹规划按模式分为关节空间三次多项式、带抛物线过渡的线性插值、纯线性插值以及笛卡尔空间直线插补每种模式生成一组关节角度序列。这些序列通过CoppeliaSim的RemoteAPI逐点发送驱动场景中的SCARA模型完成运动同时把关键位置信息反馈回MATLAB做误差分析。整个系统的数据流是单向清晰、闭环可验证的。项目做到后面我用jtraj和trapezoidal对比了好几种轨迹曲线的关节速度、加速度特性核心目的就是把每种插值方式的适用场景搞清楚。接下来我会把这套系统的每一个环节的细节、代码和参数选择逻辑都拆开讲。2. 运动学建模从DH参数到正逆解2.1 构建SCARA的DH参数表SCARA运动学建模首先需要确定DH参数。我用的是标准DHDenavit-Hartenberg表示法每个连杆用四个参数描述连杆长度a、连杆扭角alpha、关节距离d、关节角theta。对于SCARA的四自由度典型配置DH参数表长这样关节a (mm)alpha (rad)d (mm)theta偏移1L12000d115002L2180000300d3可变量0400d4800这里L1和L2是大臂和小臂长度d3是升降关节的行程d4是末端工具到第四关节的距离。alpha全部为0是因为SCARA所有旋转轴平行这个特性使得正运动学的旋转矩阵只涉及平面旋转计算非常简单。在MATLAB工具箱里定义模型只需一行核心调用% 定义SCARA机器人模型 % theta d a alpha L1 Link([0 150 200 0], standard); L2 Link([0 0 180 0], standard); L3 Link([0 0 0 -pi/2], standard); % 移动关节 L4 Link([0 80 0 0], standard); % 注意SCARA的第三关节是移动关节需要特殊处理 L3.jointtype P; scara SerialLink([L1 L2 L3 L4], name, SCARA);这里有一个容易忽略的点第三关节是移动关节必须在Link对象里显式指定jointtype P否则工具箱默认当作旋转关节处理模型就完全不对了。alpha-pi/2这个参数表示第三关节的轴线方向相对前两关节旋转了90度这是SCARA构型的关键几何特征。2.2 正运动学实现和验证正运动学的任务是在已知四个关节变量的情况下求出末端执行器的位姿矩阵。SCARA的正运动学可以手动推导也可以直接用工具箱的fkine函数自动算% 设定一组关节角度示例 q [0.5 -0.3 0.02 0.8]; T scara.fkine(q); % 输出末端位置 position T.t; % 获取XYZ位置 rotation T.R; % 获取旋转矩阵 disp(position);实际项目中我会先手动推导一遍再和工具箱结果对比确保理解到位。SCARA的末端位置可以写成p_x cos(q1)*L1 cos(q1q2)*L2 p_y sin(q1)*L1 sin(q1q2)*L2 p_z d1 - q3 - d4这个推导能直观看出SCARA的XY平面运动完全由前两关节决定Z轴运动由第三关节决定末端旋转由q1q2q4共同决定。这种解耦特性让后面的逆运动学极其简单。2.3 逆运动学解析法和数值法的选择SCARA的逆运动学有解析解。前两个关节角可以通过几何法求% 解析法逆解前两个关节角 x target_position(1); y target_position(2); z target_position(3); phi target_rpy(3); % 末端需要达到的绕Z轴角度 r sqrt(x^2 y^2); cos_q2 (r^2 - L1^2 - L2^2) / (2*L1*L2); q2 acos(cos_q2); % 注意有正负两种解 q1 atan2(y, x) - atan2(L2*sin(q2), L1 L2*cos(q2)); q3 d1 - d4 - z; q4 phi - q1 - q2;这里有个细节q2取正或取负对应了“肘部在上”和“肘部在下”两种构型。SCARA虽然是在平面内运动这个二解性问题依然存在实际控制中需要根据起始位置和目标位置的选择最接近的一组解避免关节角度跳变。我更倾向于用解析式直接算而不是调工具箱的ikine数值解原因是数值解在SCARA这种平面机构上偶尔会收敛到奇异附近而且多解选择逻辑不如自己写的清晰。当然在代码里我也保留了ikine作为交叉验证的手段两边结果一致时才能确认解算正确。3. 关节空间轨迹规划三种插值方式对比3.1 三次多项式插值及其边界条件关节空间轨迹规划的核心是给定起始关节角度和终止关节角度生成一条平滑的q(t)曲线并且要让速度、加速度可控。三次多项式插值是入门必备表达式是q(t) a0 a1t a2t^2 a3*t^3边界条件四个起始角度q0、终止角度qf、起始速度v0、终止速度vf正好解出四个系数。当起止速度都为零时a0 q0 a1 0 a2 3*(qf - q0)/T^2 a3 -2*(qf - q0)/T^3在MATLAB里可以直接用工具箱自带的函数也可以手写矩阵求解验证function q_traj cubic_traj(q0, qf, T, dt) t 0:dt:T; a0 q0; a1 0; a2 3*(qf - q0)/T^2; a3 -2*(qf - q0)/T^3; q_traj a0 a1*t a2*t.^2 a3*t.^3; end三次多项式的特点是位置和速度连续但加速度是线性的起点和终点加速度不为零会带来一定的冲击。这个项目里我把它当作基准轨迹用来评估其他更平滑轨迹的效果。3.2 三次多项式的局限性实测下来三次多项式的最大问题在于加速度曲线在起始瞬间会跳变。比如SCARA大臂从0.2rad运动到1.0rad规划时间1秒起点加速度直接跳到大约2.4rad/s^2这在仿真里看不出大问题但放到实物电机上就是柔性冲击长期运行会加速减速器磨损。正因为这个原因工业机器人厂商很少直接用纯三次多项式更常用的是带抛物线过渡的线性插值LSPB也就是梯形速度曲线。LSPB的加速度只在短暂过渡段内保持恒定中间段匀速曲线光滑程度远好于纯三次多项式。3.3 LSPB抛物线过渡线性插值实现LSPB的规划思路是把轨迹分成三段加速段、匀速段、减速段。加速度在过渡段内恒定位置轨迹在过渡段是抛物线在中间段是直线。关键参数是加速度a的选择它决定了过渡段的时长。给定起始角度q0、终止角度qf、总时间T、加速度a过渡时间tb可以求解function [q, qd, qdd] lspb_traj(q0, qf, T, dt, accel) % accel 是选定的加速度值 t 0:dt:T; tb T/2 - sqrt(T^2 * accel^2 / 4 - accel * (qf - q0)) / accel; % 实际上工具箱内部会重新计算合理的tb % 这里直接调用工具箱更稳定 [q, qd, qdd] trapezoidal(q0, qf, T, dt, accel); end选加速度的约束是必须满足a 4*abs(qf-q0)/T^2否则没有足够时间来加减速。我通常取这个最小值的1.5到2倍这样过渡段约占总时间的25%~35%速度曲线看起来是一个完整梯形运动效率和平滑性都比较均衡。MATLAB的trapezoidal函数自带加速度参数调整逻辑但我提醒大家注意工具箱默认会生成一个对称的梯形速度曲线如果你传入的加速度过小工具箱会自动增大加速度来满足时间约束。这会跟你预期的不一致所以用之前先打印一下实际规划出的加速度值确认是不是自己想要的。3.4 纯线性插值为什么需要额外处理纯线性插值就是v(t) (qf-q0)/T速度恒定位置是直线。这个最简单但起点和终点处速度不连续从零突然跳到一个非零值再突然归零对机构来说就是无限大加速度冲击。所以实际工程里哪怕是看起来简单的点对点运动也几乎不会用纯线性插值直接驱动关节。我之所以在项目里保留纯线性插值这个模式是为了在可视化对比中展示不同轨迹规划算法的优劣——让曲线并排画出来速度曲线跳变、加速度无穷大等特征一眼就能看出来。如果确实需要在“快”和“平滑”之间折中一般做法是给线性段两端加抛物线过渡这本质上又回到了LSPB。所以大家记住一个结论线性插值是理论起点LSPB是工程基线三次多项式是教材基准更高阶的规划如五次多项式、S型速度曲线是在这些基础上演化出来的。4. 笛卡尔空间轨迹规划与联合仿真可视化4.1 笛卡尔空间直线轨迹规划关节空间轨迹解决的是“从角度A到角度B怎么走”而笛卡尔空间轨迹解决的是“末端要从空间点A走到空间点B并且走一条直线”。后者更贴近实际作业需求比如点胶轨迹就要求末端直线移动。笛卡尔空间的直线规划分三步先在起始位姿和目标位姿之间线性插值得到一系列中间位姿然后用逆运动学把每个中间位姿转换回关节角度最后把关节角度序列发给仿真器执行。核心代码逻辑如下% T_start 和 T_end 是起始和目标位姿矩阵 % steps 是插值步数 step (0:steps) / steps; T_interp zeros(4, 4, steps1); q_series zeros(steps1, 4); for i 1:steps1 T_interp(:,:,i) transl(... T_start.t step(i)*(T_end.t-T_start.t)) * ... interpRotation(T_start.R, T_end.R, step(i)); q_series(i,:) scara.ikine(T_interp(:,:,i), q0, q_series(max(i-1,1),:)); end位置插值用线性姿态插值需要特别注意。欧拉角直接线性插值会导致姿态路径不走最短路径更好的做法是用单位四元数做球面线性插值slerp。Robotics Toolbox里的trinterp函数会自动处理这个所以在没有特殊要求时直接用它就对了。4.2 笛卡尔空间规划的难点与验证笛卡尔直线规划最大的坑在于中间插值点可能落到机器人工作空间之外或者在路径上遇到奇异位形。SCARA的工作空间是一个环形区域如果目标直线超出这个环逆解计算出来的关节角度会包含虚数或者NaN。我的验证方法是对每个插值点计算正运动学再用正运动学结果和期望位姿做误差对比。一旦发现误差超过1e-6毫米级别就说明逆解出了问题。另外还要检查关节角度序列是否连续——正常情况下相邻两帧的角度差应该是平滑的小量如果出现跳变说明中间有一个点掉进了奇异位形。笛卡尔直线规划的另一个实用技巧是把终点稍微留一段减速距离。比如点胶应用末端快到位时如果还保持高速直线运动到达终点瞬间会产生过冲这时可以在最后10%的路径上做一个速度渐减能让整体运动质量提升很多。4.3 MATLAB内部三维可视化在接入CoppeliaSim之前我习惯先用MATLAB的绘图接口快速验证轨迹是否正确。SerialLink类的plot函数可以加载轨迹并生成三维动画figure; scara.plot(q_series, trail, r-, movie, scara_traj.gif);这里’trail’参数会在末端画出一条红色轨迹线方便直观确认对不对。如果轨迹是一段直线笛卡尔空间红色轨迹线必须是直的如果关节空间轨迹做点对点运动末端轨迹通常是一条弧线。从实际经验来看这个“MATLAB内预览”一步非常关键。它能在5秒内帮你发现逆解的问题比直接跑去CoppeliaSim联调快得多。我每改一个轨迹参数都是先在MATLAB里跑一遍plot确认无误后再开联合仿真。4.4 CoppeliaSim环境搭建与联合仿真CoppeliaSim那边我是从零搭建的SCARA模型。最简洁的方案是用CoppeliaSim自带的“拾取并旋转”工具摆放几个圆柱体和立方体手动构造出基座、大臂、小臂、升降轴和末端工具然后用内置的Joint对象作为关节连接。搭建时注意每个Joint的旋转轴方向必须和DH参数定义一致。联合仿真的通信用的是CoppeliaSim的RemoteAPIMATLAB端要加载remApi。连接的基本代码框架% 初始化连接 sim remApi(remoteApi); sim.simxFinish(-1); clientID sim.simxStart(127.0.0.1, 19999, true, true, 5000, 5); % 获取关节句柄 [~, joint1] sim.simxGetObjectHandle(clientID, joint1, sim.simx_opmode_blocking); % 发送关节角度 sim.simxSetJointTargetPosition(clientID, joint1, q_series(i,1), sim.simx_opmode_oneshot);通信方式这里我踩过一个坑simxSetJointTargetPosition设置为oneshot模式时每次只发一次目标位置如果你循环发送太频繁可能触发通信积压。实际调试发现更稳定的做法是增加一个opmode为simx_opmode_streaming的初始化然后每一帧用simx_opmode_buffer模式发送。另外CoppeliaSim默认仿真步长是50ms如果你轨迹插值的步长比这个更细那么实际执行速度会比预期的慢需要把两个时间基准对齐。通常我的做法是规划轨迹时设置dt0.05s让插值步长和仿真器步长一致这样执行完整个轨迹的时间就是准的。这个细节看起来很小却直接影响联合仿真的视觉效果和数据分析的准确性。5. 问题排查与踩坑实录5.1 DH参数正负号和坐标系对应关系做运动学建模时最容易出的问题就是DH参数正负号出错尤其是alpha角。SCARA的第三关节移动轴方向在DH表格里是-pi/2但你在CoppeliaSim里搭建模型时如果轴方向朝上这里就要反过来。我排查了一下午才定位到这个问题MATLAB里运动学完全正确但CoppeliaSim模型就是乱动检查发现是模型里的Joint朝向和DH里的定义差了180度。排查手段很简单给定一组固定的关节角度在MATLAB里用fkine得到末端位姿同时用CoppeliaSim里物体的位置和朝向信息做对比。如果两组数据对不上优先检查每个Joint的旋转轴方向、正方向以及原点位置是否与DH表格一一对应。5.2 逆解多解选择引起的关节角度跳变SCARA虽然逆解简单但依然存在正负两种解。如果目标点在工作空间的左侧而从右侧解切换到了左侧解关节1的角度会发生大幅度跳变实际执行时机械臂会突然甩过去非常危险。解决办法是在连续轨迹规划中以上一帧的关节角为基准选择当前帧解集中距离最近的解。我在代码里维护了一个全局变量last_q每次求解之后都要做一次解的选择和比较if abs(q_solution1(1) - last_q(1)) abs(q_solution2(1) - last_q(1)) q_current q_solution1; else q_current q_solution2; end对连续轨迹来说这个策略百分之百能消除跳变。对于点对点运动我则会在规划之前先判断起点和终点的工作空间区域确保选择的构型在同一个分支上。5.3 MATLAB与CoppeliaSim通信数据不同步联合仿真经常遇到的怪问题是MATLAB里明明计算的是平滑曲线CoppeliaSim里关节运动却一顿一顿的。原因基本都在通信模式和仿真步长上。CoppeliaSim的默认仿真步长是50ms也就是每秒20帧如果MATLAB端每20ms发一个目标角度数据帧就会在这个50ms的周期里积压导致运动不均匀。解决方案有两种。第一种是把CoppeliaSim的仿真步长改为10ms或更小通过菜单栏的“Simulation-Simulation Settings”调整。第二种是控制MATLAB端发送频率与步长对齐比如每50ms发送一个目标值。我最终选的是50ms对齐方案因为不改变仿真器的物理精度。还有一个细节发送关节目标位置前先调用一次simxGetPingTime确保连接稳定否则长时间运行后偶发超时。实测下来这个设置能显著降低通信断连的概率。5.4 轨迹光滑度与加速度参数调优心得我调试轨迹规划最花时间的环节是LSPB的加速度参数。如果加速度设置太小tb会逼近T/2中间匀速段几乎消失轨迹退化成一段“伪梯形”运动效率反而降低如果加速度设置太大过渡段非常短速度曲线虽然仍是梯形但在拐角处仍然有明显的加加速度冲击。我的调参经验是先计算出加速度的理论下限a_min 4*|qf-q0|/T^2然后从1.5倍a_min开始试。在MATLAB里把速度曲线画出来观察过渡段占整个时间的比例如果小于20%就减小加速度如果大于40%就增大加速度。最终我对于SCARA的1秒规划时间、0.8rad关节行程选择加速度在3~5 rad/s^2这个区间效果比较均衡速度曲线看起来是一个饱满但不失平滑的梯形。5.5 项目执行效果和经验总结整个项目跑通后我在同一组始末关节角度下分别用三次多项式、LSPB和线性插值生成轨迹再送到CoppeliaSim执行记录末端轨迹。对比数据很明显三次多项式的末端轨迹是一条圆滑曲线LSPB的末端轨迹规整线性插值则在起止点有明显的抖动。这些可视化对比结论比我当时在书本上看一百遍公式印象都深刻。我印象最深的一个细节是用LSPB执行点对点任务末端轨迹是曲线而用笛卡尔直线规划末端轨迹严格走直线但代价是每个插值点都要做逆解算力开销大得多。所以实际应用中点对点运动基本用关节空间规划连续路径作业点胶、焊接、切割才用笛卡尔空间规划千万不要拿关节空间规划去做直线路径也不要拿笛卡尔规划去做无谓的点对点运动这个选型原则是我做过几个项目后最想强调的一点。这个项目收尾的时候我趁热打铁做了个小扩展把轨迹规划生成的关节角度数据保存成CSV直接用来驱动实际控制器的离线回放。你如果想继续深化可以在这个基础上加入动力学计算、基于力矩的前馈控制或者把轨迹规划算法换成五次多项式、S型速度曲线都是顺理成章的下一步。本文还有配套的精品资源点击获取
返回列表