首页 / 资讯中心 / 文章详情

基于Koopman算子的四旋翼数据驱动建模与MPC控制

基于Koopman算子的四旋翼数据驱动建模与MPC控制 ★ FEATURED ARTICLE
四旋翼的非线性模型一直是控制算法落地的拦路虎。做轨迹跟踪也好、姿态镇定也好仿真里跑得再漂亮换个工况往往就原形毕露。这两年以数据驱动的方式估计系统动态逐渐成了主流思路但真正能在无人机上闭环飞起来的方法并不多。Koopman算子理论是其中一个比较巧妙的解法它不跟非线性动力学硬碰硬而是把系统状态“提升”到高维空间让非线性演化在那个空间里“看起来”是线性的然后直接套用MPC这类成熟的线性控制框架。这个项目我前后做了两版核心就是基于Koopman算子做数据驱动建模再搭建模型预测控制器全程在MATLAB里实现包含离线训练、在线推理和闭环仿真验证。这个课题适合正在做无人机控制、或者想从非线性控制转向数据驱动控制研究的同学参考。特别是你已经有一定MPC基础但被非线性在线求解的实时性、以及精确建模的困难折磨过的话这篇文章应该能给你一个可直接落地的替代方案。我会把原理、建模细节、代码实现流程、参数整定和踩过的坑一并整理出来。1. 项目整体设计与核心思路1.1 为什么用Koopman算子替代传统系统辨识传统四旋翼控制器的设计路径一般分两步先通过牛顿-欧拉方程或者拉格朗日方程建立完整的非线性动力学模型然后在平衡点附近做线性化得到线性时不变模型据此设计LQR或PID。这个流程没问题但有两个痛点。第一是真实系统跟理想模型之间永远有偏差比如气动阻尼系数、旋翼的陀螺效应、电机响应延迟等机理建模很难把这些因素全部精确刻画。第二是工作范围逼近线性化点附近才准一旦姿态角偏大或者速度过快线性模型预测出来的未来状态会严重失真。Koopman算子的思路是不去直接征服非线性而是把它“搬运”到一个更高维的空间中在新空间里构造一个全局线性动态。严格说Koopman算子本身是无穷维的实际工程中我们只能选取有限的观测函数集合词典做有限维近似。但这个近似在无人机飞行包线内往往足够精确——因为四旋翼动力学虽然非线性强但平滑性很好能被一组适当的基函数充分表示。这个项目里我把Koopman模型当作MPC的内部预测模型。每个控制周期MPC根据当前系统状态利用数据驱动学到的线性提升动态推算出未来N步的状态演化并求解一个带约束的二次规划问题得到最优控制序列。整个框架能做到模型训练离线完成、在线求解只用一次线性二次规划实时性比非线性MPC高一个量级。1.2 整体系统架构与数据流整个项目分为数据采集、模型训练、控制器设计和闭环仿真验证四大块核心数据流如下。数据采集阶段在被控对象这里就是四旋翼的数值仿真模型上施加激励信号采集大量“状态-输入-下一状态”的三元组数据。接着是Koopman模型的离线训练选择提升函数、构造数据矩阵、用EDMD算法回归出Koopman矩阵。控制器设计阶段把训练得到的线性提升系统作为MPC预测模型设计代价函数、约束条件和求解器配置。最后在仿真环境中把MPC接到四旋翼模型上从悬停、轨迹跟踪等任务验证闭环性能同时对比Koopman模型预测轨迹与实际系统响应评估建模误差。这个架构最大的优势是模块解耦。模型训练和控制器设计互不影响调MPC权重参数的时候完全不需要重新训练模型除非你想更换工作点。而换了激励信号重新训练模型之后MPC部分也可以原封不动继续用。2. Koopman算子理论与EDMD算法细节2.1 从非线性动态到线性提升Koopman算子理论有一个很漂亮的思想内核系统状态空间虽然是非线性的但存在一个可测量的标量函数空间在这个空间上非线性动态的演化可以用一个线性算子来描述。写成离散时间形式设系统状态为$x_k$受控输入为$u_k$下一个状态为$x_{k1}$非线性映射记为$F(x_k, u_k)$。Koopman算子$\mathcal{K}$作用于提升函数$\psi(x)$时满足$$(\mathcal{K}\psi)(x_k, u_k) \psi( F(x_k, u_k) ) \psi(x_{k1}) \epsilon_k$$这里的$\epsilon_k$是有限维近似带来的残差。直观理解就是传统的视角盯着状态$x$本身看它怎么被$F$扭曲而Koopman的视角盯着状态的一个函数$\psi(x)$看这个函数的取值如何被一个线性算子推着走。实际工程中我们取$N_d$个基函数组成提升函数向量$\Psi(x) [\psi_1(x), \psi_2(x), ..., \psi_{N_d}(x)]^T$通常还会把控制输入的原样复制进提升空间。于是整体的提升向量写作$$z_k \begin{bmatrix} \Psi(x_k) \ u_k \end{bmatrix}$$目标是找到一个大矩阵$K$离散时间版本是$A$和$B$拼接使得$$z_{k1} \approx K z_k$$更常用的写法是把它拆成$$\Psi(x_{k1}) \approx A \Psi(x_k) B u_k$$其中$A$是系统矩阵$N_d \times N_d$$B$是输入矩阵$N_d \times m$。后面设计MPC的时候状态向量就是$\Psi(x_k)$而$u_k$是输入。这就是能套用线性MPC的关键一步。2.2 EDMD算法与正则化细节EDMD算法的数学过程并不复杂。从采集到的$N$条数据构建两个矩阵$$\Psi_X \begin{bmatrix} \Psi(x_1) \Psi(x_2) \cdots \Psi(x_N) \end{bmatrix}$$$$\Psi_Y \begin{bmatrix} \Psi(x_2) \Psi(x_3) \cdots \Psi(x_{N1}) \end{bmatrix}$$对应的控制输入矩阵为$U [u_1, u_2, \cdots, u_N]$。构造增广矩阵$$H \begin{bmatrix} \Psi_X \ U \end{bmatrix}$$则线性最小二乘问题为$$\min_{A,B} | \Psi_Y - [A \ B] H |_F^2$$解为$$[A \ B] \Psi_Y H^T (H H^T)^{-1}$$这里有个非常容易踩坑的细节当词典维数较高、数据量大时$HH^T$往往是病态矩阵直接求逆会让K矩阵中的特征值远远偏离单位圆导致预测发散。实际项目里我建议加岭回归正则化$$[A \ B] \Psi_Y H^T (H H^T \lambda I)^{-1}$$$\lambda$取$1e-6$到$1e-3$之间即可具体值取决于数据尺度。如果数据已经做了归一化$\lambda$取$1e-5$左右通常够用。另外一个细节EDMD虽然能得到一个线性的$A$和$B$但不保证$A$的特征值都落在单位圆内。如果训练数据覆盖不足某些模态会出现特征值模长大于1的情况。后面我会专门讲这个问题怎么排查。2.3 提升函数的选择原则提升函数是整个模型中最依赖经验的地方也是最影响最终性能的地方。常见的选择有三类。第一类是多项式函数。包括状态本身的一次项、二次项和交互项。优点是简单直观、实现方便缺点是表达能力有限对强非线性工况覆盖不足。第二类是径向基函数。以预设中心点$c_i$为基准计算$\psi_i(x) \exp(-|x - c_i|_2^2 / \sigma^2)$。这类函数局部表达能力强但中心点的分布需要覆盖系统的有效工作区域否则没有中心点覆盖的区域预测效果会很差。第三类是随机傅里叶特征。$\psi_i(x) \cos(\omega_i^T x b_i)$本质上是把状态映射到频率域空间适合周期性较强的动态但对四旋翼这种非周期轨迹跟踪任务不太常用。项目里最终选的是一组混合特征原始状态分量保证线性一致性、所有状态分量的二次方项、若干关键交互项比如俯仰角乘以俯仰角速度、滚转角乘以滚转角速度加上重心处的高度和垂直速度平方项。总共约70维。初始维度选得不算高但已经能覆盖四旋翼的机动飞行区间。选词典时有一条经验法则宁可多选一些基函数也先别急着降维。EDMD回归自带正则化多出的基函数只会增加计算量不会大幅度伤害预测精度。真正的问题是高维提升空间会放大观测噪声所以噪声比较大的情况下反过来要控制词典维度不超过状态维度的10倍左右。3. MPC控制器设计与参数整定3.1 预测模型与代价函数设计Koopman模型训练完成之后预测模型的形式为$$\Psi(x_{k1}) A \Psi(x_k) B u_k$$注意$\Psi(x_k)$中通常有一部分就是原始状态本身。为了保证MPC能直接约束真实状态比如俯仰角不要超过30度提升函数的第一组分量必须包含所有原始状态变量。设计提升函数时这个要刻意安排否则后面写约束条件时会很别扭。MPC的优化问题为$$\min_{u_0, ..., u_{N_p-1}} \sum_{k0}^{N_p-1} | \Psi(x_k) - \Psi_{ref,k} |Q^2 | u_k - u{ref} |R^2 | \Psi(x{N_p}) - \Psi_{ref,N_p} |_P^2$$其中$Q$是状态权重对角矩阵$R$是输入权重矩阵$P$是末端惩罚矩阵。$N_p$是预测时域项目里取20。控制时域$N_c$取10后半部分控制输入保持最后一个值不变。关于几个权重参数的经验值$Q$中对位置状态的权重取10到50$Q$中对速度状态的权重取1到5$Q$中对姿态角状态取5到20$Q$中角速度尽量取小因为角速度反馈太多容易引起震荡$R$取0.5到2之间反映对输入幅值和变化的惩罚。3.2 约束条件的建模与松弛处理四旋翼的约束通常包括输入饱和约束、姿态角边界和状态可行性。姿态角约束相对直接因为提升函数包含了原始姿态角所以直接在MPC中写$-\phi_{max} \le \phi_k \le \phi_{max}$即可。输入约束上四个电机的PWM输入或转速控制在上下界之间用$u_{min} \le u_k \le u_{max}$表达。比较隐蔽的问题是Koopman模型是数据驱动的模型误差在预测时域末尾会累积。这时候严格的约束可能导致MPC优化问题不可行——也就是说在这个预测时域内没有任何一组控制序列能满足所有约束条件。解决思路有两个一是缩短预测时域、减小外推误差二是引入松弛变量。我实际采用后者。引入松弛变量$\varepsilon$把约束改写为$$-\phi_{max} - \varepsilon \le \phi_k \le \phi_{max} \varepsilon, \quad \varepsilon \ge 0$$同时在代价函数中加惩罚项$\rho |\varepsilon|_2^2$。$\rho$是一个很大的正数例如10000优先级很高只有确实无法满足硬约束时才允许越界。这种做法的好处是MPC绝大多数情况下都不会因为数值问题而突然输出NaN或者直接失效必要时刻以安全姿态的轻微越界换取控制指令的连续性。这在工程中是完全可以接受的。3.3 求解器选择与实时性分析Matlab环境下的二次规划问题求解标准选择是quadprog。如果预测时域取20、状态提升维度是70、输入维度是4那么决策变量维度大约是70×20加4×20约1500维。这个规模用quadprog的默认算法interior-point单次求解大概需要10到50毫秒取决于机器配置和稀疏性利用程度。要想提速有几个技巧把预测模型写成稀疏矩阵描述减少内存拷贝把计算好的预测矩阵预先分解控制周期内如果参考轨迹不变代价函数的Hessian矩阵可以离线计算好。闭环仿真时每个时间步的典型控制周期是0.05秒20Hzquadprog的求解时间远小于一个控制周期因此有充足余量。如果要跑到50Hz以上建议把预测时域降到10或者在提升空间里做一次PCA降维减少决策变量数目。4. 四旋翼建模与数据集生成4.1 简化动力学模型与状态方程四旋翼的全量模型包含位置方程、姿态运动学方程和角速度动力学方程。写成便于仿真的形式位置平动方程$$ \begin{cases} \ddot{x} \frac{u_1}{m} (\cos\phi \sin\theta \cos\psi \sin\phi \sin\psi) \ \ddot{y} \frac{u_1}{m} (\cos\phi \sin\theta \sin\psi - \sin\phi \cos\psi) \ \ddot{z} \frac{u_1}{m} \cos\phi \cos\theta - g \end{cases} $$角速度动力学简化为$$ \dot{p} \frac{u_2}{I_{xx}}, \quad \dot{q} \frac{u_3}{I_{yy}}, \quad \dot{r} \frac{u_4}{I_{zz}} $$姿态运动学用四元数或者欧拉角传播欧拉角在小角度范围内足够准确但在大机动情况下会出现万向节锁问题。项目里仿真主体使用的是四元数传播但给MPC反馈时再转换为欧拉角避免奇异点。控制输入$u_1$到$u_4$分别是总推力、滚转力矩、俯仰力矩和偏航力矩。实际电机转速跟这些力矩之间还有一个混控矩阵做机载移植时需要补充这部分但仿真阶段直接以力矩为输入可以简化问题。4.2 激励信号设计与数据覆盖数据驱动模型最怕数据覆盖度不够。如果只在悬停点附近加小幅扰动训练出的Koopman模型只适合悬停任务一做大轨迹跟踪就崩。我的做法是先用一个低增益的PID控制器托底保证系统不发散然后在参考轨迹上叠加随机生成的机动指令让系统遍历不同的姿态角和速度区间。具体来说位置参考信号用随机生成的平滑曲线在$x, y$方向分别附加幅度在±3米、频率在0.1到0.5Hz的正弦组合波偏航角附加±30度的斜坡和阶跃信号在控制输入端额外叠加伪随机噪声频率范围为0.1到20Hz幅度为标称推力的5%。每组轨迹时长约20秒仿真步长0.01秒采集到的数据点约2000个。重复生成8组不同的机动轨迹合并成一个约16000个数据点的数据集。这里有一个重要的细节数据必须覆盖闭环系统可能达到的所有姿态和速度范围。所以训练集里既要有小幅悬停扰动也要有大机动转弯、快速爬升下降的数据点。4.3 数据归一化与训练集构造EDMD回归对数据尺度极其敏感。Koopman提升函数里的多项式项是状态分量的乘积如果位置以米为单位、角速度以弧度每秒为单位这些分量的数值范围差异巨大二次项必然由量级最大的分量主导小信号信息被淹没。因此必须先归一化再训练。采用的归一化方式是对每个原始状态分量独立计算均值和标准差$$ \tilde{x}^{(i)} \frac{x^{(i)} - \mu_i}{\sigma_i} $$然后基于归一化后的状态构造提升函数。训练完成后在使用模型的任何地方都先归一化输入并在读取Koopman模型输出后反归一化。这一步不做好后面的MPC会时好时坏而且问题非常难排查——因为从数据曲线看好像一切正常但模型本质上被噪声主导了。MPC内部使用的$\Psi(x_k)$也要用相同的方式构造保持一致。5. 核心代码实现与实操流程5.1 四旋翼仿真模型搭建仿真模型是基础。我采用面向对象思路封装了一个四旋翼动力学类主要函数是状态导数的计算。核心部分如下。classdef Quadrotor handle properties m 1.2; % 质量 kg g 9.81; % 重力加速度 Ixx 0.013; % 转动惯量 Iyy 0.013; Izz 0.024; end methods function dx dynamics(obj, x, u) % x [x y z phi theta psi vx vy vz p q r] % u [u1 u2 u3 u4] (总推力, 滚转力矩, 俯仰力矩, 偏航力矩) phi x(4); theta x(5); psi x(6); vx x(7); vy x(8); vz x(9); p x(10); q x(11); r x(12); u1 u(1); u2 u(2); u3 u(3); u4 u(4); dx zeros(12, 1); dx(1) vx; dx(2) vy; dx(3) vz; dx(4) p sin(phi)*tan(theta)*q cos(phi)*tan(theta)*r; dx(5) cos(phi)*q - sin(phi)*r; dx(6) sin(phi)/cos(theta)*q cos(phi)/cos(theta)*r; dx(7) (u1/obj.m) * (cos(phi)*sin(theta)*cos(psi) sin(phi)*sin(psi)); dx(8) (u1/obj.m) * (cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)); dx(9) (u1/obj.m) * cos(phi)*cos(theta) - obj.g; dx(10) u2 / obj.Ixx; dx(11) u3 / obj.Iyy; dx(12) u4 / obj.Izz; end end end实际仿真用ode45以0.01秒间隔推进控制周期和仿真步长分开设置。控制周期为0.05秒也就是20Hz仿真步长0.01秒。5.2 数据采集与数据集构造数据采集阶段的核心是生成激励信号并记录状态和输入。伪代码如下。load(quadrotor_init.mat); % 初始状态 x zeros(12, N_total); u zeros(4, N_total); for k 1:N_total-1 % 更新参考轨迹 ref_k ref_generator(t_k); % 低增益PID输出基准控制量 u_base pid_tracking(quad, x(:, k), ref_k); % 叠加包含丰富频谱的激励 u_noise excitation_signal(t_k); u_k u_base u_noise; % 以0.01s步长推进四个中值点模拟零阶保持效果 for j 1:5 x_sim quad.step(x_sim, u_k, dt_sim); end x(:, k1) x_sim; u(:, k) u_k; end记录数据时注意一个容易出错的地方EDMD要求的是“状态-输入-下一状态”三元组。也就是说用$x_k$和$u_k$预测$x_{k1}$。控制周期内的多个仿真步长推进得到的状态才是$x_{k1}$。数据记录时不要记录了中间点否则训练数据的时间对齐就乱了。5.3 EDMD模型训练实现训练模块是整个项目中数据处理最集中的地方。关键代码是词典构造和最小二乘回归。function [A, B, dict_info] train_koopman(data, params) X data.X; % N x 12 U data.U; % N x 4 Y data.Y; % N x 12 (X的下一状态) % 归一化 [Xn, mu_x, sigma_x] zscore(X); Yn (Y - mu_x) ./ sigma_x; % 构造提升函数 PsiX lift_state(Xn); PsiY lift_state(Yn); H [PsiX; U]; % N x (Nd 4) M PsiY * H / (H * H params.lambda * eye(size(H,2))); A M(:, 1:size(PsiX,2)); B M(:, size(PsiX,2)1:end); dict_info.mu mu_x; dict_info.sigma sigma_x; endlift_state函数需要实现提升函数向量$\Psi(x)$的计算。由于提升函数中包含原始状态的线性项lift_state输出向量的前12位就是归一化后的状态值后面依次是二次项和交互项。这里有一个关键点H*H的维度是设计的提升维度加上输入维度之和当这个维度超过100时inv或/运算都会被非常慢而且数值不稳。我实际使用的是pinv加小量对角扰动或者直接用lsqminnorm函数。Matlab自带的lsqminnorm在解决这类欠定/病态最小二乘问题时比普通除法稳定得多。5.4 MPC预测矩阵构造与求解MPC的核心是将Koopman模型转成标准二次规划形式。将预测时域内所有时刻的状态提升向量堆叠$$ Z S_z \Psi(x_k) S_u U_{seq} $$其中$Z [\Psi(x_{k1}), \Psi(x_{k2}), ..., \Psi(x_{kN_p})]^T$$U_{seq}$是所有控制输入的堆叠。矩阵$S_z$和$S_u$由$A$和$B$反复相乘组合而成可以在每个MPC周期内现场构造也可以在系统参数不变时离线造好。代价函数转化为标准QP形式后直接用quadprog求解H_qp 2 * (S_u * Q_bar * S_u R_bar); f_qp 2 * (S_z * x_k - ref_bar) * Q_bar * S_u; [U_seq, fval, exitflag] quadprog(H_qp, f_qp, A_ineq, b_ineq, A_eq, b_eq, lb, ub);注意$S_u$矩阵维度是$(N_p \times N_d) \times (N_c \times m)$通常很大但非常稀疏。用sparse存储能显著提高quadprog的速度。我在实践中发现稀疏化之后求解时间下降约4到5倍。约束方程矩阵A_ineq需要把预测时域内所有状态约束和控制约束拼装起来。对状态约束关键是从$Z S_z x_k S_u U_{seq}$中提取出对应的状态行再换算为对$U_{seq}$的不等式。5.5 闭环仿真框架闭环仿真主循环如下。for k 1:round(T_total/dt_ctrl) x_k x_history(:, k); % 归一化并构造提升状态 psi_k lift_state((x_k - mu_x) ./ sigma_x); % 构造参考轨迹 ref_k ref_trajectory(t_k); psi_ref lift_state((ref_k - mu_x) ./ sigma_x); % 求解QP U_opt solve_mpc(psi_k, psi_ref); u_k U_opt(1:4); % 以0.01s步长推进仿真 for j 1:5 x_sim quad.step(x_sim, u_k, dt_sim); end x_history(:, k1) x_sim; end这里有一个细节MPC的参考轨迹需要转换成提升空间中的参考值。如果参考轨迹本身变化较平稳直接对参考状态调用lift_state即可如果参考轨迹有跳变比如阶跃指令建议先对参考状态做低通滤波再提升否则Koopman模型在预测时域内会被这个跳变激励出不真实的动态响应。6. 常见问题与排查技巧实录6.1 Koopman模型预测发散这是最容易遇到的现象。训练完成之后拿一段验证数据做开环预测原本应该跟真实状态接近的预测轨迹跑了十几步之后突然飞到十万八千里。排查顺序第一步检查$A$矩阵的特征值。在MATLAB里用eig(A)观察如果有模长大于1的特征值模型本身就不稳定。可能的原因是提升函数维数过高、训练数据不足、或者正则化系数太大。第二步检查数据覆盖。如果训练数据里姿态角最大只到10度验证时给到30度的参考轨迹模型必然崩。解决办法是重新生成数据扩大激励幅度。第三步检查归一化。如果mu_x和sigma_x统计错了或者验证时用了不同的归一化参数提升函数输出就会乱。这个看起来低级但确实踩过。6.2 MPC求解失败与控制失效quadprog返回exitflag 0或者解出来的控制量剧烈震荡。这类问题多数是因为QP不可行或数值病态。解决办法按优先级排序引入松弛变量前面已经说过降低预测时域$N_p$从20降到10到15能大幅增加可行域增大$R$权重限制控制变化率检查约束边界是否跟训练数据覆盖范围一致。如果约束给得太紧比如姿态角限制在5度但训练数据到过30度QP经常找不到可行解。另外一个容易被忽略的点quadprog的H_qp矩阵必须是对称正定的。如果$R$矩阵中存在为0的对角元比如你认为某个输入不需要惩罚QP就变成半正定的quadprog可能偶尔报错。解决办法是对$R$加一个很小的单位阵扰动比如$R 1e-6I$保证严格正定。6.3 轨迹跟踪有稳态误差Koopman模型是纯数据驱动的训练数据的均值将与实际悬停点有关。如果训练时系统的平均位置不在原点那么Koopman模型学习到的平衡点可能同样是偏移的。这会导致MPC跟踪阶跃参考时出现稳态偏差。解决办法有两种。第一种是在训练数据中把参考均值对齐到原点离线生成轨迹时让系统反复回归原点悬停。第二种是在MPC代价函数中引入积分项把位置误差的累积值加入代价函数中做惩罚类似PI控制的思想。第二种做法见效更快代码改动量也小。6.4 在线计算延迟过大当提升函数维度超过200时QP规模会急剧膨胀仿真速度明显下降。此时有几个降载手段把预测时域从20降到10对提升空间做主成分分析或者自动编码器降维把$\Psi(x)$从200维压缩到60维保持动态特性的同时减少决策变量使用quadprog的active-set算法而非默认的interior-point在中小规模问题上通常更快。6.5 问题速查表现象可能原因解决方案开环预测发散A特征值模长1数据覆盖不足检查特征值增加激励幅度调正则化QP不可行约束过紧预测时域过长引入松弛变量缩短Np放宽状态约束稳态误差训练数据均值偏移无积分作用对齐数据均值加积分惩罚项控制量抖动R过小hp维度太高增大R降低Nc降维在线计算慢优化问题规模大稀疏化降维换求解器算法7. 扩展方向与个人实操体会这个框架跑通一次之后可以延伸的方向其实挺多。我给后续接手这个课题的同学一个建议不要把Koopman模型固定在“训练时覆盖的工况”里。你可以把它当作一个可以随时重新训练的内核比如在真实飞行器上采集几组飞行数据然后重新跑一遍EDMD得到针对当前机体特性的新模型。这样换电池、换桨叶之后模型响应特性变了不需要重新推导机理方程只需要重新训练即可。我之前测试过一个想法在Koopman提升空间里引入积分状态等效于在MPC中做无静差跟踪。这个方法对轨迹跟踪的帮助很明显但对模型精度的要求也更高——如果Koopman模型的预测偏差在某个方向上是系统性的积分项会把误差累积变成控制量的持续偏移导致迟滞和超调。建议先保证开环预测在轨迹跟踪任务中足够准再加积分。最后再分享一个小技巧训练Koopman模型的时候把提升函数的输出也做一次白化处理也就是对$\Psi(x)$的协方差矩阵做Cholesky分解然后左乘其逆。这样能显著改善EDMD回归的数值条件特别是在基函数之间相关性较强时比如高次项和低次项数值范围差异较大。我在实验中发现白化之后即便提升维度从70增加到150模型特征值依然能保持稳定而不会出现患病的模态。代价是你需要额外维护白化矩阵并在部署时同步更新到控制器里。但这个代价换来的数值稳定性绝对值回票。
阅读完成 · 觉得有帮助?
咨询建站