☰
任意初始状态下的迭代学习控制:从初值漂移到遗忘因子
2026/10/22 3:33:10 网站建设 项目流程

简介:面向迭代学习控制(ILC)研究者和控制工程师,该压缩包围绕“任意初始状态下的迭代学习控制”问题,提出一种适用于线性时不变系统的新型ILC方案,克服了传统方法对初始条件固定的依赖,可在不同起始条件下逐步优化控制输入并提高重复任务中的跟踪精度与鲁棒性。包内共3个文件,含2个MATLAB脚本和1个Word算法说明文档,rar压缩后仅10KB,轻量但覆盖了从理论推导、算法设计到仿真验证的完整流程。已有344人学习浏览,对于正在探索非固定初始状态ILC算法的读者,是一份可直接参考的示例。算法说明文档详细给出了控制律更新规则、误差收敛分析及稳定性讨论;配套代码分别对应控制器实现与线性时不变被控对象模型,可直接运行并观察不同初始状态下的迭代收敛过程,也为实际系统改造提供了可扩展的算法起点。

1. 任意初始状态下的迭代学习控制:从"每次必须从零开始"到"从哪开始都能学"

迭代学习控制(ILC)是处理重复运动任务最直接的一种控制方案:同样的轨迹、同样的系统、反复跑,每次根据上一次的误差修正控制输入,多跑几次就能把跟踪误差压下去。机械臂重复抓放、批量注塑温控、工业转台往复运动,都能看到它的影子。但经典ILC有一个不太起眼的隐含前提——每次开始前,系统必须回到同一个初始状态,否则理论推导里的误差收敛性就会被打折扣。实际产线上,启停位置漂移、换料碰撞、传感器回零偏差,都会让初始状态"每次都不一样"。这篇文章按工程落地的顺序,把任意初始状态下的迭代学习控制拆开讲:为什么初值漂移会让经典ILC失效、有哪些修正方案、参数怎么调、实际调试中会踩哪些坑。

2. 迭代学习控制为什么怕"初始状态漂移":问题建模与收敛条件

在动手写代码之前,先把数学模型立起来。这一章的内容决定了后面所有参数选择的依据,也解释了为什么"任意初始状态"会让教科书里的收敛结论失效。

2.1 lifted域建模:把迭代学习变成矩阵迭代

我分析ILC问题时习惯先做一次lifted变换,把所有时间点上的输入输出堆成一个大向量,让系统变成一个纯粹的矩阵乘法。这是理解ILC收敛性最直观的入口,也是后面推导初始状态影响的数学基础。

考虑一个离散线性时不变系统:

x(t+1) = A x(t) + B u(t) y(t) = C x(t)

其中x是n维状态,u和y是标量输入输出。假设每次迭代跑N个时间点,把输入序列u(0),u(1),...,u(N-1)堆成向量U,输出序列y(1),y(2),...,y(N)堆成向量Y,就可以把系统写成:

Y = G·U + D·x(0)

G是N×N的下三角矩阵,由马尔可夫参数构成,表示每个时刻的输入对未来输出的影响;D项把初始状态对输出序列的贡献单独摘了出来。下面这段Python代码可以快速构建这个lifted模型:

import numpy as np def build_lifted(A, B, C, N): """ 构建离散LTI系统的lifted矩阵G和初始状态贡献矩阵D A: 状态矩阵 (n×n) B: 输入矩阵 (n×1) C: 输出矩阵 (1×n) N: 迭代时域长度 """ n = A.shape[0] G = np.zeros((N, N)) D = np.zeros((N, n)) # G[i, j] = C @ A^(i-j-1) @ B,当 i > j # 对应第j个输入u(j)对第i+1个输出y(i+1)的影响 for i in range(N): for j in range(i): power = i - j - 1 G[i, j] = C @ np.linalg.matrix_power(A, power) @ B # D[i, :] = C @ A^(i+1),对应初始状态x(0)对y(i+1)的贡献 for i in range(N): D[i, :] = C @ np.linalg.matrix_power(A, i + 1) return G, D

