diff --git a/python/MXTuning.py b/python/MXTuning.py index 36bfd64..a8bd5e0 100755 --- a/python/MXTuning.py +++ b/python/MXTuning.py @@ -9,13 +9,14 @@ tuning functions for ESB-MX Modes: -bit 0=1: record/plot current step -bit 1=2: custom chirp record/plot for IdCmd->ActPos transfer function -bit 1=4: custom chirp record/plot for DesPos->ActPos transfer function -bit 2=8: plot the full bode recording -bit 3=16: plot the full bode recording with an approximation model -bit 4=32: plot all raw acquired data files -bit 5=64: generate observer code (after files generated with matlab) +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: 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 @@ -44,9 +45,10 @@ class MXTuning(Tuning): self.homed=False - def init_stage(self,fn=''): + def init_stage(self,mot=3,fn=''): + print(fn) comm=self.comm - if comm is None or self.homed or os.path.isfile(fn): + if comm is None or (self.homed&mot)==mot or os.path.isfile(fn): return gpascii=comm.gpascii @@ -60,7 +62,7 @@ class MXTuning(Tuning): break sys.stdout.write('.');sys.stdout.flush() time.sleep(.2) - self.homed=True + self.homed=3 def bode_model_plot(self, mot): self.bode_full_plot(mot,self.baseDir) @@ -347,14 +349,17 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) def run(self,mode): #plt.ion() + self.homed=0 if mode&1: # full recording current step plt.close('all') - self.homed=False for mot in (1, 2): fn=os.path.join(self.baseDir, 'curr_step%d.npz' % mot) - self.init_stage(fn) + self.init_stage(mot,fn) + plt.close('all') self.bode_current(motor=mot, magMove=1000, magPhase=500, dwell=10, file=fn) + self.homed&=~mot plt.show(block=False) + save_figs(fn) f=np.load(fn) fn=fn[:-3]+'mat' import scipy.io @@ -362,8 +367,6 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) print('save to matlab file:'+fn) if mode&2: - plt.close('all') - self.homed=False motLst = (1, 2) # (2,)# #recType: # IA 0 IqCmd,ActPos (for plant transfer function) @@ -374,25 +377,30 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) #>>>>> IqCmd->ActPos transfer function (plant) using closed loop for low frequencies for mot in motLst: fn = os.path.join(self.baseDir, 'chirp_IA_%da.npz' % mot) - self.init_stage(fn) - self.custom_chirp(motor=mot, minFrq=1, maxFrq=15, amp=1000, tSec=15, recType=0,openLoop=False, file=fn) - self.homed=False + self.init_stage(mot,fn) + plt.close('all') + self.custom_chirp(motor=mot, minFrq=1, maxFrq=15, amp=1000, tSec=15, recType=0,mode=1, file=fn) + self.homed &= ~mot + plt.show(block=False) + save_figs(fn) #>>>>> IqCmd->ActPos transfer function (plant) using open loop for high frequencies for ext,amp,minFrq,maxFrq,tSec in (('b', 10, 10, 100*1.5, 30), ('c', 50, 100, 300*1.5, 30), ('d', 50, 300, 1000*1.5, 10), ('e', 100, 1000, 2000, 10)): - self.homed=False for mot in motLst: fn = os.path.join(self.baseDir, 'chirp_IA_%d%s.npz' % (mot,ext)) - self.init_stage(fn) - self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=0,openLoop=True, file=fn) + self.init_stage(mot,fn) + plt.close('all') + self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=0,mode=0, file=fn) + self.homed&=~mot + plt.show(block=False) + save_figs(fn) if mode&4: plt.close('all') - self.homed = False - motLst = (1, 2) # (2,)# + motLst = (1, 2) #(2,)# #>>>>> desPos->actPos transfer function (regulation) using closed loop #motor1: 0dB at 20.4 Hz #motor2: 0dB at 11.3 Hz @@ -408,49 +416,59 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) ('b', 20, 30, 75*1.5, 15), ('c', 5, 75, 150*1.5, 5), ('d', 1, 150, 750, 5)): - self.homed=False for mot in motLst: fn = os.path.join(self.baseDir, 'chirp_DA_%d%s.npz' % (mot,ext)) - self.init_stage(fn) - self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=1,openLoop=False, file=fn) + self.init_stage(mot,fn) + plt.close('all') + self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=1,mode=1, file=fn) + self.homed&=~mot + plt.show(block=False) + save_figs(fn) + if mode & 8: #>>>>> all data for different transfer function - for ext,amp,minFrq,maxFrq,tSec in (('a', 5, 10, 250, 10),): - self.homed=False - for mot in motLst: - fn = os.path.join(self.baseDir, 'chirp_all_%d%s.npz' % (mot,ext)) - self.init_stage(fn) - self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=2,openLoop=False, file=fn) + #using closed loop with 1/w^2 lower amplitude + for ext,amp,minFrq,maxFrq,tSec,crpMd,mot in (('a', 800, 10, 250, 20, 2, 1), + ('a', 800, 10, 250, 20, 2, 2), + ('b', 5, 10, 220, 20, 1, 1), + ('b', 5, 10, 220, 20, 1, 2), + ): + fn = os.path.join(self.baseDir, 'chirp_all_%d%s.npz' % (mot,ext)) + self.init_stage(mot,fn) + plt.close('all') + self.custom_chirp(motor=mot, minFrq=minFrq, maxFrq=maxFrq, amp=amp, tSec=tSec, recType=2,mode=crpMd, file=fn) + self.homed&=~mot + plt.show(block=False) + save_figs(fn) - if os.path.isfile(fn): - f = np.load(fn) - data = f['data'] - meta = f['meta'].item() - meta['file'] = file - if len(meta['address']) == 4: - for xy in ((0, 1), (0, 3), (2, 3)): - self.bode_plot(data, xy=xy, mode=25, **meta) - - if mode&8: #plot the full bode recording + if mode&16: #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&16: #plot the full bode recording with an approximation model + if mode&32: #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&32: # plot all raw acquired data files + if mode&64: # plot all raw acquired data files # display bode plots import glob for fn in glob.glob(os.path.join(self.baseDir,'*.npz')): + print(fn) fh = np.load(fn) meta = fh['meta'].item() data = fh['data'] - self.bode_plot(data, mode=25, **meta) + plt.close('all') + self.bode_plot(data, mode=25, kwargs=meta) + plt.show(block=False) + save_figs(fn) - if mode&64: #generater code + if mode&128: #generater code #before this can be done, the observer controller has to be designed with matlab: #s.a.ESB_MX/matlab/Readme.md #clear; @@ -487,6 +505,18 @@ EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid) print('done') plt.show() +def save_figs(fn): + figures = [manager.canvas.figure + for manager in mpl._pylab_helpers.Gcf.get_all_fig_managers()] + #print(figures) + fnBase=fn.rsplit('.')[0] + (a,b)=os.path.split(fnBase) + fnBase=os.path.join(a,'img',b) + for i, figure in enumerate(figures): + #figure.savefig('figure%d.png' % i) + fn=fnBase+'%d.png' % i + figure.savefig(fn) + #figure.savefig(fn.rsplit('.')[0]+'%d.eps' % i) def bode(mdl): diff --git a/src/triggerSync/triggerSync.layout b/src/triggerSync/triggerSync.layout index 3d3f646..ff67cdb 100644 --- a/src/triggerSync/triggerSync.layout +++ b/src/triggerSync/triggerSync.layout @@ -4,7 +4,7 @@ - +