diff --git a/Makefile b/Makefile index 5075207..95f7951 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ MODULE = $(notdir $(shell pwd)) BUILDCLASSES = Linux ARCH_FILTER = eldk42% SL6-x86_64 EXCLUDE_VERSIONS = 3.14.8 -SCRIPTS+=$(wildcard add_EXPMX*.cmd cfg/*.cfg cfg/*.py cfg/*.pbi python/*.py) +#SCRIPTS+=$(wildcard add_EXPMX*.cmd cfg/*.cfg cfg/*.py cfg/*.pbi python/*.py) +SCRIPTS+=$(wildcard add_EXPMX*.cmd cfg/*.cfg cfg/*.pbi) #SOURCES+=src/DHVSaSub.cpp #DBDS+=src/DHVSaSub.dbd USR_CXXFLAGS+= -fno-operator-names diff --git a/Readme.md b/Readme.md index ddc8272..8448f07 100644 --- a/Readme.md +++ b/Readme.md @@ -1098,12 +1098,14 @@ Software esbMX deploy zamofing_t@ganymede:~$ ll /sf/bernina/config/swissmx/zamofing_t/ /sf/bernina/config/swissmx/ ssh saresb-cons-01 - ssh sf-cons-01 + ssh sf-cons-01 source /opt/gfa/python source activate /sf/bernina/config/swissmx/conda/envs/b440_clone -zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python$ +zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python$ cp -rL ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/*.py ~/Documents/prj/SwissFEL/PBTools/pbtools/ /sf/bernina/config/swissmx/zamofing_t/ +scp -r ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/*.py ganymede:~/Documents/prj/SwissFEL/PBTools/pbtools/ /sf/bernina/config/swissmx/zamofing_t/ + ``` diff --git a/matlab/StateSpaceControlDesign.m b/matlab/StateSpaceControlDesign.m index 2ae1427..a63f972 100644 --- a/matlab/StateSpaceControlDesign.m +++ b/matlab/StateSpaceControlDesign.m @@ -16,7 +16,6 @@ function [ssc]=StateSpaceControlDesign(mot) % % https://www.youtube.com/watch?v=Lax3etc837U - %ss_ol=mot.ssPlt; ssPlt=mot.ssPlt; %real plant (model of real plant) ssPlt.Name='open loop plant'; ssMdl=mot.ssMdl;%ssMdl; %simplified model (observable,controlable) for observer @@ -93,6 +92,7 @@ function [ssc]=StateSpaceControlDesign(mot) P=[p1 p1' p2 p2' p3 p3'];% p4 p4' p5 p5' p6 p6']; end end + %P=P*.1; % P was too aggressive K = place(Am,Bm,P); %K = acker(Am,Bm,Pm); end %if lqr @@ -118,29 +118,7 @@ function [ssc]=StateSpaceControlDesign(mot) % *** observer controller *** % %observer poles-> 5 times farther left than system poles - if mot.id==1 - op1=(p1*5); - op2=(p2*5); - if length(poles)>4 - op3=(p3*5); - OP=[op1 op1' op2 op2' op3 op3']; - else - OP=[op1 op1' op2 op2']; - end - - else - op1=(p1*2); - op2=(p2*2); - if length(poles)>4 - op3=(p3*2); - op4=(p4*2); - op5=(p5*2); - op6=(p6*2); - OP=[op1 op1' op2 op2' op3 op3'];% op4 op4' op5 op5' op6 op6']; - else - OP=[op1 op1' op2 op2']; - end - end + OP=2*P; L=place(Am',Cm',OP)'; %L=acker(A',C',OP)'; @@ -150,8 +128,9 @@ function [ssc]=StateSpaceControlDesign(mot) zeros(size(Bm)) ]; Ct = [ Cm zeros(size(Cm)) ]; + Dt=0; % step answer on closed loop with observer controller: - ss_t = ss(At,Bt,Ct,0,'Name','observer controller','InputName',{'desPos'},'OutputName',mot.ssMdl.OutputName); + ss_t = ss(At,Bt,Ct,Dt,'Name','observer controller','InputName',{'desPos'},'OutputName',mot.ssMdl.OutputName); figure();lsim(ss_t,ones(size(t)),t,[xm0 xm0]);title('step on closed loop with observer'); @@ -159,12 +138,12 @@ function [ssc]=StateSpaceControlDesign(mot) % Ts=1/5000; % 5kHz ss_tz = c2d(ss_t,Ts); + [Atz,Btz,Ctz,Dtz]=ssdata(ss_tz ); ss_tz .Name='discrete obsvr ctrl'; % step answer on closed loop with disctrete observer controller: t = 0:Ts:.05; figure();lsim(ss_tz ,ones(size(t)),t,[xm0 xm0]);title('step on closed loop with observer discrete'); - %plot all bode diagrams of desPos->actPos figure(); h=bodeplot(ss_cl(3),ss_t(3),ss_tz(3)); @@ -182,20 +161,23 @@ function [ssc]=StateSpaceControlDesign(mot) Do=zeros(size(Co,1),size(Bo,2)); ss_o = ss(Ao,Bo,Co,Do,'Name','observer controller','InputName',{'desPos','iqMeas','iqVolts','actPos'},'OutputName',{'k*xt'}); - + + %discrete plant + ssPltz = c2d(ssPlt,Ts); + [Apz,Bpz,Cpz,Dpz]=ssdata(ssPltz); + + %discrete observer controller ss_oz = c2d(ss_o,Ts); [Aoz,Boz,Coz,Doz]=ssdata(ss_oz); mdlName='observer'; open(mdlName); -ssPltz = c2d(ssPlt,Ts); -[Apz,Bpz,Cpz,Dpz]=ssdata(ssPltz); %state space controller ssc=struct(); - for k=["Ts","Ap","Bp","Cp","Dp","Ao","Bo","Co","Do","Apz","Bpz","Cpz","Dpz","Aoz","Boz","Coz","Doz","V","K","L","ss_cl","ss_o","ss_oz","numV","denV"] + 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","ss_cl","ss_o","ss_oz","numV","denV"] ssc=setfield(ssc,k,eval(k)); end save(sprintf('/tmp/ssc%d.mat',mot.id),'-struct','ssc'); diff --git a/matlab/observer.slx b/matlab/observer.slx index 9e2673c..25462e5 100644 Binary files a/matlab/observer.slx and b/matlab/observer.slx differ diff --git a/matlab/stage_closed_loop.slx b/matlab/stage_closed_loop.slx index 0a29f9a..6afde47 100644 Binary files a/matlab/stage_closed_loop.slx and b/matlab/stage_closed_loop.slx differ diff --git a/python/MXTuning.py b/python/MXTuning.py index 30d7c14..88daf45 100755 --- a/python/MXTuning.py +++ b/python/MXTuning.py @@ -335,8 +335,8 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' args=parser.parse_args() #plt.ion() - args.host='MOTTEST-CPPM-CRM0573' - args.host=None + #args.host='MOTTEST-CPPM-CRM0573' + #args.host=None if args.host is None: comm=gt=None else: @@ -412,7 +412,8 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' elif mode == 6: # plot all raw acquired data files # display bode plots - for fn in args.plot: + import glob + for fn in glob.glob(os.path.join(base,'*.npz')): if os.path.basename(fn).startswith('sine_ol_mot'): tune.bode_sine(openloop=True, file=fn) if os.path.basename(fn).startswith('chirp_ol_mot'): @@ -421,14 +422,33 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' tune.bode_sine(openloop=False, file=fn) if os.path.basename(fn).startswith('chirp_cl_mot'): tune.bode_chirp(openloop=False, file=fn) - print('done') elif mode==7: #further tests - #tune.init_stage(); - plt.close('all') - #tune.custom_chirp() - tune.custom_chirp(motor=1,minFrq=100,maxFrq=3000,amp=10,tSec=5,mode=0,file='/tmp/cst_chirp0.npz') - #tune.custom_chirp(motor=2,minFrq=1,maxFrq=1000,tSec=5,mode=1,file='/tmp/cst_chirp1.npz') - #tune.custom_chirp(motor=1,minFrq=1,maxFrq=3000,tSec=5,mode=2,file='/tmp/cst_chirp2.npz') + fn='/tmp/cst_chirp0.npz' + motLst=(1, 2)#(2,)# + init_stage=False + for mot in motLst: + fn=os.path.join(base, 'cst_chirp_s_ol_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=100,maxFrq=1000,amp=50,tSec=15,mode=0,file=fn) + init_stage=False + for mot in motLst: + fn=os.path.join(base, 'cst_chirp_s_cl1_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=1,maxFrq=100,amp=20,tSec=15,mode=1,file=fn) + init_stage=False + for mot in motLst: + fn=os.path.join(base, 'cst_chirp_s_cl2a_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=1,maxFrq=30,amp=100,tSec=30,mode=2,file=fn) + for mot in motLst: + fn=os.path.join(base, 'cst_chirp_s_cl2b_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=20,maxFrq=150,amp=10,tSec=30,mode=2,file=fn) + init_stage=False + for mot in motLst: + fn=os.path.join(base, 'cst_chirp_s_cl2c_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=100,maxFrq=300,amp=1,tSec=30,mode=2,file=fn) elif mode==8: #generater code #before this can be done, the observer controller has to be designed with matlab: #s.a.ESB_MX/matlab/Readme.md @@ -462,6 +482,15 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' fh.close() print(fnc+' generated.') print('now compile it looking at PBTools/pbtools/usr_servo_phase/usrServoSample') + elif mode==9: #SCRATCH + motLst=(1, 2)#(2,)# + init_stage=False + for mot in motLst: + fn=os.path.join(base, 'scratch_%d.npz' % mot) + if not init_stage and not os.path.isfile(fn):tune.init_stage();init_stage=True + tune.custom_chirp(motor=mot,minFrq=1,maxFrq=20,amp=200,tSec=15,mode=2,file=fn) + + print('done') plt.show() #------------------ Main Code ---------------------------------- #ssh_test()'/tmp/usrcode.c' diff --git a/python/shapepath.py b/python/shapepath.py index f397259..fb5e4b2 100755 --- a/python/shapepath.py +++ b/python/shapepath.py @@ -552,16 +552,16 @@ if __name__=='__main__': #setup_gather(self, acq_per=1) - sp.setup_gather() + sp.setup_gather(acq_per=2) #setup_sync(self, crdId=1, prgId=2, plcId=2, mode=0, **kwargs): sp.setup_sync() #no sync at all #sp.setup_sync(mode=1) #sync with timing system #sp.gen_grid_points(w=2,h=2,pitch=50,rnd=.2);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1) - #sp.gen_swissmx_points(scale=10);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1) + sp.gen_swissmx_points(scale=10);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40,acq_per=1) #sp.gen_grid_points(w=2,h=20,pitch=50,rnd=0);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1) - sp.gen_rand_points(n=500, scale=1000);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1) + #sp.gen_rand_points(n=500, scale=1000);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1) #>>>setup gather and sync<<<