|
32 | 32 | %% ===== 第 1 步:参考模型与被控对象 ===== |
33 | 33 |
|
34 | 34 | % 参考模型:我们希望系统表现成的样子 |
35 | | -tau_m = 0.5; % 参考时间常数(快!) |
36 | | -sys_model = tf([1], [tau_m, 1]); |
| 35 | +tau = 0.5; % 公共时间常数(对象和模型相同,这是 MRAC 能完全匹配的前提) |
| 36 | +b_m = 1.0; % 参考模型直流增益 |
| 37 | +sys_model = tf([b_m], [tau, 1]); |
37 | 38 |
|
38 | | -% 真实被控对象:参数会变化(我们假装不知道) |
39 | | -tau_real = 2.0; % 真实时间常数(比参考模型慢很多) |
40 | | -sys_real = tf([1], [tau_real, 1]); |
| 39 | +% 真实被控对象:增益未知(比模型小),时间常数与模型相同 |
| 40 | +b_p = 0.5; % 真实对象直流增益(控制器不知道的真实值) |
| 41 | +sys_real = tf([b_p], [tau, 1]); |
41 | 42 |
|
42 | 43 | fprintf('【系统参数】\n'); |
43 | | -fprintf(' 参考模型: G_m(s) = 1/(%.1fs+1) — 理想行为(快)\n', tau_m); |
44 | | -fprintf(' 真实系统: G_p(s) = 1/(%.1fs+1) — 实际行为(慢 4 倍)\n', tau_real); |
45 | | -fprintf(' 目标: 通过自适应调整增益,让真实系统追平参考模型\n\n'); |
| 44 | +fprintf(' 参考模型: G_m(s) = %.0f/(%.1fs+1) — 理想行为\n', b_m, tau); |
| 45 | +fprintf(' 真实系统: G_p(s) = %.1f/(%.1fs+1) — 增益未知(真实 %.1f)\n', b_p, tau, b_p); |
| 46 | +fprintf(' 目标: 自适应增益 θ 补偿增益差异,使 θ·b_p → b_m\n\n'); |
46 | 47 |
|
47 | 48 | %% ===== 第 2 步:Simulink 模型搭建 ===== |
48 | 49 |
|
|
59 | 60 | add_block('simulink/Continuous/Transfer Fcn', [mdl '/Ref Model'], ... |
60 | 61 | 'Position', [350, 50, 440, 90]); |
61 | 62 | set_param([mdl '/Ref Model'], ... |
62 | | - 'Numerator', '[1]', 'Denominator', ['[' num2str(tau_m) ' 1]']); |
| 63 | + 'Numerator', num2str(b_m), 'Denominator', ['[' num2str(tau) ' 1]']); |
63 | 64 |
|
64 | 65 | % --- 自适应控制器路径 --- |
65 | 66 | % Apply Gain 模块:计算 θ(t) * r(t),直接驱动被控对象 |
|
70 | 71 | add_block('simulink/Continuous/Transfer Fcn', [mdl '/Real Plant'], ... |
71 | 72 | 'Position', [350, 160, 440, 200]); |
72 | 73 | set_param([mdl '/Real Plant'], ... |
73 | | - 'Numerator', '[1]', 'Denominator', ['[' num2str(tau_real) ' 1]']); |
| 74 | + 'Numerator', num2str(b_p), 'Denominator', ['[' num2str(tau) ' 1]']); |
74 | 75 |
|
75 | 76 | % --- 固定增益对比路径 --- |
76 | 77 | add_block('simulink/Math Operations/Gain', [mdl '/Fixed Gain'], ... |
|
80 | 81 | add_block('simulink/Continuous/Transfer Fcn', [mdl '/Real Plant Fixed'], ... |
81 | 82 | 'Position', [350, 310, 440, 350]); |
82 | 83 | set_param([mdl '/Real Plant Fixed'], ... |
83 | | - 'Numerator', '[1]', 'Denominator', ['[' num2str(tau_real) ' 1]']); |
| 84 | + 'Numerator', num2str(b_p), 'Denominator', ['[' num2str(tau) ' 1]']); |
84 | 85 |
|
85 | 86 | % --- MIT 自适应律:θ̇ = -γ · e · ym --- |
86 | 87 | add_block('simulink/Math Operations/Add', [mdl '/Error Calc'], ... |
|
167 | 168 |
|
168 | 169 | % 欧拉仿真 |
169 | 170 | for k = 1:N-1 |
170 | | - % 参考模型: τm·ẏm + ym = r |
171 | | - ym_dot = (r(k) - ym(k)) / tau_m; |
| 171 | + % 参考模型: τ·ẏm + ym = b_m·r |
| 172 | + ym_dot = (b_m * r(k) - ym(k)) / tau; |
172 | 173 | ym(k+1) = ym(k) + ym_dot * dt; |
173 | 174 |
|
174 | | - % 自适应对象: τp·ẏp + yp = θ·r |
175 | | - yp_dot = (theta(k) * r(k) - yp_adapt(k)) / tau_real; |
| 175 | + % 自适应对象: τ·ẏp + yp = θ·b_p·r |
| 176 | + yp_dot = (theta(k) * b_p * r(k) - yp_adapt(k)) / tau; |
176 | 177 | yp_adapt(k+1) = yp_adapt(k) + yp_dot * dt; |
177 | 178 |
|
178 | 179 | % 固定增益对象 |
179 | | - yp_dot_f = (K_fixed * r(k) - yp_fixed(k)) / tau_real; |
| 180 | + yp_dot_f = (K_fixed * b_p * r(k) - yp_fixed(k)) / tau; |
180 | 181 | yp_fixed(k+1) = yp_fixed(k) + yp_dot_f * dt; |
181 | 182 |
|
182 | 183 | % MIT 规则:dθ/dt = -γ · (yp - ym) · ym |
|
187 | 188 |
|
188 | 189 | %% ===== 第 4 步:系统参数突变 — 自适应 vs 固定 ===== |
189 | 190 |
|
190 | | -% 5 秒时 τ_real 从 2.0 突变为 4.0 |
191 | | -tau_init = tau_real; |
192 | | -tau_change_time = 5; |
193 | | -tau_changed = 4.0; |
| 191 | +% 5 秒时对象增益 b_p 从 0.5 突变为 0.25 |
| 192 | +b_p_init = b_p; |
| 193 | +b_change_time = 5; |
| 194 | +b_p_changed = 0.25; |
194 | 195 |
|
195 | 196 | ym2 = zeros(1, N); yp_a2 = zeros(1, N); |
196 | 197 | yp_f2 = zeros(1, N); theta2 = zeros(1, N); |
197 | 198 | theta2(1) = 1.0; |
198 | 199 |
|
199 | 200 | for k = 1:N-1 |
200 | | - % 当前真实时间常数 |
201 | | - if t(k) < tau_change_time |
202 | | - tau_now = tau_init; |
| 201 | + % 当前真实对象增益 |
| 202 | + if t(k) < b_change_time |
| 203 | + b_now = b_p_init; |
203 | 204 | else |
204 | | - tau_now = tau_changed; |
| 205 | + b_now = b_p_changed; |
205 | 206 | end |
206 | 207 |
|
207 | | - ym_dot = (r(k) - ym2(k)) / tau_m; |
| 208 | + ym_dot = (b_m * r(k) - ym2(k)) / tau; |
208 | 209 | ym2(k+1) = ym2(k) + ym_dot * dt; |
209 | 210 |
|
210 | | - yp_dot = (theta2(k) * r(k) - yp_a2(k)) / tau_now; |
| 211 | + yp_dot = (theta2(k) * b_now * r(k) - yp_a2(k)) / tau; |
211 | 212 | yp_a2(k+1) = yp_a2(k) + yp_dot * dt; |
212 | 213 |
|
213 | | - yp_dot_f = (K_fixed * r(k) - yp_f2(k)) / tau_now; |
| 214 | + yp_dot_f = (K_fixed * b_now * r(k) - yp_f2(k)) / tau; |
214 | 215 | yp_f2(k+1) = yp_f2(k) + yp_dot_f * dt; |
215 | 216 |
|
216 | 217 | e_adapt = yp_a2(k) - ym2(k); |
|
236 | 237 | % 图2:自适应增益变化 |
237 | 238 | subplot(2,2,2); hold on; |
238 | 239 | plot(t, theta, 'r', 'LineWidth', 1.5); |
239 | | -yline(1, 'b--', 'LineWidth', 1); % 理论最优值 θ* = 1(直流增益匹配) |
240 | | -text(t_end*0.6, 1*1.1, '理论最优 θ*=1(直流增益匹配)'); |
| 240 | +yline(b_m/b_p, 'b--', 'LineWidth', 1); % 理论最优 θ* = b_m/b_p |
| 241 | +text(t_end*0.6, b_m/b_p*1.1, sprintf('理论最优 θ*=b_m/b_p=%.1f', b_m/b_p)); |
241 | 242 | title('自适应增益 θ(t)'); |
242 | 243 | xlabel('时间 (s)'); ylabel('增益'); grid on; |
243 | | -fprintf(' 理论最优增益: θ* = 1 (直流增益匹配,G_p(0)=G_m(0)=1)\n'); |
| 244 | +fprintf(' 理论最优增益: θ* = %.1f (b_m/b_p = %.1f/%.1f)\n', b_m/b_p, b_m, b_p); |
244 | 245 | fprintf(' MIT 自适应最终收敛于 θ* 附近 ✓\n\n'); |
245 | 246 |
|
246 | 247 | % 图3:参数突变工况 |
|
249 | 250 | plot(t, ym2, 'b', 'LineWidth', 1.5); |
250 | 251 | plot(t, yp_a2, 'r', 'LineWidth', 1.5); |
251 | 252 | plot(t, yp_f2, 'Color', [0 0.6 0], 'LineWidth', 1); |
252 | | -xline(tau_change_time, 'k:', 'LineWidth', 1.5); |
253 | | -text(tau_change_time+0.2, 2.5, '参数突变!'); |
| 253 | +xline(b_change_time, 'k:', 'LineWidth', 1.5); |
| 254 | +text(b_change_time+0.2, 2.5, '参数突变!'); |
254 | 255 | legend('目标', '参考模型', '自适应', '固定增益', 'Location', 'southeast'); |
255 | | -title(sprintf('参数突变 (τ: %.1f→%.1f) 时对比', tau_init, tau_changed)); |
| 256 | +title(sprintf('参数突变 (b_p: %.2f→%.2f) 时对比', b_p_init, b_p_changed)); |
256 | 257 | xlabel('时间 (s)'); ylabel('输出'); grid on; |
257 | 258 |
|
258 | 259 | % 图4:突变后增益重新调整 |
259 | 260 | subplot(2,2,4); hold on; |
260 | 261 | plot(t, theta2, 'r', 'LineWidth', 1.5); |
261 | | -yline(1, 'b--', 'LineWidth', 1); |
262 | | -xline(tau_change_time, 'k:', 'LineWidth', 1.5); |
263 | | -legend('θ(t)', 'θ*=1', 'Location', 'best'); |
| 262 | +yline(b_m/b_p_init, 'b--', 'LineWidth', 1); |
| 263 | +yline(b_m/b_p_changed, 'g--', 'LineWidth', 1); |
| 264 | +xline(b_change_time, 'k:', 'LineWidth', 1.5); |
| 265 | +legend('θ(t)', '旧最优值', '新最优值', 'Location', 'best'); |
264 | 266 | title('参数突变后增益自适应重新收敛'); |
265 | 267 | xlabel('时间 (s)'); ylabel('增益'); grid on; |
266 | 268 |
|
|
0 commit comments