Ajouter fichier matlab
This commit is contained in:
parent
653268a307
commit
7a28f921b3
16 changed files with 525 additions and 0 deletions
21
matlab/LICENSE
Executable file
21
matlab/LICENSE
Executable file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Charles Poussot-Vassal
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
30
matlab/README.md
Executable file
30
matlab/README.md
Executable file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
This page accompany the three lectures and five labs given at INSA Toulouse. The repository contains three folders:
|
||||||
|
|
||||||
|
- `+insapack`: gathers MATLAB routines for (i) signals generation and (ii) identification (in the Loewner Framework);
|
||||||
|
- `documents`: provides the main refenerences used to build this course;
|
||||||
|
- `lectures`: gathers the lecture supports.
|
||||||
|
|
||||||
|
# The "insapack" MATLAB package
|
||||||
|
|
||||||
|
The code (`+insapack` folder) provided in this GitHub page is given for open education purpose. Its principal objective is to accompany the students, and thus aims at being as educative as possible rather than industry-oriented. Evolutions (numerical improvements) may come with time. Please, cite the references suggested in the `documents` folde if used in your work and do not hesitate to contact me in case of bug of problem when using it.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- MATLAB R2023b or later (tested on this version)
|
||||||
|
- Toolboxes: "System Identification Toolbox" and "Control System Toolbox"
|
||||||
|
|
||||||
|
## A simple MATLAB code example
|
||||||
|
|
||||||
|
Here is a simple code that describes how to deploy the INSAPACK. Code below is `demo_main.m`.
|
||||||
|
|
||||||
|
## Feedbacks
|
||||||
|
|
||||||
|
Please send any comment to C. Poussot-Vassal (charles.poussot-vassal@onera.fr) if you want to report any bug or user experience issues.
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
This deposit consitutes a research code that accompany the paper mentionned above. It is not aimed to be included in any third party software without the consent of the authors. Authors decline responsabilities in case of problem when applying the code.
|
||||||
|
|
||||||
|
Notice also that pathological cases may appear. A more advanced and professional code, to deal with practical and theoretical issues/limitations is currently under development by the authors.
|
||||||
84
matlab/demo_LQ.m
Executable file
84
matlab/demo_LQ.m
Executable file
|
|
@ -0,0 +1,84 @@
|
||||||
|
% DEMO LQ CONTROL
|
||||||
|
% Author: C. Poussot-Vassal [MOR Digital Systems / Onera]
|
||||||
|
% Date : December 2014 (creation)
|
||||||
|
% March 2022 (update)
|
||||||
|
%
|
||||||
|
% Description
|
||||||
|
% Demonstration script for LQ control design and robustness properties.
|
||||||
|
% This small script illustrates how to construct and analyse the LQ control
|
||||||
|
% design in a SISO setting. In particular, we compute the LQ controller by
|
||||||
|
% solving the CARE equation, then we illustrate some classic margin
|
||||||
|
% properties of this special and well known control method.
|
||||||
|
%
|
||||||
|
% Note
|
||||||
|
% The script uses the "+insapack" matlab package.
|
||||||
|
%
|
||||||
|
clear all, close all, clc;
|
||||||
|
set(groot,'DefaultFigurePosition', [300 100 1000 600]);
|
||||||
|
set(groot,'defaultlinelinewidth',2)
|
||||||
|
set(groot,'defaultlinemarkersize',14)
|
||||||
|
set(groot,'defaultaxesfontsize',18)
|
||||||
|
list_factory = fieldnames(get(groot,'factory')); index_interpreter = find(contains(list_factory,'Interpreter')); for iloe1 = 1:length(index_interpreter); set(groot, strrep(list_factory{index_interpreter(iloe1)},'factory','default'),'latex'); end
|
||||||
|
|
||||||
|
%%% INSAPACK
|
||||||
|
addpath('/Users/charles/Documents/GIT/insapack')
|
||||||
|
|
||||||
|
%%% >> Chose a SISO model (2 cases are proposed)
|
||||||
|
nom = 'tf4'
|
||||||
|
%nom = 'random'
|
||||||
|
switch lower(nom)
|
||||||
|
case 'tf4'
|
||||||
|
Gs = tf([1 9 6],conv([1/100 2*.3/10 1],[10 5 1]));
|
||||||
|
Gs_ss = ss(Gs);
|
||||||
|
case 'random'
|
||||||
|
Gs_ss = stabsep(rss(30));
|
||||||
|
Gs = tf(Gs_ss);
|
||||||
|
end
|
||||||
|
|
||||||
|
%%% >> LQ control with infinite horizon, u = -K*(x-x_ref)
|
||||||
|
% Design parameters
|
||||||
|
[A,B,C,D] = ssdata(Gs_ss);
|
||||||
|
n = length(A);
|
||||||
|
nu = size(B,2);
|
||||||
|
R = eye(nu);
|
||||||
|
%
|
||||||
|
rho = 1e3; % You may play with rho>0
|
||||||
|
Q = rho*eye(n);
|
||||||
|
% Continuous Algebraic Riccati Equation resolution ...
|
||||||
|
[P,L,G] = care(A,B,Q,R); % CARE
|
||||||
|
% ... and controller construction
|
||||||
|
K = R\eye(nu)*B'*P; % Optimal control u = -Kx
|
||||||
|
% Transfer of interest
|
||||||
|
Ls = tf(ss(A,B,K,0)); % Loop transfer => for robustness
|
||||||
|
Ss = (1+Ls)\1; % Sensitivity function => for disturbance rejection
|
||||||
|
Ts = 1-Ss; % Complementary sensitivity function
|
||||||
|
h = 1/(C*((-A+B*K)\B)); % Steady-state closed-loop gain
|
||||||
|
CLs = h*tf(ss(A-B*K,B,C,0)); % Closed-loop => input-output performance
|
||||||
|
% Margin and Hinf-norm
|
||||||
|
gamma = norm(CLs,inf) % Hinf norm
|
||||||
|
S = allmargin(Ls) % Margins
|
||||||
|
% Frequency responses
|
||||||
|
figure
|
||||||
|
subplot(121), hold on
|
||||||
|
bodemag(Ss,'b',Ts,'r-',tf(1,1),'k-'), grid on
|
||||||
|
title('Sensitivity function')
|
||||||
|
legend('$S(\imath \omega)$','$T(\imath \omega)$','1','Location','Best')
|
||||||
|
subplot(122), hold on
|
||||||
|
sigma(CLs,'b',gamma*tf(1,1),'r'), grid on
|
||||||
|
title('Closed-loop')
|
||||||
|
legend('$T(\imath \omega)$','$\gamma$','Location','Best')
|
||||||
|
% Robustness margin illustration
|
||||||
|
figure
|
||||||
|
subplot(121), hold on
|
||||||
|
margin(Ls)
|
||||||
|
legend('$L(\imath \omega)$','Location','Best')
|
||||||
|
subplot(122), hold on
|
||||||
|
nyquist(Ls,'b-'), grid on
|
||||||
|
theta = linspace(0,2*pi,1e3);
|
||||||
|
plot(cos(theta),sin(theta),'g-');
|
||||||
|
plot(cos(theta)-.5,sin(theta),'r--');
|
||||||
|
legend('$L(\imath \omega)$','PM = $L(\imath \omega)$ crosses circle','$L(\imath \omega)$ outside circle','Location','Best'), axis equal
|
||||||
|
% %% Step response
|
||||||
|
% figure, hold on
|
||||||
|
% step(Gs,'b-')
|
||||||
|
% step(CLs,'r-')
|
||||||
246
matlab/demo_main.m
Executable file
246
matlab/demo_main.m
Executable file
|
|
@ -0,0 +1,246 @@
|
||||||
|
clear all, close all, clc;
|
||||||
|
set(groot,'DefaultFigurePosition', [100 100 1300 600]);
|
||||||
|
set(groot,'defaultlinelinewidth',2)
|
||||||
|
set(groot,'defaultlinemarkersize',14)
|
||||||
|
set(groot,'defaultaxesfontsize',18)
|
||||||
|
list_factory = fieldnames(get(groot,'factory')); index_interpreter = find(contains(list_factory,'Interpreter')); for iloe1 = 1:length(index_interpreter); set(groot, strrep(list_factory{index_interpreter(iloe1)},'factory','default'),'latex'); end
|
||||||
|
|
||||||
|
%%% INSAPACK
|
||||||
|
addpath('/Users/charles/Documents/GIT/insapack')
|
||||||
|
col = colororder;
|
||||||
|
|
||||||
|
%%% System to identify (chose 1, 2 or 3)
|
||||||
|
CAS = 1;
|
||||||
|
switch CAS
|
||||||
|
case 1
|
||||||
|
G = tf([1 -2],[.1 .4 1]); G = G/dcgain(G);
|
||||||
|
% Frequency
|
||||||
|
w = logspace(-2,2.5,300);
|
||||||
|
ratio = 5;
|
||||||
|
maxEig = max(abs(eig(G)));
|
||||||
|
wmax = ratio*maxEig;
|
||||||
|
fmax = wmax/2/pi;
|
||||||
|
Fs = 2^(nextpow2(fmax)+1);
|
||||||
|
Ws = 2*pi*Fs;
|
||||||
|
Ts = 1/Fs;
|
||||||
|
% Duration
|
||||||
|
Ns = 2^9;
|
||||||
|
% Non-parametric
|
||||||
|
P = 50;
|
||||||
|
noise_i = .1;
|
||||||
|
noise_o = .2;
|
||||||
|
% Identification
|
||||||
|
nx = 2;
|
||||||
|
case 2
|
||||||
|
rng(1);
|
||||||
|
G = stabsep(rss(20,1,1));
|
||||||
|
% Frequency
|
||||||
|
w = logspace(-2,2.5,300);
|
||||||
|
ratio = 5;
|
||||||
|
maxEig = max(abs(eig(G)));
|
||||||
|
wmax = ratio*maxEig;
|
||||||
|
fmax = wmax/2/pi;
|
||||||
|
Fs = 2^(nextpow2(fmax)+1);
|
||||||
|
Ws = 2*pi*Fs;
|
||||||
|
Ts = 1/Fs;
|
||||||
|
% Duration
|
||||||
|
Ns = 2^12;
|
||||||
|
% Non-parametric
|
||||||
|
P = 50;
|
||||||
|
noise_i = .1;
|
||||||
|
noise_o = .2;
|
||||||
|
% Identification
|
||||||
|
nx = 8%10;
|
||||||
|
case 3
|
||||||
|
rng(1);
|
||||||
|
G = stabsep(rss(100,1,1));
|
||||||
|
% Frequency
|
||||||
|
w = logspace(-2,2,300);
|
||||||
|
ratio = 5;
|
||||||
|
maxEig = max(abs(eig(G)));
|
||||||
|
wmax = ratio*maxEig;
|
||||||
|
fmax = wmax/2/pi;
|
||||||
|
Fs = 2^(nextpow2(fmax)+1);
|
||||||
|
Ws = 2*pi*Fs;
|
||||||
|
Ts = 1/Fs;
|
||||||
|
% Duration
|
||||||
|
Ns = 2^11;
|
||||||
|
% Non-parametric
|
||||||
|
P = 7;
|
||||||
|
noise_i = .1;
|
||||||
|
noise_o = .3;
|
||||||
|
% Identification
|
||||||
|
nx = 5;
|
||||||
|
end
|
||||||
|
% %%% Noise generator
|
||||||
|
% Gn = tf(n*[1/20 1],[1/100 1]);
|
||||||
|
% eigGn = eig(Gn);
|
||||||
|
% frGn = freqresp(Gn,w);
|
||||||
|
%%% Original system analysis
|
||||||
|
eigG = eig(G);
|
||||||
|
frG = freqresp(G,w);
|
||||||
|
theta = linspace(pi/2,3*pi/2,500);
|
||||||
|
figure
|
||||||
|
subplot(2,2,[1 3]),
|
||||||
|
plot(real(eigG),imag(eigG),'.','DisplayName','$\lambda(\mathbf G)$'), grid on, xlabel('Real'), ylabel('Imag.'), hold on
|
||||||
|
%plot(real(eigGn),imag(eigGn),'x','DisplayName','$\lambda(\mathbf G_n)$'),
|
||||||
|
plot(maxEig*cos(theta),maxEig*sin(theta),'--','DisplayName','$|\lambda_{max}|$'),
|
||||||
|
plot(wmax*cos(theta),wmax*sin(theta),'--','DisplayName',['$' num2str(ratio) '|\lambda_{max}|$']),
|
||||||
|
plot(Ws*cos(theta),Ws*sin(theta),'--','DisplayName','$2\pi F_s$'),
|
||||||
|
hh = gca;
|
||||||
|
plot([0 0],hh.YLim,'k:','DisplayName','Stability limit')
|
||||||
|
legend('show','location','best'), axis equal
|
||||||
|
title('Eigenvalues')
|
||||||
|
subplot(222)
|
||||||
|
plot(w,20*log10(abs(frG(:))),'-','DisplayName','$\mathbf G$'), set(gca,'XScale','log'), grid on, xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'), hold on
|
||||||
|
%plot(w,20*log10(abs(frGn(:))),'-','DisplayName','$\mathbf G_n$'), set(gca,'XScale','log'), grid on, xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'), hold on
|
||||||
|
axis tight, hh = gca;
|
||||||
|
plot([1 1]*maxEig,hh.YLim,'--','DisplayName','$|\lambda_{max}|$'),
|
||||||
|
plot([1 1]*wmax,hh.YLim,'--','DisplayName',['$' num2str(ratio) '|\lambda_{max}|$']),
|
||||||
|
plot([1 1]*Ws,hh.YLim,'--','DisplayName','$2\pi F_s$')
|
||||||
|
legend('show','location','best')
|
||||||
|
title('Bode gain')
|
||||||
|
subplot(224)
|
||||||
|
plot(w,angle(frG(:)),'-','DisplayName','$\mathbf G$'), set(gca,'XScale','log'), grid on, xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'), hold on
|
||||||
|
%plot(w,angl(frGn(:)),'-','DisplayName','$\mathbf G_n$'), set(gca,'XScale','log'), grid on, xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'), hold on
|
||||||
|
axis tight, hh = gca;
|
||||||
|
plot([1 1]*maxEig,hh.YLim,'--','DisplayName','$|\lambda_{max}|$'),
|
||||||
|
plot([1 1]*wmax,hh.YLim,'--','DisplayName',['$' num2str(ratio) '|\lambda_{max}|$']),
|
||||||
|
plot([1 1]*Ws,hh.YLim,'--','DisplayName','$2\pi F_s$')
|
||||||
|
legend('show','location','best')
|
||||||
|
title('Bode phase')
|
||||||
|
%%
|
||||||
|
%%% Generate exciting signal
|
||||||
|
FBND = [0 Fs/4];
|
||||||
|
REV = false;
|
||||||
|
SHOW = true;
|
||||||
|
RPHI = false;
|
||||||
|
ODD = 'all';
|
||||||
|
[u,t,info] = insapack.multisine(Ns,Ts,FBND,RPHI,ODD,REV,SHOW);
|
||||||
|
u = u.'; t = t.';
|
||||||
|
|
||||||
|
%%% Apply to system to be identified
|
||||||
|
y = lsim(G,u,t);
|
||||||
|
for i = 1:P
|
||||||
|
% +i/o noise
|
||||||
|
nin = noise_i*randn(length(t),1);
|
||||||
|
nout = noise_o*randn(length(t),1);
|
||||||
|
un(:,i) = u.*(1+nin);
|
||||||
|
yn(:,i) = y.*(1+nout);
|
||||||
|
end
|
||||||
|
[f0,U0,Y0,G0,sigU2,sigY2,sigUY2,sigG2,b,rho] = insapack.non_param_freq(un,yn,Ts);
|
||||||
|
w0 = 2*pi*f0;
|
||||||
|
|
||||||
|
%%% Data
|
||||||
|
figure,
|
||||||
|
subplot(221); hold on, grid on, axis tight
|
||||||
|
h1=plot(t,yn,'-','Color',[1 1 1]*.8,'DisplayName','$\mathbf G+n$');
|
||||||
|
h2=plot(t,y,'-','Color',col(1,:),'DisplayName','$\mathbf G$');
|
||||||
|
legend('show',[h1(1) h2(1)]),
|
||||||
|
title('Data vs. model')
|
||||||
|
xlabel('time [s]'), ylabel('Output'),
|
||||||
|
%
|
||||||
|
subplot(222); hold on, grid on, axis tight
|
||||||
|
plot(w,20*log10(abs(frG(:))),'-','DisplayName','$\mathbf G(\imath\omega)$')
|
||||||
|
plot(w0,20*log10(abs(G0(:))),'.','DisplayName','$\mathbf G_0(\imath\omega)$')
|
||||||
|
hh = gca;
|
||||||
|
plot([1 1]*wmax,hh.YLim,'--','DisplayName',['$' num2str(ratio) '|\lambda_{max}|$']),
|
||||||
|
plot([1 1]*Ws/2,hh.YLim,'--','DisplayName','$\pi F_s$')
|
||||||
|
plot([1 1]*2*pi*max(FBND),hh.YLim,'--','DisplayName','Max. exct. signal')
|
||||||
|
set(gca,'XScale','log')
|
||||||
|
legend('show','Location','best')
|
||||||
|
title('Bode gain')
|
||||||
|
xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'),
|
||||||
|
%
|
||||||
|
subplot(224); hold on, grid on, axis tight
|
||||||
|
plot(w,angle(frG(:)),'-','DisplayName','$\mathbf G(\imath\omega)$')
|
||||||
|
plot(w0,angle(G0(:)),'.','DisplayName','$\mathbf G_0(\imath\omega)$')
|
||||||
|
hh = gca;
|
||||||
|
plot([1 1]*wmax,hh.YLim,'--','DisplayName',['$' num2str(ratio) '|\lambda_{max}|$']),
|
||||||
|
plot([1 1]*Ws/2,hh.YLim,'--','DisplayName','$\pi F_s$')
|
||||||
|
plot([1 1]*2*pi*max(FBND),hh.YLim,'--','DisplayName','Max. exct. signal')
|
||||||
|
set(gca,'XScale','log')
|
||||||
|
legend('show','Location','best')
|
||||||
|
title('Bode phase')
|
||||||
|
xlabel('Pulsation [rad/s]'), ylabel('Phase [rad]'),
|
||||||
|
%%
|
||||||
|
%%% Identification via N4SID
|
||||||
|
Hn4sid = n4sid(u,mean(yn,2),nx,'Ts',Ts);
|
||||||
|
Hn4sid_td = d2c(stabsep(ss(Hn4sid)),'tustin');
|
||||||
|
frHn4sid_td = freqresp(Hn4sid_td,w);
|
||||||
|
eigHn4sid_td = eig(Hn4sid_td);
|
||||||
|
|
||||||
|
%%% Identification via N4SID in frequency-domain
|
||||||
|
data = iddata(Y0,U0,Ts,'Frequency',w0);
|
||||||
|
Hn4sid_fd = n4sid(data,nx);
|
||||||
|
Hn4sid_fd = d2c(stabsep(ss(Hn4sid_fd)),'tustin');
|
||||||
|
frHn4sid_fd = freqresp(Hn4sid_fd,w);
|
||||||
|
eigHn4sid_fd = eig(Hn4sid_fd);
|
||||||
|
|
||||||
|
%%% Identification via Loewner
|
||||||
|
wid = 2*pi*f0(f0<FBND(end)/2);
|
||||||
|
wRange = 1:floor(length(wid)/2)*2;
|
||||||
|
wid = 2*pi*f0(wRange);
|
||||||
|
G0id = G0(wRange);
|
||||||
|
[la,mu,W,V,R,L] = insapack.data2loewner(wid,G0);
|
||||||
|
opt.target = nx;
|
||||||
|
[hr,info] = insapack.loewner_tng(la,mu,W,V,R,L,opt);
|
||||||
|
Hloe = dss(info.Ar,info.Br,info.Cr,info.Dr,info.Er);
|
||||||
|
Hloe = stabsep(Hloe);
|
||||||
|
frHloe = freqresp(Hloe,w);
|
||||||
|
eigHloe = eig(Hloe);
|
||||||
|
|
||||||
|
%%% Validation signal
|
||||||
|
[uv,tv,infov] = insapack.mlbs(Ns,Ts,FBND,REV,SHOW); uv = uv.'; tv = tv.';
|
||||||
|
%[uv,tv,infov] = insapack.chirp(Ns,Ts,FBND,REV,'linear',SHOW); uv = uv.'; tv = tv.';
|
||||||
|
yv = lsim(G,uv,tv);
|
||||||
|
yn4sid_td = lsim(Hn4sid_td,uv,tv);
|
||||||
|
yn4sid_fd = lsim(Hn4sid_fd,uv,tv);
|
||||||
|
yloe = lsim(Hloe,uv,tv);
|
||||||
|
|
||||||
|
figure
|
||||||
|
subplot(221); hold on, grid on, axis tight
|
||||||
|
plot(tv,yv,'-','DisplayName','$\mathbf G$');
|
||||||
|
plot(tv,yn4sid_td,'--','DisplayName','$\mathbf H_{n4sid}$ (time-domain)');
|
||||||
|
plot(tv,yn4sid_fd,'--','DisplayName','$\mathbf H_{n4sid}$ (freq.-domain)');
|
||||||
|
plot(tv,yloe,'--','DisplayName','$\mathbf H_{loe}$');
|
||||||
|
legend('show'),
|
||||||
|
subplot(223),hold on, grid on, axis equal
|
||||||
|
plot(real(eigG),imag(eigG),'o','DisplayName','$\lambda(\mathbf G)$'), grid on,
|
||||||
|
plot(real(eigHn4sid_td),imag(eigHn4sid_td),'x','DisplayName','$\lambda(\mathbf H_{n4sid})$ (time-domain)')
|
||||||
|
plot(real(eigHn4sid_fd),imag(eigHn4sid_fd),'x','DisplayName','$\lambda(\mathbf H_{n4sid})$ (freq.-domain)')
|
||||||
|
plot(real(eigHloe),imag(eigHloe),'s','DisplayName','$\lambda(\mathbf H_{loe})$')
|
||||||
|
plot(maxEig*cos(theta),maxEig*sin(theta),'k--','DisplayName','$|\lambda_{max}|$'),
|
||||||
|
hh = gca;
|
||||||
|
plot([0 0],hh.YLim,'k:','DisplayName','Stability limit')
|
||||||
|
legend('show','Location','best'),
|
||||||
|
xlabel('Real'), ylabel('Imag.'), hold on
|
||||||
|
subplot(222); hold on, grid on, axis tight
|
||||||
|
plot(w,20*log10(abs(frG(:))),'-','DisplayName','$\mathbf G(\imath\omega)$')
|
||||||
|
plot(w,20*log10(abs(frHn4sid_td(:))),'--','DisplayName','$\mathbf H_{n4sid}$ (time-domain)')
|
||||||
|
plot(w,20*log10(abs(frHn4sid_fd(:))),'--','DisplayName','$\mathbf H_{n4sid}$ (freq.-domain)')
|
||||||
|
plot(w,20*log10(abs(frHloe(:))),'--','DisplayName','$\mathbf H_{loe}$')
|
||||||
|
set(gca,'XScale','log'),
|
||||||
|
legend('show','Location','best')
|
||||||
|
title('Bode gain'), xlabel('Pulsation [rad/s]'), ylabel('Gain [dB]'),
|
||||||
|
subplot(224); hold on, grid on, axis tight
|
||||||
|
plot(w,angle(frG(:)),'-','DisplayName','$\mathbf G(\imath\omega)$')
|
||||||
|
plot(w,angle(frHn4sid_td(:)),'--','DisplayName','$\mathbf H_{n4sid}$ (time-domain)')
|
||||||
|
plot(w,angle(frHn4sid_fd(:)),'--','DisplayName','$\mathbf H_{n4sid}$ (freq.-domain)')
|
||||||
|
plot(w,angle(frHloe(:)),'--','DisplayName','$\mathbf H_{loe}$')
|
||||||
|
set(gca,'XScale','log'),
|
||||||
|
legend('show','Location','best')
|
||||||
|
title('Bode phase'), xlabel('Pulsation [rad/s]'), ylabel('Phase [rad]'),
|
||||||
|
|
||||||
|
%%% Metrics
|
||||||
|
N = length(yv);
|
||||||
|
En4sid_td = 1/N*sum(abs(yv-yn4sid_td)/max(abs(yv)));
|
||||||
|
En4sid_fd = 1/N*sum(abs(yv-yn4sid_fd)/max(abs(yv)));
|
||||||
|
Eloe = 1/N*sum(abs(yv-yloe)/max(abs(yv)));
|
||||||
|
sgtitle(sprintf('TD errors: $%0.2f$ (N4SID-TD) / $%0.2f$ (N4SID-FD) / $%0.2f$ (LF)',En4sid_td,En4sid_fd,Eloe),'interpreter','latex','FontSize',20)
|
||||||
|
|
||||||
|
% %%
|
||||||
|
% figure,
|
||||||
|
% plot(info.sv,'-o'), grid on, axis tight
|
||||||
|
% set(gca,'YScale','log')
|
||||||
|
% xlabel('Index $k$'), ylabel('Singular value'), title('Normalized Loewner singular value')
|
||||||
BIN
matlab/expe1.mat
Executable file
BIN
matlab/expe1.mat
Executable file
Binary file not shown.
BIN
matlab/expe2_multisine.mat
Executable file
BIN
matlab/expe2_multisine.mat
Executable file
Binary file not shown.
BIN
matlab/expe3_multisine.mat
Executable file
BIN
matlab/expe3_multisine.mat
Executable file
Binary file not shown.
BIN
matlab/expe4_multisine.mat
Executable file
BIN
matlab/expe4_multisine.mat
Executable file
Binary file not shown.
BIN
matlab/expe5_multisine.mat
Executable file
BIN
matlab/expe5_multisine.mat
Executable file
Binary file not shown.
BIN
matlab/identification.rxw64
Executable file
BIN
matlab/identification.rxw64
Executable file
Binary file not shown.
BIN
matlab/identification.slx
Executable file
BIN
matlab/identification.slx
Executable file
Binary file not shown.
144
matlab/identificationScript.m
Executable file
144
matlab/identificationScript.m
Executable file
|
|
@ -0,0 +1,144 @@
|
||||||
|
%% Initialisation
|
||||||
|
clc
|
||||||
|
clear all
|
||||||
|
close all
|
||||||
|
%load expe1.mat simout
|
||||||
|
%load expe2_multisine.mat
|
||||||
|
%load expe3_multisine.mat
|
||||||
|
%load expe4_multisine.mat
|
||||||
|
load expe5_multisine.mat
|
||||||
|
|
||||||
|
%% Variables
|
||||||
|
N = 2^9; % Nombre
|
||||||
|
Te = 5e-2; % Temps d'échantillonage
|
||||||
|
fdeb = 0; % fréquence de début d'échantillonage
|
||||||
|
ffin = 4; % fréquence de fin d'éch.
|
||||||
|
BP = [fdeb, ffin]; % Bande passante
|
||||||
|
REV = false; % Si on passe de fdeb à ffin ou l'inverse (booléen)
|
||||||
|
SHOW = true; % Montre les résultats (graphes) du MLBS (booléen)
|
||||||
|
|
||||||
|
%[u, t] = insapack.mlbs(N, Te, BP, REV, SHOW);
|
||||||
|
[u, t] = insapack.multisine(N, Te, BP, false,'all',REV, SHOW);
|
||||||
|
u = 4*u;
|
||||||
|
% var.time = t.';
|
||||||
|
% var.signals.values=u.';
|
||||||
|
% var.signals.dimensions= 1 ;
|
||||||
|
%%
|
||||||
|
% Muligens litt for hoey frekvens, den maa kanskje skrus litt ned. Deretter
|
||||||
|
% finner vi modell ved bruk av div. verktoey.
|
||||||
|
|
||||||
|
% figure()
|
||||||
|
% hold on;
|
||||||
|
% plot(simout.time, simout.signals.values)
|
||||||
|
% plot(var.time, var.signals.values)
|
||||||
|
|
||||||
|
%%% N4SID
|
||||||
|
tn = simout.time; % On enlève les dix primières valeurs
|
||||||
|
un = var.signals.values; % On enlève les dix primières valeurs
|
||||||
|
yn = simout.signals.values; % On enlève les dix primières valeurs
|
||||||
|
data = iddata(yn,un,Te);
|
||||||
|
ordre = 2;
|
||||||
|
sys = n4sid(data, ordre, 'Ts',Te);
|
||||||
|
y = lsim(ss(sys), un, tn);
|
||||||
|
H = tf(sys);
|
||||||
|
G = (H)/(1-H);
|
||||||
|
numG = G.Numerator;
|
||||||
|
denumG = G.Denominator;
|
||||||
|
|
||||||
|
|
||||||
|
%%% Freq
|
||||||
|
[f0,U0,Y0,G0,sigU2,sigY2,sigUY2,sigG2,b,rho] = insapack.non_param_freq(un,yn,Te);
|
||||||
|
w0 = 2*pi*f0;
|
||||||
|
|
||||||
|
%%% Identification via N4SID in frequency-domain
|
||||||
|
data = iddata(Y0,U0,Te,'Frequency',w0); %Ici peut-etre changer avec f0, comme ça il marche très mieux avec Loewner
|
||||||
|
Hn4sid_fd = n4sid(data,ordre);
|
||||||
|
y2 = lsim(ss(Hn4sid_fd), un, tn);
|
||||||
|
|
||||||
|
%%% Identification via Loewner
|
||||||
|
wid = 2*pi*f0(f0<BP(end)/2);
|
||||||
|
wRange = 1:floor(length(wid)/2)*2;
|
||||||
|
wid = 2*pi*f0(wRange);
|
||||||
|
G0id = G0(wRange);
|
||||||
|
[la,mu,W,V,R,L] = insapack.data2loewner(wid,G0);
|
||||||
|
opt.target = ordre;
|
||||||
|
[hr,info] = insapack.loewner_tng(la,mu,W,V,R,L,opt);
|
||||||
|
Hloe = dss(info.Ar,info.Br,info.Cr,info.Dr,info.Er);
|
||||||
|
Hloe = stabsep(Hloe);
|
||||||
|
y3 = lsim(ss(Hloe), un, tn);
|
||||||
|
|
||||||
|
%%% Plots
|
||||||
|
figure()
|
||||||
|
subplot(211)
|
||||||
|
plot(tn, un)
|
||||||
|
legend("Signal d'entrée (d'exitation)")
|
||||||
|
subplot(212)
|
||||||
|
hold on;
|
||||||
|
plot(tn, yn)
|
||||||
|
plot(tn, y)
|
||||||
|
plot(tn, y2)
|
||||||
|
plot(tn, y3)
|
||||||
|
legend('Signal de sortie observée','Sortie simuléee avec n4sid en temporel', 'Sortie simuléee avec n4sid en fréquenciel', 'Sortie simuléee avec Loewner')
|
||||||
|
|
||||||
|
|
||||||
|
var2 = var;
|
||||||
|
var2.signals.values(1:100) = 1;
|
||||||
|
var2.signals.values(101:200) = 3.3;
|
||||||
|
var2.signals.values(201:300) = 0;
|
||||||
|
var2.signals.values(301:400) = 1.5;
|
||||||
|
var2.signals.values(401:503) = 2.7;
|
||||||
|
|
||||||
|
%% Comment est-ce qu'on a trouvé la valeur du P dans notre système rail
|
||||||
|
Gc=d2c(G)
|
||||||
|
consigne = 1;
|
||||||
|
P = [ 0.8 1 1.5 2 3 5];
|
||||||
|
figure()
|
||||||
|
hold on;
|
||||||
|
|
||||||
|
for i = 1:1:length(P)
|
||||||
|
Gcf = P(i)*Gc/(1+P(i)*Gc);
|
||||||
|
step(Gcf,10)
|
||||||
|
end;
|
||||||
|
yline(0);
|
||||||
|
title("Reponse d'échelon du système rail");
|
||||||
|
legend("Kp=0.8","Kp=1","Kp=1.5","Kp=2","Kp=3","Kp=5");
|
||||||
|
|
||||||
|
|
||||||
|
%% Bille
|
||||||
|
g = 9.81
|
||||||
|
|
||||||
|
a = 10
|
||||||
|
b = 0.2 % V/cm sur le rail, +-10V pour le rail de +-50cm
|
||||||
|
Kb = b*g
|
||||||
|
T = 0.22
|
||||||
|
Kp = 1
|
||||||
|
|
||||||
|
Gb = tf([Kb], [1 0 0])
|
||||||
|
|
||||||
|
figure()
|
||||||
|
bode(Gb)
|
||||||
|
%margin(Gb)
|
||||||
|
title('Bode système rail')
|
||||||
|
|
||||||
|
Cb = tf([a*T 1], [T, 1])*Kp; %Correcteur d'avance de phase
|
||||||
|
|
||||||
|
figure()
|
||||||
|
bode(Cb)
|
||||||
|
title('Bode correcteur avance de phase')
|
||||||
|
|
||||||
|
%% marge de phase
|
||||||
|
figure()
|
||||||
|
title("Marge de phase et gain pour le système complet");
|
||||||
|
Hc = d2c(H);
|
||||||
|
Lbo = Cb*Hc*Gb;
|
||||||
|
Lbf = Lbo / (1+Lbo);
|
||||||
|
Margin = allmargin(Lbf);
|
||||||
|
h=bodeplot(Lbf);
|
||||||
|
margin(Lbf);
|
||||||
|
title({'Marge de phase et gain pour le système complet','Gm= Inf Pm =-40.6 deg (at 5.97rad/s)'});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
matlab/identificationSim.slx
Executable file
BIN
matlab/identificationSim.slx
Executable file
Binary file not shown.
BIN
matlab/identificationSimOld.rxw64
Executable file
BIN
matlab/identificationSimOld.rxw64
Executable file
Binary file not shown.
BIN
matlab/identificationSimOld.slx
Executable file
BIN
matlab/identificationSimOld.slx
Executable file
Binary file not shown.
BIN
matlab/identificationSimOld.slx.r2020a
Executable file
BIN
matlab/identificationSimOld.slx.r2020a
Executable file
Binary file not shown.
Loading…
Reference in a new issue