Go to the documentation of this file.00001 CLOSE
00002
00003 ;###############################################
00004 ;; \file
00005 ;; Define motion for Energy in IDT sagital DCM
00006 ;;
00007 ;; Original Author: Tom Cobb.
00008 ;;
00009 ;; Defined axes:
00010 ;; - X (addr 6) = Energy in kEv
00011 ;; - Y (addr 7) = Beam Offset in mm
00012 ;;
00013 ;; Macros (and example values):
00014 ;; - COORD = $(COORD) CS number (only works for CS 1..9), e.g. 2
00015 ;; - PLC = $(PLC) PLC number, should be CS number+15, e.g. 17
00016 ;; - BRAGG = $(BRAGG) Axisnum for Bragg, e.g. 2
00017 ;; - PERP = $(PERP) Axisnum for Perp, e.g. 3
00018 ;; - Z = $(Z) Axisnum for Z, e.g. 4
00019 ;################################################
00020
00021 ; Change to CS$(COORD)
00022 &$(COORD)
00023
00024 ; Set relevant axes to use kinematics
00025 #$(BRAGG)->I
00026 #$(PERP)->I
00027 #$(Z)->I
00028
00029 ; These are set by motor_in_cs.template
00030 #define BMOVE P(4700+$(BRAGG))
00031 #define BMRES P(4800+$(BRAGG))
00032 #define BOFF P(4900+$(BRAGG))
00033 #define PMOVE P(4700+$(PERP))
00034 #define PMRES P(4800+$(PERP))
00035 #define POFF P(4900+$(PERP))
00036 #define ZMOVE P(4700+$(Z))
00037 #define ZMRES P(4800+$(Z))
00038 #define ZOFF P(4900+$(Z))
00039
00040 ; Crystal d spacing in angstrom
00041 ; NOTE: default is silicon 111 at room temp,
00042 ; at liquid N2 it is 3.13475 or 3.13492 depending on who you believe...)
00043 #define DSPACING Q20
00044 DSPACING=3.1355
00045 ; EvLambda constant
00046 #define EVLAMBDA Q22
00047 EVLAMBDA=12.3985
00048
00049 ; Calculate Energy and Offset from Bragg and PERP
00050 #define BPOS (BMRES*P$(BRAGG)+BOFF)
00051 #define PPOS (PMRES*P$(PERP)+POFF)
00052 #define ZPOS (ZMRES*P$(Z)+ZOFF)
00053 #define ENERGY Q7
00054 #define OFFSET Q8
00055 #define SETERROR M(100*$(COORD)+5082)=1
00056 ; Local variables
00057 #define NLAMBDA Q128
00058 OPEN FORWARD
00059 CLEAR
00060 NLAMBDA=2*DSPACING*sin(BPOS)
00061 IF (ABS(NLAMBDA)>0.01)
00062 ENERGY = EVLAMBDA/NLAMBDA
00063 OFFSET = 2*PPOS*cos(BPOS)
00064 ELSE
00065 SETERROR
00066 ENDIF
00067 CLOSE
00068
00069 ; Calculate Bragg and PERP from Energy and Offset
00070 ; Local variables
00071 #define SINTHETA Q228
00072 #define BPOS Q229
00073 #define PPOS Q230
00074 #define ZPOS Q231
00075 OPEN INVERSE
00076 CLEAR
00077 SINTHETA=EVLAMBDA/(2*DSPACING*ENERGY)
00078 IF (ABS(SINTHETA)<1)
00079 ; calculate bragg in EGUs
00080 BPOS=asin(SINTHETA)
00081 ; then in cts
00082 P$(BRAGG)=(BPOS-BOFF)/BMRES
00083 ; calculate PERP in EGUs
00084 PPOS=OFFSET/(2*cos(asin(SINTHETA)))
00085 ; then in cts
00086 P$(PERP)=(PPOS-POFF)/PMRES
00087 ; calculate Z in EGUs
00088 ZPOS=OFFSET/(2*SINTHETA)
00089 ; then in cts
00090 P$(Z)=(ZPOS-ZOFF)/ZMRES
00091 ELSE
00092 SETERROR
00093 ENDIF
00094 CLOSE
00095
00096 ; A PLC(sx+15) needs to be made to do position reporting
00097 ; Readbacks should be in &{axisnum}Q81..89
00098 ; As forward kinematic, but with Px = mx62/(Ix08*32) and no error reporting
00099 #define BPOS (BMRES*m$(BRAGG)62/(I$(BRAGG)08*32)+BOFF)
00100 #define PPOS (PMRES*m$(PERP)62/(I$(PERP)08*32)+POFF)
00101 #define ENERGY Q87
00102 #define OFFSET Q88
00103 ; Local variables
00104 #define NLAMBDA Q328
00105 OPEN PLC $(PLC)
00106 CLEAR
00107 ADDRESS&$(COORD)
00108 NLAMBDA=2*DSPACING*sin(BPOS)
00109 IF (ABS(NLAMBDA)>0.01)
00110 ENERGY = EVLAMBDA/NLAMBDA
00111 OFFSET = 2*PPOS*cos(BPOS)
00112 ENDIF
00113 ; If bragg or PERP motor record did the last move, set demands = readbacks
00114 if (BMOVE = 1)
00115 or (PMOVE = 1)
00116 or (ZMOVE = 1)
00117 BMOVE = 0
00118 PMOVE = 0
00119 ZMOVE = 0
00120 Q77 = Q87
00121 Q78 = Q88
00122 endif
00123 CLOSE
00124 ENABLE PLC $(PLC)
00125
00126