逻辑说明:G矩阵的下三角结构由因果性决定——当前时刻的输出只受当前及之前输入的影响,所以上三角全是零。第(i,j)个元素表示第j个控制量对第i+1个输出采样的单位脉冲响应,这正是马尔可夫参数。D矩阵计算的是初始状态自由运动项,如果不把它单独摘出来,初始状态变化对输出的影响就会和输入的影响混在一起,后面分析收敛性时说不清楚。

参数说明:A矩阵维度n×n对应系统阶数,一阶系统n=1时G的对角线就是CB,这是最常用来估算学习增益上限的量。N的选择取决于期望轨迹长度和采样周期,N太短会截断系统动态,N太长则lifted矩阵规模变大,仿真耗时增加但对收敛性分析没有本质影响。

2.2 固定初始状态下的经典收敛条件

在经典ILC框架里,一个默认假设是每次迭代初始状态相同,通常取x(0)=0。这样D·x(0)项为零,迭代学习律的分析就干净了。最常见的P型学习律写成:

u_{k+1}(t) = u_k(t) + Γ·e_k(t+1)

其中e_k(t)=y_d(t)-y_k(t)是第k次迭代的跟踪误差,Γ是学习增益。注意这里用的是e(t+1)而不是e(t),因为u(t)最早只能在y(t+1)上体现,这是因果性的要求,新手写ILC代码最容易在这里出错。

把学习律代入lifted模型,得到误差递推关系:

E_{k+1} = (I - G·Γ_lifted)·E_k

其中Γ_lifted是学习增益在对角线上的块矩阵。收敛的充要条件是矩阵(I-G·Γ_lifted)的谱半径小于1。对于单输入单输出系统、学习增益为常数Γ时,这个条件退化为一个简洁的不等式:

|1 - Γ·(C·B)| < 1

也就是0 < Γ·CB < 2。这个式子看起来简单,但它的意义重大:收敛性只取决于系统的相对阶和首个马尔可夫参数,与期望轨迹的具体形状无关。我调试时优先用这个式子估算Γ的取值范围,再往中间取,而不是盲目试。

下表对比了三种常见学习律在固定初始状态假设下的收敛特性和使用成本:

学习律形式收敛条件需要的模型信息工程使用频率
P型:u_{k+1}=u_k+Γe(t+1)|1-ΓCB|<1只需CB最高
D型:u_{k+1}=u_k+Γė(t+1)需分析G与微分算子的组合需要相对阶知识较低
高阶:u_{k+1}=Σa_i·u_{k-i}+Γe(t+1)谱半径条件更复杂需要多个历史迭代数据低

P型之所以最常用,是因为它对模型信息的需求最小——只知道首脉冲响应系数CB就能定出Γ的范围,这对工程调试非常友好。高阶ILC收敛速度理论上更快,但对噪声更敏感,参数也多,除非有特殊性能要求,我一般不会首推。

2.3 初始状态偏移时,误差为什么会残留

现在把初始状态的约束放开。假设第k次迭代的初始状态是x_k(0),它自由运动对输出的贡献为D·x_k(0)。这时误差递推关系变成:

E_{k+1} = (I - G·Γ)·E_k + D·(x_k(0) - x_{k+1}(0))

等号右边多了一项。即便(I-G·Γ)谱半径小于1,只要前后两次迭代的初始状态存在差异,就会有新的扰动注入误差。如果初始状态是随机漂移的,稳态误差的期望下界与D的范数和初始状态方差成正比,数学上可以算出来,但工程上更常见的表现是:误差曲线下降到一定程度后就不再下降,而是在某个带宽内波动。

