在工业控制和机器人领域,我们经常需要处理复杂的非线性系统控制问题。传统模型预测控制(MPC)在面对强非线性系统时,要么需要复杂的非线性优化计算,要么需要对系统进行过度简化。Koopman算子理论提供了一种革命性的思路——将非线性系统"提升"到更高维的线性空间进行处理。
我最近在无人机轨迹跟踪项目中实践了Koopman-MPC方法,相比传统非线性MPC,计算时间缩短了60%以上,而控制精度保持在同一量级。这种方法特别适合实时性要求高、系统非线性强的场景,比如:
Koopman算子是一种将非线性动力学系统转化为无限维线性系统的数学工具。给定非线性系统:
dx/dt = f(x,u)
通过构造观测函数g(x),将状态空间"提升"到更高维的线性空间:
dg(x)/dt ≈ Kg(x)
其中K就是我们要学习的Koopman算子矩阵。在实践中,我们通常用有限维矩阵来近似这个无限维算子。
常用的Koopman算子学习方法包括:
我在Matlab中实现时发现,EDMD方法在大多数情况下已经能提供足够好的近似,且计算复杂度适中。其核心步骤包括:
以下是我的实现框架代码结构:
matlab复制classdef KoopmanMPC
properties
KoopmanMatrix % 学习到的Koopman算子
BasisFunc % 基函数句柄
PredictionHorizon % 预测时域
ControlHorizon % 控制时域
Q,R % 代价函数权重
end
methods
function obj = learnKoopman(trainingData)
% EDMD方法实现
end
function [u_opt, pred_traj] = solveMPC(current_state)
% 构建线性MPC问题并求解
end
end
end
经过多次实验,我发现基函数的选择对性能影响巨大。对于机械系统,以下组合效果较好:
matlab复制function g = defaultBasis(x,u)
% 状态本身
g1 = x;
% 二次项
g2 = x'*x;
% 三角函数项
g3 = [sin(x); cos(x)];
% 控制相关项
g4 = [u; x.*u];
g = [g1; g2; g3; g4];
end
重要提示:基函数中必须包含足够的非线性项,否则无法准确描述原系统动力学。但维度也不宜过高,否则会导致计算负担过重。
优质的训练数据是模型成功的关键。我建议:
matlab复制% 生成训练数据示例
T = 100; % 秒
dt = 0.01;
N = T/dt;
X = zeros(nx, N);
U = zeros(nu, N);
for k = 1:N-1
U(:,k) = randn(nu,1); % 随机激励
X(:,k+1) = simulateSystem(X(:,k), U(:,k), dt);
end
将Koopman模型嵌入MPC框架:
构建预测模型:
z_{k+1} = K z_k
其中z_k = g(x_k, u_k)
设计代价函数:
J = Σ (z_k^T Q z_k + u_k^T R u_k)
添加约束条件:
u_min ≤ u_k ≤ u_max
Δu_min ≤ Δu_k ≤ Δu_max
在Matlab中可以使用quadprog或MPC工具箱高效求解。
考虑经典的非线性倒立摆系统:
matlab复制function dx = pendulumDynamics(x,u)
g = 9.81; l = 1.0; m = 1.0; b = 0.1;
theta = x(1);
dtheta = x(2);
dx = [dtheta;
(m*g*l*sin(theta) - b*dtheta + u)/(m*l^2)];
end
使用EDMD方法学习Koopman算子:
matlab复制% 收集训练数据
[Z, Z_prime] = collectPendulumData();
% 构建EDMD问题
Psi = basisFunction(Z);
Psi_prime = basisFunction(Z_prime);
% 最小二乘求解
K = (Psi_prime * Psi') / (Psi * Psi');
与传统LQR和非线性MPC对比:
| 方法 | 计算时间(ms) | 稳定裕度(deg) | 抗扰能力 |
|---|---|---|---|
| LQR(线性化) | 0.1 | ±15° | 差 |
| 非线性MPC | 45.2 | ±35° | 优 |
| Koopman-MPC | 5.7 | ±32° | 良 |
增量学习:当系统参数变化时,可以在原Koopman矩阵基础上进行增量更新,避免重新训练
matlab复制function onlineUpdate(obj, newData)
% 递归最小二乘更新
[Psi, Psi_prime] = processData(newData);
obj.KoopmanMatrix = obj.KoopmanMatrix + ...
(Psi_prime - obj.KoopmanMatrix*Psi)*Psi'/(Psi*Psi' + lambda*eye(size(Psi,1)));
end
局部模型组合:在工作空间不同区域训练多个Koopman模型,使用时根据当前状态选择最合适的模型
问题1:预测误差随时间累积
问题2:MPC求解不稳定
问题3:实时性不达标
将Koopman方法扩展到多智能体系统,每个智能体的提升状态包含邻居信息:
matlab复制function g = multiAgentBasis(x_all, u)
n_agents = length(x_all);
g = [];
for i = 1:n_agents
% 自身状态
g_i = x_all{i};
% 邻居状态信息
neighbors = getNeighbors(i);
for j = neighbors
g_i = [g_i; x_all{j}];
end
g = [g; g_i];
end
end
用自动编码器学习最优提升空间:
matlab复制% 编码器网络
encoder = [
featureInputLayer(nx)
fullyConnectedLayer(64)
reluLayer
fullyConnectedLayer(32)
reluLayer
fullyConnectedLayer(nz)
];
% 解码器网络
decoder = [
featureInputLayer(nz)
fullyConnectedLayer(32)
reluLayer
fullyConnectedLayer(64)
reluLayer
fullyConnectedLayer(nx)
];
考虑模型不确定性的鲁棒Koopman-MPC:
min_u max_ΔK J(x,u)
s.t. z_{k+1} = (K+ΔK) z_k
‖ΔK‖ ≤ ρ
这种形式可以通过鲁棒优化技术求解,提高在模型失配情况下的控制性能。
在实际项目中,我发现Koopman-MPC特别适合那些需要频繁快速重新规划的场景。比如在无人机竞速比赛中,传统非线性MPC由于计算耗时,往往只能运行在20-30Hz,而Koopman-MPC可以轻松达到100Hz以上的控制频率,这对高速机动至关重要。