update gui and triggering: speed sync works!

This commit is contained in:
2018-11-22 12:32:43 +01:00
parent 2e534f306e
commit e832b40124
7 changed files with 183 additions and 113 deletions

View File

@@ -1167,6 +1167,10 @@ adapt speed
make longer acquisition time by enhancing the gather server make longer acquisition time by enhancing the gather server
``` ```

View File

@@ -38,7 +38,8 @@ class MotionBase:
def setup_sync(self, crdId=1, prgId=2, plcId=2, mode=0, **kwargs): def setup_sync(self, crdId=1, prgId=2, plcId=2, mode=0, **kwargs):
'''setup the timing synchronization for the motion program '''setup the timing synchronization for the motion program
mode=0 : no sync at all mode=0 : no sync at all
mode=1 : first sync test mode=1 : synchronize start
mode=2 : synchronize start and adapt motion speed
this function generates the code blocks: this function generates the code blocks:
self.sync_wait and self.sync_run self.sync_wait and self.sync_run
sync_wait can be put in the program to force a timing sync sync_wait can be put in the program to force a timing sync
@@ -51,45 +52,7 @@ class MotionBase:
pass pass
self.sync_run = '&{crdId}b{prgId}r'''.format(prgId=prgId, crdId=crdId) self.sync_run = '&{crdId}b{prgId}r'''.format(prgId=prgId, crdId=crdId)
elif mode == 1: elif mode in (1,2):
# changes the Timebase of coord system
# modifies the timebase to start/stop a running program
# this can also be used to adjust the execution speed
# the plc for now
# - waits untis <flag> is false
# - waits raising edge of <flag> and the sets DesTimeBase=ServoPeriod
# flag ='PowerBrick[0].GpioData[0].0.1==1'
flag = 'Gate3[1].Chan[0].UserFlag==0'
prg = '''close all buffers
disable plc {plcId}
open plc {plcId}
L0=Sys.PhaseCount
send 1"sync0 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L0
while({flag}){{}}
send 1"sync1 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L0
L1=Sys.PhaseCount
while(1)
{{
if({flag})
{{
PowerBrick[0].GpioData[0].16.1=1
Coord[{crdId}].DesTimeBase=Sys.ServoPeriod
send 1"sync2 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L1
break
}}
}}
disable plc {plcId}
close
'''.format(plcId=plcId, crdId=crdId, flag=flag)
comm=self.comm
if comm is not None:
gpascii=comm.gpascii
gpascii.send_block(prg)
self.sync_prg = 'Coord[{crdId}].DesTimeBase=0'.format(prgId=prgId, plcId=plcId, crdId=crdId)
self.sync_run = 'enable plc {plcId};&{crdId}b{prgId}r'''.format(prgId=prgId, plcId=plcId, crdId=crdId)
elif mode == 2:
# code block to insert in the program # code block to insert in the program
# - waits untis <flag> is false # - waits untis <flag> is false
# - waits raising edge of <flag> and the sets DesTimeBase=ServoPeriod # - waits raising edge of <flag> and the sets DesTimeBase=ServoPeriod
@@ -109,6 +72,76 @@ close
'''.format(plcId=plcId, crdId=crdId, flag0=flag0, flag1=flag1) '''.format(plcId=plcId, crdId=crdId, flag0=flag0, flag1=flag1)
self.sync_prg = prg self.sync_prg = prg
self.sync_run = '&{crdId}b{prgId}r'''.format(prgId=prgId, plcId=plcId, crdId=crdId) self.sync_run = '&{crdId}b{prgId}r'''.format(prgId=prgId, plcId=plcId, crdId=crdId)
if mode==2:
notFlag1 = 'Gate3[1].Chan[1].UserFlag!=0'
try:
prop=kwargs['prop'] #proportional value to adapt speed
except KeyError:
prop = 1E-4
try:
maxJitter = kwargs['maxJitter'] # proportional value to adapt speed
except KeyError:
maxJitter=100
prg='''close all buffers
disable plc {plcId}
open plc {plcId}
Coord[1].DesTimeBase=Sys.ServoPeriod //reset to 100% timebase
Coord[1].Q[0]=0 //set CryPos counter to 0
while({flag0}){{}} //wait Jungfrau start Trigger
while({flag1}){{}} //ESx detector trigger
L0=0 //CryPos counter
//L1 ServoCount event 1
//L2 jitter: neg:motion lags trigger,pos:motion leads trigger
while(L0>=0) //as long we are not at the last point
{{
L0=Coord[1].Q[0] //CryPos counter
while({flag1} && L0==Coord[1].Q[0]){{}} //wait for event
L1=Sys.ServoCount //a event happened
L2=1000
//send 1"event\\n"
if(L0==Coord[1].Q[0])
{{//it was a trigger
//send 1"trigger %d %d\\n",L0,L1
while(Sys.ServoCount<L1+{maxJitter}) //wait half a trigger period for event
{{
if(L0!=Coord[1].Q[0])
{{//event CryPos counter
L2=L1-Sys.ServoCount //jitter: neg:motion lags trigger
break
}}
}}
}}
else
{{//it was a CryPos counter
//send 1"CryPos%d %d\\n",L0,L1
while(Sys.ServoCount<L1+{maxJitter}) //wait half a trigger period for event
{{
if({notFlag1})
{{//event trigger
L2=Sys.ServoCount-L1 //jitter: pos:motion leads trigger
break
}}
}}
}}
if(L2!=1000)
{{
L3=Sys.ServoPeriod*(1-{prop}*L2)
//send 1"jitter %d timebase: %f\\n",L2,L3
Coord[1].DesTimeBase=L3
}}
}}
disable plc {plcId}
close
enable plc {plcId}
'''.format(plcId=plcId, crdId=crdId, flag0=flag0, flag1=flag1, notFlag1=notFlag1, prop=prop, maxJitter=maxJitter)
comm=self.comm
if comm is not None:
gpascii=comm.gpascii
gpascii.send_block(prg)
def run(self): def run(self):
'runs the code sync_run which has been generated with setup_sync()' 'runs the code sync_run which has been generated with setup_sync()'