更隐蔽的一种情况是初始状态偏移呈现固定偏差,比如每次启动都偏0.05。这时候误差递推方程里等效于叠加了一个常值激励,稳态误差会收敛到一个非零常数。直观表现就是输出轨迹和期望轨迹之间永远隔着一层"贴不上去"的偏差,位置大约在轨迹的起始段最明显。

我自己调试中见过最多的情况就是第三种:仿真里初始状态清零,迭代30次误差降到1e-4,效果完美;一上实物台架,每次启动的位置都有零点几个毫米的偏差,误差曲线降到0.02就再也下不去了。这就是初始状态项在作怪,跟学习律收敛性没有关系,需要换方案。

3. 任意初始状态下的三类修正方案:选型逻辑与适用边界

明确了问题来源,这一章讲怎么改。三类方案分别从"初值可学习""遗忘旧数据""抑制扰动"三个角度切入,适用场景差别很大,选错方案的代价通常是浪费大量调参时间。

3.1 方案一:初始状态学习律,把初值也"学"出来

最常见的做法是在原有ILC外面套一层初始状态学习律。每次迭代结束后,不仅更新输入序列,还更新下一次迭代的初始状态设定值:

x_{k+1}(0) = x_k(0) + β·(x_d(0) - x_k(0))

同时输入序列仍然按标准P型学习律更新。x_d(0)是期望轨迹起点对应的状态值,β是初始状态学习增益。注意,如果x_d(0)就等于期望轨迹的第一个点,这个方案的效果就是让每次迭代的初始状态不断逼近期望起点,最终恢复到经典ILC的收敛轨道上。

def update_initial_state(x0_current, x0_desired, beta, lower, upper): """ 初始状态学习律更新 beta: 学习增益, 典型范围 (0, 2) lower/upper: 物理约束下界/上界, 超出时截断 """ x0_next = x0_current + beta * (x0_desired - x0_current) # 物理约束截断: 比如伺服有软限位 x0_next = np.clip(x0_next, lower, upper) return x0_next

参数说明:β和ILC学习增益Γ一样,不能取太大。β接近0时收敛极慢,接近2时可能振荡甚至发散。工程上我一般取0.3到0.8之间,具体要看初始状态的可控精度。

这个方案有一个硬前提:系统必须允许外部设定初始状态。伺服电机可以在每次启动前走到指定的示教位置,温控系统可以预加热到指定初温,这类场景适用。但如果系统启动位置被机械硬限位强制固定,或者物理上无法主动调整初始状态,这个方案就用不了——没有可操控的入口,一切白搭。

3.2 方案二:带遗忘因子的P型学习律,用数据遗忘换鲁棒性

这是工程上改动最小、适用面最广的一种方案。把标准P型学习律改成:

u_{k+1}(t) = (1 - α)·u_k(t) + Γ·e_k(t+1)

α是遗忘因子,取值通常在0到0.3之间。α=0时退化为标准P型;α越大,每次迭代对旧输入的"记忆"越少。直观理解是:初值偏移导致旧输入中累积了一部分针对旧初始状态的修正量,遗忘因子把这些过时的修正量按比例洗掉,避免它们和当前初值不匹配而持续产生误差。

遗忘因子的引入是有代价的。收敛后跟踪误差不再趋近于零,而是收敛到一个与α成正比的稳态带。下面这组经验关系可以帮你在选型时建立直觉:

遗忘因子α收敛速度稳态误差对初值偏移的鲁棒性典型场景
0(纯P型)最快理论为零,实际有偏差差仿真验证、精确复位场景
0.05~0.1较快小,约为期望幅值的1%~5%中大多数工业重复运动
0.2~0.3较慢明显,5%~10%好初值漂移大、复位精度差
>0.5很慢很大,失去ILC意义很强基本不使用

我一般建议从α=0.05起步。如果误差曲线在迭代后期出现明显的周期性波动(说明旧数据在捣乱),再逐步加大到0.1或0.15。不要一上来就设0.3,那等于主动放弃ILC的高精度优势。

3.3 方案三:滑模ILC或自适应ILC,对模型不确定性的兜底

