diff --git a/MXfastStageDoc/MXfastStage.tex b/MXfastStageDoc/MXfastStage.tex index 7738626..684123b 100644 --- a/MXfastStageDoc/MXfastStage.tex +++ b/MXfastStageDoc/MXfastStage.tex @@ -194,12 +194,34 @@ $\rightarrow$ The closed loop response becomes bad above 20Hz (motor 1 ca. -10\% \FloatBarrier \subsubsection{Friction} -\begin{tcolorbox}[width=15cm,colback=red!5!white,colframe=red!75!black,colbacktitle=red!50,coltitle=black,title=TODO] -Record the friction (=current) at a slow move from +lim to -lim.\\ -Analyse the friction depending on the positions and motion directions.\\ -Do the records and analysis at different speeds. -\end{tcolorbox} +To measure the friction, the stage is moved at slow speed from ++lim to -lim. The current is proportional to the force. +Additionally the friction is measured depending on the stage positions and motion directions. This is measured at different speed to see if at these velocities the viscose friction is visible. +\begin{figure}[h!] +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/friction10.eps} +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/friction11.eps} +\caption{position dependant friction of motor 1} +\label{fig:mot1_frict} +\end{figure} + +\begin{figure}[h!] +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/friction20.eps} +\includegraphics[scale=.45]{../python/MXTuning/19_01_29/img/friction21.eps} +\caption{position dependant friction of motor 2} +\label{fig:mot2_frict} +\end{figure} + +Data recording is done with: \verb|./MXTuning.py --dir MXTuning/19_01_29 --mode 16|.\\ +The function parameters are: \verb|pMin=-10000, pMax=10000, speed=(5,10,20,30,60), cnt=2, period=10|. +The recorded data moves from -10000um to 10000um at speed of 5 to 60 mm/s.\\ + +Avg current forward: 111.7 Avg current backward: -105.3\\ +Avg current forward: 95.3 Avg current backward: -130.7\\ + +These values should be used for the $K_{fff}$ parameter of the Servo loop:\\ + +Motor 1,2: $K_{fff}\approx100$\\ \FloatBarrier \subsubsection{using advanced Deltatau Servo Loop} @@ -311,8 +333,7 @@ The inductance of the stage is 2.4 mH.\\ Nevertheless simulations with \verb|current_loop.slx| showed, that the current loop only works in the discrete domain. In continous domain neither the amplification nor the shape mached.\\ Therefore the only approach is to use the second order transfer function as approximated in section \ref{sec:measCurStep}.\\ -\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,colbacktitle=red!50,coltitle=black,title=TODO] -A further test will be to 'remove' the current loop. This can be done by setting:$IiGain=0, IpfGain=1, IpbGain=-1$. +A further test is to 'turn of' the current loop. This can be done by setting:$IiGain=0, IpfGain=1, IpbGain=-1$. The resulting transfer function is: \[ \frac{Ipf} @@ -323,8 +344,16 @@ The resulting transfer function is: {\frac{L}{R} s +1}\\ \\ \] -This is a $PT_1$ element with a time constant of $\frac{L}{R}=\frac{2.4mH}{8.8\Omega}=0.27ms$. But probably due to additional cables etc. the resistance and therefore also the timeconstant is bigger. -\end{tcolorbox} +This is a $PT_1$ element with a time constant of $\frac{L}{R}=\frac{2.4mH}{8.8\Omega}=0.27ms$. Figures \ref{fig:curr_ol} shows a current step of 3000 \verb|curr_bit| resulting in a current of about 150 \verb|curr_bit|. The rise time matches roughly. So the cable resistance has not a major impact. + +\begin{figure}[h!] +\centering +\includegraphics[scale=.25]{../python/MXTuning/19_01_29/img/curr_step_ol_10.eps} +\includegraphics[scale=.25]{../python/MXTuning/19_01_29/img/curr_step_ol_20.eps} +\caption{voltage step (current open loop)} +\label{fig:curr_ol} +\end{figure} + \subsection{Mechanical model} @@ -610,8 +639,9 @@ Following code calculates parameters for a observer controller, does a simulatio \begin{verbatim} clear;clear global;close all; mot=identifyFxFyStage(7); +sscType=0 for k =1:2 - [ssc]=StateSpaceControlDesign(mot{k});sim('observer'); + [ssc]=StateSpaceControlDesign(mot{k},sscType);sim('observer'); f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g'); set(h(1),'color','b'); set(h(2),'color',[0 0.5 0]); print(f,sprintf('figures/sim_cl_observer_%d',mot{k}.id),'-depsc'); @@ -629,10 +659,10 @@ end \begin{figure}[h!] \center -\includegraphics[scale=.45]{../matlab/figures/sim_cl_obs_0_1.eps} -\includegraphics[scale=.45]{../matlab/figures/sim_cl_obs_bode0_1.eps}\\ -\includegraphics[scale=.45]{../matlab/figures/sim_cl_obs_0_2.eps} -\includegraphics[scale=.45]{../matlab/figures/sim_cl_obs_bode0_2.eps} +\includegraphics[scale=.45]{../matlab/figures/sim_cl_observer_1.eps} +\includegraphics[scale=.45]{../matlab/figures/sim_cl_observer_bode1.eps}\\ +\includegraphics[scale=.45]{../matlab/figures/sim_cl_observer_2.eps} +\includegraphics[scale=.45]{../matlab/figures/sim_cl_observer_bode2.eps} \caption{Observer sim: Motor 1 Motor 2} \label{fig:mot_observer_sim} \end{figure} @@ -673,11 +703,56 @@ Finally the real time servo code is compliled for the DeltaTau with:\\ \verb|/epics_ioc_modules/ESB_MX/python/usr_code$ make|\\ -Following lines in gpasciiCommander will activate the user servo loop code: +Following lines in gpasciiCommander will activate the user servo loop code. +\vspace{1pc} -\begin{tcolorbox}[width=15cm,colback=red!5!white,colframe=red!75!black,colbacktitle=red!50,coltitle=black,title=TODO] +Here the full process: + +\begin{tcolorbox}[width=15cm,colback=yellow!5!white,colframe=yellow!75!black,colbacktitle=yellow!50,coltitle=black,title=MATLAB] +\begin{verbatim} +clear;clear global;close all; +mot=identifyFxFyStage(7); +sscType=0; +for k =1:2 + [ssc]=StateSpaceControlDesign(mot{k},sscType); +end +\end{verbatim} \end{tcolorbox} +\begin{tcolorbox}[width=15cm,colback=yellow!5!white,colframe=yellow!75!black,colbacktitle=yellow!50,coltitle=black,title=Shell] +\begin{verbatim} +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python +./MXTuning.py -m512 + +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/usr_code +make + +cd /home/zamofing_t/Documents/prj/SwissFEL/PBTools/pbtools/usr_servo_phase +scp userservo_util userphase_util usrServoSample/usralgo.ko root@SAR-CPPM-EXPMX1:/tmp + + +\end{verbatim} +\end{tcolorbox} + + +\begin{tcolorbox}[width=15cm,colback=yellow!5!white,colframe=yellow!75!black,colbacktitle=yellow!50,coltitle=black,title=DeltaTau Shell] +\begin{verbatim} +root@:/opt/ppmac# +LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/userservo_util -d 1 +rmmod usralgo +insmod /tmp/usralgo.ko +LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/userservo_util -l 1 usr_servo_ctrl_2 +LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/userservo_util -e 1 + +gpascii: +Motor[1].Ctrl =UserAlgo.ServoCtrlAddr[1] +\end{verbatim} +\end{tcolorbox} + + + + + \vspace{1pc} \begin{appendix} diff --git a/MXfastStageDoc/Scratch.tex b/MXfastStageDoc/Scratch.tex index 9111ca6..4de9b08 100644 --- a/MXfastStageDoc/Scratch.tex +++ b/MXfastStageDoc/Scratch.tex @@ -1,6 +1,11 @@ \newpage \section{SCRATCH} +\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,colbacktitle=red!50,coltitle=black,title=TODO] +Here is still work to do... +\end{tcolorbox} + + \begin{verbatim} clear; clear global; diff --git a/cfg/MX1_setup.cfg b/cfg/MX1_setup.cfg index 6b6105c..2bd5ace 100644 --- a/cfg/MX1_setup.cfg +++ b/cfg/MX1_setup.cfg @@ -49,8 +49,6 @@ !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') - - //Stage X Parker MX80L (top stage, mounted on Y stage) //---------------------------------------------------- //Motor[2].pPhaseEnc -> PowerBrick[0].Chan[1].PhaseCapt.a @@ -64,6 +62,11 @@ !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') +//Tweaks: +//Motor[1].Servo.Kfff=100 +//Motor[2].Servo.Kfff=100 + + //rot stage //--------- diff --git a/matlab/StateSpaceControlDesign.m b/matlab/StateSpaceControlDesign.m index 325b0c5..b7cb4ce 100644 --- a/matlab/StateSpaceControlDesign.m +++ b/matlab/StateSpaceControlDesign.m @@ -41,6 +41,7 @@ function [ssc]=StateSpaceControlDesign(mot,mode) %use_lqr: use lqr instead of pole placement verb=1; use_lqr=0; + MaxDac=2011.968; filt_pos_err=Prefilt(mot,2); %locate poles: 2500rad/s = 397Hz, 6300rad/s = 1027Hz switch mode @@ -214,10 +215,19 @@ function [ssc]=StateSpaceControlDesign(mot,mode) %state space controller ssc=struct(); - for k=["Ts","ss_plt","ss_o","ss_oz","filt_pos_err","filt_pos_err_z","V"] + for k=["Ts","ss_plt","ss_o","ss_oz","filt_pos_err","filt_pos_err_z","V","MaxDac"] ssc=setfield(ssc,k,eval(k)); end - save(sprintf('/tmp/ssc%d.mat',mot.id),'-struct','ssc'); + + mat2py=struct(); + [ozA,ozB,ozC,ozD]=ssdata(ss_oz); + [pos_err_num,pos_err_den]=tfdata(filt_pos_err_z); + for k=["Ts","V","MaxDac","ozA","ozB","ozC","ozD","pos_err_num","pos_err_den"] + mat2py=setfield(mat2py,k,eval(k)); + end + fn=sprintf('/tmp/ssc%d.mat',mot.id); + save(fn,'-struct','mat2py'); + disp(['saved ' fn]); end function pf=Prefilt(mot,mode) diff --git a/matlab/documentFunctions.m b/matlab/documentFunctions.m index afaac54..670656c 100644 --- a/matlab/documentFunctions.m +++ b/matlab/documentFunctions.m @@ -2,7 +2,7 @@ baseDir='/home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/matlab/figures'; clear;clear global; -close all;disp('löoad identification data...'); +close all;disp('load identification data...'); mot=identifyFxFyStage(7); close all;disp('simulate stage closed loop...'); @@ -16,21 +16,9 @@ for k =1:2 end close all;disp('simulate observer...'); -for k =1:2 - [ssc]=StateSpaceControlDesign(mot{k});sim('observer'); - f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g'); - set(h(1),'color','b'); set(h(2),'color',[0 0.5 0]); - print(f,sprintf('figures/sim_cl_observer_%d',mot{k}.id),'-depsc'); - f=bodeSamples(desPos_actPos); - print(f,sprintf('figures/sim_cl_observer_bode%d',mot{k}.id),'-depsc'); -end -disp('document figure generation done');close all; - - -close all;disp('simulate observer with prefilter...'); -for m =0%0:1 - for k =1:2 - [ssc]=StateSpaceControlDesign(mot{k},m);sim('observer'); +for sscType=0%0:1 + for k=1:2 + [ssc]=StateSpaceControlDesign(mot{k},sscType);sim('observer'); f=figure(); h=plot(desPos_actPos.Time,desPos_actPos.Data,'g'); 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'); diff --git a/matlab/observer.slx b/matlab/observer.slx index 69a6764..a199d8b 100644 Binary files a/matlab/observer.slx and b/matlab/observer.slx differ diff --git a/python/MXTuning.py b/python/MXTuning.py index 43846aa..1eda88c 100755 --- a/python/MXTuning.py +++ b/python/MXTuning.py @@ -13,11 +13,12 @@ bit 0=1: record/plot current step bit 1=2: custom chirp record/plot for IdCmd->ActPos transfer function bit 2=4: custom chirp record/plot for DesPos->ActPos transfer function bit 3=8: custom chirp record/plot for various transfer function -bit 4=16: plot the full bode recording -bit 5=32: plot the full bode recording with an approximation model -bit 6=64: plot all raw acquired data files -bit 7=128: custom plots -bit 8=256: generate observer code (after files generated with matlab) +bit 4=16: slow linear move record/plot friction +bit 5=32: plot the full bode recording +bit 6=64: plot the full bode recording with an approximation model +bit 7=128: plot all raw acquired data files +bit 8=256: custom plots +bit 9=512: generate observer code (after files generated with matlab) -> check https://github.com/klauer/ppmac for fast data gathering server which supports phase gathering -> not yet compiling: /home/zamofing_t/Documents/prj/SwissFEL/PowerBrickInspector/ppmac/fast_gather @@ -281,10 +282,10 @@ class MXTuning(Tuning): #[ssc]=StateSpaceControlDesign(mot1); mat=scipy.io.loadmat(fn) motid=int(re.search('(\d)\.mat',fn).group(1)) - A=mat['Aoz'] - B=mat['Boz'] - C=mat['Coz'] - D=mat['Doz'] + A=mat['ozA'] + B=mat['ozB'] + C=mat['ozC'] + D=mat['ozD'] V=mat['V'] u=('DesPos','IqMeas','IqVolts','ActPos') y=('obsvOut',) @@ -348,6 +349,136 @@ class MXTuning(Tuning): EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) return (hdr,prog) + def friction(self, motor=1, pMin=-10000, pMax=10000, speed=(5,10,20,30,60), cnt=2, period=10, phase=False, + file='/tmp/gather.npz'): + if os.path.isfile(file): + f=np.load(file) + data=f['data'] + meta=f['meta'].item() + meta['file']=file + else: + gpascii=self.comm.gpascii + gt=self.gather + gt.set_phasemode(phase) + m='Motor[%d].'%motor + address=('ActPos','IqMeas') + address=tuple(map(lambda x: m+x, address)) + gt.set_address(*address) + # gt.set_property(MaxSamples=300000, Period=1) + gt.set_property(Period=period) + + tSrv=gpascii.servo_period + tSrv=2E-4 # seconds + phOsv=gpascii.get_variable('sys.PhaseOverServoPeriod', float) + homePos=gpascii.get_variable('Motor[%d].HomePos'%motor, float) + JogTa=gpascii.get_variable('Motor[%d].JogTa'%motor, float) + gpascii.set_variable('Motor[%d].JogTa'%motor, -5) + + subs={'prgId':999,'mot':motor,'num':100,'phase':'Phase' if phase else '','pMin':pMin,'pMax':pMax} + prog = [''' + &1 + open prog {prgId} + linear abs + jog{mot}={pMin} + dwell 100 + Gather.{phase}Enable=2 + '''.format(**subs),] + + for spd in sorted(speed*cnt): + prog.append(''' + Motor[{mot}].JogSpeed=%d + jog{mot}={pMax} + dwell 0 + jog{mot}={pMin} + dwell 0'''.format(**subs)%spd) + prog.append(''' + dwell 10 + Gather.{phase}Enable=0 + close + &1 + b{prgId}r + '''.format(**subs)) + gpascii.send_block('\n'.join(prog)) + res=gpascii.sync() + res=res.replace(GpasciiChannel.ACK+'\r\n','') + print(res) + t=time.time() + gt.wait_stopped() + print('time %f'%(time.time()-t)) + self.data=data=gt.upload() + gpascii.set_variable('Motor[%d].JogTa'%motor, JogTa) + data[:,0]-=homePos + + meta={'motor':motor,'date':time.asctime(),'ts':tSrv*period if not phase else tSrv*phOsv*period,'address':address} + np.savez_compressed(file, data=data, meta=meta) + meta['file'] = file + ts=meta['ts'] + t=ts*np.arange(data.shape[0]) + fig, ax1 = plt.subplots() + ax2=ax1.twinx() + ax3=ax1.twinx() + ax3.spines["right"].set_position(("axes", 1.12)) + fig.subplots_adjust(right=0.80) + + actPos=data[:,0] + iqMeas=data[:,1] + actVel=np.diff(actPos)/ts/1000. + actVel=np.hstack((actVel, actVel[-1])) + h1,=ax1.plot(t,actPos,'b',label="actPos (um)") + h2,=ax2.plot(t,iqMeas,'g',label="IqMeas (curr_bit)") + h3,=ax3.plot(t,actVel,'r',label="actVel (mm/s)") + ax1.yaxis.label.set_color(h1.get_color()) + ax2.yaxis.label.set_color(h2.get_color()) + ax3.yaxis.label.set_color(h3.get_color()) + ax1.tick_params(axis='y', colors=h1.get_color()) + ax2.tick_params(axis='y', colors=h2.get_color()) + ax3.tick_params(axis='y', colors=h3.get_color()) + + hl=[h1,h2,h3] + ax1.legend(hl, [h.get_label() for h in hl],loc='best') + + sz=100; weights = np.repeat(1.0, sz) / sz + + idx=actVel[:-1]>0 + arg=np.argsort(actPos[idx]) + p1=actPos[idx][arg];c1=iqMeas[idx][arg] + c1 = np.convolve(c1, weights, 'same') + + idx=actVel[:-1]<0 + arg=np.argsort(actPos[idx]) + p2=actPos[idx][arg];c2=iqMeas[idx][arg] + c2 = np.convolve(c2, weights, 'same') + + fig, ax1 = plt.subplots() + hl=[] + hl+=ax1 .plot(actPos,iqMeas,'y-',label='raw') + hl+=ax1 .plot(p1,c1,'g-',label='vel>0') + hl+=ax1 .plot(p2,c2,'r-',label='vel<0') + + #cAll=c1;pAll=p1 + #cAll=cAll-cAll.mean() + #p=np.arange(500,28000,100) #np.arange(500,28000,128) + #c=np.interp(p,pAll,cAll) + #hl+=ax1.plot(p,c,'b.',label='vel<0') + #FfricLut=np.array([p,c]).T + Ffric=np.array([c1.mean(),c2.mean()]) + print 'Avg current forward:',Ffric[0],'Avg current backward:',Ffric[1] + #print 'FfricLut',FfricLut + #print '//positions '+'%g,%g,%g'%tuple(p[0:3]),'...%g,%g,%g'%tuple(p[-3:]) + #print 'float lutCur[%d]={'%len(p) + #for i in range(len(p)): + # print '%g,'%(c[i]), + #print '};' + import scipy.io + #fn='/home/zamofing_t/afs/ESB-MX/data/friction.mat' + #scipy.io.savemat(fn,mdict={'Ffric':Ffric,'FfricLut':FfricLut}) + #print '\n\nuncomment line above to saved to matlab file',fn + + #ax.xaxis.set_label_text(channels[1]) + #ax1.yaxis.set_label_text('current in bits: '+channels[4]) + ax1.legend(loc='best') + plt.show(block=False) + def check_fast_stage(self,file='/tmp/gather.npz'): if os.path.isfile(file): f=np.load(file) @@ -433,6 +564,31 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) scipy.io.savemat(fn, mdict=f) print('save to matlab file:'+fn) + fn=os.path.join(self.baseDir, 'curr_step_ol_%d.npz' % mot) + doSet=not os.path.isfile(fn) + if doSet: + gpascii = self.comm.gpascii + IpfGain=gpascii.get_variable('Motor[%d].IpfGain'%mot,float) + IpbGain=gpascii.get_variable('Motor[%d].IpbGain'%mot,float) + IiGain =gpascii.get_variable('Motor[%d].IiGain' %mot,float) + gpascii.set_variable('Motor[%d].IpfGain'%mot,1) + gpascii.set_variable('Motor[%d].IpbGain'%mot,-1) + gpascii.set_variable('Motor[%d].IiGain' %mot,0) + plt.close('all') + mag=3000 + self.bode_current(motor=mot, magMove=mag, magPhase=500, dwell=10, file=fn) + if doSet: + gpascii = self.comm.gpascii + gpascii.set_variable('Motor[%d].IpfGain'%mot,IpfGain) + gpascii.set_variable('Motor[%d].IpbGain'%mot,IpbGain) + gpascii.set_variable('Motor[%d].IiGain' %mot,IiGain) + self.homed&=~mot + ax,=plt.figure(1).axes + ax.set_ylim(0,200) + ax.set_title('step of 0->3000 with current in open loop') + plt.show(block=False) + save_figs(fn) + if mode&2: motLst = (1, 2) # (2,)# #recType: @@ -508,21 +664,30 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) plt.show(block=False) save_figs(fn) - if mode&16: #plot the full bode recording + if mode&16: #record/plot friction + for mot in (1, 2): + plt.close('all') + fn=os.path.join(self.baseDir, 'friction%d.npz' % mot) + self.init_stage(mot,fn) + self.friction(motor=mot, file=fn); + save_figs(fn) + + + if mode&32: #plot the full bode recording plt.close('all') self.bode_full_plot(mot=1,base=self.baseDir) self.bode_full_plot(mot=2,base=self.baseDir) plt.show(block=False) save_figs(os.path.join(self.baseDir,'bode_full_plot')) - if mode&32: #plot the full bode recording with an approximation model + if mode&64: #plot the full bode recording with an approximation model plt.close('all') self.bode_model_plot(mot=1) self.bode_model_plot(mot=2) plt.show(block=False) save_figs(os.path.join(self.baseDir,'bode_model_plot')) - if mode&64: # plot all raw acquired data files + if mode&128: # plot all raw acquired data files plt.close('all') import glob for fn in glob.glob(os.path.join(self.baseDir,'*.npz')): @@ -541,7 +706,7 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) raw_input('press return') - if mode&128: #custom plots + if mode&256: #custom plots plt.close('all') G1=signal.lti([1/8.8], [2.4E-3/8.8,1]) # num denum print('rise time %e s'%(2.4E-3/8.8)) @@ -588,7 +753,7 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) save_figs(os.path.join(self.baseDir,'iqCmd_TF')) - if mode&256: #generater code + if mode&512: #generater code #before this can be done, the observer controller has to be designed with matlab: #s.a.ESB_MX/matlab/Readme.md #clear; @@ -622,8 +787,10 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) print(fnc+' generated.') print('now compile it looking at PBTools/pbtools/usr_servo_phase/usrServoSample') print('done') - plt.show(block=False) - raw_input('press return') + + if mode&~512: # show and block only if not code generation + plt.show(block=False) + raw_input('press return') def save_figs(fn): @@ -701,7 +868,7 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' #plt.ion() #args.host='MOTTEST-CPPM-CRM0573' - args.host=None + #args.host=None if args.host is None: comm=gt=None else: diff --git a/python/shapepath.py b/python/shapepath.py index 2f8146f..aabf3c6 100755 --- a/python/shapepath.py +++ b/python/shapepath.py @@ -323,7 +323,7 @@ class DebugPlot: if mode&8: self.plot_trigger_jitter() - plt.show() + plt.show(block=False) def plot_bode(self,xy=(0,1),mode=25,db=True): '''displays a bode plot of the data @@ -872,6 +872,10 @@ if __name__=='__main__': sp.gather_upload(fnRec=fn+'.npz') dp=DebugPlot(sp);dp.plot_gather(mode=11) + print('done') + plt.show(block=False) + raw_input('press return') + #sp.plot_points(sp.points);plt.show()