major renaming of transfer functions

This commit is contained in:
2019-02-15 10:46:29 +01:00
parent f3c5fafe5f
commit e792d0b028
11 changed files with 592 additions and 580 deletions

View File

@@ -39,43 +39,67 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
%use_lqr: use lqr instead of pole placement
verb=1;
t=0:1E-4:.5; %time vector for simulations
verb=0;
use_lqr=0;
MaxDac=2011.968;
filt_pos_err=Prefilt(mot,2);
tfDesPos=tf(1,1);
tfPosErr=tf(1,1);
ssc=struct();
ssc.sel1={3,[3]};
%locate poles: 2500rad/s = 397Hz, 6300rad/s = 1027Hz
switch mode
case -1 %TESTING
case 0 %for document: best observer without prefilter
ss_plt=mot.ss_plt; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_d1; %ss_plt ss_c1 ss_d1 ss_1 ss_0
if mot.id==1
pl=[-2200 -2100 -2000]; % stable with scaling of .05 .. 1.0;
else
pl=[-2500 -900 -800];
end
plObs=2*pl;
case 0
ss_plt=mot.ss_plt; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_c1; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_cp; %ss_plt ss_c1 ss_d1 ss_1 ss_0
if mot.id==1
pl=[-3300 -3200 -2900 -2800];
else
pl=[-3300 -3200 -2700 -2600];
end
plObs=2*pl;
case 1
case 1 %for document: best observer without prefilter
ss_plt=mot.ss_plt; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_d1; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_cp; %ss_plt ss_c1 ss_d1 ss_1 ss_0
if mot.id==1
pl=[-3300 -3200 -2900 -2800];
else
pl=[-3300 -3200 -2700 -2600];
end
plObs=2*pl;
tfDesPos=Prefilt(mot,2);%user designed envelope
tfPosErr=Prefilt(mot,1);%inverse resonance
case 2 %for document: best observer with prefilter
ss_plt=mot.ss_plt; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_dp; %ss_plt ss_c1 ss_d1 ss_1 ss_0
if mot.id==1
pl=[-2200 -2100 -2000]; % stable with scaling of .05 .. 1.0;
else
pl=[-2500 -900 -800];
end
plObs=2*pl;
case 2
case 3
ss_plt=mot.ss_plt; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=mot.ss_c1; %ss_plt ss_c1 ss_d1 ss_1 ss_0
use_lqr=1
ss_mdl=mot.ss_dp; %ss_plt ss_c1 ss_d1 ss_1 ss_0
if mot.id==1
pl=[-2200 -2100 -2000]; % stable with scaling of .05 .. 1.0;
else
pl=[-2500 -900 -800];
end
plObs=2*pl;
case 4
%this is the hovering ball model
A = [ 0 1 0; 980 0 -2.8;0 0 -100 ];
B = [ 0 0 100 ]';
C = [ 1 0 0 ];
D = 0;
ssBall=ss(A,B,C,D,'InputName','iCmd','OutputName','actPos');
ss_plt=ssBall; %ss_plt ss_c1 ss_d1 ss_1 ss_0
ss_mdl=ssBall; %ss_plt ss_c1 ss_d1 ss_1 ss_0
pl=[-10+10i -10-10i -50];
plObs=[-100 -101 -102];
end
[Am,Bm,Cm,Dm]=ssdata(ss_mdl);
@@ -100,12 +124,14 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
if bitand(verb,4)
% step answer on open loop:
t = 0:1E-4:.5;
u = ones(size(t));
[yp,t,x] = lsim(ss_plt,u,t,xp0);
[ym,t,x] = lsim(ss_mdl,u,t,xm0);
figure();plot(t,yp,t,ym,'--');title('step on open loop (plant and model)');
legend('plt.iqMeas','plt.iqVolts','plt.actPos','mdl.iqMeas','mdl.iqVolts','mdl.actPos')
figure();hold on; plot(t,yp,'DisplayName',ss_plt.OutputName{1})
plot(t,ym,'--','DisplayName',ss_plt.OutputName{1});
title('step on open loop (plant and model)');
%legend('plt.iqMeas','plt.iqVolts','plt.actPos','mdl.iqMeas','mdl.iqVolts','mdl.actPos')
legend('location','best')
end
%w0=abs(poles);
%ang=angle(-poles);
@@ -126,13 +152,13 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
V=-1./(Cm*(Am-Bm*K)^-1*Bm); %(from Lineare Regelsysteme2 (Glattfelder) page:173 )
if length(V)>1
V=V(3); % only the position scaling needed
disp(['scaling (should be actPos): ' ss_mdl.OutputName{end}])
V=V(end); % only the position scaling needed
end
ss_cl = ss(Am-Bm*K,Bm*V,Cm,0,'Name','space state controller','InputName',ss_mdl.InputName,'OutputName',ss_mdl.OutputName);
if bitand(verb,8)
% step answer on closed loop with space state controller:
t = 0:1E-4:.5;
[y,t,x]=lsim(ss_cl,V*u,t,xm0);
figure();plot(t,y);title('step on closed loop');
end
@@ -206,7 +232,8 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
ss_oz = c2d(ss_o,Ts);
%discrete prefilter
filt_pos_err_z=c2d(filt_pos_err,Ts);
tfDesPos_z=c2d(tfDesPos,Ts);
tfPosErr_z=c2d(tfPosErr,Ts);
if bitand(verb,128)
h=bodeplot(filt_pos_err,filt_pos_err_z);
@@ -214,11 +241,10 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
end
%state space controller
ssc=struct();
for k=["Ts","ss_plt","ss_o","ss_oz","filt_pos_err","filt_pos_err_z","V","MaxDac"]
for k=["Ts","ss_plt","ss_o","ss_oz","tfDesPos","tfDesPos_z","tfPosErr","tfPosErr_z","V","MaxDac"]
ssc=setfield(ssc,k,eval(k));
end
mat2py=struct();
%[ozA,ozB,ozC,ozD]=ssdata(ss_oz);
%[pos_err_num,pos_err_den]=tfdata(filt_pos_err_z);
@@ -230,12 +256,9 @@ function [ssc]=StateSpaceControlDesign(mot,mode)
mat2py.ozB=ss_oz.B;
mat2py.ozC=ss_oz.C;
mat2py.ozD=ss_oz.D;
mat2py.ozInpName=ss_oz.InputName
mat2py.ozOutName=ss_oz.OutputName
mat2py.pos_err_num=filt_pos_err_z.Numerator{1};
mat2py.pos_err_den=filt_pos_err_z.Denominator{1};
mat2py.ozInpName=ss_oz.InputName;
mat2py.ozOutName=ss_oz.OutputName;
fn=[pwd '/' sprintf( 'ssc%d.mat',mot.id)];
save(fn,'-struct','mat2py');
disp(['saved ' fn]);
@@ -247,23 +270,26 @@ function pf=Prefilt(mot,mode)
pf=tf(1,1);
case 1 %inverse resonance
if mot.id==1
den=mot.mdl.num2;%num=1;
num=mot.mdl.den2;%den=[1 0 0];
den=mot.mdl.num1;%num=1;
num=mot.mdl.den1;%den=[1 0 0];
pf=tf(num,den);
else
den=conv(conv(conv(mot.mdl.num2,mot.mdl.num3),mot.mdl.num4),mot.mdl.num5);%num=1;
num=conv(conv(conv(mot.mdl.den2,mot.mdl.den3),mot.mdl.den4),mot.mdl.den5);%den=[1 0 0];
den=conv(conv(conv(mot.mdl.num1,mot.mdl.num2),mot.mdl.num3),mot.mdl.num4);%num=1;
num=conv(conv(conv(mot.mdl.den1,mot.mdl.den2),mot.mdl.den3),mot.mdl.den4);%den=[1 0 0];
pf=tf(num,den);
end
case 2
if mot.id==1
f=200;w0=f*2*pi; num1=[1 300 w0^2]; den1=[1 200 w0^2];
numV=num1;
denV=den1;
pf=tf(numV,denV);
%f=200;w0=f*2*pi; num1=[1 300 w0^2]; den1=[1 200 w0^2];
%numV=num1;
%denV=den1;
%pf=tf(numV,denV);
%Lag
f=[200 300]; w=f*2*pi; T=1./w;
pf=tf([T(1) 1],[T(2) 1]);
else
%Lag
f=[100 200]; w=f*2*pi; T=1./w;
f=[200 400]; w=f*2*pi; T=1./w;
tf1=tf([T(1) 1],[T(2) 1]);
%bo = bodeoptions;
%bo.FreqUnits = 'Hz'; bo.MagUnits='abs'; bo.Grid='on';