当系统本身非线性明显,或者模型参数随时间漂移时,前两种方案可能都不够稳。这时常见做法是改用滑模ILC,把学习律中的线性误差项换成饱和函数形式:

u_{k+1}(t) = u_k(t) + Γ·sat(e_k(t+1)/φ)

其中sat是标准饱和函数,当|z|≤1时sat(z)=z,否则sat(z)=sign(z)。φ是边界层厚度。滑模项的设计思想是把初值偏移和外部扰动视为有界扰动,符号函数可以对这些扰动保持鲁棒性,而饱和函数的存在是为了避免理想滑模带来的抖振。φ取得太小,抖振明显;φ取得太大,滑模特性消失,退化成普通P型。

自适应ILC则是每一步在线估计系统参数或学习增益,理论上更强大,但对实时计算量和激励条件有要求,工程实现复杂度高。我的经验是:优先用遗忘因子方案,压不住再考虑滑模ILC;自适应ILC除非课题需要,否则不建议在产线上贸然尝试,调参周期可能比省下来的迭代次数更长。

4. 在MATLAB里搭一个任意初始状态ILC仿真:从系统方程到学习律落地

这一章直接给一套可以抄作业的仿真代码。用MATLAB是因为控制领域调试ILC时MATLAB最顺手,而且代码转成Simulink也容易。系统选一阶惯性加延迟模型,简单到能手工验算收敛条件,又能清晰暴露初值偏移的问题。

4.1 系统与期望轨迹设定

选一个离散一阶惯性系统:

x(t+1) = 0.8·x(t) + 0.4·u(t) y(t) = x(t)

这个系统CB=0.4,按P型收敛条件|1-0.4Γ|<1,Gamma必须小于5。期望轨迹用慢变正弦,从0开始,N=100步。初始状态不再是定值,而是服从均值为0.1、标准差为0.05的随机分布——这就是"任意初始状态"的最小模拟。均值为0.1意味着平均来说初始状态偏离期望起点10%的幅值,足够让纯P型ILC看出问题。

% 任意初始状态ILC仿真 - 一阶惯性系统 % 系统: x(t+1) = 0.8x(t) + 0.4u(t), y(t) = x(t) % 学习律: P型 + 遗忘因子 clear; clc; % ---- 系统参数 ---- A = 0.8; B = 0.4; C = 1; % 一阶SISO系统 N = 100; % 迭代时域长度 T = 0:N-1; % 时间轴 % ---- 期望轨迹: 慢变正弦, 起点为0 ---- yd = 0.3 * sin(2 * pi * T / 60); % ---- 迭代学习参数 ---- Gamma = 0.6; % 学习增益: 0.6*0.4=0.24, 远离边界2 alpha = 0.1; % 遗忘因子 Kmax = 60; % 最大迭代次数 % ---- 初始状态分布 ---- x0_mean = 0.1; x0_std = 0.05; % ---- 初始化存储空间 ---- u_k = zeros(1, N); % 初始输入序列 err_max = zeros(1, Kmax); % 最大绝对误差记录 err_rms = zeros(1, Kmax); % 均方根误差记录

这段是初始化部分。Gamma=0.6对应的CB乘积是0.24,离收敛边界|1-0.24|<1还有很大裕量,既保证收敛速度又不会出现前几次迭代的大幅振荡。alpha取0.1是为应对随机初值。如果alpha=0,等会你会看到误差曲线降到某个水平后开始震荡,这就是初值偏移没有被抑制的直接证据。

4.2 学习律更新与迭代主循环

主循环是ILC的核心。外层按迭代次数走,内层按时间轴跑被控对象。顺序不能乱:先跑系统得到输出,再算误差,最后更新输入。