View File

@@ -91,12 +91,12 @@ class MPLCanvasErr(FigureCanvas):
def OnBtnPress(self, event): def OnBtnPress(self, event):
"""on button press we will see if the mouse is over us and store some data""" """on button press we will see if the mouse is over us and store some data"""
print(dir(event.guiEvent)) #print(dir(event.guiEvent))
return return
def OnBtnRelease(self, event): def OnBtnRelease(self, event):
"""on release we reset the press data""" """on release we reset the press data"""
print(dir(event.guiEvent)) #print(dir(event.guiEvent))
#self.OnMouse(event) #self.OnMouse(event)
return return

View File

@@ -100,12 +100,12 @@ class MPLCanvasVelo(FigureCanvas):
def OnBtnPress(self, event): def OnBtnPress(self, event):
"""on button press we will see if the mouse is over us and store some data""" """on button press we will see if the mouse is over us and store some data"""
print(dir(event.guiEvent)) #print(dir(event.guiEvent))
return return
def OnBtnRelease(self, event): def OnBtnRelease(self, event):
"""on release we reset the press data""" """on release we reset the press data"""
print(dir(event.guiEvent)) #print(dir(event.guiEvent))
#self.OnMouse(event) #self.OnMouse(event)
return return

View File

@@ -46,34 +46,20 @@ class MPLCanvasImg(FigureCanvas):
self.fig=fig self.fig=fig
self.ax=ax self.ax=ax
def InitChild(self,pts,rec): def InitChild(self,doc):
fig=self.fig fig=self.fig
ax=self.ax ax=self.ax
pts=doc.fh['pts']
rec=doc.fh['rec']
idxTrigger=doc.idxTrigger
#res=rot.ActPos,x.ActPos,y.ActPos,rot.DesPos,x.DesPos,y.DesPos # idx=[]
#idx 0 1 2 3 4 5
#idx=np.ndarray(shape=len(pts),dtype=np.int32)
# for i in range(len(pts)): # for i in range(len(pts)):
# l=rec[:,(3,2)]-pts[i,:] # l=rec[:,(3,2)]-pts[i,:]
# l2=l[:,0]**2+l[:,1]**2 # l2=l[:,0]**2+l[:,1]**2
# idx[i]=np.argmin(l2) # idx.extend(np.where(l2<1)[0].tolist())
# recPts=rec[idx,:]
idx=[]
for i in range(len(pts)):
l=rec[:,(3,2)]-pts[i,:]
l2=l[:,0]**2+l[:,1]**2
idx.extend(np.where(l2<1)[0].tolist())
#print idx
recPts=rec[idx,:]
#f2 = plt.figure()
#a2 = f2.add_axes([0.075,0.075,0.85,0.85])
#a2.plot(rec[:,1],'r-',label='ptsDot') #,picker=5 default value
#a2.plot(rec[:,0],'g-',label='ptsDot') #,picker=5 default value
#a2.plot(rec[:,3],'r--',label='ptsDot') #,picker=5 default value
#a2.plot(rec[:,2],'g--',label='ptsDot') #,picker=5 default value
#plt.show()
hl=[] hl=[]
hl+=ax.plot(pts[:,0],pts[:,1],'r.',label='ptsDot') #,picker=5 default value hl+=ax.plot(pts[:,0],pts[:,1],'r.',label='ptsDot') #,picker=5 default value
@@ -86,7 +72,13 @@ class MPLCanvasImg(FigureCanvas):
hl+=ax.plot(rec[:, 3], rec[:, 2], 'b-',label='recDesPos') hl+=ax.plot(rec[:, 3], rec[:, 2], 'b-',label='recDesPos')
hl+=ax.plot(rec[:,1],rec[:,0],'g-',label='recActPos') hl+=ax.plot(rec[:,1],rec[:,0],'g-',label='recActPos')
hl+=ax.plot(recPts[:,1],recPts[:,0],'g.',label='recDot') #hl+=ax.plot(recPts[:,1],recPts[:,0],'g.',label='recDot')
hl+=ax.plot(rec[-1:,1],rec[-1:,0],'r.--',label='recNxt')
#hh=ax.plot(rec[idxTrigger,1],rec[idxTrigger,0],'rx',label='trig')
#hh[0].get_markeredgewidth();hh[0].get_markersize()
hl+=ax.plot(rec[idxTrigger,1],rec[idxTrigger,0],'rx',label='trig',markeredgewidth=1.,markersize=6.)
#hl+=ax.plot(recPts[:,1],recPts[:,0],'g.',label='recDot')
ax.xaxis.set_label_text('x-pos um') ax.xaxis.set_label_text('x-pos um')
ax.yaxis.set_label_text('y-pos um') ax.yaxis.set_label_text('y-pos um')
ax.axis('equal') ax.axis('equal')
@@ -149,7 +141,7 @@ class MPLCanvasImg(FigureCanvas):
def OnBtnPress(self, event): def OnBtnPress(self, event):
"""on button press we will see if the mouse is over us and store some data""" """on button press we will see if the mouse is over us and store some data"""
print(dir(event.guiEvent)) #print(dir(event.guiEvent))
return return
if event.inaxes == self.colBar.ax: if event.inaxes == self.colBar.ax:
#if event.guiEvent.LeftDClick()==True: #if event.guiEvent.LeftDClick()==True:
@@ -247,7 +239,7 @@ class MAxyPlotFrame(wx.Frame):
#wxAxCtrl.SetCallback(MAxyPlotFrame.OnSetView,wxAxCtrl) #wxAxCtrl.SetCallback(MAxyPlotFrame.OnSetView,wxAxCtrl)
#sizer.Add(wxAxCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5) #sizer.Add(wxAxCtrl.sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALL, border=5)
canvas.InitChild(doc.fh['pts'],doc.fh['rec']) canvas.InitChild(doc)
#self.Fit() #self.Fit()
self.Centre() self.Centre()
@@ -295,6 +287,7 @@ class MAxyPlotFrame(wx.Frame):
hl=canvas.hl hl=canvas.hl
hl[2].set_data(rec[:idx+1, 3], rec[:idx+1, 2]) hl[2].set_data(rec[:idx+1, 3], rec[:idx+1, 2])
hl[3].set_data(rec[:idx+1, 1], rec[:idx+1, 0]) hl[3].set_data(rec[:idx+1, 1], rec[:idx+1, 0])
hl[4].set_data(rec[idx:idx+10, 1], rec[idx:idx+10, 0])
#ax.draw_artist(hl[2]) #ax.draw_artist(hl[2])
x=ax.get_xlim();x=(x[1]-x[0])/2; x=ax.get_xlim();x=(x[1]-x[0])/2;
y=ax.get_ylim();y=(y[1]-y[0])/2; y=ax.get_ylim();y=(y[1]-y[0])/2;

