function [reg1,fil1,reg2,fil2,reg3,fil3]=...
	casc(T,k,n01,d01,code1,n02,d02,code2,n03,d03,code3)
%CASC     Kodierte Koeffiz.-ber. von max. drei kaskadierten dig. Regelern
%         [reg1,fil1,reg2,fil2,reg3,fil3]=...
%			  casc(T,k,n01,d01,code1,n02,d02,code2,n03,d03,code3)
% vom PID-Typ nach dem Digitalen Betragsoptimum; entspricht Mehrfachanwendung
% von bod.m; Programmsteuerung kodiert, d.h. keine Menuefuehrung
% [reg1,fil1,reg2,fil2(,reg3,fil3)]=...
%	casc(T,k,n01,d01,code1,n02,d02,code2(,n03,d03,code3))
% "casc" errechnet
%    reg1.. Reglerkoeffizienten des inneren Kaskadenreglers
%    fil1.. Filterkoeffizienten des inneren Kaskadenreglers
%    reg2.. Reglerkoeffizienten des mittleren Kaskadenreglers
%    fil2.. Filterkoeffizienten des mittleren Kaskadenreglers
%    reg3.. Reglerkoeffizienten des äußeren Kaskadenreglers
%    fil3.. Filterkoeffizienten des äußeren Kaskadenreglers
% Die Berechnung der dritten Schleife ist optional und erfolgt nur
% nach Eingabe der äußeren Streckenparameter. Bei Berechnung des
% äußeren Reglers muß im inneren und mittleren Kreis Polkompensation
% verwendet werden, da sonst der Speicherplatz zu gering ist !!
% nach Eingabe von
%    T .... Abtastzeit in Millisekunden
%    k .... Kopplung (Abtaster(0) oder Halteglied 0.Ordng(1))
%    n01... innerer Streckennenner
%    d01... innerer Streckenzähler
%    n02... mittlerer Streckennenner
%    d02... mittlerer Streckenzähler
%    n03... äußerer Streckennenner
%    d03... äußerer Streckenzähler
%    (Eingabe im Laplacebereich mit fallenden Koeffizienten und ms^n)
%    code1,code2,code3=[t u v w x y z]  Schalter für inneren(code1),
%     		     mittleren(code2) und äußeren(code3) Regelkreis
%    t... Messvorgabe (Augenblickswert(0) oder Mittelwert(1))
%    u... Vorgabe der Rechen-, Meß- od. Stellgliedreaktionszeit in ms
%    v... zur Fuehrungs(0)-bzw.Stoeroptimierung(1)
%    w... Polkompensation(vollstaend.(2),teilweise(1),keine(0))
%    x... Reglerzaehlerordnung (ohne zu komp. Pole!! w+x<5)
%    y... Reglerintegralanteil(ja(1),nein(0))
%    z... Daempfung des D-Anteils(ja(1),nein(0)) bei v=1 z=0 !

% SCHLUESSELWOERTER: Digitales Betragsoptimum, Kaskadenregelstruktur,
%                    Programmsteuerung codiert, Regleroptimierung,
%                    Digitaler Regler von PID-Typ

% Vorraussetzung ist das Vorhandensein
% der m-Files casbod.m und trans.m

% Copyright (c) 1994 Hagen Jahn
%                    TU Dresden; Elektrotechnisches Institut
%                    Mommsenstr. 13; D-01062 Dresden; Germany

% Eingabeueberpruefung
if (nargin<8)|(nargin==9)|(nargin==10)|(nargin>11)
  error('Eingangsargumentfehler'); end
if (nargin==8) sch=2; else sch=3; end
[rn1,cn1]=size(n01); [rd1,cd1]=size(d01); co1(1)=0;
[rn2,cn2]=size(n02); [rd2,cd2]=size(d02); co2(1)=0;
if ((rn1~=1)|(rd1~=1)|(rn2~=1)|(rd2~=1))
  error('Streckenkoeffizienten als Vektoren uebergeben');  end
if ((cn1>6)|(cd1>6)|(cn2>6)|(cd2>6))
  disp('Ist die Ordnung der Eingangsvektoren tatsaechlich so gross ?');
  end
if ((k~=0)&(k~=1))
  error('Vorgabe der Kopplung falsch'); end
[kr1,kc1]=size(code1); [kr2,kc2]=size(code2);
if ((kr1~=1)|(kr2~=1)) error('Code als Vektoren uebergeben');  end
if kc1~=7 error('Code innerer Regelkreis falsch'); end
if kc2~=7 error('Code mittlerer Regelkreis falsch'); end
if ((code1(1)~=0)&(code1(1)~=1)) 
  error('Vorgabe Messung innerer Regelkreis falsch'); end
if ((k==0)&(code1(1)==0)) code1(1)=0;
elseif ((k==1)&(code1(1)==0)) code1(1)=1;
elseif ((k==0)&(code1(1)==1)) code1(1)=1; co1(1)=3; 
else code1(1)=2; end
if ((code2(1)~=0)&(code2(1)~=1))
  error('Vorgabe Messung mittlerer Regelkreis falsch'); end
