简介:面向从事摩擦建模、伺服控制与机械系统仿真的Matlab学习者,这套代码围绕Stribeck摩擦模型展开,重点复现低速阶段的负斜率摩擦现象:克服静摩擦后,摩擦力随速度先降后升,并以指数形式描述该过程。内容适合需要理解非线性摩擦特性、开展控制补偿或完成课程实验的初、中级读者使用。包内共3个.m文件,压缩包约1KB,包含模型实现、演示脚本及辅助函数,便于直接运行观察参数变化及δ、vs等对曲线形态的影响,也方便嵌入已有仿真流程。已有1138人学习。读者可据此理解静摩擦、库仑摩擦与Stribeck速度尺度等参数的含义,掌握从公式到代码的映射,并通过示例快速验证负斜率段与速度拐点,为控制算法补偿和论文复现提供可改可扩的基础脚本。
1. 低速爬行不是机械问题:Stribeck 摩擦力模型在 Matlab 里的一次完整落地
精密进给台做 0.5 mm/s 匀速跟随,速度曲线却走成台阶,位置环一抖一抖地"呼吸",换成更贵的导轨还是原样。遇到这种低速爬行,很多人的第一反应是查机械装配和伺服增益,但真正的原因常常在摩擦力本身:它在零速附近不是常数,而是一条先陡降、再回升的曲线。Stribeck 摩擦力模型描述的就是这段曲线,而这组 Matlab 实现代码与使用示例想干的事很直接——把这条曲线变成一个能算、能拟合、能接进 Simulink 的解析函数,让你的仿真里出现和台架上一样的爬行,也让前馈补偿有参数可调。它适合做运动控制仿真的工程师、做摩擦补偿算法验证的研究生,以及手上有一批速度-摩擦力实测数据但不知道怎么反推参数的人。
2. 拆开 Stribeck 曲线:五个参数各自的物理含义与选型理由
动手写函数之前,先把模型本身的骨架立住。不然后面拟合出来的数字看着能过,一放进闭环就会翻车。
2.1 从边界润滑到流体润滑:负斜率段是哪来的
两个接触面在相对运动时,润滑油膜的状态随速度变化分三段。速度极低时处于边界润滑,微凸体直接接触,摩擦力最大,这就是最大静摩擦力Fs;速度稍微上来一点,油膜开始建立、微凸体接触面积下降,摩擦力反而随速度升高而下降,这一段就是 Stribeck 负斜率段,也是低速爬行的直接来源;速度继续升高,流体动压效应占据主导,粘性阻力随速度线性上升,斜率变正。
稳态下把这三段写成一个关于速度v的解析式,最常用的形式是:
F(v) = Fc·sgn(v) + (Fs - Fc)·exp(-|v/vs|^d)·sgn(v) + Fv·v五个参数含义如下:Fc是库仑摩擦力,也就是负斜率段走完之后剩下的那部分近似恒定的摩擦力;Fs是最大静摩擦力,必须满足Fs ≥ Fc;Fv是粘性阻尼系数,单位 N·s/m,描述高速段的线性上升;vs是 Stribeck 特征速度,量纲上就是速度,它决定负斜率段在哪个速度量级上"塌下去";d是形状指数,控制从Fs衰减到Fc的曲线陡峭程度,工程上常见取值在 0.5 到 2 之间,取 1 的指数衰减和取 2 的高斯型衰减在低速段差别很大。
这里有个容易忽略的细节:vs和d是强相关的。同一批数据,用vs=0.01, d=1和vs=0.014, d=1.6可能拟合出几乎一样的残差平方和,但把速度外推到 0.05 mm/s 时两条曲线会分叉。这也是后面参数辨识章节要反复强调固定d或者做多初值搜索的原因。
2.2 五种常见写法怎么选:指数型、tanh 平滑型、LuGre 与 Karnopp
市面上叫"Stribeck 模型"的实现其实不止一种,选错了会在特定场景下白干。
经典指数型就是上面那个式子,sgn函数在零速处跳变。优点是形式简单、参数物理意义清楚、拟合稳定;缺点是零速不连续,直接丢进 ode45 会在零速附近反复穿越、步长被压到极小,仿真时间成倍增加。适合稳态摩擦特性绘制、参数辨识、不关心零速细节的场合。
tanh 平滑型把sgn(v)换成tanh(v/v_eps),v_eps是平滑带宽。好处是全域连续可导,数值求解器不会在零速处卡死;代价是丢掉了真正的静摩擦——零速时输出为 0 而不是Fs。做带位置保持的伺服仿真时这一点必须注意,否则你的系统会"自己滑走"。
Karnopp 模型走的是另一条路:设定一个零速判定带|v| < v_0,带内直接按静摩擦处理,用一个力的平衡判断是否起步。它能把静摩擦和粘滑切换都表达出来,但要处理状态判断,写起来啰嗦,且v_0选得不好会引入非物理的极限环。
LuGre 动态模型在 Stribeck 稳态曲线的基础上加了一个内部状态z描述鬃毛平均变形,能复现预滑移阶段的滞回和微位移下的非线性刚度。如果研究对象是微米级定位、需要关注换向时的位移滞后,只靠稳态 Stribeck 是不够的,必须上 LuGre 或 GMS。LuGre 的代价是多了两个参数(鬃毛刚度sigma0、微观阻尼sigma1),辨识难度和对初值的敏感性都上一个台阶。
多项式型在零速附近用低阶多项式拼接,好处是求导方便、便于做控制器设计时的线性化,坏处是拼接点不光滑、参数没有物理含义。
一份实用的选型对照:
| 使用场景 | 推荐写法 | 关键理由 |
|---|---|---|
| 绘制摩擦-速度特性曲线、教学演示 | 经典指数型 | 参数直观,曲线形状可控 |
| 闭环伺服仿真,需要长时间积分 | tanh 平滑型 | 零速连续,求解器不易卡步 |
| 位置保持、粘滑振动复现 | Karnopp 或 tanh + 静摩擦补偿项 | 需要明确的静摩擦区间 |
| 微米级定位、换向滞后分析 | LuGre / GMS | 需要预滑移滞回 |
| 摩擦前馈补偿的工程实现 | 经典指数型(离线算表) | 在线计算量小,可查表插值 |
多数工程仿真里,我一般会准备两个版本:辨识和画图用经典指数型保证参数干净,闭环仿真用 tanh 平滑型保证数值稳定,两者的Fs/Fc/Fv/vs/d完全共用一套。
2.3 参数从哪来:三种获取路径和它们的可信度
Fs、Fc、Fv、vs、d五个参数,来源无非三条路。
第一条是查样本和估算。导轨、丝杠的厂商样本一般会给动摩擦系数和静摩擦系数,乘上法向载荷就得到Fc和Fs的量级,Fv按润滑脂粘性粗估,vs按经验取 0.01~0.05 m/s,d先取 1。这条路的好处是十分钟就能让仿真跑起来,坏处是误差可能到 50% 以上,只能用来验证控制结构是否合理,不能用来下"补偿后能到多少精度"的结论。
第二条是准静态扫频实验。让执行机构以一系列恒定速度单向运动,每个速度点稳定后采集驱动力,减去惯性力和已知外载,剩下的就是摩擦力。速度点建议在低速段密、高速段疏,比如 0.01、0.02、0.05、0.1、0.2、0.5、1、2、5、10 mm/s 各采 2~3 秒取均值。正反两个方向分别采一遍,能顺带看出方向依赖的非对称性。
第三条是闭环辨识。给定控制器,让系统做正弦或扫频跟随,用输入输出数据通过最小二乘或智能优化算法反推参数。这条路的难点在于摩擦力和控制器输出、惯性力完全耦合在一起,必须先有一个足够准的动力学模型,否则辨识出来的摩擦参数会把模型误差一起吸收进去。
三条路的可信度是递增的,成本也是递增的。实际项目里比较稳妥的做法是:先用第一条路给出一组初值,用第二条路的数据做最小二乘拟合,把拟合残差控制在满量程摩擦力的 5% 以内再往下走。
3. Matlab 实现:一个可复用函数、一组默认参数、两种调用方式
代码部分按"能直接抄"的标准写。整个实现拆成三个文件:参数默认值函数、摩擦计算函数、被控对象导数函数。这样拆的好处是参数只在一个地方维护,仿真脚本、辨识脚本、Simulink 模块都能共用。
3.1 stribeck_friction.m:核心计算函数
function F = stribeck_friction(v, p) %STRIBECK_FRICTION 稳态 Stribeck 摩擦模型 % F = stribeck_friction(v, p) % v : 相对速度,标量或任意维数组,单位 m/s % p : 参数结构体,字段 Fs/Fc/Fv/vs/d/v_eps % F : 与 v 同尺寸的摩擦力,单位 N % % F(v) = Fc*s(v) + (Fs-Fc)*exp(-|v/vs|^d)*s(v) + Fv*v % 其中 s(v) = tanh(v/v_eps),v_eps 为 0 时退化为 sign(v) if nargin < 2 || isempty(p) p = stribeck_default_params(); end v = double(v); av = abs(v); % 零速邻域平滑:v_eps>0 用 tanh 过渡,否则用严格 sign if isfield(p, 'v_eps') && p.v_eps > 0 s = tanh(v ./ p.v_eps); else s = sign(v); end % 逐元素运算,保证 v 为矩阵时也能正确广播 stribeck = (p.Fs - p.Fc) .* exp(-(av ./ p.vs) .^ p.d) .* s; F = p.Fc .* s + stribeck + p.Fv .* v; end逻辑说明:先做参数缺省判断,再算|v|和符号项。符号项是唯一有分支的地方,v_eps > 0走tanh、否则退回sign,这样同一份代码既能画教科书上的理想曲线(v_eps = 0),也能直接喂给 ode 求解器(v_eps = 1e-4)。三项分别对应库仑项、Stribeck 衰减项和粘性项,全部用.运算符保证向量化,v传 2001 点的等距向量时一次算完,画图不用循环。
参数说明:v必须是 SI 单位 m/s,如果实验数据是 mm/s,调用前统一除以 1000。p.vs的量纲和v一致,p.d无量纲,p.Fv是 N·s/m。v_eps的取值建议是仿真中最小关注速度的 1/10 到 1/100,太小起不到平滑作用,太大会把真实的低速非线性抹平,一般 1e-4 到 1e-3 之间。
3.2 stribeck_default_params.m:把参数收在一处
function p = stribeck_default_params() %STRIBECK_DEFAULT_PARAMS 一组中等负载滑动导轨的量级参数 % 数值仅作仿真起点,实际项目必须用实测数据替换 p.Fs = 1.20; % 最大静摩擦力,N p.Fc = 0.85; % 库仑摩擦力,N p.Fv = 0.060; % 粘性阻尼系数,N·s/m p.vs = 0.012; % Stribeck 特征速度,m/s p.d = 1.0; % 形状指数,建议 0.5~2 p.v_eps = 1e-4; % 零速平滑带宽,m/s;置 0 退化为 sign end这里的数值是给中等负载滑动导轨的一个量级参考,Fs/Fc比值约 1.4,属于偏"干"的接触状态,润滑充分时这个比值会更接近 1.05~1.15。每次改参数只改这个文件,其他脚本用p = stribeck_default_params(); p.vs = 0.02;这种覆盖方式,避免同一批数字散落在十几个文件里——这一点吃过亏,后面在避坑章节还会提。
3.3 画曲线验证形状:三分钟确认参数没填反
p = stribeck_default_params(); % 低速段加密,才能看清负斜率 v = [-flip(linspace(0, 0.05, 1000)), linspace(0, 0.05, 1000)]; F = stribeck_friction(v, p); figure('Color', 'w'); plot(v * 1000, F, 'LineWidth', 1.6); hold on; yline(p.Fc, '--', 'Fc'); yline(-p.Fc, '--', '-Fc'); xline(0, ':', 'Color', [0.5 0.5 0.5]); grid on; box off; xlabel('速度 v (mm/s)'); ylabel('摩擦力 F (N)'); title('Stribeck 摩擦特性曲线');画出来应该看到:原点附近跳变到Fs,随速度绝对值增加迅速下凹到接近Fc,然后被粘性项缓慢抬起,整体关于原点奇对称。如果曲线是单调上升或者原点附近没有尖峰,多半是Fs < Fc或者v_eps给大了。这一步花三分钟,能挡掉后面几小时的困惑。
3.4 接进动力学:ode15s 求解质量-弹簧-摩擦系统
function dx = plant(t, x, p, c) %PLANT 单自由度质量-弹簧-阻尼 + Stribeck 摩擦 % x(1)=位移 m,x(2)=速度 m/s % c.m 质量 kg,c.c 阻尼 N·s/m,c.k 刚度 N/m,c.F 驱动力 N Ff = stribeck_friction(x(2), p); dx = [ x(2); (c.F - c.k * x(1) - c.c * x(2) - Ff) / c.m ]; endp = stribeck_default_params(); c = struct('m', 0.5, 'c', 2.0, 'k', 120, 'F', 1.0); opts = odeset('RelTol', 1e-8, 'AbsTol', 1e-10, 'MaxStep', 1e-3); [t, x] = ode15s(@(t, x) plant(t, x, p, c), [0 2.0], [0; 0], opts); figure('Color', 'w'); subplot(2,1,1); plot(t, x(:,1)*1000); ylabel('位移 (mm)'); grid on; subplot(2,1,2); plot(t, x(:,2)*1000); ylabel('速度 (mm/s)'); xlabel('时间 (s)'); grid on;逻辑说明:plant把摩擦力直接作为状态导数的一部分,没有引入额外的内部状态,所以这是纯稳态模型。求解器选ode15s而不是ode45,因为 tanh 平滑后系统在零速附近仍然接近刚性——摩擦力对速度的等效刚度可达Fs/v_eps量级,ode45会把步长压到 1e-9 以下,仿真几秒钟要跑几分钟。参数上,MaxStep限制在 1e-3 是为了不错过粘滑切换的细节,RelTol放到 1e-8 是因为位移量级只有毫米、速度量级只有毫米每秒,默认的 1e-3 相对误差会吃掉有效数字。驱动力取 1.0 N 略大于Fc而小于Fs,是为了让系统从静止起步后进入低速滑移,从而把爬行现象逼出来。
3.5 Simulink 里的 MATLAB Function 模块写法
模型结构不复杂:常值力源 → Sum → Gain(1/m) → Integrator → Integrator → 速度反馈回摩擦模块。摩擦模块用 MATLAB Function 模块,内容如下:
function F = fcn(v, Fs, Fc, Fv, vs, d) % 代码生成友好的写法:全部用标量输入,不用结构体和 isfield av = abs(v); s = tanh(v / 1e-4); F = Fc * s + (Fs - Fc) * exp(-(av / vs) ^ d) * s + Fv * v; end三个必须注意的点。一是不要在这个模块里用结构体,MATLAB Function 模块在代码生成时对结构体字段的动态访问支持有限,isfield这类判断在部分配置下会直接报错,全部展开成标量输入最稳。二是参数不要写死在函数体里,在基础工作区建Simulink.Parameter对象再连到模块输入端,改参数不用重新编译模型。三是零速平滑带宽1e-4是硬编码的,如果模型用定步长求解器(比如ode1步长 1e-3),这个带宽比步长还小,等于没平滑,此时要么把带宽放大到 1e-3 量级,要么改用变步长求解器。
4. 参数辨识实战:用 lsqcurvefit 从实测数据反推五个参数
有了模型和函数,下一步是让五个参数从数据里"长"出来,而不是拍脑袋。
4.1 数据预处理:把台架数据整理成速度和摩擦力两张表
前提是有准静态匀速实验数据。每个速度点采一段稳定区间,取均值和标准差,剔除标准差超过均值 10% 的坏点。正反行程分开存,先用正向数据拟合,再用反向数据验证,如果两向的Fc差超过 15%,说明机构存在明显的方向依赖,这时要么做成非对称模型(Fc+、Fc-分开),要么回去查装配。
数据处理脚本:
raw = readmatrix('friction_sweep.csv'); % 第1列速度 mm/s,第2列力 N v_mm = raw(:,1); F_N = raw(:,2); % 剔除反向行程与异常点 mask = v_mm > 0 & abs(F_N) < 10; v = v_mm(mask) / 1000; % 统一到 m/s F = F_N(mask); % 按速度排序,便于后面画残差 [v, idx] = sort(v); F = F(idx);单位统一是这一步唯一但最致命的动作。速度用 mm/s、力用 N 混着进拟合,最后出来的Fv会差三个数量级,模型在闭环里表现完全不对。
4.2 lsqcurvefit 拟合:初值、边界与多起点
% 待拟合参数向量 x = [Fs, Fc, Fv, vs, d] model = @(x, v) x(2) .* tanh(v/1e-4) ... + (x(1) - x(2)) .* exp(-(abs(v)./x(4)).^x(5)) .* tanh(v/1e-4) ... + x(3) .* v; x0 = [max(F)*1.05, min(F)*0.95, 0.05, 0.010, 1.0]; lb = [0, 0, 0, 1e-4, 0.5]; ub = [inf, inf, inf, 1.0, 2.0]; opts = optimoptions('lsqcurvefit', ... 'Display', 'iter', ... 'Algorithm', 'trust-region-reflective', ... 'MaxFunctionEvaluations', 3000, ... 'FunctionTolerance', 1e-12, ... 'StepTolerance', 1e-10); [xopt, resnorm, residual] = lsqcurvefit(model, x0, v, F, lb, ub, opts); fprintf('Fs=%.4f N Fc=%.4f N Fv=%.5f Ns/m vs=%.5f m/s d=%.3f\n', xopt); fprintf('RMSE = %.4f N\n', sqrt(mean(residual.^2)));逻辑说明:model是匿名函数形式的模型,参数顺序和x0严格对应,这里最容易错位的是把Fv和vs的位置搞反——错位后拟合照样收敛,但参数毫无意义,一定要打印出来和量级核对。x0的构造有讲究:Fs取实测力的最大值略放大,Fc取最小值略缩小,这两个初值基本靠谱;vs的初值用低速段中摩擦力衰减到(Fs+Fc)/2对应的速度估计,懒得估就取 0.01;d固定从 1.0 起步。
边界条件的作用:Fs ≥ Fc这个物理约束没法直接写成lb/ub,要靠初值和后面的校验保证;d限制在 [0.5, 2] 是防止拟合出 5 以上的形状指数,那种曲线在拟合区间内贴合、外推时完全失真。
trust-region-reflective算法要求残差个数不少于参数个数,这里十几个速度点对五个参数,满足条件。如果数据点少于 8 个,改用levenberg-marquardt,但要接受它更容易陷局部极小。
单次拟合很可能停在局部极小,尤其是vs和d的耦合方向。稳妥做法是撒一组初值做多起点:
best = struct('rmse', inf); for vs0 = [0.003 0.008 0.015 0.030] for d0 = [0.6 1.0 1.5] try [x, ~, r] = lsqcurvefit(model, [max(F)*1.05, min(F)*0.95, 0.05, vs0, d0], ... v, F, lb, ub, opts); rmse = sqrt(mean(r.^2)); if rmse < best.rmse best = struct('rmse', rmse, 'x', x); end catch continue; % 某些初值组合会发散,直接跳过 end end end xopt = best.x;十二次拟合通常十几秒跑完,比手工调初值省时间。try-catch不能省,边界附近偶尔会抛Local minimum possible之外的错误,一次异常不该中断整个搜索。
4.3 结果验证:残差图比 RMSE 更能说明问题
Ffit = model(xopt, v); figure('Color','w'); subplot(2,1,1); semilogx(v*1000, F, 'o', v*1000, Ffit, '-', 'LineWidth', 1.4); grid on; xlabel('速度 (mm/s)'); ylabel('摩擦力 (N)'); legend('实测','拟合','Location','southeast'); subplot(2,1,2); semilogx(v*1000, F - Ffit, 'o-'); grid on; yline(0, '--'); xlabel('速度 (mm/s)'); ylabel('残差 (N)');看三件事。第一,残差是否随速度出现系统性趋势,如果低速段残差普遍为正、高速段普遍为负,说明形状指数d没选对,曲线"弯"的程度不匹配。第二,残差绝对值是否小于满量程摩擦力的 5%,超了就别急着往下做补偿。第三,拟合出的vs是否落在实验速度点的覆盖范围内,如果vs落在了最小测试速度以下,说明数据对负斜率段根本没有约束,这个参数是"编"出来的,闭环里会出问题。
还有一步常被跳过:拿反向行程数据当验证集,不参与拟合,只看预测误差。两边误差都在可接受范围内,参数才算可信。
5. 避坑与排查:五个让仿真结果失真的细节
这一节全是踩出来的,按"现象 → 原因 → 解决"组织。
5.1 现象:仿真跑不动,oder45 步长被压到 1e-9
原因:用了严格sign版本的摩擦函数,系统在零速附近反复穿越,摩擦力在+Fc和-Fc之间跳变,求解器为了满足误差要求不断缩步。这在闭环位置保持仿真里几乎必然发生。
解决:把v_eps从 0 改成 1e-4 量级,或直接换ode15s并把MaxStep限制在 1e-3。如果必须保留理想静摩擦,用 Karnopp 的零速判定带替代sign,带宽取求解器步长对应的速度变化量的 2~3 倍。
5.2 现象:辨识残差很小,但换一组数据参数全变
原因:vs和d在拟合区间内高度相关,数据点又集中在高速段,低速负斜率段只有两三个点,参数不可辨识。残差小是因为模型在高速段被粘性项主导,低速段的形状怎么变残差都差不多。
解决:补低速实验点,在vs附近至少布 5 个点;拟合时固定d = 1.0,只放Fs/Fc/Fv/vs四个参数,稳定后再考虑放开d;或者对vs加一个弱的正则项,把解往物理合理区间拉。
5.3 现象:Simulink 仿真结果和 m 脚本对不上
原因:多半是单位或者求解器设置不一致。脚本里v是 m/s,Simulink 里某个 Gain 忘了换算;脚本用ode15s变步长,Simulink 用定步长ode1且步长 1e-3,而v_eps只有 1e-4,平滑完全失效。
解决:在 Simulink 模型里显式标注每个信号的单位,速度信号进摩擦模块之前加一个单位换算的注释块;把v_eps设成不小于求解器步长对应速度变化的量级,定步长 1e-3 时v_eps至少给 1e-3。
5.4 现象:位置保持工况下,系统缓慢"漂移"
原因:用了 tanh 平滑版本,零速时tanh(0) = 0,摩擦力输出为 0,静摩擦被彻底抹掉了。系统在零速附近没有任何阻力矩,积分器上的微小残差会让位置慢慢滑走。
解决:位置保持场景不能只用平滑版。要么改成 Karnopp 结构,在|v| < v_0时按静摩擦做力平衡判断;要么在平滑版基础上叠加一个零速保持项,当|v| < v_0且外力小于Fs时输出等于外力反向。这一点没得绕。
5.5 现象:模型在台架上验证通过,换一台同型号设备就失效
原因:摩擦参数是装配预紧、润滑状态、表面粗糙度的函数,同型号设备的Fs差异可以到 30%。把一台设备辨识出的参数当"型号参数"用,必然翻车。
解决:参数按单机管理,每台设备建一份参数文件,标定流程固化成脚本;控制算法里给Fs/Fc留 20%~30% 的在线自适应余量,或者用低速段的跟踪误差做慢速在线修正。别指望一套参数通吃。
6. 进阶用法:把摩擦模型接进前馈补偿,附一份验证清单
模型算得准只是前提,真正产生价值的是拿它去做补偿。思路很直接:既然F(v)能算,那就在控制量里预先加上同样大小的力,把摩擦"顶掉"。
function u = control_with_friction_ff(v_ref, u_pid, p, alpha) %CONTROL_WITH_FRICTION_FF 带摩擦前馈补偿的控制量 % v_ref : 参考速度,m/s % u_pid : 反馈控制器输出,N 或 A % alpha : 补偿系数,0~1,工程上常取 0.6~0.8 F_ff = stribeck_friction(v_ref, p); u = u_pid + alpha * F_ff; endalpha不取 1 是有原因的。前馈力完全等于模型输出时,一旦参数偏大,系统会在换向瞬间被"推过头",产生反向的超调;取 0.6~0.8 相当于留了一条退路,让反馈环还有活干。另外v_ref在零速附近符号会抖,直接用会让前馈力来回跳,常见做法是给v_ref加一个一阶低通(截止频率 20~50 Hz),或者在前馈通道里对F_ff做速率限幅。
验证环节比补偿本身更容易被糊弄过去。我习惯按下面这张表逐项走,每项都有明确的判据,不看"感觉好多了"。
| 验证项 | 做法 | 通过判据 | 常见异常 |
|---|---|---|---|
| 曲线形状 | 画v ∈ [-50, 50]mm/s 的 F-v 曲线 | 原点有尖峰,低速有负斜率,高速线性上升 | Fs < Fc,或曲线单调 |
| 参数物理性 | 打印五个参数并与样本量级比对 | Fs/Fc在 1.05~1.5,vs在 1~50 mm/s | vs小于最小测试速度 |
| 拟合残差 | 残差-速度图 | 无系统趋势,绝对值 < 满量程 5% | 低速正、高速负 →d偏小 |
| 开环爬行复现 | 恒力驱动,力介于Fc与Fs之间 | 速度曲线呈台阶状,台阶周期与台架同量级 | 完全平滑 → 静摩擦被抹掉 |
| 补偿前后对比 | 0.5 mm/s 匀速跟随,比较位置误差峰峰值 | 补偿后峰峰值下降 40% 以上 | 下降不足 →alpha太小或vs偏大 |
| 换向死区 | 正弦 0.1 Hz 跟随,看过零附近误差 | 死区宽度缩小,无新增超调 | 出现反向超调 →alpha偏大 |
表里最容易出问题的是"开环爬行复现"这一项。很多人的模型参数是从样本上抄的,曲线画出来漂亮,但一跑恒力驱动就是平滑的指数趋近,根本没有台阶——这说明Fs/Fc比值给得太小,或者v_eps太大把负斜率段抹平了。爬行复现不出来,后面的补偿效果就无从对比,整个验证链条断在第一环。
还有一个我后来固定加上的动作:把辨识出的参数、拟合残差、验证曲线一起写进一个friction_calib_YYYYMMDD.mat,和当次的实验数据放在同一个目录。原因是三个月后回头查"当时为什么把vs定成 0.018",光看代码里的数字根本想不起来,有这份存档才能复盘。同一个项目里换过三次参数、每次都没留档,最后只能重新做一遍扫频实验,那个下午的教训记到现在。从那以后我每次改摩擦参数,都强制走一遍"拟合 → 残差图 → 爬行复现 → 存档"这四步,一步不跳。希望帮到你。
本文还有配套的精品资源,点击获取