View File

@@ -148,21 +148,22 @@ class MAMainFrame(wx.Frame):
l=rec[idx:idx+rng,(3,2)]-pts[i,:] l=rec[idx:idx+rng,(3,2)]-pts[i,:]
l2=l[:,0]**2+l[:,1]**2 l2=l[:,0]**2+l[:,1]**2
ofs=l2.argmin() ofs=l2.argmin()
print(l2[ofs]) #print(l2[ofs])
idx+=ofs idx+=ofs
idxInPos.append(idx) idxInPos.append(idx)
idx+=rng/2 idx+=rng/2
doc.idxInPos=idxInPos=np.array(idxInPos) doc.idxInPos=idxInPos=np.array(idxInPos)
#jitter=idxInPos-idxTrigger[:idxInPos.shape[0]]
self.SetStatusText('scaling of DesTimeBase: %f'%(float(idxInPos[-1])/idxTrigger[idxInPos.shape[0]-1]))
#self.PlotJitter()
self.wxTimeCtrl.slider.SetRange(0,lenRec-1) self.wxTimeCtrl.slider.SetRange(0,lenRec-1)
self.wxTimeCtrl.slider.SetPageSize(idxInPos[1]-idxInPos[0])
ts=fh['meta'].item()['timebase']
page=idxInPos[1]-idxInPos[0]
self.wxTimeCtrl.slider.SetPageSize(page)
self.wxPosCtrl.slider.SetRange(0,lenPts-1) self.wxPosCtrl.slider.SetRange(0,lenPts-1)
self.wxPosCtrl.slider.SetPageSize(10)
self.wxTrigCtrl.slider.SetRange(0,idxTrigger.shape[0]-1) self.wxTrigCtrl.slider.SetRange(0,idxTrigger.shape[0]-1)
self.wxTrigCtrl.slider.SetPageSize(10)
def CloseFile(self): def CloseFile(self):
#http://docs.wxwidgets.org/2.8/wx_windowdeletionoverview.html#windowdeletionoverview #http://docs.wxwidgets.org/2.8/wx_windowdeletionoverview.html#windowdeletionoverview
@@ -173,6 +174,26 @@ class MAMainFrame(wx.Frame):
except AttributeError as e: except AttributeError as e:
pass pass
def PlotJitter(self):
doc=self.doc
fh=doc.fh
idxInPos=doc.idxInPos
idxTrigger=doc.idxTrigger
#display the jitter of inPos->trigger
ts=fh['meta'].item()['timebase']
jitter=idxTrigger[:idxInPos.shape[0]]-idxInPos
import matplotlib.pyplot as plt # used for the colormaps
plt.figure('jitter inPos -> trigger: scaling of DesTimeBase: %f'%(float(idxInPos[-1])/idxTrigger[idxInPos.shape[0]-1]))
plt.plot(jitter*ts)
plt.ylabel('jitter in ms')
plt.ylabel('point idx')
plt.show()
def DispJitter(self,idxInPos,idxTrigger):
doc=self.doc
ts=doc.fh['meta'].item()['timebase']
self.SetStatusText("Jitter: %.2gms scaling: %.6g"%((idxTrigger-idxInPos)*ts,float(idxInPos)/idxTrigger))
def OnOpen(self, event): def OnOpen(self, event):
dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), '','numpy files (*.npz;*.npy)|*.npz;*.npy|all (*.*)|*.*', wx.OPEN|wx.FD_CHANGE_DIR) dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), '','numpy files (*.npz;*.npy)|*.npz;*.npy|all (*.*)|*.*', wx.OPEN|wx.FD_CHANGE_DIR)
if dlg.ShowModal() == wx.ID_OK: if dlg.ShowModal() == wx.ID_OK:
@@ -287,40 +308,43 @@ rec
pass pass
@staticmethod @staticmethod
def OnSetTime(usrData, value, msg): def OnSetTime(usrData, idxRec, msg):
'called when the time slider has been changed' 'called when the time slider has been changed'
#print('OnSetTime', usrData, value, msg) #print('OnSetTime', usrData, value, msg)
view=usrData.slider.Parent view=usrData.slider.Parent
doc=view.doc doc=view.doc
idx=np.argmin(abs(doc.idxInPos-value)) idxInPos=np.argmin(abs(doc.idxInPos-idxRec))
view.wxPosCtrl.SetValue(idx) view.wxPosCtrl.SetValue(idxInPos)
idx=np.argmin(abs(doc.idxTrigger-value)) idxTrigger=np.argmin(abs(doc.idxTrigger-idxRec))
view.wxTrigCtrl.SetValue(idx) view.wxTrigCtrl.SetValue(idxTrigger)
doc.Update(view,0,value) view.DispJitter(doc.idxInPos[idxInPos],doc.idxTrigger[idxTrigger])
doc.Update(view,0,idxRec)
@staticmethod @staticmethod
def OnSetIdxInPos(usrData, value, msg): def OnSetIdxInPos(usrData, idxInPos, msg):
'called when the idxInPos slider has been changed' 'called when the idxInPos slider has been changed'
#print('OnSetPosIdx', usrData, value, msg) #print('OnSetPosIdx', usrData, value, msg)
view = usrData.slider.Parent view = usrData.slider.Parent
doc = view.doc doc = view.doc
value=doc.idxInPos[value] idxRec=doc.idxInPos[idxInPos]
view.wxTimeCtrl.SetValue(value) view.wxTimeCtrl.SetValue(idxRec)
idx=np.argmin(abs(doc.idxTrigger-value)) idxTrigger=np.argmin(abs(doc.idxTrigger-idxRec))
view.wxTrigCtrl.SetValue(idx) view.wxTrigCtrl.SetValue(idxTrigger)
doc.Update(view, 0, value) view.DispJitter(doc.idxInPos[idxInPos],doc.idxTrigger[idxTrigger])
doc.Update(view, 0, idxRec)
@staticmethod @staticmethod
def OnSetIdxTrigger(usrData, value, msg): def OnSetIdxTrigger(usrData, idxTrigger, msg):
'called when the idxTrigger slider has been changed' 'called when the idxTrigger slider has been changed'
#print('OnSetIdxTrigger', usrData, value, msg) #print('OnSetIdxTrigger', usrData, value, msg)
view = usrData.slider.Parent view = usrData.slider.Parent
doc = view.doc doc = view.doc
value=doc.idxTrigger[value] idxRec=doc.idxTrigger[idxTrigger]
view.wxTimeCtrl.SetValue(value) view.wxTimeCtrl.SetValue(idxRec)
idx=np.argmin(abs(doc.idxInPos-value)) idxInPos=np.argmin(abs(doc.idxInPos-idxRec))
view.wxPosCtrl.SetValue(idx) view.wxPosCtrl.SetValue(idxInPos)
doc.Update(view, 0, value) view.DispJitter(doc.idxInPos[idxInPos],doc.idxTrigger[idxTrigger])
doc.Update(view, 0, idxRec)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -184,9 +184,14 @@ class ShapePath(MotionBase):
1. generates program <prgId> and saves to fnPrg 1. generates program <prgId> and saves to fnPrg
the type of generated program is defined by <mode> the type of generated program is defined by <mode>
2. runs the program on the deltatau 2. runs the program on the deltatau
mode=-1 jog a 10mm square
mode=0 linear motion
mode=1 pvt motion
mode=2 spline motion
kwargs: kwargs:
acq_per : acquire period: acquire data all acq_per servo loops (default=1)
pt2pt_time : time to move from one point to the next point pt2pt_time : time to move from one point to the next point
sync_frq : synchronization mark all n points
''' '''
prg=['close all buffers','open prog %d'%(prgId)] prg=['close all buffers','open prog %d'%(prgId)]
comm=self.comm comm=self.comm
@@ -229,6 +234,10 @@ class ShapePath(MotionBase):
cnt=kwargs['cnt'] #move path multiple times cnt=kwargs['cnt'] #move path multiple times
except KeyError: except KeyError:
cnt=1 cnt=1
try:
sync_frq=kwargs['sync_frq'] #synchronization mark all n points
except KeyError:
sync_frq=10
try: try:
pt=self.ptsCorr pt=self.ptsCorr
except AttributeError: except AttributeError:
@@ -259,7 +268,10 @@ class ShapePath(MotionBase):
prg.append('N100:') prg.append('N100:')
prg.append(' pvt%g abs'%pt2pt_time) #100ms to next position prg.append(' pvt%g abs'%pt2pt_time) #100ms to next position
for idx in range(1,pv.shape[0]): for idx in range(1,pv.shape[0]):
if sync_frq is not None and idx%sync_frq==0:
prg.append('Coord[1].Q[0]=%d'%(idx))
prg.append('X%g:%g Y%g:%g'%tuple(pv[idx,(0,2,1,3)])) prg.append('X%g:%g Y%g:%g'%tuple(pv[idx,(0,2,1,3)]))
prg.append('Coord[1].Q[0]=%d' % (idx))
prg.append('X%g Y%g' % tuple(pv[-1, (0,1)])) prg.append('X%g Y%g' % tuple(pv[-1, (0,1)]))
if cnt>1: if cnt>1:
prg.append('dwell 10') prg.append('dwell 10')
@@ -273,6 +285,8 @@ class ShapePath(MotionBase):
prg.append('}') prg.append('}')
else: else:
prg.append('dwell 1000') prg.append('dwell 1000')
if sync_frq is not None:
prg.append('Coord[1].Q[0]=-1')
prg.append('Gather.Enable=0') prg.append('Gather.Enable=0')
elif mode==2: #### spline motion elif mode==2: #### spline motion
try: try:
@@ -446,19 +460,21 @@ class ShapePath(MotionBase):
l=rec[idx:idx+rng,(3,2)]-pts[i,:] l=rec[idx:idx+rng,(3,2)]-pts[i,:]
l2=l[:,0]**2+l[:,1]**2 l2=l[:,0]**2+l[:,1]**2
ofs=l2.argmin() ofs=l2.argmin()
print(l2[ofs]) #print(l2[ofs])
idx+=ofs idx+=ofs
idxInPos.append(idx) idxInPos.append(idx)
idx+= rng/2 idx+= rng/2
idxInPos = np.array(idxInPos) idxInPos = np.array(idxInPos)
jitter=idxInPos-idxTrigger[:idxInPos.shape[0]] jitter=idxTrigger[:idxInPos.shape[0]]-idxInPos
fig = plt.figure('trigger jitter') fig = plt.figure('trigger jitter')
ax = fig.add_subplot(1, 1, 1) ax = fig.add_subplot(1, 1, 1)
hl = [] hl = []
hl += ax.plot(jitter*ts, 'b-',label='jitter') hl += ax.plot(jitter*ts, 'b-',label='jitter')
ax.xaxis.set_label_text('position idx') ax.xaxis.set_label_text('position idx')
ax.yaxis.set_label_text('jitter (ms)') ax.yaxis.set_label_text('jitter motion (ms)')
print('scaling of DesTimeBase: %f'%(float(idxInPos[-1])/idxTrigger[idxInPos.shape[0]-1]))
plt.show() plt.show()
@@ -623,8 +639,8 @@ if __name__=='__main__':
sp.setup_gather(acq_per=2) sp.setup_gather(acq_per=2)
#setup_sync(self, crdId=1, prgId=2, plcId=2, mode=0, **kwargs): #setup_sync(self, crdId=1, prgId=2, plcId=2, mode=0, **kwargs):
#sp.setup_sync() #no sync at all #sp.setup_sync() #no sync at all
#sp.setup_sync(mode=1) #sync with timing system (PLC) #sp.setup_sync(mode=1) #sync with timing system (PROG)
sp.setup_sync(mode=2) #sync with timing system (PROG) sp.setup_sync(mode=2) #sync with timing system and PLC to sync speed (PROG)
#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_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(width=1000,ofs=(-500,0));sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40,acq_per=1) #sp.gen_swissmx_points(width=1000,ofs=(-500,0));sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40,acq_per=1)
@@ -647,7 +663,7 @@ if __name__=='__main__':
sp.run() sp.run()
trigger(0.5) trigger(0.5)
sp.gather_upload(fnRec=fn+'.npz') sp.gather_upload(fnRec=fn+'.npz')
sp.plot_gather() sp.plot_gather(mode=8)
# cfg={"points": [[100,523],[635,632],[756,213]],"sequencer":[sort_points,move_trj+')']} # cfg={"points": [[100,523],[635,632],[756,213]],"sequencer":[sort_points,move_trj+')']}