if ((k==0)&(code2(1)==0)) code2(1)=0; 
elseif ((k==1)&(code2(1)==0)) code2(1)=1;
elseif ((k==0)&(code2(1)==1)) code2(1)=1; co2(1)=3;
else code2(1)=2; end
if (code1(2)<0)   
  error('Vorgabe der echten Zeitverschiebung code1(2) unzulaessig');
  end
if (code2(2)<0)   
  error('Vorgabe der echten Zeitverschiebung code2(2) unzulaessig');
  end
if ((code1(3)~=0)&(code1(3)~=1))
  error('Vorgabe Führungs-bzw. Störoptimierung innerer RK falsch');
  end
if ((code2(3)~=0)&(code2(3)~=1))
  error('Vorgabe Führungs-bzw.Störoptimierung mittlerer RK falsch');
  end
if ((code1(4)~=0)&(code1(4)~=1)&(code1(4)~=2))
  error('Vorgabe Polkompensation innerer Regelkreis falsch'); end
if ((code2(4)~=0)&(code2(4)~=1)&(code2(4)~=2))
  error('Vorgabe Polkompensation mittlerer Regelkreis falsch'); end
if ((code1(5)~=0)&(code1(5)~=1)&(code1(5)~=3)&(code1(5)~=4))
  error('Vorgabe Reglerzaehlerordnung innerer Regelkreis falsch'); end
if ((code1(5)==0)&(code1(3)==1))
  disp('Reglerzaehlerordnung nicht sinnvoll');
  error('zwei Freiheitsgrade zur Stoeroptimierung notwendig')
  end
if ((code2(5)~=0)&(code2(5)~=1)&(code2(5)~=2)&(code2(5)~=3)...
                                                      &(code2(5)~=4))
  error('Vorgabe Reglerzaehlerordnung mittlerer Regelkreis falsch');
  end
if ((code2(5)==0)&(code2(3)==1))
  disp('Reglerzaehlerordnung nicht sinnvoll');
  error('zwei Freiheitsgrade zur Stoeroptimierung notwendig')
  end
if ((code1(6)~=0)&(code1(6)~=1))
  error('Vorgabe Reglerintegralanteil innerer Regelkreis falsch');end
if ((code2(6)~=0)&(code2(6)~=1))
  error('Vorgabe Reglerintegralanteil mittlerer Regelkreis falsch');end
if ((code1(7)~=0)&(code1(7)~=1))
  error('Vorgabe "gedaempftem" D-Anteil innerer Regelkreis falsch');end
if ((code2(7)~=0)&(code2(7)~=1))
  error('Vorgabe "gedaempftem" D-Anteil mittlerer Regelkreis falsch');
  end
if sch==3
  [rn3,cn3]=size(n03); [rd3,cd3]=size(d03); co3(1)=0;
  if ((rn3~=1)|(rd3~=1))
  error('Streckenkoeffizienten als Vektoren uebergeben');  end
  if ((cn3>6)|(cd3>6))
    disp('Ist die Ordnung der Eingangsvektoren tatsaechlich so gross?');
  end
  [kr3,kc3]=size(code3);
  if (kr3~=1) error('Code als Vektoren uebergeben');  end
  if kc3~=7 error('Code äußerer Regelkreis falsch'); end
  if ((code3(1)~=0)&(code3(1)~=1))
    error('Vorgabe Messung aeusserer Regelkreis falsch'); end
  if ((k==0)&(code3(1)==0)) code3(1)=0; 
  elseif ((k==1)&(code3(1)==0)) code3(1)=1; 
  elseif ((k==0)&(code3(1)==1)) code3(1)=1; co3(1)=3;
  else code3(1)=2; end
  if (code3(2)<0)   
    error('Vorgabe der echten Zeitverschiebung code3(2) unzulaessig');
  end
  if ((code3(3)~=0)&(code3(3)~=1))
    error('Vorgabe Führungs-bzw.Störoptimierung aeusserer RK falsch');
  end
  if ((code3(4)~=0)&(code3(4)~=1)&(code3(4)~=2))
    error('Vorgabe Polkompensation aeusserer Regelkreis falsch'); end
  if ((code3(5)~=0)&(code3(5)~=1)&(code3(5)~=2)&(code3(5)~=3)...
                                                      &(code3(5)~=4))
    error('Vorgabe Reglerzaehlerordnung aeusserer Regelkreis falsch');
  end
  if ((code3(5)==0)&(code3(3)==1))
    disp('Reglerzaehlerordnung nicht sinnvoll');
    error('zwei Freiheitsgrade zur Stoeroptimierung notwendig')
  end
  if ((code3(6)~=0)&(code3(6)~=1))
    error('Vorgabe Reglerintegralanteil aeusserer Regelkreis falsch');
  end
  if ((code3(7)~=0)&(code3(7)~=1))
    error('Vorgabe "gedaempftem" D-Anteil aeusserer Regelkreis falsch');
  end
end

