Advertisement
shmile03

Untitled

May 3rd, 2025
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 6.91 KB | None | 0 0
  1. % robust_stability_tools.m
  2. % Набор функций для анализа робастной устойчивости
  3.  
  4. function robust_stability_square(ncffs, bcffs)
  5. % robust_stability_square - строит годограф Цыпкина–Поляка и квадраты для
  6. % проверки робастной устойчивости по квадратам.
  7. % Входные данные:
  8. %   ncffs - вектор номинальных коэффициентов [a_n ... a_0]
  9. %   bcffs - вектор границ коэффициентов изменений [b_n ... b_0]
  10.  
  11.     % Построение вспомогательных полиномов U0, Ua, V0, Va
  12.     rev_nc = flip(ncffs);
  13.     tmp_u = rev_nc(1:2:end);
  14.     for i = 1:length(tmp_u)
  15.         if mod(i-1,2)==1, tmp_u(i) = -tmp_u(i); end
  16.     end
  17.     u0cffs = flip(tmp_u);
  18.     uacffs = flip(flip(bcffs)(1:2:end)); %# 求 bcffs(end:-2:1) 然后反转
  19.  
  20.     rev_nc2 = ncffs(end-1:-2:1);
  21.     tmp_v = rev_nc2;
  22.     for i = 1:length(tmp_v)
  23.         if mod(i-1,2)==1, tmp_v(i) = -tmp_v(i); end
  24.     end
  25.     v0cffs = flip(tmp_v);
  26.     vacffs = flip(flip(bcffs(end-1:-2:1)));
  27.  
  28.     % Параметры для построения
  29.     count = 5001;
  30.     omega = linspace(0, 100, count);
  31.     xy = zeros(2, count);
  32.     for k = 1:count
  33.         xy(1,k) = polyval(u0cffs, omega(k)) / polyval(uacffs, omega(k));
  34.         xy(2,k) = polyval(v0cffs, omega(k)) / polyval(vacffs, omega(k));
  35.     end
  36.  
  37.     % Вычисление корней полиномов wp и wm
  38.     wp = conv(u0cffs, vacffs) - conv(v0cffs, uacffs);
  39.     wm = conv(u0cffs, vacffs) + conv(v0cffs, uacffs);
  40.     rts_wp = roots(wp);
  41.     rts_wm = roots(wm);
  42.     rts = [rts_wp; rts_wm];
  43.     rts = rts(real(rts)>0 & abs(imag(rts))<1e-8);
  44.  
  45.     deltas = arrayfun(@(r) polyval(u0cffs,r)/polyval(uacffs,r), rts);
  46.     labels = arrayfun(@(d) sprintf("%.3f", abs(d)), deltas, 'UniformOutput',false);
  47.     cmap = jet(5);
  48.  
  49.     % Построение графика
  50.     figure; hold on;
  51.     plot(xy(1,:), xy(2,:), 'b', 'LineWidth',2);
  52.     for k = 1:length(deltas)
  53.         d = deltas(k);
  54.         vtx = [ d,-d,-d, d, d; d, d,-d,-d, d];
  55.         plot(vtx(1,:), vtx(2,:), 'Color', cmap(end-k+1,:), 'LineWidth',2);
  56.     end
  57.     grid on; axis equal;
  58.     legend(labels);
  59.     title('Робастная устойчивость: квадрат');
  60.     hold off;
  61. end
  62.  
  63. function min_radius = robust_stability_disk(ncffs, bcffs)
  64. % robust_stability_disk - строит годограф и окружности радиусов роб.уст.
  65. % Возвращает минимальный радиус.
  66.  
  67.     % Формирование полиномов
  68.     U0 = flip(apply_alternating_signs(flip(ncffs(1:2:end))));
  69.     Ua = flip(bcffs(1:2:end));
  70.     V0 = flip(apply_alternating_signs(ncffs(end-1:-2:1)));
  71.     Va = flip(bcffs(end-1:-2:1));
  72.  
  73.     % Производные
  74.     U0p = polyder(U0); Ua_p = polyder(Ua);
  75.     V0p = polyder(V0); Va_p = polyder(Va);
  76.  
  77.     % Построение A и B
  78.     A = conv(U0p, Ua) - conv(U0, Ua_p);
  79.     B = conv(V0p, Va) - conv(V0, Va_p);
  80.  
  81.     % Кубы
  82.     Va3 = conv(conv(Va,Va),Va);
  83.     Ua3 = conv(conv(Ua,Ua),Ua);
  84.  
  85.     % Уравнение
  86.     T1 = conv(conv(U0, A), Va3);
  87.     T2 = conv(conv(V0, B), Ua3);
  88.     eqpoly = T1 + T2;
  89.  
  90.     % Корни и радиусы
  91.     rts = roots(eqpoly);
  92.     rts = unique(round(real(rts(imag(rts)==0 & real(rts)>0)),6));
  93.     radii = arrayfun(@(r) norm([ polyval(U0,r)/polyval(Ua,r), polyval(V0,r)/polyval(Va,r) ]), rts);
  94.     radii = sort(radii);
  95.  
  96.     % Годограф
  97.     omega = linspace(0,100,10001);
  98.     x = polyval(U0,omega)./polyval(Ua,omega);
  99.     y = polyval(V0,omega)./polyval(Va,omega);
  100.     figure; hold on;
  101.     plot(x,y,'b');
  102.     phi = linspace(0,2*pi,100);
  103.     for r = radii
  104.         plot(r*cos(phi), r*sin(phi),'--','DisplayName',sprintf('R=%.2f',r));
  105.     end
  106.     axis equal; grid on; legend; title('Робастная устойчивость: диск');
  107.     hold off;
  108.  
  109.     if isempty(radii), min_radius = Inf; else min_radius = radii(1); end
  110. end
  111.  
  112. function H = hurwitz_matrix_(coeffs)
  113. % hurwitz_matrix_ - строит матрицу Гурвица для Routh-Hurwitz
  114.     n = length(coeffs)-1;
  115.     if coeffs(1)<=0, error('Старший коэффициент должен быть положительным.'); end
  116.     H = zeros(n);
  117.     num = 0;
  118.     while num <= floor(n/2)
  119.         cur_i = 2*num+1; cur_j = num+1; cnt=1;
  120.         while cnt <= length(coeffs)
  121.             try
  122.                 H(cur_i,cur_j) = coeffs(cnt);
  123.             end
  124.             switch mod(cnt-1,4)
  125.                 case 0, cur_i = cur_i-1;
  126.                 case {1,3}, cur_i = cur_i+1; cur_j = cur_j+1;
  127.                 case 2, cur_i = cur_i-1;
  128.             end
  129.             cnt = cnt+1;
  130.         end
  131.         num = num+1;
  132.     end
  133. end
  134.  
  135. function [is_stable, H, minors] = check_hurwitz_stability(coeffs)
  136. % check_hurwitz_stability - проверка по главным минорам матрицы Гурвица
  137.     n = length(coeffs)-1;
  138.     H = hurwitz_matrix_(coeffs);
  139.     disp('Матрица Гурвица:'); disp(H);
  140.     minors = zeros(1,n);
  141.     for k=1:n
  142.         M = H(1:k,1:k);
  143.         minors(k) = det(M);
  144.         fprintf('Минор M%d = %.4f\n', k, minors(k));
  145.     end
  146.     is_stable = all(minors>0);
  147. end
  148.  
  149. function is_robust = check_robust_stability_kharitonov(low, up)
  150. % check_robust_stability_kharitonov - проверка по полиномам Харитонова
  151.     if any(low<=0)
  152.         disp('Есть не положительные коэффициенты -> не робастно устойчив.');
  153.         is_robust = false; return;
  154.     end
  155.     l = length(low);
  156.     % Формирование 4 полиномов
  157.     nn = zeros(1,l); nv = nn; vn = nn; vv = nn;
  158.     for i=1:l
  159.         idx = mod(i-1,4);
  160.         nn(i) = low(i)   * (idx<=1) + up(i)   * (idx>1);
  161.         nv(i) = up(i)    * (idx>=1&&idx<=2) + low(i)*(~(idx>=1&&idx<=2));
  162.         vn(i) = low(i)   * (idx>=1&&idx<=2) + up(i) *(~(idx>=1&&idx<=2));
  163.         vv(i) = up(i)    * (idx<=1) + low(i)  * (idx>1);
  164.     end
  165.     polys = {nn,nv,vn,vv}; names = {'NN','NV','VN','VV'};
  166.     for k=1:4
  167.         fprintf('Полином %s:\n', names{k});
  168.         [ok,~,~] = check_hurwitz_stability(polys{k});
  169.         if ~ok
  170.             disp('-> Не робастно устойчив.'); is_robust = false; return;
  171.         end
  172.     end
  173.     disp('-> Многочлен робастно устойчив.'); is_robust = true;
  174. end
  175.  
  176. function r_c = robust_stability_radii(A,B,C)
  177. % robust_stability_radii - вычисление радиуса h-inf нормы
  178. % A' = A + B*Delta*C, r_c = 1/||Delta||∞
  179.     r_c = 1 / h_inf_norm_lmi_continuous(A,B,C);
  180. end
  181.  
  182. % Вспомогательная функция для чередования знаков
  183. function out = apply_alternating_signs(vec)
  184.     out = vec;
  185.     for i = 1:length(vec)
  186.         if mod(i-1,2)==1, out(i) = -out(i); end
  187.     end
  188. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement