From 952925d25f6118d350334acddcd1dd7dff8fee01 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Tue, 26 Feb 2019 16:48:48 +0100 Subject: [PATCH] adding optimizer tool and found better parameters --- matlab/DeltaTauOptimizer.m | 91 +++++++++++++++++++++++++++++++++++++ matlab/DeltaTauParam.m | 67 ++++++++++++++++++--------- matlab/DeltaTauSim.slx | Bin 39781 -> 39663 bytes matlab/Readme.md | 57 +++++++++++++++++++++++ matlab/identifyFxFyStage.m | 22 ++++++++- python/helicalscan.py | 2 +- python/shapepath.py | 7 ++- 7 files changed, 218 insertions(+), 28 deletions(-) create mode 100644 matlab/DeltaTauOptimizer.m diff --git a/matlab/DeltaTauOptimizer.m b/matlab/DeltaTauOptimizer.m new file mode 100644 index 0000000..3af9d1a --- /dev/null +++ b/matlab/DeltaTauOptimizer.m @@ -0,0 +1,91 @@ +%before calling that put following line in the command window: +% +% global mot pb; +% or even: +% clear global all;clear all;global mot pb; + +function DeltaTauOptimizer() + global mot simData1 simData2; + if isempty(mot) + mot=identifyFxFyStage(7); + end + SIM1=[1 1; 1 2; 8 2; 9 2]; + SIM2=[1 1; 1 2; 8 2; 9 2]; + if isempty(simData1) + close all; + simData1=ExecSim(mot{1},SIM1); + end + if isempty(simData2) + close all; + simData2=ExecSim(mot{2},SIM2); + end + close all; + %test() + bodeSim(simData1); + bodeSim(simData2); +end + +function test() + global pb mot simData1 simData2; + %pb=DeltaTauParam(mot{2},7,0); + pb=DeltaTauParam(mot{2},9,0); + sim('DeltaTauSim'); + i=6; + %simData2(i).mot_mdl_param=SIM(i,:); + simData2(i).pb=pb; + simData2(i).desPos_actPos=desPos_actPos; + bodeSim(simData2); +end + + +function simData=ExecSim(mot,SIM) + global pb; + % mot mdl param + simData=struct; + for i =1:size(SIM,1) + [mdl,param]=feval(@(x) x{:}, num2cell(SIM(i,:))); + pb=DeltaTauParam(mot,mdl,param); + sim('DeltaTauSim'); + simData(i).mot_mdl_param=SIM(i,:); + simData(i).pb=pb; + simData(i).desPos_actPos=desPos_actPos; + + fig=bodeSamples(desPos_actPos); + title(fig.Children(2),pb.desc); + end +end + +function bodeSim(simData) + fig=figure(); + ax1=subplot(2,1,1); hold(ax1,'on') + ax2=subplot(2,1,2); hold(ax2,'on') + Ts=1/5000; % sampling period + + for i =1:length(simData) + sd=simData(i).desPos_actPos; + t=0:Ts:sd.Time(end); + posI=interp1(sd.Time,sd.Data(:,1),t); + posO=interp1(sd.Time,sd.Data(:,2),t); + ftI=fft(posI); + ftO=fft(posO); + tf=ftO./ftI; + + L=length(t); + k=(L-1)*Ts; % fmax =1/Ts at sample (L-1)/2 (index0-base) + N=[10 220]*k; % number of relevant indexes (index0-base) + frq=(N(1):N(2))/k; + N=N+1;%index0-base -> index1-base + tfn=tf(N(1):N(2)); + + %fig=figure(); h=plot(abs(ftI)); + %fig=figure(); h=plot(abs(ftO)); + %fig=figure(); h=plot(abs(ftI(N(1):N(2)))); + h=plot(ax1,frq,abs(tfn), 'DisplayName',simData(i).pb.desc); + p=unwrap(phase(tfn))/(2*pi)*360; + h=plot(ax2,frq,p, 'DisplayName',simData(i).pb.desc); + end + grid(ax1,'on');grid(ax2,'on'); + set(ax1, 'XScale', 'log'); + set(ax2, 'XScale', 'log'); + legend('Location','best'); +end \ No newline at end of file diff --git a/matlab/DeltaTauParam.m b/matlab/DeltaTauParam.m index 719c87a..79e613e 100644 --- a/matlab/DeltaTauParam.m +++ b/matlab/DeltaTauParam.m @@ -1,4 +1,4 @@ -function [pb]=DeltaTauParam(mot) +function [pb]=DeltaTauParam(mot,mdl,param) % !!! first it need to run: [mot1,mot2]=identifyFxFyStage() tobuild a motor object !!! % %loads the current (11.10.2018) controller settings of the @@ -10,45 +10,70 @@ function [pb]=DeltaTauParam(mot) 'Ts', 2E-4, ... % 0.2ms=5kHz 'MaxDac' ,2011.968, ... 'MaxPosErr', 10000); - %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]}; - %pb.ss_plt=mot.ss_q; pb.sel={2,[2]}; - %pb.ss_plt=mot.ss_cq; pb.sel={3,[3]}; - %pb.ss_plt=mot.ss_cqr; pb.sel={3,[3]}; + desc=sprintf('mot:%d mdl:',mot.id); + switch mdl + case 1 + pb.ss_plt=mot.ss_plt;desc=desc+"plt"; pb.sel={3,[3]}; + case 2 + pb.ss_plt=mot.ss_plt0;desc=desc+"plt0"; pb.sel={3,[3]}; + case 3 + pb.ss_plt=mot.ss_c1;desc=desc+"c1"; pb.sel={3,[3]}; + case 4 + pb.ss_plt=mot.ss_d1;desc=desc+"d1"; pb.sel={3,[3]}; + case 5 + pb.ss_plt=mot.ss_1;desc=desc+"1"; pb.sel={2,[2]}; + case 6 + pb.ss_plt=mot.ss_p;desc=desc+"p"; pb.sel={2,[2]}; + case 7 + pb.ss_plt=mot.ss_q;desc=desc+"q"; pb.sel={2,[2]}; + case 8 + pb.ss_plt=mot.ss_cq;desc=desc+"cq"; pb.sel={3,[3]}; + case 9 + pb.ss_plt=mot.ss_cqr;desc=desc+"cqr"; pb.sel={3,[3]}; + end pb.A=[1];pb.B=[1];pb.C=[1];pb.D=[1];pb.E=[1];pb.F=[1]; + desc=desc+" param:"; 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') - %pb.Kp=25;pb.Kvfb=400;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=5000;pb.MaxInt=1000; - pb.Kp=25;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=1/(1.548e04*(pb.Ts^2));pb.MaxInt=1000; + switch param + case 0 %scratch + desc=desc+"scratch"; + case 1 %origin parameters + desc=desc+"orig"; + pb.Kp=25;pb.Kvfb=400;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=5000;pb.MaxInt=1000; + case 2%enhances first step + desc=desc+"2"; + pb.Kp=25;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=1/(1.548e04*(pb.Ts^2));pb.MaxInt=1000; + end %pb.Kp=0.1;pb.Kvfb=0;pb.Ki=0.00;pb.Kvff=0;pb.Kaff=1/(1.548e04*(pb.Ts^2));pb.MaxInt=1000; %filter [z^0 z^-1 ... z^-n]; - pb.A=[1]; - pb.B=[1]; - pb.C=[1]; - pb.D=[1]; - pb.E=[1]; - pb.F=[1]; %19.8Hz 0dB K=(19.8*2*np.pi)**2=15477.1 Ts=5kHz=.2ms %Kaff = 1/(Ts*Ts*K) = 1/((19.8*2*np.pi)**2/5000**2) = 1615.2877200403302 %Kfff=100 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') - %pb.Kp=22;Kvfb=350;Ki=0.02;Kvff=240;Kaff=1500;MaxInt=1000; - pb.Kp=22;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=240;pb.Kaff=3500;pb.MaxInt=1000; + switch param + case 0 %scratch + desc=desc+"scratch"; + pb.Kp=22;pb.Kvfb=450;pb.Ki=0.02;pb.Kvff=450;pb.Kaff=4517;pb.MaxInt=1000; + case 1 %origin parameters + desc=desc+"orig"; + pb.Kp=22;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=240;pb.Kaff=1500;pb.MaxInt=1000; + case 2%enhances first step + desc=desc+"2"; + pb.Kp=22;pb.Kvfb=450;pb.Ki=0.02;pb.Kvff=450;pb.Kaff=4517;pb.MaxInt=1000; + %pb.Kp=22;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=240;pb.Kaff=3500;pb.MaxInt=1000; + end %11.84Hz 0dB K=(11.84*2*np.pi)**2=5534.3 Ts=5kHz=.2ms %Kaff = 1/(Ts*Ts*K) = 1/((11.84*2*np.pi)**2/5000**2) = 4517.278506241803 %Kfff=100 %pb.MaxInt=200 %200mA should be enought to fix static errors end - + pb.desc=desc; %mdlName='stage_closed_loop'; %open(mdlName) %sim(mdlName) diff --git a/matlab/DeltaTauSim.slx b/matlab/DeltaTauSim.slx index d8c6e007e49d0c05054b945f322c4ae07c2a984a..e008aced0e59b56d5037d34c26b5e7ad1c93e128 100644 GIT binary patch delta 18059 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 V zS)a;@zUtztKVPkV<-xx%I~)FfdQ`GnSJbBS;5zyHVUs1#o>^JH^MRFi+v~zvAsuRg z;*%eGFSaoHJNcnf^9tj<{`xy*Y>Q97jy1vip zk*Xu`xP?EAlV_9~)Su6icI0V)U)hyJV9Jcny!$~Hi}r>t5q^>TWz_gL5U z+UhR9XPXzgJx_*T^?FyE)DjVaJ^CCwqxeNEMENqLk9rzio#Sz!P2k}4oQ9}P6SgQ6 z>D+Uhqp~zaGwgv1Ta6P-SkZ&29a4!-{<5orCanxuYxF}wti`%B?joyiSkl}bn(2K^ zlDTgyy$=L3D}3deSIbwZmD63s?VoUD3tuARxx1Qjb6IZtZu3o&FtuPcT$k_kUf?Fj z)J>|X`7x&^FK+AWY5Kg>x$n21E$++fUUi5j@99!Z(|jg>oGvoCdb%J)YywcMA`2{bV7j0J$jN+u{hrN0t#5%?3SJKle>OQ?5Aq%}gF}oK5}%6r0gMxv)ZXvhFOXnC&bn`M8M;4Dm&&ImP;VAQHpu lU9+T^?o67TH(71+AD})^cunS+EyWlxS$(zzTi{fX0|7B9%{%}A delta 18277 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 iqMeas--->actPos ``` +Optimizing params +----------------- +``` + %Kaff = 1/(Ts*Ts*K) = 1/((11.84*2*np.pi)**2/5000**2) = 4517.278506241803 + %Kfff=100 + + + pb.Kp=25;pb.Kvfb=350;pb.Ki=0.02;pb.Kvff=350;pb.Kaff=1/(1.548e04*(pb.Ts^2));pb.MaxInt=1000; + %19.8Hz 0dB K=(19.8*2*np.pi)**2=15477.1 Ts=5kHz=.2ms + %Kaff = 1/(Ts*Ts*K) = 1/((19.8*2*np.pi)**2/5000**2) = 1615.2877200403302 + + +/opt/gfa/python-2.7/2018.12/bin/python -c 'import wx' +OTHER VERSION DO NOT YET HAVE WX + + + +********** ORIG ************** +Motor[1].Servo.Kp=25 +Motor[1].Servo.Kvfb=400 +Motor[1].Servo.Ki=0.02 +Motor[1].Servo.Kvff=350 +Motor[1].Servo.Kaff=5000 +Motor[1].Servo.MaxInt=1000 +Motor[1].Servo.Kfff=0 + +Motor[2].Servo.Kp=22 +Motor[2].Servo.Kvfb=350 +Motor[2].Servo.Ki=0.02 +Motor[2].Servo.Kvff=240 +Motor[2].Servo.Kaff=1500 +Motor[2].Servo.MaxInt=1000 +Motor[2].Servo.Kfff=0 + + + + +********** OPTIMIZED ************** +Motor[1].Servo.Kp=25 +Motor[1].Servo.Kvfb=350 +Motor[1].Servo.Ki=0.02 +Motor[1].Servo.Kvff=350 +Motor[1].Servo.Kaff=1615. // 1/(1.548e04*(pb.Ts^2)) +Motor[1].Servo.MaxInt=1000 +Motor[1].Servo.Kfff=100 + +Motor[2].Servo.Kp=22 +Motor[2].Servo.Kvfb=450 +Motor[2].Servo.Ki=0.02 +Motor[2].Servo.Kvff=450 +Motor[2].Servo.Kaff=4517 +Motor[2].Servo.MaxInt=1000 +Motor[2].Servo.Kfff=100 + + + + diff --git a/matlab/identifyFxFyStage.m b/matlab/identifyFxFyStage.m index 9b10473..86f1458 100644 --- a/matlab/identifyFxFyStage.m +++ b/matlab/identifyFxFyStage.m @@ -270,7 +270,6 @@ function motCell=identifyFxFyStage(mode) mot.ss_q.Name='simplified mechanics, no current loop, no resonance'; chkCtrlObsv(mot.ss_q,'ss_q fyStage'); - % TESTS % u +-----------+ y %iqCmd------->|1 1|-------> iqMeas % | 2|-------> actVel @@ -281,7 +280,6 @@ function motCell=identifyFxFyStage(mode) mot.ss_cq.Name='simplified mechanics, current loop, no resonance'; tfq.InputName{1}=s;%restore - % TESTS % u +-----------+ y %iqCmd------->|1 1|-------> actVel % | 2|-------> actPos @@ -386,6 +384,26 @@ function motCell=identifyFxFyStage(mode) % +-----------+ mot.ss_q=ss(tfq); chkCtrlObsv(mot.ss_q,'ss_q fxStage'); + + % u +-----------+ y + %iqCmd------->|1 1|-------> iqMeas + % | 2|-------> actVel + % | 3|-------> actPos + % +-----------+ + s=tfq.InputName{1};tfq.InputName{1}='iqMeas'; + mot.ss_cq=connect(tfc,tfq,'iqCmd',{'iqMeas','actVel','actPos'}); + mot.ss_cq.Name='simplified mechanics, current loop, no resonance'; + tfq.InputName{1}=s;%restore + + % u +-----------+ y + %iqCmd------->|1 1|-------> actVel + % | 2|-------> actPos + % +-----------+ + s=tf1.InputName{1};tf1.InputName{1}='iqCmd'; + mot.ss_qr=connect(tfq,tf1,tf2,tf3,tf4,'iqCmd',{'actVel','actPos'}); + mot.ss_qr.Name='simplified mechanics, no current loop, resonance'; + tfp.InputName{1}=s;%restore + plotBode(mot) end diff --git a/python/helicalscan.py b/python/helicalscan.py index d7f4988..dfc0aac 100755 --- a/python/helicalscan.py +++ b/python/helicalscan.py @@ -1217,7 +1217,7 @@ if __name__=='__main__': gpascii = comm.gpascii # direct start - #hs=HelicalScan(comm, gather, args.verbose,sync_mode=0) + #hs=HelicalScan(comm, gather, args.verbose,sync_mode=0,pt2pt_time=20) #simulated start and frame trigger no sync #hs=HelicalScan(comm, gather, args.verbose,sync_mode=1,sync_flag=3) diff --git a/python/shapepath.py b/python/shapepath.py index 1f66e4d..9d17bd7 100755 --- a/python/shapepath.py +++ b/python/shapepath.py @@ -812,7 +812,7 @@ if __name__=='__main__': #sp = ShapePath(comm, gather, args.verbose) # direct start - #sp = ShapePath(comm, gather, args.verbose,sync_mode=0) + #sp = ShapePath(comm, gather, args.verbose,sync_mode=0,pt2pt_time=10) #simulated start and frame trigger no sync #sp = ShapePath(comm, gather, args.verbose,sync_mode=1,sync_flag=3) @@ -842,7 +842,6 @@ if __name__=='__main__': # 10ms 3 6860 # 10ms 4 9180 - #xy=False #sp.gen_grid_points(w=6,h=6,pitch=100,rnd=0,ofs=(0,0));sp.sort_points(False); #sp.gen_grid_points(w=100,h=100,pitch=10,rnd=.2) #sp.gen_swissfel_points(width=1000,ofs=(-500,0));sp.sort_points(xy=xy) @@ -851,13 +850,13 @@ if __name__=='__main__': #sp.gen_closed_shifted() #sp.gen_swissmx_points(width=1000,ofs=(-500,0)) #sp.gen_swissfel_points(width=1000,ofs=(-500,0)) - #sp.gen_rand_points(n=14, scale=1000);sp.sort_points(xy=xy) + sp.gen_rand_points(n=200, scale=1000);sp.sort_points(xy=False) #sp.gen_swissmx_points(width=1000, ofs=(-500, 0)); #sp.gen_spiral_points(rStart=100,rInc=10,numSeg=4,numCir=60, ofs=(0, 0)) #sp.gen_spiral_points(rStart=100,rInc=130,numSeg=4,numCir=2, ofs=(0, 0)) #sp.gen_grid_points(w=10,h=10,pitch=100,rnd=0,ofs=(0,0));sp.sort_points(False); #sp.gen_grid_points(w=1,h=10,pitch=100,rnd=0,ofs=(0,0)) - sp.gen_spiral_points(rStart=100,rInc=20,numSeg=8,numCir=32, ofs=(0, 0)) + #sp.gen_spiral_points(rStart=100,rInc=20,numSeg=8,numCir=32, ofs=(0, 0)) #sp.gen_closed_shifted() sp.setup_gather(acq_per=1)