% Innere Schleife
% Berechnung der Teilstrecke Gs1b
[numo1b,deno1b]=trans(n01,d01,T,code1(2),code1(1));
% innerer Regler
if code1(4)==1 disp('Innerer Regler'); end
[numr1,denr1,nufil1,defil1]=casbod(numo1b,deno1b,code1);		
% Berechnung der Teilstrecke Gs1a
if co1(1)==3    
   [numo1a,deno1a]=trans(n01,d01,T,code1(2),0);
elseif code1(1)==2
   [numo1a,deno1a]=trans(n01,d01,T,code1(2),1);
else
   numo1a=numo1b; deno1a=deno1b;
end
% Zusammenfassung innere Schleife
nn=conv(numr1,numo1a); dn=conv(denr1,deno1a);
nd=conv(numr1,numo1b); dd=conv(denr1,deno1b);nd=dd+nd;
numg1=conv(nn,dd); deng1=conv(dn,nd);
[numg1f]=conv(numg1,nufil1); [deng1f]=conv(deng1,defil1);
[numg1f,deng1f]=minreal(numg1f,deng1f);

% Mittlere Schleife
% Berechnung der Teilstrecke Gs2b
nu=conv(n01,n02); de=conv(d01,d02);
[numo2b,deno2b]=trans(nu,de,T,code2(2),code2(1));
% Berechnung der offenen mittleren Schleife
nums2=conv(numg1f,numo2b); nums2=conv(nums2,deno1a);
dens2=conv(deng1f,deno2b); dens2=conv(dens2,numo1a); 
[nums2,dens2]=minreal(nums2,dens2);
e=length(nums2); f=length(dens2);
if e<f g=f-e; h=zeros(1,g); h(1,g+1)=1; nums2=conv(nums2,h);
elseif f<e g=e-f; h=zeros(1,g); h(1,g+1)=1; dens2=conv(dens2,h);
else end
% Mittlerer Regler
if code2(4)==1 disp('Mittlerer Regler'); end
[numr2,denr2,nufil2,defil2]=casbod(nums2,dens2,code2);		
% Berechnung der Teilstrecke Gs2a
if co2(1)==3 
   [numo2a,deno2a]=trans(nu,de,T,code2(2),0);
elseif code2(1)==2
   [numo2a,deno2a]=trans(nu,de,T,code2(2),1);
else
   numo2a=numo2b; deno2a=deno2b;
end
% Zusammenfassung mittlere Schleife
nn1=conv(numr2,numg1f); nn2=conv(nn1,numo2a);
dn1=conv(denr2,deng1f); dn2=conv(dn1,deno2a);
nd1=conv(nn1,numo2b); dd1=conv(dn1,deno2b);
nd2=conv(numo1a,dd1); nd1=conv(nd1,deno1a);
dd2=conv(dd1,deno1a);
e=length(nd1); f=length(nd2);
if e<f g=f-e; h=zeros(1,g); h(1,g+1)=1; nd1=conv(nd1,h);
elseif f<e g=e-f; h=zeros(1,g); h(1,g+1)=1; nd2=conv(nd2,h);
else end
nd3=nd1+nd2;
numg2=conv(nn2,dd2); deng2=conv(dn2,nd3);
[ao2,bo2,co2,do2]=tf2ss(numg2,deng2);
[w,x,y,z]=minreal(ao2,bo2,co2,do2);
[numg2,deng2]=ss2tf(w,x,y,z,1);		
[numg2f]=conv(numg2,nufil2); [deng2f]=conv(deng2,defil2);

if sch==3
  % Äußere Schleife
  % Berechnung der Teilstrecke Gs3b
  nu=conv(nu,n03); de=conv(de,d03);
  [numo3b,deno3b]=trans(nu,de,T,code3(2),code3(1));
  % Berechnung der offenen äußeren Schleife
  nums3=conv(numg2f,numo3b); nums3=conv(nums3,deno2a);
  dens3=conv(deng2f,deno3b); dens3=conv(dens3,numo2a); 
  [nums3,dens3]=minreal(nums3,dens3);
  e=length(nums3); f=length(dens3);
  if e<f g=f-e; h=zeros(1,g); h(1,g+1)=1; nums3=conv(nums3,h);
  elseif f<e g=e-f; h=zeros(1,g); h(1,g+1)=1; dens3=conv(dens3,h);
  else end
  % Äußerer Regler
  if code3(4)==1 disp('Aeusserer Regler'); end
  [numr3,denr3,nufil3,defil3]=casbod(nums3,dens3,code3);		
end
 
% Ergebnisausgabe
reg1=[numr1;denr1]; fil1=[nufil1;defil1];
reg2=[numr2;denr2]; fil2=[nufil2;defil2];
if sch==3
  numr3=1e10*numr3; numr3=round(numr3); numr3=numr3/1e10;
  nufil3=1e10*nufil3; nufil3=round(nufil3); nufil3=nufil3/1e10;
  defil3=1e10*defil3; defil3=round(defil3); defil3=defil3/1e10;
  reg3=[numr3;denr3]; fil3=[nufil3;defil3];
end