% ---- 迭代主循环 ---- for k = 1:Kmax % 1. 生成随机初始状态: 每次迭代都不一样 x0 = x0_mean + x0_std * randn(); % 2. 运行被控对象, 得到输出轨迹 x = zeros(1, N+1); x(1) = x0; u = u_k; for t = 1:N x(t+1) = A * x(t) + B * u(t); end y = x(2:end); % y(1)对应t=1, 共N个点 % 3. 计算跟踪误差 e = yd - y; err_max(k) = max(abs(e)); err_rms(k) = sqrt(mean(e.^2)); % 4. 学习律更新: P型 + 遗忘因子 % 注意e(2:end)对齐u(t): u(t)对应修正e(t+1) u_next = (1 - alpha) * u_k + Gamma * [e(2:end), 0]; u_k = u_next; end % ---- 绘图 ---- figure; subplot(2,1,1); plot(T, yd, 'k--', T, y, 'r-', 'LineWidth', 1.5); xlabel('时间t'); ylabel('输出y'); legend('期望轨迹', '第60次迭代输出'); title('最终迭代跟踪效果'); subplot(2,1,2); semilogy(1:Kmax, err_max, 'b-', 1:Kmax, err_rms, 'r-'); xlabel('迭代次数k'); ylabel('误差'); legend('最大绝对误差', '均方根误差'); grid on;

逻辑说明:第2步先跑系统是ILC的基本顺序——用上一轮更新好的输入去跑新一轮对象,拿到真实输出才能算误差。第4步中[e(2:end), 0]是时间对齐的关键代码。对于一阶系统,u(t)要到y(t+1)才能体现,所以修正u(t)应该使用e(t+1)。向量末尾补零是因为e(N+1)不存在,表示最后一个控制量在这一轮不做修正,下一轮自然会被后续误差带出来。

参数说明:randn()每次生成不同的随机初值,模拟实际系统的不可控漂移。如果想把问题调得更尖锐,可以固定随机种子或用固定偏移量,比如x0=0.15,观察纯P型(alpha=0)时的误差残留。err_rms和err_max同时记录,是为了后面判断收敛是否"真实"——最大值进入稳态带但均方根还在下降,说明还有局部误差可以继续优化。

4.3 参数整定的经验法则与对比实验

把上一节的仿真跑一遍,你会看到两条误差曲线先快后慢地下降,最终稳定在某个量级。现在做对比实验,把alpha改成0,其他参数不变,重跑一次。结果通常是:误差先快速下降,然后开始在一个平台上不规则波动,再也压不下去。这个波动就是初始状态每轮注入的随机扰动,遗忘因子alpha=0时没有任何机制去衰减它。

% 对比不同遗忘因子在随机初始状态下的收敛行为 alpha_list = [0, 0.05, 0.1, 0.3]; colors = {'r', 'b', 'g', 'm'}; figure; hold on; for idx = 1:4 alpha = alpha_list(idx); u_k = zeros(1, N); err_tmp = zeros(1, Kmax); for k = 1:Kmax x0 = x0_mean + x0_std * randn(); x = zeros(1, N+1); x(1) = x0; for t = 1:N x(t+1) = A * x(t) + B * u(t); end y = x(2:end); e = yd - y; err_tmp(k) = max(abs(e)); u_next = (1 - alpha) * u_k + Gamma * [e(2:end), 0]; u_k = u_next; end semilogy(1:Kmax, err_tmp, colors{idx}, 'LineWidth', 1.5); end hold off; xlabel('迭代次数'); ylabel('最大绝对误差'); legend('alpha=0', 'alpha=0.05', 'alpha=0.1', 'alpha=0.3'); grid on;

我调参数时的一般顺序:先alpha=0跑一遍,确认系统本身收敛、只是后期波动。然后alpha从0.05开始逐步增加,每加一档重跑一次,观察两个指标——前期收敛速度是否可接受、后期波动是否被压住。alpha=0.1到0.15之间通常能找到一个同时满足二者的平衡点。不要追求alpha把波动完全抹掉,那会牺牲太多稳态精度。

