资讯动态

UR5机器人动力学参数辨识:MATLAB实现与源码解析

发布时间:2026/9/20 15:06:41 来源:尧图企业网站定制
简介针对UR5六轴协作机器人动力学模型参数辨识需求提供一套Matlab分析源码适用于从事机器人控制、动力学建模的研究者与工程师可帮助完成从运动学到动力学转换、参数估计与模型验证等关键环节。压缩包共9个文件包含8个.m脚本和1个.mat数据文件整体仅12KB脚本涵盖轨迹规划、回归矩阵构建、参数求解等典型流程mat文件用于存放基础参数数据方便用户直接运行和二次开发。目前已有217人学习。该资源代码结构清晰、步骤完整既可用于理解最小二乘与傅里叶级数激励轨迹等辨识思路也可作为实际UR5动力学建模的参考工具对精密装配、焊接等场景下的机器人控制优化具有实用价值。1. 先理解UR5参数辨识在解决什么问题UR5的动力学模型参数辨识本质上是把牛顿-欧拉方程里的连杆质量、质心位置、惯性张量和关节摩擦系数从图纸上的名义值换成能从实测数据中估计出来的实际值。很多人以为用Simscape拖一个模型就能拿到靠谱的动力学参数但真正的前馈控制、拖拽示教、负载辨识场景下Simscape里的默认参数往往差得离谱。这里要拆的matlab源码是一条从傅里叶激励轨迹生成、回归矩阵堆叠、QR分解去相关到最小二乘求解的完整链路能够一次性输出UR5六关节的基础参数集。这篇文章会按这条链路逐段解释每个m文件的作用并给出可以直接改参数运行的代码骨架适合正在做机器人辨识、准备做前馈补偿或需要评估UR5模型精度的工程师。2. UR5动力学模型与线性化参数化从牛顿-欧拉到回归矩阵2.1 为什么必须线性化惯性参数与基础参数集UR5每个关节的力矩方程可以写成τ M(q)q̈ C(q,q̇)q̇ G(q) F_v q̇ F_c sign(q̇)其中M(q)是惯性矩阵C(q,q̇)是科氏力及离心力矩阵G(q)是重力项F_v、F_c是粘性摩擦和库仑摩擦向量。直接对每个连杆的质量、质心XYZ坐标、惯性张量六个独立分量做非线性优化问题很难收敛因为参数之间存在线性耦合轨迹稍微不够充分的时候结果就会在多个局部最优之间跳来跳去。更致命的是UR5的DH参数决定了部分质量和质心组合根本不可能被独立辨识强行求解会让信息矩阵奇异。线性化参数化的思路是把动力学方程改写为τ Y(q, q̇, q̈) · θ这里Y称为回归矩阵θ是待辨识参数向量中的基础参数。这个形式的优势在于一旦通过符号推导或数值差分获得Y参数辨识就退化为一个线性最小二乘问题数学性质清楚解唯一且稳定。UR5的完整惯性参数有60个每个连杆质量、质心3个、惯性矩阵6个再加上6个关节的粘性摩擦和库仑摩擦一共72个参数。但经过线性化降维后基础参数通常落在36个左右具体数量取决于你的摩擦模型和是否把电机转子惯量合并进去。下表给出了UR5动力学参数集合的大致构成参数类别每连杆数量总数量辨识后数量基础参数质量 m16部分合并到质心组合质心坐标 r_x, r_y, r_z318大部分可辨识惯性张量 I_xx..I_zz636大量线性相关粘性摩擦 F_v166库仑摩擦 F_c166合计—72约 36注意表格里的“约36”是一个常见工程经验值实际数字取决于你选择的惯性张量参数化方式。比如绕Y轴对称的连杆会丢失部分惯性参数这时基础参数更少。所以源码里ur_base_params_QR.m不是写死数字而是用QR分解自动识别哪些列可辨识。2.2 从标准动力学方程到Y(q,qd,qdd)θ拿到UR5的DH参数后可以用拉格朗日法或牛顿-欧拉递推法把关节力矩τ表示成q、q̇、q̈和非线性参数的函数。写代码时我更喜欢牛顿-欧拉递推因为它结构化好易于符号化。第一个连杆的角速度、角加速度递推关系可以写成如下形式ω_1 R_1^T · (ω_0 q̇_1 · z_0) ω̇_1 R_1^T · (ω̇_0 q̈_1 · z_0 q̇_1 · z_0 × ω_0)其中R_1是连杆1到基座的旋转矩阵z_0是基座Z轴单位向量。把这些递推式展开后所有运动学量都只是q、q̇、q̈的组合而动力学参数则作为线性系数出现在力矩表达式里。因此求解Y的方式是对τ向量关于所有待辨识参数取偏导得到每列。下面给出了一个截断的matlab函数骨架用于计算单个采样点的回归矩阵Yfunction [Y, tau] ur5_regressor_point(q, qd, qdd, P) % q/qd/qdd: 6x1 关节位置、速度、加速度 % P: struct包含m,r,I,Fv,Fc等原始参数 % Y: 6 x n_params 回归矩阵 % tau: 6x1 关节力矩 % 通过牛顿欧拉递推得到tau省略中间步骤 % tau newton_euler(q, qd, qdd, P); % 对每个参数做有限差分获得Y的每一列 param_list {m1,r1x,r1y,r1z,I1xx,I1yy,I1zz, ... m2,r2x,r2y,r2z,I2xx,I2yy,I2zz}; n length(param_list); Y zeros(6, n); tau0 newton_euler(q, qd, qdd, P); for i 1:n Pp P; Pp.(param_list{i}) P.(param_list{i}) 1e-6; Pm P; Pm.(param_list{i}) P.(param_list{i}) - 1e-6; tau_p newton_euler(q, qd, qdd, Pp); tau_m newton_euler(q, qd, qdd, Pm); Y(:,i) (tau_p - tau_m) / 2e-6; end end这里用中心差分代替符号求导因为newton_euler函数可以接受结构体参数差分法不需要重写符号表达式。注意有限差分步长取1e-6对质量、惯性这类量级差异很大的参数可能需要归一化后再差分。更严谨的做法是用符号数学工具箱求解析偏导然后在每个采样点上代入数值。2.3 用Matlab符号工具箱推导UR5回归矩阵有限差分法在参数多时容易累计算出误差尤其当你需要在一个采样周期内反复调用回归函数时性能也扛不住。我一般会先用符号工具箱生成回归矩阵的闭式函数syms q1 q2 q3 q4 q5 q6 real; syms qd1 qd2 qd3 qd4 qd5 qd6 real; syms qdd1 qdd2 qdd3 qdd4 qdd5 qdd6 real; syms m1 m2 m3 m4 m5 m6 real; syms r1x r1y r1z r2x r2y r2z real; % ... 定义全部动力学参数 param_vec [m1,m2,m3,m4,m5,m6, r1x,r1y,r1z, r2x,r2y,r2z]; % 由牛顿欧拉递推得到tau一个6x1符号向量 tau ur_dynamics_symbolic(q,qd,qdd,param_vec); Y_sym jacobian(tau, param_vec); % 6 x n 回归矩阵 % 生成可调用的matlab函数 matlabFunction(Y_sym, Vars, {[q1 q2 q3 q4 q5 q6], ... [qd1 qd2 qd3 qd4 qd5 qd6], [qdd1 qdd2 qdd3 qdd4 qdd5 qdd6]}, ... File, Y_symbolic.m);这里jacobian是处理线性化最干净的工具它给出了“力矩对每个动力学参数的偏导”。得到的是n个参数的完整列还没有剔除线性相关列所以后续在全部采样点组合后再通过QR分解筛出独立列。注意符号方法生成的Y_symbolic.m执行速度并不快因为表达式中包含大量的sin、cos和组合项。实际使用时可以在离线阶段把Y_symbolic.m转换为mex函数或者用codegen生成C代码。对于UR5这种六个连杆的规模即使不转mex在测量1000个点、每点6行72列的情况下matlab也能在几秒内算完。3. 傅里叶激励轨迹的设计与条件数检查3.1 参数辨识需要什么样的激励回归矩阵Y的条件数直接决定参数估计的上限。如果轨迹中每个关节都在低速小范围运动很多参数对力矩的贡献会被噪声淹没Y的某些列接近零或共线信息矩阵出现病态。UR5的关节摩擦力较大粘性摩擦参数需要足够的关节速度变化才能被激励出来惯性参数则对加速度变化更敏感。因此激励轨迹的设计目标是在满足关节限位、速度、加速度边界的前提下尽可能让Y的信息矩阵条件数最小化。工程上通常采用有限傅里叶级数轨迹原因是它天然满足周期性且位置、速度、加速度都有闭式表达式容易计算和约束。傅里叶轨迹的另一个好处是可以将激励能量集中在特定频段内避开机械臂的结构谐振和测量噪声较高的高频段。3.2 Fourier_series_trj.m 中的周期轨迹设计UR5的每个关节参考位置写成傅里叶级数q_i(t) q_0i \sum_{k1}^{L} \frac{a_{ik}}{k\omega}\sin(k\omega t) - \frac{b_{ik}}{k\omega}\cos(k\omega t)其中 \omega 2\pi / TT是轨迹周期。速度、加速度表达式分别为q̇_i(t) \sum_{k1}^{L} a_{ik}\cos(k\omega t) b_{ik}\sin(k\omega t) q̈_i(t) \sum_{k1}^{L} -k\omega a_{ik}\sin(k\omega t) k\omega b_{ik}\cos(k\omega t)Fourier_series_trj.m 的核心工作是生成每个关节的基函数矩阵并留给后续的优化器去决定系数。下面是生成轨迹的matlab代码% Fourier_series_trj.m N 2000; % 每个周期的采样数 T 20; % 周期长度 秒 dt T / N; t (0:N-1) * dt; L 5; % 谐波阶数 w 2 * pi / T; % 基函数矩阵 F: 位置 F * coeff F zeros(N, 2*L 1); F(:,1) 1; for k 1:L F(:, 2*k) sin(k * w * t) / (k * w); F(:, 2*k1) -cos(k * w * t) / (k * w); end % 速度基函数矩阵 Fd Fd zeros(N, 2*L 1); Fd(:,1) 0; for k 1:L Fd(:, 2*k) cos(k * w * t); Fd(:, 2*k1) sin(k * w * t); end % 加速度基函数矩阵 Fdd Fdd zeros(N, 2*L 1); Fdd(:,1) 0; for k 1:L Fdd(:, 2*k) -k * w * sin(k * w * t); Fdd(:, 2*k1) k * w * cos(k * w * t); end这里的F、Fd、Fdd分别对应位置、速度、加速度的基函数。系数向量coeff是一个长度为2L1的向量其中第一个元素是常数偏置q_0后面2L个元素是a_k和b_k。实际设计时优化变量是6个关节的系数矩阵C6 × (2L1)目标函数是信息矩阵的条件数约束是每个关节的位置、速度、加速度限位。在traj_cnt.m中通常还会检查起始点的连续性。因为UR5的底层控制器要求轨迹在启动时刻速度、加速度为0否则会造成冲击。你可以把起始时刻的条件写成等式约束例如q_i(0)q_i(T)、q̇_i(0)q̇_i(T)0。傅里叶级数本身满足周期性所以起点终点位置自动一致但速度和加速度需要额外通过系数约束强制为0。3.3 traj_cond.m 与轨迹条件数检查设计好的轨迹不能直接拿去跑要先在matlab里仿真或离线计算信息矩阵的条件数。traj_cond.m 就是做这件事的。它会调用后面要讲的full_regressor函数在每个采样时刻生成回归矩阵Y并累加Y^T Y最后计算条件数。function condC traj_cond(q, qd, qdd) % q/qd/qdd: Nx6 矩阵分别代表关节位置/速度/加速度轨迹 % 返回累积信息矩阵的条件数 N size(q, 1); I_info zeros(72, 72); % 先用完整参数维数后续会降维 for i 1:N Y full_regressor_point(q(i,:), qd(i,:), qdd(i,:)); I_info I_info Y * Y; end % 只评估可辨识的基础参数维数这里假定前36列为有效 condC cond(I_info(1:36, 1:36)); fprintf(信息矩阵条件数: %.3e\n, condC); end注意这里full_regressor_point返回的是完整Y其列数多于基础参数个数。在优化轨迹系数时我们需要对每个候选轨迹先做一次QR分解确定当前Y下哪些列线性独立然后只对独立子矩阵求条件数。这样计算量会增大但换来的是更可靠的激励。判断某个轨迹是否合格我一般看条件数是否小于1e4。如果条件数大于1e6说明数据几乎无法区分某些参数即使估计出来也毫无意义。此时应增加谐波阶数或改变优化初值。还有一种常见误用是直接对Y本身求cond而不是对Y^T Y求cond前者是矩阵奇异值比后者才是信息矩阵的病态度量。在matlab里cond(Y)和cond(Y*Y)相差很大后者更能反映最小二乘解的稳定性。4. 回归矩阵的构建与基础参数筛选4.1 关节角速度/加速度计算与滤波从UR5实际采集回来的数据中位置信号通常来自编码器噪声很小但差分得到的速度和加速度噪声会被放大。UR5的通信周期是2ms如果直接对位置做二阶差分加速度信号会充满高频毛刺。常用做法是先对位置信号做零相位低通滤波再用中心差分计算速度与加速度。fs 500; % 采样率 500Hz fc 3; % 截止频率根据轨迹激励频率调整 [b, a] butter(4, fc / (fs/2), low); q_filtered filtfilt(b, a, q_measured); qt q_filtered; qtm [qt(1,:); qt(1:end-1,:)]; qtp [qt(2:end,:); qt(end,:)]; qd (qtp - qtm) / (2 / fs); qdd (qtp qtm - 2*qt) / (1/fs)^2;这段代码中filtfilt是零相位滤波避免了普通filter带来的相位偏移。中心差分使用的步长正好是2个采样间隔。注意截止频率不能设太低否则会削减傅里叶轨迹中高频谐波的幅度导致激励不足。通常把fc设为傅里叶轨迹最高谐波频率的2倍以上比如轨迹中k5、基频0.05Hz最高频率0.25Hz那么fc选3Hz已经足够。4.2 去除线性相关列ur_base_params_QR与QR分解UR5的完整回归矩阵W是由N个采样点的Y拼接而成的维度是(6N)×72。这72列之间存在线性相关直接做最小二乘会得到无限多解。解决办法是使用主元QR分解找到一组列索引使得剩余列线性无关。在ur_base_params_QR.m中典型实现如下function [base_idx, Q, R, perm] ur_base_params_QR(W, tol) % W: (6N) x n_param 完整回归矩阵 % tol: 对角元容忍度默认1e-6 if nargin 2, tol 1e-6; end [Q, R, perm] qr(W, 0); % 经济型QR分解 d abs(diag(R)); base_idx perm(d tol * max(d)); % 保留对角元相对较大的列 fprintf(从 %d 列中筛选出 %d 个基础参数\n, size(W,2), length(base_idx)); end这里的关键是perm列置换向量它记录了原始参数列的重排顺序。d是R矩阵的对角元绝对值如果某一列不可辨识对应d会非常小。默认容忍度取1e-6乘以最大对角元。运行此函数后base_idx就是筛出的基础参数索引可以保存到base_QR.mat中后续求解时只使用这些列。4.3 装配完整回归矩阵full_regressor.m 的作用是处理一整条轨迹的采样数据输出一个用于辨识的稀疏矩阵W。下面是一段可运行的装配逻辑function W full_regressor(q, qd, qdd, param_idx) N size(q, 1); rows 6 * N; n_sel length(param_idx); W zeros(rows, n_sel); for i 1:N row_idx (i-1)*61 : i*6; Yi full_regressor_point(q(i,:), qd(i,:), qdd(i,:)); W(row_idx, :) Yi(:, param_idx); end % 如果采样点很多可以转为稀疏矩阵节省内存 W sparse(W); endfull_paramts.m 则是参数打包工具它把角度、速度、加速度、力矩以及参数索引封装成一个结构体方便后续调用最小二乘。参数索引来自base_QR.mat其中保存的是上一步QR分解选中的列号。如果直接使用所有列软件会提示你“参数不可辨识请先运行ur_base_params_QR”。这里有一个常见误区QR分解必须在整条轨迹的W矩阵上做而不能在单个采样点的Y矩阵上做。单个点的Y通常秩不足但累积多个不同状态后列相关性可能被打破。所以源码里的操作顺序是先设计轨迹、采集数据、拼W再做QR筛选。这样筛选出的基础参数集才覆盖整条轨迹的激励空间。5. 最小二乘估计与摩擦项处理5.1 最小二乘参数估计的问题形式有了筛选后的回归矩阵W和实测力矩向量τ参数估计就是求解线性方程W θ τ因为W的行数远大于列数这是一个超定方程组标准解法是最小二乘目标为min ||Wθ - τ||^2。在matlab中直接用反斜杠运算符即可求解theta_est W \ tau;W是6N×n_base矩阵tau是6N×1向量。反斜杠会自动调用最小二乘算法对稀疏矩阵使用QR或Cholesky分解。要注意的是τ的单位是N·m线性化后的参数θ向量中既包含惯性参数也包含摩擦参数不同列的量级可能相差很大。例如质量约数千克惯性张量约0.1 kg·m^2摩擦系数可能只有0.01 N·m·s/rad。这种情况下应使用归一化后再求解。5.2 Solve_C.m 中的核心实现Solve_C.m 在源码中的任务是把测量数据与基础参数索引结合起来完成最终的参数求解。一个典型的实现片段如下% Solve_C.m 求解基础参数C load(base_QR.mat, base_idx); % 载入基础参数索引 q raw_data.q; qd raw_data.qd; qdd raw_data.qdd; tau_exp raw_data.tau; % 计算完整回归矩阵并抽取基础列 W_full full_regressor(q, qd, qdd); W W_full(:, base_idx); % 求解最小二乘 theta W \ tau_exp(:); % 输出标准格式的参数向量未辨识列置0 theta_full zeros(1, 72); theta_full(base_idx) theta; % 保存参数结果 save(identified_params.mat, theta_full, base_idx);这里比较重要的是求解得到的theta只是基础参数部分。如果你需要把结果反代回完整动力学模型必须维持一个从完整参数到基础参数的线性映射否则会破坏匹配关系。UR5的源码里full_paramts.m就是为了管理这个映射的。5.3 加权最小二乘与摩擦项处理实际测量中末端关节力矩小传感器噪声占比高不同关节的信号信噪比差异很大。如果直接最小二乘大力矩关节会主导误差。我一般会用加权最小二乘来平衡各关节贡献w_vec ones(6*N, 1); for i 1:N w_vec((i-1)*61 : i*6) 1 ./ max(abs(tau_exp((i-1)*61:i*6)), 0.1); end Ww W .* w_vec; tau_w tau_exp(:) .* w_vec; theta_wls Ww \ tau_w;权重取每个时刻实际力矩绝对值的倒数外加下限0.1避免零力矩时刻权重无限大。这样辨识出的参数在高力矩和低力矩时刻都有较好的拟合度。另一种做法是使用鲁棒最小二乘例如迭代重加权最小二乘将力矩残差中的离群点权重降低。摩擦参数的辨识时常被忽略。UR5的关节减速器摩擦表现出Stribeck效应仅仅用库仑粘性摩擦并不完全准确。如果源码里只有Fv和Fc可以在线性化时把摩擦项单独拆出来作为输入的一部分在回归矩阵中增加一列速度q̇和一列符号sign(q̇)。注意摩擦项只与速度有关不依赖加速度因此如果在傅里叶轨迹中速度过零时刻太多摩擦列与惯性列之间可能产生额外相关性。解决办法是在激励轨迹设计时让关节速度尽量不长时间停留在零附近。下表给出了几种摩擦模型的辨识对比模型公式参数个数回归矩阵可辨识性粘性库仑F F_v q̇ F_c sign(q̇)2/关节良好常用简单粘性F F_v q̇1/关节简单但低速误差大StribeckF F_c (F_s-F_c)e^{-(q̇/v_s)^2}3/关节非线性需迭代双向摩擦正反转摩擦系数不同4/关节需要正反向数据如果你的应用要求低速时力矩预测准确光靠前两阶摩擦模型是不够的。这里可以扩展回归矩阵加入速度的平方项或指数项但代价是线性化特征被破坏需要改用非线性优化。对于大多数UR5使用场景粘性库仑模型配合良好激励轨迹已经能达到95%以上的力矩预测精度。6. 验证方法、常见坑和一个实用辨识技巧6.1 用辨识出的参数回代验证力矩拿到theta_full后必须做交叉验证。做法是再用一段与辨识轨迹不同的验证轨迹采集关节角度和力矩然后计算预测力矩与实测力矩的差异。% 验证脚本 for i 1:N tau_pred(i,:) Y_symbolic(q(i,:), qd(i,:), qdd(i,:)) * theta_full; end error tau_pred - tau_measured; rmse sqrt(mean(sum(error.^2,2))); nrmse rmse / sqrt(mean(sum(tau_measured.^2,2))); fprintf(RMSE %.3f Nm, NRMSE %.2f%%\n, rmse, nrmse*100);NRMSE在5%以下说明模型可用。如果NRMSE大于10%优先检查轨迹是否激励充分、滤波是否削弱了有效信号、摩擦模型是否需要扩展。6.2 常见坑噪声、测量偏差与局部最优第一个坑是对力矩信号做低通滤波时引入了相位延迟。力矩放大器输出的信号如果和编码器位置数据没有对齐即便只有几毫秒延迟也会在辨识结果里引入偏差表现为质量参数偏大或偏小。建议在采集时同步记录时间戳离线用cross-correlation对齐。第二个坑是奇异值阈值选得不合适。QR分解的tol过大会把有用的参数列筛掉tol过小会保留数值相关的列导致最小二乘解发散。一个实用技巧是画出R对角线对数幅度图看是否存在明显峭壁。第三个坑是惯性参数和重力参数之间的耦合。当UR5处于水平姿态时重力项对某些关节没有作用导致重力相关参数不可辨识。因此激励轨迹应包含大幅度俯仰、偏航运动让所有关节在重力方向上都有足够的变化。6.3 实用技巧对回归矩阵做列归一化再求解这是一个低成本但常常被忽略的提升数值稳定性技巧。在求解前先计算W每列的RMS然后对每列除以RMS求解后乘回。这样能让最小二乘法不再被大数值列主导。col_norm sqrt(sum(W.^2, 1)); % 每列2范数 Wn W ./ col_norm; % 归一化 theta_n Wn \ tau(:); theta_scaled theta_n ./ col_norm; % 还原到原始参数dom这一技巧配合加权最小二乘能让参数结果在多次重复实验中波动很小。完成辨识后我建议把theta_scaled保存为mat文件并在simulink中搭一个前馈补偿模块用UR5实际负载跑几次定位精度测试对比前馈开和关的轨迹跟踪误差。真正有价值的辨识输出是一套能直接部署到控制器里的参数而不仅仅是论文里的一个表格。关于基频优化留一个可操作的调参路径先固定L5用fmincon优化系数C目标为cond(Wn * Wn)约束里加入每个关节位置速度限位。如果优化耗时过长可以降低采样点到500点条件是轨迹周期和基频不变。这样既能得到满意的激励轨迹又能控制在matlab里的计算时间。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价