SFELPHOTON-1335:rework triggerSync
This commit is contained in:
124
Readme.md
124
Readme.md
@@ -10,4 +10,128 @@ This repository contains PowerBrick documents and tool to generate trajectories
|
|||||||
|
|
||||||
for more info about SwissMX read:
|
for more info about SwissMX read:
|
||||||
psigithub git@git.psi.ch:grp-sf_cristallina/SwissMX.git --> ~/Documents/prj/SwissFEL/apps/SwissMX/Readme.md
|
psigithub git@git.psi.ch:grp-sf_cristallina/SwissMX.git --> ~/Documents/prj/SwissFEL/apps/SwissMX/Readme.md
|
||||||
|
|
||||||
|
For more details about triggerSync read:
|
||||||
|
~/Documents/prj/SwissFEL/apps/PBSwissMX/src/triggerSync/Readme.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
motion/frame synchronization
|
||||||
|
----------------------------
|
||||||
|
```
|
||||||
|
s.a. ~/Documents/prj/SwissFEL/apps/PBSwissMX/src/triggerSync/Readme.md
|
||||||
|
|
||||||
|
Coord[1].Q[0] : sync points indicator: (at whick point is the motion program)
|
||||||
|
val: desc set in code
|
||||||
|
-3: waiting at start position motion code generated in MXMotion.py:setup_sync(mode=?)
|
||||||
|
-2: got start trigger triggerSync.c:trigsync_func(mode&1) else motion code generated in MXMotion.py:setup_sync(mode=?)
|
||||||
|
0: after MXMotion.py:setup_sync call triggerSync.c:trigsync_func(mode&1)
|
||||||
|
idx: index of position during run triggerSync.c:trigsync_func(mode&1)
|
||||||
|
-1: motion is finished MXMotion.py:setup_sync(mode=?)
|
||||||
|
|
||||||
|
Gather.Enable : mode of gathering data
|
||||||
|
1: prepared (calculate Gather.MaxLines) MotionBase.py:setup_gather()
|
||||||
|
2: finite motion code: during data gathering
|
||||||
|
0: disabled motion code: when gather finished
|
||||||
|
|
||||||
|
Gather.Samples : number af gathered data samples
|
||||||
|
|
||||||
|
MXMotion.py:setup_sync():
|
||||||
|
sync_mode : default=2
|
||||||
|
0 : no sync at all
|
||||||
|
1 : synchronize start
|
||||||
|
2 : synchronize start and adapt motion speed
|
||||||
|
|
||||||
|
sync_flag : default=0
|
||||||
|
bit 0=1 : simulated start trigger
|
||||||
|
bit 1=2 : simulated frame trigger
|
||||||
|
|
||||||
|
triggerSync.c mode:
|
||||||
|
bit0:1: sync mode
|
||||||
|
bit1:2: simulate start trigger
|
||||||
|
bit2:4: simulate frame trigger
|
||||||
|
bit3:8: verbose
|
||||||
|
|
||||||
|
Acquisition start event:
|
||||||
|
sim: Coord[1].Q[10]
|
||||||
|
EVR: Gate3[1].Chan[0].UserFlag == (gate3_1->Chan[0].Status&0x800) == FrontUnivOut4 -> Pulser0 -> (active Low, 5000us delay 0us) Map: 214
|
||||||
|
|
||||||
|
Frame event:
|
||||||
|
sim: Coord[1].Q[11]
|
||||||
|
EVR: Gate3[1].Chan[1].UserFlag == (gate3_1->Chan[1].Status&0x800) == FrontUnivOut5 -> Pulser1 -> (active Low, 5000us delay 750us) Map: 40
|
||||||
|
```
|
||||||
|
|
||||||
|
testing shapepath.py in different modes (tunneling)
|
||||||
|
---------------------------------------------------
|
||||||
|
```
|
||||||
|
zamofing_t@ganymede:~$
|
||||||
|
>>> kill previous tunnels 127.0.0.1:100??
|
||||||
|
ps -f `lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | awk '{print $2}'`
|
||||||
|
kill `lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | awk '{print $2}'`
|
||||||
|
#lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | tee /tmp/0.log | awk '{print $2}' | tee /tmp/1.log && grep -n '' /tmp/*.log
|
||||||
|
|
||||||
|
>>> open cameras in chrome
|
||||||
|
ssh -L 10010:cristallina-cam-top:80 saresc-vcons-01 'uname -a'
|
||||||
|
google-chrome --app-url 127.0.0.1:10010
|
||||||
|
google-chrome --app-url http://cristallina-cam-north.psi.ch/camera/index.html#/video
|
||||||
|
|
||||||
|
|
||||||
|
>>> prepare debug environment
|
||||||
|
cmdt.py -p EXPMX -tpb # select SAR-CPPM-EXPMX1
|
||||||
|
|
||||||
|
>>> prepare shapepath and ssh tunneling
|
||||||
|
cd ~/Documents/prj/SwissFEL/apps/PBSwissMX/python/
|
||||||
|
subl shapepath.py
|
||||||
|
./shapepath.py -h
|
||||||
|
|
||||||
|
PPMAC=SAR-CPPM-EXPMX1
|
||||||
|
ssh -L 10001:localhost:22 root@$PPMAC 'uname -a'
|
||||||
|
ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a'
|
||||||
|
|
||||||
|
gather_server triggerSync are copied with sftp. This does not work with tunneling:
|
||||||
|
gather_server: ~/Documents/prj/SwissFEL/PBTools/build/lib/pbtools/misc/pp_comm.py:889
|
||||||
|
triggerSync: ~/Documents/prj/SwissFEL/apps/PBSwissMX/python/MXMotion.py:122
|
||||||
|
|
||||||
|
rsync -vai ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/
|
||||||
|
rsync -vai ~/Documents/prj/SwissFEL/apps/PBSwissMX/src/triggerSync/triggerSync root@$PPMAC:/tmp/
|
||||||
|
|
||||||
|
gather_server needs to be started explicitly in tunneling:
|
||||||
|
ssh root@$PPMAC
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server
|
||||||
|
|
||||||
|
triggerSync is started if required at each acquisition and exits when done.
|
||||||
|
|
||||||
|
mode:
|
||||||
|
0 unused
|
||||||
|
1 pvt motion
|
||||||
|
2 unused
|
||||||
|
3 pvt motion using inverse fft velocity
|
||||||
|
4 pvt motion short code using grid parameters
|
||||||
|
5 pvt motion short code using grid parameters. Instead of continous motion it moves and waits as give in the parameter time
|
||||||
|
|
||||||
|
sync:
|
||||||
|
0 real start and frame trigger with sync
|
||||||
|
1 direct start
|
||||||
|
2 simulated start and frame trigger no sync
|
||||||
|
3 simulated start and frame trigger with sync
|
||||||
|
4 simulated start real frame trigger no sync
|
||||||
|
5 simulated start real frame trigger with sync
|
||||||
|
|
||||||
|
|
||||||
|
# set start EVT to value 0 (=Force Hi)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 9
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s0 # works
|
||||||
|
# set start EVT to value 1 (=Force Lo)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 8
|
||||||
|
# reset EVT default value (Pulser 0)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-SP 0
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s1 # works
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s2 # works
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s3 # works
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s4 # works
|
||||||
|
./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s5 # works
|
||||||
|
|
||||||
|
Debugging were the coordinate program counter is:
|
||||||
|
&1 list pc,10
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -45,16 +45,17 @@ class MotionBase:
|
|||||||
self.meta.update(kwargs)
|
self.meta.update(kwargs)
|
||||||
|
|
||||||
def setup_sync(self, crdId=1, prgId=2,verbose=False, timeOfs=0.,timeCor=0.):
|
def setup_sync(self, crdId=1, prgId=2,verbose=False, timeOfs=0.,timeCor=0.):
|
||||||
'''setup the timing synchronization for the motion program
|
'''setup the timing synchronization code snipplets for the motion program
|
||||||
kwargs:
|
- sync_run: command to start the motion program
|
||||||
|
- sync_prg: code snipplet at top of the motion program used for synchronization if required
|
||||||
|
- sync_cmd: Deltatau command to excutable for synchronization if required
|
||||||
|
starts the triggerSync on the Deltatau if required
|
||||||
|
|
||||||
|
args in self.meta:
|
||||||
sync_mode : default=2
|
sync_mode : default=2
|
||||||
0 : no sync at all
|
0 : no sync at all
|
||||||
1 : synchronize start
|
1 : synchronize start
|
||||||
2 : synchronize start and adapt motion speed
|
2 : synchronize start and adapt motion speed
|
||||||
this function generates the code blocks:
|
|
||||||
self.sync_wait and self.sync_run
|
|
||||||
sync_wait can be put in the program to force a timing sync
|
|
||||||
sync_run are the commands to run the whole program
|
|
||||||
|
|
||||||
sync_flag : default=0
|
sync_flag : default=0
|
||||||
bit 0=1 : simulated start trigger
|
bit 0=1 : simulated start trigger
|
||||||
@@ -63,7 +64,7 @@ class MotionBase:
|
|||||||
1 : simulated start and real frame trigger
|
1 : simulated start and real frame trigger
|
||||||
2 : real start and simulated frame trigger
|
2 : real start and simulated frame trigger
|
||||||
3 : simulated start and frame trigger
|
3 : simulated start and frame trigger
|
||||||
fel_per : FEL-period: time FEL-pulse to FEL-pulse in ms (needed for sync code)
|
fel_per : FEL-period: time FEL-pulse to FEL-pulse in ms (needed for triggerSync executable)
|
||||||
'''
|
'''
|
||||||
sync_mode=self.meta['sync_mode']
|
sync_mode=self.meta['sync_mode']
|
||||||
sync_flag=self.meta['sync_flag']
|
sync_flag=self.meta['sync_flag']
|
||||||
@@ -74,62 +75,68 @@ class MotionBase:
|
|||||||
_log.info({0: 'real start trigger', 1: 'simulated start trigger'}[sync_flag&1])
|
_log.info({0: 'real start trigger', 1: 'simulated start trigger'}[sync_flag&1])
|
||||||
_log.info({0: 'real frame trigger', 2: 'simulated frame trigger'}[sync_flag&2])
|
_log.info({0: 'real frame trigger', 2: 'simulated frame trigger'}[sync_flag&2])
|
||||||
|
|
||||||
self.sync_run = '&{crdId}b{prgId}r'''.format(prgId=prgId, crdId=crdId)
|
self.sync_run = f'&{crdId}b{prgId}r'
|
||||||
|
|
||||||
if sync_mode==0:
|
if sync_mode==0:
|
||||||
try:
|
try:
|
||||||
del self.sync_prg
|
del self.sync_prg
|
||||||
|
del self.sync_cmd
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
else: # sync_mode 1,2
|
||||||
elif sync_mode in(1,2):
|
|
||||||
#frequence jitter 50Hz Swissgrid:
|
#frequence jitter 50Hz Swissgrid:
|
||||||
#https://www.swissgrid.ch/de/home/operation/grid-data/current-data.html#
|
#https://www.swissgrid.ch/de/home/operation/grid-data/current-data.html#
|
||||||
flag0='Coord[{crdId}].Q[10]'.format(crdId=crdId) if sync_flag&1 else 'Gate3[1].Chan[0].UserFlag'
|
|
||||||
flag1='Coord[{crdId}].Q[11]'.format(crdId=crdId) if sync_flag&2 else 'Gate3[1].Chan[1].UserFlag'
|
# Gather.Enable=2 is done in the triggerSync executable
|
||||||
if sync_mode==1:
|
# triggerSync waits for Coord[1].Q[0]=-3 and then sets Coord[1].DesTimeBase to continue motion
|
||||||
prg = f'\n{flag0}=0\n' if sync_flag&1 else ''
|
# triggerSync set Coord[1].DesTimeBase to the servoPeriod to match last interval of frame triggers if sync_mode==1
|
||||||
prg += f'''
|
# triggerSync modifies Coord[1].DesTimeBase if sync_mode==2
|
||||||
Coord[{crdId}].Q[0]=-2 // motion program started and armed
|
|
||||||
|
if sync_mode==1: # triggerSync:trigsync_func not called, therefore need to make own start synchronization
|
||||||
|
flag0=f'Coord[{crdId}].Q[10]' if sync_flag&1 else 'Gate3[1].Chan[0].UserFlag'
|
||||||
|
flag1=f'Coord[{crdId}].Q[11]' if sync_flag&2 else 'Gate3[1].Chan[1].UserFlag'
|
||||||
|
prg= f'''
|
||||||
Coord[{crdId}].TimeBaseSlew=1 //1E-4 is default
|
Coord[{crdId}].TimeBaseSlew=1 //1E-4 is default
|
||||||
Coord[{crdId}].DesTimeBase=0
|
Coord[{crdId}].DesTimeBase=0
|
||||||
|
Coord[{crdId}].Q[0]=-3 // motion program waiting at start position
|
||||||
|
Coord[{crdId}].Q[0]=-2 // motion program started and armed
|
||||||
while({flag0}==0){{}}
|
while({flag0}==0){{}}
|
||||||
Coord[{crdId}].Q[0]=-1
|
Coord[{crdId}].Q[0]=-1
|
||||||
Gather.Enable=2
|
Gather.Enable=2
|
||||||
while({flag1}==0){{}}
|
while({flag1}==0){{}}
|
||||||
Coord[1].DesTimeBase=Sys.ServoPeriod
|
Coord[1].DesTimeBase=Sys.ServoPeriod
|
||||||
|
Coord[{crdId}].Q[0]=0 //
|
||||||
'''
|
'''
|
||||||
else:
|
else: #sync_mode==2: triggerSync:trigsync_func called
|
||||||
prg = f'''
|
prg = f'''
|
||||||
//Gather.Enable=2 is done in the triggerSync program
|
Coord[{crdId}].TimeBaseSlew=1 //1E-4 is default
|
||||||
Coord[1].TimeBaseSlew=1 //1E-4 is default
|
Coord[{crdId}].DesTimeBase=0
|
||||||
Coord[1].DesTimeBase=0
|
Coord[{crdId}].Q[0]=-3 //motion program waiting at start position
|
||||||
Coord[1].Q[0]=-3 //motion program started and waits. Arm(-2) is done in triggerSync program
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
self.sync_prg = prg
|
self.sync_prg = prg
|
||||||
#download and start triggerSync code
|
#download and start triggerSync code
|
||||||
comm=self.comm
|
comm=self.comm
|
||||||
if comm is None:
|
if comm is None:
|
||||||
_log.info('simulated');return
|
_log.info('simulated');return
|
||||||
|
|
||||||
mode=0 #mode to pass to triggerSync program
|
mode=0 #for triggerSync
|
||||||
|
# mode: (triggerSync executable)
|
||||||
|
# bit0:1: sync mode
|
||||||
|
# bit1:2: simulate start trigger
|
||||||
|
# bit2:4: simulate frame trigger
|
||||||
|
# bit3:8: verbose
|
||||||
if sync_mode==2:mode+=1 #synchronize
|
if sync_mode==2:mode+=1 #synchronize
|
||||||
mode+=sync_flag*2 #simulated or real triggers
|
mode+=sync_flag*2 #simulated or real triggers
|
||||||
if verbose: mode+=8
|
if verbose: mode+=8
|
||||||
if sync_mode==2 or mode&4:
|
sftp = comm.sftp
|
||||||
sftp = comm.sftp
|
dst = '/tmp/triggerSync'
|
||||||
dst = '/tmp/triggerSync'
|
src = os.path.abspath(os.path.join(os.path.dirname(__file__), 'triggerSync'))
|
||||||
src = os.path.abspath(os.path.join(os.path.dirname(__file__), 'triggerSync'))
|
sftp.put(src, dst)
|
||||||
sftp.put(src, dst)
|
sftp.chmod(dst, 0o755)
|
||||||
sftp.chmod(dst, 0o755)
|
cmd = 'LD_LIBRARY_PATH=/opt/ppmac/libppmac/ ' + dst
|
||||||
cmd = 'LD_LIBRARY_PATH=/opt/ppmac/libppmac/ ' + dst
|
#cmd+=' %d %g %g %g'%(mode,pt2pt_time,timeOfs,timeCor)
|
||||||
#cmd+=' %d %g %g %g'%(mode,pt2pt_time,timeOfs,timeCor)
|
cmd+=' %d %g %g'%(mode,fel_per+timeCor,timeOfs)
|
||||||
cmd+=' %d %g %g'%(mode,fel_per+timeCor,timeOfs)
|
self.sync_cmd = cmd
|
||||||
self.cmdSync = cmd
|
|
||||||
print ('starting '+cmd)
|
|
||||||
self.syncShell=comm.shell_channel(cmd)
|
|
||||||
#syncChan=sc=comm._client.exec_command(cmd) #this is less simple to communicate with
|
|
||||||
|
|
||||||
def homing(self):
|
def homing(self):
|
||||||
if self.comm is None: return
|
if self.comm is None: return
|
||||||
@@ -143,21 +150,30 @@ Coord[1].Q[0]=-3 //motion program started and waits. Arm(-2) is done in triggerS
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
if gpascii.get_variable('Motor[1].HomeComplete', int)==1:
|
if gpascii.get_variable('Motor[1].HomeComplete', int)==1:
|
||||||
break
|
break
|
||||||
print('homing done')
|
_log.info('homing done')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run(self, crdId=1):
|
def run(self, crdId=1):
|
||||||
'runs the code sync_run which has been generated with setup_sync()'
|
'runs the code sync_run which has been generated with setup_sync()'
|
||||||
|
try:
|
||||||
|
run=self.sync_run
|
||||||
|
except AttributeError:
|
||||||
|
raise 'Need to call setup sync before'
|
||||||
|
|
||||||
comm = self.comm
|
comm = self.comm
|
||||||
if comm is None: return
|
if comm is None: return
|
||||||
gpascii = comm.gpascii
|
gpascii = comm.gpascii
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd=self.sync_run
|
cmd=self.sync_cmd
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise 'Need to call setup sync before'
|
pass
|
||||||
gpascii.send_block(cmd)
|
else:
|
||||||
|
if gpascii.get_variable('Gather.Enable', type_=int)==0:
|
||||||
|
raise 'Gather.Enable must be !=0'
|
||||||
|
_log.info('starting '+cmd)
|
||||||
|
self.sync_shell=comm.shell_channel(cmd)
|
||||||
|
#syncChan=sc=comm._client.exec_command(cmd) #this is less simple to communicate with
|
||||||
|
gpascii.send_block(run)
|
||||||
|
|
||||||
def wait_armed(self,crdId=1): #wait until motors are at first position
|
def wait_armed(self,crdId=1): #wait until motors are at first position
|
||||||
sm=self.meta['sync_mode']
|
sm=self.meta['sync_mode']
|
||||||
@@ -168,7 +184,7 @@ Coord[1].Q[0]=-3 //motion program started and waits. Arm(-2) is done in triggerS
|
|||||||
if comm is None: return
|
if comm is None: return
|
||||||
gpascii = comm.gpascii
|
gpascii = comm.gpascii
|
||||||
while (True):
|
while (True):
|
||||||
val = gpascii.get_variable('Coord[{crdId}].Q[0]'.format(crdId=crdId), type_=int)
|
val = gpascii.get_variable(f'Coord[{crdId}].Q[0]', type_=int)
|
||||||
if val==-2:
|
if val==-2:
|
||||||
break
|
break
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
@@ -196,9 +212,9 @@ Coord[1].Q[0]=-3 //motion program started and waits. Arm(-2) is done in triggerS
|
|||||||
if comm is None: return
|
if comm is None: return
|
||||||
gpascii = comm.gpascii
|
gpascii = comm.gpascii
|
||||||
gpascii.send_block('Coord[1].Q[10]=1')
|
gpascii.send_block('Coord[1].Q[10]=1')
|
||||||
else:
|
#else:
|
||||||
import CaChannel
|
# import CaChannel
|
||||||
pvTrigger = CaChannel.CaChannel('SAR-CVME-TIFALL5-EVG0:SoftEvt-EvtCode-SP.VAL')
|
# pvTrigger = CaChannel.CaChannel('SAR-CVME-TIFALL5-EVG0:SoftEvt-EvtCode-SP.VAL')
|
||||||
pvTrigger.searchw()
|
# pvTrigger.searchw()
|
||||||
pvTrigger.putw(254)
|
# pvTrigger.putw(254) # ??? does this send a trigger or just set the event code ???
|
||||||
|
|
||||||
|
|||||||
@@ -17,19 +17,26 @@ verbose bits:
|
|||||||
0x20 plot pvt trajectory (before motion)
|
0x20 plot pvt trajectory (before motion)
|
||||||
0x40 print sync details
|
0x40 print sync details
|
||||||
|
|
||||||
|
mode:
|
||||||
|
0 unused
|
||||||
|
1 pvt motion
|
||||||
|
2 unused
|
||||||
|
3 pvt motion using inverse fft velocity
|
||||||
|
4 pvt motion short code using grid parameters
|
||||||
|
5 pvt motion short code using grid parameters. Instead of continous motion it moves and waits as give in the parameter time
|
||||||
|
|
||||||
if mode&1:
|
sync:
|
||||||
self.plot_trajectory()
|
0 real start and frame trigger with sync
|
||||||
|
1 direct start
|
||||||
|
2 simulated start and frame trigger no sync
|
||||||
|
3 simulated start and frame trigger with sync
|
||||||
|
4 simulated start real frame trigger no sync
|
||||||
|
5 simulated start real frame trigger with sync
|
||||||
|
|
||||||
if mode&2:
|
if motion not possible check the DesTimeBase:
|
||||||
self.plot_pos_error()
|
Coord[1].DesTimeBase
|
||||||
|
> Coord[1].DesTimeBase=0 // this is blocked
|
||||||
if mode&4:
|
Coord[1].DesTimeBase=Sys.ServoPeriod // to unblock
|
||||||
self.plot_bode(xy=(3,1),mode=31,db=True) # FX
|
|
||||||
self.plot_bode(xy=(2,0),mode=31,db=True) # FY
|
|
||||||
|
|
||||||
if mode&8:
|
|
||||||
self.plot_trigger_jitter()
|
|
||||||
|
|
||||||
|
|
||||||
Gather motor order
|
Gather motor order
|
||||||
@@ -71,7 +78,7 @@ if __name__=="__main__":
|
|||||||
sys.path.insert(0, os.path.abspath(os.path.join(base,'../../../PBTools')))
|
sys.path.insert(0, os.path.abspath(os.path.join(base,'../../../PBTools')))
|
||||||
else:
|
else:
|
||||||
base=os.path.abspath(os.path.dirname(__file__))
|
base=os.path.abspath(os.path.dirname(__file__))
|
||||||
sys.path.insert(0, os.path.join(base,'PBTools'))
|
sys.path.insert(0, os.path.abspath(os.path.join(base,'../../PBTools')))
|
||||||
sys.path.insert(0, os.path.join(base,'PBSwissMX/python'))
|
sys.path.insert(0, os.path.join(base,'PBSwissMX/python'))
|
||||||
#_log.info(sys.path)
|
#_log.info(sys.path)
|
||||||
|
|
||||||
@@ -652,7 +659,7 @@ class ShapePath(MotionBase):
|
|||||||
address=("Motor[1].ActPos","Motor[2].ActPos","Motor[1].DesPos","Motor[2].DesPos","Gate3[1].Chan[1].UserFlag")
|
address=("Motor[1].ActPos","Motor[2].ActPos","Motor[1].DesPos","Motor[2].DesPos","Gate3[1].Chan[1].UserFlag")
|
||||||
#address=("Motor[1].ActPos","Motor[2].ActPos","Motor[1].DesPos","Motor[2].DesPos","Gate3[1].Chan[1].UserFlag","EncTable[20].PrevEnc")
|
#address=("Motor[1].ActPos","Motor[2].ActPos","Motor[1].DesPos","Motor[2].DesPos","Gate3[1].Chan[1].UserFlag","EncTable[20].PrevEnc")
|
||||||
#address=("Motor[1].ActPos", "Motor[2].ActPos", "Motor[1].DesPos", "Motor[2].DesPos", "Gate3[1].Chan[1].UserFlag","Coord[1].TimeBase","EncTable[20].DeltaPos")
|
#address=("Motor[1].ActPos", "Motor[2].ActPos", "Motor[1].DesPos", "Motor[2].DesPos", "Gate3[1].Chan[1].UserFlag","Coord[1].TimeBase","EncTable[20].DeltaPos")
|
||||||
gtMaxLn=gt.set_address(*address)
|
gtMaxLn=gt.set_address(*address) # sets also Gather.Enable=1
|
||||||
if acq_per is None:
|
if acq_per is None:
|
||||||
if numPts is None:
|
if numPts is None:
|
||||||
numPts=self.mot_pts.shape[0]
|
numPts=self.mot_pts.shape[0]
|
||||||
@@ -1016,11 +1023,11 @@ f(P100>0)
|
|||||||
self.rec=rec=gt.upload()
|
self.rec=rec=gt.upload()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
syncShell=self.syncShell
|
sync_shell=self.sync_shell
|
||||||
except AttributeError: pass
|
except AttributeError: pass
|
||||||
else:
|
else:
|
||||||
print(syncShell.sync())
|
print(sync_shell.sync())
|
||||||
del self.syncShell
|
del self.sync_shell
|
||||||
|
|
||||||
pts=self.mot_pts
|
pts=self.mot_pts
|
||||||
|
|
||||||
@@ -1066,23 +1073,30 @@ if __name__=='__main__':
|
|||||||
comm=gather=None
|
comm=gather=None
|
||||||
|
|
||||||
gp=GenPath()
|
gp=GenPath()
|
||||||
#real start and frame trigger with sync
|
|
||||||
#sp = ShapePath(comm, gather, args.verbose)
|
|
||||||
|
|
||||||
# direct start
|
sync=args.sync
|
||||||
#sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=0)
|
mode=args.mode
|
||||||
|
|
||||||
#simulated start and frame trigger no sync
|
if sync==0:
|
||||||
#sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=1,sync_flag=3)
|
#real start and frame trigger with sync
|
||||||
|
sp = ShapePath(comm, gather, args.verbose)
|
||||||
#simulated start and frame trigger with sync
|
elif sync==1:
|
||||||
#sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=2,sync_flag=3)
|
# direct start
|
||||||
|
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=0)
|
||||||
#simulated start real frame trigger no sync
|
elif sync==2:
|
||||||
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=1,sync_flag=1)
|
#simulated start and frame trigger no sync
|
||||||
|
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=1,sync_flag=3)
|
||||||
#simulated start real frame trigger with sync
|
elif sync==3:
|
||||||
#sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=2,sync_flag=1)
|
#simulated start and frame trigger with sync
|
||||||
|
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=2,sync_flag=3)
|
||||||
|
elif sync==4:
|
||||||
|
#simulated start real frame trigger no sync
|
||||||
|
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=1,sync_flag=1)
|
||||||
|
elif sync==5:
|
||||||
|
#simulated start real frame trigger with sync
|
||||||
|
sp = ShapePath(comm, gather, args.verbose,fel_per=10,sync_mode=2,sync_flag=1)
|
||||||
|
else:
|
||||||
|
raise(ValueError(f'unsupported sync:{sync}'))
|
||||||
|
|
||||||
fn='/tmp/shapepath'
|
fn='/tmp/shapepath'
|
||||||
#fn =unique_filename('ShapePathAnalyser/records/19_01_24/spiral')
|
#fn =unique_filename('ShapePathAnalyser/records/19_01_24/spiral')
|
||||||
@@ -1130,7 +1144,8 @@ if __name__=='__main__':
|
|||||||
gp.grid(w=10,h=15,pitch=120,rnd=0,ofs=(-1000,-1200));gp.sort(grp_sz=15)
|
gp.grid(w=10,h=15,pitch=120,rnd=0,ofs=(-1000,-1200));gp.sort(grp_sz=15)
|
||||||
|
|
||||||
# for motion mode 4,5
|
# for motion mode 4,5
|
||||||
grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(10, 15)}
|
#grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(10, 15)}
|
||||||
|
grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(20, 25)}
|
||||||
|
|
||||||
# mode:0 unused
|
# mode:0 unused
|
||||||
# mode:1 pvt motion
|
# mode:1 pvt motion
|
||||||
@@ -1139,7 +1154,6 @@ if __name__=='__main__':
|
|||||||
# mode:4 pvt motion short code using grid parameters
|
# mode:4 pvt motion short code using grid parameters
|
||||||
# mode:5 pvt motion short code using grid parameters. Instead of continous motion it moves and waits as give in the parameter time
|
# mode:5 pvt motion short code using grid parameters. Instead of continous motion it moves and waits as give in the parameter time
|
||||||
#mode=3;scale=0
|
#mode=3;scale=0
|
||||||
mode=5
|
|
||||||
if mode==5:
|
if mode==5:
|
||||||
tmove=20 # time to move in ms
|
tmove=20 # time to move in ms
|
||||||
twait=130# time to move in ms
|
twait=130# time to move in ms
|
||||||
@@ -1160,6 +1174,8 @@ if __name__=='__main__':
|
|||||||
sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=4,grid=grid)
|
sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=4,grid=grid)
|
||||||
elif mode==5:
|
elif mode==5:
|
||||||
sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=5,tmove=tmove, twait=twait, grid=grid)
|
sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=5,tmove=tmove, twait=twait, grid=grid)
|
||||||
|
else:
|
||||||
|
raise(ValueError(f'unsupported mode:{mode}'))
|
||||||
|
|
||||||
if sp.comm:
|
if sp.comm:
|
||||||
sp.setup_gather()
|
sp.setup_gather()
|
||||||
@@ -1169,7 +1185,7 @@ if __name__=='__main__':
|
|||||||
_log.info('wait_armed')
|
_log.info('wait_armed')
|
||||||
sp.wait_armed() # wait until motors are at first position
|
sp.wait_armed() # wait until motors are at first position
|
||||||
_log.info('trigger')
|
_log.info('trigger')
|
||||||
sp.trigger(0.5) #send a start trigger (if needed) ater given time
|
sp.trigger(0.5) #send a start trigger (if needed) after given time
|
||||||
_log.info('progress..')
|
_log.info('progress..')
|
||||||
if not comm is None:
|
if not comm is None:
|
||||||
while True:
|
while True:
|
||||||
@@ -1185,13 +1201,15 @@ if __name__=='__main__':
|
|||||||
def parse_args():
|
def parse_args():
|
||||||
'main command line interpreter function'
|
'main command line interpreter function'
|
||||||
(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' '
|
(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' '
|
||||||
exampleCmd=('-v15',
|
exampleCmd=('-v0xff',
|
||||||
'--host=SAR-CPPM-EXPMX1 -v 0x5d',
|
'--host=SAR-CPPM-EXPMX1 -v0x5d',
|
||||||
'--host=localhost:10001:10002 -v 0x59'
|
'--host=localhost:10001:10002 -v0x59',
|
||||||
|
'--host=SAR-CPPM-EXPMX1 -v0x5d -m5',
|
||||||
)
|
)
|
||||||
epilog=__doc__+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
|
epilog=__doc__+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
|
||||||
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
|
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
parser.add_argument("-m", "--mode", type=lambda x:int(x, 0), help="mode (see bitmasks) default=0x%(default)x", default=0xff)
|
parser.add_argument("-m", "--mode", type=lambda x:int(x, 0), help="mode default=0x%(default)x", default=4)
|
||||||
|
parser.add_argument("-s", "--sync", type=lambda x:int(x, 0), help="sync default=0x%(default)x", default=2)
|
||||||
parser.add_argument('-v', '--verbose', type=lambda x:int(x, 0), dest='verbose', help='verbosity bits (see below) default=0x%(default)x', default=0x00)
|
parser.add_argument('-v', '--verbose', type=lambda x:int(x, 0), dest='verbose', help='verbosity bits (see below) default=0x%(default)x', default=0x00)
|
||||||
parser.add_argument('--host', help='hostname', default=None)
|
parser.add_argument('--host', help='hostname', default=None)
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,110 @@
|
|||||||
Activate an user servoloop
|
triggerSync
|
||||||
--------------------------
|
===========
|
||||||
```
|
```
|
||||||
PBTools/pbtools/usr_servo_phase$ make
|
samples: root@:/opt/ppmac#
|
||||||
PBTools/pbtools/usr_servo_phase/usrServoSample$ make
|
/tmp/triggerSync 40 11 trigger all 40 ms, simulated start, use real frame triggers, verbose
|
||||||
scp userservo_util userphase_util usrServoSample/usralgo.ko root@MOTTEST-CPPM-CRM0573:/tmp
|
/tmp/triggerSync 40 14 trigger all 40 ms, simulated start and frame triggers, no sync, verbose
|
||||||
|
/tmp/triggerSync 40 15 trigger all 40 ms, simulated start and frame triggers, with sync, verbose
|
||||||
rmmod usralgo
|
/tmp/triggerSync 40 7 trigger all 40 ms, simulated start and frame triggers, with sync, minimal verbose
|
||||||
insmod /tmp/usralgo.ko
|
|
||||||
|
|
||||||
cat /proc/kallsyms | grep MyUserAlgoFunctionName (e.g. cat /proc/kallsyms | grep usr_servo_ctrl_2)
|
|
||||||
a10385ca r __kstrtab_usr_servo_ctrl_2 [usralgo]
|
|
||||||
a1038570 r __ksymtab_usr_servo_ctrl_2 [usralgo]
|
|
||||||
a103812c T usr_servo_ctrl_2 [usralgo]
|
|
||||||
|
|
||||||
UserAlgo.ServoCtrlAddr[1] = $a103812c
|
|
||||||
Motor[1].Ctrl =UserAlgo.ServoCtrlAddr[1].a
|
|
||||||
|
|
||||||
.. but this can not be set directly in gpascii.
|
|
||||||
|
|
||||||
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]
|
|
||||||
|
|
||||||
|
|
||||||
|
For real triggers, deltatau is using flags from the EVR-card:
|
||||||
|
|
||||||
|
#define SIMFLAG0 (pshm->Coord[1].Q[10])
|
||||||
|
#define SIMFLAG1 (pshm->Coord[1].Q[11])
|
||||||
|
|
||||||
|
//Power PMAC Software Reference Manual.pdf Gate3[i].Chan[j].Status -> page 919 UserFlag
|
||||||
|
#define FLAG0 (gate3_1->Chan[0].Status&0x800)
|
||||||
|
#define FLAG1 (gate3_1->Chan[1].Status&0x800)
|
||||||
|
|
||||||
|
|
||||||
|
work of triggerSync program:
|
||||||
|
- wait for [SIM]FLAG0 (arm trigger)
|
||||||
|
- once armed, each [SIM]FLAG1 trigger is a frame trigger.
|
||||||
|
|
||||||
|
SIMFLAG[0|1] are vairables Coord[1].Q[10] and Coord[1].Q[11]
|
||||||
|
|
||||||
|
the EVR flags are set in;
|
||||||
|
caqtdm -attach -macro SYS=SAR-EXPMX,DEVICE=EVR0,FF=PCIe G_EVR_main.ui
|
||||||
|
|
||||||
|
FLAG0 == Gate3[1].Chan[0].UserFlag == FrontUnivOut4 -> Pulser0 -> (active Low, 5000us delay 0us) Map: 214
|
||||||
|
FLAG1 == Gate3[1].Chan[1].UserFlag == FrontUnivOut5 -> Pulser1 -> (active Low, 5000us delay 750us) Map: 40
|
||||||
|
|
||||||
|
Pulser 0: event 214 is 'ESC multipurpose event. In this case used as: start motion'
|
||||||
|
Pulser 1: maps event 40 = 'ESA_detector 100 Hz' >>> should be 77='ESC detector'
|
||||||
|
|
||||||
|
event 214 is set with the CTA. For tests one can set manually
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 9 # Force High(0) -> arm event, before start motion
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 8 # Force Low(1) -> trigger motion
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-SP 0 # set back to Pulser 0 -> reset for CTA usage
|
||||||
|
|
||||||
|
This are values how they should be:
|
||||||
|
caget SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-RB SAR-EXPMX-EVR0:FrontUnivOut5-Src-Pulse-RB \
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Polarity-Sel SAR-EXPMX-EVR0:Pul0-Delay-RB SAR-EXPMX-EVR0:Pul0-Width-RB \
|
||||||
|
SAR-EXPMX-EVR0:Pul1-Polarity-Sel SAR-EXPMX-EVR0:Pul1-Delay-RB SAR-EXPMX-EVR0:Pul1-Width-RB \
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Evt-Trig0-SP SAR-EXPMX-EVR0:Pul1-Evt-Trig0-SP
|
||||||
|
|
||||||
|
SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-RB "Pulser 0"
|
||||||
|
SAR-EXPMX-EVR0:FrontUnivOut5-Src-Pulse-RB "Pulser 1"
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Polarity-Sel "Active Low"
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Delay-RB 0.000 us
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Width-RB 5000.000 us
|
||||||
|
SAR-EXPMX-EVR0:Pul1-Polarity-Sel "Active Low"
|
||||||
|
SAR-EXPMX-EVR0:Pul1-Delay-RB 750.000 us
|
||||||
|
SAR-EXPMX-EVR0:Pul1-Width-RB 5000.000 us
|
||||||
|
SAR-EXPMX-EVR0:Pul0-Evt-Trig0-SP 214
|
||||||
|
SAR-EXPMX-EVR0:Pul1-Evt-Trig0-SP 40
|
||||||
|
```
|
||||||
|
|
||||||
|
testing simulated start triggers
|
||||||
|
--------------------------------
|
||||||
|
```
|
||||||
|
Gather.Enable=1 // else triggerSync stops if value is 0
|
||||||
|
Coord[1].Q[0]=-3 // simulate motion ready
|
||||||
|
Coord[1].Q[10]=0 // turn off simulated start event
|
||||||
|
|
||||||
|
root@:/opt/ppmac#
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 14 10 0 # trigger all 10 ms, simulated start and frame triggers , no sync , verbose
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 15 10 0 # trigger all 10 ms, simulated start and frame triggers , with sync, verbose
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 11 10 0 # trigger all 10 ms, simulated start, real frame triggers , with sync, verbose
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 7 10 0 # trigger all 10 ms, simulated start and frame triggers , with sync, minimal verbose
|
||||||
|
|
||||||
|
....
|
||||||
|
Coord[1].Q[10]=1 # turn on simulated start event
|
||||||
|
.s.s.s.s.
|
||||||
|
Coord[1].Q[10]=0 # turn off simulated start event
|
||||||
|
....
|
||||||
|
Coord[1].Q[10]=1 # turn on simulated start event
|
||||||
|
.s.s.s.s.
|
||||||
|
Coord[1].Q[0]=0 # simulate ready at start position
|
||||||
|
.s.s.s.x.........
|
||||||
|
Gather.Enable=0 # end triggerSync
|
||||||
|
```
|
||||||
|
|
||||||
|
testing real start triggers
|
||||||
|
---------------------------
|
||||||
|
```
|
||||||
|
Gather.Enable=1 // else triggerSync stops if value is 0
|
||||||
|
Coord[1].Q[0]=0 // simulate motion not ready (!=-3)
|
||||||
|
|
||||||
|
caget SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-RB
|
||||||
|
->SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-RB "Pulser 0"
|
||||||
|
|
||||||
|
# set start EVT to value 0 (=Force Hi)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 9
|
||||||
|
|
||||||
|
root@:/opt/ppmac#
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 9 10 0 # trigger all 10 ms, real start and frame triggers, with sync, verbose
|
||||||
|
LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync 1 10 0 # trigger all 10 ms, real start and frame triggers, with sync, minimal verbose
|
||||||
|
|
||||||
|
Coord[1].Q[0]=-3 // simulate motion ready
|
||||||
|
|
||||||
|
Coord[1].Q[0] // changed to -2 to indicate 'wait for start EVT
|
||||||
|
|
||||||
|
# set start EVT to value 1 (=Force Lo)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 8
|
||||||
|
# reset EVT default value (Pulser 0)
|
||||||
|
caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-SP 0
|
||||||
|
|
||||||
|
Gather.Enable=0 # end triggerSync
|
||||||
```
|
```
|
||||||
|
|||||||
Binary file not shown.
@@ -91,7 +91,7 @@ void trigsync_func(void *arg)
|
|||||||
srvPer=pshm->ServoPeriod;
|
srvPer=pshm->ServoPeriod;
|
||||||
|
|
||||||
rtStart=rt_timer_read();
|
rtStart=rt_timer_read();
|
||||||
printf("Wait for 'arm' event...\n");
|
printf("Wait for 'acquire start' event...\n");
|
||||||
if(mode&2)
|
if(mode&2)
|
||||||
{
|
{
|
||||||
while(!SIMFLAG0)
|
while(!SIMFLAG0)
|
||||||
@@ -217,44 +217,41 @@ void trigsim_func(void *arg)
|
|||||||
rt_task_sleep_until(rtSlice); //in ns
|
rt_task_sleep_until(rtSlice); //in ns
|
||||||
if(mode&4)
|
if(mode&4)
|
||||||
{
|
{
|
||||||
SIMFLAG1=1;
|
SIMFLAG1=1; //set frame event on
|
||||||
//while(rt_timer_read()-rtStart<1E6*40*i)
|
//while(rt_timer_read()-rtStart<1E6*40*i)
|
||||||
// rt_task_wait_period(NULL);
|
// rt_task_wait_period(NULL);
|
||||||
rt_task_sleep_until(rtSlice+5*1E6); //in ns
|
rt_task_sleep_until(rtSlice+5*1E6); //in ns
|
||||||
SIMFLAG1=0;
|
SIMFLAG1=0; //set frame event off
|
||||||
if(mode&8)
|
if(mode&8)
|
||||||
{putchar('.');fflush(stdout);}
|
{putchar('.');fflush(stdout);} //indicates frame event has been generated (toggle on/off)
|
||||||
}
|
}
|
||||||
//if(pshm->Coord[1].DesTimeBase==0)
|
if(SIMFLAG0==1) //if start event on
|
||||||
if(SIMFLAG0==1)
|
|
||||||
{
|
{
|
||||||
if(j)
|
if(pshm->Coord[1].Q[0]>=0) //îf moved bejond start position, the start event was consumed
|
||||||
{
|
{
|
||||||
SIMFLAG0=0;j=0;
|
SIMFLAG0=0; //set start event off
|
||||||
|
if(mode&8){
|
||||||
|
putchar('x');fflush(stdout); //indicates start event has been turned off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(mode&8){
|
||||||
|
putchar('s');fflush(stdout); //indicates start event is on
|
||||||
}
|
}
|
||||||
else if(mode&8)
|
|
||||||
{putchar('x');fflush(stdout);}
|
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
if(!pshm->Gather.Enable)
|
if(!pshm->Gather.Enable)
|
||||||
{
|
{
|
||||||
if((mode&4) && j<10)
|
if((mode&4) && j<10)
|
||||||
{
|
{
|
||||||
putchar('o');
|
putchar('o'); //indicates Gather.Enable==0 and trigsim_func will end after further 10 simulated frame triggers
|
||||||
j++;
|
j++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//if(pshm->Coord[1].Q[10]==2)
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
printf("trigsim_func done\n");
|
printf("trigsim_func done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void trigsync_run()
|
void trigsync_run()
|
||||||
{
|
{
|
||||||
RT_TASK trigsync_task;
|
RT_TASK trigsync_task;
|
||||||
@@ -275,7 +272,7 @@ void trigsync_run()
|
|||||||
rt_task_start(&trigsync_task, &trigsync_func, 0); //Since task starts in suspended mode, start task
|
rt_task_start(&trigsync_task, &trigsync_func, 0); //Since task starts in suspended mode, start task
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode&2)
|
if(mode&6)
|
||||||
{
|
{
|
||||||
rt_task_create(&trigsim_task, strSim, 0, 50, T_JOINABLE);
|
rt_task_create(&trigsim_task, strSim, 0, 50, T_JOINABLE);
|
||||||
rt_task_start(&trigsim_task, &trigsim_func, 0);
|
rt_task_start(&trigsim_task, &trigsim_func, 0);
|
||||||
@@ -288,7 +285,7 @@ void trigsync_run()
|
|||||||
printf("trigsync_task done\n");
|
printf("trigsync_task done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode&2)
|
if(mode&6)
|
||||||
{
|
{
|
||||||
rt_task_join(&trigsim_task);
|
rt_task_join(&trigsim_task);
|
||||||
printf("trigsim_task done\n");
|
printf("trigsim_task done\n");
|
||||||
@@ -311,27 +308,31 @@ timeOfs: once added time offset in ms (default=0, float value)\n\
|
|||||||
scl: scale factor (so far unused, default=1, float value)\n\
|
scl: scale factor (so far unused, default=1, float value)\n\
|
||||||
\n\
|
\n\
|
||||||
\n\
|
\n\
|
||||||
simulate start trigger:\n\
|
mode examples:\n\
|
||||||
set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start\n\
|
|
||||||
\n\
|
|
||||||
simulate frame trigger\n\
|
|
||||||
is output to pshm->Coord[1].Q[11]\n\
|
|
||||||
1: synchronize real frame and start triggers\n\
|
1: synchronize real frame and start triggers\n\
|
||||||
3: synchronize real frame and simulated start triggers\n\
|
3: synchronize real frame and simulated start triggers\n\
|
||||||
6: simulated frame and start triggers (no sync)\n\
|
6: simulated frame and start triggers (no sync)\n\
|
||||||
7: synchronize simulated frame and start triggers\n\
|
7: synchronize simulated frame and start triggers\n\
|
||||||
\n\
|
\n\
|
||||||
in simulate mode:\n\
|
Acquire start event:\n\
|
||||||
set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start\n\
|
SIM: Coord[1].Q[10]\n\
|
||||||
set pshm->Coord[1].Q[10]=2 to stop simulate trigger generation\n\
|
EVR: Gate3[1].Chan[0].UserFlag == (gate3_1->Chan[0].Status&0x800)\n\
|
||||||
Coord[1].Q[11] is the simulated frame trigger\n\
|
|
||||||
\n\
|
\n\
|
||||||
in synchronize mode\n\
|
Frame event:\n\
|
||||||
Coord[1].Q[0]=-2 : trigsync_func start, Wait for 'arm' trigger\n\
|
SIM: Coord[1].Q[11]\n\
|
||||||
Coord[1].Q[0]=-1 : got 'arm' trigger, wait frame trigger\n\
|
EVR: Gate3[1].Chan[1].UserFlag == (gate3_1->Chan[0].Status&0x800)\n\
|
||||||
Coord[1].Q[0]= 0 : got frame trigger 0\n\
|
\n\
|
||||||
Coord[1].Q[0] is incremented at each trigger\n\
|
Coord[1].Q[0] : sync points indicator: (at whick point is the motion program) (mode=2)\n\
|
||||||
sync task ends when Gather.Enable==0\n\
|
val: desc set in code\n\
|
||||||
|
-3: motion armed at start position motion code MXMotion.py:setup_sync\n\
|
||||||
|
-2: wait for 'aquire start' event triggerSync.c:trigsync_func(mode&1==sync mode) or motion code MXMotion.py:setup_sync\n\
|
||||||
|
-1: start gathering data triggerSync.c:trigsync_func(mode&1==sync mode) or motion code MXMotion.py:setup_sync\n\
|
||||||
|
0: got first frame trigger triggerSync.c:trigsync_func(mode&1==sync mode)\n\
|
||||||
|
idx: index of frame during run triggerSync.c:trigsync_func(mode&1==sync mode)\n\
|
||||||
|
\n\
|
||||||
|
\n\
|
||||||
|
exec ends the tasks ends\n\
|
||||||
|
tasks ends (trigsync_func and trigsim_func) when Gather.Enable==0\n\
|
||||||
";
|
";
|
||||||
printf("usage:\n%s mode pt2ptTime timeOfs(default=0) scl(default=1)\n",cmd);
|
printf("usage:\n%s mode pt2ptTime timeOfs(default=0) scl(default=1)\n",cmd);
|
||||||
puts(s);
|
puts(s);
|
||||||
|
|||||||
32
src/usrServo/Readme.md
Normal file
32
src/usrServo/Readme.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Activate an user servoloop
|
||||||
|
--------------------------
|
||||||
|
```
|
||||||
|
PBTools/pbtools/usr_servo_phase$ make
|
||||||
|
PBTools/pbtools/usr_servo_phase/usrServoSample$ make
|
||||||
|
scp userservo_util userphase_util usrServoSample/usralgo.ko root@MOTTEST-CPPM-CRM0573:/tmp
|
||||||
|
|
||||||
|
rmmod usralgo
|
||||||
|
insmod /tmp/usralgo.ko
|
||||||
|
|
||||||
|
cat /proc/kallsyms | grep MyUserAlgoFunctionName (e.g. cat /proc/kallsyms | grep usr_servo_ctrl_2)
|
||||||
|
a10385ca r __kstrtab_usr_servo_ctrl_2 [usralgo]
|
||||||
|
a1038570 r __ksymtab_usr_servo_ctrl_2 [usralgo]
|
||||||
|
a103812c T usr_servo_ctrl_2 [usralgo]
|
||||||
|
|
||||||
|
UserAlgo.ServoCtrlAddr[1] = $a103812c
|
||||||
|
Motor[1].Ctrl =UserAlgo.ServoCtrlAddr[1].a
|
||||||
|
|
||||||
|
.. but this can not be set directly in gpascii.
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user