init
This commit is contained in:
28
.gitattributes
vendored
Normal file
28
.gitattributes
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
* text=auto
|
||||||
|
|
||||||
|
*.fig binary
|
||||||
|
*.mat binary
|
||||||
|
*.mdl binary diff merge=mlAutoMerge
|
||||||
|
*.mdlp binary
|
||||||
|
*.mex* binary
|
||||||
|
*.mlapp binary
|
||||||
|
*.mldatx binary
|
||||||
|
*.mlproj binary
|
||||||
|
*.mlx binary
|
||||||
|
*.p binary
|
||||||
|
*.sfx binary
|
||||||
|
*.sldd binary
|
||||||
|
*.slreqx binary merge=mlAutoMerge
|
||||||
|
*.slmx binary merge=mlAutoMerge
|
||||||
|
*.sltx binary
|
||||||
|
*.slxc binary
|
||||||
|
*.slx binary merge=mlAutoMerge
|
||||||
|
*.slxp binary
|
||||||
|
|
||||||
|
## Other common binary file types
|
||||||
|
*.docx binary
|
||||||
|
*.exe binary
|
||||||
|
*.jpg binary
|
||||||
|
*.pdf binary
|
||||||
|
*.png binary
|
||||||
|
*.xlsx binary
|
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Autosave files
|
||||||
|
*.asv
|
||||||
|
*.m~
|
||||||
|
*.autosave
|
||||||
|
*.slx.r*
|
||||||
|
*.mdl.r*
|
||||||
|
|
||||||
|
# Derived content-obscured files
|
||||||
|
*.p
|
||||||
|
|
||||||
|
# Compiled MEX files
|
||||||
|
*.mex*
|
||||||
|
|
||||||
|
# Packaged app and toolbox files
|
||||||
|
*.mlappinstall
|
||||||
|
*.mltbx
|
||||||
|
|
||||||
|
# Deployable archives
|
||||||
|
*.ctf
|
||||||
|
|
||||||
|
# Generated helpsearch folders
|
||||||
|
helpsearch*/
|
||||||
|
|
||||||
|
# Code generation folders
|
||||||
|
slprj/
|
||||||
|
sccprj/
|
||||||
|
codegen/
|
||||||
|
|
||||||
|
# Cache files
|
||||||
|
*.slxc
|
||||||
|
|
||||||
|
# Cloud based storage dotfile
|
||||||
|
.MATLABDriveTag
|
BIN
Coop3LeaderFollower1D8.slx
Normal file
BIN
Coop3LeaderFollower1D8.slx
Normal file
Binary file not shown.
BIN
Coop3LeaderFollower2.slx
Normal file
BIN
Coop3LeaderFollower2.slx
Normal file
Binary file not shown.
BIN
Coop3LeaderFollower2D2.slx
Normal file
BIN
Coop3LeaderFollower2D2.slx
Normal file
Binary file not shown.
16
FOTF Toolbox/@foss/bode.m
Normal file
16
FOTF Toolbox/@foss/bode.m
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
function H=bode(G,varargin)
|
||||||
|
% bode - draw Bode diagram for an FOSS object
|
||||||
|
%
|
||||||
|
% bode(G,w)
|
||||||
|
% H=bode(G,w)
|
||||||
|
%
|
||||||
|
% G - the FOSS object
|
||||||
|
% w - the frequency vector
|
||||||
|
% H - the frequency response data in FRD format
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, bode(fotf(G),varargin{:});
|
||||||
|
else, H=bode(fotf(G),varargin{:}); end
|
||||||
|
end
|
21
FOTF Toolbox/@foss/coss_aug.m
Normal file
21
FOTF Toolbox/@foss/coss_aug.m
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
function G1=coss_aug(G,k)
|
||||||
|
% coss_aug - state augmentation of an FOSS object
|
||||||
|
%
|
||||||
|
% G1=coss_aug(G,k)
|
||||||
|
%
|
||||||
|
% G - the FOSS object
|
||||||
|
% k - integer so that original n states can be augmented into n*k states
|
||||||
|
% G1 - the augmented FOSS model
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if G.alpha==0 || k==1, G1=G;
|
||||||
|
else, alpha=G.alpha/k; G=fotf(G); [n,m]=size(G);
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j);
|
||||||
|
a=g.den.a; na=g.den.na; b=g.num.a; nb=g.num.na;
|
||||||
|
ii=1:k:k*length(a); a1(ii)=a;
|
||||||
|
ii=1:k:k*length(b); b1(ii)=b; G2(i,j)=tf(b1,a1);
|
||||||
|
end, end
|
||||||
|
G1=foss(ss(G2)); G1.alpha=alpha;
|
||||||
|
end, end
|
13
FOTF Toolbox/@foss/ctrb.m
Normal file
13
FOTF Toolbox/@foss/ctrb.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function Tc=ctrb(G)
|
||||||
|
% ctrb - create a controllability test matrix for an FOSS
|
||||||
|
%
|
||||||
|
% Tc=ctrb(G)
|
||||||
|
%
|
||||||
|
% G - the FOSS object
|
||||||
|
% Tc - the controllability test matrix
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
Tc=ctrb(G.a,G.b);
|
||||||
|
end
|
14
FOTF Toolbox/@foss/disp.m
Normal file
14
FOTF Toolbox/@foss/disp.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function disp(G)
|
||||||
|
% display - display an FOSS. This function will be called automatically
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
disp('E*(d^alpha*X)(t)=A*X(t)+B*U(t-T)'), T=G.ioDelay;
|
||||||
|
disp('Y(t)=C*X(t)+D*U(t-T)'); ss(G.a,G.b,G.c,G.d)
|
||||||
|
if ~isempty(G.E), disp('Descriptor matrix'), E=G.E, end
|
||||||
|
if sum(T(:)), disp(['Time Delay is = ' mat2str(T)]); end
|
||||||
|
disp(['alpha = ',num2str(G.alpha)]);
|
||||||
|
if ~isempty(G.x0), x0=G.x0;
|
||||||
|
disp(['Initil state vector x0 = [' num2str(x0(:).'),']'])
|
||||||
|
end, end
|
13
FOTF Toolbox/@foss/eig.m
Normal file
13
FOTF Toolbox/@foss/eig.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function p=eig(G)
|
||||||
|
% eig - finding all the pseudo poles of an FOSS object
|
||||||
|
%
|
||||||
|
% p=eig(G)
|
||||||
|
%
|
||||||
|
% G - the FOSS object
|
||||||
|
% p - all the pseudo-poles of G
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p=eig(G.a)
|
||||||
|
end
|
13
FOTF Toolbox/@foss/eq.m
Normal file
13
FOTF Toolbox/@foss/eq.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function key=eq(G1,G2)
|
||||||
|
% eq - test whether two FOSS objects are equal or not
|
||||||
|
%
|
||||||
|
% key=G1==G2
|
||||||
|
%
|
||||||
|
% G1, G2 - the two FOSS objects
|
||||||
|
% key = 1 for equal, otherwise key = 0
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
key=fotf(G1)==fotf(G2);
|
||||||
|
end
|
24
FOTF Toolbox/@foss/feedback.m
Normal file
24
FOTF Toolbox/@foss/feedback.m
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
function G=feedback(G1,G2)
|
||||||
|
% feedback - find the overall model of two FOSS objects in feedback connection
|
||||||
|
%
|
||||||
|
% G=feedback(G1,G2)
|
||||||
|
%
|
||||||
|
% G1, G2 - the FOSS objects in the forward and backward paths
|
||||||
|
% G - the overall model of the closed-loop system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=foss(G1); G2=foss(G2);
|
||||||
|
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
|
||||||
|
else, a=common_order(G1.alpha,G2.alpha); end
|
||||||
|
if a==0
|
||||||
|
G=foss([],[],[],G1.d*inv(eye(size(G1.d))+G2.d*G1.d),0);
|
||||||
|
elseif a<0.001
|
||||||
|
G1=fotf(G1); G2=fotf(G2); G=foss(feedback(G1,G2));
|
||||||
|
else
|
||||||
|
G1=coss_aug(G1,round(G1.alpha/a));
|
||||||
|
G2=coss_aug(G2,round(G2.alpha/a));
|
||||||
|
G=foss(feedback(ss_extract(G1),ss_extract(G2))); G.alpha=a;
|
||||||
|
end
|
||||||
|
end
|
25
FOTF Toolbox/@foss/foss.m
Normal file
25
FOTF Toolbox/@foss/foss.m
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
% foss - class constructor for an FOSS class
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
classdef foss
|
||||||
|
properties, a, b, c, d, alpha, ioDelay, E, x0, end
|
||||||
|
methods
|
||||||
|
function G=foss(a,b,c,d,alpha,L,E,x0)
|
||||||
|
if nargin<=7, x0=[]; end
|
||||||
|
if nargin<=6, E=[]; end, if nargin<=5, L=0; end
|
||||||
|
if nargin==1 && isa(a,'foss'), G=a;
|
||||||
|
elseif nargin==1 && isa(a,'fotf'), G=fotf2foss(a);
|
||||||
|
elseif nargin==1 && isa(a,'double'), G=foss([],[],[],a,0);
|
||||||
|
elseif (nargin==1||nargin==2) && (isa(a,'tf')||isa(a,'ss'))
|
||||||
|
alpha=1; if nargin==2, alpha=b; end
|
||||||
|
a=ss(a); L=a.ioDelay; [a,b,c,d,E]=dssdata(a);
|
||||||
|
G=foss(a,b,c,d,alpha,L,E);
|
||||||
|
elseif nargin>=5, msg=abcdchk(a,b,c,d);
|
||||||
|
if length(msg)>0, error(msg)
|
||||||
|
else, G.alpha=alpha; G.x0=x0;
|
||||||
|
G.a=a; G.b=b; G.c=c; G.d=d; G.E=E; G.ioDelay=L;
|
||||||
|
end
|
||||||
|
else, error('wrong input arguments'); end
|
||||||
|
end, end, end
|
24
FOTF Toolbox/@foss/foss2fotf.m
Normal file
24
FOTF Toolbox/@foss/foss2fotf.m
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
function G1=foss2fotf(G)
|
||||||
|
% foss2fotf - convert an FOSS object to FOTF one
|
||||||
|
%
|
||||||
|
% G1=foss2fotf(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% G1 - an equivalent FOTF object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); G1=fotf(zeros(n,m));
|
||||||
|
G0=ss_extract(G); G0=tf(G0); key=length(G.alpha)>1;
|
||||||
|
T=G.ioDelay; if isscalar(T), T=T*ones(n,m); end
|
||||||
|
if key~=0
|
||||||
|
n0=G.alpha; n1=n0(end:-1:1); n2=0;
|
||||||
|
for i=1:length(n1), n2(i+1)=n2(i)+n1(i); end
|
||||||
|
n2=n2(end:-1:1);
|
||||||
|
end
|
||||||
|
for i=1:n, for j=1:m, g=G0(i,j);
|
||||||
|
[num,den]=tfdata(g,'v');
|
||||||
|
if key==0, n2=((length(den)-1):-1:0)*G.alpha; end
|
||||||
|
h=fotf(den,n2,num,n2,T(i,j)); h=simplify(h); G1(i,j)=h;
|
||||||
|
end, end, end
|
15
FOTF Toolbox/@foss/impulse.m
Normal file
15
FOTF Toolbox/@foss/impulse.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function Y=impulse(G,varargin)
|
||||||
|
% impulse - impulse response evaluation of an FOSS object
|
||||||
|
%
|
||||||
|
% impulse(G,t)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% t - the time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, impulse(fotf(G),varargin{:});
|
||||||
|
else, Y=impulse(fotf(G),varargin{:});
|
||||||
|
end
|
||||||
|
end
|
12
FOTF Toolbox/@foss/inv.m
Normal file
12
FOTF Toolbox/@foss/inv.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function G1=inv(G)
|
||||||
|
% inv - inverse of a multivariable FOSS system
|
||||||
|
%
|
||||||
|
% G1=inv(G)
|
||||||
|
%
|
||||||
|
% G, G1 - an FOSS object and its inverse system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
H=inv(ss_extract(G)); G1=foss(H); G1.alpha=G.alpha;
|
||||||
|
end
|
12
FOTF Toolbox/@foss/isfoss.m
Normal file
12
FOTF Toolbox/@foss/isfoss.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function key=isfoss(G)
|
||||||
|
% isfoss - check whether input is an FOSS object
|
||||||
|
%
|
||||||
|
% key=isfoss(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
key=strcmp(class(G),'foss');
|
||||||
|
end
|
20
FOTF Toolbox/@foss/isstable.m
Normal file
20
FOTF Toolbox/@foss/isstable.m
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function [K,alpha,apol]=isstable(G)
|
||||||
|
% isstable - check whether an FOSS object is stable or not
|
||||||
|
%
|
||||||
|
% [K,alpha,apol]=isstable(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% K- identifier to indicate the stability of G, returns 0, and 1
|
||||||
|
% alpha - the common order
|
||||||
|
% apol - all the pseudo poles of the system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p=eig(G); alpha=G.alpha;
|
||||||
|
plot(real(p),imag(p),'x',0,0,'o')
|
||||||
|
apol=min(abs(angle(p))); K=apol>alpha*pi/2;
|
||||||
|
xm=xlim; if alpha<1, xm(1)=0; else, xm(2)=0; end
|
||||||
|
a1=tan(alpha*pi/2)*xm; a2=tan(alpha*pi)*xm;
|
||||||
|
line(xm,a1), line(xm,-a1), line(xm,a2), line(xm,-a2)
|
||||||
|
end
|
15
FOTF Toolbox/@foss/lsim.m
Normal file
15
FOTF Toolbox/@foss/lsim.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function Y=lsim(G,varargin)
|
||||||
|
% lsim - simulation of an FOSS object driven by given inputs
|
||||||
|
%
|
||||||
|
% lsim(G,u,t)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% u, t- input samples and time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, lsim(fotf(G),varargin{:});
|
||||||
|
else, Y=lsim(fotf(G),varargin{:});
|
||||||
|
end
|
||||||
|
end
|
14
FOTF Toolbox/@foss/margin.m
Normal file
14
FOTF Toolbox/@foss/margin.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function [Gm,Pm,Wcg,Wcp]=margin(G)
|
||||||
|
% margin - gain and phase margins of an FOSS object
|
||||||
|
%
|
||||||
|
% [Gm,Pm,Wcg,Wcp]=margin(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% Gm, Wcg - gain margin in dBs and the corresponding frequency
|
||||||
|
% Pm, Wcp - phase margin in degrees and the crossover frequency
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[Gm,Pm,Wcg,Wcp]=margin(fotf(G));
|
||||||
|
end
|
14
FOTF Toolbox/@foss/mfrd.m
Normal file
14
FOTF Toolbox/@foss/mfrd.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function H=mfrd(G,varargin)
|
||||||
|
% mfrd - evaluation of frequency responses of an FOSS object
|
||||||
|
%
|
||||||
|
% H=mfrd(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% w - frequency vector
|
||||||
|
% H - frequency response of G in MFD format
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
H=mfrd(fotf(G),varargin{:});
|
||||||
|
end
|
14
FOTF Toolbox/@foss/minreal.m
Normal file
14
FOTF Toolbox/@foss/minreal.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function G=minreal(G1)
|
||||||
|
% minreal - minimum realisation of an FOSS object
|
||||||
|
%
|
||||||
|
% G=minreal(G1)
|
||||||
|
%
|
||||||
|
% G1 - an FOSS object
|
||||||
|
% G - minimum realisation of G1 as an FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
alpha=G1.alpha; G2=ss_extract(G1); G2=minreal(G2);
|
||||||
|
G=foss(G2); G.alpha=alpha;
|
||||||
|
end
|
10
FOTF Toolbox/@foss/minus.m
Normal file
10
FOTF Toolbox/@foss/minus.m
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function G=minus(G1,G2)
|
||||||
|
% minus - minus operation of two FOSS objects
|
||||||
|
%
|
||||||
|
% G=G1-G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G=G1+(-G2);
|
||||||
|
end
|
20
FOTF Toolbox/@foss/mpower.m
Normal file
20
FOTF Toolbox/@foss/mpower.m
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function G1=mpower(G,n)
|
||||||
|
% mpower - power of an FOSS object
|
||||||
|
%
|
||||||
|
% G1=G^n
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% n - power. If G is s or constant, n can be any real number,
|
||||||
|
% If G is an FOSS, n should be integers
|
||||||
|
% G1 - returns G^n, and an FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if n==fix(n), [n1,m1]=size(G); if n<0, G=inv(G); end
|
||||||
|
if n1==m1
|
||||||
|
G1=foss(eye(n1)); for i=1:abs(n), G1=G1*G; end
|
||||||
|
else, error('matrix must be square'); end
|
||||||
|
else, error('mpower: power must be an integer.');
|
||||||
|
end
|
||||||
|
end
|
22
FOTF Toolbox/@foss/mtimes.m
Normal file
22
FOTF Toolbox/@foss/mtimes.m
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function G=mtimes(G1,G2)
|
||||||
|
% mpower - product of two FOSS objects, series connection
|
||||||
|
%
|
||||||
|
% G=G1*G2
|
||||||
|
%
|
||||||
|
% G1, G2 - FOSS objects
|
||||||
|
% G - returns the product of the two FOSS objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=foss(G1); G2=foss(G2);
|
||||||
|
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
|
||||||
|
else, a=common_order(G1.alpha,G2.alpha); end
|
||||||
|
if a==0, G=foss([],[],[],G1.d*G2.d,0);
|
||||||
|
elseif a<0.001, G1=fotf(G1); G2=fotf(G2); G=foss(G1*G2);
|
||||||
|
else
|
||||||
|
G1=coss_aug(G1,round(G1.alpha/a));
|
||||||
|
G2=coss_aug(G2,round(G2.alpha/a));
|
||||||
|
G=foss(ss_extract(G1)*ss_extract(G2)); G.alpha=a;
|
||||||
|
end
|
||||||
|
end
|
15
FOTF Toolbox/@foss/nichols.m
Normal file
15
FOTF Toolbox/@foss/nichols.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function H=nichols(G,varargin)
|
||||||
|
% nichols - draw the Nichols chart of an FOSS object
|
||||||
|
%
|
||||||
|
% nichols(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% w - the frequency vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, nichols(fotf(G),varargin{:});
|
||||||
|
else, H=nichols(fotf(G),varargin{:});
|
||||||
|
end
|
||||||
|
end
|
13
FOTF Toolbox/@foss/norm.m
Normal file
13
FOTF Toolbox/@foss/norm.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function n=norm(G,varargin)
|
||||||
|
% norm -= norms of an FOSS object
|
||||||
|
%
|
||||||
|
% norm(G), norm(G,inf)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% The 2-norm and infinity-norm of G can be evaluated, respectively
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
n=norm(fotf(G),varargin{:});
|
||||||
|
end
|
15
FOTF Toolbox/@foss/nyquist.m
Normal file
15
FOTF Toolbox/@foss/nyquist.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function H=nyquist(G,varargin)
|
||||||
|
% nyquist - draw the Nyquist plot of an FOSS object
|
||||||
|
%
|
||||||
|
% nyquist(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% w - the frequency vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, nyquist(fotf(G),varargin{:});
|
||||||
|
else, H=nyquist(fotf(G),varargin{:});
|
||||||
|
end
|
||||||
|
end
|
13
FOTF Toolbox/@foss/obsv.m
Normal file
13
FOTF Toolbox/@foss/obsv.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function To=obsv(G)
|
||||||
|
% obsv - create an observability test matrix for an FOSS
|
||||||
|
%
|
||||||
|
% To=obsv(G)
|
||||||
|
%
|
||||||
|
% G - the FOSS object
|
||||||
|
% To - the observability test matrix
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
To=obsv(G.a,G.c);
|
||||||
|
end
|
13
FOTF Toolbox/@foss/order.m
Normal file
13
FOTF Toolbox/@foss/order.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function n=order(G)
|
||||||
|
% order - extract the order of an FOSS object
|
||||||
|
%
|
||||||
|
% n=order(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% n - the order
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
n=length(G.a)*G.alpha;
|
||||||
|
end
|
22
FOTF Toolbox/@foss/plus.m
Normal file
22
FOTF Toolbox/@foss/plus.m
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function G=plus(G1,G2)
|
||||||
|
% plus - evaluate the sum of two FOSS objects, parallel connection
|
||||||
|
%
|
||||||
|
% G=G1+G2
|
||||||
|
%
|
||||||
|
% G1, G2 - the two FOSS objects in parallel connection
|
||||||
|
% G - the sum of G1 and G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=foss(G1); G2=foss(G2);
|
||||||
|
if length(G1.alpha)>1 || length(G2.alpha)>1, a=0.0001;
|
||||||
|
else, a=common_order(G1.alpha,G2.alpha); end
|
||||||
|
if a==0, G=foss([],[],[],G1.d+G2.d,0);
|
||||||
|
elseif a<0.001, G1=fotf(G1); G2=fotf(G2); G=foss(G1+G2);
|
||||||
|
else
|
||||||
|
G1=coss_aug(G1,round(G1.alpha/a));
|
||||||
|
G2=coss_aug(G2,round(G2.alpha/a));
|
||||||
|
G=foss(ss_extract(G1)+ss_extract(G2)); G.alpha=a;
|
||||||
|
end
|
||||||
|
end
|
12
FOTF Toolbox/@foss/rlocus.m
Normal file
12
FOTF Toolbox/@foss/rlocus.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function rlocus(G)
|
||||||
|
% rlocus - draw the root locus of a SISO FOSS object
|
||||||
|
%
|
||||||
|
% rlocus(G)
|
||||||
|
%
|
||||||
|
% G - a SISO FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
rlocus(fotf(G))
|
||||||
|
end
|
14
FOTF Toolbox/@foss/size.m
Normal file
14
FOTF Toolbox/@foss/size.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function [p,q,n]=size(G)
|
||||||
|
% size - extract the numbers of inputs, outputs and states of an FOSS object
|
||||||
|
%
|
||||||
|
% [p,q,n]=size(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% n, m - the numbers of the inputs and outputs
|
||||||
|
% n - the number of states
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
q=size(G.c,1); p=size(G.b,2); n=length(G.a);
|
||||||
|
end
|
12
FOTF Toolbox/@foss/ss_extract.m
Normal file
12
FOTF Toolbox/@foss/ss_extract.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function G1=ss_extract(G)
|
||||||
|
% ss_extract - extract the SS object from an FOSS object
|
||||||
|
%
|
||||||
|
% G1=ss_extract(G)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% G1 - the extracted integer-order state space model
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
G1=ss(G.a,G.b,G.c,G.d); G1.E=G.E;
|
||||||
|
end
|
15
FOTF Toolbox/@foss/step.m
Normal file
15
FOTF Toolbox/@foss/step.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function Y=step(G,varargin)
|
||||||
|
% step - simulation of an FOSS object driven by step inputs
|
||||||
|
%
|
||||||
|
% step(G,t)
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% t- the time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargout==0, step(fotf(G),varargin{:});
|
||||||
|
else, Y=step(fotf(G),varargin{:});
|
||||||
|
end
|
||||||
|
end
|
13
FOTF Toolbox/@foss/uminus.m
Normal file
13
FOTF Toolbox/@foss/uminus.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function G=uminus(G1)
|
||||||
|
% uminus - unary minus of an FOSS object
|
||||||
|
%
|
||||||
|
% G1=-G
|
||||||
|
%
|
||||||
|
% G - an FOSS object
|
||||||
|
% G1- the unary minus of G, i.e., -G
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G=G1; G.c=-G1.c; G.d=-G1.d;
|
||||||
|
end
|
15
FOTF Toolbox/@fotf/base_order.m
Normal file
15
FOTF Toolbox/@fotf/base_order.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function alpha=base_order(G)
|
||||||
|
% base_order - find the base order of an FOTF object
|
||||||
|
%
|
||||||
|
% alpha=base_order(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% alpha - the base order of the system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); a=[];
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j); a=[a,g.num.na,g.den.na]; end, end
|
||||||
|
alpha=double(gcd(sym(a)));
|
||||||
|
end
|
17
FOTF Toolbox/@fotf/bode.m
Normal file
17
FOTF Toolbox/@fotf/bode.m
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
function H=bode(G,w)
|
||||||
|
% bode - draw Bode diagram for an FOTF object
|
||||||
|
%
|
||||||
|
% bode(G,w)
|
||||||
|
% H=bode(G,w)
|
||||||
|
%
|
||||||
|
% G - the FOTF object
|
||||||
|
% w - the frequency vector
|
||||||
|
% H - the frequency response data in FRD format
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
arguments, G, w=logspace(-4,4); end
|
||||||
|
H1=freqresp(1j*w,G); H1=frd(H1,w);
|
||||||
|
if nargout==0, subplot(111), bode(H1); else, H=H1; end
|
||||||
|
end
|
18
FOTF Toolbox/@fotf/diag.m
Normal file
18
FOTF Toolbox/@fotf/diag.m
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
function G=diag(G1)
|
||||||
|
% diag - diagonal matrix manipulation of an FOTF object
|
||||||
|
%
|
||||||
|
% G=diag(G1)
|
||||||
|
%
|
||||||
|
% G - the FOTF object
|
||||||
|
% G1 - if G is a vector, configurate a matrix G1, otherwise extract its
|
||||||
|
% diagonal elements to form G1
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G1); nm=max(n,m); nm1=min(n,m);
|
||||||
|
if m==1 || n==1
|
||||||
|
G=fotf(zeros(nm,nm)); for i=1:nm, G(i,i)=G1(i); end
|
||||||
|
else
|
||||||
|
G=fotf(zeros(nm1,1)); for i=1:nm1, G(i)=G1(i,i); end
|
||||||
|
end, end
|
25
FOTF Toolbox/@fotf/disp.m
Normal file
25
FOTF Toolbox/@fotf/disp.m
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
function str=disp(G)
|
||||||
|
% display - display an FOTF. This function will be called automatically
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); key=0; if nargout==1, key=1; end
|
||||||
|
for i=1:m, if m>1, disp([' From input ' int2str(i) ' to output...']), end
|
||||||
|
for j=1:n, if n>1, disp([' ' int2str(j) ':']), end
|
||||||
|
str=fotfdisp(G(j,i),key); if nargout==0, disp(' '); end
|
||||||
|
end, end, end
|
||||||
|
% display a SISO FOTF object
|
||||||
|
function str=fotfdisp(G,key)
|
||||||
|
strN=disp(G.num); str=strN;
|
||||||
|
strD=disp(G.den); nn=length(strN);
|
||||||
|
if nn==1 && strN=='0', if key==0, disp(strN), end
|
||||||
|
else, nd=length(strD); nm=max([nn,nd]);
|
||||||
|
if key==0, disp([char(' '*ones(1,floor((nm-nn)/2))) strN]), end
|
||||||
|
ss=[]; T=G.ioDelay; if T>0, ss=['exp(-' num2str(T) '*s)']; end
|
||||||
|
if T>0, str=['(' str ')*' ss '/(' strD ')'];
|
||||||
|
else, str=['(' str ')/(' strD ')']; end
|
||||||
|
str=strrep(strrep(str,'{',''),'}','');
|
||||||
|
if key==0, disp([char('-'*ones(1,nm)), ss]);
|
||||||
|
disp([char(' '*ones(1,floor((nm-nd)/2))) strD])
|
||||||
|
end, end, end
|
10
FOTF Toolbox/@fotf/double.m
Normal file
10
FOTF Toolbox/@fotf/double.m
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function a=double(G)
|
||||||
|
%double - convert FOTF to double, if possible
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 May, 2022
|
||||||
|
if G.num.na==0 && G.den.na==0
|
||||||
|
a=G.num.a./G.den.a;
|
||||||
|
else, error('G contains dynamic terms, cannot be converted into double')
|
||||||
|
end
|
||||||
|
end
|
13
FOTF Toolbox/@fotf/eig.m
Normal file
13
FOTF Toolbox/@fotf/eig.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function p=eig(G)
|
||||||
|
% eig - finding all the pseudo poles of an FOTF object
|
||||||
|
%
|
||||||
|
% p=eig(G)
|
||||||
|
%
|
||||||
|
% G - the FOTF object
|
||||||
|
% p - all the pseudo-poles of G
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p=eig(foss(G));
|
||||||
|
end
|
19
FOTF Toolbox/@fotf/eq.m
Normal file
19
FOTF Toolbox/@fotf/eq.m
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function key=eq(G1,G2)
|
||||||
|
% eq - test whether two FOTF objects are equal or not
|
||||||
|
%
|
||||||
|
% key=G1==G2
|
||||||
|
%
|
||||||
|
% G1, G2 - the two FOTF objects
|
||||||
|
% key = 1 for equal, otherwise key = 0
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n1,m1]=size(G1); [n2,m2]=size(G2);
|
||||||
|
if n1~=n2 || m1~=m2, key=0;
|
||||||
|
else
|
||||||
|
G=G1-G2; [n,m]=size(G); key=0; kk=0;
|
||||||
|
for i=1:n, for j=1:m, kk=kk+(G(i,j).num==0);
|
||||||
|
end, end, end
|
||||||
|
key=(kk==n1*m1);
|
||||||
|
end
|
13
FOTF Toolbox/@fotf/exp.m
Normal file
13
FOTF Toolbox/@fotf/exp.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function G=exp(del)
|
||||||
|
% exp - express delay term exp(-tau*s)
|
||||||
|
%only works for SISO FOTF model
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 May, 2022
|
||||||
|
try
|
||||||
|
T=double(del/fotf('s'));
|
||||||
|
if T>0, error('Delay must be negative'), else, T=-T; end
|
||||||
|
G=fotf(1); G.ioDelay=T;
|
||||||
|
catch, error('Error in extracting delay constant');
|
||||||
|
end
|
||||||
|
end
|
23
FOTF Toolbox/@fotf/feedback.m
Normal file
23
FOTF Toolbox/@fotf/feedback.m
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function G=feedback(F,H)
|
||||||
|
% feedback - find the overall model of two FOTF objects in feedback connection
|
||||||
|
%
|
||||||
|
% G=feedback(G1,G2)
|
||||||
|
%
|
||||||
|
% G1, G2 - the FOTF objects in the forward and backward paths
|
||||||
|
% G - the overall model of the closed-loop system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
F=fotf(F); H=fotf(H); [n1,m1]=size(F); [n2,m2]=size(H);
|
||||||
|
if n1*m1==1 && n2*m2==1
|
||||||
|
if F.ioDelay==H.ioDelay
|
||||||
|
G=fotf(F.den*H.den+F.num*H.num,F.num*H.den);
|
||||||
|
G=simplify(G); G.ioDelay=F.ioDelay;
|
||||||
|
else, error('delay in incompatible'), end
|
||||||
|
elseif n1==m1 && n1==n2 && n2==m2
|
||||||
|
if maxdelay(F)==0 && maxdelay(H)==0
|
||||||
|
G=inv(fotf(eye(size(F*H)))+F*H)*F; G=simplify(G);
|
||||||
|
else, error('cannot handle blocks with delays'); end
|
||||||
|
else, error('not equal sized square matrices'), end
|
||||||
|
end
|
23
FOTF Toolbox/@fotf/foss_a.m
Normal file
23
FOTF Toolbox/@fotf/foss_a.m
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function G1=foss_a(G)
|
||||||
|
% foss_a - convert an FOTF object into an extended FOSS object
|
||||||
|
%
|
||||||
|
% G1=foss_a(G)
|
||||||
|
%
|
||||||
|
% G - the FOTF object
|
||||||
|
% G1 - the equivalent extended FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); n0=[];
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j); n0=[n0, g.nn g.nd]; end, end
|
||||||
|
n0=unique(n0); n1=n0(end:-1:1);
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j);
|
||||||
|
num=[]; den=[]; nn=g.nn; nd=g.nd; b=g.num; a=g.den;
|
||||||
|
for k=1:length(nn), t=find(nn(k)==n1); num(t)=b(k); end
|
||||||
|
for k=1:length(nd), t=find(nd(k)==n1); den(t)=a(k); end
|
||||||
|
Gt(i,j)=tf(num,den); T(i,j)=g.ioDelay;
|
||||||
|
end, end
|
||||||
|
Gf=ss(Gt); E=Gf.e; [a,b,c,d]=dssdata(Gf);
|
||||||
|
alpha=-diff(n1); G1=foss(a,b,c,d,alpha,T,E);
|
||||||
|
end
|
30
FOTF Toolbox/@fotf/fotf.m
Normal file
30
FOTF Toolbox/@fotf/fotf.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
% foss - class constructor for an FOTF class
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
%Note that, the low-level support of FOTF object is changed to
|
||||||
|
%ppoly object, pseudo-polynomials
|
||||||
|
classdef fotf
|
||||||
|
properties
|
||||||
|
num, den, ioDelay
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function G=fotf(a,na,b,nb,T)
|
||||||
|
if isa(a,'fotf'), G=a;
|
||||||
|
elseif strcmp(class(a),'sym'), G=sym2fotf(a);
|
||||||
|
elseif isa(a,'foss'), G=foss2fotf(a);
|
||||||
|
elseif nargin==1 && (isa(a,'tf') || isa(a,'ss') || isa(a,'double'))
|
||||||
|
a=tf(a); [n1,m1]=size(a); G=[]; D=a.ioDelay;
|
||||||
|
for i=1:n1, g=[]; for j=1:m1
|
||||||
|
[n,d]=tfdata(tf(a(i,j)),'v'); nn=length(n)-1:-1:0;
|
||||||
|
nd=length(d)-1:-1:0; g=[g fotf(d,nd,n,nn,D(i,j))];
|
||||||
|
end, G=[G; g]; end
|
||||||
|
elseif nargin==1 && a=='s', G=fotf(1,0,1,1,0);
|
||||||
|
elseif isa(a,'ppoly'), G.num=na; G.den=a; G.ioDelay=0;
|
||||||
|
else, ii=find(abs(a)<eps); a(ii)=[]; na(ii)=[];
|
||||||
|
ii=find(abs(b)<eps); b(ii)=[]; nb(ii)=[];
|
||||||
|
if isempty(b), b=0; nb=0; end
|
||||||
|
if nargin==4, T=0; end
|
||||||
|
num=ppoly(b,nb); den=ppoly(a,na); G.num=num; G.den=den; G.ioDelay=T;
|
||||||
|
end, end, end, end
|
25
FOTF Toolbox/@fotf/fotf2cotf.m
Normal file
25
FOTF Toolbox/@fotf/fotf2cotf.m
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
function [G1,alpha]=fotf2cotf(G)
|
||||||
|
% fotf2cotf - convert an FOTF object into a commensurate-order one
|
||||||
|
%
|
||||||
|
% [G1,alpha]=fotf2cotf(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% G1 - an equivalent commensurate-order FOTF
|
||||||
|
% alpha - the base order
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); alpha=base_order(G);
|
||||||
|
if alpha==0
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
g=G(i,j); a=g.den.a; b=g.num.a; D(i,j)=b(1)/a(1); T(i,j)=g.ioDelay;
|
||||||
|
end, end, G1=tf(D);
|
||||||
|
else
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j); a=[]; b=[];
|
||||||
|
n0=round(g.den.na/alpha); a(n0+1)=g.den.a; a=a(end:-1:1);
|
||||||
|
m0=round(g.num.na/alpha); b(m0+1)=g.num.a; b=b(end:-1:1);
|
||||||
|
g1=tf(b,a); G1(i,j)=g1; T(i,j)=g.ioDelay;
|
||||||
|
end, end, end
|
||||||
|
G1.ioDelay=T;
|
||||||
|
end
|
16
FOTF Toolbox/@fotf/fotf2foss.m
Normal file
16
FOTF Toolbox/@fotf/fotf2foss.m
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
function G1=fotf2foss(G)
|
||||||
|
% fotf2foss - convert an FOTF object to FOSS one
|
||||||
|
%
|
||||||
|
% G1=fotf2foss(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% G1 - an equivalent FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G);
|
||||||
|
[G2,alpha]=fotf2cotf(G); G2=minreal(G2); G2=ss(G2);
|
||||||
|
for i=1:n, for j=1:m, g=G(i,j); T(i,j)=g.ioDelay; end, end
|
||||||
|
G1=foss(G2.a,G2.b,G2.c,G2.d,alpha,T,G2.E);
|
||||||
|
end
|
19
FOTF Toolbox/@fotf/fotfdata.m
Normal file
19
FOTF Toolbox/@fotf/fotfdata.m
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function [a,na,b,nb,L]=fotfdata(G)
|
||||||
|
% fotfdata - extract data from an FOTF object
|
||||||
|
%
|
||||||
|
% [a,na,b,nb,L]=fotfdata(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% [a,na,b,nb] - the coefficients and orders of denominator and numerator
|
||||||
|
% L - the delay constant
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G);
|
||||||
|
if n*m==1, b=G.num.a; a=G.den.a; nb=G.num.na; na=G.den.na; L=G.ioDelay;
|
||||||
|
else
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
[a0,na0,b0,nb0,L0]=fotfdata(G(i,j));
|
||||||
|
a{i,j}=a0; b{i,j}=b0; na{i,j}=na0; nb{i,j}=nb0; L(i,j)=L0;
|
||||||
|
end, end, end, end
|
23
FOTF Toolbox/@fotf/freqresp.m
Normal file
23
FOTF Toolbox/@fotf/freqresp.m
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function H=freqresp(s,G1)
|
||||||
|
% freqresp - low-level function to evaluate the frequency response of
|
||||||
|
% an FOTF object
|
||||||
|
%
|
||||||
|
% H=freqresp(s,G)
|
||||||
|
%
|
||||||
|
% s - the frequency vector or a vector for s
|
||||||
|
% G - the FOTF object
|
||||||
|
% H - frequency response, i.e., G(s) vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G1);
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
[a,na,b,nb,L]=fotfdata(G1(i,j));
|
||||||
|
for k=1:length(s)
|
||||||
|
P=b*(s(k).^nb.'); Q=a*(s(k).^na.'); H1(k)=P/Q;
|
||||||
|
end
|
||||||
|
if L>0, H1=H1.*exp(-L*s); end, H(i,j,:)=H1;
|
||||||
|
end, end
|
||||||
|
if n*m==1, H=H(:).'; end
|
||||||
|
end
|
36
FOTF Toolbox/@fotf/high_order.m
Normal file
36
FOTF Toolbox/@fotf/high_order.m
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
function Ga=high_order(G0,filter,wb,wh,N,key)
|
||||||
|
% high_order - approximate an FOTF object with high-order TFs
|
||||||
|
%
|
||||||
|
% Ga=high_order(G0,filter,wb,wh,N)
|
||||||
|
%
|
||||||
|
% G0 - an FOTF object
|
||||||
|
% filter - can be 'ousta_fod', 'new_fod' and 'matsuda_fod'
|
||||||
|
% wb, wh, N - the interested frequency interval and order of the filter
|
||||||
|
% Ga - an equivalent TF object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
arguments
|
||||||
|
G0, filter='ousta_fod', wb(1,1){mustBeNumeric}=1e-3
|
||||||
|
wh(1,1) {mustBeNumeric, mustBeGreaterThan(wh,wb)}=1e3
|
||||||
|
N(1,1) {mustBeInteger, mustBePositive}=5, key=0
|
||||||
|
end
|
||||||
|
[n,m]=size(G0); F=filter;
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
if G0(i,j)==fotf(0), Ga(i,j)=tf(0);
|
||||||
|
else, G=simplify(G0(i,j)); [a,na,b,nb]=fotfdata(G);
|
||||||
|
G1=pseudo_poly(b,nb,F,wb,wh,N,key)/pseudo_poly(a,na,F,wb,wh,N,key);
|
||||||
|
Ga(i,j)=minreal(G1);
|
||||||
|
end, end, end, end
|
||||||
|
% 伪多项式的近似
|
||||||
|
function p=pseudo_poly(a,na,filter,wb,wh,N,key)
|
||||||
|
p=0; s=tf('s');
|
||||||
|
for i=1:length(a), na0=na(i); n1=floor(na0); gam=na0-n1;
|
||||||
|
if key==1
|
||||||
|
g1=eval([filter '(gam,N,wb,wh)']); p=p+a(i)*g1;
|
||||||
|
else
|
||||||
|
if gam~=0, g1=eval([filter '(gam,N,wb,wh)']);
|
||||||
|
else, g1=1; end
|
||||||
|
p=p+a(i)*s^n1*g1;
|
||||||
|
end, end, end
|
15
FOTF Toolbox/@fotf/impulse.m
Normal file
15
FOTF Toolbox/@fotf/impulse.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function y=impulse(G,t)
|
||||||
|
% impulse - impulse response evaluation of an FOTF object
|
||||||
|
%
|
||||||
|
% impulse(G,t)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% t - the time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=G*fotf('s');
|
||||||
|
if nargout==0, step(G1,t,1); title('Impulse Response')
|
||||||
|
else, y=step(G1,t,1); end
|
||||||
|
end
|
28
FOTF Toolbox/@fotf/inv.m
Normal file
28
FOTF Toolbox/@fotf/inv.m
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
function G1=inv(G)
|
||||||
|
% inv - inverse of a multivariable FOTF system
|
||||||
|
%
|
||||||
|
% G1=inv(G)
|
||||||
|
%
|
||||||
|
% G, G1 - an FOTF object and its inverse system
|
||||||
|
% not recommended for MIMO FOTFs, use fotf2sym and work the
|
||||||
|
% model G under symbolic framework
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G);
|
||||||
|
if n*m==1
|
||||||
|
if G.ioDelay>0, error('Delay terms are not allowed');
|
||||||
|
else, G1=fotf(G.num,G.den); end
|
||||||
|
elseif n~=m
|
||||||
|
error('Error: non-square matrix, not invertible')
|
||||||
|
else, G1=fotfinv(G); end
|
||||||
|
end
|
||||||
|
function G1=fotfinv(G)
|
||||||
|
[n,~]=size(G); A1=G; E0=fotf(eye(n)); A3=E0;
|
||||||
|
for i=1:n, ij=1:n; ij=ij(ij~=i);
|
||||||
|
E=fotf(eye(n)); a0=inv(A1(i,i));
|
||||||
|
for k=ij, E(k,i)=-A1(k,i)*a0; end
|
||||||
|
E0=E*E0; A1=E*A1; A3(i,i)=a0;
|
||||||
|
end, G1=A3*E0;
|
||||||
|
end
|
7
FOTF Toolbox/@fotf/isfotf.m
Normal file
7
FOTF Toolbox/@fotf/isfotf.m
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
function key=isfotf(p)
|
||||||
|
%isfotf check input is an FOTF object or not
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
key=isa(p,'fotf');
|
||||||
|
end
|
34
FOTF Toolbox/@fotf/isstable.m
Normal file
34
FOTF Toolbox/@fotf/isstable.m
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function [K,alpha0,apol,p]=isstable(G,a0)
|
||||||
|
% isstable - check whether an FOTF object is stable or not
|
||||||
|
%
|
||||||
|
% [K,alpha,apol]=isstable(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% K- identifier to indicate the stability of G, returns 0, and 1
|
||||||
|
% alpha - the common order
|
||||||
|
% apol - all the pseudo poles of the system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n0,m0]=size(G); K=1; if nargin==1, a0=0.001; end
|
||||||
|
for i=1:n0, for j=1:m0
|
||||||
|
g=G(i,j); a=g.den.na; a1=fix(a/a0);
|
||||||
|
if length(a1)==1 && a1==0
|
||||||
|
else
|
||||||
|
[g1,alpha]=fotf2cotf(g); c=g1.den{1};
|
||||||
|
alpha0(i,j)=alpha; p0=roots(c); kk=[];
|
||||||
|
for k=1:length(p0)
|
||||||
|
a=g.den.a; na=g.den.na; pa=p0(k)^(1/alpha);
|
||||||
|
if norm(a*[pa.^na'])<1e-6, kk=[kk,k]; end
|
||||||
|
end
|
||||||
|
p=p0(kk); subplot(n0,m0,(i-1)*m0+j),
|
||||||
|
plot(real(p),imag(p),'x',0,0), xm=xlim;
|
||||||
|
if alpha<1, xm(1)=0; else, xm(2)=0; end
|
||||||
|
apol=min(abs(angle(p))); K=K*(apol>alpha*pi/2);
|
||||||
|
a1=tan(alpha*pi/2)*xm; a2=tan(alpha*pi)*xm;
|
||||||
|
line(xm,a1), line(xm,-a1), line(xm,a2), line(xm,-a2)
|
||||||
|
xlabel('Real Axis'), ylabel('Imaginary Axis')
|
||||||
|
end, end, end
|
||||||
|
title('Pole Map')
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/iszero.m
Normal file
14
FOTF Toolbox/@fotf/iszero.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function key=iszero(g)
|
||||||
|
% iszero - check whether a SISO FOTF object is zero or not
|
||||||
|
%
|
||||||
|
% key=iszero(G)
|
||||||
|
%
|
||||||
|
% G - a SISO FOTF object
|
||||||
|
% key - identifier, if G is zero, then key = 1.
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
key=0; [~,~,b,nb]=fotfdata(g);
|
||||||
|
if isempty(b) || (length(nb)==1 && abs(b(1))<eps), key=1; end
|
||||||
|
end
|
26
FOTF Toolbox/@fotf/latex.m
Normal file
26
FOTF Toolbox/@fotf/latex.m
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function str=latex(G)
|
||||||
|
% latex - convert an FOTF object into its LaTeX string
|
||||||
|
%
|
||||||
|
% str=latex(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% str - LaTeX string
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G);
|
||||||
|
if n*m==1
|
||||||
|
str=['\frac{' latex(G.num) '}{' latex(G.den) '}']; T= G.ioDelay;
|
||||||
|
if T~=0, ss=[]; if T~=1, ss=num2str(T); end
|
||||||
|
str=[str '\mathrm{e}^{-' ss 's}'];
|
||||||
|
end
|
||||||
|
else
|
||||||
|
str='\begin{bmatrix}';
|
||||||
|
for i=1:n
|
||||||
|
for j=1:m
|
||||||
|
str=[str, '\displaystyle ' latex(G(i,j)) '&'];
|
||||||
|
end, str=[str(1:end-1) '\cr'];
|
||||||
|
end, str=[str(1:end-3),'\end{bmatrix}'];
|
||||||
|
end
|
||||||
|
end
|
26
FOTF Toolbox/@fotf/lsim.m
Normal file
26
FOTF Toolbox/@fotf/lsim.m
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function y=lsim(G,u,t)
|
||||||
|
% lsim - simulation of an FOTFS object driven by given inputs
|
||||||
|
%
|
||||||
|
% lsim(G,u,t)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% u, t- input samples and time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); t0=t(1); t1=t(end); [nu,mu]=size(u);
|
||||||
|
if nu==m && mu==length(t), u=u.'; end
|
||||||
|
if nargout==0, lsim(tf(zeros(n,m)),'w',zeros(size(u)),t); end
|
||||||
|
for i=1:n, y1=0;
|
||||||
|
for j=1:m, g=G(i,j); uu=u(:,j);
|
||||||
|
y2=fode_sol9(g.den.a,g.den.na,g.num.a,g.num.na,uu,t,3);
|
||||||
|
ii=find(t>=g.ioDelay); lz=zeros(1,ii(1)-1);
|
||||||
|
y2=[lz, y2(1:end-length(lz))]; y(:,i)=y1+y2;
|
||||||
|
end, end
|
||||||
|
if nargout==0, khold=ishold; hold on
|
||||||
|
h=get(gcf,'child'); h0=h(end:-1:2);
|
||||||
|
for i=1:n, axes(h0(i));
|
||||||
|
plot(t,y(:,i),t,u,'--'), xlim([t0,t1])
|
||||||
|
end, if khold==0, hold off, end, end
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/margin.m
Normal file
14
FOTF Toolbox/@fotf/margin.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function [Gm,Pm,Wcg,Wcp]=margin(G)
|
||||||
|
% margin - gain and phase margins of an FOTF object
|
||||||
|
%
|
||||||
|
% [Gm,Pm,Wcg,Wcp]=margin(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% Gm, Wcg - gain margin in dBs and the corresponding frequency
|
||||||
|
% Pm, Wcp - phase margin in degrees and the crossover frequency
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
H=bode(G,logspace(-4,4,1000)); [Gm,Pm,Wcg,Wcp]=margin(H);
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/maxdelay.m
Normal file
14
FOTF Toolbox/@fotf/maxdelay.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function T=maxdelay(G)
|
||||||
|
% maxdelay - extract the maximum delay from an FOTF object
|
||||||
|
%
|
||||||
|
% T=maxdelay(G)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% T - the maximum delay of the system
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
T=0; [n,m]=size(G);
|
||||||
|
for i=1:n, for j=1:m, T=max(T,G(i,j).ioDelay); end, end
|
||||||
|
end
|
15
FOTF Toolbox/@fotf/mfrd.m
Normal file
15
FOTF Toolbox/@fotf/mfrd.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function H1=mfrd(G,w)
|
||||||
|
% mfrd - evaluation of frequency responses of an FOTF object
|
||||||
|
%
|
||||||
|
% H=mfrd(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% w - frequency vector
|
||||||
|
% H - frequency response of G in MFD format
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
H=bode(G,w); h=H.ResponseData; H1=[];
|
||||||
|
for i=1:length(w); H1=[H1; h(:,:,i)]; end
|
||||||
|
end
|
10
FOTF Toolbox/@fotf/minus.m
Normal file
10
FOTF Toolbox/@fotf/minus.m
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function G=minus(G1,G2)
|
||||||
|
% minus - minus operation of two FOTF objects
|
||||||
|
%
|
||||||
|
% G=G1-G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G=G1+(-G2);
|
||||||
|
end
|
10
FOTF Toolbox/@fotf/mldivide.m
Normal file
10
FOTF Toolbox/@fotf/mldivide.m
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function G=mldivide(G1,G2)
|
||||||
|
% mldivide - left division of two FOTF objects
|
||||||
|
%
|
||||||
|
% G=G1\G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
G1=fotf(G1); G2=fotf(G2);
|
||||||
|
if maxdelay(G)==0 && maxdelay(G2)==0, G=inv(G1)*G2;
|
||||||
|
else, warning('block with positive delay'); end
|
30
FOTF Toolbox/@fotf/mpower.m
Normal file
30
FOTF Toolbox/@fotf/mpower.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function G1=mpower(G,n)
|
||||||
|
% mpower - power of an FOTF object
|
||||||
|
%
|
||||||
|
% G1=G^n
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% n - power. If G is s or constant, n can be any real number,
|
||||||
|
% If G is an FOSS, n should be integers
|
||||||
|
% G1 - returns G^n, and an FOSS object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n1,m1]=size(G);
|
||||||
|
if n==fix(n)
|
||||||
|
if n1==m1
|
||||||
|
if n>=0, G1=fotf(eye(n1)); for i=1:n, G1=G1*G; end
|
||||||
|
else, G1=inv(G)^(-n); end
|
||||||
|
elseif n==1, G1=G;
|
||||||
|
else, error('G must be a square matrix');
|
||||||
|
end
|
||||||
|
elseif n1==1 && m1==1
|
||||||
|
if length(G.num)==1 && length(G.den)==1
|
||||||
|
[a,na,b,nb,L]=fotfdata(G);
|
||||||
|
G1=fotf(a^n,na*n,b^n,nb*n,L*n);
|
||||||
|
else, error('mpower: power must be an integer.');
|
||||||
|
end
|
||||||
|
else, error('mpower: power must be an integer.');
|
||||||
|
end
|
||||||
|
end
|
12
FOTF Toolbox/@fotf/mrdivide.m
Normal file
12
FOTF Toolbox/@fotf/mrdivide.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function G=mrdivide(G1,G2)
|
||||||
|
% mldivide - right division of two FOTF objects
|
||||||
|
%
|
||||||
|
% G=G1/G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=fotf(G1); G2=fotf(G2);
|
||||||
|
if maxdelay(G1)==0 && maxdelay(G2)==0, G=G1*inv(G2);
|
||||||
|
else, error('block with positive delay'); end
|
||||||
|
end
|
30
FOTF Toolbox/@fotf/mtimes.m
Normal file
30
FOTF Toolbox/@fotf/mtimes.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function G=mtimes(G1,G2)
|
||||||
|
% mpower - product of two FOTF objects, series connection
|
||||||
|
%
|
||||||
|
% G=G1*G2
|
||||||
|
%
|
||||||
|
% G1, G2 - FOTF objects
|
||||||
|
% G - returns the product of the two FOTF objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=fotf(G1); G2=fotf(G2);
|
||||||
|
if numel(G1)==1 && numel(G2)==1, G=sisofotftimes(G1,G2);
|
||||||
|
else, [n1,m1]=size(G1); [n2,m2]=size(G2);
|
||||||
|
if m1==n2, G=fotf(zeros(n1,m2));
|
||||||
|
for i=1:n1, for j=1:m2
|
||||||
|
for k=1:m1, G(i,j)=G(i,j)+sisofotftimes(G1(i,k),G2(k,j));
|
||||||
|
end, end, end
|
||||||
|
elseif n1*m1==1, G=fotf(zeros(n2,m2)); % if G1 is scalar
|
||||||
|
for i=1:n2, for j=1:m2, G(i,j)=G1*G2(i,j); end, end
|
||||||
|
elseif n2*m2==1, G=fotf(zeros(n1,m1)); % if G2 is scalar
|
||||||
|
for i=1:n1, for j=1:m1, G(i,j)=G2*G1(i,j); end, end
|
||||||
|
else
|
||||||
|
error('The two matrices are incompatible for multiplication')
|
||||||
|
end, end, end
|
||||||
|
% product of two SISO FOTF objects
|
||||||
|
function G=sisofotftimes(G1,G2)
|
||||||
|
G=fotf(G1.den*G2.den,G1.num*G2.num); G=simplify(G);
|
||||||
|
G.ioDelay=G1.ioDelay+G2.ioDelay;
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/nichols.m
Normal file
14
FOTF Toolbox/@fotf/nichols.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function nichols(G,w)
|
||||||
|
% nichols - draw the Nichols chart of an FOTF object
|
||||||
|
%
|
||||||
|
% nichols(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% w - the frequency vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
arguments, G, w=logspace(-4,4); end
|
||||||
|
H=bode(G,w); nichols(H);
|
||||||
|
end
|
26
FOTF Toolbox/@fotf/norm.m
Normal file
26
FOTF Toolbox/@fotf/norm.m
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function n=norm(G,eps0)
|
||||||
|
% norm -= norms of an FOTF object
|
||||||
|
%
|
||||||
|
% norm(G), norm(G,inf)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% The 2-norm and infinity-norm of G can be evaluated, respectively
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); if nargin==1, eps0=1e-6; end
|
||||||
|
for i=1:n, for j=1:m, A(i,j)=snorm(G(i,j),eps0); end, end
|
||||||
|
n=norm(A);
|
||||||
|
end
|
||||||
|
% norm of a SISO FOTF object
|
||||||
|
function n=snorm(G,eps0)
|
||||||
|
j=sqrt(-1);
|
||||||
|
if nargin==2 && ~isfinite(eps0) % H infinity norm, find the maximum value
|
||||||
|
f=@(w)-abs(freqresp(j*w,G));
|
||||||
|
w=fminsearch(f,0); n=abs(freqresp(j*w,G));
|
||||||
|
else % H2 norm, numerical integration
|
||||||
|
f=@(s)freqresp(s,G).*freqresp(-s,G);
|
||||||
|
n=integral(f,-inf,inf)/(2*pi*j);
|
||||||
|
end
|
||||||
|
end
|
12
FOTF Toolbox/@fotf/numel.m
Normal file
12
FOTF Toolbox/@fotf/numel.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function n=numel(G)
|
||||||
|
% numel - the number of FOTF objects in G
|
||||||
|
%
|
||||||
|
% n=numel(G)
|
||||||
|
%
|
||||||
|
% G - FOTF object
|
||||||
|
% n - returns the number of FOTF objects in G
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); n=n*m;
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/nyquist.m
Normal file
14
FOTF Toolbox/@fotf/nyquist.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function nyquist(G,w)
|
||||||
|
% nyquist - draw the Nyquist plot of an FOTF object
|
||||||
|
%
|
||||||
|
% nyquist(G,w)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% w - the frequency vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
arguments, G, w=logspace(-4,4); end
|
||||||
|
H=bode(G,w); nyquist(H);
|
||||||
|
end
|
30
FOTF Toolbox/@fotf/plus.m
Normal file
30
FOTF Toolbox/@fotf/plus.m
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function G=plus(G1,G2)
|
||||||
|
% plus - evaluate the sum of two FOTF objects, parallel connection
|
||||||
|
%
|
||||||
|
% G=G1+G2
|
||||||
|
%
|
||||||
|
% G1, G2 - the two FOTF objects in parallel connection
|
||||||
|
% G - the sum of G1 and G2
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
G1=fotf(G1); G2=fotf(G2);
|
||||||
|
[n1,m1]=size(G1); [n2,m2]=size(G2);
|
||||||
|
if n1==n2 && m1==m2, G=G1;
|
||||||
|
for i=1:n1, for j=1:m1
|
||||||
|
G(i,j)=sisofotfplus(G1(i,j),G2(i,j));
|
||||||
|
end, end
|
||||||
|
elseif n1*m1==1, G1=G1*fotf(ones(n2,m2)); G=G1+G2;
|
||||||
|
elseif n2*m2==1, G2=G2*fotf(ones(n1,m1)); G=G1+G2;
|
||||||
|
else
|
||||||
|
error('Error: the sizes of the two FOTF matrices mismatch');
|
||||||
|
end
|
||||||
|
% sum of two SISO FOTF objects
|
||||||
|
function G=sisofotfplus(G1,G2)
|
||||||
|
if G1.ioDelay==G2.ioDelay
|
||||||
|
G=fotf(G1.den*G2.den,G1.num*G2.den+G2.num*G1.den);
|
||||||
|
G=simplify(G); G.ioDelay=G1.ioDelay;
|
||||||
|
else, error('Error: cannot handle different delays');
|
||||||
|
end, end
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/residue.m
Normal file
14
FOTF Toolbox/@fotf/residue.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function [alpha,r,p,K]=residue(G)
|
||||||
|
% residue - partial fraction expansion of a SISO FOTF object
|
||||||
|
%
|
||||||
|
% [alpha,r,p,K]=residue(G)
|
||||||
|
%
|
||||||
|
% G - a SISO commensurate-order FOTF object
|
||||||
|
% alpha - base order
|
||||||
|
% r, p, K - the definitions are the same as the conventional residue function
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[H,alpha]=fotf2cotf(G); [r,p,K]=residue(H.num{1},H.den{1});
|
||||||
|
end
|
19
FOTF Toolbox/@fotf/rlocus.m
Normal file
19
FOTF Toolbox/@fotf/rlocus.m
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function rlocus(G)
|
||||||
|
% rlocus - draw the root locus of a SISO FOTF object
|
||||||
|
%
|
||||||
|
% rlocus(G)
|
||||||
|
%
|
||||||
|
% G - a SISO FOTF object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if numel(G)==1
|
||||||
|
[G1,alpha]=fotf2cotf(G); rlocus(G1), xm=xlim;
|
||||||
|
if alpha<1, xm(1)=0; else, xm(2)=0; end
|
||||||
|
line(xm,tan(alpha*pi/2)*xm), line(xm,-tan(alpha*pi/2)*xm)
|
||||||
|
line(xm,tan(alpha*pi)*xm), line(xm,-tan(alpha*pi)*xm)
|
||||||
|
else
|
||||||
|
error('Root locus only applies to SISO systems');
|
||||||
|
end
|
||||||
|
end
|
20
FOTF Toolbox/@fotf/sigma.m
Normal file
20
FOTF Toolbox/@fotf/sigma.m
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function sigma(G,w)
|
||||||
|
% sigma - singular value plots of a MIMO FOTF object
|
||||||
|
%
|
||||||
|
% sigma(G,w)
|
||||||
|
%
|
||||||
|
% G - a MIMO FOTF object
|
||||||
|
% w - a frequency vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if nargin==1, w=logspace(-4,4); end
|
||||||
|
H=bode(G,w); subplot(111); h1=[]; H1=H;
|
||||||
|
h=H.ResponseData; [n,m,k]=size(h);
|
||||||
|
for i=1:k, h1=[h1, svd(h(:,:,i))]; end
|
||||||
|
for i=1:min([n,m])
|
||||||
|
h2(1,1,:)=h1(i,:).'; H1.ResponseData=h2; bodemag(H1), hold on
|
||||||
|
end
|
||||||
|
hold off
|
||||||
|
end
|
20
FOTF Toolbox/@fotf/simplify.m
Normal file
20
FOTF Toolbox/@fotf/simplify.m
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function G=simplify(G,eps1)
|
||||||
|
% simplify - simplification of an FOTF object
|
||||||
|
%
|
||||||
|
% G=simplify(G1,eps1)
|
||||||
|
%
|
||||||
|
% G1 - a FOTF object
|
||||||
|
% eps1 - error tolerance
|
||||||
|
% G - simplified FOTF object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); if nargin==1, eps1=eps; end
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
g=G(i,j); num=g.num.a; den=g.den.a; nn=g.num.na; nd=g.den.na;
|
||||||
|
i1=abs(num)>eps1; i2=abs(den)>eps1; num=num(i1); den=den(i2);
|
||||||
|
nn=nn(i1); nd=nd(i2); n0=min(nn); d0=min(nd);
|
||||||
|
na=min(n0,d0); if isempty(na), na=0; end
|
||||||
|
G(i,j)=fotf(den,nd-na,num,nn-na,g.ioDelay);
|
||||||
|
end, end, end
|
33
FOTF Toolbox/@fotf/step.m
Normal file
33
FOTF Toolbox/@fotf/step.m
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
function Y=step(G,t,key)
|
||||||
|
% step - simulation of an FOTF object driven by step inputs
|
||||||
|
%
|
||||||
|
% step(G,t)
|
||||||
|
%
|
||||||
|
% G - an FOTF object
|
||||||
|
% t- the time vector
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G); M=tf(zeros(n,m));
|
||||||
|
if nargin==1, t=(0:0.2:10)'; elseif length(t)==1, t=0:t/100:t; end
|
||||||
|
if nargout==0, t0=t(1); t1=t(end);
|
||||||
|
if nargin<=2, step(M,'w'); else, impulse(M,'w');
|
||||||
|
end, end
|
||||||
|
for i=1:n, for j=1:m
|
||||||
|
g=G(i,j); y1=g_step(g,t); y(i,j,:)=y1';
|
||||||
|
end, end
|
||||||
|
if nargout==0, khold=ishold; hold on
|
||||||
|
h=get(gcf,'child'); h0=h(end:-1:2);
|
||||||
|
for i=1:n, for j=1:m, axes(h0((i-1)*n+j));
|
||||||
|
yy=y(i,j,:); plot(t,yy(:)), xlim([t0,t1])
|
||||||
|
end, end
|
||||||
|
if khold==0, hold off, end
|
||||||
|
elseif n*m==1, Y=y1; else, Y=y; end
|
||||||
|
end
|
||||||
|
%subfunction to evaluate step response of SISO model
|
||||||
|
function y=g_step(g,t,key)
|
||||||
|
u=ones(size(t));
|
||||||
|
[a,na,b,nb,T]=fotfdata(g); y1=fode_sol(a,na,b,nb,u,t);
|
||||||
|
ii=find(t>=T); lz=zeros(1,ii(1)-1); y=[lz, y1(1:end-length(lz))];
|
||||||
|
end
|
14
FOTF Toolbox/@fotf/uminus.m
Normal file
14
FOTF Toolbox/@fotf/uminus.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function G=uminus(G)
|
||||||
|
% uminus - unary minus of an FOTFS object
|
||||||
|
%
|
||||||
|
% G1=-G
|
||||||
|
%
|
||||||
|
% G - an FOT object
|
||||||
|
% G1- the unary minus of G, i.e., -G
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
[n,m]=size(G);
|
||||||
|
for i=1:n, for j=1:m, G(i,j).num=-G(i,j).num; end, end
|
||||||
|
end
|
18
FOTF Toolbox/@ppoly/collect.m
Normal file
18
FOTF Toolbox/@ppoly/collect.m
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
function p=collect(p)
|
||||||
|
% collect - collect like terms in ppoly objects
|
||||||
|
%
|
||||||
|
% p=collect(p)
|
||||||
|
%
|
||||||
|
% p - a ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
a=p.a; na=p.na;
|
||||||
|
[na,ii]=sort(na,'descend'); a=a(ii); ax=diff(na); key=1;
|
||||||
|
for i=1:length(ax)
|
||||||
|
if abs(ax(i))<=1e-10
|
||||||
|
a(key)=a(key)+a(key+1); a(key+1)=[]; na(key+1)=[];
|
||||||
|
else, key=key+1; end
|
||||||
|
end
|
||||||
|
ii=find(abs(a)~=0); a=a(ii); na=na(ii); p=ppoly(a,na);
|
||||||
|
end
|
23
FOTF Toolbox/@ppoly/disp.m
Normal file
23
FOTF Toolbox/@ppoly/disp.m
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function str=disp(p)
|
||||||
|
% collect - collect like terms in ppoly objects
|
||||||
|
%
|
||||||
|
% p=collect(p)
|
||||||
|
%
|
||||||
|
% p - a ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
np=p.na; p=p.a;
|
||||||
|
if isempty(np), p=0; np=0; end
|
||||||
|
P=''; [np,ii]=sort(np,'descend'); p=p(ii);
|
||||||
|
for i=1:length(p)
|
||||||
|
P=[P,'+',num2str(p(i)),'*s^{',num2str(np(i)),'}'];
|
||||||
|
end
|
||||||
|
P=P(2:end); P=strrep(P,'s^{0}',''); P=strrep(P,'+-','-');
|
||||||
|
P=strrep(P,'^{1}',''); P=strrep(P,'+1*s','+s');
|
||||||
|
P=strrep(P,'*+','+'); P=strrep(P,'*-','-');
|
||||||
|
P=strrep(P,'-1*s','-s'); nP=length(P);
|
||||||
|
if nP>=3 && isequal(P(1:3),'1*s'), P=P(3:end); end
|
||||||
|
if P(end)=='*', P(end)=''; end
|
||||||
|
if nargout==0, disp(P), else, str=P; end
|
||||||
|
end
|
12
FOTF Toolbox/@ppoly/eq.m
Normal file
12
FOTF Toolbox/@ppoly/eq.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function key=eq(p1,p2)
|
||||||
|
% eq - test whether two PPOLY objects are equal or not
|
||||||
|
%
|
||||||
|
% key=p1==p2
|
||||||
|
%
|
||||||
|
% p1, p2 - the two PPOLY objects
|
||||||
|
% key = 1 for equal, otherwise key = 0
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
g=collect(p1-p2); key=isempty(g.a);
|
||||||
|
end
|
13
FOTF Toolbox/@ppoly/freqw.m
Normal file
13
FOTF Toolbox/@ppoly/freqw.m
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
function H=freqw(p,w)
|
||||||
|
% freqw - get frequency response of ppoly object
|
||||||
|
%
|
||||||
|
% H=freqw(p,w)
|
||||||
|
%
|
||||||
|
% p - a ppoly object
|
||||||
|
% w - frequency vector
|
||||||
|
% H - frequency response data
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
for i=1:length(w), H(i)=p.a(:).'*(1i*w(i)).^p.na(:); end
|
||||||
|
end
|
19
FOTF Toolbox/@ppoly/get.m
Normal file
19
FOTF Toolbox/@ppoly/get.m
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function p1=get(varargin)
|
||||||
|
% get - get fields from ppoly object
|
||||||
|
%
|
||||||
|
% a=get(p,'a') or na=get(p,'na')
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p=varargin{1};
|
||||||
|
if nargin==1
|
||||||
|
s=sprintf('%f ,',p.a); disp([' a: [' s(1:end-1) ']'])
|
||||||
|
s=sprintf('%f ,',p.na); disp([' na: [' s(1:end-1) ']'])
|
||||||
|
elseif nargin==2, key=varargin{2};
|
||||||
|
switch key
|
||||||
|
case 'a', p1=p.a; case 'na', p1=p.na;
|
||||||
|
otherwise, error('Wrong field name used'),
|
||||||
|
end
|
||||||
|
else, error('Wrong number of input argumants');
|
||||||
|
end
|
||||||
|
end
|
11
FOTF Toolbox/@ppoly/isppoly.m
Normal file
11
FOTF Toolbox/@ppoly/isppoly.m
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
function key=isppoly(p)
|
||||||
|
% isppoly - check whether input is an ppoly object
|
||||||
|
%
|
||||||
|
% key=isppoly(p)
|
||||||
|
%
|
||||||
|
% key returns 1 or 0
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
key=strcmp(class(p),'ppoly');
|
||||||
|
end
|
12
FOTF Toolbox/@ppoly/latex.m
Normal file
12
FOTF Toolbox/@ppoly/latex.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function strA=latex(p)
|
||||||
|
% latex - convert ppoly object into LaTeX string
|
||||||
|
%
|
||||||
|
% str=latex(p)
|
||||||
|
%
|
||||||
|
% p - a ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
str=disp(p); str=strrep(str,'*s','s');
|
||||||
|
if nargout==0, disp(str), else, strA=str; end
|
||||||
|
end
|
11
FOTF Toolbox/@ppoly/minus.m
Normal file
11
FOTF Toolbox/@ppoly/minus.m
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
function p=minus(p1,p2)
|
||||||
|
% minus - find the differences in two ppoly objects
|
||||||
|
%
|
||||||
|
% p=p1-p2
|
||||||
|
%
|
||||||
|
% p, p1, p2 - ppoly objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p=p1+(-p2);
|
||||||
|
end
|
15
FOTF Toolbox/@ppoly/mpower.m
Normal file
15
FOTF Toolbox/@ppoly/mpower.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function p1=mpower(p,n)
|
||||||
|
% mpower - power of a ppoly object
|
||||||
|
%
|
||||||
|
% p1=p^n
|
||||||
|
%
|
||||||
|
% p - a ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
if length(p.a)==1, p1=ppoly(p.a^n,p.na*n);
|
||||||
|
elseif n==floor(n)
|
||||||
|
if n<0, p.na=-p.na; n=-n; end
|
||||||
|
p1=ppoly(1); for i=1:n, p1=p1*p; end
|
||||||
|
else, error('n must be an integer'), end
|
||||||
|
end
|
11
FOTF Toolbox/@ppoly/mrdivide.m
Normal file
11
FOTF Toolbox/@ppoly/mrdivide.m
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
function p=mrdivide(p1,p2)
|
||||||
|
% mrdivide - right divide ppoly objects
|
||||||
|
%
|
||||||
|
% p=p1/p2
|
||||||
|
%
|
||||||
|
% p, p1, p2 - ppoly objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p1=collect(ppoly(p1)); p2=collect(ppoly(p2)); p=fotf(p2,p1);
|
||||||
|
end
|
12
FOTF Toolbox/@ppoly/mtimes.m
Normal file
12
FOTF Toolbox/@ppoly/mtimes.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function p=mtimes(p1,p2)
|
||||||
|
% mtimes - product of two ppoly objects
|
||||||
|
%
|
||||||
|
% p=p1*p2
|
||||||
|
%
|
||||||
|
% p, p1, p2 - ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p1=ppoly(p1); p2=ppoly(p2); a=kron(p1.a,p2.a);
|
||||||
|
na=kronsum(p1.na,p2.na); p=collect(ppoly(a,na));
|
||||||
|
end
|
12
FOTF Toolbox/@ppoly/plus.m
Normal file
12
FOTF Toolbox/@ppoly/plus.m
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function p=plus(p1,p2)
|
||||||
|
% plus - sum of twp ppoly objects
|
||||||
|
%
|
||||||
|
% p=p1+p2
|
||||||
|
%
|
||||||
|
% p, p1, p2 - ppoly objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p1=ppoly(p1); p2=ppoly(p2);
|
||||||
|
a=[p1.a,p2.a]; na=[p1.na,p2.na]; p=collect(ppoly(a,na));
|
||||||
|
end
|
15
FOTF Toolbox/@ppoly/ppoly.m
Normal file
15
FOTF Toolbox/@ppoly/ppoly.m
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
% ppoly - class definition of a ppoly object
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
classdef ppoly
|
||||||
|
properties, a, na, end
|
||||||
|
methods
|
||||||
|
function p=ppoly(a,na)
|
||||||
|
if nargin==1
|
||||||
|
if isa(a,'double'), p=ppoly(a,length(a)-1:-1:0);
|
||||||
|
elseif isa(a,'ppoly'), p=a;
|
||||||
|
elseif a=='s', p=ppoly(1,1); end
|
||||||
|
elseif length(a)==length(na), p.a=a; p.na=na;
|
||||||
|
else, error('Error: miss matching in a and na'); end
|
||||||
|
end, end, end
|
11
FOTF Toolbox/@ppoly/uminus.m
Normal file
11
FOTF Toolbox/@ppoly/uminus.m
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
function p1=uminus(p)
|
||||||
|
% uminus - find -p
|
||||||
|
%
|
||||||
|
% p1=-p
|
||||||
|
%
|
||||||
|
% p, p1 - ppoly objects
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
p1=ppoly(-p.a,p.na);
|
||||||
|
end
|
197
FOTF Toolbox/Contents.m
Normal file
197
FOTF Toolbox/Contents.m
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
%FOTF Toolbox - A MATLAB Toolbox for the modeling, analysis and design of fractional-order systems
|
||||||
|
%
|
||||||
|
% (c) Professor Dingy\"u Xue, Northeastern University, Shenyang, China
|
||||||
|
% Email: xuedingyu@mail.neu.edu.cn
|
||||||
|
% Date of last modification, 23 December, 2016
|
||||||
|
%
|
||||||
|
% This newly modified toolbox is written for the monograph,
|
||||||
|
%
|
||||||
|
% @BOOK{bkXueDFOCS,
|
||||||
|
% Author = {Xue Dingy\"u},
|
||||||
|
% Address = {Berlin},
|
||||||
|
% Publisher = {de Gruyter Press},
|
||||||
|
% Title = {Fractional-order Control Systems - Fundamentals and Numerical Implementations},
|
||||||
|
% Year = {2017}
|
||||||
|
% }
|
||||||
|
%
|
||||||
|
% Multivariable fractional-order systems are fully supported in the classes FOTF and FOSS
|
||||||
|
% and low-level numerical algorithms are replaced by $O(h^p)$ precision ones.
|
||||||
|
% For details in theory and programming, please refer to the monograph.
|
||||||
|
|
||||||
|
% (I) Special functions and fundamentals in numerical computation
|
||||||
|
% beta_c - beta function evaluation for complex arguments
|
||||||
|
% common_order - compute the common order
|
||||||
|
% fence_shadow - draw the shawdows on the walls
|
||||||
|
% fmincon_global - a global constrained optimisation problem solver
|
||||||
|
% funmsym - evaluate symbolic matrix functions
|
||||||
|
% gamma_c - Gamma function evaluation for complex arguments
|
||||||
|
% kronsum - compute Kronecker sum
|
||||||
|
% mittag_leffler - symbolic evaluation of Mittag-Leffler functions
|
||||||
|
% ml_func - numerical evaluation of Mittag-Leffler functions and derivatives
|
||||||
|
% more_sols - find possible all solutions of nonlinear matrix equations
|
||||||
|
% more_vpasols - symbolic version of more_sols, high precision solutions
|
||||||
|
% new_inv - simple matrix inverse function, not recommended in applications
|
||||||
|
%
|
||||||
|
%(II) Numerical evaluations of fractional-order derivatives and integrals
|
||||||
|
% caputo - computation of Caputo derivatives with interpolation, not recommended
|
||||||
|
% caputo9 - evaluation of Caputo derivatives with $O(h^p)$, recommended
|
||||||
|
% genfunc - computation of generating function coefficients symbolically
|
||||||
|
% get_vecw - computation of $O(h^p)$ weighting coefficients
|
||||||
|
% glfdiff0 - evaluation of GL derivatives, not recommended
|
||||||
|
% glfdiff - standard evaluation of GL derivatives, with $O(h)$
|
||||||
|
% glfdiff2 - evaluation of $O(h^p)$ GL derivatives, not recommended
|
||||||
|
% glfdiff9 - evaluation of $O(h^p)$ GL derivatives, recommended
|
||||||
|
% glfdiff_fft - evaluation of $O(h^p)$ GL derivatives with FFT, not recommended
|
||||||
|
% glfdiff_mat - matrix version of glfdiff, not recommended for large samples
|
||||||
|
% glfdiff_mem - GL derivative evaluation with short-memory effect
|
||||||
|
% rlfdiff evaluation of RL derivatives, not recommended, use glfdiff9 instead
|
||||||
|
%
|
||||||
|
%(III) Numerical evaluations of linear fractional-order differential equations
|
||||||
|
% caputo_ics - equivalent initial condition reconstruction, called by fode_caputo9
|
||||||
|
% fode_caputo0 - simple Caputo FODE solver with nonzero initial conditions
|
||||||
|
% fode_caputo9 - $O(h^p)$ solution of Caputo equations with nonzero ICs
|
||||||
|
% fode_sol - closed-form solution of FODE with zero initial conditions
|
||||||
|
% fode_solm - matrix version of fode_sol, not recommended for large samples
|
||||||
|
% fode_sol9 - $O(h^p)$ version of fode_sol
|
||||||
|
% ml_step3 - numerical solution of step response of 3-term models
|
||||||
|
%
|
||||||
|
%(IV) Numerical evaluations of nonlinear fractional-order differential equations
|
||||||
|
% INVLAP_new - closed-loop response evaluation with inverse Laplace transform
|
||||||
|
% nlfode_mat - matrix-based solutions of implicit nonlinear FODEs
|
||||||
|
% nlfode_vec - nonlinear fractional-order extended state space equation solver
|
||||||
|
% nlfode_vec1 - a different version of nlfode_vec, not recommended
|
||||||
|
% nlfec - $O(h^p)$ corrector solution of nonlinear multi-term FODEs
|
||||||
|
% nlfep - $O(h^p)$ predictor solution of nonlinear multi-term fractional-order ODEs
|
||||||
|
% pepc_nlfode - numerical solutions of single-term nonlinear FODE with PCPE algorithm
|
||||||
|
%
|
||||||
|
%(V) Filter design for fractional-order derivatives and systems
|
||||||
|
% carlson_fod - design of a Carlson filter
|
||||||
|
% charef_fod - design of a Charef filter
|
||||||
|
% charef_opt - design of an optimal Charef filter
|
||||||
|
% cont_frac0 - continued-fraction interface to irrational functions
|
||||||
|
% matsuda_fod - design of Matsuda-Fujii filter
|
||||||
|
% new_fod - design of a modified Oustaloup filter
|
||||||
|
% opt_app - optimal IO transfer approximation of high-order models
|
||||||
|
% ousta_fod - design of a standard Oustaloup filter
|
||||||
|
%
|
||||||
|
%(VI) FOTF object design and overload functions
|
||||||
|
% base_order - find the base order from an FOTF object
|
||||||
|
% bode - Bode diagram analysis
|
||||||
|
% diag - diagonal FOTF matrix creation and extraction
|
||||||
|
% display - overload function to display a MIMO FOTF object
|
||||||
|
% eig - find all the poles, including extraneous roots
|
||||||
|
% eq - checks whether two FOTF blocks equal or not
|
||||||
|
% feedback - overload the feedback function for two FOTF blocks
|
||||||
|
% foss_a - convert an FOTF to an extended FOSS object
|
||||||
|
% fotf - creation of an FOTF class
|
||||||
|
% fotf2cotf - convert an FOTF object into commensurate form
|
||||||
|
% fotf2foss - low-level conversion function of FOTF to FOSS object
|
||||||
|
% fotfdata - extract all the fields from an FOTF object
|
||||||
|
% freqresp - low-level frequency response function of an FOTF object
|
||||||
|
% high_order - high-order IO transfer function approximation of FOTF objects
|
||||||
|
% impulse - evaluation of impulse response of an FOTF object
|
||||||
|
% inv - inverse FOTF matrix
|
||||||
|
% isstable - check whether an FOTF object stable or not
|
||||||
|
% iszero - check whether an FOTF object is zero or not
|
||||||
|
% lsim - time response evaluation to arbitrary input signals
|
||||||
|
% margin - compute the gain and phase margins
|
||||||
|
% maxdelay - extract maximum delay from an FOTF object
|
||||||
|
% mfrd - frequency response evaluation
|
||||||
|
% minus - minus operation of two FOTF objects
|
||||||
|
% mldivide - left-division function
|
||||||
|
% mpower - power of an FOTF object
|
||||||
|
% mrdivide - right-division function
|
||||||
|
% mtimes - overload function of * operation of two blocks
|
||||||
|
% nichols - Nichols chart
|
||||||
|
% norm - H2 and Hinf evaluation
|
||||||
|
% nyquist - Nyquist plot
|
||||||
|
% plus - overload function of + operation of two blocks
|
||||||
|
% residue - partial fraction expansion
|
||||||
|
% rlocus - root locus analysis
|
||||||
|
% sigma - singular value plots
|
||||||
|
% simplify - simplification of an FOTF object
|
||||||
|
% step - step response
|
||||||
|
% uminus - unary minus of an FOTF object
|
||||||
|
%
|
||||||
|
%(VII) FOSS object design and overload functions
|
||||||
|
% bode - Bode diagram analysis
|
||||||
|
% coss_aug - FOSS augmentation
|
||||||
|
% ctrb - controllability test matrix creation
|
||||||
|
% display - overload function to display a MIMO FOSS object
|
||||||
|
% eig - compute the poles of a FOSS object
|
||||||
|
% eq - checks two FOSS blocks equal or not
|
||||||
|
% feedback - overload the feedback function for two FOSS blocks
|
||||||
|
% foss - FOSS class creation
|
||||||
|
% foss2fotf - low-level conversion from FOSS to FOTF object
|
||||||
|
% impulse - evaluation of impulse response of an FOSS object
|
||||||
|
% inv - inverse of an FOSS object
|
||||||
|
% isstable - check an FOSS object stable or not
|
||||||
|
% lsim - time response evaluation to arbitrary input signals
|
||||||
|
% margin - compute the gain and phase margins
|
||||||
|
% mfrd - frequency response evaluation
|
||||||
|
% minreal - minimum realisation of a FOSS object
|
||||||
|
% minus - minus operation of two FOTF objects
|
||||||
|
% mpower - power of an FOSS object
|
||||||
|
% mtimes - overload function of * operation of two blocks
|
||||||
|
% nichols - Nichols chart
|
||||||
|
% norm - H2 and Hinf evaluation
|
||||||
|
% nyquist - Nyquist plot
|
||||||
|
% obsv - construct observability test matrix
|
||||||
|
% order - find the orders of an FOSS object
|
||||||
|
% plus - overload function of + operation of two blocks
|
||||||
|
% rlocus - root locus analysis
|
||||||
|
% size - find the numbers of inputs, outputs and states
|
||||||
|
% ss_extract - extract integer-order state space object from FOSS
|
||||||
|
% step - step response
|
||||||
|
% uminus - unary minus of an FOSS object
|
||||||
|
%
|
||||||
|
%(VIII) Simulink models
|
||||||
|
% fotflib - Simulink blockset for FOTF Toolbox
|
||||||
|
% fotf2sl - multivariable FOTF to Simulink block convertor
|
||||||
|
% sfun_mls - S-function version of Mittag-Leffler function
|
||||||
|
% slblocks - default Simulink description file
|
||||||
|
% c9mvofuz - Simulink model for variable-order fuzzy PID control systems
|
||||||
|
% c9mvofuz2 - Simulink model for variable-order fuzzy PID systems with variable delays
|
||||||
|
% c10mpdm2 - Simulink model for multivariable PID control system
|
||||||
|
% c10mpopt - Simulink model for multivariable parameter optimisation control systems
|
||||||
|
% fPID_simu - Simulink model fractional-order PID controller for single-variable system
|
||||||
|
%
|
||||||
|
%(IX) Fractional-order and other controller design
|
||||||
|
% c9mfpid - fractional-order PID controller design with equation solution techniques
|
||||||
|
% c9mfpid_con - constraints in optimum FOPID design of FOPDT plants
|
||||||
|
% c9mfpid_con1 - constraints in optimum FOPID design of FOIPDT plants
|
||||||
|
% c9mfpid_con2 - constraints in optimum FOPID design of FO-FOPDT plants
|
||||||
|
% c9mfpid_opt - objective function in optimum FOPID design of FOPDT plants
|
||||||
|
% c9mfpid_opt1 - objective function in optimum FOPID design of FOIPDT plants
|
||||||
|
% c9mfpid_opt2 - objective function in optimum FOPID design of FO-FOPDT plants
|
||||||
|
% ffuz_param - S-function for parameter setting of fuzzy fractional-order PIDs
|
||||||
|
% fopid - construct a \fPID{} controller from parameters
|
||||||
|
% fpidfun - an example of objective function for optimum fractional-order PIDs
|
||||||
|
% fpidfuns - objective function for fractional-order PID controller design
|
||||||
|
% fpidtune - design of optimum fractional-order PID controllers
|
||||||
|
% gershgorin - draw Nyquist plots with Gershgorin bands
|
||||||
|
% get_fpidf - build string expression of the open-loop model
|
||||||
|
% mfd2frd - convert MFD data into FRD data
|
||||||
|
% optimfopid - GUI for optimum fractional-order PID design
|
||||||
|
% optimpid - GUI for optimum integer-order PID design
|
||||||
|
% pseuduag - pseudodiagonalisation of multivariable systems
|
||||||
|
%
|
||||||
|
%(X) Dedicated functions and models for the examples
|
||||||
|
% c2exnls - constraint function of an example
|
||||||
|
% c8mstep - Simulink model of a multivariable fractional-order system
|
||||||
|
% c8mfpid1 - Simulink model of a fractional-order PID control system
|
||||||
|
% c8mchaos - vectorised Simulink model for fractional-order Chua system
|
||||||
|
% c8mchaosd - data input file for c8mchaos
|
||||||
|
% c8mchua - MATLAB description of fractional-order Chua equations
|
||||||
|
% c8mchuasim - Simulink model for fractional-order Chua circuit
|
||||||
|
% c8mblk2,3,5 - three Simulink models of a linear fractional-order equation
|
||||||
|
% c8mcaputo - complicated Simulink model for nonlinear FODE
|
||||||
|
% c8mexp2 - simpler Simulink model for nonlinear Caputo equations
|
||||||
|
% c8mexp2m - MATLAB description of nonlinear Caputo equation
|
||||||
|
% c8mnlf1, c8mnlf2 - two different Simulink models of a nonlinear FODE
|
||||||
|
% c8mexp1x - MATLAB function for describing nonlinear Caputo equations
|
||||||
|
% c8nleq - MATLAB description of a nonlinear single-term Caputo equation
|
||||||
|
% c8mlinc1 - Simulink model of a linear fractional-order Caputo equation
|
||||||
|
% c9ef1-c9ef3 - criteria for optimum fractional-order PID controllers
|
||||||
|
% c9mplant - Simulink model used for optimpid design
|
||||||
|
|
49
FOTF Toolbox/INVLAP_new.m
Normal file
49
FOTF Toolbox/INVLAP_new.m
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
function [t,y]=INVLAP_new(G,t0,tn,N,H,tx,ux)
|
||||||
|
% INVLAP_new - updated version of INVLAP for closed-loop system with any inputs
|
||||||
|
%
|
||||||
|
% [t,y]=INVLAP_new(G,t0,tn,N)
|
||||||
|
% [t,y]=INVLAP_new(G,t0,tn,N,H)
|
||||||
|
% [t,y]=INVLAP_new(G,t0,tn,N,H,u)
|
||||||
|
% [t,y]=INVLAP_new(G,t0,tn,N,H,tx,ux)
|
||||||
|
%
|
||||||
|
% G - the string representation of the open-loop model
|
||||||
|
% t0, tn, N - the time interval and number of points in the interval
|
||||||
|
% H - the string representation of the feedback model
|
||||||
|
% u - the function handle of the input signal
|
||||||
|
% tx, ux - the samples of time and input signal
|
||||||
|
% y, t - the output and time vectors
|
||||||
|
|
||||||
|
% Copyright (c) Dingyu Xue, Northeastern University, China
|
||||||
|
% Last modified 28 March, 2017
|
||||||
|
% Last modified 18 May, 2022
|
||||||
|
arguments
|
||||||
|
G, t0(1,1), tn(1,1) {mustBeGreaterThan(tn,t0)}
|
||||||
|
N(1,1){mustBePositiveInteger}=100;
|
||||||
|
H(1,1)=0; tx='1'; ux(1,:) {mustBeNumeric}=0;
|
||||||
|
end
|
||||||
|
G=add_dots(G); if ischar(H), H=add_dots(H); end
|
||||||
|
if ischar(tx), tx=add_dots(tx); end
|
||||||
|
a=6; ns=20; nd=19; t=linspace(t0,tn,N);
|
||||||
|
if t0==0, t=[1e-6 t(2:N)]; end
|
||||||
|
n=1:ns+1+nd; alfa=a+(n-1)*pi*1j; bet=-exp(a)*(-1).^n;
|
||||||
|
n=1:nd; bet(1)=bet(1)/2;
|
||||||
|
bdif=fliplr(cumsum(gamma(nd+1)./gamma(nd+2-n)./gamma(n)))./2^nd;
|
||||||
|
bet(ns+2:ns+1+nd)=bet(ns+2:ns+1+nd).*bdif;
|
||||||
|
if isnumeric(H), H=num2str(H); end
|
||||||
|
for i=1:N
|
||||||
|
tt=t(i); s=alfa/tt; bt=bet/tt; sG=eval(G); sH=eval(H);
|
||||||
|
if ischar(tx), sU=eval(tx);
|
||||||
|
else
|
||||||
|
if isnumeric(tx)
|
||||||
|
f=@(x)interp1(tx,ux,x,'spline').*exp(-s.*x);
|
||||||
|
else, f=@(x)tx(x).*exp(-s.*x); end
|
||||||
|
sU=integral(f,t0,tn,'ArrayValued',true);
|
||||||
|
end
|
||||||
|
btF=bt.*sG./(1+sG.*sH).*sU; y(i)=sum(real(btF));
|
||||||
|
end, t=t(:); y=y(:);
|
||||||
|
end
|
||||||
|
% remove and add back dots uniformly
|
||||||
|
function F=add_dots(F)
|
||||||
|
F=strrep(strrep(strrep(F,'.*','*'),'./','/'),'.^','^');
|
||||||
|
F=strrep(strrep(strrep(F,'*','.*'),'/','./'),'^','.^');
|
||||||
|
end
|
34
FOTF Toolbox/Readme.txt
Normal file
34
FOTF Toolbox/Readme.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
About FOTF Toolbox
|
||||||
|
|
||||||
|
(c) Professor Dingy\"u Xue, Northeastern University, Shenyang, China
|
||||||
|
Email: xuedingyu@mail.neu.edu.cn
|
||||||
|
Date of last modification, 09 May, 2022
|
||||||
|
|
||||||
|
This newly modified toolbox is written for the monograph, for details, please cite
|
||||||
|
|
||||||
|
@BOOK{bkXueDFOCS,
|
||||||
|
Author = {Xue Dingy\"u},
|
||||||
|
Address = {Berlin},
|
||||||
|
Publisher = {de Gruyter Press},
|
||||||
|
Title = {Fractional-order Control Systems - Fundamentals and Numerical Implementations},
|
||||||
|
Year = {2017}
|
||||||
|
}
|
||||||
|
|
||||||
|
For the new version, please cite
|
||||||
|
|
||||||
|
@BOOK{bkXueNew,
|
||||||
|
Author = {Xue Dingy\"u, Bai Lu},
|
||||||
|
Address = {Beijing},
|
||||||
|
Publisher = {Tsinghua University Press},
|
||||||
|
Title = {Fractional Calculus - Numerical Algorithms and Implementations},
|
||||||
|
Year = {2022}
|
||||||
|
}
|
||||||
|
|
||||||
|
For the full list of the toolbox, please check Contents.m
|
||||||
|
|
||||||
|
Please Note that
|
||||||
|
If you are using MATLAB 2022a or newer, please disable the simulink2019 subfolders in your MATLAB path,
|
||||||
|
while if you are using old versions, disable the subfolder Simulink in your MATLAB path.
|
||||||
|
---------------------------------
|
||||||
|
FOTF Toolbox, Release 2.0, 9 May, 2022
|
||||||
|
|
BIN
FOTF Toolbox/Simulink/bench/bp1_model.slx
Normal file
BIN
FOTF Toolbox/Simulink/bench/bp1_model.slx
Normal file
Binary file not shown.
BIN
FOTF Toolbox/Simulink/bench/bp1_model2.slx
Normal file
BIN
FOTF Toolbox/Simulink/bench/bp1_model2.slx
Normal file
Binary file not shown.
BIN
FOTF Toolbox/Simulink/bench/bp2_model.slx
Normal file
BIN
FOTF Toolbox/Simulink/bench/bp2_model.slx
Normal file
Binary file not shown.
4
FOTF Toolbox/Simulink/bench/bp3_fcn.m
Normal file
4
FOTF Toolbox/Simulink/bench/bp3_fcn.m
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
function y=bp3_fcn(u)
|
||||||
|
y=u^(1.5-sqrt(2))*exp(u)*...
|
||||||
|
ml_func([1,3-sqrt(2)],-u)./ml_func([1,1.5],-u);
|
||||||
|
end
|
BIN
FOTF Toolbox/Simulink/bench/bp3_model.slx
Normal file
BIN
FOTF Toolbox/Simulink/bench/bp3_model.slx
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user