diff --git a/Logbook.md b/Logbook.md new file mode 100644 index 0000000..0afe02b --- /dev/null +++ b/Logbook.md @@ -0,0 +1,305 @@ +Work log +======== + +# xx.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 +``` + +# xx.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 +``` + + +# 12.2.25: debugging motion code +``` +&1b2r +go to <&>coordsystem <1> eginning of program <2> and un + +s step one line +q quit program +a abort motion program +bpset set breakpoints + +list plc2,10,3 + list 3 lines strating from line 10 + +list pc + show program counter + &1b2r + +open prog 3 + linearabs + X2Y1 + dwell10 + X0Y3 + dwell10 + X3Y3 + dwell10 + X3Y0 + dwell10 + X0Y0 +close + +&1b3 + +cpx linearabs X1Y1 + +//return coordinate transcormation of all axes (in coordinate system 1) +&1 #1..8-> + +&1p // returns coordinate positions in 'wells' (in coordinate system 1) +X1.000208333333334 Y1.000104166666666 + +#1..2p + +//show were the program is: +list pc +list pc, // with line numbers + +Coord[1].ProgRunning +Coord[1].ProgActive +Coord[1].ProgProceeding +Coord[1].Program.Lsize +Coord[1].Program.Number +Coord[1].Program.Size +Coord[1].Program.Store +``` + +# 08.05.2026: SFELPHOTON-1957: stop-go-and-return motion +``` +5 stop-and-go +6 hit-and-return +7 stop-go-and-return + +./shapepath.py -v0x04 -m5 +./shapepath.py -v0x04 -m60 +./shapepath.py -v0x04 -m70 + +./shapepath.py -v0x04 -m60 ; mv /tmp/shapepath.prg /tmp/shapepath60.pr +./shapepath.py -v0x04 -m70 ; mv /tmp/shapepath.prg /tmp/shapepath60.pr + + + +------- mode 5 ------- + L1=0 //slow loop x + L0=0 //fast loop y + while(L1<20) + { + //send 1"A:move X%g:%g Y%g:%g",-1000+L1*120,0,-1200+L0*120,0 + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L0+=1 + while(L0<25-1) + { + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L0+=1 + } + if(L1>=20-1) + { + break + } + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L1+=1 + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L0-=1 + while(L0>=1) + { + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L0-=1 + } + if(L1>=20-1) + { + break + } + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L1+=1 + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + L0+=1 + } + X(-1000+L1*120):0 Y(-1200+L0*120):0 + while(Sys.Udata[2]==Sys.Udata[1]){};Sys.Udata[2]=Sys.Udata[1] // wait motion trigger + dwell 100 + +------- mode 6 ------- + L6=1 // motion pvt tome scaling + L5=-1 // key position + L0=0;L1=0 // section counter + L10=0;L12=0;L4=0 // counter well in region + L2=0;L3=1 // motion pitch + L7=0;L8=12000.0 // scaled velocity + pvt10 abs + while(1){ + if (L1%2==0){ // even rows + L9=6*L0+L10;L11=10*L1+L12 + }else{ // odd rows + L9=(2-L0)*6-L10-1;L11=10*L1+L12 + L7=-L7 + } + L10+=L2;L12+=L3 + //send 1"A:move(%d) X%g:%g Y%g:%g",L5,-1000+L9*120,L7,-1200+L11*120,L8 + X(-1000+L9*120):(L7) Y(-1200+L11*120):(L8) + if (L6!=1){ + pvt10 abs;L6=1 + } + if (L5>=0){ //if keypoint not directly followed by an other keypoint, define future velocity + if (L5==0 || L5==4){ + L7=0;L8=12000.0 + }else if (L5==2){ + L7=0;L8=-12000.0 + }else if (L5==5){ + L7=-12000.0;L8=0 + }else if (L5==6){ + L4+=1 + if (6!=1) { + pvt60 abs;L6=6 + } + }else if (L5==7){ + //send 1"next h section" + L0+=1 + L10=0;L12=0;L4=0;L2=0;L3=0 + if (9!=1) { + pvt90 abs;L6=9 + } + }else if (L5==8){ + //send 1"next v section" + L0=0;L1+=1 + L10=0;L12=0;L4=0;L2=0;L3=0 + if (L1>=2){ + //send 1"finished whole grid" + break + } + if (19!=1) { + pvt190 abs;L6=19 + } + } + //send 1"after keypoint %d: %g|%g",L5,L7,L8 + L5=-1 + } + if (L12==10-1){ + if (L3==1){ //(1) + L2=1;L3=0 + L7=12000.0/2;L8=12000.0/2 + }else{ + L5=2;L2=0;L3=-1 //(2) + L7=12000.0/2;L8=-12000.0/2 + } + }else if (L12==1 && L10>0 && L10<6-1){ + if (L3==-1){ //(3) + L2=1;L3=0 + L7=12000.0/2;L8=-12000.0/2 + }else{ + L5=4;L2=0;L3=1 //(4) + L7=12000.0/2;L8=12000.0/2 + } + }else if (L12==0){ + if (L4==1 && L10==1){ //(7 or 8) + if (L0<2-1){ + L5=7;L2=-1;L3=0 + L7=0;L8=0 + }else{ //(8) + L5=8;L2=6-1;L3=10 + L7=0;L8=0 + } + }else if (L10==1){ //(6) + L5=6;L2=-1;L3=0 + L7=-12000.0;L8=0 + }else if (L10==0){ //(0) + L5=0;L2=0;L3=1 + L7=0;L8=12000.0 + }else if (L10==6-1){ //(5) + L5=5;L2=-1;L3=0 + L7=-12000.0/2;L8=-12000.0/2 + } + } + } + dwell 100 + +------- mode 7 ------- + + +``` diff --git a/Readme.md b/Readme.md index dae64bc..61d9b26 100644 --- a/Readme.md +++ b/Readme.md @@ -200,153 +200,3 @@ sequenceDiagram Note over py: .gather_upload() deactivate py ``` - -12.2.25: debugging motion code ------------------------------------------------------------ -``` -&1b2r -go to <&>coordsystem <1> eginning of program <2> and un - -s step one line -q quit program -a abort motion program -bpset set breakpoints - -list plc2,10,3 - list 3 lines strating from line 10 - -list pc - show program counter - &1b2r - -open prog 3 - linearabs - X2Y1 - dwell10 - X0Y3 - dwell10 - X3Y3 - dwell10 - X3Y0 - dwell10 - X0Y0 -close - -&1b3 - -cpx linearabs X1Y1 - -//return coordinate transcormation of all axes (in coordinate system 1) -&1 #1..8-> - -&1p // returns coordinate positions in 'wells' (in coordinate system 1) -X1.000208333333334 Y1.000104166666666 - -#1..2p - -//show were the program is: -list pc -list pc, // with line numbers - -Coord[1].ProgRunning -Coord[1].ProgActive -Coord[1].ProgProceeding -Coord[1].Program.Lsize -Coord[1].Program.Number -Coord[1].Program.Size -Coord[1].Program.Store -``` - - -------------------------------- -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 -``` diff --git a/python/MXMotion.py b/python/MXMotion.py index 7e0425b..15e1c8f 100644 --- a/python/MXMotion.py +++ b/python/MXMotion.py @@ -154,15 +154,13 @@ Coord[{crdId}].Q[0]=-3 //motion program waiting at start position def run(self, crdId=1): 'runs the code sync_run which has been generated with setup_sync()' + comm = self.comm + if comm is None: return + gpascii = comm.gpascii try: run=self.sync_run except AttributeError: raise 'Need to call setup sync before' - - comm = self.comm - if comm is None: return - gpascii = comm.gpascii - try: cmd=self.sync_cmd except AttributeError: diff --git a/python/hit_return_sim.py b/python/hit_return_sim.py index bc01854..0621422 100755 --- a/python/hit_return_sim.py +++ b/python/hit_return_sim.py @@ -240,17 +240,17 @@ if __name__=='__main__': def parse_args(): 'main command line interpreter function' (h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' ' - exampleCmd=('-v0xff', - '--host=SAR-CPPM-EXPMX1 -v0x5d', - '--host=localhost:10001:10002 -v0x59', - '--host=SAR-CPPM-EXPMX1 -v0x5d -m5', + exampleCmd=(#'-v0xff', + #'--host=SAR-CPPM-EXPMX1 -v0x5d', + #'--host=localhost:10001:10002 -v0x59', + #'--host=SAR-CPPM-EXPMX1 -v0x5d -m5', ) epilog=__doc__+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n ' parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) - 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('--host', help='hostname', default=None) + #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('--host', help='hostname', default=None) args=parser.parse_args() _log.info('Arguments:{}'.format(args.__dict__)) diff --git a/python/shapepath.py b/python/shapepath.py index 2e9d6d6..e89c571 100755 --- a/python/shapepath.py +++ b/python/shapepath.py @@ -738,7 +738,7 @@ class ShapePath(MotionBase): tmove: (m) time to move in ms (move start on FEL-trigger twait: (m) time to wait in ms (tmove+twait will be rounded to a multiple of fel_per) - mode:6 pvt motion 'hit and return using grid parameters. continous motion on 2n ells to pump then same 2n wells to probe, then go 2 rows down + mode:6 pvt motion 'hit and return using grid parameters. continous motion on 2n wells to pump then same 2n wells to probe, then go 2 rows down common kwargs plus: trf : (o) transformation that will be done on 'grid points' grid : (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0} @@ -746,8 +746,20 @@ class ShapePath(MotionBase): smv : (o) time(in num of shots) to move to next section (horiz/vert) default is (ssz[0]-1,ssz[1]) sdelay: (o) shots count of delay. Default is ssz[0]*ssz[1] + mode:7 pvt motion 'stop-go-hit-and-return using grid parameters. stop go motion on 2n wells to pump then same 2n wells to probe, then go 2 rows down + common kwargs plus: + trf : (o) transformation that will be done on 'grid points' + grid : (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0} + ssz : (m) section size (in wells) + smv : (o) time(in num of shots) to move to next section (horiz/vert) + default is (ssz[0]-1,ssz[1]) + sdelay: (o) section shots count delay. Default is ssz[0]*ssz[1]. A the point will be reached after sdelay shots in the next loop + tmove: (m) time(in num of shots) to move to the next well + twait: (m) time(in num of shots) to wait at the well + if twait=0, the motion will will not stop but continue motion (as mode 4 or 6) + seccnt: (o) number of timmes a section motion is done (default=2) ''' - if mode not in (1,3,4,5,6): #### pvt motion + if mode not in (1,3,4,5,6,7): #### pvt motion raise ValueError(f'unsupported mode:{mode}') try: self.sync_prg @@ -838,14 +850,14 @@ class ShapePath(MotionBase): ox, oy=g['pos'] px, py=g['pitch'] #self.mot_pts=pt - self.mot_pts=pt*np.array(g['pitch'], np.float)+np.array(g['pos'], np.float) + self.mot_pts=pt*np.array(g['pitch'], np.float64)+np.array(g['pos'], np.float64) else: ox, oy=(0,0) px, py=(1,1) self.mot_pts=(np.hstack((pt, np.ones((pt.shape[0], 1))))*np.asmatrix(trf)).A # pt*trf #prg+=f' linear abs\n X{ox:g} Y{oy:g}\n' prg+=f' linear abs\n X{ox-px:g} Y{oy-py:g}\n' # start one position out of grid - else: #mode==6: #### pvt motion, hit and return using grid parameters + else: #mode in (6,7): #### pvt motion, hit and return using grid parameters g=kwargs['grid'] nx,ny=g['count'] #total count of wells #TODO: rework pt calculation @@ -857,7 +869,7 @@ class ShapePath(MotionBase): except KeyError as e: ox, oy=g['pos'] px, py=g['pitch'] - self.mot_pts=pt*np.array(g['pitch'], np.float)+np.array(g['pos'], np.float) + self.mot_pts=pt*np.array(g['pitch'], np.float64)+np.array(g['pos'], np.float64) else: ox, oy=(0,0) px, py=(1,1) @@ -1165,6 +1177,126 @@ enable plc 2 }} }} +''' + elif mode==7: + if scan==0: + raise Exception('scan=0 not supported') + pass + else: # scan=1 + vsx=px/(pt2pt_time)*scale*CoordFeedTime # scaling for Deltatau + vsy=py/(pt2pt_time)*scale*CoordFeedTime # scaling for Deltatau + + #g=kwargs['grid'] + #ox,oy=g['pos'] #origin position in um (or counts if scaled) + #px,py=g['pitch'] #pitch to next position in um (or 1 if scaled) + #nx,ny=g['count'] #total count of wells + #sx,sy=kwargs['ssz'] #section size (in wells) + #tsx, tsy, tsd #time scale to pvt move to (next horiz|next vert| after position #6) + tx,ty=nx//sx,ny//sy #total sections + + #variables + cx,cy,dx,dy,n,k,t,vx,vy,x,x0,y,y0=map(lambda x: f'L{x}',range(13)) + # replace in python code of hit_and_return.py setup_motion: + # (cx|cy|dx|dy|n|k|sx|sy|tsd|tsx|tsy|tx|ty|vsx|vsy|vx|vy|x|x0|y|y0) -> {\1} + # if ([^:]*): -> if \(\1\){{ + # else: -> }}else{{ + # elif ([^:]*): -> }}else if \(\1\){{ + + prg+=f'''\ + //mode 7: stop-go-and-return pvt motion + + {t}=1 // motion pvt tome scaling + {k}=-1 // key position + {cx}=0;{cy}=0 // section counter + {x0}=0;{y0}=0;{n}=0 // counter well in region + {dx}=0;{dy}=1 // motion pitch + {vx}=0;{vy}={vsy} // scaled velocity + pvt{pt2pt_time} abs + while(1){{ + if ({cy}%2==0){{ // even rows + {x}={sx}*{cx}+{x0};{y}={sy}*{cy}+{y0} + }}else{{ // odd rows + {x}=({tx}-{cx})*{sx}-{x0}-1;{y}={sy}*{cy}+{y0} + {vx}=-{vx} + }} + {x0}+={dx};{y0}+={dy} + //send 1"A:move(%d) X%g:%g Y%g:%g",{k},{ox}+{x}*{px},{vx},{oy}+{y}*{py},{vy} + X({ox}+{x}*{px}):({vx}) Y({oy}+{y}*{py}):({vy}) + if ({t}!=1){{ + pvt{pt2pt_time} abs;{t}=1 + }} + if ({k}>=0){{ //if keypoint not directly followed by an other keypoint, define future velocity + if ({k}==0 || {k}==4){{ + {vx}=0;{vy}={vsy} + }}else if ({k}==2){{ + {vx}=0;{vy}=-{vsy} + }}else if ({k}==5){{ + {vx}=-{vsx};{vy}=0 + }}else if ({k}==6){{ + {n}+=1 + if ({tsd}!=1) {{ + pvt{pt2pt_time*tsd} abs;{t}={tsd} + }} + }}else if ({k}==7){{ + //send 1"next h section" + {cx}+=1 + {x0}=0;{y0}=0;{n}=0;{dx}=0;{dy}=0 + if ({tsx}!=1) {{ + pvt{pt2pt_time*tsx} abs;{t}={tsx} + }} + }}else if ({k}==8){{ + //send 1"next v section" + {cx}=0;{cy}+=1 + {x0}=0;{y0}=0;{n}=0;{dx}=0;{dy}=0 + if ({cy}>={ty}){{ + //send 1"finished whole grid" + break + }} + if ({tsy}!=1) {{ + pvt{pt2pt_time*tsy} abs;{t}={tsy} + }} + }} + //send 1"after keypoint %d: %g|%g",{k},{vx},{vy} + {k}=-1 + }} + if ({y0}=={sy}-1){{ + if ({dy}==1){{ //(1) + {dx}=1;{dy}=0 + {vx}={vsx}/2;{vy}={vsy}/2 + }}else{{ + {k}=2;{dx}=0;{dy}=-1 //(2) + {vx}={vsx}/2;{vy}=-{vsy}/2 + }} + }}else if ({y0}==1 && {x0}>0 && {x0}<{sx}-1){{ + if ({dy}==-1){{ //(3) + {dx}=1;{dy}=0 + {vx}={vsx}/2;{vy}=-{vsy}/2 + }}else{{ + {k}=4;{dx}=0;{dy}=1 //(4) + {vx}={vsx}/2;{vy}={vsy}/2 + }} + }}else if ({y0}==0){{ + if ({n}==1 && {x0}==1){{ //(7 or 8) + if ({cx}<{tx}-1){{ + {k}=7;{dx}=-1;{dy}=0 + {vx}=0;{vy}=0 + }}else{{ //(8) + {k}=8;{dx}={sx}-1;{dy}={sy} + {vx}=0;{vy}=0 + }} + }}else if ({x0}==1){{ //(6) + {k}=6;{dx}=-1;{dy}=0 + {vx}=-{vsx};{vy}=0 + }}else if ({x0}==0){{ //(0) + {k}=0;{dx}=0;{dy}=1 + {vx}=0;{vy}={vsy} + }}else if ({x0}=={sx}-1){{ //(5) + {k}=5;{dx}=-1;{dy}=0 + {vx}=-{vsx}/2;{vy}=-{vsy}/2 + }} + }} + }} + ''' #common code to repeat the motion multiple times if cnt>1: @@ -1360,7 +1492,7 @@ if __name__=='__main__': sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=4,grid=grid) elif mode==5: sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=5,grid=grid,tmove=tmove,twait=twait) - elif mode==6: + elif mode==60: grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(16, 20)} ssz=(6, 10) # section size (in wells) smv=(ssz[0]-1+4,ssz[1]+1+8) # time(in num of shots) to move to next section (horiz/vert) @@ -1374,14 +1506,17 @@ if __name__=='__main__': grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(30, 20)} ssz=(2, 10) # section size (in wells) sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=6,grid=grid,ssz=ssz) - - + elif mode==70: # mode 7 testcase 0 + grid={'pos':(-1000, -1200), 'pitch':(120, 120), 'count':(16, 20)} + ssz=(6, 10) # section size (in wells) + smv=(ssz[0]-1+4,ssz[1]+1+8) # time(in num of shots) to move to next section (horiz/vert) + sdelay=ssz[0]*ssz[1]+5 # wait after section for motion trigger. swait=0:never wait + sp.setup_motion(fnPrg=fn+'.prg',scale=1.,cnt=1,dwell=100,mode=7,grid=grid,ssz=ssz,smv=smv,sdelay=sdelay) else: raise(ValueError(f'unsupported mode:{mode}')) if sp.comm: sp.setup_gather() - sp.homing() #homing if needed sp.run() #start motion program _log.info('wait_armed')