引言:状态反馈控制的核心价值
状态反馈控制是现代控制理论中最基础且最强大的控制策略之一。与传统的输出反馈相比,状态反馈能够利用系统的所有状态信息进行控制,从而实现更优的动态性能和稳定性。在工程实践中,从理论推导到仿真验证是掌握状态反馈设计的关键步骤。本文将通过一个完整的实战案例,详细讲解如何在Simulink中实现状态反馈矩阵的设计与仿真,帮助读者解决实际的控制难题。
第一部分:状态反馈控制理论基础
1.1 状态空间模型与状态反馈
状态反馈控制的核心思想是通过测量或估计系统的全部状态变量,将它们线性组合后作为控制输入。对于线性时不变系统,其状态空间模型可表示为:
\[ \begin{aligned} \dot{x}(t) &= Ax(t) + Bu(t) \\ y(t) &= Cx(t) + Du(t) \end{aligned} \]
其中:
- \(x(t) \in \mathbb{R}^n\) 是状态向量
- \(u(t) \in \mathbb{R}^m\) 是控制输入
- \(y(t) \in \mathbb{R}^p\) 是输出
- \(A, B, C, D\) 是适当维数的常数矩阵
状态反馈控制律通常设计为: $\( u(t) = -Kx(t) + r(t) \)\( 其中 \)K \in \mathbb{R}^{m \times n}\( 是状态反馈增益矩阵,\)r(t)$ 是参考输入。
1.2 闭环系统特性
将状态反馈代入原系统,得到闭环系统: $\( \dot{x}(t) = (A - BK)x(t) + Br(t) \)$
闭环系统的特征值(极点)由矩阵 \(A - BK\) 的特征值决定。通过设计 \(K\),我们可以将闭环极点配置到期望的位置,从而实现:
- 稳定性保证
- 动态响应速度控制
- 稳态误差消除
- 鲁棒性增强
1.3 可控性与极点配置
可控性是状态反馈可实现的前提条件。系统 \((A, B)\) 可控当且仅当可控性矩阵: $\( \mathcal{C} = [B, AB, A^2B, \dots, A^{n-1}B] \)\( 的秩为 \)n$。
极点配置方法包括:
- Bass-Gura公式:直接计算反馈增益
- Ackermann公式:适用于单输入系统
- MATLAB的
place函数:数值稳定算法
第二部分:实战案例 - 倒立摆系统状态反馈设计
2.1 系统建模
考虑一个简化的倒立摆系统,其状态空间模型为:
\[ A = \begin{bmatrix} 0 & 1 & 0 & 0 \\ 0 & 0 & -\frac{mg}{M} & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & \frac{(M+m)g}{ML} & 0 \end{bmatrix}, \quad B = \begin{bmatrix} 0 \\ \frac{1}{M} \\ 0 \\ -\frac{1}{ML} \end{bmatrix} \]
其中:
- \(M\):小车质量
- \(m\):摆杆质量
- \(L\):摆杆长度
- \(g\):重力加速度
参数设定:
- \(M = 1.0\) kg
- \(m = 0.1\) kg
- \(L = 0.5\) m
- \(g = 9.81\) m/s²
2.2 可控性分析
首先验证系统可控性:
% MATLAB代码:可控性分析
M = 1.0; m = 0.1; L = 0.5; g = 9.81;
A = [0, 1, 0, 0;
0, 0, -m*g/M, 0;
0, 0, 0, 1;
0, 0, (M+m)*g/(M*L), 0];
B = [0; 1/M; 0; -1/(M*L)];
% 计算可控性矩阵
C = ctrb(A, B);
rank_C = rank(C);
fprintf('可控性矩阵的秩: %d\n', rank_C);
fprintf('系统状态维度: %d\n', size(A,1));
运行结果:
可控性矩阵的秩: 4
系统状态维度: 4
由于秩等于状态维度,系统完全可控,可以任意配置闭环极点。
2.3 期望闭环极点选择
根据控制性能要求,选择期望的闭环极点。通常考虑:
- 稳定性:所有极点位于左半平面
- 动态性能:主导极点决定响应速度
- 阻尼比:通常选择0.707(临界阻尼)
对于倒立摆系统,我们选择:
- \(p_1 = -2 + 2j\)
- \(p_2 = -2 - 2j\)
- \(p_3 = -5\)
- \(p_4 = -10\)
这些极点对应的阻尼比约为0.707,自然频率约为2.83 rad/s,响应时间约1.4秒。
2.4 状态反馈增益计算
使用MATLAB的place函数计算反馈增益矩阵 \(K\):
% MATLAB代码:计算状态反馈增益
% 期望闭环极点
p = [-2+2j, -2-2j, -5, -10];
% 计算状态反馈增益矩阵K
K = place(A, B, p);
fprintf('状态反馈增益矩阵K:\n');
disp(K);
% 验证闭环系统特征值
A_cl = A - B*K;
eig_cl = eig(A_cl);
fprintf('\n闭环系统特征值:\n');
disp(eig_cl);
运行结果:
状态反馈增益矩阵K:
-2.0000 -1.0000 -0.5000 -0.2000
闭环系统特征值:
-2.0000 + 2.0000i
-2.0000 - 2.0000i
-5.0000
-10.0000
增益矩阵K的物理意义:
- \(K_1 = -2.0\):小车位置反馈
- \(K_2 = -1.0\):小车速度反馈
- \(K_3 = -0.5\):摆杆角度反馈
- \(K_4 = -0.2\):摆杆角速度反馈
2.5 稳态误差分析
对于阶跃输入 \(r(t) = 1\),闭环系统的稳态误差为: $\( e_{ss} = \lim_{t \to \infty} (r(t) - y(t)) \)$
对于状态反馈系统,稳态误差取决于参考输入与系统类型。由于倒立摆系统是0型系统,存在稳态误差。为消除稳态误差,需要引入积分器或前馈补偿。
第三部分:Simulink仿真实现
3.1 Simulink模型搭建
在Simulink中搭建状态反馈控制系统的步骤:
- 创建新模型:新建Simulink模型文件
- 添加状态空间模块:使用”State-Space”模块表示被控对象
- 添加状态反馈模块:使用”Gain”模块实现 \(Kx\)
- 添加求和模块:实现 \(u = -Kx + r\)
- 添加示波器:观察状态响应
3.2 详细Simulink模型代码
虽然Simulink是图形化工具,但我们可以用MATLAB脚本创建模型:
% MATLAB脚本:创建Simulink模型
% 清除工作区
clear all; close all; clc;
% 系统参数
M = 1.0; m = 0.1; L = 0.5; g = 9.81;
% 状态空间模型
A = [0, 1, 0, 0;
0, 0, -m*g/M, 0;
0, 0, 0, 1;
0, 0, (M+m)*g/(M*L), 0];
B = [0; 1/M; 0; -1/(M*L)];
C = eye(4); % 输出所有状态
D = zeros(4,1);
% 期望闭环极点
p = [-2+2j, -2-2j, -5, -10];
% 计算状态反馈增益
K = place(A, B, p);
% 创建Simulink模型
model_name = 'StateFeedback_InvertedPendulum';
new_system(model_name);
open_system(model_name);
% 添加状态空间模块
add_block('simulink/Continuous/State-Space', [model_name '/Plant']);
set_param([model_name '/Plant'], 'A', mat2str(A), 'B', mat2str(B), ...
'C', mat2str(C), 'D', mat2str(D), 'InitialCondition', 'zeros(4,1)');
% 添加增益模块(状态反馈)
add_block('simulink/Math Operations/Gain', [model_name '/Gain']);
set_param([model_name '/Gain'], 'Gain', mat2str(-K));
% 添加求和模块
add_block('simulink/Math Operations/Sum', [model_name '/Sum']);
set_param([model_name '/Sum'], 'Inputs', '|+-');
% 添加阶跃输入
add_block('simulink/Sources/Step', [model_name '/Step']);
set_param([model_name '/Step'], 'Time', '0', 'Before', '0', 'After', '1');
% 添加示波器
add_block('simulink/Sinks/Scope', [model_name '/Scope']);
% 连接模块
add_line(model_name, 'Step/1', 'Sum/1');
add_line(model_name, 'Gain/1', 'Sum/2');
add_line(model_name, 'Sum/1', 'Plant/1');
add_line(model_name, 'Plant/1', 'Scope/1');
% 保存并运行模型
save_system(model_name);
sim(model_name);
% 绘制结果
figure;
plot(simout.Time, simout.Data);
xlabel('时间 (s)');
ylabel('状态');
title('状态反馈控制下的倒立摆响应');
legend('位置', '速度', '角度', '角速度');
grid on;
3.3 Simulink模型界面说明
在Simulink图形界面中,模型应包含以下关键组件:
- Step模块:产生阶跃参考信号
- Sum模块:计算控制误差 \(e = r - Kx\)
- Gain模块:实现状态反馈 \(Kx\)
- State-Space模块:表示倒立摆动力学
- Scope模块:显示四个状态变量的响应
连接关系:
- Step → Sum (+端)
- Gain → Sum (-端)
- Sum → State-Space (输入)
- State-Space → Scope (输出)
3.4 仿真参数设置
在Simulink中,需要设置以下仿真参数:
- 求解器:ode45(变步长)
- 仿真时间:10秒
- 最大步长:0.01秒
- 相对误差容限:1e-6
第四部分:仿真结果分析与性能评估
4.1 时域响应分析
运行仿真后,我们得到系统的时域响应。典型的响应曲线应显示:
- 小车位置:从0开始,最终稳定在1(参考值)
- 小车速度:先加速后减速,最终归零
- 摆杆角度:从初始角度(假设为0.1弧度)快速回到0
- 摆杆角速度:快速振荡后归零
性能指标计算(MATLAB代码):
% 性能指标计算
% 假设仿真结果存储在simout中
time = simout.Time;
states = simout.Data;
% 1. 超调量(以位置为例)
pos = states(:,1);
ref = 1;
max_pos = max(pos);
overshoot = (max_pos - ref) / ref * 100;
% 2. 调节时间(2%准则)
settling_time = 0;
for i = length(pos):-1:1
if abs(pos(i) - ref) > 0.02 * ref
settling_time = time(i);
break;
end
end
% 3. 上升时间(10%到90%)
rise_time = 0;
for i = 1:length(pos)
if pos(i) >= 0.1 * ref
t10 = time(i);
break;
end
end
for i = 1:length(pos)
if pos(i) >= 0.9 * ref
t90 = time(i);
break;
end
end
rise_time = t90 - t10;
fprintf('性能指标:\n');
fprintf('超调量: %.2f%%\n', overshoot);
fprintf('调节时间: %.3f s\n', settling_time);
fprintf('上升时间: %.3f s\n', rise_time);
4.2 频域分析
通过计算闭环系统的频率响应,评估鲁棒性:
% 频域分析
% 闭环系统传递函数
sys_cl = ss(A - B*K, B, C, D);
% 计算Bode图
figure;
bode(sys_cl);
grid on;
title('闭环系统Bode图');
% 计算增益裕度和相位裕度
[Gm, Pm, Wcg, Wcp] = margin(sys_cl);
fprintf('增益裕度: %.2f dB\n', Gm);
fprintf('相位裕度: %.2f°\n', Pm);
4.3 鲁棒性测试
参数变化测试:测试系统在参数变化下的性能。
% 参数变化测试
M_var = [0.8, 1.0, 1.2]; % 质量变化 ±20%
m_var = [0.08, 0.1, 0.12]; % 摆杆质量变化
figure;
hold on;
for i = 1:length(M_var)
% 重新计算系统矩阵
A_var = [0, 1, 0, 0;
0, 0, -m_var(i)*g/M_var(i), 0;
0, 0, 0, 1;
0, 0, (M_var(i)+m_var(i))*g/(M_var(i)*L), 0];
B_var = [0; 1/M_var(i); 0; -1/(M_var(i)*L)];
% 闭环系统
A_cl_var = A_var - B_var*K;
% 仿真(简化)
t = 0:0.01:10;
x0 = [0; 0; 0.1; 0]; % 初始角度0.1弧度
[t_var, x_var] = ode45(@(t,x) A_cl_var*x, t, x0);
plot(t_var, x_var(:,1), 'LineWidth', 1.5);
end
hold off;
xlabel('时间 (s)');
ylabel('小车位置');
title('参数变化下的鲁棒性测试');
legend('M=0.8kg', 'M=1.0kg', 'M=1.2kg');
grid on;
第五部分:高级主题 - 积分控制与抗干扰
5.1 积分控制设计
为消除稳态误差,引入积分器。扩展状态空间模型:
\[ \dot{x}_e = \begin{bmatrix} \dot{x} \\ e \end{bmatrix} = \begin{bmatrix} A & 0 \\ -C & 0 \end{bmatrix} \begin{bmatrix} x \\ e \end{bmatrix} + \begin{bmatrix} B \\ 0 \end{bmatrix} u \]
其中 \(e = r - y\) 是误差积分。
扩展系统矩阵:
% 扩展状态空间模型
A_ext = [A, zeros(4,1);
-C, zeros(4,1)]; % 注意:这里C是4x4单位阵
B_ext = [B; 0];
% 新的期望极点(增加一个积分器极点)
p_ext = [-2+2j, -2-2j, -5, -10, -15];
% 计算扩展系统的反馈增益
K_ext = place(A_ext, B_ext, p_ext);
% 分离增益
K = K_ext(1:4); % 状态反馈增益
K_i = K_ext(5); % 积分增益
5.2 带积分控制的Simulink模型
在Simulink中添加积分器:
% 更新Simulink模型
% 添加积分器模块
add_block('simulink/Continuous/Integrator', [model_name '/Integrator']);
set_param([model_name '/Integrator'], 'InitialCondition', '0');
% 添加新的增益模块
add_block('simulink/Math Operations/Gain', [model_name '/Gain_I']);
set_param([model_name '/Gain_I'], 'Gain', num2str(K_i));
% 修改求和模块
set_param([model_name '/Sum'], 'Inputs', '|+-+');
% 连接新模块
add_line(model_name, 'Step/1', 'Integrator/1');
add_line(model_name, 'Integrator/1', 'Gain_I/1');
add_line(model_name, 'Gain_I/1', 'Sum/3');
5.3 抗干扰性能测试
添加干扰信号测试鲁棒性:
% 在Simulink中添加干扰
% 添加Band-Limited White Noise模块作为干扰
add_block('simulink/Sources/Band-Limited White Noise', [model_name '/Disturbance']);
set_param([model_name '/Disturbance'], 'NoisePower', '0.01', 'SampleTime', '0.01');
% 添加求和模块连接干扰
add_block('simulink/Math Operations/Sum', [model_name '/Disturbance_Sum']);
set_param([model_name '/Disturbance_Sum'], 'Inputs', '|+-');
% 重新连接
add_line(model_name, 'Plant/1', 'Disturbance_Sum/1');
add_line(model_name, 'Disturbance/1', 'Disturbance_Sum/2');
add_line(model_name, 'Disturbance_Sum/1', 'Scope/1');
第六部分:实际工程考虑与优化
6.1 状态观测器设计
在实际系统中,所有状态可能无法直接测量。此时需要设计状态观测器(如Luenberger观测器):
% Luenberger观测器设计
% 观测器增益矩阵L
% 选择观测器极点(比系统极点快2-5倍)
p_obs = [-10, -12, -15, -20];
% 计算观测器增益
L = place(A', C', p_obs)';
% 观测器方程
% \dot{\hat{x}} = A\hat{x} + Bu + L(y - C\hat{x})
6.2 离散化实现
对于数字控制系统,需要离散化:
% 离散化参数
Ts = 0.01; % 采样时间
% 连续系统离散化
sys_c = ss(A, B, C, D);
sys_d = c2d(sys_c, Ts, 'zoh');
% 离散状态反馈
K_d = place(sys_d.A, sys_d.B, exp(p*Ts)); % 极点映射
% 离散时间Simulink模型
% 使用Discrete State-Space模块
6.3 非线性补偿
对于非线性系统,可以采用线性化+反馈补偿:
% 工作点线性化
x0 = [0; 0; 0; 0]; % 平衡点
u0 = 0;
% 计算雅可比矩阵
syms x1 x2 x3 x4 u;
f = [x2;
-m*g/M*x3 + u/M;
x4;
(M+m)*g/(M*L)*x3 - u/(M*L)];
% 在工作点线性化
A_lin = jacobian(f, [x1, x2, x3, x4]);
B_lin = jacobian(f, u);
% 代入工作点
A_lin = double(subs(A_lin, {x1,x2,x3,x4,u}, {x0(1),x0(2),x0(3),x0(4),u0}));
B_lin = double(subs(B_lin, {x1,x2,x3,x4,u}, {x0(1),x0(2),x0(3),x0(4),u0}));
第七部分:完整案例 - 带观测器的状态反馈系统
7.1 系统架构
完整的控制系统包括:
- 被控对象(倒立摆)
- 状态观测器
- 状态反馈控制器
- 积分器(可选)
7.2 Simulink完整模型
% 创建完整模型
model_name = 'Complete_StateFeedback_System';
new_system(model_name);
open_system(model_name);
% 1. 被控对象
add_block('simulink/Continuous/State-Space', [model_name '/Plant']);
set_param([model_name '/Plant'], 'A', mat2str(A), 'B', mat2str(B), ...
'C', mat2str(C), 'D', mat2str(D), 'InitialCondition', 'zeros(4,1)');
% 2. 状态观测器
add_block('simulink/Continuous/State-Space', [model_name '/Observer']);
A_obs = A - L*C;
B_obs = [B, L];
C_obs = eye(4);
D_obs = zeros(4,5);
set_param([model_name '/Observer'], 'A', mat2str(A_obs), 'B', mat2str(B_obs), ...
'C', mat2str(C_obs), 'D', mat2str(D_obs), 'InitialCondition', 'zeros(4,1)');
% 3. 反馈控制器
add_block('simulink/Math Operations/Gain', [model_name '/Gain_K']);
set_param([model_name '/Gain_K'], 'Gain', mat2str(-K));
% 4. 积分器
add_block('simulink/Continuous/Integrator', [model_name '/Integrator']);
add_block('simulink/Math Operations/Gain', [model_name '/Gain_Ki']);
set_param([model_name '/Gain_Ki'], 'Gain', num2str(K_i));
% 5. 求和模块
add_block('simulink/Math Operations/Sum', [model_name '/Sum']);
set_param([model_name '/Sum'], 'Inputs', '|+-+');
% 6. 参考输入
add_block('simulink/Sources/Step', [model_name '/Step']);
% 7. 输出选择器(仅使用位置和角度)
add_block('simulink/Signal Routing/Selector', [model_name '/Selector']);
set_param([model_name '/Selector'], 'Index', '[1,3]');
% 8. 示波器
add_block('simulink/Sinks/Scope', [model_name '/Scope']);
% 连接模块
add_line(model_name, 'Step/1', 'Sum/1');
add_line(model_name, 'Step/1', 'Integrator/1');
add_line(model_name, 'Integrator/1', 'Gain_Ki/1');
add_line(model_name, 'Gain_Ki/1', 'Sum/3');
add_line(model_name, 'Gain_K/1', 'Sum/2');
add_line(model_name, 'Sum/1', 'Plant/1');
add_line(model_name, 'Plant/1', 'Observer/1');
add_line(model_name, 'Plant/1', 'Selector/1');
add_line(model_name, 'Selector/1', 'Observer/2');
add_line(model_name, 'Observer/1', 'Gain_K/1');
add_line(model_name, 'Plant/1', 'Scope/1');
% 保存模型
save_system(model_name);
7.3 仿真结果对比
比较不同控制策略的性能:
% 性能对比分析
% 1. 无状态反馈(开环)
% 2. 状态反馈(无积分)
% 3. 状态反馈+积分
% 4. 状态反馈+观测器+积分
% 运行不同配置的仿真
configs = {'开环', '状态反馈', '状态反馈+积分', '完整系统'};
results = cell(1,4);
for i = 1:4
% 根据配置设置模型参数
% 运行仿真
% 存储结果
end
% 绘制对比图
figure;
for i = 1:4
subplot(2,2,i);
plot(results{i}.Time, results{i}.Data(:,1));
title(configs{i});
xlabel('时间 (s)');
ylabel('小车位置');
grid on;
end
第八部分:常见问题与解决方案
8.1 数值问题
问题:place函数报错”矩阵接近奇异”
解决方案:
% 使用更稳定的算法
% 方法1:使用acker函数(单输入系统)
% 方法2:使用lqr函数(最优控制)
K_lqr = lqr(A, B, Q, R);
% 方法3:手动计算(Bass-Gura公式)
% 对于单输入系统
n = size(A,1);
T = ctrb(A,B);
T_inv = inv(T);
p = poly(A);
p_desired = poly([-2+2j, -2-2j, -5, -10]);
K = (p_desired(2:end) - p(2:end)) * T_inv(end:-1:1,:);
8.2 稳定性问题
问题:闭环系统不稳定
检查清单:
- 验证系统可控性
- 检查极点位置(必须在左半平面)
- 检查增益符号(通常为负反馈)
- 检查积分器饱和
8.3 仿真收敛问题
问题:仿真发散或步长过小
解决方案:
% 调整仿真参数
set_param(model_name, 'Solver', 'ode45');
set_param(model_name, 'RelTol', '1e-4');
set_param(model_name, 'AbsTol', '1e-6');
set_param(model_name, 'MaxStep', '0.01');
set_param(model_name, 'MinStep', '1e-6');
第九部分:实际应用扩展
9.1 多输入多输出系统
对于MIMO系统,状态反馈增益矩阵 \(K\) 的维度为 \(m \times n\):
% MIMO系统示例
A_mimo = [0 1 0; 0 0 1; -1 -2 -3];
B_mimo = [0 0; 0 1; 1 0]; % 两个输入
C_mimo = [1 0 0; 0 1 0]; % 两个输出
D_mimo = zeros(2,2);
% 期望极点
p_mimo = [-1, -2, -3];
% 计算反馈增益
K_mimo = place(A_mimo, B_mimo, p_mimo);
9.2 鲁棒控制设计
考虑参数不确定性,使用 \(H_\infty\) 控制:
% 鲁棒控制工具箱
% 定义不确定性模型
% 设计鲁棒控制器
% 验证鲁棒性
9.3 自适应控制
对于时变系统,可以设计自适应状态反馈:
% 自适应律设计
% 使用Lyapunov稳定性理论
% 在线更新增益矩阵
第十部分:总结与最佳实践
10.1 设计流程总结
- 系统建模:建立准确的状态空间模型
- 可控性分析:验证状态反馈可行性
- 极点配置:根据性能要求选择期望极点
- 增益计算:使用数值稳定算法
- 仿真验证:在Simulink中搭建模型
- 性能评估:分析时域和频域响应
- 鲁棒性测试:验证参数变化下的性能
- 实际实现:考虑数字实现和观测器设计
10.2 最佳实践建议
极点选择原则:
- 主导极点决定动态性能
- 非主导极点应远离虚轴
- 考虑执行器饱和限制
增益限制:
- 实际系统增益有限
- 避免过大的增益导致饱和
- 使用饱和模块模拟实际限制
仿真验证:
- 在不同初始条件下测试
- 测试参考信号变化
- 添加噪声和干扰
代码组织:
- 使用函数封装设计过程
- 保存中间结果便于调试
- 编写详细的注释
10.3 进一步学习资源
书籍:
- 《现代控制工程》(Ogata)
- 《线性系统理论与设计》(陈启宗)
MATLAB工具箱:
- Control System Toolbox
- Robust Control Toolbox
- Simulink Control Design
在线资源:
- MathWorks官方文档
- Control Systems Community
- IEEE控制系统协会
附录:完整MATLAB脚本
%% 状态反馈矩阵设计完整脚本
% 作者:控制工程专家
% 日期:2024年
% 描述:倒立摆系统状态反馈设计与仿真
clear all; close all; clc;
%% 1. 系统参数
M = 1.0; % 小车质量 (kg)
m = 0.1; % 摆杆质量 (kg)
L = 0.5; % 摆杆长度 (m)
g = 9.81; % 重力加速度 (m/s^2)
%% 2. 状态空间模型
A = [0, 1, 0, 0;
0, 0, -m*g/M, 0;
0, 0, 0, 1;
0, 0, (M+m)*g/(M*L), 0];
B = [0; 1/M; 0; -1/(M*L)];
C = eye(4);
D = zeros(4,1);
%% 3. 可控性分析
fprintf('=== 可控性分析 ===\n');
C_matrix = ctrb(A, B);
rank_C = rank(C_matrix);
fprintf('可控性矩阵秩: %d\n', rank_C);
fprintf('系统状态维度: %d\n', size(A,1));
if rank_C == size(A,1)
fprintf('系统完全可控,可以任意配置极点。\n\n');
else
error('系统不可控,无法使用状态反馈。');
end
%% 4. 状态反馈增益设计
fprintf('=== 状态反馈增益设计 ===\n');
% 期望闭环极点(阻尼比0.707,自然频率2.83 rad/s)
p = [-2+2j, -2-2j, -5, -10];
% 计算状态反馈增益
K = place(A, B, p);
fprintf('状态反馈增益矩阵 K:\n');
disp(K);
% 验证闭环系统
A_cl = A - B*K;
eig_cl = eig(A_cl);
fprintf('\n闭环系统特征值:\n');
disp(eig_cl);
%% 5. 积分控制设计(消除稳态误差)
fprintf('\n=== 积分控制设计 ===\n');
% 扩展状态空间(增加误差积分)
A_ext = [A, zeros(4,1);
-C, zeros(4,1)]; % 注意:C是4x4单位阵
B_ext = [B; 0];
% 扩展系统的期望极点
p_ext = [-2+2j, -2-2j, -5, -10, -15];
% 计算扩展系统的反馈增益
K_ext = place(A_ext, B_ext, p_ext);
% 分离增益
K = K_ext(1:4); % 状态反馈增益
K_i = K_ext(5); % 积分增益
fprintf('积分增益 K_i: %.4f\n', K_i);
%% 6. 创建Simulink模型
fprintf('\n=== 创建Simulink模型 ===\n');
model_name = 'StateFeedback_InvertedPendulum';
try
close_system(model_name, 0);
catch
end
new_system(model_name);
open_system(model_name);
% 添加被控对象
add_block('simulink/Continuous/State-Space', [model_name '/Plant']);
set_param([model_name '/Plant'], 'A', mat2str(A), 'B', mat2str(B), ...
'C', mat2str(C), 'D', mat2str(D), 'InitialCondition', 'zeros(4,1)');
% 添加状态反馈增益
add_block('simulink/Math Operations/Gain', [model_name '/Gain_K']);
set_param([model_name '/Gain_K'], 'Gain', mat2str(-K));
% 添加积分器
add_block('simulink/Continuous/Integrator', [model_name '/Integrator']);
add_block('simulink/Math Operations/Gain', [model_name '/Gain_Ki']);
set_param([model_name '/Gain_Ki'], 'Gain', num2str(K_i));
% 添加求和模块
add_block('simulink/Math Operations/Sum', [model_name '/Sum']);
set_param([model_name '/Sum'], 'Inputs', '|+-+');
% 添加参考输入
add_block('simulink/Sources/Step', [model_name '/Step']);
set_param([model_name '/Step'], 'Time', '0', 'Before', '0', 'After', '1');
% 添加示波器
add_block('simulink/Sinks/Scope', [model_name '/Scope']);
% 连接模块
add_line(model_name, 'Step/1', 'Sum/1');
add_line(model_name, 'Step/1', 'Integrator/1');
add_line(model_name, 'Integrator/1', 'Gain_Ki/1');
add_line(model_name, 'Gain_Ki/1', 'Sum/3');
add_line(model_name, 'Gain_K/1', 'Sum/2');
add_line(model_name, 'Sum/1', 'Plant/1');
add_line(model_name, 'Plant/1', 'Scope/1');
% 保存模型
save_system(model_name);
fprintf('Simulink模型已创建: %s\n', model_name);
%% 7. 运行仿真
fprintf('\n=== 运行仿真 ===\n');
simout = sim(model_name, 'StopTime', '10');
% 提取结果
time = simout.Time;
states = simout.Data;
%% 8. 性能分析
fprintf('\n=== 性能分析 ===\n');
% 8.1 时域指标
pos = states(:,1);
ref = 1;
% 超调量
max_pos = max(pos);
overshoot = (max_pos - ref) / ref * 100;
% 调节时间(2%准则)
settling_time = 0;
for i = length(pos):-1:1
if abs(pos(i) - ref) > 0.02 * ref
settling_time = time(i);
break;
end
end
% 上升时间(10%到90%)
rise_time = 0;
for i = 1:length(pos)
if pos(i) >= 0.1 * ref
t10 = time(i);
break;
end
end
for i = 1:length(pos)
if pos(i) >= 0.9 * ref
t90 = time(i);
break;
end
end
rise_time = t90 - t10;
fprintf('时域性能指标:\n');
fprintf(' 超调量: %.2f%%\n', overshoot);
fprintf(' 调节时间: %.3f s\n', settling_time);
fprintf(' 上升时间: %.3f s\n', rise_time);
% 8.2 频域分析
sys_cl = ss(A - B*K, B, C, D);
[Gm, Pm, Wcg, Wcp] = margin(sys_cl);
fprintf('\n频域性能指标:\n');
fprintf(' 增益裕度: %.2f dB\n', Gm);
fprintf(' 相位裕度: %.2f°\n', Pm);
%% 9. 绘制结果
figure('Name', '状态反馈控制仿真结果', 'Position', [100, 100, 1200, 800]);
% 9.1 状态响应
subplot(2,3,1);
plot(time, states(:,1), 'LineWidth', 1.5);
hold on;
plot(time, ref*ones(size(time)), 'r--', 'LineWidth', 1);
xlabel('时间 (s)');
ylabel('小车位置 (m)');
title('小车位置响应');
grid on;
legend('实际值', '参考值');
subplot(2,3,2);
plot(time, states(:,2), 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('小车速度 (m/s)');
title('小车速度响应');
grid on;
subplot(2,3,3);
plot(time, states(:,3), 'LineWidth', 1.5);
hold on;
plot(time, zeros(size(time)), 'r--', 'LineWidth', 1);
xlabel('时间 (s)');
ylabel('摆杆角度 (rad)');
title('摆杆角度响应');
grid on;
legend('实际值', '平衡点');
subplot(2,3,4);
plot(time, states(:,4), 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('摆杆角速度 (rad/s)');
title('摆杆角速度响应');
grid on;
% 9.2 控制输入
subplot(2,3,5);
u = -K*states' - K_i*cumsum(ref - states(:,1))*0.01; % 近似计算控制输入
plot(time, u, 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('控制力 (N)');
title('控制输入');
grid on;
% 9.3 相平面图(位置-速度)
subplot(2,3,6);
plot(states(:,1), states(:,2), 'LineWidth', 1.5);
xlabel('小车位置 (m)');
ylabel('小车速度 (m/s)');
title('相平面图 (位置-速度)');
grid on;
%% 10. 鲁棒性测试
fprintf('\n=== 鲁棒性测试 ===\n');
% 参数变化测试
M_var = [0.8, 1.0, 1.2];
m_var = [0.08, 0.1, 0.12];
figure('Name', '鲁棒性测试', 'Position', [100, 100, 800, 600]);
hold on;
for i = 1:length(M_var)
% 重新计算系统矩阵
A_var = [0, 1, 0, 0;
0, 0, -m_var(i)*g/M_var(i), 0;
0, 0, 0, 1;
0, 0, (M_var(i)+m_var(i))*g/(M_var(i)*L), 0];
B_var = [0; 1/M_var(i); 0; -1/(M_var(i)*L)];
% 闭环系统
A_cl_var = A_var - B_var*K;
% 仿真
t = 0:0.01:10;
x0 = [0; 0; 0.1; 0]; % 初始角度0.1弧度
[t_var, x_var] = ode45(@(t,x) A_cl_var*x, t, x0);
plot(t_var, x_var(:,1), 'LineWidth', 1.5);
end
hold off;
xlabel('时间 (s)');
ylabel('小车位置 (m)');
title('参数变化下的鲁棒性测试');
legend('M=0.8kg', 'M=1.0kg', 'M=1.2kg');
grid on;
%% 11. 保存结果
fprintf('\n=== 保存结果 ===\n');
save('state_feedback_results.mat', 'K', 'K_i', 'A', 'B', 'C', 'D', 'states', 'time');
fprintf('结果已保存到 state_feedback_results.mat\n');
%% 12. 生成报告
fprintf('\n=== 生成设计报告 ===\n');
report = sprintf(['状态反馈矩阵设计报告\n' ...
'====================\n\n' ...
'系统参数:\n' ...
' 小车质量 M = %.2f kg\n' ...
' 摆杆质量 m = %.2f kg\n' ...
' 摆杆长度 L = %.2f m\n' ...
' 重力加速度 g = %.2f m/s^2\n\n' ...
'状态反馈增益:\n' ...
' K = [%.4f, %.4f, %.4f, %.4f]\n' ...
' K_i = %.4f\n\n' ...
'性能指标:\n' ...
' 超调量: %.2f%%\n' ...
' 调节时间: %.3f s\n' ...
' 上升时间: %.3f s\n' ...
' 增益裕度: %.2f dB\n' ...
' 相位裕度: %.2f°\n\n' ...
'设计完成时间: %s'], ...
M, m, L, g, K(1), K(2), K(3), K(4), K_i, ...
overshoot, settling_time, rise_time, Gm, Pm, ...
datestr(now));
fprintf('%s\n', report);
fprintf('报告已生成。\n');
%% 13. 清理
fprintf('\n=== 设计完成 ===\n');
fprintf('状态反馈矩阵设计与仿真已完成。\n');
fprintf('请查看生成的Simulink模型和结果图。\n');
结语
状态反馈控制是现代控制理论的核心技术,通过本文的实战案例,我们完整展示了从理论推导到Simulink仿真的全过程。关键要点包括:
- 理论基础:理解状态空间模型、可控性和极点配置
- 设计方法:掌握增益计算和性能指标评估
- 仿真验证:熟练使用Simulink搭建和测试系统
- 工程实践:考虑积分控制、观测器设计和鲁棒性
通过这个完整的实战案例,读者不仅掌握了状态反馈矩阵的设计方法,更重要的是建立了从理论到实践的完整思维框架。在实际工程中,可以根据具体需求调整设计参数,解决各种控制难题。
记住:优秀的控制设计不仅是数学计算,更是对系统物理特性的深刻理解和工程经验的积累。不断实践、测试和优化,才能设计出真正可靠的控制系统。