View File

@@ -8,7 +8,7 @@ mot=identifyFxFyStage(7);
close all;disp('simulate stage closed loop...');
for k =1:2
[pb]=simFxFyStage(mot{k});sim('stage_closed_loop');
f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g');
f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g');grid on;
set(h(1),'color','b'); set(h(2),'color',[0 0.5 0]);
print(f,sprintf('figures/sim_cl_DTGz_%d',mot{k}.id),'-depsc');
f=bodeSamples(desPos_actPos);
@@ -16,14 +16,14 @@ for k =1:2
end
close all;disp('simulate observer...');
for sscType=0%0:1
for sscType=1%0:1
for k=1:2
[ssc]=StateSpaceControlDesign(mot{k},sscType);sim('observer');
f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g');
f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g');grid on;
set(h(1),'color','b'); set(h(2),'color',[0 0.5 0]);
print(f,sprintf('figures/sim_cl_obs_%d_%d',m,mot{k}.id),'-depsc');
print(f,sprintf('figures/sim_cl_obs_%d_%d',sscType,mot{k}.id),'-depsc');
f=bodeSamples(desPos_actPos);
print(f,sprintf('figures/sim_cl_obs_bode%d_%d',m,mot{k}.id),'-depsc');
print(f,sprintf('figures/sim_cl_obs_bode%d_%d',sscType,mot{k}.id),'-depsc');
end
end
disp('document figure generation done');close all;