5. 任意初始状态ILC的常见坑与排查:从迭代发散到稳态误差

这一章写我调试ILC时踩过、也看别人踩过的坑。每一条都按现象、原因、解决的顺序展开,可以直接当排查手册用。

5.1 坑一:初始状态偏移大但学习增益偏小,前几次迭代剧烈波动甚至发散

现象:前3到5次迭代,误差不降反升,最大误差一度超过初始误差的好几倍,之后才慢慢收敛;严重时直接发散,整个输出轨迹飞掉。

原因:任意初始状态下,第一轮的误差里有很大一部分来自初始状态自由运动,而不是控制输入不当。学习增益Γ偏小时,修正量不足以抵消初值偏差带来的输出偏离,二者叠加产生一种"先学歪再慢慢学回来"的过冲。这其实是ILC的固有学习过程,但初值偏移会把前期的过冲放大好几倍。

解决:分段学习增益——前3次迭代用正常增益的一半甚至三分之一,先把初值造成的偏差"磨"掉一部分,再切换到正常增益。另一种做法是直接用带遗忘因子的学习律起步,让旧数据从一开始就不参与累积。注意观察前几次迭代的误差方向,如果始终朝向初值偏移的方向,说明是初值主导,不是增益问题。

5.2 坑二:遗忘因子加得过大,稳态误差明显偏高

现象:误差曲线下降速度很快,但很快就平了,稳态误差比alpha=0时的波动下界还高。输出轨迹和期望轨迹之间始终有一条明显的缝隙,尤其在轨迹前半段。

原因:遗忘因子在抑制旧数据的同时,也在遗忘正确的学习成果。alpha=0.3时,即使当前输入已经很接近理想值,每次迭代也会被强制抹掉30%,这等于给系统加了一个持续的"削弱力",最后收敛的平衡点必然偏离零误差。

解决:把alpha从0开始按0.02的步长往上加,每次重跑仿真,找到"误差波动恰好被压下但稳态误差不明显上升"的临界值。工程上alpha=0.1附近通常是这个平衡点,但系统不同、期望轨迹不同,建议每次都实际验证,不要照搬经验值。

5.3 坑三:测量噪声被学习律放大,迭代后期输出越学越抖

现象:第30次迭代以后,输出轨迹上开始出现高频锯齿状抖动,误差曲线呈锯齿形下降停滞。把输入序列单独画出来,能看到高频分量明显被放大了。

原因:ILC本质是把误差沿迭代轴积分到输入上。误差里混入测量噪声后,学习律无法区分噪声和真实跟踪误差,于是把噪声也"学"进了输入。迭代次数越多,输入里的噪声累积越多。这个问题在任意初始状态下更容易暴露,因为随机初值本身就相当于注入了一部分等效噪声。

解决:三选一。第一,dead-zone学习律,误差绝对值小于阈值时不更新输入;第二,对误差信号在时间轴上做滑动平均滤波,把高频噪声先滤掉再进学习律;第三,批次方向低通滤波,这是下一章会细讲的技巧。我用得最多的是dead-zone加批次方向滤波的组合,简单有效,也不引入明显延迟。

5.4 坑四:只盯最大绝对误差提前收工,实际拐点处严重过冲

现象:最大绝对误差已经进入稳态带,看起来"收敛了",但把输出轨迹和期望轨迹叠在一起看,在期望轨迹的拐弯处有一个明显的凸起,持续一两拍后消失。

原因:最大绝对误差是单点指标,丢失了误差的空间分布信息。ILC收敛后残余误差通常集中在期望轨迹曲率大、加速度要求高的区段——这些地方系统的惯性滞后最难补偿。只盯最大值会误判,因为峰值可能出现在初值影响最明显的区段,而真正需要关注的轨迹拐点反而被掩盖。

解决:每次迭代同时记录最大绝对误差和均方根误差两个指标。只有两者都进入稳态带,才算真正收敛。另外,可以定期把误差曲线本身存下来,和期望轨迹的导数叠在一起看(这就是最后一章的过零分析技巧)。

