如何在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
相关产品推荐
相关产品推荐

