update gui and triggering: speed sync works!
This commit is contained in:
@@ -1167,6 +1167,10 @@ adapt speed
|
|||||||
|
|
||||||
make longer acquisition time by enhancing the gather server
|
make longer acquisition time by enhancing the gather server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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()'
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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__':
|
||||||
|
|||||||
@@ -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+')']}
|
||||||
|
|||||||
Reference in New Issue
Block a user