积分强化学习驱动的不确定非线性系统H∞跟踪控制 简介一套基于积分强化学习的不确定非线性系统H∞跟踪控制文档资源面向控制工程与强化学习交叉领域的研究人员与开发者。内容聚焦外部干扰和输入约束下的跟踪控制问题提出在线模型无关的积分强化学习算法构建评价-执行-干扰三神经网络同步更新解决HJI方程求解难题并结合Lyapunov方法证明系统稳定性与收敛性控制器中加入鲁棒项以削弱神经网络逼近误差保证闭环渐近稳定。资源共1个docx文档压缩包约49KB包含HJI方程计算、IRL算法、鲁棒控制设计、控制策略生成等完整理论推导与可运行Python示例代码附有详细注释和两个仿真示例验证思路便于读者复现论文方法、调整网络结构与超参数。目前已有153人学习浏览适合具备编程基础、对非线性系统控制和神经网络在线学习算法有一定了解的研发人员作为算法设计与仿真参考。 前段时间有人问我论文里那些用强化学习做鲁棒控制的方案到底能不能落地。我复现了一个比较典型的设置不确定非线性系统的 H∞ 跟踪控制用积分强化学习Integral Reinforcement Learning, IRL在线训练一个神经网络在不显式依赖系统漂移动力学的前提下让控制器学会抑制外部扰动。这篇文章把这套方法拆开讲清楚同时给一段可以直接跑的 Python 代码适合正在复现论文、准备用强化学习做控制方向研究的同学参考。1. 问题建模H∞跟踪控制为什么让人头疼1.1 被控对象和跟踪误差考虑一类常见的仿射非线性系统x1_dot x2 x2_dot f(x1, x2) u w其中f是未知的非线性函数u是控制输入w是外部扰动。为了让它更接近工程实际我额外加了一个未建模项比如0.1*sin(3x1)这样一个简单的单摆模型就会带有明显的不确定性。跟踪控制的目标是让状态x跟踪一个给定的参考轨迹xd(t)。定义跟踪误差z1 x1 - xd1 z2 x2 - xd2整个误差系统的动态可以写成z1_dot z2 z2_dot f(x) u w - xd2_dot传统鲁棒控制的思路是先对未知的f做界估计然后设计一个大增益控制器把不确定性“压”下去。这种做法能保证稳定但往往非常保守控制力整天在抖实际系统根本受不了。H∞ 控制的提法更讲究我们希望设计一个控制器u使闭环系统从扰动w到评价输出z^T Q z u^T R u的 L2 增益不超过某个给定水平γ。翻译成人话就是外部扰动对系统的影响不能超过一个预先约定的倍数。1.2 目标不是“找一个控制器”而是“逼近一个偏微分方程”对 H∞ 控制问题做最优解推导时会发现它本质是一个二人零和博弈控制器想让代价变小扰动想让代价变大。对应的最优值函数V(z)满足著名的 HJI 方程0 z^T Q z u^T R u - γ^2 w^T w ∇V^T (F g u k w)这里的F是误差动力学中的非线性项g和k分别是控制输入矩阵和扰动输入矩阵。问题在于HJI 是一个偏微分方程解析解只存在于极少数特殊情况。非线性系统稍微复杂一点根本写不出闭式解数值求解也会被“维度灾难”卡住。传统方法到这里基本就放弃了要么把模型线性化要么只求次优解。强化学习的思路完全不同不直接解方程而是用神经网络去逼近V(z)再通过闭环系统的数据不断修正网络权值。这里有个很关键的问题——连续时间系统里神经网络权值更新的目标函数里含有V对时间的导数而V_dot的表达式里恰好包含未知的f(x)。如果直接做就等于还是要建模。这个问题积分强化学习给出了一个相当漂亮的回避方案。2. 积分强化学习的核心思想把HJI方程改写成人能算的形式2.1 为什么是积分而不是微分积分强化学习的所有优势都体现在一个积分恒等式上。对于连续时间系统如果V(z)沿着系统轨迹是连续可微的那么在任意时间区间[t-T, t]上都有V(z(t-T)) - V(z(t)) ∫_{t-T}^{t} r(z, u, w) dτ其中r z^T Q z u^T R u - γ^2 w^T w。注意等式右边是一个积分只依赖于从系统中采集到的状态、控制输入和扰动等式左边也只依赖于区间两端的V值。整个表达式里根本不需要出现f(x)的解析式。这就是“积分”两个字的核心意义。它把连续时间 Bellman 方程中的未知动态项变成了一个可以用实验数据直接计算的时间差分形式。只要我们能沿系统轨迹做积分回报就能评估当前控制策略的好坏完全不需要辨识系统模型。2.2 神经网络解法与策略迭代如果直接用表格形式存V(z)状态一多就不现实。更常见的是用一个参数化函数逼近它比如单层神经网络V(z) W^T φ(z)我下面代码里选用的是二次型基函数φ(z) [0.5*z1^2, z1*z2, 0.5*z2^2]选择这个基函数不是拍脑袋。H∞控制和 LQR 之间有深刻联系线性情形下最优值函数就是二次型非线性系统在平衡点附近的一阶近似通常也能用二次型获得一个不错的初始猜测。更重要的是二次型基函数对应的控制律和扰动策略形式非常简洁方便在仿真里验证整套机制。根据神经网络逼近控制策略可以写成u -0.5 * R^{-1} * B^T * ∇V(z)扰动策略则为了使代价最大按零和博弈取w 0.5 * γ^{-2} * K^T * ∇V(z)这里的B和K分别对应控制通道和扰动通道的输入矩阵。推导过程并不复杂把参数化的V代入 HJI 方程对u和w分别求驻点条件即可。注意这个表达式里没有f(x)只有值函数梯度和输入矩阵这是我们能实现模型无关学习的关键。策略迭代的流程如下用一个初始稳定的控制策略开始比如u -0.3*z1 - 0.6*z2。在当前策略下运行系统沿轨迹采集积分回报数据。对每个时间区间计算φ(z(t-T)) - φ(z(t))和对应的代价积分。用最小二乘更新权值W使所有数据的W^T Δφ ≈ ∫ r dτ成立。用更新后的W重新生成控制策略和扰动策略重复以上过程。这里的最小二乘更新本质就是在做神经网络权值的学习。单层网络可以直接用最小二乘闭式解换成多层网络只需要把闭式解改成梯度下降即可其他推导保持不变。3. 完整可运行代码受扰单摆跟踪正弦参考3.1 仿真对象说明我用一个受扰动且带未建模项的倒立摆系统来演示。系统模型为x1_dot x2 x2_dot -sin(x1) - 0.3*x2 0.1*sin(3*x1) u w其中0.1*sin(3*x1)是不确定项实际控制器完全不知道这一项。参考轨迹设定为xd1 0.5*sin(t) xd2 0.5*cos(t)代价函数中取Q diag(1, 0.5)R 1γ 3。3.2 Python代码可直接运行import numpy as np gamma 3.0 Qz np.array([1.0, 0.5]) R 1.0 reg 1e-3 # 正则化系数防止最小二乘矩阵奇异 mix 0.5 # 权值混合更新系数 def xd_func(t): 参考轨迹及其导数。 return 0.5 * np.sin(t), 0.5 * np.cos(t), -0.5 * np.sin(t) def phi(z): 二次型基函数。 return np.array([0.5 * z[0] ** 2, z[0] * z[1], 0.5 * z[1] ** 2]) def collect_data(W, T_total30.0, T_int0.15, dt0.002): 在当前策略 W 下采样数据。 返回 P_rows: 每个时间区间两端基函数之差 targets: 对应区间内的累积代价积分 x np.array([1.0, 0.0]) t 0.0 P_rows [] targets [] while t T_total - 1e-6: t0 t x0 x.copy() xd1_0, xd2_0, _ xd_func(t0) z0 np.array([x0[0] - xd1_0, x0[1] - xd2_0]) phi0 phi(z0) integ 0.0 while t t0 T_int and t T_total: xd1, xd2, xdd xd_func(t) z np.array([x[0] - xd1, x[1] - xd2]) # 当前策略控制律和扰动律都由 W 导出 u -0.5 * (W[1] * z[0] W[2] * z[1]) w 0.5 / (gamma ** 2) * (W[1] * z[0] W[2] * z[1]) # 代价积分项 integ (Qz[0] * z[0] ** 2 Qz[1] * z[1] ** 2 R * u ** 2 - gamma ** 2 * w ** 2) * dt # 真实被控对象全部放在仿真函数里不参与权值更新 f -np.sin(x[0]) - 0.3 * x[1] 0.1 * np.sin(3.0 * x[0]) x_next x np.array([x[1], f u w]) * dt x x_next t dt xd1_f, xd2_f, _ xd_func(t) z_f np.array([x[0] - xd1_f, x[1] - xd2_f]) phi_f phi(z_f) P_rows.append(phi0 - phi_f) targets.append(integ) return np.array(P_rows), np.array(targets) # 初始稳定策略对应的 W # 控制律 u -0.5*(W[1]*z1 W[2]*z2) # 取 W[1]0.6, W[2]1.2 时u -0.3*z1 - 0.6*z2 W np.array([2.0, 0.6, 1.2]) for it in range(25): P, b collect_data(W) A P.T P reg * np.eye(3) bvec P.T b W_new np.linalg.solve(A, bvec) W W mix * (W_new - W) print(iter %2d, W [%.4f, %.4f, %.4f] % (it, W[0], W[1], W[2])) print(\n学习结束最终权值为) print(W , W)3.3 代码运行逻辑解读重点看collect_data函数里的两个循环。外层循环按时间区间切分数据每个区间长度是T_int 0.15秒内层循环用欧拉法积分被控系统并把每一小步的代价累积起来。内层循环里出现的f是仿真器里的真实系统它完全不知道权值更新过程。实际部署时这些数据直接来自传感器采样和代价计算代码里用模型只是为了让实验可复现。权值更新只用到三样东西区间两端的z、区间内累积的代价积分、以及已知的输入矩阵。最小二乘这一步需要稍微解释。我们期望对每个区间都满足W^T (φ(z(t-T)) - φ(z(t))) ≈ ∫_{t-T}^{t} r dτ所以把所有区间的数据堆成矩阵P和向量b求解P W b。直接用最小二乘闭式解容易在特征激励不足时出现病态问题所以我加了reg * I做正则化并把mix设为0.5让每次迭代只往新解方向走半步。后面你会看到这种“软化”对收敛稳定非常重要。4. 运行结果与最容易翻车的几个细节4.1 收敛趋势与结果观察我本地跑下来大约迭代 10 次以后W的三个分量就开始在某个邻域内缓慢调整不再出现大幅度跳变。控制律里的核心系数W[1]和W[2]会稳定到一组比初始手调值稍大的参数说明通过积分回报反馈值函数确实在学习“更优”的东西。如果你把W代入闭环系统再做一次仿真会看到跟踪误差z1的峰值明显小于初始固定增益控制器下的峰值。这就是 H∞ 控制的效果同样的控制器在未知非线性和外部扰动同时存在时依然能把误差限制在可接受范围内。这类算法有一个特点中间过程并不是单调下降的。偶尔一次迭代后W会往一边偏一下但混合更新会把它拉回来。我建议你跑的时候把W打印出来观察趋势不要因为某一次迭代反弹就认为是代码错了。4.2 几个实操坑第一个坑是时间区间T_int的选择。这个参数对应积分强化学习里的“采样间隔”理论上是任意的但实际影响很大。取太小相邻两点间差分会被数值噪声淹没取太大整个区间内策略变化太大积分近似和权值更新都会失真。我试过从0.02到0.5的不同取值0.15在这个系统上比较舒服。换到别的系统你先看一眼动态时间常数再定这个参数。第二个坑是探测激励问题。强化学习离线训练时可以自由加探测信号在线学习就必须依赖参考轨迹本身提供激励。我这里参考是正弦信号状态一直在变化数据丰富度足够如果你做调节问题参考是常数状态很快收敛到零P矩阵就会近似退化最小二乘解很容易乱飞。解决办法有两个在控制输入端叠加小幅度的探测信号或者在参考轨迹上做适当变化。第三个坑是γ的取值。理论上γ越小H∞ 性能越好但 HJI 方程的解会更难逼近值函数很容易在学习过程中变成不定的二次型。我先取γ 10跑通全流程再一步一步减小到3每一步都在上一步结果基础上初始化W这样收敛概率高得多。直接上来就取γ 1大概率会看到权值发散。第四个坑是初始策略必须稳定。积分强化学习的策略迭代需要一个初始稳定的控制策略否则系统轨迹直接发散采集到的数据没有任何意义。前面代码里W [2.0, 0.6, 1.2]对应的控制律是u -0.3*z1 - 0.6*z2这个反馈本身已经把摆稳定住了。新手最容易犯的错误是随机初始化网络参数然后指望算法自己学会稳定这在连续时间最优控制里风险极高。5. 从Demo到工程应用几个扩展方向这套代码虽然只有几十行但已经把积分强化学习的核心链路跑通了。想做更接近论文效果的研究有几个方向可以继续深入。第一基函数可以升级成真正的多层神经网络。单层二次基函数的好处是能直接用最小二乘缺点是表达能力有限。换成 MLP 之后权值更新就不能用闭式解了需要把积分回报目标改成随机梯度下降的 loss用 PyTorch 或 JAX 做自动微分。算法框架不变只是 Critic 的参数更新方式变了。第二可以去掉“扰动输入矩阵已知”的假设。我的例子里扰动w穿过和u相同的通道叫做匹配扰动这是 H∞ 控制里最常见也最容易处理的假设。非匹配扰动会更复杂通常需要先构造一个辅助扰动观测器或者把状态扩展到包含扰动动态的形式。第三可以加入事件触发机制。实际系统不希望在每个采样周期都更新控制器而是在误差超过某个阈值时才刷新控制量。积分强化学习天然适合这类问题因为它的 Bellman 方程本身就是定义在任意时间区间上的事件触发的时间步长变化不会破坏基本方程结构。第四考虑控制饱和。真实执行器都有幅值限制直接使用无约束控制律可能在启动阶段出现大幅超调。常见做法是在值函数里加入控制幅度的惩罚项或者把控制策略做一次带约束的投影。这两种方式都会让 HJI 方程变得更复杂但思路依然可行。最后再分享一个我自己的体会这类算法表面上看数学推导很重但真正把它拆成“积分回报 神经网络逼近 策略迭代”三块之后每一块都不难实现。难点在于你要理解每个参数在系统里的物理意义比如T_int对应采样频率、γ对应鲁棒性需求、基函数对应你希望值函数长成什么样。把这些想清楚跑通一篇论文中的仿真并不是什么难事。本文还有配套的精品资源点击获取