adding Q1 for triggering status

This commit is contained in:
2018-11-29 15:56:05 +01:00
parent d16249d863
commit 38a8c8484b
6 changed files with 122 additions and 29 deletions

View File

@@ -1,26 +1,27 @@
#some further usefull PMAC commands:
# list pc , 10 //list program counter during motion exec
# buffer //list allocated buffers
#the rotary stuff only works from gpascii, not gpasciiCommander
#delete rotary
#define rotary 4096 //allocates mem
#open rotary //same as open prog 0
#
# X100 Y100
# X200 Y300
# X600 Y500
# adding lines alway are acknowledged with ACK,
# if not, it means that the buffer is full
# it will acknowlegde when there is again free space.
# close
# delete rotary
#!/usr/bin/env python
# *-----------------------------------------------------------------------*
# | |
# | Copyright (c) 2016 by Paul Scherrer Institute (http://www.psi.ch) |
# | |
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
# *-----------------------------------------------------------------------*
'''
Coord[1].Q[0] : sync points when using setup_sync(mode=2)
0: after setup_sync(mode=2) call
idx: index of position during run
-1: pvt motion is finished
Coord[1].Q[1] : sync trigger: when setup_sync(mode=1 or 2)
0: idle
1: waiting for trigger
2: running
#from other gpascii
#list rotary
#rotfree
#size
#b0s //start the rotary buffer in single step mode
Gather.Enable : 1: after .setup_gather() called
2: during data gathering
0: when gather finished
Gather.Samples : number af gathered data samples
'''
import os, sys
sys.path.insert(0,os.path.expanduser('~/Documents/prj/SwissFEL/PBTools/'))
@@ -63,10 +64,12 @@ class MotionBase:
prg = '''
//L0=Sys.PhaseCount
//send 1"sync0 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L0
Coord[1].Q[1]=1
while({flag0}){{}}
//send 1"sync1 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L0
//L1=Sys.PhaseCount
while({flag1}){{}}
Coord[1].Q[1]=2
//PowerBrick[0].GpioData[0].16.8=255
//send 1"sync2 %d:%d\\n",Sys.PhaseCount,Sys.PhaseCount-L1
'''.format(plcId=plcId, crdId=crdId, flag0=flag0, flag1=flag1)

View File

@@ -289,6 +289,75 @@ class MXTuning(Tuning):
EXPORT_SYMBOL(obsvr_servo_ctrl_{motid});'''.format(motid=motid)
return (hdr,prog)
def check_fast_stage(self,file='/tmp/gather.npz'):
if os.path.isfile(file):
f=np.load(file)
data=f['data']
meta=f['meta'].item()
meta['file']=file
else:
#self.init_stage();time sleep
phase=False
motor=2
gpascii = self.comm.gpascii
gt = self.gather
gt.set_phasemode(phase)
address=('Motor[2].ActPos','Motor[8].ActPos')
gt.set_address(*address)
gt.set_property(Period=1)
tSrv=gpascii.servo_period
tSrv=2E-4 # seconds
phOsv = gpascii.get_variable('sys.PhaseOverServoPeriod', float)
subs={'prgId':999,'mot':motor,'num':100,'phase':'Phase' if phase else ''}
#the servoloop is called 2 times per servo cycle ?!?
#don't know why, but this is the reason why the value L10 is incremented by 0.5
prog = '''
&1
open prog {prgId}
P1=Motor[{mot}].DesPos-Motor[{mot}].HomePos
Q2=10
Gather.{phase}Enable=2
Q1={num}
while (Q1>0)
{{
jog{mot}=(P1-1000)
dwell 10
jog{mot}=(P1)
dwell 10
Q1=Q1-1
}}
dwell 10
Gather.{phase}Enable=0
close
&1
b{prgId}r
'''.format(**subs)
gpascii.send_line(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()
meta={'motor':motor,'date':time.asctime(),'ts':tSrv if not phase else tSrv*phOsv,'address':address}
np.savez_compressed(file, data=data, meta=meta)
meta['file'] = file
tSrv=meta['ts']
t=tSrv*np.arange(data.shape[0])
data=data-data[0,:]
plt.plot(t,data[:,0],t,data[:,1])
plt.figure()
plt.plot(t,data[:,0]-data[:,1])
plt.show()
def bode(mdl):
w,mag,phase = signal.bode(mdl,1000)
f=w/(2*np.pi)
@@ -337,7 +406,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:
@@ -490,7 +559,8 @@ Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
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)
elif mode==10: # record stage x and probe encoder
tune.check_fast_stage()
print('done')
plt.show()
#------------------ Main Code ----------------------------------

View File

@@ -1070,7 +1070,8 @@ close
else:
prg.append(' dwell 1000')
if sync_frq is not None:
prg.append('Coord[1].Q[0]=-1')
prg.append(' Coord[1].Q[0]=-1')
prg.append(' Coord[1].Q[1]=0')
prg.append(' Gather.Enable=0')
prg.append('close')
#prg.append('&1\nb%dr\n'%prgId)

View File

@@ -113,14 +113,14 @@ class ShapePath(MotionBase):
pts=np.random.rand(n,2)*scale
self.points=pts
def gen_grid_points(self,w=10,h=10,pitch=100,rnd=.2):
def gen_grid_points(self,w=10,h=10,pitch=100,rnd=.2,ofs=(0,0)):
'generates points in a grid with a given pitch and a bit randomness'
np.random.seed(0)
xx,yy=np.meshgrid(range(w), range(h))
pts=np.array([xx.reshape(-1),yy.reshape(-1)],dtype=np.float).transpose()*pitch
if rnd != 0:
pts+=(np.random.rand(pts.shape[0],2)*(rnd*pitch))
pts[:,0]+=500
pts+=ofs
self.points=pts
def opt_pts(self,fn):
@@ -277,6 +277,7 @@ class ShapePath(MotionBase):
prg.append('dwell 1000')
if sync_frq is not None:
prg.append('Coord[1].Q[0]=-1')
prg.append('Coord[1].Q[1]=0')
prg.append('Gather.Enable=0')
elif mode==2: #### spline motion
try:
@@ -636,15 +637,21 @@ if __name__=='__main__':
#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_grid_points(w=30,h=30,pitch=50,rnd=.2);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
#sp.gen_grid_points(w=200,h=200,pitch=50,rnd=.2);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
#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_grid_points(w=30,h=30,pitch=50,rnd=0.2);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
#sp.gen_grid_points(w=30,h=30,pitch=50,rnd=0.2);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
#sp.gen_rand_points(n=400, scale=1000);sp.sort_points(xy);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10)
#sp.gen_swissmx_points(width=500,flipx=True,flipy=True,ofs=(-380,3980));sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40,acq_per=1)
#sp.gen_grid_points(w=20,h=20,pitch=20,rnd=0,ofs=(-464,1754));sp.sort_points(True);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
sp.gen_grid_points(w=20,h=20,pitch=20,rnd=0,ofs=(-160,3700));sp.sort_points(False);sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=40)
#>>>setup gather and sync<<<
#sp.setup_gather()
#sp.setup_sync()
@@ -653,6 +660,7 @@ if __name__=='__main__':
#sp.setup_motion(fnPrg=fn+'.prg',mode=1,pt2pt_time=10,acq_per=1)
#>>>run gather and plot trajectory<<<
#return
sp.run()
trigger(0.5)
sp.gather_upload(fnRec=fn+'.npz')