跳到正文
格致开物MATHWIKI

自适应控制

自适应控制在系统运行中利用观测到的数据调整控制器参数,使未知或变化的动力学仍能满足一定的控制目标。它与离线先估计一个模型再固定控制器不同:状态、控制和参数更新相互作用,必须一起分析稳定性。

最基本的问题不是“参数最后是否看起来接近真实值”,而是闭环信号是否有界、跟踪误差是否收敛,以及证明依赖什么条件。本条用一个未知常数系数的一阶系统,逐步构造模型参考自适应控制律。

未知参数与参考模型

实际系统为 x˙=ax+u, 其中未知的 a 是有限常数,状态 x 可以准确测得,输入系数已知且为一。给定有界、分段连续的参考输入 r(t),希望状态跟随稳定参考模型 x˙m=−xm+r. 参考模型的显式解为 xm(t)=e−txm(0)+∫0te−(t−s)r(s)ds. 因此有界参考输入会产生有界参考状态。

若已知 a,取 u=−ax−x+r,则实际系统正好满足参考模型的同一方程。未知时,用在线估计 â(t) 代替: u=−âx−x+r. 定义跟踪误差和参数误差 e=x−xm,a~=â−a. 代入两条状态方程,有 e˙=−e−a~x. 第一项会使误差衰减,第二项来自参数不准确。如何更新估计,正要针对这一项设计。

从李雅普诺夫函数构造更新律

选定学习率 γ>0,考虑 V=12e2+12γa~2. 它同时衡量跟踪误差和参数误差。因为 a 是常数,所以 a~˙=â˙,于是 V˙=e(−e−a~x)+a~γâ˙=−e2+a~(−ex+â˙γ). 把更新律选为 â˙=γex, 交叉项正好消去,得到 V˙=−e2≤0。更新律的正号来自这里的误差定义;若改用 xm−x 定义误差,必须相应改号。

这种借助参数误差项消去交叉项的方法,是模型参考自适应控制的典型构造。更一般系统的增益符号、参数化方式与稳定性条件见Yang的自适应控制讲义。[1]

有界性与跟踪误差收敛的证明

由 V(t)≤V(0),误差 e 与参数误差 a~ 有界。真实参数为有限常数,故 â 也有界。参考状态有界,因而 x=e+xm 有界。控制公式表明 u 有界;在有限初值下,这些界也排除了该闭环多项式微分方程的有限时间逃逸。

沿轨迹积分可得 ∫0∞e(t)2dt≤V(0). 单凭平方可积,尚不能排除越来越窄的误差尖峰。这里还有 e˙=−e−a~x 有界,故存在有限 M 使 |e˙|≤M。

若 M=0,误差恒定,平方可积迫使其为零。若 M>0 且误差不趋于零,则存在 ε>0 和趋于无穷的时刻序列,使 |e(tj)|≥ε。由导数界,在每个 tj 附近一段长度至少 ε/(2M) 的单侧区间内,误差绝对值至少为 ε/2。可选取互不相交的无穷多个这种区间,迫使误差平方积分无穷大,矛盾。因此 limt→∞e(t)=0. 这个证明说明,在上述理想模型和有界参考条件下,未知常数参数不会阻止渐近跟踪。

数值案例与复算

取真实系数 a=2、参考 r(t)=1、学习率 γ=2,初值为 x(0)=14,xm(0)=0,â(0)=0. 参考模型解为 xm(t)=1−e−t。闭环的实际状态导数为 x˙=(1−â)x+1. 初时状态导数为 1.25,参考状态导数为一,误差导数为 0.25;更新率为 2(1/4)2=1/8。这些初始值可用于检查程序是否把参数更新的符号写反。

自适应闭环实际状态与参考状态的时间轨迹,初期有偏差,之后逐渐重合
曲线由文中三维常微分方程采用四阶Runge–Kutta积分得到,步长零点零零二。数值轨迹说明本例,渐近结论由前面的证明保证。

初始李雅普诺夫值为 V(0)=12(14)2+(0−2)24=3332. 因此 ∫0∞e2dt≤33/32,且参数估计始终满足 |â(t)−2|≤4V(0)=33/8. 估计不必单调,跟踪误差也可以先增大再减小;单调不增的是这里特意构造的 V。

参数估计与真实参数二的对照,以及归一化李雅普诺夫函数随时间不增加
参数曲线与能量曲线使用分开的坐标轴。看到一条参数轨迹靠近真值,不等于所有参考输入都会使参数估计收敛。

= Python积分

代码返回 (t,x,xm,â) 的点列,仅复算这一确定初值案例。四阶Runge–Kutta对光滑解在有限区间具有四阶全局精度;它不自动保留连续系统的李雅普诺夫恒等式,应通过减小步长和核对误差检验数值结果。

Python 3
from math import isfinite

def simulate(dt=0.002, steps=7500):
    if not isinstance(steps, int) or steps < 0:
        raise ValueError("steps must be a nonnegative integer")
    if not isfinite(dt) or dt <= 0:
        raise ValueError("positive dt and nonnegative steps required")
    state = [0.25, 0.0, 0.0]  # x, reference state, parameter estimate
    out = [(0.0, *state)]
    def rhs(s):
        x, xm, estimate = s
        return [(1.0 - estimate) * x + 1.0,
                -xm + 1.0, 2.0 * (x - xm) * x]
    def shifted(s, k, scale):
        return [a + scale * b for a, b in zip(s, k)]
    for j in range(steps):
        k1 = rhs(state)
        k2 = rhs(shifted(state, k1, dt / 2))
        k3 = rhs(shifted(state, k2, dt / 2))
        k4 = rhs(shifted(state, k3, dt))
        state = [a + dt * (b + 2*c + 2*d + e) / 6
                 for a, b, c, d, e in zip(state, k1, k2, k3, k4)]
        out.append(((j + 1) * dt, *state))
    return out

trajectory = simulate()
assert trajectory[0] == (0.0, 0.25, 0.0, 0.0)
assert len(trajectory) == 7501
fine = simulate(0.001, 15000)
assert max(abs(a - b) for a, b in zip(trajectory[-1], fine[-1])) < 1e-6

每一步处理固定维数状态,执行 N 步耗时 O(N),保存整条轨迹占 O(N) 空间;只保留当前点可降为常数空间。学习率改为 γ=1 时必须同时修改更新方程和李雅普诺夫函数中的参数权重,不能只替换图上的标注。

跟踪收敛与参数收敛

如果参考输入为零,且初始 x=xm=0,那么无论把 â(0) 设为什么,状态和误差都恒为零,更新律也恒为零。即使真实参数为二、估计一直为负一,跟踪仍然完美。没有运动数据便不能从中辨认未知参数。

因此 e→0 不推出 â→a。参数辨识通常还需要足够丰富的回归信号,例如持续激励及相应的闭环条件。参考模型、输入增益符号和可用测量也必须满足设计要求。

本条的证明依赖参数恒定、没有外加扰动、状态准确可测和输入不受饱和限制。若 a=a(t),则 a~˙=â˙−a˙,会出现额外项;若有测量噪声,持续积分可能使参数漂移。投影、泄漏修正、死区等方法可以调整鲁棒性,但需要重新证明它们能保证的有界性或误差范围。

参考文献

  1. ↑ Hank Yang,Optimal Control and Estimation, Chapter 8: Adaptive Control,§8.1模型参考自适应控制,李雅普诺夫更新律与持续激励的区分。