前阵子帮一个做无人车路径跟踪的团队看控制方案,他们用的还是经典的"在每个工作点线性化+MPC"那套,结果遇到一个头疼的问题:系统状态离标定点一远,线性化模型就失真,预测出来的轨迹完全不能用,又不敢把MPC预测时域加长,因为非线性在线求解压根算不动。后来我把Koopman算子那套理论搬过去,用Matlab做了个快速验证,效果出乎意料地好——预测模型是全局线性的,控制律求解退化成标准二次规划,计算速度快了两个数量级,而且非线性特征保留得相当不错。这篇文章就把这个思路完整拆开讲清楚。
标题里说的"Koopman模型预测MPC",本质上是用Koopman算子理论把非线性受控动力系统"提升"到一个高维线性空间,然后在这个线性空间里做模型预测控制,省掉传统非线性MPC最头疼的在线优化负担。文章适合这几类读者:正在被非线性MPC求解速度折磨的工程师,想给系统加上先进控制却不知道怎么绕过非线性优化的研究生,以及想弄清楚Koopman算子到底怎么落地而不是停留在理论推导的科研人员。我会把数据准备、字典函数选取、Koopman矩阵拟合、MPC控制器搭建、状态估计配合这一整条链路都走一遍,代码用Matlab实现,最后拿一个倒立摆系统做完整验证。
1. 为什么会盯上Koopman算子:非线性MPC的计算困境
1.1 非线性MPC的"老三难"
做过非线性模型预测控制的人都清楚,真正落地的时候会撞上三堵墙。
第一堵墙是在线求解速度。非线性MPC每个控制周期都要解一个非线性规划(NLP)问题,常用的求解器是IPOPT、fmincon这类,内部要做大量Hessian矩阵计算和迭代收敛,在嵌入式控制器上经常跑不完一个周期。我见过一个工程案例,预测时域设成10步,系统有3个状态2个输入,NLP求解时间就到了200毫秒以上,对控制周期50毫秒的机械系统来说这直接宣判了死刑。
第二堵墙是局部最优问题。非线性规划是非凸的,求解器只能保证找到局部最优解,初始猜测给不好就收敛到某个不可用的解上。这个坑特别隐蔽,因为它不是每次都出错,而是系统运行到某个状态区域才触发,排查起来非常痛苦。
第三堵墙是标定参数多。非线性MPC的代价函数、约束、终端惩罚项里全是权重,每个权重对闭环性能的影响又高度耦合,调参基本靠经验加蒙特卡洛试错。
所以工程上有个很现实的需求:能不能找一个预测模型,它既是全局的而非局部线性化、又让在线优化变成凸问题、还能保留非线性系统的动态特征?Koopman算子理论恰好同时满足这三条。
1.2 Koopman思想的精髓:把非线性问题"提升"到线性空间
Koopman算子的核心思想听起来有点绕,但可以用一句话概括:在原状态空间里是非线性的系统,在某个"观测函数空间"里是线性的。
严格地说,对离散系统 (x_{k+1}=f(x_k)),Koopman算子 (\mathcal{K}) 作用在观测函数 (g) 上满足:
[
\mathcal{K} g(x) = g(f(x))
]
也就是说,(\mathcal{K}) 把"观测当前状态"这件事映射到"观测下一时刻状态",这个算子在函数空间里是线性的。如果我们找到一组坐标变换 (\varphi(x)),使得 (\varphi(x_{k+1}) = K \varphi(x_k)),那么非线性系统在新的坐标下就变成了线性系统 (z_{k+1} = K z_k),其中 (z = \varphi(x))。
这里的关键点是:Koopman算子本身是无穷维的,实际使用时必须做有限维近似。有控制的系统形式稍微改一下,变成:
[
z_{k+1} = A z_k + B u_k
]
这是最常用的受控Koopman线性模型,虽然为了简化丢掉了一些输入和状态之间的耦合项,但在很多实际系统中已经足够用。更高的精度可以考虑双线性形式 (z_{k+1} = A z_k + B (u_k \otimes z_k)),但MPC求解就会从QP变成双线性优化,计算优势就没了,所以工程实现通常还是用线性形式。
1.3 它跟常见的"线性化+MPC"有什么本质差别
很多人会问:这不就是换个方式做线性化吗?跟在每个工作点做泰勒展开有什么区别?
区别在"全局性"。传统的线性化是在某个工作点附近做一阶展开,只在该点附近有效,离开一段距离误差就爆炸。Koopman提升则是找一个全局的坐标变换,把整个感兴趣的状态空间区域映射到高维空间,在这个高维空间里动态是线性的。理论上说,字典函数够多、提升维数够高,近似精度可以无限逼近原非线性系统。
打个生活化的比方:地球表面是非线性的曲面,你直接在球面上规划航线非常麻烦;但如果你先把经纬度坐标提升到三维直角坐标,地面上任意两点间的大圆航线就变成三维空间里的简单几何计算。Koopman做的事情就是这个——找一个合适的"坐标系",让原来复杂的问题变简单,而且这个坐标变换是全局有效的。
这也是为什么我在实际项目里宁可多花时间在字典函数设计上,也不愿意回去调非线性MPC——Koopman模型一旦训好,在线部分就只剩一个二次规划,稳定性、实时性、可维护性全都上一个台阶。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从高维空间回到现实中:有限维近似与EDMD
2.1 字典函数选取——决定模型精度的"隐形手"
Koopman理论看起来漂亮,落地时第一个要解决的问题就是:(\varphi(x)) 到底取什么?这个选择直接决定模型精度,比后续任何一步都重要。
我的经验是,字典函数要从系统非线性特征反推。比如倒立摆系统里有 (\sin\theta) 和 (\cos\theta) 项,字典里就必须包含这两个函数;如果系统有速度相关的阻尼非线性,那就要考虑多项式项 (x_1 x_2) 或高次项。
常用的字典函数有这几类:
- 基本状态本身:(x_1, x_2, \dots, x_n),保证线性部分被覆盖
- 多项式项:一直到3阶或4阶,覆盖主要的非线性特征
- 三角函数项:(\sin, \cos),对摆动、旋转系统至关重要
- 高斯基函数:覆盖局部非线性突变,比如摩擦、间隙
- 输入相关的交叉项:(x_1 u_1, x_2 u_2) 等,能够捕捉输入与状态耦合
实际选取时有个实用技巧:先用包含大量函数项的字典训练模型,然后用稀疏回归(类似SINDy的思路)把系数接近零的项去掉,这样既避免了手工筛选的盲目性,又能得到一个紧凑的模型。在Matlab里这个操作很好做,OLS求解之后直接看
