ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FANUC机器人运动学建模与轨迹规划:从DH参数到MATLAB正逆解实践

FANUC机器人运动学建模与轨迹规划:从DH参数到MATLAB正逆解实践 简介面向机器人方向学生与工程师的FANUC机器人仿真与控制资料包涵盖LR-Mate 200iD三维模型、正逆运动学分析及轨迹规划MATLAB代码。模型文件包含sldprt、sldasm、step等格式可在SolidWorks等环境中观察结构与虚拟调试便于进行可达空间分析、运动轨迹预演等MATLAB脚本与配套文档则展示了正解、反解计算及常用轨迹规划方法。共34个文件其中三维模型文件12个sldprt与1个sldasm、1个step另有5个p2m仿真文件、3个docx说明文档、2个m源码、图片与caj论文等压缩包整体约112.81MB。已有997人学习下载。初学者可从中直观理解机器人关节运动与工作空间也可用于运动学算法验证、轨迹优化及课程项目开发。1. FANUC机器人三维模型只是壳正逆解和轨迹规划才是本体FANUC机器人三维模型、正逆运动学分析和轨迹规划这三件事很多人第一反应是找个STEP文件导入MATLAB画个图就算完事。等你真去做一个离线的上下料或涂胶演示会发现三维模型只是外壳真正要面对的是如何从说明书里抠出DH参数表、一个用不好就会发散的逆解迭代器以及一段末端一加速就开始抖的轨迹。这里直接用MATLAB把六轴FANUC类机械臂的标准DH建模、正逆解和轨迹规划串起来每一步都留下可运行的代码和参数表。适合已经有了基本机器人概念、想用MATLAB做运动学验证或者正在被机械臂轨迹规划算法折磨的工程师。2. 从DH参数到FANUC机械臂三维模型先建运动学骨架很多新手在建三维模型时直接画连杆却没有考虑“关节坐标系在哪儿”。这会导致后边的正逆运动学没法算。工业机器人建模的通用做法是先建立DH参数模型把DH参数当作机器人的运动学骨架再让三维线框依附在这些坐标系上。三维模型可以后画但坐标系必须先定。2.1 标准DH参数与关节坐标系的定义工业机器人外观千差万别但从运动学上看两个相邻连杆之间的关系用4个参数描述就够。FANUC六轴机器人同样适用。标准DH参数表里每个关节有4个值theta绕前一个坐标系z轴的旋转角度d沿前一个坐标系z轴的平移距离a沿当前坐标系x轴的平移距离alpha绕当前坐标系x轴的旋转角度。对于旋转关节theta是变量其余三个是常量。下面给出一组示例参数形态接近常见的小型六轴机。注意这组参数不是官方值只用于教学实际项目必须替换成你手头型号的DH表。关节 itheta 初值 (rad)d (m)a (m)alpha (rad)100.3300.075-pi/22-pi/200.30003000.040-pi/2400.3300pi/25000-pi/2600.06000这组数据里轴2的theta初值是-90度目的是让机械臂在零位时前端朝上而不是朝前这是很多FANUC型号的常见处理方式。注意标准DH和Modified DH后置DH的矩阵表达不同网上很多代码混用会导致仿真结果和真机“头尾颠倒”。我一般习惯先把DH表打印在纸上标出每个参数属于前置还是后置再写代码。2.1.1 把DH参数变成矩阵标准DH变换函数标准DH的相邻连杆齐次矩阵可以写成function T dhTransform(theta, d, a, alpha) % 标准DH齐次变换矩阵 % theta, d, a, alpha 均为标量单位分别是 rad, m, m, rad T [cos(theta), -sin(theta)*cos(alpha), sin(theta)*sin(alpha), a*cos(theta); sin(theta), cos(theta)*cos(alpha), -cos(theta)*sin(alpha), a*sin(theta); 0, sin(alpha), cos(alpha), d; 0, 0, 0, 1]; end这个函数的四个输入都是标量返回4x4齐次矩阵。注意MATLAB三角函数默认用弧度如果你从手册拿到的DH表是角度必须先deg2rad。alpha列如果是-90度就写成-pi/2不要写成-90否则矩阵算出来的关节位置会完全错位。这个函数是整个运动学代码的地基后边所有变换都复用它。2.2 用MATLAB绘制三维模型从线框到实体有了单关节的变换函数只要把每个关节坐标系原点在基坐标系下的坐标依次算出来再连起来就是一个能动的“火柴人”机械臂。预研阶段验证运动学算法这种线框模型完全够用。如果非要渲染成实体可以自己用patch画圆柱或矩形但会增加大量绘图代码对算法没有帮助。2.2.1 写一个drawRobot函数下面的函数输入6个关节角输出并绘制简化三维模型。它内部逐级累乘矩阵算出关节1到末端的位置坐标。function pos drawRobot(theta, dh, showModel) % theta: 1x6关节角向量单位rad % dh: 6x4矩阵每行 [theta_offset, d, a, alpha] % showModel: 是否绘制true/false % 输出pos: 3x7矩阵第1列是基座第7列是末端 pos zeros(3, 7); T_base eye(4); pos(:,1) T_base(1:3,4); % 基座位置 for i 1:6 t theta(i) dh(i,1); % 叠加DH表里的theta初值 Ti dhTransform(t, dh(i,2), dh(i,3), dh(i,4)); T_base T_base * Ti; pos(:,i1) T_base(1:3,4); end if showModel figure; plot3(pos(1,:), pos(2,:), pos(3,:), o-, LineWidth, 2, MarkerSize, 8); grid on; axis equal; xlabel(X/m); ylabel(Y/m); zlabel(Z/m); view(135, 25); title(FANUC-like 6-axis Robot); end end参数说明dh矩阵第一句是theta初值第二和第三列是d和a第四列是alpha。调用时先定义dh数据dh_data [0, 0.330, 0.075, -pi/2; -pi/2, 0, 0.300, 0; 0, 0, 0.040, -pi/2; 0, 0.330, 0, pi/2; 0, 0, 0, -pi/2; 0, 0.060, 0, 0]; drawRobot(zeros(1,6), dh_data, true);运行后会看到6个圆点和7段连线这就是零位的线框模型。如果以后要加第七轴变位机只需要扩展dh矩阵的行数循环体不用改。这段代码在MATLAB R2017b之后都能跑不需要安装Robotics Toolbox。2.3 让模型动起来关节角到末端坐标的映射静态模型没意义我们要的是“给定关节角算出末端在哪然后画出来”。常见做法是写一个for循环让某一关节从0扫到pi/2每步调用drawRobot刷新坐标轴。figure; for q1 0:0.05:pi/2 pos drawRobot([q1, -pi/4, 0, 0, 0, 0], dh_data, true); drawnow; end这里q1每次增加0.05rad视觉上接近连续动画。drawnow是关键没有它你会看一个卡死窗。注意如果theta值直接跨过pi/2连杆会瞬间翻转。这通常不是机器人画错而是DH表里的theta_offset没配好。比如轴2初值设为-pi/2零位时小臂就自然竖直向上调整范围也更合理。到这里三维模型已经搭好正运动学函数也顺手有了。下一步把它单独拆出来再补逆解让模型能真正“指哪打哪”。3. 正运动学与逆运动学FANUC系统的两层映射正运动学是已知6个关节角求末端位姿逆运动学反着来。对FANUC这类六轴关节机器人正解唯一但逆解可能有多组甚至无穷解。实际机器人控制柜里一般用解析法速度快且可预测。我们在MATLAB里做分析通常会先用解析解验证正解再用数值解兜底处理特殊位形。3.1 正运动学连乘齐次变换矩阵把第2章的正解函数单独封装出来便于轨迹规划反复调用。函数输入6个关节角返回末端位姿矩阵和每个关节坐标系原点。function [T06, positions] fkRobot(theta, dh) % 正运动学求末端位姿和所有连杆坐标系原点 % theta: 1x6关节角 % dh: 6x4矩阵定义见前文 T eye(4); positions zeros(3,7); positions(:,1) T(1:3,4); for i 1:6 t theta(i) dh(i,1); T T * dhTransform(t, dh(i,2), dh(i,3), dh(i,4)); positions(:,i1) T(1:3,4); end T06 T; end正运动学没有技巧就是6个矩阵相乘。容易出现的问题有三个一是DH表里的a或d符号写反导致末端y轴反向二是看到网上代码用Modified DH你把它当成标准DH用alpha取反三是theta_offset没有叠加到变量上导致零位姿态错误。排查时用第2章的drawRobot在零位画一下对照FANUC说明书的零位图片一眼就能看出问题。3.2 逆运动学有球腕结构的解析解大多数FANUC六轴机器人在结构上满足Pieper准则后三个关节的轴线交于一点这个点叫腕心。因此把位置逆解和姿态逆解分开处理先根据末端位置沿z轴退回d6得到腕心坐标由腕心坐标解出前三个关节角再由姿态矩阵解出后三个关节角。这种解析解法的优点是可以得到多组显式解并且能根据关节限位快速筛选。工程里你会把所有解都做一次正运动学校验再剔除非限位内的组。由于完整推导很长这里给出关键一步剩下的可以在MATLAB里用符号工具箱辅助推导。3.2.1 腕心分离与冗余解的选择假设T06已知d6也已知则腕心坐标为p_center T06(1:3,4) - d6 * T06(1:3,3);因为末端坐标系z轴方向就是轴6方向。得到腕心坐标后前三个关节角的解析表达式通常是atan2加几何判定。注意atan2(0,0)在某些位形下返回0可能丢解所以解析解算完后一定要带回正解验证。3.3 数值逆解用Jacobian和LM法兜底解析解快但换一个机械臂结构就得重新推一遍很累。在MATLAB里快速验证轨迹规划算法时我一般先用数值解。常见做法是把逆解转化为最小化残差问题给定当前关节角计算正解误差再用Jacobian或阻尼最小二乘更新关节角。下面给出一个不依赖任何工具箱的数值逆解实现。方法优点缺点适用场景解析解速度快、可预测多组解每个结构需重新推导FANUC控制器内常用数值解通用、实现简单依赖初值、可能发散MATLAB验证、快速原型3.3.1 数值逆解的MATLAB实现function q ikRobot(T_des, q_init, dh, tol) % 数值逆解阻尼最小二乘 % T_des: 4x4目标位姿 % q_init: 1x6初始关节角 % tol: 位置/姿态误差容忍度比如1e-6 q q_init(:); for iter 1:200 T_cur fkRobot(q, dh); % 位置误差 err_pos T_des(1:3,4) - T_cur(1:3,4); % 姿态误差旋转矩阵误差转轴角 R_err T_des(1:3,1:3) * T_cur(1:3,1:3); th acos( min(max((trace(R_err)-1)/2, -1), 1) ); if abs(th) 1e-6 axis_vec [1 0 0]; else axis_vec [R_err(3,2)-R_err(2,3); R_err(1,3)-R_err(3,1); R_err(2,1)-R_err(1,2)] / (2*sin(th)); end err_rot th * axis_vec; err [err_pos; err_rot]; if norm(err) tol return; end % 数值Jacobian 6x6 delta 1e-6; J zeros(6,6); for j 1:6 qp q; qp(j) qp(j) delta; Tp fkRobot(qp, dh); dp Tp(1:3,4) - T_cur(1:3,4); Rp Tp(1:3,1:3) * T_cur(1:3,1:3); thp acos( min(max((trace(Rp)-1)/2, -1), 1) ); if thp 1e-6 ax [1 0 0]; else ax [Rp(3,2)-Rp(2,3); Rp(1,3)-Rp(3,1); Rp(2,1)-Rp(1,2)] / (2*sin(thp)); end J(:,j) [dp; thp*ax]; end damp 0.01; % 阻尼系数 dq (J*J damp^2*eye(6)) \ (J * err); q q dq; end warning(IK not converged); end关键参数有三个。damp阻尼系数一般在0.01到0.1之间太小会震荡甚至发散太大会让末端走不到目标。tol位置和姿态合成误差仿真用1e-6足够实时性要求高可放宽到1e-4。q_init初值很重要与真解相差超过30度时容易陷入局部极小。连续轨迹规划时把上一周期的解作为下一周期初值这是最实用的做法。T_target [1 0 0 0.5; 0 1 0 0.2; 0 0 1 0.8; 0 0 0 1]; q_initial [0, -pi/4, pi/4, 0, pi/6, 0]; q_sol ikRobot(T_target, q_initial, dh_data, 1e-6);如果迭代过程中误差反而变大把数值Jacobian的delta改成1e-8。如果误差卡住不动多半遇到奇异位形可以加大damp或者更换初值。数值解返回的关节角不一定在FANUC软限位内。我在轨迹规划前面会写一个过滤函数把超限位的解直接丢弃而不是截断因为截断会破坏末端姿态。4. 关节空间与笛卡尔空间的轨迹规划让机械臂按规矩走运动学解决的是“能不能到”轨迹规划解决的是“怎么走”。工程里最常见两种需求点到点移动只需要对关节角做平滑过渡另一种要求末端走直线或圆弧比如涂胶和焊接。后者必须做笛卡尔空间规划。机械臂轨迹规划算法五花八门但核心无非“插补加逆解”。4.1 关节空间梯形速度与五次多项式的选择如果机器人只要求从A点到B点不关心中间路径形状关节空间规划最省事。典型速度曲线有两种梯形速度适合快速点到点五次多项式适合要求首末加速度为零的场景。下表是工程选型时的主要参考曲线类型计算成本连续量典型场景梯形速度低速度连续加速度突变上下料、拆码垛S型速度中加加速连续平滑性好精密装配、搬运易碎品五次多项式低位置、速度、加速度连续需要jerk受控的工艺下面用MATLAB实现一个梯形速度规划函数输入起点角、终点角、最大速度、加速度和采样周期返回各轴位置、速度、加速度。function [q, qd, qdd, t] trapTraj(q0, q1, v_max, a_max, dt) % 梯形速度规划 % q0, q1: 1x6 起始/终点关节角 delta_q q1 - q0; dist norm(delta_q, 2); t_acc v_max / a_max; % 加速时间 dist_acc a_max * t_acc^2; % 加速段位移 if dist_acc dist % 距离太短到不了最大速度直接三角速度 t_acc sqrt(dist / a_max); v_peak a_max * t_acc; t_total 2 * t_acc; else v_peak v_max; dist_cruise dist - 2 * dist_acc; t_cruise dist_cruise / v_max; t_total 2 * t_acc t_cruise; end t 0:dt:t_total; q zeros(length(t), 6); qd zeros(length(t), 6); qdd zeros(length(t), 6); for k 1:length(t) tau t(k); if tau t_acc s 0.5 * a_max * tau^2; s_v a_max * tau; s_a a_max; elseif tau t_total - t_acc s dist_acc v_peak * (tau - t_acc); s_v v_peak; s_a 0; else t_dec t_total - tau; s dist - 0.5 * a_max * t_dec^2; s_v a_max * t_dec; s_a -a_max; end ratio s / dist; q(k,:) q0 ratio * delta_q; qd(k,:) (s_v / dist) * delta_q; qdd(k,:) (s_a / dist) * delta_q; end end注意这个函数把6个关节的差值当作一个6维向量求了欧几里得范数意味着所有轴同时到达目标。如果6个轴行程差异太大会强迫所有轴等比例跟随造成某轴速度很慢。工程里更常见的是每轴独立做梯形规划最后让总时间取各轴最大时间。上面的写法适合末端近似直线路径直接用即可。4.2 笛卡尔空间直线与圆弧轨迹规划算法焊接、涂胶工艺要求末端走直线或圆弧。直线轨迹规划的核心是在端点之间插值位置和姿态保证位置在直线上姿态过渡不被扭曲。4.2.1 直线插补function [poses] lineInterp(p0, p1, R0, R1, step) % 直线插补 % p0/p1: 3x1位置R0/R1: 3x3旋转矩阵 % step: 插补步长单位米 line_dir p1 - p0; total_dist norm(line_dir); n_steps ceil(total_dist / step); poses cell(1, n_steps1); for i 0:n_steps t i / n_steps; p p0 t * (p1 - p0); R R0 t * (R1 - R0); % SVD重新正交化防止数值漂移 [U,~,V] svd(R); R U * V; poses{i1} [R p; 0 0 0 1]; end end旋转矩阵线性插值后必须做正交化否则变换矩阵会引入剪切变形。上面用SVD重新正交化是一种简单稳定的方法。如果两个姿态相差超过30度建议改用四元数slerp否则中间姿态会明显扭曲。MATLAB R2018b之后自带quaternion类型但需要Aerospace Toolbox。没有工具箱的话自己写一个四元数插值函数也不难。4.2.2 圆弧插补三点定义圆弧是涂胶轨迹里最常见的场景。给定起点p0、中间点p1、终点p2先计算圆心和半径再按角度参数化生成弧上点。function [circlePoints] circularTraj(p0, p1, p2, stepAngle) % 三点圆弧插补 % p0,p1,p2: 3x1位置向量stepAngle: 每步弧度 v1 p1 - p0; v2 p2 - p0; n cross(v1, v2); if norm(n) 1e-6 error(三点共线无法构造圆弧); end n n / norm(n); % 圆心在v1和v2的中垂面交线上 A [2*v1; 2*v2]; b [v1*v1; v2*v2]; c A \ b; c p0 c; v_start p0 - c; v_end p2 - c; theta_start atan2(n*cross(v_start, [1;0;0]), v_start*[1;0;0]); theta_total acos( min(max(v_start*v_end / (norm(v_start)*norm(v_end)), -1), 1) ); step_total ceil(theta_total / stepAngle); circlePoints zeros(3, step_total1); for k 0:step_total th theta_start k * stepAngle; R axisAngleToMatrix(n, th); % 自实现Rodrigues公式 circlePoints(:, k1) c R * v_start; end end function Rm axisAngleToMatrix(axis, angle) % 绕单位轴旋转angle的旋转矩阵Rodrigues公式 K [0, -axis(3), axis(2); axis(3), 0, -axis(1); -axis(2), axis(1), 0]; Rm eye(3) sin(angle)*K (1-cos(angle))*K*K; end注意我没有用Matlab自带的axang2rotm因为该函数属于Aerospace Toolbox不是基础函数。发布代码给别人时如果对方没有这个工具箱运行会直接报错。因此这里给出Rodrigues公式的自实现版本这也是圆弧轨迹规划里很值得封装成通用工具的一段代码。4.3 轨迹规划中的奇异性与速度突变问题笛卡尔轨迹生成后每个插补点都要通过逆解变成关节角。如果某一点落在奇异位形附近数值逆解的Jacobian会接近奇异导致关节速度瞬间飙升。这是机械臂轨迹规划算法里最常见的难点。规避手段有三个在逆解里对Jacobian判定最小奇异值低于阈值时加大阻尼系数规划路径时预先绕开奇异位形对逆解后的关节角序列做平滑处理。最直接的办法是先逆解出一整条关节角序列然后查看各轴速度曲线。如果某轴在某一小段出现尖峰说明路径穿过了奇异区域。用smoothdata对关节角做滑动平均是临时救急但要小心滤掉太多角位移会让末端轨迹偏离预定直线。5. 用逆解验证正解、绕开离线编程的授权码陷阱最后回答工程师每天都在纠结的两个问题怎么证明这套运动学代码是对的离线仿真和FANUC真机对接时要注意什么5.1 随机采样验证正逆解一致性正解和逆解互为对偶。怀疑哪个不对就用另一个去验。我一般随机生成1000组关节角逐组正解得到末端位姿再送入逆解比较逆解结果与原始关节角的末端误差。max_pos_err 0; for i 1:1000 q_rand -pi 2*pi*rand(1,6); [T, ~] fkRobot(q_rand, dh_data); q_ik ikRobot(T, q_rand, dh_data, 1e-8); [T_check, ~] fkRobot(q_ik, dh_data); pos_err norm(T_check(1:3,4) - T(1:3,4)); max_pos_err max(max_pos_err, pos_err); end fprintf(最大位置误差: %.3e m\n, max_pos_err);正常情况下最大位置误差应该低于1e-6米。如果达不到先检查逆解中的姿态误差向量是不是写错了。常见错误是把旋转误差拆成三个欧拉角误差拼进向量这样在万向锁附近会产生假误差。5.2 用matlab优化工具箱做运动学参数标定如果机械臂末端定位总差一点说明DH参数与真机有偏差。常见做法是用matlab优化工具箱里的lsqcurvefit把关节角作为输入把实测末端位置作为观测反求DH参数。但不要优化所有参数一般只优化d和aalpha和theta保持出厂值因为后者在机械装配中相对稳定。% 伪代码示意 % Q_meas: Nx6关节角P_meas: Nx3实测位置 % 目标函数minimize sum(|fkRobot(q, dh_opt) - p_meas|^2) % dh_opt lsqcurvefit((dh, Q) fkAllPositions(Q, dh), dh_data, Q_meas, P_meas);标定出来的参数可以回灌到离线轨迹规划里。但注意实测末端位置前必须先确认工具坐标系TCP已经设定准确。TCP有1mm误差标定出来的DH参数也会偏1mm源头污染会让标定结果失去意义。5.3 离线仿真与FANUC授权码坐标系先对齐再谈导入MATLAB里验证好轨迹下一步往往是想导入FANUC的Roboguide做离线仿真。很多人第一次看到Roboguide提示需要离线编程授权码就以为这是破解不了的门槛。实际上授权码是FANUC官方软件许可的一部分和MATLAB代码没关系。你只需要在合法授权环境下把MATLAB生成的关节角序列保存成CSV再在Roboguide里用程序文件导入。整个过程不涉及任何绕过动作保持合规。我在导入前会额外做一件事在MATLAB里把每个插补点的笛卡尔位姿也导出一份。这样到了Roboguide里可以用三点测量工具快速核对轨迹位置。一旦发现偏差先查机器人坐标系定义是否一致而不是急着怀疑算法。FANUC机器人的基坐标系、腕部法兰坐标系和工具坐标系的定义在不同型号间有细微差异离线仿真和真机对不上时大概率是这里出了问题。留一个值得动手的练习把第2章的drawRobot、第4章的trapTraj和lineInterp拼在一起让末端走一段直线然后画出6个关节角速度曲线。你会发现“笛卡尔直线轨迹”并不等于“关节角线性变化”看到曲线中间偶尔出现的尖峰就说明路径靠近了奇异位形。这个观察比多读十篇理论文章都管用。本文还有配套的精品资源点击获取
返回列表