function [FI1,RE1,FI2,RE2,FI3,RE3]=kaskade(SM1,SP1,SM2,SP2,SM3,SP3,TLR)
%KASKADE Optimization of a cascade structure using discontinuous controllers
%        [FI1,RE1,FI2,RE2,FI3,RE3]=kaskade(SM1,SP1,SM2,SP2(,SM3,SP3)(,TLR))
% Inputs:
% SPx      - plants in Laplace domain using >>>LTI<<< syntax
%            applying variable InputDelay to input dead times
% SMx      - control matrix as >>>'structure array'<<<
%            SMx.Optimization={'bod','eez'} - or m-Files of same calling syntax
%            SMx.ControlVector=control vector for controller calculation -no menu
%                            please compare inp2(LTI) regarding bod.m and eez.m
%            SMx.ControlLoop=[T m kode]=control vector for control loop modelling
%                            please compare inp2,inp3,inp4(LTI) regarding trans.m
% TLR        last argin = optional tolerance to control function minreal.m
%            default (kaskade): sqrt(1e-12); [default(MATLAB): sqrt(eps)]
%            HINT: there may occur a need to reduce to e.g. sqrt(1e-08)
% Outputs:
% FIx, REx - discontinuous filter resp. controller in z-domain and >>LTI<< syntax
% HINTS for SMx.ControlLoop:
%           T:   same sampling time for all control loops - in this version     
%           m:   dead times of SPx will be added to the respective m of each loop
%           kode: == {0, 3} useful in the inner loop only
% ATTENTION subjected to the parameters of the plant there may be necessary
%           a further decrease of the tolerance calling function minreal:
%           X=minreal(X,Tol)

% KEY WORDS: Discontinuous Magnitude Optimum, digital controller, PID-type family
%            Finite Time Settling, control loop, undelayed input signals, delayed
%		     input signal, pre-filter, control vector, menu switch off, dead time
%            z-transform, pole compensation, LTI syntax

%  ***** Preconditions: existence of trans, bod, bodg, vobo, eez ****
%  Copyright (c) 1997-2023. All Rights Reserved. 
%                     Dr. Gert-Helge Geitner, TU Dresden,
%                     https://wwwpub.zih.tu-dresden.de/~geitner/ae_1_0e.htm
%  Reference regarding application of z-transform, Discontinuous Magnitude Optimum,
%  Finite Time Settling: Geitner, G.-H.:
%                        Entwurf digitaler Regler für elektrische Antriebe.
%                        publisher: VDE-Verlag GmbH Berlin und Offenbach 1996
%                        ISBN 3-8007-1847-2

FT01='Wrong number of input and/or output argumentes!';
FT02='At least one input argument SMx not of type >>>STRUCT<<<! ';
FT03='At least one input argument SPx not of type >>>LTI<<< !';
FT04='Same sampling times mandatory in this version!';
%no: FT05='useful for inner loops only: kode={0, 3} !';
FT06='Wrong external tolerance definition!';
narginchk(2,7);    % 1, 2 or 3 loops, optional each with TOL
                   % obsolete version: error(nargchk(2, 7, nargin),FT01)
Anz=nargin/2;
if rem(Anz,1)~=0                     %EXTERNAL tolerance setting
   if nargin==3 TOL=SM2;  elseif nargin==5 TOL=SM3; else TOL=TLR; end
   Anz=(nargin-1)/2;
   if ~isnumeric(TOL)|~isscalar(TOL) error(FT06); end
else 
   TOL=sqrt(1e-12);                  %INTERNAL decrease of the standard tolerance
end
x1=abs('FI0'); x2=abs('RE0'); x4=abs('SM0'); x5=abs('SP0');
if (2*Anz)~=nargout error(FT01); end
for i=1:Anz
   if     ~isa(eval(setstr(x4+[0 0 i])),'struct') error(FT02);
   elseif ~isa(eval(setstr(x5+[0 0 i])),'lti')    error(FT03); end; end
x41=abs('SM0.Optimization'); x42=abs('SM0.ControlVector');  %manipulated at end
x43=abs('SM0.ControlLoop');                                 %manipulated at start
for i=1:Anz
   eval(['TVL=' x43+[0 0 i 0 0 0 0 0 0 0 0 0 0 0 0] ';']);%transform vector local
   T=TVL(1); m=TVL(2); kode=TVL(3);
   eval(['SPL=' x5+[0 0 i] ';']);       %s-domain: "increase" by local plant part  
   if i==1                                                     % >>>inner loop<<<
           SPG=SPL;                                  %s-domain: local total plant
           SZd=tf(1,1);                            %open loop: discontinuous part
           TVS=TVL;                                 %storage for transform vector
   else                                                 % >>> superposed loops<<<
        SPG=series(SPG,SPL); SPG=minreal(SPG,TOL);   %s-domain: local total plant
        if TVS(1)~=T error(FT04); end       %same sampling times for this version
        %no: if kode==0|kode==3 error(FT05); end  %superposed loops: kode={1, 2}!
     if i==2                                                  % >>>middle loop<<<
        RF1=feedback(RE1,Zi); RF1=minreal(RF1,TOL);         %Zi of previous loop!
        SZd=series(FI1,RF1); SZd=minreal(SZd,TOL); %open loop: discontinuous part
     else                                                      % >>>outer loop<<<
        VWZ=series(RE2,SZd); VWZ=minreal(VWZ,TOL);         %SZd of previous loop!
        RF2=feedback(VWZ,Zi); RF2=minreal(RF2,TOL);         %Zi of previous loop!
        SZd=series(FI2,RF2); SZd=minreal(SZd,TOL); %open loop: discontinuous part
     end
   end
   Zi=trans(SPG,T,m,kode);        %transform of the local total plant of s-domain
   SZG=series(SZd,Zi); SZG=minreal(SZG,TOL);   %z-domain: total plant - open loop
   s3=eval(setstr(x41+[0 0 i 0 0 0 0 0 0 0 0 0 0 0 0 0]));   %optimization method
   SV=eval(setstr(x42+[0 0 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0]));      %control vector
   eval(['[' x2+[0 0 i] ',' x1+[0 0 i] ']=' s3 '(SZG,SV);']);       %optimization
end