View File

@@ -163,11 +163,11 @@ function motCell=identifyFxFyStage(mode)
catch
return
end
h=bodeplot(mot.meas,'r',mot.ss_plt(3,1),'g',mot.ss_c1(3,1),'b',mot.ss_d1(3,1),'m',mot.ss_1(2,1),'c',mot.ss_0(2,1),'k',mot.w);
h=bodeplot(mot.meas,'r',mot.ss_plt(3,1),'g',mot.ss_cp(3,1),'b',mot.ss_dp(3,1),'m',mot.ss_p(2,1),'c',mot.ss_q(2,1),'k',mot.w);
setoptions(h,'FreqUnits','Hz','Grid','on');
p=getoptions(h);p.YLim{2}=[-360 90];p.YLimMode='manual';setoptions(h,p);
ax=h.getaxes();
legend(ax(1),'Location','sw',{'real','plant','c1','d1','1','0'});
legend(ax(1),'Location','sw',{'real','plant','cp','dp','p','q'});
print(gcf,sprintf('figures/plotBode_%d',mot.id),'-depsc');
end
@@ -175,24 +175,24 @@ function motCell=identifyFxFyStage(mode)
%current loop iqCmd->iqMeas
tfc=tf(mot.mdl.numc,mot.mdl.denc,'InputName','iqCmd','OutputName','iqMeas');
%simplified current loop iqCmd->iqMeas (first order tf)
tfd=tf(mot.mdl.numd,mot.mdl.dend,'InputName','iqCmd','OutputName','iqMeas');
%force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tfp=tf({[mot.mdl.nump 0];mot.mdl.nump},mot.mdl.denp,'InputName','iqForce','OutputName',{'actVel','actPos'});
%simplified force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tfq=tf({[mot.mdl.numq 0];mot.mdl.numq},mot.mdl.denq,'InputName','iqForce','OutputName',{'actVel','actPos'});
%simplified force(=current) to velocity iqForce->(actVel)
tfv=tf(mot.mdl.numv,mot.mdl.denv,'InputName','iqForce','OutputName',{'actVel'});
%resonance iqMeas->iqForce
tf2=tf(mot.mdl.num2,mot.mdl.den2,'InputName','iqMeas','OutputName','iqForce');
tf1=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqMeas','OutputName','iqForce');
%current to position iqForce->actPos
tf1_=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqForce','OutputName','actPos');
%force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tf1=tf({[mot.mdl.num1 0];mot.mdl.num1},mot.mdl.den1,'InputName','iqForce','OutputName',{'actVel','actPos'});
%simplified force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tf0=tf({[mot.mdl.num0 0];mot.mdl.num0},mot.mdl.den0,'InputName','iqForce','OutputName',{'actVel','actPos'});
%tf1_=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqForce','OutputName','actPos');
%check observable/controlable of transfer functions
ssLst=["tfc","tfd","tf0","tf1","tf2","tfc*tf1*tf2","tfc*tf1","tfd*tf1","tf1*tf2"];
ssLst=["tfc","tfd","tfp","tfq","tfv","tf1","tfc*tfp*tf1","tfc*tfp","tfd*tfp","tfp*tf1","tfc*tfv","tfd*tfv","tfd*tfv*tf1"];
sys=[];
for s = ssLst
eval('sys=ss('+s+');')
@@ -201,23 +201,32 @@ function motCell=identifyFxFyStage(mode)
% sample code:
%tfc iqCmd-> iqMeas
%tf2 resonance iqMeas->iqForce
%tf1 iqForce->(actVel,actPos)
%tfp iqForce->(actVel,actPos)
%tf1 resonance iqMeas->iqForce
%connect(tfc,tf2,'iqCmd','iqForce');
%connect(tfc,tf2,'iqCmd',{'iqMeas','iqForce'});
%connect(tfc,tf2,tf1_,'iqCmd',{'iqMeas','iqForce','actPos'});
%connect(tfc,tf2,tf1_,'iqCmd',{'iqMeas','actPos'});
% best plant approximation
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
mot.ss_plt=connect(tfc,tf1,tf2,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_plt=connect(tfc,tfp,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_plt.Name='best plant approximation';
chkCtrlObsv(mot.ss_plt,'ss_plt fyStage');
% best plant approximation without friction (always -40dB)
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
mot.ss_cqr=connect(tfc,tfq,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_cqr.Name='plant no friction';
chkCtrlObsv(mot.ss_plt,'ss_cqr fyStage');
%without resonance
% u +-----------+ y
@@ -225,44 +234,41 @@ function motCell=identifyFxFyStage(mode)
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
s=tf1.InputName{1};tf1.InputName{1}='iqMeas';
mot.ss_c1=connect(tfc,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_c1.Name='without resonance';
chkCtrlObsv(mot.ss_c1,'ss_c1 fyStage');
tf1.InputName{1}=s;%restore
s=tfp.InputName{1};tfp.InputName{1}='iqMeas';
mot.ss_cp=connect(tfc,tfp,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_cp.Name='without resonance';
chkCtrlObsv(mot.ss_cp,'ss_cp fyStage');
tfp.InputName{1}=s;%restore
%simplified current, without resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
s=tf1.InputName{1};tf1.InputName{1}='iqMeas';
mot.ss_d1=connect(tfd,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_d1.Name='simplified current, without resonance';
chkCtrlObsv(mot.ss_d1,'ss_d1 fyStage');
tf1.InputName{1}=s;%restore
s=tfp.InputName{1};tfp.InputName{1}='iqMeas';
mot.ss_dp=connect(tfd,tfp,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_dp.Name='simplified current, without resonance';
chkCtrlObsv(mot.ss_dp,'ss_dp fyStage');
tfp.InputName{1}=s;%restore
%no current loop, no resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> actVel
% | 2|-------> actPos
% +-----------+
mot.ss_1=ss(tf1);
mot.ss_1.Name='no current loop, no resonance';
chkCtrlObsv(mot.ss_1,'ss_1 fyStage');
mot.ss_p=ss(tfp);
mot.ss_p.Name='no current loop, no resonance';
chkCtrlObsv(mot.ss_p,'ss_p fyStage');
%simplified mechanics, no current loop, no resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> actVel
% | 2|-------> actPos
% +-----------+
mot.ss_0=ss(tf0);
mot.ss_0.Name='simplified mechanics, no current loop, no resonance';
chkCtrlObsv(mot.ss_0,'ss_0 fyStage');
mot.ss_q=ss(tfq);
mot.ss_q.Name='simplified mechanics, no current loop, no resonance';
chkCtrlObsv(mot.ss_q,'ss_q fyStage');
%h=bodeplot(mot.meas,'r',mot.tf4_2,'b',mot.tf6_4,'g');
%h=bodeplot(mot.meas,'r',mot.tf2_0,'b',mot.tf_mdl,'g',mot.w);
@@ -272,58 +278,64 @@ function motCell=identifyFxFyStage(mode)
function mot=fxStage(mot)
%current loop iqCmd->iqMeas
tfc=tf(mot.mdl.numc,mot.mdl.denc,'InputName','iqCmd','OutputName','iqMeas');
%simplified current loop iqCmd->iqMeas (first order tf)
tfd=tf(mot.mdl.numd,mot.mdl.dend,'InputName','iqCmd','OutputName','iqMeas');
%force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tfp=tf({[mot.mdl.nump 0];mot.mdl.nump},mot.mdl.denp,'InputName','iqForce','OutputName',{'actVel','actPos'});
%simplified force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tfq=tf({[mot.mdl.numq 0];mot.mdl.numq},mot.mdl.denq,'InputName','iqForce','OutputName',{'actVel','actPos'});
%resonance iqMeas->iqForce
tf2=tf(mot.mdl.num2,mot.mdl.den2,'InputName','iqMeas','OutputName','iqF1');
tf1=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqMeas','OutputName','iqF1');
%resonance iqMeas->iqForce
tf3=tf(mot.mdl.num3,mot.mdl.den3,'InputName','iqF1','OutputName','iqF2');
tf2=tf(mot.mdl.num2,mot.mdl.den2,'InputName','iqF1','OutputName','iqF2');
%resonance iqMeas->iqForce
tf4=tf(mot.mdl.num4,mot.mdl.den4,'InputName','iqF2','OutputName','iqF3');
tf3=tf(mot.mdl.num3,mot.mdl.den3,'InputName','iqF2','OutputName','iqF3');
%resonance iqMeas->iqForce
tf5=tf(mot.mdl.num5,mot.mdl.den5,'InputName','iqF3','OutputName','iqForce');
tf4=tf(mot.mdl.num4,mot.mdl.den4,'InputName','iqF3','OutputName','iqForce');
%current to position iqForce->actPos
tf1_=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqForce','OutputName','actPos');
%force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tf1=tf({[mot.mdl.num1 0];mot.mdl.num1},mot.mdl.den1,'InputName','iqForce','OutputName',{'actVel','actPos'});
%simplified force(=current) to velocity and position iqForce->(actVel,actPos), actVel=s*actPos
tf0=tf({[mot.mdl.num0 0];mot.mdl.num0},mot.mdl.den0,'InputName','iqForce','OutputName',{'actVel','actPos'});
%tf1_=tf(mot.mdl.num1,mot.mdl.den1,'InputName','iqForce','OutputName','actPos');
%check observable/controlable of transfer functions
ssLst=["tfc","tfd","tf0","tf1","tf2","tf3","tf4","tf5",...
"tfc*tf1*tf2","tfc*tf1","tfd*tf1","tf1*tf2","tf1*tf2*tf3"];
ssLst=["tfc","tfd","tfp","tfq","tf1","tf2","tf3","tf4",...
"tfc*tfp*tf1","tfc*tfp","tfd*tfp","tfp*tf1","tfd*tfp*tf1","tfc*tf1","tfd*tf1","tfc*tf1*tf2","tfd*tf1*tf2"];
sys=[];
for s = ssLst
eval('sys=ss('+s+');')
chkCtrlObsv(sys,char(s));
end
% best plant approximation
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
mot.ss_plt=connect(tfc,tf1,tf2,tf3,tf4,tf5,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_plt=connect(tfc,tfp,tf1,tf2,tf3,tf4,'iqCmd',{'iqMeas','actVel','actPos'});
chkCtrlObsv(mot.ss_plt,'ss_plt fxStage');
% best plant approximation without friction (always -40dB)
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
mot.ss_cqr=connect(tfc,tfq,tf1,tf2,tf3,tf4,'iqCmd',{'iqMeas','actVel','actPos'});
mot.ss_cqr.Name='plant no friction';
chkCtrlObsv(mot.ss_cqr,'ss_plt0 fxStage');
%without resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> iqMeas
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
s=tf1.InputName{1};tf1.InputName{1}='iqMeas';
mot.ss_c1=connect(tfc,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
chkCtrlObsv(mot.ss_c1,'ss_c1 fxStage');
tf1.InputName{1}=s;%restore
s=tfp.InputName{1};tfp.InputName{1}='iqMeas';
mot.ss_cp=connect(tfc,tfp,'iqCmd',{'iqMeas','actVel','actPos'});
chkCtrlObsv(mot.ss_cp,'ss_cp fxStage');
tfp.InputName{1}=s;%restore
%simplified current, without resonance
% u +-----------+ y
@@ -331,28 +343,26 @@ function motCell=identifyFxFyStage(mode)
% | 2|-------> actVel
% | 3|-------> actPos
% +-----------+
s=tf1.InputName{1};tf1.InputName{1}='iqMeas';
mot.ss_d1=connect(tfd,tf1,'iqCmd',{'iqMeas','actVel','actPos'});
chkCtrlObsv(mot.ss_d1,'ss_d1 fxStage');
tf1.InputName{1}=s;%restore
s=tfp.InputName{1};tfp.InputName{1}='iqMeas';
mot.ss_dp=connect(tfd,tfp,'iqCmd',{'iqMeas','actVel','actPos'});
chkCtrlObsv(mot.ss_dp,'ss_dp fxStage');
tfp.InputName{1}=s;%restore
%no current loop, no resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> actVel
% | 2|-------> actPos
% +-----------+
mot.ss_1=ss(tf1);
chkCtrlObsv(mot.ss_1,'ss_1 fxStage');
mot.ss_p=ss(tfp);
chkCtrlObsv(mot.ss_p,'ss_p fxStage');
%simplified mechanics, no current loop, no resonance
% u +-----------+ y
%iqCmd------->|1 1|-------> actVel
% | 2|-------> actPos
% +-----------+
mot.ss_0=ss(tf0);
chkCtrlObsv(mot.ss_0,'ss_0 fxStage');
mot.ss_q=ss(tfq);
chkCtrlObsv(mot.ss_q,'ss_q fxStage');
plotBode(mot)
end

Binary file not shown.

View File

@@ -6,24 +6,27 @@ function [pb]=simFxFyStage(mot)
%the returned variable pb contains varous parameters:
% Kp,Kvfb,Ki,Kvff,Kaff,MaxInt,mot_num,mot_den,Ts,MaxDac,MaxPosErr,A,B,C,D
Ts=2E-4; % 0.2ms=5kHz
MaxDac=2011.968;
MaxPosErr=10000;
pb=struct(...
'Ts', 2E-4, ... % 0.2ms=5kHz
'MaxDac' ,2011.968, ...
'MaxPosErr', 10000);
if mot.id==1
%!motor_servo(mot=1,ctrl='ServoCtrl',Kp=25,Kvfb=400,Ki=0.02,Kvff=350,Kaff=5000,MaxInt=1000)
%!motor(mot=1,dirCur=0,contCur=800,peakCur=2400,timeAtPeak=1,IiGain=5,IpfGain=8,IpbGain=8,JogSpeed=10.,numPhase=3,invDir=True,servo=None,PhasePosSf=1./81250,PhaseFindingDac=100,PhaseFindingTime=50,SlipGain=0,AdvGain=0,PwmSf=10000,FatalFeLimit=200,WarnFeLimit=100,InPosBand=2,homing='enc-index')
Kp=25;Kvfb=400;Ki=0.02;Kvff=350;Kaff=5000;MaxInt=1000;
pb.Kp=25;pb.Kvfb=400;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=5000;pb.MaxInt=1000;
else
%!motor_servo(mot=2,ctrl='ServoCtrl',Kp=22,Kvfb=350,Ki=0.02,Kvff=240,Kaff=1500,MaxInt=1000)
%!motor(mot=2,dirCur=0,contCur=800,peakCur=2400,timeAtPeak=1,IiGain=5,IpfGain=8,IpbGain=8,JogSpeed=10.,numPhase=3,invDir=True,servo=None,PhasePosSf=1./81250,PhaseFindingDac=100,PhaseFindingTime=50,SlipGain=0,AdvGain=0,PwmSf=10000,FatalFeLimit=200,WarnFeLimit=100,InPosBand=2,homing='enc-index')
%Kp=22;Kvfb=350;Ki=0.02;Kvff=240;Kaff=1500;MaxInt=1000;
Kp=22;Kvfb=350;Ki=0.02;Kvff=240;Kaff=3500;MaxInt=1000;
end
ss_plt=mot.ss_plt;
pb=struct();
for k=["Kp","Kvfb","Ki","Kvff","Kaff","MaxInt","Ts","MaxDac","MaxPosErr","ss_plt"]
pb=setfield(pb,k,eval(k));
pb.Kp=22;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=240;pb.Kaff=3500;pb.MaxInt=1000;
end
pb.ss_plt=mot.ss_plt; pb.sel={3,[3]};
%pb.ss_plt=mot.ss_plt0; pb.sel={3,[3]};
%pb.ss_plt=mot.ss_c1; pb.sel={3,[3]};
%pb.ss_plt=mot.ss_d1; pb.sel={3,[3]};
%pb.ss_plt=mot.ss_1; pb.sel={2,[2]};
%pb.ss_plt=mot.ss_p; pb.sel={2,[2]};
%mdlName='stage_closed_loop';
%open(mdlName)
%sim(mdlName)

Binary file not shown.

View File

@@ -1,50 +1,16 @@
function [ssc]=testObserver(mot)
function [ssc]=testObserver()
%http://ctms.engin.umich.edu/CTMS/index.php?example=Introduction&section=ControlStateSpace
mdl=1; % 0:hovering ball 1:fast stage
if mdl==0
A = [ 0 1 0
980 0 -2.8
100
0 0 -100 ];
A = [ 0 1 0
980 0 -2.8
0 0 -100 ];
B = [ 0
0];
B = [ 0
0
100 ];
C = [ 1 0 0 ];
D=0;
else
[A,B,C,D]=ssdata(mot.ssMdl);
C=C(3,:);D=D(3);
numc=(mot.mdl.numc);
denc=(mot.mdl.denc);
num1=(mot.mdl.num1);
den1=(mot.mdl.den1);
g1=tf(numc,denc); % iqCmd->iqMeas
s1=ss(g1);
s1.C=[s1.C; 1E5* 2.4E-3 1E-3*s1.C(2)*8.8]; % add output iqVolts: iqVolts= i_meas*R+i_meas'*L 2.4mH 8.8Ohm (took random scaling values)
g2=tf(num1,den1); %iqMeas->ActPos without resonance frequencies
s2=ss(g2);
s3=append(s1,s2);
s3.A(3,2)=s3.C(1,2)*s3.B(3,2);
%d=.77;w0=9100; %1.44kHz -> T0=6.9046e-04
%numc=[w0^2];
%denc=[1 d*2*w0 w0^2];
%T0=6E-4; %w=1/1E-3=1E3 -> f=w/(2pi)=1000/6.2=159Hz
%numc=[1];
%denc=[T0^2 d*2*T0 1];
%bode(numc,denc)
num=conv(numc,num1);%num=1;
den=conv(denc,den1);%den=[1 0 0];
g4=tf(num,den); %iqMeas->ActPos
s4=ss(g4);
mot.ssMdl
s3
s4
[A,B,C,D]=ssdata(s4);
end
C = [ 1 0 0 ];
D=0;
Ap=A;Am=A;
Bp=B;Bm=B;
@@ -52,159 +18,79 @@ function [ssc]=testObserver(mot)
Dp=D;Dm=D;Dt=D;
poles = eig(A);
disp(poles);
poles
if mdl==0
t = 0:0.01:2;
u = zeros(size(t));
x0 = [0.01 0 0];
t = 0:0.01:2;
u = zeros(size(t));
x0 = [0.01 0 0];
sys = ss(A,B,C,D);
sys = ss(A,B,C,D);
[y,t,x] = lsim(sys,u,t,x0);
plot(t,y)
title('Open-Loop Response to Non-Zero Initial Condition')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
[y,t,x] = lsim(sys,u,t,x0);
plot(t,y)
title('Open-Loop Response to Non-Zero Initial Condition')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
p1 = -10 + 10i; p2 = -10 - 10i; p3 = -50;
K = place(A,B,[p1 p2 p3]);
sys_cl = ss(A-B*K,B,C,0);
lsim(sys_cl,u,t,x0);
xlabel('Time (sec)')
ylabel('Ball Position (m)')
p1 = -10 + 10i; p2 = -10 - 10i; p3 = -50;
K = place(A,B,[p1 p2 p3]);
sys_cl = ss(A-B*K,B,C,0);
lsim(sys_cl,u,t,x0);
xlabel('Time (sec)')
ylabel('Ball Position (m)')
p1 = -20 + 20i; p2 = -20 - 20i; p3 = -100;
P=[p1 p2 p3];
K = place(A,B,P);
sys_cl = ss(A-B*K,B,C,0);
lsim(sys_cl,u,t,x0);
xlabel('Time (sec)')
ylabel('Ball Position (m)')
t = 0:0.01:2;
u = 0.001*ones(size(t));
t = 0:0.01:2;
u = 0.001*ones(size(t));
sys_cl = ss(A-B*K,B,C,0);
sys_cl = ss(A-B*K,B,C,0);
lsim(sys_cl,u,t);
xlabel('Time (sec)')
ylabel('Ball Position (m)')
axis([0 2 -4E-6 0])
lsim(sys_cl,u,t);
xlabel('Time (sec)')
ylabel('Ball Position (m)')
axis([0 2 -4E-6 0])
V=-1./(Cm*(Am-Bm*K)^-1*Bm); %(from Lineare Regelsysteme2 (Glattfelder) page:173 )
lsim(sys_cl,V*u,t)
title('Linear Simulation Results (with Nbar)')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
axis([0 2 0 1.2*10^-3])
else
x0 = [0 0 0 0];
p1=-63+2.80i;
p2=-62+1.50i;
P=[p1 p1' p2 p2'];
P=[-4000+100j -4000-100j -500+10j -500-10j];
K = place(A,B,P);
Ts=1/5000
t = 0:Ts:2;
u = 0.001*ones(size(t));
V=-1./(Cm*(Am-Bm*K)^-1*Bm); %(from Lineare Regelsysteme2 (Glattfelder) page:173 )
sys_cl = ss(A-B*K,B*V,C,0);
V=-1./(Cm*(Am-Bm*K)^-1*Bm); %(from Lineare Regelsysteme2 (Glattfelder) page:173 )
lsim(sys_cl,V*u,t)
title('Linear Simulation Results (with Nbar)')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
axis([0 2 0 1.2*10^-3])
lsim(sys_cl,u,t,x0);
xlabel('Time (sec)')
ylabel('Motor Position (m)')
axis([0 2 0 1.2E-3])
end
op1 = -100;
op2 = -101;
op3 = -102;
OP=[op1,op2,op3];
%OP=P*2;
L = place(A',C',OP)';
At = [ A-B*K B*K
zeros(size(A)) A-L*C ];
Bt = [ B*V
zeros(size(B)) ];
Ct = [ C zeros(size(C)) ];
if mdl==0
op1 = -100;
op2 = -101;
op3 = -102;
OP=[op1,op2,op3];
OP=P*2;
L = place(A',C',OP)';
At = [ A-B*K B*K
zeros(size(A)) A-L*C ];
Bt = [ B*V
zeros(size(B)) ];
Ct = [ C zeros(size(C)) ];
sys = ss(At,Bt,Ct,0);
%lsim(sys,zeros(size(t)),t,[x0 x0]);
lsim(sys,u,t,[x0 x0]);
title('Linear Simulation Results (with observer)')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
sys = ss(At,Bt,Ct,0);
%lsim(sys,zeros(size(t)),t,[x0 x0]);
lsim(sys,u,t,[x0 x0]*0);
title('Linear Simulation Results (with observer)')
xlabel('Time (sec)')
ylabel('Ball Position (m)')
else
OP=P*2;
L = place(A',C',OP)';
At = [ A-B*K B*K
zeros(size(A)) A-L*C ];
Bt = [ B*V
zeros(size(B)) ];
Ct = [ C zeros(size(C)) ];
t = 0:1E-6:0.1;
x0 = [0.01 0.5 -5];
[y,t,x] = lsim(sys,zeros(size(t)),t,[x0 x0]);
sys = ss(At,Bt,Ct,0);
lsim(sys,u,t,[x0 x0]*0);
title('Linear Simulation Results (with observer)')
xlabel('Time (sec)')
ylabel('Motor Position (m)')
axis([0 2 0 1.2E-3])
end
if mdl==0
t = 0:1E-6:0.1;
x0 = [0.01 0.5 -5];
[y,t,x] = lsim(sys,zeros(size(t)),t,[x0 x0]);
n = 3;
e = x(:,n+1:end);
x = x(:,1:n);
x_est = x - e;
n = 3;
e = x(:,n+1:end);
x = x(:,1:n);
x_est = x - e;
% Save state variables explicitly to aid in plotting
h = x(:,1); h_dot = x(:,2); i = x(:,3);
h_est = x_est(:,1); h_dot_est = x_est(:,2); i_est = x_est(:,3);
% Save state variables explicitly to aid in plotting
h = x(:,1); h_dot = x(:,2); i = x(:,3);
h_est = x_est(:,1); h_dot_est = x_est(:,2); i_est = x_est(:,3);
plot(t,h,'-r',t,h_est,':r',t,h_dot,'-b',t,h_dot_est,':b',t,i,'-g',t,i_est,':g')
legend('h','h_{est}','hdot','hdot_{est}','i','i_{est}')
xlabel('Time (sec)')
end
%discrete
Ts=1/5000; % deltatau std. frq. is 5kHz
%The discrete system works with sampling >100Hz,. the bigger the frequency the better the result
%With sampling = 80Hz hte system already becomes instable.
ss_t=ss(At,Bt,Ct,Dt);
%figure();pzplot(ss_t)
ss_tz=c2d(ss_t,Ts);
%figure();pzplot(ss_tz)
[Atz,Btz,Ctz,Dtz]=ssdata(ss_tz);
[Apz,Bpz,Cpz,Dpz]=ssdata(c2d(ss(Ap,Bp,Cp,Dp),Ts));
[Amz,Bmz,Cmz,Dmz]=ssdata(c2d(ss(Am,Bm,Cm,Dm),Ts));
Ao=Am-L*Cm;
Bo=[Bm L];
Co=K;
Do=zeros(size(Co,1),size(Bo,2));
[Aoz,Boz,Coz,Doz]=ssdata(c2d(ss(Ao,Bo,Co,Do),Ts));
%state space controller
ssc=struct();
for k=["Ts","At","Bt","Ct","Dt","Atz","Btz","Ctz","Dtz","Ap","Bp","Cp","Dp","Am","Bm","Cm","Dm","Ao","Bo","Co","Do","Apz","Bpz","Cpz","Dpz","Aoz","Boz","Coz","Doz","V","K","L"]
ssc=setfield(ssc,k,eval(k));
end
mdlName='testObserverSim';
open(mdlName);
plot(t,h,'-r',t,h_est,':r',t,h_dot,'-b',t,h_dot_est,':b',t,i,'-g',t,i_est,':g')
legend('h','h_{est}','hdot','hdot_{est}','i','i_{est}')
xlabel('Time (sec)')
K,L,V
end