You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MATLAB中结合LQR与卡尔曼滤波器实现LQG控制器?

嘿,我来帮你搞定LQR和卡尔曼滤波整合为LQG控制器的问题!其实核心逻辑非常直观——就是让卡尔曼滤波器输出的状态估计值$\hat{x}$,代替LQR原本需要的真实状态$x$,直接喂给LQR的控制律就行。下面我一步步给你拆解,结合MATLAB代码来演示:

第一步:确认基础模块正常工作

首先得确保你单独实现的LQR和卡尔曼滤波都能正常运行:

  • LQR部分:你应该已经通过lqr函数算出了控制增益矩阵K
  • 卡尔曼滤波部分:你需要有估计器增益Kf(MATLAB里也常叫这个为卡尔曼增益),以及对应的过程/测量噪声协方差矩阵Qn、Rn
第二步:MATLAB里的整合核心代码

LQG的闭环逻辑很清晰:先让卡尔曼滤波器根据系统输出和输入估计状态,再把这个估计值代入LQR控制律计算输入。结合你给出的系统矩阵Akal, Bkal, Ckal, Dkal(其中Bkal=[B1,B2],B1是控制输入矩阵,B2是扰动输入矩阵),给你一个可直接参考的代码框架:

1. 先计算LQR控制增益

% 替换成你自己定义的状态权重Q和输入权重R
Q = diag([10, 10, 1]); % 示例:假设3维状态,权重按需调整
R = 0.1; % 示例:单输入的权重

% 注意这里要传入Bkal的第一列(对应控制输入的B1)
[K, ~, ~] = lqr(Akal, Bkal(:,1), Q, R);

2. 实现卡尔曼滤波器

你可以用MATLAB自带的kalman函数快速生成,也可以手动实现预测-更新步骤:

% 替换成你系统的过程噪声协方差Qn和测量噪声协方差Rn
Qn = diag([0.1, 0.1, 0.01]); % 示例过程噪声
Rn = 0.5; % 示例测量噪声

% 生成卡尔曼滤波器,Kf就是估计器增益
[Kf, P, ~] = kalman(ss(Akal, Bkal, Ckal, Dkal), Qn, Rn);

3. 闭环仿真整合

下面是一个离散时间的仿真示例,把两者串起来:

% 仿真参数设置
t_final = 10;
dt = 0.01;
t = 0:dt:t_final;
n_steps = length(t);

% 初始化状态和输入
x_true = zeros(size(Akal,1), 1); % 系统真实状态
x_hat = zeros(size(Akal,1), 1); % 卡尔曼估计的状态
u = zeros(size(Bkal(:,1),2), 1); % 控制输入
y = Ckal*x_true + Dkal*[u; zeros(size(Bkal(:,2),2),1)] + sqrt(Rn)*randn(size(Ckal,1),1);

% 存储数据用于绘图
x_history = zeros(size(Akal,1), n_steps);
x_hat_history = zeros(size(Akal,1), n_steps);
u_history = zeros(size(Bkal(:,1),2), n_steps);

% 仿真循环
for i = 1:n_steps
    % 存储当前数据
    x_history(:,i) = x_true;
    x_hat_history(:,i) = x_hat;
    u_history(:,i) = u;
    
    % --- 卡尔曼滤波:预测+更新 ---
    % 预测步:根据上一时刻的估计和输入预测当前状态
    x_hat_pred = Akal*x_hat + Bkal*[u; zeros(size(Bkal(:,2),2),1)];
    % 更新步:用当前测量值修正预测结果
    innovation = y - Ckal*x_hat_pred - Dkal*[u; zeros(size(Bkal(:,2),2),1)];
    x_hat = x_hat_pred + Kf*innovation;
    
    % --- LQR控制律:用估计状态计算输入 ---
    u = -K*x_hat; % 如果是跟踪问题,可改成 u = -K*(x_hat - x_ref),x_ref是参考状态
    
    % --- 真实系统状态更新(加入噪声) ---
    process_noise = sqrt(Qn)*randn(size(Akal,1),1);
    disturbance = zeros(size(Bkal(:,2),2),1); % 可替换成真实扰动
    x_true = Akal*x_true + Bkal*[u; disturbance] + process_noise;
    
    % --- 更新测量值 ---
    measurement_noise = sqrt(Rn)*randn(size(Ckal,1),1);
    y = Ckal*x_true + Dkal*[u; disturbance] + measurement_noise;
end

% 绘图查看结果
figure;
subplot(3,1,1); plot(t, x_history'); title('真实系统状态'); xlabel('时间(s)');
subplot(3,1,2); plot(t, x_hat_history'); title('卡尔曼估计状态'); xlabel('时间(s)');
subplot(3,1,3); plot(t, u_history'); title('控制输入'); xlabel('时间(s)');
几个关键注意事项
  • 矩阵维度要对应:Bkal=[B1,B2],所以LQR计算时要传入Bkal(:,1)(只取控制输入对应的列),卡尔曼滤波则要传入完整的Bkal(因为要考虑扰动输入)
  • 噪声协方差Qn和Rn的设定很重要:如果噪声水平估计不准,卡尔曼滤波的状态估计精度会下降,进而影响LQG的控制效果
  • 如果你用的是连续时间系统,可以直接用MATLAB的lqg函数一键生成LQG控制器,省去手动整合的麻烦:
[lqg_controller, K, Kf] = lqg(ss(Akal, Bkal, Ckal, Dkal), Q, R, Qn, Rn);
% 之后可以用lsim函数直接仿真闭环系统
lsim(lqg_controller, t);

内容的提问来源于stack exchange,提问作者Cled1990

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:06:37