5.5 坑五:仿真里初值设为零,参数选得再好,实物上直接翻车

现象:仿真里ILC收敛完美,误差降到1e-4,换到实物上迭代二十次之后误差停在1e-2量级,怎么调都降不下去。

原因:仿真里的理想条件(初值严格为零、无噪声、模型精确)掩盖了任意初始状态ILC的两个核心挑战:初始状态的随机漂移和模型不确定性。你把所有参数都按"初值零"来选定,遗忘因子为零、学习增益贴着收敛边界取,结果就是一上实物就暴露问题。

解决:仿真阶段就把初始状态设置成带噪声的随机变量,噪声幅值按实际系统复位精度的量级来给。比如伺服系统的复位精度是0.1毫米,那初值偏差的标准差就设成对应的状态量。这样仿真出来的参数直接搬到实物上,即使不完全匹配,至少不会差到无法收敛。

6. 用批次方向滤波和变增益把任意初始状态ILC调得更稳:几个上手就能用的技巧

最后一章落在具体技巧上。这三个技巧不需要改动学习律的根本结构,纯属参数和信号处理层面的增强,但往往能把"能收敛"变成"收敛得快且稳"。

6.1 技巧一:批次方向低通滤波,专治噪声放大

ILC的更新过程沿迭代轴推进,噪声和真实误差在迭代轴上的"频率特征"是不同的。真实跟踪误差随迭代次数增加而单调下降,而测量噪声在迭代轴上近似白噪声。用一阶低通滤波沿迭代轴做平滑:

u_{k+1}(t) = (1 - λ)·u_{k+1,raw}(t) + λ·u_k(t)

λ是批次方向滤波系数,典型取0.3到0.5。u_{k+1,raw}是学习律算出的原始更新值,u_k是上一轮输入。这个滤波的本质是对输入序列做迭代轴上的指数平滑,让每次更新的步伐变缓,噪声在迭代轴上的累积被显著抑制。代价是收敛速度略有下降,但相比于反复调Gamma解决抖振,这个代价很值得。

6.2 技巧二:变学习增益,前期大增益快速收敛,后期小增益抑制抖振

固定增益Gamma需要在快速收敛和后期稳定之间做取舍。一个几乎零成本的优化方案是让增益随迭代次数线性递减:

Gamma_k = Gamma_max - (Gamma_max - Gamma_min)·(k / Kmax)

前20次迭代用比较大的Gamma,比如0.8,快速跨越初始大误差阶段;后20次迭代逐步降到0.3,减小在误差已经很小时对噪声的敏感性。这个方案对任意初始状态ILC特别友好,因为前期的初值误差需要大的修正力度,后期的稳态带需要小的修正步长,两者天然冲突,变增益是化解冲突最直接的办法。

6.3 技巧三:误差过零分析,判断收敛是否还有下降空间

调试时把最终的一帧误差曲线和期望轨迹的导数叠在一起看,观察误差峰值相对轨迹峰值的位置。如果误差在轨迹的拐弯处(加速度最大处)达到峰值,说明误差主要是惯性滞后造成的,理论上还能通过加大学习增益或延长迭代次数进一步压制;如果误差峰位和期望轨迹的峰值同位,说明是相位延迟型误差,根源在初始状态偏移或系统相位特性,此时继续迭代意义不大,应该回头调遗忘因子或检查初值设定。

这个技巧不算严格的理论方法,更像一个经验判据,但非常省时间。我调ILC的习惯是每轮迭代都把误差曲线存下来,而不是只看收敛曲线。有一次迭代次数已经跑满,最大误差和均方根误差都平了,但我把误差曲线叠在期望轨迹导数上看,发现所有误差峰都落在加速度峰值的位置,于是把Gamma调大一档,又压下去近一半误差。从那以后,这个习惯就保留下来了。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询