296 lines
11 KiB
Markdown
296 lines
11 KiB
Markdown
PBSwissMX
|
|
=========
|
|
This repository is used by the SwissMX application.<br/>
|
|
A complete list of SwissMX repositories dependencies is shown in [grp-sf_cristallina/SwissMX.git](https://git.psi.ch/grp-sf_cristallina/SwissMX).
|
|
|
|
|
|
PBSwissMX contains python application and executables to:
|
|
- generate trajectories and motion programs for SwissMX (`shapepath.py` and `helicalscan.py`[obsolete])
|
|
- motion synchronization executables (`triggerSync`) for Deltatau
|
|
- analyse recorded trajectories on SwissMX (`ShapePathAnalyser`)
|
|
- motor tuning tools (`MXTuning`)
|
|
- documentation about the tuning results (`MXfastStageDoc`)
|
|
|
|
motion start/framesynchronization (update31.10.24)
|
|
---------------------------------------------------
|
|
|
|
**<font color="red">For more details about triggerSync read: [src/triggerSync/Readme.md](src/triggerSync/Readme.md)</font>**
|
|
|
|
#### Important used vaiables:
|
|
```
|
|
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
|
|
```
|
|
|
|
### start/frame event system
|
|
```
|
|
Start event:
|
|
sim: Coord[1].Q[10]
|
|
EVR: Gate3[1].Chan[0].UserFlag == (gate3_1->Chan[0].Status&0x800) == FrontUnivOut4, EPICS MACRO: $(USR_FLAG_ID)=5
|
|
-> Pulser0 -> (active Low, 5000us delay 0us) Map: 214
|
|
-> event 214 is 'ESC multipurpose event. In this case used as: start motion'
|
|
|
|
Frame event:
|
|
sim: Coord[1].Q[11]
|
|
EVR: Gate3[1].Chan[1].UserFlag == (gate3_1->Chan[1].Status&0x800) == FrontUnivOut5, EPICS MACRO: $(USR_FLAG_ID)=5
|
|
-> Pulser1 -> (active Low, 5000us delay 750us) Map: 40
|
|
-> event 40 = 'ESA_detector 100 Hz' >>> should be 77='ESC detector'
|
|
|
|
unused EVR input?:
|
|
EVR: Gate3[1].Chan[2].UserFlag == (gate3_1->Chan[2].Status&0x800) == FrontUnivOut6, EPICS MACRO: $(USR_FLAG_ID)=7
|
|
|
|
!!! Deltatau flags are inverted: FrontUnivOut6(Force Low) -> Gate3[1].Chan[2].UserFlag==1
|
|
```
|
|
|event |simulated |real |
|
|
|- |- |- |
|
|
|start |Coord[.].Q[10] | Gate3[1].Chan[0].UserFlag |
|
|
|frame |Coord[.].Q[11] | Gate3[1].Chan[1].UserFlag |
|
|
|
|
**frequence jitter 50Hz Swissgrid:** https://www.swissgrid.ch/de/home/operation/grid-data/current-data.html
|
|
|
|
### partial python class diagram of PBSwissMX
|
|
|
|
```mermaid
|
|
classDiagram
|
|
MotionBase <|-- ShapePath
|
|
MotionBase <|-- HelicalScan
|
|
|
|
class MotionBase {
|
|
@MXMotion.py
|
|
+ setup_sync(self, crdId, prgId, verbose, timeOfs, timeCor)
|
|
+ homing(self)
|
|
+ run(self, crdId)
|
|
+ wait_armed(self, crdId)
|
|
+ progress(self)
|
|
+ trigger(self, wait)
|
|
}
|
|
|
|
class ShapePath {
|
|
@shapepath.py
|
|
%%- __init__(self, args) None
|
|
+ setup_gather(self,acq_per=None,numPts=None)
|
|
+ setup_coord_trf(self,fx='X',fy='Y',cz='0')
|
|
+ setup_motion(self,prgId=2,fnPrg=None,mode=0,**kwargs)
|
|
+ gather_upload(self,fnRec=None)
|
|
}
|
|
|
|
class HelicalScan {
|
|
@helicalscan.py [obsolete]
|
|
+ setup_gather(self,acq_per=1)
|
|
+ setup_coord_trf(self,fnCrdTrf='/tmp/coordTrf.cfg')
|
|
+ setup_motion(self,prgId=2,fnPrg=None,mode=0,**kwargs)
|
|
+ gather_upload(self,fnRec=None)
|
|
}
|
|
|
|
class GenPath {
|
|
@shapepath.py
|
|
+ swissmx(self, flipx, flipy, ofs, width)
|
|
+ swissfel(self, flipx, flipy, ofs, width)
|
|
%%+ rand(self, n, scale, ofs)
|
|
+ grid(self, w, h, pitch, rnd, ofs)
|
|
%%+ spiral(self, rStart, rInc, numSeg, numCir, phase, ofs)
|
|
%%+ closed_shifted(self, pitch, shift, mult)
|
|
%%+ sort(self, mode, grp_sz)
|
|
}
|
|
```
|
|
|
|
### Simplified Python sequence
|
|
|
|
Source for the instance "start/frame event system" can be:
|
|
- python code
|
|
- timing system (EVR)
|
|
- motion code
|
|
- triggerSync executable running on Deltatau
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant es as start/frame<br/>event system
|
|
participant py as Python
|
|
participant pb as PowerBrick
|
|
|
|
Note over py: .setup_sync()<br/>prepare code snipplets
|
|
activate py
|
|
opt needs triggerSync
|
|
Note over es,pb: triggerSync is needed in case of:<br/>simulated start/frame triggers<br/>and/or adjust DesTimeBase
|
|
py -) pb: sftp / ssh
|
|
Note over pb: sftp triggerSync<br/>run triggerSync
|
|
pb ->> es: run triggerSync
|
|
end
|
|
|
|
Note over py: .setup_coord_trf()
|
|
py -) pb: download code
|
|
Note over pb: setup coordinate transformation
|
|
Note over py: .setup_motion()
|
|
py -) pb: generate code<br/>download code
|
|
Note over pb: setup motion program
|
|
Note over py: .setup_gather()
|
|
py -) pb: download code<br/>set gather vars
|
|
Note over pb: set addresses to gather<br/>Gather.Enable=1
|
|
Note over py: .homing()
|
|
py -)+ pb: download code<br/>run homing PLC
|
|
Note over py: wait(Motor[1].HomeComplete)
|
|
deactivate py
|
|
Note over pb: runs homing PLC [if needed]<br/>enable plc 1
|
|
pb ->>- py: Motor[1].HomeComplete
|
|
activate py
|
|
Note over py: .run()
|
|
py -)+ pb: run motion program
|
|
Note over pb: runs motion program 2 in coordSystem 1<br/>&1br2
|
|
Note over pb: move to first point<br/>DesTimeBase=0 (wait motion)<br/>Q[0]=-3 (motion program waiting at start position)
|
|
pb ->>- es: Q[0]=-3
|
|
Note over es: Q[0]=-2 (event system armed)<br/>[in motion code or<br/>triggerSync exe]
|
|
Note over py: .wait_armed()<br/>wait(Q[0]==-2) # wait until motors are at first position
|
|
deactivate py
|
|
es ->>+ py: Q[0]=-2
|
|
Note over es: wait for start trigger
|
|
Note over py: .trigger()
|
|
alt sim start trig
|
|
Note over py: Q[10]=1 [send a simulated start trigger<br/>after given time]
|
|
py ->> es: Q[10]=1
|
|
else real start trig
|
|
es->> es: Gate3[1].Chan[0].UserFlag==1
|
|
end
|
|
Note over es: DesTimeBase=Sys.ServoPeriod<br/>[in motion code or<br/>triggerSync exe]
|
|
es->>+pb: continue motion
|
|
opt adjust time base
|
|
Note over es: in thread trigger_sync_func()<br/>of triggerSync exe
|
|
es->>es: adjust DesTimeBase
|
|
end
|
|
Note over pb: pvt10abs<br/>move to all points
|
|
loop 10 ms
|
|
Note over pb: move to next point
|
|
end
|
|
opt triggerSync running
|
|
pb ->> es: Gather.Enable=0
|
|
Note over es: exit triggerSync exe
|
|
end
|
|
Note over py: while .progress()<br/>wait(Gather.Enable==0)
|
|
deactivate py
|
|
Note over pb: end motion program
|
|
pb ->>- py: Gather.Enable=0
|
|
activate py
|
|
Note over py: .gather_upload()
|
|
deactivate py
|
|
```
|
|
|
|
-------------------------------
|
|
Work log
|
|
========
|
|
|
|
??10.24: 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
|
|
```
|
|
|
|
??.10.24: mermaid tricks and links
|
|
---------------------------------
|
|
- https://mermaid.live/
|
|
- https://app.zenuml.com/
|
|
- https://www.mermaidchart.com/
|
|
- https://help.whimsical.com/article/732-sequence-diagrams
|
|
- https://www.visual-paradigm.com/guide/uml-unified-modeling-language/what-is-sequence-diagram/
|
|
- https://www.geeksforgeeks.org/unified-modeling-language-uml-sequence-diagrams/
|
|
|
|
```
|
|
pip install pymermaider --user
|
|
pymermaider ~/Documents/prj/SwissFEL/apps/PBSwissMX/python -o /tmp
|
|
subl /tmp/python.md
|
|
```
|