added Lyrebird instrument config

r3038 | jgn | 2010-12-13 16:10:57 +1100 (Mon, 13 Dec 2010) | 1 line
This commit is contained in:
Jing Chen
2010-12-13 16:10:57 +11:00
committed by Douglas Clowes
parent a3d551c8bb
commit 28772f6ec2
53 changed files with 4451 additions and 3 deletions

View File

@@ -17,4 +17,5 @@
127.0.0.1 mc1-platypus mc2-platypus mc3-platypus mc4-platypus 127.0.0.1 mc1-platypus mc2-platypus mc3-platypus mc4-platypus
127.0.0.1 mc1-pelican mc2-pelican mc3-pelican mc4-pelican 127.0.0.1 mc1-pelican mc2-pelican mc3-pelican mc4-pelican
127.0.0.1 mc1-taipan mc2-taipan mc3-taipan mc4-taipan mc5-taipan 127.0.0.1 mc1-taipan mc2-taipan mc3-taipan mc4-taipan mc5-taipan
127.0.0.1 mc1-lyrebird mc2-lyrebird mc3-lyrebird mc4-lyrebird mc5-lyrebird
127.0.0.1 mc1-sika mc2-sika mc3-sika mc4-sika 127.0.0.1 mc1-sika mc2-sika mc3-sika mc4-sika

View File

@@ -48,6 +48,12 @@ pmc3-taipan 62732/tcp
pmc4-taipan 62733/tcp pmc4-taipan 62733/tcp
pmc5-taipan 62734/tcp pmc5-taipan 62734/tcp
pmc1-lyrebird 62830/tcp
pmc2-lyrebird 62831/tcp
pmc3-lyrebird 62832/tcp
pmc4-lyrebird 62833/tcp
pmc5-lyrebird 62834/tcp
sics-telnet-echidna 60000/tcp sics-telnet-echidna 60000/tcp
sics-telnet-echidna 60000/udp sics-telnet-echidna 60000/udp
sics-interrupt-echidna 60001/udp sics-interrupt-echidna 60001/udp
@@ -132,3 +138,15 @@ sics-interrupt-val-taipan 60711/udp
sics-server-val-taipan 60712/tcp sics-server-val-taipan 60712/tcp
sics-quieck-val-taipan 60713/udp sics-quieck-val-taipan 60713/udp
sics-telnet-lyrebird 60800/tcp
sics-telnet-lyrebird 60800/udp
sics-interrupt-lyrebird 60801/udp
sics-server-lyrebird 60802/tcp
sics-quieck-lyrebird 60803/udp
sics-telnet-val-lyrebird 60810/tcp
sics-telnet-val-lyrebird 60810/udp
sics-interrupt-val-lyrebird 60811/udp
sics-server-val-lyrebird 60812/tcp
sics-quieck-val-lyrebird 60813/udp

View File

@@ -84,6 +84,7 @@ namespace eval histogram_memory {
quokka INTERNAL quokka INTERNAL
taipan INTERNAL taipan INTERNAL
wombat INTERNAL wombat INTERNAL
lyrebird INTERNAL
} }
array set default_frame_source_always_internal { array set default_frame_source_always_internal {
@@ -95,6 +96,7 @@ namespace eval histogram_memory {
quokka "false" quokka "false"
taipan "false" taipan "false"
wombat "false" wombat "false"
lyrebird "false"
} }
::utility::mkVar detector_active_height_mm Float user active_height true detector true true ::utility::mkVar detector_active_height_mm Float user active_height true detector true true

View File

@@ -48,6 +48,7 @@ namespace eval nexus {
"kowari" "simple" "kowari" "simple"
"quokka" "fname" "quokka" "fname"
"platypus" "simple" "platypus" "simple"
"lyrebird" "simple"
} }
} }
namespace eval ::nexus::histmem {} namespace eval ::nexus::histmem {}
@@ -114,7 +115,7 @@ proc ::nexus::datapath {} {
# @param postfix This is the filename suffix, must be one of: nx.hdf, hdf, h5, nx5, xml # @param postfix This is the filename suffix, must be one of: nx.hdf, hdf, h5, nx5, xml
proc newFileName {idNum postfix} { proc newFileName {idNum postfix} {
if [ catch { if [ catch {
array set inst_mnem {quokka QKK wombat WBT echidna ECH kowari KWR koala KOL taipan TPN platypus PLP pelican PLN} array set inst_mnem {quokka QKK wombat WBT echidna ECH kowari KWR koala KOL taipan TPN platypus PLP pelican PLN lyrebird LBD}
# set prefix [SplitReply [sicsdataprefix]] # set prefix [SplitReply [sicsdataprefix]]
set date_time_arr [split [sicstime] " "] set date_time_arr [split [sicstime] " "]
set isodate [lindex $date_time_arr 0] set isodate [lindex $date_time_arr 0]

View File

@@ -22,7 +22,7 @@ Usage:
./deploySICS.sh [-n] INSTRUMENT [TARGET_HOST [TARGET_DIR]] ./deploySICS.sh [-n] INSTRUMENT [TARGET_HOST [TARGET_DIR]]
where where
-n if present inhibits the actual deployment (for testing the script) -n if present inhibits the actual deployment (for testing the script)
INSTRUMENT can be hrpd, echidna, hipd, wombat, ... (not "./xxx") INSTRUMENT can be hrpd, echidna, hipd, wombat, lyrebird ... (not "./xxx")
or test/INSTRUMENT or INSTRUMENT/test for test deployment or test/INSTRUMENT or INSTRUMENT/test for test deployment
TARGET_HOST can be a remote host or 'localhost' TARGET_HOST can be a remote host or 'localhost'
defaults to ics1-<instrument>.nbi... or ics1-test.nbi... for test defaults to ics1-<instrument>.nbi... or ics1-test.nbi... for test
@@ -126,6 +126,10 @@ pelican|pas)
INSTRUMENT=pelican INSTRUMENT=pelican
DESTHOST=${2:-ics1-pelican.nbi.ansto.gov.au} DESTHOST=${2:-ics1-pelican.nbi.ansto.gov.au}
INSTSRC=$SRCDIR/pas;; INSTSRC=$SRCDIR/pas;;
lyrebird|lyrebird)
INSTRUMENT=lyrebird
DESTHOST=${2:-ics1-lyrebird.nbi.ansto.gov.au}
INSTSRC=$SRCDIR/lyrebird;;
taipan|tas) taipan|tas)
INSTRUMENT=taipan INSTRUMENT=taipan
DESTHOST=${2:-ics1-taipan.nbi.ansto.gov.au} DESTHOST=${2:-ics1-taipan.nbi.ansto.gov.au}

View File

@@ -0,0 +1 @@
Programs for the DMC2280 controllers.

View File

@@ -0,0 +1,168 @@
NO TE: QUOKKA - CONTROLLER 1
NO TE:
NO TE: $Revision: 1.9 $
NO TE: $Name: not supported by cvs2svn $
NO TE: $Date: 2008-05-30 00:26:57 $
NO TE: Author: Dan Bartlett
NO TE: Last revision by: $Author: ffr $
NO TE:
NO TE: A-SAMPLE UPPER TILT
NO TE: B-SAMPLE LOWER TILT
NO TE: C-SAMPLE TRANSLATION X (ACROSS BEAM)
NO TE: D-SAMPLE TRANSLATION Y (ALONG BEAM)
NO TE: E-SAMPLE RAISE
NO TE: F-SAMPLE ROTATE
NO TE: G-DETECTOR Y (ALONG BEAM) PRG=25000*70/377*mm
NO TE: H-DETECTOR X (ACCROSS BEAM)
NO ----------------------------------------
#AUTO
NO TE: THIS IS THE PROGRAM THAT RUNS AUTOMATICALLY ON CONTROLLER STARTUP
MT-2,-2,-2,-2,-2,-2,-2,-2;'CONFIGURES ALL AXES AS STEPPER
MO;' FIRST TIME MOTOR OFF
CN 1;' CONFIGURES LIMIT SWITCHES TO ACCEPT NC CONTACTS
II 8,,,0;' CONFIGURES THE 8TH INPUT TO ACTIVATE THE #ININT ROUTINE
OP 65280;' SETS OUTPUTS 9-16 ON = RELAYS OFF
IA 137,157,202,67;' CONFIGURES IP ADDRESS
AC 25000,25000,25000,25000,100000,25000,50000,25000;' SET ACELERATION
DC 25000,25000,25000,25000,100000,25000,50000,25000;' SET DECELERATION
SP 25000,25000,25000,50000,200000,25000,200000,25000;' SET SPEED
SIA=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIB=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIC=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SID=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIE=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIF=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIG=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIH=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
JS #THREAD0
EN
NO ----------------------------------------
#THREAD0
NO TE: THERE MUST BE A THREAD RUNNING FOR #LIMSWI, #TCPERR AND #ININT TO WORK
NO TE: CHECKS IF SPEEDS ARE ABOVE MAXIMUM ALLOWED
IF (_SPA>50000)
SPA=50000
ENDIF
IF (_SPB>50000)
SPB=50000
ENDIF
IF (_SPC>50000)
SPC=50000
ENDIF
IF (_SPD>100000)
SPD=100000
ENDIF
IF (_SPE>200000)
SPE=200000
ENDIF
IF (_SPF>50000)
SPF=50000
ENDIF
IF (_SPG>200000)
SPG=200000
ENDIF
IF (_SPH>100000)
SPH=100000
ENDIF
NO TE: CONTROLS THE SAMPLE RAISE ELECTRO-MECHANICAL BRAKE
IF (_MOE=0)
CB 13;' MOTOR ON = BRAKE ENERGISED = UNLOCKED
ELSE
SB 13;' MOTOR OFF = BRAKE DENERGISED = LOCKED
ENDIF
NO TE: CONTROLS THE FAST SHUTTER
NO TE:
NO TE: FAST SHUTTER MUST BE CLOSED WHEN DETECTOR Z AXIS ACTIVE
NO TE: INPUT 13 = FAST SHUTTER OPEN
NO TE: INPUT 14 = FAST SHUTTER CLOSED
NO TE: INPUT 5 = ONE OR MORE BEAM STOPS RAISED (FROM CONTROLLER 4)
IF (_MOG=1) & (@IN[5]=0)
NO TE: DETECTOR Y INACTIVE AND ONE OR MORE BEAM STOPS UP
CB 15;' ENERGISE FAST SHUTTER SOLENOID = SHUTTER OPEN
ENDIF
IF (_MOG=0)&(@IN[14])
NO TE: DETECTOR Y AXIS IS ACTIVE AND FAST SHUTTER NOT CLOSED
SB15;' CLOSE FAST SHUTTER
IF (_BGG=1)
STG;' DETECTOR Y MOVING, COMMANDED TO STOP
AMG;'WAIT UNTIL STOPPED
ENDIF
MOG;' TURN DETECTOR Y OFF UNTIL FAST SHUTTER IS CLOSED
AI13;' WAIT FOR SHUTTER TO CLOSE
IF (@IN[14]=0)
NO TE: FAST SHUTTER IS CLOSED
SHG
ENDIF
ENDIF
JP #THREAD0
EN
NO ----------------------------------------
#TCPERR
NO TE: EMPTY ROUTINE FOR A TCP ERROR
RE
NO ----------------------------------------
#ININT
NO TE: INTERUPT ROUTINE TO STOP ALL AXES
NO TE: WHEN SAFETY & INTERLOCK SYSTEM REQUESTS IT
STA,B,C,D,E,F,G,H
AM
MO
RI
NO ----------------------------------------
#CMDERR
NO TE: THIS IS A ROUTINE TO HANDLE COMMAND ERRORS
ZS0;' ZERO STACK
EN1
NO ----------------------------------------
#LIMSWI
NO TE: LIMIT SWITCH ROUTINE WHICH SHORTENS DECEL TIME WHEN A LIMIT IS HIT
OLDDCA=_DCA;' REMEMBERS CURRENT DECEL
OLDDCB=_DCB
OLDDCC=_DCC
OLDDCD=_DCD
OLDDCE=_DCE
OLDDCF=_DCF
OLDDCG=_DCG
OLDDCH=_DCH
IF (_LFA = 0) | (_LRA = 0)
DCA=100000;' DECEL FOR LIMIT HIT OCCURENCE
STA
ENDIF
IF (_LFB = 0) | (_LRB = 0)
DCB=100000;' DECEL FOR LIMIT HIT OCCURENCE
STB
ENDIF
IF (_LFC = 0) | (_LRC = 0)
DCC=100000;' DECEL FOR LIMIT HIT OCCURENCE
STC
ENDIF
IF (_LFD = 0) | (_LRD = 0)
DCD=100000;' DECEL FOR LIMIT HIT OCCURENCE
STD
ENDIF
IF (_LFE = 0) | (_LRE = 0)
DCE=400000;' DECEL FOR LIMIT HIT OCCURENCE
STE
ENDIF
IF (_LFF = 0) | (_LRF = 0)
DCF=100000;' DECEL FOR LIMIT HIT OCCURENCE
STF
ENDIF
IF (_LFG = 0) | (_LRG = 0)
DCG=200000;' DECEL FOR LIMIT HIT OCCURENCE
STG
ENDIF
IF (_LFH = 0) | (_LRH = 0)
DCH=100000;' DECEL FOR LIMIT HIT OCCURENCE
STH
ENDIF
AM ABCDEFGH;' AFTER ALL AXES STOPPED
DCA=OLDDCA;' RESET DECEL TO OLD VALUE
DCB=OLDDCB
DCC=OLDDCC
DCD=OLDDCD
DCE=OLDDCE
DCF=OLDDCF
DCG=OLDDCG
DCH=OLDDCH
RE

View File

@@ -0,0 +1,140 @@
NO TE: QUOKKA - CONTROLLER 2
NO TE:
NO TE: $Revision: 1.6 $
NO TE: $Name: not supported by cvs2svn $
NO TE: $Date: 2008-05-30 00:26:57 $
NO TE: Author: Dan Bartlett
NO TE: Last revision by: $Author: ffr $
NO TE:
NO TE: A-COLLIMATION OPTICS - CHAMBER 1
NO TE: B-COLLIMATION OPTICS - CHAMBER 2
NO TE: C-COLLIMATION OPTICS - CHAMBER 3
NO TE: D-COLLIMATION OPTICS - CHAMBER 4
NO TE: E-COLLIMATION OPTICS - CHAMBER 5
NO TE: F-COLLIMATION OPTICS - CHAMBER 6
NO TE: G-COLLIMATION OPTICS - CHAMBER 7
NO TE: H-COLLIMATION OPTICS - CHAMBER 8
NO TE:
NO TE: +VE MOTOR MOVES ALL IN A WESTERLY DIRECTION
NO ----------------------------------------
#AUTO
NO TE: THIS IS THE PROGRAM THAT RUNS AUTOMATICALLY ON CONTROLLER STARTUP
MT-2,-2,-2,-2,-2,-2,-2,-2;'CONFIGURES ALL AXES AS STEPPER
MO;' FIRST TIME MOTOR OFF
CN 1;' CONFIGURES LIMIT SWITCHES TO ACCEPT NC CONTACTS
II 8,,,0;' CONFIGURES THE 8TH INPUT TO ACTIVATE THE #ININT ROUTINE
OP 65280;' SETS OUTPUTS 9-16 ON = RELAYS OFF
IA 137,157,202,68;' CONFIGURES IP ADDRESS
AC 12500,12500,12500,12500,12500,12500,12500,12500;' SET ACELERATION
DC 12500,12500,12500,12500,12500,12500,12500,12500;' SET DECELERATION
SP 25000,25000,25000,25000,25000,25000,25000,25000;' SET SPEED
SIA=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIB=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIC=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SID=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIE=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIF=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIG=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIH=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
JS #THREAD0
EN
NO ----------------------------------------
#THREAD0
NO TE: THERE MUST BE A THREAD RUNNING FOR #LIMSWI, #TCPERR AND #ININT TO WORK
NO TE: CHECKS IF SPEEDS ARE ABOVE MAXIMUM ALLOWED
IF (_SPA>25000)
SPA=25000
ENDIF
IF (_SPB>25000)
SPB=25000
ENDIF
IF (_SPC>25000)
SPC=25000
ENDIF
IF (_SPD>25000)
SPD=25000
ENDIF
IF (_SPE>25000)
SPE=25000
ENDIF
IF (_SPF>25000)
SPF=25000
ENDIF
IF (_SPG>25000)
SPG=25000
ENDIF
IF (_SPH>25000)
SPH=25000
ENDIF
JP #THREAD0
EN
NO ----------------------------------------
#TCPERR
NO TE: EMPTY ROUTINE FOR A TCP ERROR
RE
NO ----------------------------------------
#ININT
NO TE: INTERUPT ROUTINE TO STOP ALL AXES
NO TE: WHEN SAFETY & INTERLOCK SYSTEM REQUESTS IT
STA,B,C,D,E,F,G,H
AM
MO
RI
NO ----------------------------------------
#CMDERR
NO TE: THIS IS A ROUTINE TO HANDLE COMMAND ERRORS
ZS0;' ZERO STACK
EN1
NO ----------------------------------------
#LIMSWI
NO TE: LIMIT SWITCH ROUTINE WHICH SHORTENS DECEL TIME WHEN A LIMIT IS HIT
OLDDCA=_DCA;' REMEMBERS CURRENT DECEL
OLDDCB=_DCB
OLDDCC=_DCC
OLDDCD=_DCD
OLDDCE=_DCE
OLDDCF=_DCF
OLDDCG=_DCG
OLDDCH=_DCH
IF (_LFA = 0) | (_LRA = 0)
DCA=75000;' DECEL FOR LIMIT HIT OCCURENCE
STA
ENDIF
IF (_LFB = 0) | (_LRB = 0)
DCB=75000;' DECEL FOR LIMIT HIT OCCURENCE
STB
ENDIF
IF (_LFC = 0) | (_LRC = 0)
DCC=75000;' DECEL FOR LIMIT HIT OCCURENCE
STC
ENDIF
IF (_LFD = 0) | (_LRD = 0)
DCD=75000;' DECEL FOR LIMIT HIT OCCURENCE
STD
ENDIF
IF (_LFE = 0) | (_LRE = 0)
DCE=75000;' DECEL FOR LIMIT HIT OCCURENCE
STE
ENDIF
IF (_LFF = 0) | (_LRF = 0)
DCF=75000;' DECEL FOR LIMIT HIT OCCURENCE
STF
ENDIF
IF (_LFG = 0) | (_LRG = 0)
DCG=75000;' DECEL FOR LIMIT HIT OCCURENCE
STG
ENDIF
IF (_LFH = 0) | (_LRH = 0)
DCH=75000;' DECEL FOR LIMIT HIT OCCURENCE
STH
ENDIF
AM ABCDEFGH;' AFTER ALL AXES STOPPED
DCA=OLDDCA;' RESET DECEL TO OLD VALUE
DCB=OLDDCB
DCC=OLDDCC
DCD=OLDDCD
DCE=OLDDCE
DCF=OLDDCF
DCG=OLDDCG
DCH=OLDDCH
RE

View File

@@ -0,0 +1,140 @@
NO TE: QUOKKA - CONTROLLER 3
NO TE:
NO TE: $Revision: 1.6 $
NO TE: $Name: not supported by cvs2svn $
NO TE: $Date: 2008-05-30 00:26:57 $
NO TE: Author: Dan Bartlett
NO TE: Last revision by: $Author: ffr $
NO TE:
NO TE: A-COLLIMATION OPTICS - CHAMBER 9
NO TE: B-COLLIMATION OPTICS - CHAMBER 10
NO TE: C-SOURCE END CHAMBER - PENTAPRISM
NO TE: D-SOURCE END CHAMBER - SRC APERTURES
NO TE: E-SPARE WITH 8 AMP AMPLIFIER
NO TE: F-SPARE WITH 8 AMP AMPLIFIER
NO TE: G-ROTARY ATTENUATOR
NO TE: H-SPARE
NO TE:
NO TE: +VE MOTOR MOVES COLL. 9&10 IN A WESTERLY DIRECTION
NO ----------------------------------------
#AUTO
NO TE: THIS IS THE PROGRAM THAT RUNS AUTOMATICALLY ON CONTROLLER STARTUP
MT-2,-2,-2,-2,-2,-2,-2,-2;'CONFIGURES ALL AXES AS STEPPER
MO;' FIRST TIME MOTOR OFF
CN 1;' CONFIGURES LIMIT SWITCHES TO ACCEPT NC CONTACTS
II 8,,,0;' CONFIGURES THE 8TH INPUT TO ACTIVATE THE #ININT ROUTINE
OP 65280;' SETS OUTPUTS 9-16 ON = RELAYS OFF
IA 137,157,202,69;' CONFIGURES IP ADDRESS
AC 12500,12500,25000,25000,,,25000,;' SET ACELERATION
DC 12500,12500,25000,25000,,,25000,;' SET DECELERATION
SP 25000,25000,25000,25000,,,25000,;' SET SPEED
SIA=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIB=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIC=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SID=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIE=0,25,13,0<-2>2;'NOT USED
SIF=0,25,13,0<-2>2;'NOT USED
SIG=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIH=0,25,13,0<-2>2;'NOT USED
JS #THREAD0
EN
NO ----------------------------------------
#THREAD0
NO TE: THERE MUST BE A THREAD RUNNING FOR #LIMSWI, #TCPERR AND #ININT TO WORK
NO TE: CHECKS IF SPEEDS ARE ABOVE MAXIMUM ALLOWED
IF (_SPA>25000)
SPA=25000
ENDIF
IF (_SPB>25000)
SPB=25000
ENDIF
IF (_SPC>50000)
SPC=50000
ENDIF
IF (_SPD>50000)
SPD=50000
ENDIF
NO IF (_SPE>50000)
NO SPE=50000
NO ENDIF
NO IF (_SPF>50000)
NO SPF=50000
NO ENDIF
IF (_SPG>50000)
SPG=50000
ENDIF
NO IF (_SPH>50000)
NO SPH=50000
NO ENDIF
JP #THREAD0
EN
NO ----------------------------------------
#TCPERR
NO TE: EMPTY ROUTINE FOR A TCP ERROR
RE
NO ----------------------------------------
#ININT
NO TE: INTERUPT ROUTINE TO STOP ALL AXES
NO TE: WHEN SAFETY & INTERLOCK SYSTEM REQUESTS IT
STA,B,C,D,E,F,G,H
AM
MO
RI
NO ----------------------------------------
#CMDERR
NO TE: THIS IS A ROUTINE TO HANDLE COMMAND ERRORS
ZS0;' ZERO STACK
EN1
NO ----------------------------------------
#LIMSWI
NO TE: LIMIT SWITCH ROUTINE WHICH SHORTENS DECEL TIME WHEN A LIMIT IS HIT
OLDDCA=_DCA;' REMEMBERS CURRENT DECEL
OLDDCB=_DCB
OLDDCC=_DCC
OLDDCD=_DCD
NO OLDDCE=_DCE
NO OLDDCF=_DCF
OLDDCG=_DCG
NO OLDDCH=_DCH
IF (_LFA = 0) | (_LRA = 0)
DCA=75000;' DECEL FOR LIMIT HIT OCCURENCE
STA
ENDIF
IF (_LFB = 0) | (_LRB = 0)
DCB=75000;' DECEL FOR LIMIT HIT OCCURENCE
STB
ENDIF
IF (_LFC = 0) | (_LRC = 0)
DCC=100000;' DECEL FOR LIMIT HIT OCCURENCE
STC
ENDIF
IF (_LFD = 0) | (_LRD = 0)
DCD=100000;' DECEL FOR LIMIT HIT OCCURENCE
STD
ENDIF
NO IF (_LFE = 0) | (_LRE = 0)
NO DCE=100000;' DECEL FOR LIMIT HIT OCCURENCE
NO STE
NO ENDIF
NO IF (_LFF = 0) | (_LRF = 0)
NO DCF=100000;' DECEL FOR LIMIT HIT OCCURENCE
NO STF
NO ENDIF
IF (_LFG = 0) | (_LRG = 0)
DCG=100000;' DECEL FOR LIMIT HIT OCCURENCE
STG
ENDIF
NO IF (_LFH = 0) | (_LRH = 0)
NO DCH=100000;' DECEL FOR LIMIT HIT OCCURENCE
NO STH
ENDIF
AM ABCDEFGH;' AFTER ALL AXES STOPPED
DCA=OLDDCA;' RESET DECEL TO OLD VALUE
DCB=OLDDCB
DCC=OLDDCC
DCD=OLDDCD
NO DCE=OLDDCE
NO DCF=OLDDCF
DCG=OLDDCG
NO DCH=OLDDCH
RE

View File

@@ -0,0 +1,152 @@
NO TE: QUOKKA - CONTROLLER 4
NO TE:
NO TE: $Revision: 1.8 $
NO TE: $Name: not supported by cvs2svn $
NO TE: $Date: 2008-05-30 00:26:57 $
NO TE: Author: Dan Bartlett
NO TE: Last revision by: $Author: ffr $
NO TE:
NO TE: A-BEAM STOPS TRANS. X (ACCROSS BEAM) +VE=WEST
NO TE: B-BEAM STOPS TRANSLATION - RAISE
NO TE: C-BEAM STOP 1 -VE=UP (LARGEST DISK)
NO TE: D-BEAM STOP 2 -VE=UP
NO TE: E-BEAM STOP 3 +VE=UP
NO TE: F-BEAM STOP 4 -VE=UP
NO TE: G-BEAM STOP 5 +VE=UP (SMALLEST DISK)
NO TE: H-POLARISER
NO ----------------------------------------
#AUTO
NO TE: THIS IS THE PROGRAM THAT RUNS AUTOMATICALLY ON CONTROLLER STARTUP
MT-2,-2,-2,-2,-2,-2,-2,-2;'CONFIGURES ALL AXES AS STEPPER
MO;' FIRST TIME MOTOR OFF
CN 1;' CONFIGURES LIMIT SWITCHES TO ACCEPT NC CONTACTS
II 8,,,0;' CONFIGURES THE 8TH INPUT TO ACTIVATE THE #ININT ROUTINE
OP 65280;' SETS OUTPUTS 9-16 ON = RELAYS OFF
IA 137,157,202,70;' CONFIGURES IP ADDRESS
AC 25000,100000,5000,15000,15000,15000,15000,25000;' SET ACELERATION
DC 25000,100000,5000,15000,15000,15000,15000,25000;' SET DECELERATION
SP 100000,100000,30000,40000,40000,40000,40000,25000;' SET SPEED
SIA=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIB=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
SIC=0,25,13,0<-2>2;'NO ENCODER
SID=0,25,13,0<-2>2;'NO ENCODER
SIE=0,25,13,0<-2>2;'NO ENCODER
SIF=0,25,13,0<-2>2;'NO ENCODER
SIG=0,25,13,0<-2>2;'NO ENCODER
SIH=1,25,13,0<-2>2;'HEIDENHAIN ROQ425
JS #THREAD0
EN
NO ----------------------------------------
#THREAD0
NO TE: THERE MUST BE A THREAD RUNNING FOR #LIMSWI, #TCPERR AND #ININT TO WORK
NO TE: CHECKS IF SPEEDS ARE ABOVE MAXIMUM ALLOWED
IF (_SPA>100000)
SPA=100000
ENDIF
IF (_SPB>100000)
SPB=100000
ENDIF
IF (_SPC>50000)
SPC=50000
ENDIF
IF (_SPD>50000)
SPD=50000
ENDIF
IF (_SPE>50000)
SPE=50000
ENDIF
IF (_SPF>50000)
SPF=50000
ENDIF
IF (_SPG>50000)
SPG=50000
ENDIF
IF (_SPH>50000)
SPH=50000
ENDIF
NO TE: CONTROLS THE BEAM STOPS RAISE ELECTRO-MECHANICAL BRAKE
IF (_MOB=0)
CB 10;' MOTOR ON = BRAKE ENERGISED = UNLOCKED
ELSE
SB 10;' MOTOR OFF = BRAKE DENERGISED = LOCKED
ENDIF
NO TE: SETS AN OUTPUT IF ONE OR MORE BEAM STOPS ARE FULLY RAISED
NO TE: OUTPUT 5 ON IF ONE OR MORE BEAMS TOPS RAISED
NO IF (_TSC&12=4)|(_TSD&12=4)|(_TSE&12=4)|(_TSF&12=4)|(_TSG&12=4)
NO TE: IF ANY OF THE 5 BEAMSTOPS IS NOT DOWN AND UP THEN SET BIT 1 HIGH
NO SB1
NO ELSE
NO CB1
NO ENDIF
JP #THREAD0
EN
NO ----------------------------------------
#TCPERR
NO TE: EMPTY ROUTINE FOR A TCP ERROR
RE
NO ----------------------------------------
#ININT
NO TE: INTERUPT ROUTINE TO STOP ALL AXES
NO TE: WHEN SAFETY & INTERLOCK SYSTEM REQUESTS IT
STA,B,C,D,E,F,G,H
AM
MO
RI
NO ----------------------------------------
#CMDERR
NO TE: THIS IS A ROUTINE TO HANDLE COMMAND ERRORS
ZS0;' ZERO STACK
EN1
NO ----------------------------------------
#LIMSWI
NO TE: LIMIT SWITCH ROUTINE WHICH SHORTENS DECEL TIME WHEN A LIMIT IS HIT
OLDDCA=_DCA;' REMEMBERS CURRENT DECEL
OLDDCB=_DCB
OLDDCC=_DCC
OLDDCD=_DCD
OLDDCE=_DCE
OLDDCF=_DCF
OLDDCG=_DCG
OLDDCH=_DCH
IF (_LFA = 0) | (_LRA = 0)
DCA=100000;' DECEL FOR LIMIT HIT OCCURENCE
STA
ENDIF
IF (_LFB = 0) | (_LRB = 0)
DCB=200000;' DECEL FOR LIMIT HIT OCCURENCE
STB
ENDIF
IF (_LFC = 0) | (_LRC = 0)
DCC=100000;' DECEL FOR LIMIT HIT OCCURENCE
STC
ENDIF
IF (_LFD = 0) | (_LRD = 0)
DCD=100000;' DECEL FOR LIMIT HIT OCCURENCE
STD
ENDIF
IF (_LFE = 0) | (_LRE = 0)
DCE=100000;' DECEL FOR LIMIT HIT OCCURENCE
STE
ENDIF
IF (_LFF = 0) | (_LRF = 0)
DCF=100000;' DECEL FOR LIMIT HIT OCCURENCE
STF
ENDIF
IF (_LFG = 0) | (_LRG = 0)
DCG=100000;' DECEL FOR LIMIT HIT OCCURENCE
STG
ENDIF
IF (_LFH = 0) | (_LRH = 0)
DCH=100000;' DECEL FOR LIMIT HIT OCCURENCE
STH
ENDIF
AM ABCDEFGH;' AFTER ALL AXES STOPPED
DCA=OLDDCA;' RESET DECEL TO OLD VALUE
DCB=OLDDCB
DCC=OLDDCC
DCD=OLDDCD
DCE=OLDDCE
DCF=OLDDCF
DCG=OLDDCG
DCH=OLDDCH
RE

View File

@@ -0,0 +1,5 @@
lyrebird_configuration.tcl
sics_ports.tcl
script_validator_ports.tcl
config
util

View File

@@ -0,0 +1,5 @@
all:
make -C config
clean:
make -C config clean

View File

@@ -0,0 +1,17 @@
config/source/source_common.tcl
config/anticollider/anticollider_common.tcl
config/plc/plc_common_1.tcl
config/counter/counter_common_1.tcl
config/hipadaba/hipadaba_configuration_common.tcl
config/hipadaba/common_instrument_dictionary.tcl
config/hipadaba/instdict_specification.tcl
config/hmm/hmm_configuration_common_1.tcl
config/hmm/hmm_object.tcl
config/hmm/anstohm_linked.xml
config/hmm/sct_orhvps_common.tcl
config/scan/scan_common_1.hdd
config/scan/scan_common_1.tcl
config/nexus/nxscripts_common_1.tcl
config/commands/commands_common.tcl
config/motors/sct_positmotor_common.tcl
config/motors/sct_jogmotor_common.tcl

View File

@@ -0,0 +1,4 @@
all:
clean:

View File

@@ -0,0 +1,3 @@
# Forbid detector motion when the detector voltage is on
forbid {-inf inf} for det when dhv1 in {800 inf}
forbid {-inf inf} for detoff when dhv1 in {800 inf}

View File

@@ -0,0 +1,14 @@
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
source $cfPath(anticollider)/anticollider_common.tcl
# NOTE: This is called with a list of motorname target pairs
proc ::anticollider::enable {args} {
if {[SplitReply [::anticollider::protect_detector]] == "false"} {
return "false"
} else {
return "true"
}
}
::anticollider::loadscript acscript.txt

View File

@@ -0,0 +1,418 @@
##
# @file Spin flipper control for Quokka
#
# Author: Ferdi Franceschini (ffr@ansto.gov.au) May 2010
#
# The spin flipper can be installed with the following command,
# ::scobj::rfgen::mkFlipper {
# name "flipper"
# address 1
# opCurr 68
# opFreq 241
# IP localhost
# PORT 65123
# tuning 1
# currtol 1
# interval 2
# }
#
# NOTE:
# If tuning=1 this will generate flipper/set_current and flipper/set_frequency
# nodes for the instrument scientists.
# The tuning parameter should be set to 0 for the users.
#
# The operation_manual_Platypus_polarization_system.doc:Sec 3.1 states the following
# Attention
# a) Do not switch on the RF output with non-zero current setting (the current
# control becomes unstable)! If unsure, rotate the current setting
# potentiometer 10 turns counter-clockwise.
# b) In case of RF vacuum discharge (harmful for the system)
# " the main symptom is that the RF power source turns into CV mode, the
# voltage increases to 34 Vem and the current decreases;
# " switch off the RF output;
# " decrease current setting by rotating the potentiometer 10 turns counter-clockwise;
# " verify the vacuum level in the tank and restart the flipper operation only if it is below 0.01 mbar.
namespace eval ::scobj::rfgen {
# Control states
variable RAMPIDLE 0
variable RAMPSTOP 1
variable RAMPSTART 2
variable RAMPBUSY 3
variable RAMPTOZERO 4
variable FLIPOFF 5
variable MAXVOLTAGE 34
}
##
# @brief Utility for trimming zero padding from current and frequency readings.
# We do this to avoid misinterpreting numbers as octal
proc ::scobj::rfgen::mkStatArr {stateArrName stateReport} {
upvar $stateArrName stateArr
array set stateArr $stateReport
if {$stateArr(curr) != 0} {
set val [string trimleft $stateArr(curr) 0]
if {[string is integer $val]} {
set stateArr(curr) $val
} else {
set stateArr(curr) -1
}
}
if {$stateArr(freq) != 0} {
set val [string trimleft $stateArr(freq) 0]
if {[string is integer $val]} {
set stateArr(freq) $val
} else {
set stateArr(freq) -1
}
}
if {$stateArr(voltage) != 0} {
set val [string trimleft $stateArr(voltage) 0]
if {[string is integer $val]} {
set stateArr(voltage) $val
} else {
set stateArr(voltage) -1
}
}
}
##
# @brief Switch the spin flipper on or off
proc ::scobj::rfgen::set_flip_on {basePath} {
variable RAMPSTART
variable RAMPTOZERO
set flipState [sct target]
switch $flipState {
"0" {
hsetprop $basePath targetCurr 0
hsetprop $basePath OutputState 0
hsetprop $basePath ramping $RAMPSTART
sct update 0
sct utime readtime
}
"1" {
hsetprop $basePath targetCurr [hgetpropval $basePath opCurr]
hsetprop $basePath targetFreq [hgetpropval $basePath opFreq]
hsetprop $basePath OutputState 1
hsetprop $basePath ramping $RAMPSTART
sct update 1
sct utime readtime
}
default {
set ErrMsg "[sct] invalid input $flipState, Valid states for [sct] are 1 or 0"
sct seterror "ERROR: $ErrMsg"
return -code error $ErrMsg
}
}
return idle
}
##
# @brief Get the target current and scale it for the RF generator.
# Also updates the operating current for this session.
#
# @param basePath, The "spin-flipper" object path, this is where we keep our state variables.
proc ::scobj::rfgen::set_current {basePath} {
variable RAMPSTART
set newCurr [sct target]
set current [expr {round(10.0 * $newCurr)}]
hsetprop $basePath targetCurr $current
hsetprop $basePath opCurr $current
hsetprop $basePath ramping $RAMPSTART
hsetprop $basePath OutputState 1
return idle
}
##
# @brief Get the target frequency. Also updates the operating frequency for this session.
#
# @param basePath, The "spin-flipper" object path, this is where we keep our state variables.
proc ::scobj::rfgen::set_frequency {basePath} {
variable RAMPSTART
set newFreq [sct target]
hsetprop $basePath targetFreq $newFreq
hsetprop $basePath opFreq $newFreq
hsetprop $basePath ramping $RAMPSTART
hsetprop $basePath OutputState 1
return idle
}
##
# @brief Request a state report from the RF generator
proc ::scobj::rfgen::rqStatFunc {} {
sct send "L:[sct address]"
return rdState
}
##
# @brief Read and record the state report from the RF generator
proc ::scobj::rfgen::rdStatFunc {} {
variable RAMPBUSY
variable RAMPSTART
variable RAMPTOZERO
variable RAMPIDLE
variable FLIPOFF
variable MAXVOLTAGE
set basePath [sct]
set currSuperState [sct ramping]
set updateFlipper 0
set statStr [sct result]
if {[string match "ASCERR:*" $statStr]} {
sct geterror $statStr
sct ramping $RAMPIDLE
return stateChange
}
set statList [split $statStr "|="]
foreach {k v} $statList {
if {$k == "type"} {
lappend temp "$k $v"
continue
}
if {[string is integer $v]} {
lappend temp "$k $v"
} else {
lappend temp "$k -1"
}
}
set statList [join $temp]
mkStatArr stateArr $statList
if {$statList != [sct oldStateRep]} {
hset $basePath/flip_current [expr {$stateArr(curr) / 10.0}]
hset $basePath/flip_frequency $stateArr(freq)
hset $basePath/flip_voltage $stateArr(voltage)
hset $basePath/flip_on $stateArr(O)
hset $basePath/state_report $statList
sct update $statList
sct utime readtime
sct oldStateRep $statList
}
if {$currSuperState != $FLIPOFF && $stateArr(curr) > [sct currTol] && $stateArr(O) && $stateArr(CV)} {
broadcast "WARNING: spin flipper has switched to voltage control, voltage = $stateArr(voltage)"
if {$stateArr(voltage) >= $MAXVOLTAGE} {
sct ramping $FLIPOFF
}
}
return stateChange
}
##
# @brief State transition function
proc ::scobj::rfgen::stateFunc {} {
variable RAMPIDLE
variable RAMPSTOP
variable RAMPSTART
variable RAMPBUSY
variable RAMPTOZERO
variable FLIPOFF
variable MAXVOLTAGE
set basePath [sct]
set currSuperState [sct ramping]
mkStatArr stateArr [hval $basePath/state_report]
set currControlStatus [sct status]
switch $currSuperState [ subst -nocommands {
$RAMPSTART {
# broadcast RAMPSTART
if [string match $currControlStatus "IDLE"] {
statemon start flipper
sct status "BUSY"
sct ramping $RAMPBUSY
return ramp
} else {
# Flipper is off, set current to zero before switching on
sct origTargetCurr [sct targetCurr]
sct targetCurr 0
sct OutputState 0
sct ramping $RAMPTOZERO
return ramp
}
}
$RAMPTOZERO {
# broadcast RAMPTOZERO
if {$stateArr(curr) <= [sct currTol]} {
# We've reached a safe state so switch on and ramp to target current
sct targetCurr [sct origTargetCurr]
sct OutputState 1
sct ramping $RAMPBUSY
} else {
sct targetCurr 0
sct OutputState 0
}
return ramp
}
$RAMPBUSY {
# broadcast RAMPBUSY
if { [expr {abs($stateArr(curr) - [sct targetCurr])}] <= [sct currTol] } {
sct ramping $RAMPSTOP
return idle
}
return ramp
}
$FLIPOFF {
sct targetCurr 0
sct OutputState 0
if { $stateArr(curr) <= [sct currTol] } {
sct ramping $RAMPSTOP
broadcast "ERROR: Spin flipper switched off voltage exceeds $MAXVOLTAGE in voltage control state, check vacuum"
return idle
} else {
return ramp
}
}
$RAMPSTOP {
# broadcast RAMPSTOP
if [string match $currControlStatus "BUSY"] {
statemon stop flipper
sct status "IDLE"
}
sct ramping $RAMPIDLE
return idle
}
$RAMPIDLE {
# broadcast RAMPIDLE
return idle
}
}]
}
##
# @brief Ramps the current up or down in steps of 0.5A and/or sets the frequency
proc ::scobj::rfgen::rampFunc {} {
set basePath [sct]
set currSuperState [sct ramping]
mkStatArr stateArr [hval $basePath/state_report]
set targetCurr [sct targetCurr]
set targetFreq [sct targetFreq]
set output [sct OutputState]
if { [expr {abs($stateArr(curr) - [sct targetCurr])}] <= [sct currTol] } {
set curr $stateArr(curr)
} elseif {$targetCurr < $stateArr(curr)} {
set curr [expr $stateArr(curr)-5]
if {$curr < $targetCurr} {
set curr $targetCurr
}
} elseif {$targetCurr > $stateArr(curr)} {
set curr [expr $stateArr(curr)+5]
if {$curr > $targetCurr} {
set curr $targetCurr
}
}
set reply [sct_rfgen send "S:[sct address]:I=$curr:F=$targetFreq:K3=$stateArr(K3):K2=$stateArr(K2):K1=$stateArr(K1):O=$output"]
return idle
}
##
# @brief Make a spin flipper control object
#
# @param argList, {name "flipper" address "1" opCurr 68 opFreq 241 IP localhost PORT 65123 tuning 0 interval 1}
#
# name: name of spin flipper object
# address: address assigned to RF generator 1-9
# opCurr: the operating current, when you switch the spin flipper on it will ramp to this current
# opFreq: the operating frequency, when you switch on the spin flipper it will set this frequency
# IP: IP address of RF generator moxa box
# PORT: Port number assigned to the generator on the moxa-box
# tuning: boolean, set tuning=1 to allow instrument scientists to set the current and frequency
# interval: polling and ramping interval in seconds. One sets the ramp rate to 0.5A/s
proc ::scobj::rfgen::mkFlipper {argList} {
variable RAMPIDLE
# Generate parameter array from the argument list
foreach {k v} $argList {
set KEY [string toupper $k]
set pa($KEY) $v
}
MakeSICSObj $pa(NAME) SCT_OBJECT
sicslist setatt $pa(NAME) klass instrument
sicslist setatt $pa(NAME) long_name $pa(NAME)
# hfactory /sics/$pa(NAME)/status plain spy text
hsetprop /sics/$pa(NAME) status "IDLE"
hfactory /sics/$pa(NAME)/state_report plain internal text
hfactory /sics/$pa(NAME)/flip_current plain internal float
hfactory /sics/$pa(NAME)/flip_frequency plain internal int
hfactory /sics/$pa(NAME)/flip_voltage plain internal int
hfactory /sics/$pa(NAME)/flip_on plain internal int
hsetprop /sics/$pa(NAME) read ::scobj::rfgen::rqStatFunc
hsetprop /sics/$pa(NAME) rdState ::scobj::rfgen::rdStatFunc
hsetprop /sics/$pa(NAME) stateChange ::scobj::rfgen::stateFunc
hsetprop /sics/$pa(NAME) ramp ::scobj::rfgen::rampFunc
hsetprop /sics/$pa(NAME) address $pa(ADDRESS)
hsetprop /sics/$pa(NAME) tuning $pa(TUNING)
hsetprop /sics/$pa(NAME) ramping $RAMPIDLE
hsetprop /sics/$pa(NAME) opCurr $pa(OPCURR)
hsetprop /sics/$pa(NAME) opFreq $pa(OPFREQ)
hsetprop /sics/$pa(NAME) targetCurr 0
hsetprop /sics/$pa(NAME) origTargetCurr 0
hsetprop /sics/$pa(NAME) oldStateRep ""
hsetprop /sics/$pa(NAME) currTol $pa(CURRTOL)
hfactory /sics/$pa(NAME)/comp_current plain internal float
hsetprop /sics/$pa(NAME)/comp_current units "A"
hset /sics/$pa(NAME)/comp_current $pa(COMPCURR)
hfactory /sics/$pa(NAME)/guide_current plain internal float
hsetprop /sics/$pa(NAME)/guide_current units "A"
hset /sics/$pa(NAME)/guide_current $pa(GUIDECURR)
hfactory /sics/$pa(NAME)/thickness plain internal float
hsetprop /sics/$pa(NAME)/thickness units "mm"
hset /sics/$pa(NAME)/thickness $pa(THICKNESS)
hfactory /sics/$pa(NAME)/set_flip_on plain user int
hsetprop /sics/$pa(NAME)/set_flip_on write ::scobj::rfgen::set_flip_on /sics/$pa(NAME)
# Only create the set current and frequency nodes when commissioning
# Initialise properties required for generating the API for GumTree and to save data
::scobj::hinitprops $pa(NAME) flip_current flip_frequency flip_voltage flip_on comp_current guide_current thickness
hsetprop /sics/$pa(NAME)/comp_current mutable false
hsetprop /sics/$pa(NAME)/guide_current mutable false
hsetprop /sics/$pa(NAME)/thickness mutable false
if {[SplitReply [rfgen_simulation]] == "false"} {
makesctcontroller sct_rfgen rfamp $pa(IP):$pa(PORT)
mkStatArr stateArr [split [sct_rfgen transact "L:$pa(ADDRESS)"] "|="]
hset /sics/$pa(NAME)/flip_current [expr {$stateArr(curr) / 10.0}]
hset /sics/$pa(NAME)/flip_frequency $stateArr(freq)
hset /sics/$pa(NAME)/flip_voltage $stateArr(voltage)
hset /sics/$pa(NAME)/flip_on $stateArr(O)
hsetprop /sics/$pa(NAME) targetFreq $stateArr(freq)
hsetprop /sics/$pa(NAME) targetCurr [expr {$stateArr(curr) / 10.0}]
sct_rfgen poll /sics/$pa(NAME) $pa(INTERVAL)
sct_rfgen write /sics/$pa(NAME)/set_flip_on
}
if {$pa(TUNING)} {
hfactory /sics/$pa(NAME)/set_current plain user float
hfactory /sics/$pa(NAME)/set_frequency plain user int
hsetprop /sics/$pa(NAME)/set_current write ::scobj::rfgen::set_current /sics/$pa(NAME)
hsetprop /sics/$pa(NAME)/set_frequency write ::scobj::rfgen::set_frequency /sics/$pa(NAME)
if {[SplitReply [rfgen_simulation]] == "false"} {
sct_rfgen write /sics/$pa(NAME)/set_current
sct_rfgen write /sics/$pa(NAME)/set_frequency
}
}
}

View File

@@ -0,0 +1,18 @@
fileeval $cfPath(beamline)/sct_flipper.tcl
# NOTE: opCurr is 10 * your operating current, ie if the current is 7.1 then opCurr = 71
::scobj::rfgen::mkFlipper {
name "flipper"
address 1
opCurr 71
opFreq 407
IP 137.157.202.86
PORT 4001
tuning 1
interval 2
currtol 1
compCurr 1
guideCurr 1
thickness 1
}

View File

@@ -0,0 +1,216 @@
source $cfPath(commands)/commands_common.tcl
namespace eval motor {
# is_homing_list = comma separated list of motors which are safe to send "home"
variable is_homing_list ""
}
#namespace eval sample {
# command select {int=0:8 sampid} {
# SampleNum $sampid
# }
#}
##
# @brief Beamstop select command
# @param bs beamstop, 1,2,3,4,5 or 6
# @param bx beam position in detector coordinates
# @param bz beam position in detector coordinates
# Given
# (Xbf,Zbf) = beam pos in frame coords
# (Xbd,Zbd) = beam pos in detector coords
# (Xbbs, Zbbs) = beam pos in beamstop coords
# (Xdf,Zdf) = detector pos in frame coords
# (Xbsf,Zbsf) = beamstop pos in frame coords
#
# (Xbf,Zbf) = (Xdf+Xbd, Zdf+Zbd) = (Xbsf+Xbbs, Zbsf+Zbbs)
# Origin of detector coords = frame origin
#
# Detector and beamstop motor readings with beamstop disk centers
# overlapping over detector center mark.
# Xdf = 264.542 (7283813) Zdf = 0
# Xbbs = 296.291 (8054270)
# Zbbs = 259.641 (13488244)
# Xbd = dethw, Zbd = (dethh)
#
# 264.542+dethw = Xbsf+296.291
# 0+dethh = Zbsf+259.641
#
# Xbsf = -31.749 + dethw, Zbsf = -259.641 + dethh
proc selbs {bs {bx "UNDEF"} {bz "UNDEF"}} {
set bsdriving false
set dethw [expr {[SplitReply [detector_active_height_mm]]/2.0}]
set dethh [expr {[SplitReply [detector_active_width_mm]]/2.0}]
set Xbsf [expr -31.749 + $dethw]
set Zbsf [expr -259.641 + $dethh]
array set bsl [subst {
1 [SplitReply [bs1 softlowerlim]]
2 [SplitReply [bs2 softlowerlim]]
3 [SplitReply [bs3 softlowerlim]]
4 [SplitReply [bs4 softlowerlim]]
5 [SplitReply [bs5 softlowerlim]]
6 [SplitReply [bs6 softlowerlim]]
}]
if [ catch {
switch $bs {
"1" {
set bsmot "bs1"
set bs_target 93.20
set bs_diameter 110
set bsdownCmd "drive bs2 $bsl(2) bs3 $bsl(3) bs4 $bsl(4) bs5 $bsl(5) bs6 $bsl(6)"
}
"2" {
set bsmot "bs2"
set bs_target 86.84
set bs_diameter 88
set bsdownCmd "drive bs1 $bsl(1) bs3 $bsl(3) bs4 $bsl(4) bs5 $bsl(5) bs6 $bsl(6)"
}
"3" {
set bsmot "bs3"
set bs_target 93.35
set bs_diameter 66
set bsdownCmd "drive bs2 $bsl(2) bs1 $bsl(1) bs4 $bsl(4) bs5 $bsl(5) bs6 $bsl(6)"
}
"4" {
set bsmot "bs4"
set bs_target 86.85
set bs_diameter 44
set bsdownCmd "drive bs2 $bsl(2) bs3 $bsl(3) bs1 $bsl(1) bs5 $bsl(5) bs6 $bsl(6)"
}
"5" {
set bsmot "bs5"
set bs_target 93.27
set bs_diameter 22
set bsdownCmd "drive bs2 $bsl(2) bs3 $bsl(3) bs4 $bsl(4) bs1 $bsl(1) bs6 $bsl(6)"
}
"6" {
set bsmot "bs6"
set bs_target 86.98
set bs_diameter 11
set bsdownCmd "drive bs2 $bsl(2) bs3 $bsl(3) bs4 $bsl(4) bs5 $bsl(5) bs1 $bsl(1)"
}
default {
error "beamstop selection must be an integer from 1 to 6"
}
}
set detoff_val [SplitReply [detoff]]
if {$bx == "UNDEF" || $bz == "UNDEF"} {
statemon start selbs
if {[info level] > 1} {statemon start [lindex [info level -1] 0]}
set bsdriving true
BeamStop -1
BSdiam -1
drive $bsmot $bs_target
eval $bsdownCmd
BeamStop $bs
BSdiam $bs_diameter
set bsdriving false
statemon stop selbs
if {[info level] > 1} {statemon stop [lindex [info level -1] 0]}
} else {
if { [string is double $bx] == false } {
if { [string is double $bz] == false } {
error "beam coordinates must be floats"
}
}
set bsx_target [expr {$bx-$Xbsf+$detoff_val}]
set bsz_target [expr {$bz-$Zbsf}]
statemon start selbs
if {[info level] > 1} {statemon start [lindex [info level -1] 0]}
set bsdriving true
BeamStop -1
BSdiam -1
drive $bsmot $bs_target bsx $bsx_target bsz $bsz_target
eval $bsdownCmd
BeamStop $bs
BSdiam $bs_diameter
set bsdriving false
statemon stop selbs
if {[info level] > 1} {statemon stop [lindex [info level -1] 0]}
}
} msg ] {
if {$bsdriving} {
statemon stop selbs
if {[info level] > 1} {statemon stop [lindex [info level -1] 0]}
}
return -code error $msg
}
}
publish selbs user
namespace eval beamstops {
command selbsn {int=1,2,3,4,5,6 bs} {
selbs $bs "UNDEF" "UNDEF"
}
command selbsxz {int=1,2,3,4,5,6 bs float bx float bz} {
selbs $bs $bx $bz
}
}
namespace eval optics {
VarMake ::optics::select::section text user
VarMake ::optics::polarizer::in text user
VarMake ::optics::lens::selection text user
command rotary_attenuator {int=0,15,45,90,180 angle} {
drive att $angle
}
command entrance_aperture {
int=0,45,90,135,180,270 angle
} {
drive srce $angle
}
# TODO Do we need this
# command sample_aperture {
# int=25,50 size
# text=circ,squ,open,rect shape
# } {
# SApXmm $size
# SApZmm $size
# SApShape $shape
# }
##############################
##
# @brief The "guide" command uses a lookup table to setup the collimation system
# @param row, selects a row from the guide configuration table
#
# eg\n
# guide ga
command guide "
text=[join [array names ::optics::guide_configuration] , ] configuration
" {
variable guide_configuration
variable guide_configuration_columns
if [ catch {
foreach {compselection position} $guide_configuration($configuration) {
foreach el $compselection guide $guide_configuration_columns {
lappend to_config $guide
lappend to_config [set ::optics::${guide}_map($el)]
}
::optics::guide -set feedback status BUSY
set msg [eval "drive $to_config"]
EApPosY $position
}
GuideConfig $configuration
} message ] {
::optics::guide -set feedback status IDLE
if {$::errorCode=="NONE"} {return $message}
return -code error $message
}
::optics::guide -set feedback status IDLE
}
::optics::guide -addfb text status
::optics::guide -set feedback status IDLE
}
proc ::commands::isc_initialize {} {
::commands::ic_initialize
}

View File

@@ -0,0 +1,28 @@
source $cfPath(counter)/counter_common_1.tcl
## TODO Put all the counter macros in the counter namespace
namespace eval counter {
variable isc_numchannels
variable isc_monitor_address
variable isc_portlist
variable isc_beam_monitor_list
proc set_sobj_attributes {} {
}
}
proc ::counter::isc_initialize {} {
if [catch {
variable isc_numchannels
variable isc_monitor_address
variable isc_portlist
variable isc_beam_monitor_list {MONITOR_1 MONITOR_2 MONITOR_3}
set isc_monitor_address "das1-[SplitReply [instrument]]"
set isc_portlist [list 30000 30001 30002 30003 30004 30005 30006 30007]
set isc_numchannels [llength $isc_beam_monitor_list]
::counter::ic_initialize
} message ] {
if {$::errorCode=="NONE"} {return $message}
return -code error "$message"
}
}

View File

@@ -0,0 +1,55 @@
proc select_environment_controller {envtemp} {
if [ catch {
puts "selecting $envtemp for environment control"
switch $envtemp {
"lh45" {
add_lh45 tc1 ca5-lyrebird 4003 1
proc ::histogram_memory::pre_count {} {
hset /sample/tc1/sensor/start_temperature [hval /sample/tc1/sensor/value]
hset /sample/tc1/sensor/end_temperature [hval /sample/tc1/sensor/value]
}
proc ::histogram_memory::post_count {} {
hset /sample/tc1/sensor/end_temperature [hval /sample/tc1/sensor/value]
}
}
"rhqc" {
puts "Configuring RHQC"
# 9600 8 1 None None Enable
add_sct_ls340 tc1 ca5-[instname] 4001 "\r" 0.5 5.0
# TODO Set controlsensor
# if { [SplitReply [environment_simulation]] == "false"} {
# tc1 controlsensor sensorB
# }
# puts "Added tc1 with [tc1 controlsensor]"
# 9600 8 1 None None Enable
add_sct_ls340 tc2 ca5-[instname] 4002 "\r" 0.5 5.0
# TODO Set controlsensor
# if { [SplitReply [environment_simulation]] == "false"} {
# tc2 controlsensor sensorD
# }
# puts "Added tc2 with [tc2 controlsensor]"
}
"11TMagnet" {
puts "Configuring 11TMagnet"
add_sct_ls340 tc2 ca5-[instname] 4001 "\r" 0.5 5.0
if { [SplitReply [environment_simulation]] == "false"} {
::utility::macro::getset float temperature {} {
return [sicsmsgfmt [hval /sample/tc2/sensor/sensorValueA]]
}
sicslist setatt temperature long_name temperature
sicslist setatt temperature klass sample
sicslist setatt temperature units K
# TODO Set controlsensor
# tc1 controlsensor sensorA
# }
add_ips120 ips120 ca5-lyrebird 4004 0.001
}
default {
clientput "Unknown environment controller $envtemp"
}
}
} msg ] {
puts "Failed to configure $envtemp: $msg"
}
}

View File

@@ -0,0 +1,51 @@
source $cfPath(environment)/temperature/lakeshore340_common.tcl
# @brief Adds a lakeshore 340 temperature controller object.
#
# This must be called when the instrument configuration is loaded and before\n
# the buildHDB function is called. Currently there is no way to add and remove\n
# environment controllers and their hdb paths at runtime.
#
# @param tcn temperature controller name, the hdb name will be tcn_cntrl
# @param mport, the moxa RS232 port number, ie 1,2,3,4
#
# Optional parameters, see lakeshore340_common.tcl for defaults in tc_dfltPar
# @param tolerance, temperature controller tolerance
# @param settle, settling time in seconds
# @param range, lakeshore range
# @param upperlimit, upper temperature limit Kelvin
# @param lowerlimit, lower temperature limit Kelvin
proc ::environment::temperature::add_ls340 {tcn tc_dfltURL mport args} {
variable tc_dfltPar
variable moxaPortMap
if [catch {
if {$tcn == "" || $mport == ""} {
error "ERROR: You must provide a temperature controller name and moxa port number"
}
array set tc_param [array get tc_dfltPar]
if {$args != ""} {
array set tc_param $args
foreach {nm v} $args {
set tc_param($nm) $v
}
}
set sim_mode [SplitReply [environment_simulation]]
if {$sim_mode == "true"} {
::environment::temperature::mkls340sim $tcn
} else {
::environment::temperature::mkls340 $tcn $tc_dfltURL $moxaPortMap($mport)
foreach nm [array names tc_param] {
$tcn $nm $tc_param($nm)
}
}
sicslist setatt $tcn environment_name ${tcn}_cntrl
sicslist setatt $tcn long_name control_sensor_reading
::environment::mkenvinfo $tcn {heateron {priv user} range {priv manager} }
} message ] {
if {$::errorCode=="NONE"} {return $message}
return -code error $message
}
}

View File

@@ -0,0 +1,183 @@
##
# @file Goniometer controller
#
# Author: Jing Chen (jgn@ansto.gov.au) June 2010
#
# The Goniometer controller can be installed with the following command,
# ::scobj::goniometer::mkGoniometer {
# name "goniometer"
# IP localhost
# PORT 62944
# tuning 1
# interval 1
# }
#
# NOTE:
# If tuning=1 this will generate gom/set_gom, gchi/set_gchi and gphi/set_gphi
# nodes for the instrument scientists.
# The tuning parameter should be set to 0 for the users.
#
namespace eval ::scobj::goniometer {
}
proc ::scobj::goniometer::set_gom {basePath} {
set newGOM [sct target]
hsetprop $basePath targetGom $newGOM
return idle
}
proc ::scobj::goniometer::set_gchi {basePath} {
set newGCHI [sct target]
hsetprop $basePath targetGchi $newGCHI
return idle
}
proc ::scobj::goniometer::set_gphi {basePath} {
set newGPHI [sct target]
hsetprop $basePath targetGphi $newGPHI
return idle
}
##
# @brief Request a state report from the PLC controller by sending a get_prop command
proc ::scobj::goniometer::rqStatFunc {} {
set comm "<get><var>gom,gchi,gphi</var></get>\n"
sct send $comm
return rdState
}
##
# @brief Read and record the state report from the PLC server
proc ::scobj::goniometer::rdStatFunc {basePath} {
set replyStr [sct result]
#broadcast $replyStr
if {[string first "err" $replyStr] != -1} {
broadcast "ERROR: cannot get the value to the PLC server, check again!"
} else {
set s1 [string map {<get> | <gom> gom: </gom> | <gchi> gchi: </gchi> | <gphi> gphi: </gphi> | </get> |} $replyStr]
set s2 [string trim $s1 "|\n"]
set s3 [split $s2 "|:"]
array set stateArr $s3
hset $basePath/gom $stateArr(gom)
hset $basePath/gchi $stateArr(gchi)
hset $basePath/gphi $stateArr(gphi)
hsetprop $basePath currGom $stateArr(gom)
hsetprop $basePath currGchi $stateArr(gchi)
hsetprop $basePath currGphi $stateArr(gphi)
#sct update $s3
sct utime readtime
}
return idle
}
##
# @Check if any of gom/gchi/gphi has been changed by client
proc ::scobj::goniometer::checkStatusFunc {basePath} {
set targetGom [hgetpropval $basePath targetGom]
set targetGchi [hgetpropval $basePath targetGchi]
set targetGphi [hgetpropval $basePath targetGphi]
set currGom [hgetpropval $basePath currGom]
set currGchi [hgetpropval $basePath currGchi]
set currGphi [hgetpropval $basePath currGphi]
if {$targetGom != $currGom} {
set comm "<set><var>gom</var><val>$targetGom</val></set>\n"
} elseif {$targetGchi != $currGchi} {
set comm "<set><var>gchi</var><val>$targetGchi</val></set>\n"
} elseif {$targetGphi != $currGphi} {
set comm "<set><var>gphi</var><val>$targetGphi</val></set>\n"
} else {
return idle
}
sct send $comm
return CheckReply
}
proc ::scobj::goniometer::checkReplyFunc {} {
set replyStr [sct result]
broadcast $replyStr
if {[string first "<err>var</err>" $replyStr] != -1} {
broadcast "ERROR: the varaible does not exist!"
} elseif {[string first "<err>set</err>" $replyStr] != -1} {
broadcast "ERROR: PLC cannot write new values for variable due to internal reason!"
} else {
sct utime readtime
}
return idle
}
##
# @brief Make a Goniometer controller
#
# @param argList, {name "goniometer" IP localhost PORT 62944 tuning 1 interval 1}
#
# name: name of goniometer controller object
# IP: IP address of RF generator moxa box
# PORT: Port number assigned to the generator on the moxa-box
# tuning: boolean, set tuning=1 to allow instrument scientists to set the axe positions
# interval: polling and ramping interval in seconds.
proc ::scobj::goniometer::mkGoniometer {argList} {
# Generate parameter array from the argument list
foreach {k v} $argList {
set KEY [string toupper $k]
set pa($KEY) $v
}
MakeSICSObj $pa(NAME) SCT_OBJECT
sicslist setatt $pa(NAME) klass instrument
sicslist setatt $pa(NAME) long_name $pa(NAME)
hfactory /sics/$pa(NAME)/gom plain internal int
hfactory /sics/$pa(NAME)/gchi plain internal int
hfactory /sics/$pa(NAME)/gphi plain internal int
hfactory /sics/$pa(NAME)/set_gom plain user int
hfactory /sics/$pa(NAME)/set_gchi plain user int
hfactory /sics/$pa(NAME)/set_gphi plain user int
makesctcontroller sct_goniometer std $pa(IP):$pa(PORT)
hset /sics/$pa(NAME)/gom 0
hset /sics/$pa(NAME)/gchi 0
hset /sics/$pa(NAME)/gphi 0
hsetprop /sics/$pa(NAME) currGom 0
hsetprop /sics/$pa(NAME) currGchi 0
hsetprop /sics/$pa(NAME) currGphi 0
hsetprop /sics/$pa(NAME) targetGom 10
hsetprop /sics/$pa(NAME) targetGchi 15
hsetprop /sics/$pa(NAME) targetGphi 20
hsetprop /sics/$pa(NAME)/gom read ::scobj::goniometer::rqStatFunc
hsetprop /sics/$pa(NAME)/gom rdState ::scobj::goniometer::rdStatFunc /sics/$pa(NAME)
hsetprop /sics/$pa(NAME)/gchi read ::scobj::goniometer::checkStatusFunc /sics/$pa(NAME)
hsetprop /sics/$pa(NAME)/gchi CheckReply ::scobj::goniometer::checkReplyFunc
# Initialise properties required for generating the API for GumTree and to save data
::scobj::hinitprops $pa(NAME) gom gchi gphi
sct_goniometer poll /sics/$pa(NAME)/gom $pa(INTERVAL)
sct_goniometer poll /sics/$pa(NAME)/gchi $pa(INTERVAL)
if {$pa(TUNING)} {
hsetprop /sics/$pa(NAME)/set_gom write ::scobj::goniometer::set_gom /sics/$pa(NAME)
hsetprop /sics/$pa(NAME)/set_gchi write ::scobj::goniometer::set_gchi /sics/$pa(NAME)
hsetprop /sics/$pa(NAME)/set_gphi write ::scobj::goniometer::set_gphi /sics/$pa(NAME)
sct_goniometer write /sics/$pa(NAME)/set_gom
sct_goniometer write /sics/$pa(NAME)/set_gchi
sct_goniometer write /sics/$pa(NAME)/set_gphi
}
}

View File

@@ -0,0 +1,10 @@
fileeval $cfPath(goniometer)/sct_goniometer.tcl
::scobj::goniometer::mkGoniometer {
name "goniometer"
IP localhost
PORT 62944
tuning 1
interval 3
}

View File

@@ -0,0 +1 @@
source $cfPath(hipadaba)/hipadaba_configuration_common.tcl

View File

@@ -0,0 +1,33 @@
set hpaths [list experiment ]
# Maps devices (eg motors) to hipadaba paths.
# obj name path
set motor_hpath [list \
aperture slits \
attenuator attenuator \
collimator collimator \
detector detector \
polarizer polarizer \
sample sample ]
# Configurable virtual motors
# obj name path master_obj
set cvirtmotor_hpath [list \
ss1hg gap slits/1/horizontal [list left right]\
ss1ho offset slits/1/horizontal [list left right]\
ss1vg gap slits/1/vertical [list upper lower]\
ss1vo offset slits/1/vertical [list upper lower]\
ss2hg gap slits/2/horizontal [list left right]\
ss2ho offset slits/2/horizontal [list left right]\
ss2vg gap slits/2/vertical [list upper lower]\
ss2vo offset slits/2/vertical [list upper lower]\
ss3hg gap slits/3/horizontal [list left right]\
ss3ho offset slits/3/horizontal [list left right]\
ss3vg gap slits/3/vertical [list upper lower]\
ss3vo offset slits/3/vertical [list upper lower]\
ss4hg gap slits/4/horizontal [list left right]\
ss4ho offset slits/4/horizontal [list left right]\
ss4vg gap slits/4/vertical [list upper lower]\
ss4vo offset slits/4/vertical [list upper lower]]

View File

@@ -0,0 +1,6 @@
# Detector voltage controller
fileeval $cfPath(hmm)/sct_orhvps_common.tcl
::scobj::dethvps::init ca1-lyrebird 4001 4.1
dhv1 max 2600
dhv1 lower 19
dhv1 upper 57

View File

@@ -0,0 +1,488 @@
# Ordela 21000N detector calibration
proc ord_get_pot { potxy potnumber } {
for { set rsp "Bad" } { $rsp == "Bad" } { } {
set potname [ format "%s%d" $potxy [expr $potnumber ^ 3] ]
# set rspall [ dhv1 cmd P $potname ]
set rspall [ sct_dhv1 transact "P $potname" ]
set rsp [lindex [split $rspall " "] 1]
}
return $rsp
}
Publish ord_get_pot User
proc ord_set_pot { potxy potnumber potvalue } {
set potname [ format "%s%d" $potxy [expr $potnumber ^ 3] ]
# set rsp [ dhv1 cmd p $potname $potvalue ]
set rsp [ sct_dhv1 transact "p $potname $potvalue" ]
return $rsp
}
Publish ord_set_pot User
set ord_pot_all_x ""
Publish ord_pot_all_x User
set ord_pot_all_y ""
Publish ord_pot_all_y User
set ord_pot_all_xy ""
Publish ord_pot_all_xy User
proc ord_get_pot_all { } {
global ord_pot_all_x
global ord_pot_all_y
global ord_pot_all_xy
clientput " Reading Ordela 21000N pots, please wait..."
set ord_pot_all_x ""
set ord_pot_all_y ""
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
lappend ord_pot_all_x [ord_get_pot x $ixy]
lappend ord_pot_all_y [ord_get_pot y $ixy]
}
set ord_pot_all_xy [ format "%s\n%s\n" $ord_pot_all_x $ord_pot_all_y ]
clientput " All pots read. Current x and y pot settings are shown below:"
return $ord_pot_all_xy
}
Publish ord_get_pot_all User
proc ord_set_pot_all { } {
global ord_pot_all_x
global ord_pot_all_y
clientput " Writing Ordela 21000N pots, please wait..."
set rspx ""
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
lappend rspx [ord_set_pot x $ixy [lindex $ord_pot_all_x $ixy] ]
}
set rspy ""
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
lappend rspy [ord_set_pot y $ixy [lindex $ord_pot_all_y $ixy] ]
}
clientput " All pots written. x and y pot setting responses are shown below:"
set rsp [ format "%s\n%s\n" $rspx $rspy ]
return $rsp
}
Publish ord_set_pot_all User
proc ord_set_pot_all_const_range_x_y { xy ord_pot_all_x_y pot_l s_x_y pot_h } {
global $ord_pot_all_x_y
set $ord_pot_all_x_y ""
if { $s_x_y <= 0 } {
clientput " Applying constant value" $pot_h "to all" $xy "pots."
} elseif { $s_x_y >= 192 } {
clientput " Applying constant value" $pot_l "to all" $xy "pots."
} else {
clientput " Applying constant value" $pot_l "to" $xy "pots 0 to" [expr $s_x_y - 1] "and" $pot_h "to" $xy "pots" $s_x_y "to 191."
}
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
if { $ixy < $s_x_y } {
set pot_value_x_y $pot_l
} else {
set pot_value_x_y $pot_h
}
lappend $ord_pot_all_x_y $pot_value_x_y
}
}
proc ord_set_pot_all_const_range_xy { pot_l_x s_x pot_h_x pot_l_y s_y pot_h_y } {
global ord_pot_all_x
global ord_pot_all_y
ord_set_pot_all_const_range_x_y x ord_pot_all_x $pot_l_x $s_x $pot_h_x
ord_set_pot_all_const_range_x_y y ord_pot_all_y $pot_l_y $s_y $pot_h_y
clientput $ord_pot_all_x
clientput $ord_pot_all_y
}
Publish ord_set_pot_all_const_range_xy User
proc ord_set_pot_all_const_range { pot_l_x s_x pot_h_x pot_l_y s_y pot_h_y } {
ord_set_pot_all_const_range_xy $pot_l_x $s_x $pot_h_x $pot_l_y $s_y $pot_h_y
return [ord_set_pot_all]
}
Publish ord_set_pot_all_const_range User
proc ord_set_pot_all_const_xy { pot_value_x pot_value_y } {
ord_set_pot_all_const_range_xy $pot_value_x 0 $pot_value_x $pot_value_y 0 $pot_value_y
return [ord_set_pot_all]
}
Publish ord_set_pot_all_const_xy User
proc ord_set_pot_all_const { pot_value } {
ord_set_pot_all_const_range_xy $pot_value 0 $pot_value $pot_value 0 $pot_value
return [ord_set_pot_all]
}
Publish ord_set_pot_all_const User
proc ord_save_pot_all { filename } {
global ord_pot_all_xy
set fh [ open $filename w ]
puts $fh $ord_pot_all_xy
close $fh
clientput " All pot settings saved to file."
}
Publish ord_save_pot_all User
proc ord_load_pot_all { filename } {
global ord_pot_all_x
global ord_pot_all_y
global ord_pot_all_xy
set fh [ open $filename ]
gets $fh ord_pot_all_x
gets $fh ord_pot_all_y
set ord_pot_all_xy [ format "%s\n%s\n" $ord_pot_all_x $ord_pot_all_y ]
close $fh
clientput " All pot settings loaded from file."
clientput "x settings:" $ord_pot_all_x
clientput "y settings:" $ord_pot_all_y
}
Publish ord_load_pot_all User
set histogram_xy ""
set histogram_x ""
set histogram_y ""
# Calibration procedure should not include data from edges of the detector pattern in corresponding 2D histogram.
# The set values can be viewed/adjusted using the ord_get_cal_roi and ord_set_bs_pos functions provided below.
set roi_x_l 24
set roi_x_h 167
set roi_y_l 24
set roi_y_h 167
proc ord_get_histogram_xy { bs_x_l bs_x_h bs_y_l bs_y_h roi_x_l roi_x_h roi_y_l roi_y_h } {
# Use data from within the x,y ROI (inclusive) to calculate 2D histograms.
# Excludes the beamstop region from the histogram calculations.
# Note the ROI and beamstop coords are in terms of histogram server coord system
# but the result x and y histograms are in detector coordinate system (match pot order).
# Also note that when calculating the x and y 1D histogram, it includes data from the y or x ROI respectively
# and excludes data from the BS region. (i.e. x histogram is computed by summing in y across the y ROI,
# but excludes the portion of y occupied by the beamstop). The calculation is done in this way so that
# the result is as uniform as possible in x and y.
global histogram_xy
global histogram_x
global histogram_y
clientput "Retrieving 2D xy histogram..."
set histogram_xy [ lreplace [ split [ hmm get 1 ] ] 0 1 ]
if { ($bs_x_l > $bs_x_h || $bs_y_l > $bs_y_h) && $roi_x_l == 0 && $roi_x_h == 191 && $roi_y_l == 0 && $roi_y_h == 191 } {
set get_full_histogram 1
clientput "Calculating 2D histograms over full detector area..."
set bs_x_l 1
set bs_x_h 0
set bs_y_l 1
set bs_y_h 0
} else {
set get_full_histogram 0
clientput "Calculating 2D histograms excluding beamstop area x =" $bs_x_l "to" $bs_x_h "and y =" $bs_y_l "to" $bs_y_h "..."
clientput "Histograms ROI is x =" $roi_x_l "to" $roi_x_h "(for y histogram) and y =" $roi_y_l "to" $roi_y_h "(for x histogram)."
}
set histogram_memory_x ""
set histogram_memory_y ""
for { set ia 0 } { $ia <= 191 } { incr ia } {
set sum_x 0
set sum_y 0
# NOTE: In the sum loops below, do NOT include the edges! Too unreliable. Sum in the ROI only instead.
for { set ib $roi_x_l } { $ib < $bs_x_l } { incr ib } {
set sum_x [expr $sum_x + [lindex $histogram_xy [expr $ib + $ia * 192] ]]
}
for { set ib [expr $bs_x_h + 1] } { $ib <= $roi_x_h } { incr ib } {
set sum_x [expr $sum_x + [lindex $histogram_xy [expr $ib + $ia * 192] ]]
}
for { set ib $roi_y_l } { $ib < $bs_y_l } { incr ib } {
set sum_y [expr $sum_y + [lindex $histogram_xy [expr $ia + $ib * 192] ]]
}
for { set ib [expr $bs_y_h + 1] } { $ib <= $roi_y_h } { incr ib } {
set sum_y [expr $sum_y + [lindex $histogram_xy [expr $ia + $ib * 192] ]]
}
lappend histogram_memory_x $sum_y
lappend histogram_memory_y $sum_x
}
#
# If x and y need to be swapped or reordered, do it in the loop below.
# (histo server raw data x,y order matches pot order)
set histogram_x ""
set histogram_y ""
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
lappend histogram_x [lindex $histogram_memory_y [expr $ixy]]
lappend histogram_y [lindex $histogram_memory_x [expr 191 - $ixy]]
}
#
#
if { $get_full_histogram == 1 } {
clientput "Calculated x and y histograms over entire detector area. Data:"
} else {
clientput "Calculated x and y histograms for ROI, excluding beamstop area. Data:"
}
set rsp [ format "%s\n%s\n" $histogram_x $histogram_y ]
return $rsp
}
Publish ord_get_histogram_xy User
# Beamstop and spill nominally occupies the center 1/4 of the detector pattern.
# The set values can be viewed/adjusted using the ord_get_bs_pos and ord_set_bs_pos functions provided below.
set bss_x_l 72
set bss_x_h 120
set bss_y_l 72
set bss_y_h 120
proc ord_get_bs_pos { } {
global bss_x_l
global bss_x_h
global bss_y_l
global bss_y_h
clientput "The current beamstop position settings (in histogram server xy coordinates) are: xl =" $bss_x_l "xh =" $bss_x_h$
}
Publish ord_get_bs_pos User
proc ord_set_bs_pos { bss_x_l_new bss_x_h_new bss_y_l_new bss_y_h_new } {
global bss_x_l
global bss_x_h
global bss_y_l
global bss_y_h
set bss_x_l $bss_x_l_new
set bss_x_h $bss_x_h_new
set bss_y_l $bss_y_l_new
set bss_y_h $bss_y_h_new
return [ord_get_bs_pos]
}
Publish ord_set_bs_pos User
# Calibration procedure should not include data from edges of the detector pattern in corresponding 2D histogram.
# The set values can be viewed/adjusted using the ord_get_cal_roi and ord_set_bs_pos functions provided below.
set roi_x_l 24
set roi_x_h 167
set roi_y_l 24
set roi_y_h 167
proc ord_get_roi_pos { } {
global roi_x_l
global roi_x_h
global roi_y_l
global roi_y_h
clientput "The current histogram ROI settings (in histogram server xy coordinates) are: xl =" $roi_x_l "xh =" $roi_x_h "yl =" $roi_y_l "yh =" $roi_y_h
}
Publish ord_get_roi_pos User
proc ord_set_roi_pos { roi_x_l_new roi_x_h_new roi_y_l_new roi_y_h_new } {
global roi_x_l
global roi_x_h
global roi_y_l
global roi_y_h
set roi_x_l $roi_x_l_new
set roi_x_h $roi_x_h_new
set roi_y_l $roi_y_l_new
set roi_y_h $roi_y_h_new
return [ord_get_roi_pos]
}
Publish ord_set_roi_pos User
proc ord_get_histogram_xy_bs { } {
global bss_x_l
global bss_x_h
global bss_y_l
global bss_y_h
global roi_x_l
global roi_x_h
global roi_y_l
global roi_y_h
return [ ord_get_histogram_xy $bss_x_l $bss_x_h $bss_y_l $bss_y_h $roi_x_l $roi_x_h $roi_y_l $roi_y_h ]
}
Publish ord_get_histogram_xy_bs User
proc ord_get_histogram_xy_all { } {
return [ ord_get_histogram_xy 1 0 1 0 0 191 0 191 ]
}
Publish ord_get_histogram_xy_all User
set histogram_min_x ""
set histogram_min_y ""
set histogram_max_x ""
set histogram_max_y ""
set histogram_mean_x ""
set histogram_mean_y ""
proc ord_calc_hist_mmm_xy { } {
# Calculates min, max and mean of histogram values.
# NOTE: Because of edge effects in the detector, three of the edges return
# very high or low values. In order to stop these from dragging the mean
# high or low, they are excluded from the min/max/mean calculation entirely.
global histogram_x
global histogram_y
global histogram_min_x
global histogram_min_y
global histogram_max_x
global histogram_max_y
global histogram_mean_x
global histogram_mean_y
global bss_x_l
global bss_x_h
global bss_y_l
global bss_y_h
# NOTE: Ignore the edges entirely, as they are not reliable.
set histogram_mean_x 0
set histogram_mean_y 0
for { set ixy 1 } { $ixy <= 190 } { incr ixy } {
set histogram_x_val [lindex $histogram_x $ixy]
set histogram_y_val [lindex $histogram_y $ixy]
if { $ixy == 1 } { # NOTE edge at 0 is ignored
set histogram_min_x $histogram_x_val
set histogram_min_y $histogram_y_val
set histogram_max_x $histogram_x_val
set histogram_max_y $histogram_y_val
} else {
if {$histogram_x_val < $histogram_min_x } {
set histogram_min_x $histogram_x_val
}
if {$histogram_y_val < $histogram_min_y } {
set histogram_min_y $histogram_y_val
}
if {$histogram_x_val > $histogram_max_x } {
set histogram_max_x $histogram_x_val
}
if {$histogram_y_val > $histogram_max_y } {
set histogram_max_y $histogram_y_val
}
}
set histogram_mean_x [expr $histogram_mean_x + $histogram_x_val ]
set histogram_mean_y [expr $histogram_mean_y + $histogram_y_val ]
}
# NOTE beamstop region and edges are not included.
# ALSO NOTE we sum x histo over y, but x and y are transposed when the histo is retrieved,
# so we divide x histo values by span_x and y by span_y!
# set span_x [expr 190 - ( $bss_x_h - $bss_x_l ) ]
# set span_y [expr 190 - ( $bss_y_h - $bss_y_l ) ]
# if { $bss_x_l == 0 } { incr span_x }
# if { $bss_x_h == 191 } { incr span_x }
# if { $bss_y_l == 0 } { incr span_y }
# if { $bss_y_h == 191 } { incr span_y }
set span_x 190
set span_y 190
set histogram_mean_x [expr double($histogram_mean_x) / double($span_x) ]
set histogram_mean_y [expr double($histogram_mean_y) / double($span_y) ]
clientput "Calculated histogram means: mx =" $histogram_mean_x "and my =" $histogram_mean_y "(should be
roughly equal if bs window is square)."
}
Publish ord_calc_hist_mmm_xy User
proc ord_calc_pot { pot_in histogram_value histogram_mean CP_divider add_deviation } {
set CP 0.25
set histogram_deviation [expr double($histogram_value) / double($histogram_mean) - 1.]
set pot_out [ expr double($pot_in) - $histogram_deviation * $CP * 100. / $CP_divider ]
set pot_out [ expr int($pot_out + double($add_deviation) + 0.5) ]
if { $pot_out < 0 } {
set pot_out 0
} elseif { $pot_out > 63 } {
set pot_out 63
}
return $pot_out
}
Publish ord_calc_pot User
proc ord_calc_pot_all_xy { CP_divider desiredpotsmidrange_x desiredpotsmidrange_y } {
global histogram_x
global histogram_y
global histogram_mean_x
global histogram_mean_y
global ord_pot_all_x
global ord_pot_all_y
clientput "Calculating new pot settings based on old pot settings and histogram data..."
set ord_pot_all_x_new ""
set ord_pot_all_y_new ""
set ord_pot_dev_av_x 0
set ord_pot_dev_av_y 0
set ord_pot_dev_max_x 0
set ord_pot_dev_max_y 0
# Find current mean pot values. Do NOT include the edge pots.
set ord_pot_mean_x 0
set ord_pot_mean_y 0
for { set ixy 1 } { $ixy <= 190 } { incr ixy } {
set ord_pot_mean_x [expr $ord_pot_mean_x + [lindex $ord_pot_all_x $ixy]]
set ord_pot_mean_y [expr $ord_pot_mean_y + [lindex $ord_pot_all_y $ixy]]
}
set ord_pot_mean_x [expr double($ord_pot_mean_x) / 190.]
set ord_pot_mean_y [expr double($ord_pot_mean_y) / 190.]
# Calculate additional deviation to apply during new pot value calculation,
# to keep pot average close to desired mid range.
set ord_pot_add_dev_x [expr double($desiredpotsmidrange_x) - $ord_pot_mean_x]
set ord_pot_add_dev_y [expr double($desiredpotsmidrange_y) - $ord_pot_mean_y]
# Find all new pot values.
for { set ixy 0 } { $ixy <= 191 } { incr ixy } {
# clientput "Index" $ixy "x pot value" [lindex $ord_pot_all_x $ixy]
# clientput "Index" $ixy "histogram x value" [lindex $histogram_x $ixy]
# clientput "Index" $ixy "x pot value" $histogram_mean_x
# clientput "Index" $ixy "y pot value" [lindex $ord_pot_all_y $ixy]
# clientput "Index" $ixy "histogram y value" [lindex $histogram_y $ixy]
# clientput "Index" $ixy "y pot value" $histogram_mean_y
set ord_pot_old_x [lindex $ord_pot_all_x $ixy]
set ord_pot_old_y [lindex $ord_pot_all_y $ixy]
set ord_pot_new_x [ ord_calc_pot $ord_pot_old_x [lindex $histogram_x $ixy] $histogram_mean_x $CP_divider $ord_pot_add_dev_x ]
set ord_pot_new_y [ ord_calc_pot $ord_pot_old_y [lindex $histogram_y $ixy] $histogram_mean_y $CP_divider $ord_pot_add_dev_y ]
lappend ord_pot_all_x_new $ord_pot_new_x
lappend ord_pot_all_y_new $ord_pot_new_y
# Also get some stats on deviations (just take this as absolute)
set ord_pot_dev_x [ expr abs ( $ord_pot_new_x - $ord_pot_old_x ) ]
set ord_pot_dev_y [ expr abs ( $ord_pot_new_y - $ord_pot_old_y ) ]
set ord_pot_dev_av_x [ expr $ord_pot_dev_av_x + $ord_pot_dev_x ]
set ord_pot_dev_av_y [ expr $ord_pot_dev_av_y + $ord_pot_dev_y ]
if { $ord_pot_dev_x > $ord_pot_dev_max_x } {
set ord_pot_dev_max_x $ord_pot_dev_x
}
if { $ord_pot_dev_y > $ord_pot_dev_max_y } {
set ord_pot_dev_max_y $ord_pot_dev_y
}
}
set ord_pot_dev_av_x [ expr $ord_pot_dev_av_x / 192. ]
set ord_pot_dev_av_y [ expr $ord_pot_dev_av_y / 192. ]
clientput "Average deviations: x =" $ord_pot_dev_av_x "and y =" $ord_pot_dev_av_y
clientput "Maximum deviations: x =" $ord_pot_dev_max_x "and y =" $ord_pot_dev_max_y
#
set ord_pot_all_x $ord_pot_all_x_new
set ord_pot_all_y $ord_pot_all_y_new
set ord_pot_all_xy [ format "%s\n%s\n" $ord_pot_all_x $ord_pot_all_y ]
return $ord_pot_all_xy
}
Publish ord_calc_pot_all_xy User
proc ord_calibrate_iterate { CP_divider desiredpotsmidrange_x desiredpotsmidrange_y iteration } {
# For this to work we must first read pot values and the x and y histograms.
# Note the beamstop location is hard coded - position detector so that beamstop image is in the specified range
clientput [ord_get_histogram_xy_bs]
clientput [ord_calc_hist_mmm_xy]
# if { $iteration == 1 } {
# clientput [ord_get_pot_all] ## while iterating, the pot values are in the memory anyway so don't read
# }
clientput [ord_calc_pot_all_xy $CP_divider $desiredpotsmidrange_x $desiredpotsmidrange_y]
clientput [ord_set_pot_all]
}
proc ord_calibrate { CP_divider desiredpotsmidrange_x desiredpotsmidrange_y } {
clientput [ord_get_pot_all]
ord_calibrate_iterate $CP_divider $desiredpotsmidrange_x $desiredpotsmidrange_y 1
}
Publish ord_calibrate User
proc ord_calibrate_auto { CP_divider desiredpotsmidrange_x desiredpotsmidrange_y resetallpotsmidrange iterations acqtime } {
#
if { $resetallpotsmidrange == 1 } {
clientput [ord_set_pot_all_const_xy $desiredpotsmidrange_x $desiredpotsmidrange_y ]
} else {
clientput [ord_get_pot_all]
}
#
for { set iteration 1 } { $iteration <= $iterations } { incr iteration } {
clientput "*** Commencing detector calibration iteration" $iteration
# NOTE: Assumes the histogram memory is set up in its DEFAULT state
# (that which SICS configures, but perhaps including HISTOGRAM_TRANSPOSE_RAW_XY=ENABLE).
# At 9/08 the configuration is HISTOGRAM_TRANSPOSE_RAW_XY=ENABLE, X OAT flipped, Y OAT non-flipped.
# Modify ordering in the ord_get_histogram_xy routine as needed.
# Alternately reconfigure transpose and OAT flipping here, so we get what we expect...
# (but this might not get put back by SICS so it's better not to)
# dhv1 cmd d # Diagnostic mode - CD turned off
histmem stop
histmem mode time
histmem preset $acqtime
histmem pause # NOTE - start in paused mode - server sends reset to Ordela first
# dhv1 cmd d # Place in diagnostic mode - will stay in this mode since reset won't occur on start, from paused
clientput [histmem start block]
# wait $acqtime # Can't figure out how to make histmem block, so just wait
clientput [histmem stop]
# dhv1 cmd n # Normal mode - CD turned back on
clientput [ord_calibrate_iterate $CP_divider $desiredpotsmidrange_x $desiredpotsmidrange_y $iteration ]
clientput "*** Detector calibration iteration" $iteration "completed."
}
}
Publish ord_calibrate_auto User

View File

@@ -0,0 +1,64 @@
source $cfPath(hmm)/hmm_configuration_common_1.tcl
set sim_mode [SplitReply [hmm_simulation]]
proc ::histogram_memory::init_OAT_TABLE {} {
if [ catch {
# We don't need a MAX_CHAN parameter for time because the time channel
# is scaled by calling the ::histogram_memory::clock_scale function
OAT_TABLE X -setdata MAX_CHAN 192
OAT_TABLE Y -setdata MAX_CHAN 192
OAT_TABLE X -setdata BMIN -0.5
OAT_TABLE X -setdata BMAX 191.5
OAT_TABLE Y -setdata BMIN -0.5
OAT_TABLE Y -setdata BMAX 191.5
OAT_TABLE -set X { 191.5 190.5 } NXC 192 Y { -0.5 0.5 } NYC 192 T { 0 20000 } NTC 1
} message ] {
return -code error $message
}
}
proc ::histogram_memory::pre_count {} {}
proc ::histogram_memory::post_count {} {}
proc ::histogram_memory::isc_initialize {} {
# Instrument specific X and Y dimension names
variable INST_NXC "oat_nxc_eff"
variable INST_NYC "oat_nyc_eff"
if [ catch {
::histogram_memory::init_hmm_objs
if {$::sim_mode == "true"} {
hmm configure oat_ntc_eff 1
hmm configure $INST_NYC 127
hmm configure $INST_NXC 127
}
BAT_TABLE -init
CAT_TABLE -init
SAT_TABLE -init
OAT_TABLE -init
FAT_TABLE -init
::histogram_memory::ic_initialize
detector_active_height_mm [expr 5.08 * 192]
detector_active_width_mm [expr 5.08 * 192]
detector_active_height_mm lock
detector_active_width_mm lock
# hmm configure FAT_SIMULATED_EVENT_Y0 $y_bb0
# hmm configure FAT_SIMULATED_EVENT_Y1 $ybbmax
# hmm configure FAT_SIMULATED_EVENT_X0 $x_bb0
# hmm configure FAT_SIMULATED_EVENT_X1 $xbbmax
::histogram_memory::init_OAT_TABLE
::histogram_memory::upload_config Filler_defaults
set ::histogram_memory::histmem_axes(HOR) /instrument/detector/x_pixel_offset
set ::histogram_memory::histmem_axes(VER) /instrument/detector/y_pixel_offset
} message ] {
return -code error $message
}
}
proc histmem {cmd args} {
eval "_histmem $cmd $args"
}
publish histmem user

View File

@@ -0,0 +1,988 @@
# Author: Jing Chen (jgn@ansto.gov.au)
# START MOTOR CONFIGURATION
::utility::mkVar FastShutter text manager FastShutter false instrument true false
# SET TO 1 TO USE THE TILT STAGE ie sample phi and chi
set use_tiltstage 0
set animal lyrebird
set sim_mode [SplitReply [motor_simulation]]
# Setup addresses of Galil DMC2280 controllers.
set dmc2280_controller1(host) mc1-$animal
set dmc2280_controller1(port) pmc1-$animal
set dmc2280_controller2(host) mc2-$animal
set dmc2280_controller2(port) pmc2-$animal
set dmc2280_controller3(host) mc3-$animal
set dmc2280_controller3(port) pmc3-$animal
set dmc2280_controller4(host) mc4-$animal
set dmc2280_controller4(port) pmc4-$animal
if {$sim_mode == "true"} {
set motor_driver_type asim
} else {
set motor_driver_type DMC2280
MakeAsyncQueue mc1 DMC2280 $dmc2280_controller1(host) $dmc2280_controller1(port)
MakeAsyncQueue mc2 DMC2280 $dmc2280_controller2(host) $dmc2280_controller2(port)
MakeAsyncQueue mc3 DMC2280 $dmc2280_controller3(host) $dmc2280_controller3(port)
MakeAsyncQueue mc4 DMC2280 $dmc2280_controller4(host) $dmc2280_controller4(port)
}
# Beam stop gearing and signs (BS1=largest)
# 4,5 160:1
# 1,2,3 110:1
# MOTS need 400 steps per rev = 50000 steps per rev
set bs_steps_per_rev 50000.0
set bs1gear 160
set bs2gear 160
set bs3gear 110
set bs4gear 110
set bs5gear 110
set bs45_gear 110.0
set bs123_gear 160.0
#set bs45_gear 160.0
#set bs123_gear 110.0
set bs125sign -1
set bs34sign 1
#Measured absolute encoder reading at home position
set samchi_Home 7808328
set samphi_Home 7675008
set samx_Home 7420441
set samy_Home 7101486
set samz_Home 9944901
set samthet_Home 23004075
set det_Home 7055209
set detoff_Home 6857213
set srce_Home 7281463
set apx_Home 12965422
set apz_Home 7500000
set att_Home 24782942
set bsx_Home 7578346
set bsz_Home 10568857
set bs1_Home 21298
set bs2_Home 9942
set bs3_Home 30928
set bs4_Home 22111
set bs5_Home 14558
set bs6_Home 27251
set bs_cntsPerX [expr 32768.0/360.0]
set bs_stepsPerX [expr -25000.0*160.0/360.0]
set pol_Home 7500000
#HERE ARE THE LATEST VALUES
set pent_Home 8146159
# Guide Positions Mirrotron ffr 2009-07-18
set pc1_Guide 7995952
set pc1_Polarizer 7723328
set pc2_Guide 7459329
set pc2_Polarizer 7186701
set pc3_Guide 8440904
set pc4_Guide 6161076
set pc5_Guide 7856254
set pc6_Guide 8800665
set pc7_Guide 24167224
set pc8_Guide 8302146
set pc9_Guide 7851820
set pc10_Guide 25977227
#lens
set pc10_Lens 26196301
#lens_and_prism
set pc10_LensandPrism 25729419
set pc3_Aperture 8304893
set pc4_Aperture 6029466
set pc5_Aperture 7728755
set pc6_Aperture 8663189
set pc7_Aperture 24036241
set pc8_Aperture 8169931
set pc9_Aperture 7718840
set pc10_Aperture 25835335
set pc1_Home $pc1_Guide
set pc2_Home $pc2_Guide
set pc3_Home $pc3_Guide
set pc4_Home $pc4_Guide
set pc5_Home $pc5_Guide
set pc6_Home $pc6_Guide
set pc7_Home $pc7_Guide
set pc8_Home $pc8_Guide
set pc9_Home $pc9_Guide
set pc10_Home $pc10_Guide
set pc1_Empty [expr ($pc1_Guide + $pc1_Polarizer)/2]
set pc2_Empty [expr ($pc2_Guide + $pc2_Polarizer)/2]
set pc3_Empty [expr (2 * $pc3_Guide) - $pc3_Aperture]
set pc4_Empty [expr (2 * $pc4_Guide) - $pc4_Aperture]
set pc5_Empty [expr (2 * $pc5_Guide) - $pc5_Aperture]
set pc6_Empty [expr (2 * $pc6_Guide) - $pc6_Aperture]
set pc7_Empty [expr (2 * $pc7_Guide) - $pc7_Aperture]
set pc8_Empty [expr (2 * $pc8_Guide) - $pc8_Aperture]
set pc9_Empty [expr (2 * $pc9_Guide) - $pc9_Aperture]
set pc10_Empty [expr (2 * $pc10_Guide) - $pc10_Aperture]
#Measured or computed step/count rates for collimator translation
set coll_StepsPerX [expr -25000.0/6.0]
set coll_CntsPerX [expr 8192.0/6.0]
#Measured or computed step rate for samz (Sample Raise)
#Copied from Reflectometer then divided by 2.0 for SANS
# Motor:25000/turn, gear:1/25, screw:5mm/turn
set samzStepRate [expr -((25000.0*25.0)/5.0)/2.0]
#set samzCountRate [expr -(8192.0/5.0/0.932)]
# 8192 count encoder, 5mm/Turn screw, 14:15 gearing?
set samzCountRate [expr -((8192.0/5.0)/(14.0/15.0))/2.0]
# set movecount high to reduce the frequency of
# hnotify messages to a reasonable level
set move_count 100
############################
# Motor Controller 1
# Motor Controller 1
# Motor Controller 1
############################
#:TP at HOME
#
# Dummy translation motor, useful for testing scans
Motor dummy_motor asim [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis C\
units mm\
hardlowerlim -500\
hardupperlim 500\
maxSpeed 1\
maxAccel 5\
maxDecel 5\
stepsPerX [expr 25000.0/5.0]\
absEnc 1\
absEncHome $samx_Home\
cntsPerX [expr 8192.0/5.0]]
dummy_motor part instrument
dummy_motor long_name dummy_motor
dummy_motor softlowerlim -500
dummy_motor softupperlim 500
dummy_motor home 0
if $use_tiltstage {
# Sample tilt along beam [-20,+20] degrees
Motor samchi $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis A\
units degrees\
hardlowerlim -20\
hardupperlim 20\
maxSpeed 1\
maxAccel 5\
maxDecel 5\
stepsPerX 25000\
absEnc 1\
absEncHome $samchi_Home\
cntsPerX 8192]
samchi part sample
samchi long_name sample_chi
samchi softlowerlim -20
samchi softupperlim 20
samchi home 0
# Sample tilt across beam [-20,+20] degrees
Motor samphi $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis B\
units degrees\
hardlowerlim -20\
hardupperlim 20\
maxSpeed 1\
maxAccel 5\
maxDecel 5\
stepsPerX 25000\
absEnc 1\
absEncHome $samphi_Home\
cntsPerX 8192]
samphi part sample
samphi long_name sample_phi
samphi softlowerlim -20
samphi softupperlim 20
samphi home 0
}
# Sample translation across beam [0,1000] mm
Motor samx $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis C\
units mm\
hardlowerlim -500\
hardupperlim 500\
maxSpeed 10\
maxAccel 10\
maxDecel 10\
stepsPerX [expr 25000.0/5.0]\
absEnc 1\
absEncHome $samx_Home\
cntsPerX [expr 8192.0/5.0]]
samx part sample
samx long_name sample_x
samx softlowerlim -500
samx softupperlim 500
samx home 0
# Sample translation along beam [0,1000] mm
Motor samy $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis D\
units mm\
hardlowerlim 0\
hardupperlim 1000\
maxSpeed 10\
maxAccel 5\
maxDecel 5\
stepsPerX [expr 25000.0/5.0]\
absEnc 1\
absEncHome $samy_Home\
cntsPerX [expr 8192.0/5.0]]
samy part sample
samy long_name sample_y
samy softlowerlim 0
samy softupperlim 1000
samy home 0
samy speed 5
# Sample translation vertical [0,500] mm
Motor samz $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis E\
units mm\
hardlowerlim 0\
hardupperlim 500\
maxSpeed 10\
maxAccel 1\
maxDecel 10\
stepsPerX $samzStepRate\
absEnc 1\
absEncHome $samz_Home\
cntsPerX $samzCountRate]
samz part sample
samz long_name sample_z
samz softlowerlim 0
samz softupperlim 500
samz home 0
# Sample rotation (theta) [0,180] degrees
Motor samthet $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis F\
units degrees\
hardlowerlim -30\
hardupperlim 30\
maxSpeed 10\
maxAccel 1\
maxDecel 10\
stepsPerX [expr 25000.0/2.0]\
absEnc 1\
absEncHome $samthet_Home\
cntsPerX [expr 8192.0/2.0]]
samthet part sample
samthet long_name sample_theta
samthet softlowerlim -10
samthet softupperlim 10
samthet home 0
# Motor feeds 70:1 gearbox to 120mm diameter drive wheel ~= 377mm circumference
#set det_StepsPerX [expr 25000.0*70.0*3.1415926*120.0]
#set det_StepsPerX [expr 25000.0/5.385]
set det_StepsPerX [expr (25000.0*70.0)/377.0]
# Absolute encoder is on the drive wheel
#set det_CntsPerX [expr 8192.0/3.1415926/120.0]]
#set det_CntsPerX [expr 21.6898]
set det_CntsPerX [expr 8192.0/377.0]
# Detector translation along beam [0,20000] mm
Motor det $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
action MC1\
axis G\
units mm\
hardlowerlim 488\
hardupperlim 19320\
maxSpeed 53\
maxAccel 5\
maxDecel 10\
stepsPerX $det_StepsPerX\
absEnc 1\
absEncHome $det_Home\
cntsPerX $det_CntsPerX]
det part detector
det long_name detector_y
det precision 1
det softlowerlim 500
det softupperlim 19310
det home 350.5
det speed 53
det Blockage_Fail 0
# Detector translation across beam [-50,450] mm
# Looks like an non-metric screw pitch 0.2 inches / turn
Motor detoff $motor_driver_type [params \
asyncqueue mc1\
host mc1-lyrebird\
port pmc1-lyrebird\
axis H\
units mm\
hardlowerlim -9\
hardupperlim 465\
maxSpeed 10\
maxAccel 1\
maxDecel 10\
stepsPerX [expr -(25000.0*3.0)/5.08]\
absEnc 1\
absEncHome $detoff_Home\
cntsPerX [expr 8192.0/5.08]]
detoff part detector
detoff long_name detector_x
detoff softlowerlim 0
detoff softupperlim 450
detoff home 0
############################
# Motor Controller 2
# Motor Controller 2
# Motor Controller 2
############################
#:TP at HOME
#
# Collimation motor 1
Motor pc1 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis A\
units mm\
hardlowerlim -295\
hardupperlim 95\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc1_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc1 posit_1 [expr $pc1_Guide]
pc1 posit_2 [expr $pc1_Empty]
pc1 posit_3 [expr $pc1_Polarizer]
pc1 part collimator
pc1 long_name pc1
setHomeandRange -motor pc1 -home 0 -lowrange 295 -uprange 95
pc1 speed 6
pc1 creep_offset 1
# Collimation motor 2
Motor pc2 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis B\
units mm\
hardlowerlim -295\
hardupperlim 95\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc2_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc2 posit_1 [expr $pc2_Guide]
pc2 posit_2 [expr $pc2_Empty]
pc2 posit_3 [expr $pc2_Polarizer]
pc2 part collimator
pc2 long_name pc2
setHomeandRange -motor pc2 -home 0 -lowrange 295 -uprange 95
pc2 speed 6
pc2 creep_offset 1
# Collimation motor 3
Motor pc3 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis C\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc3_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc3 posit_1 [expr $pc3_Empty]
pc3 posit_2 [expr $pc3_Guide]
pc3 posit_3 [expr $pc3_Aperture]
pc3 part collimator
pc3 long_name pc3
setHomeandRange -motor pc3 -home 0 -lowrange 190 -uprange 190
pc3 speed 6
pc3 creep_offset 1
# Collimation motor 4
Motor pc4 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis D\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc4_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc4 posit_1 [expr $pc4_Empty]
pc4 posit_2 [expr $pc4_Guide]
pc4 posit_3 [expr $pc4_Aperture]
pc4 part collimator
pc4 long_name pc4
setHomeandRange -motor pc4 -home 0 -lowrange 190 -uprange 190
pc4 speed 6
pc4 creep_offset 1
# Collimation motor 5
Motor pc5 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis E\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc5_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc5 posit_1 [expr $pc5_Empty]
pc5 posit_2 [expr $pc5_Guide]
pc5 posit_3 [expr $pc5_Aperture]
pc5 part collimator
pc5 long_name pc5
setHomeandRange -motor pc5 -home 0 -lowrange 190 -uprange 190
pc5 speed 6
pc5 creep_offset 1
# Collimation motor 6
Motor pc6 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis F\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc6_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc6 posit_1 [expr $pc6_Empty]
pc6 posit_2 [expr $pc6_Guide]
pc6 posit_3 [expr $pc6_Aperture]
pc6 part collimator
pc6 long_name pc6
setHomeandRange -motor pc6 -home 0 -lowrange 190 -uprange 190
pc6 speed 6
pc6 creep_offset 1
# Collimation motor 7
Motor pc7 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis G\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc7_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc7 posit_1 [expr $pc7_Empty]
pc7 posit_2 [expr $pc7_Guide]
pc7 posit_3 [expr $pc7_Aperture]
pc7 part collimator
pc7 long_name pc7
setHomeandRange -motor pc7 -home 0 -lowrange 190 -uprange 190
pc7 speed 6
pc7 creep_offset 1
# Collimation motor 8
Motor pc8 $motor_driver_type [params \
asyncqueue mc2\
host mc2-lyrebird\
port pmc2-lyrebird\
axis H\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc8_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc8 posit_1 [expr $pc8_Empty]
pc8 posit_2 [expr $pc8_Guide]
pc8 posit_3 [expr $pc8_Aperture]
pc8 part collimator
pc8 long_name pc8
setHomeandRange -motor pc8 -home 0 -lowrange 190 -uprange 190
pc8 speed 6
pc8 creep_offset 1
############################
# Motor Controller 3
# Motor Controller 3
# Motor Controller 3
############################
#
# Collimation motor 9
Motor pc9 $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis A\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc9_Home\
cntsPerX $coll_CntsPerX\
posit_count 3]
pc9 posit_1 [expr $pc9_Empty]
pc9 posit_2 [expr $pc9_Guide]
pc9 posit_3 [expr $pc9_Aperture]
pc9 part collimator
pc9 long_name pc9
setHomeandRange -motor pc9 -home 0 -lowrange 190 -uprange 190
pc9 speed 6
pc9 creep_offset 1
# Collimation motor 10
Motor pc10 $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis B\
units mm\
hardlowerlim -190\
hardupperlim 190\
maxSpeed 6\
maxAccel 1\
maxDecel 1\
stepsPerX $coll_StepsPerX\
absEnc 1\
absEncHome $pc10_Home\
cntsPerX $coll_CntsPerX\
posit_count 5]
pc10 posit_1 [expr $pc10_Lens]
pc10 posit_2 [expr $pc10_Empty]
pc10 posit_3 [expr $pc10_Guide]
pc10 posit_4 [expr $pc10_Aperture]
pc10 posit_5 [expr $pc10_LensandPrism]
pc10 part collimator
pc10 long_name pc10
setHomeandRange -motor pc10 -home 0 -lowrange 190 -uprange 190
pc10 speed 6
pc10 creep_offset 1
# Pentaprism
Motor pent $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis C\
units mm\
hardlowerlim -30\
hardupperlim 300\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX [expr 25000.0/3.0]\
absEnc 1\
absEncHome $pent_Home\
cntsPerX [expr -8192.0/3.0]]
pent part collimator
pent long_name pent
setHomeandRange -motor pent -home 0 -lowrange 30 -uprange 300
pent speed 1
# Rotary source aperture
Motor srce $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis D\
units degrees\
hardlowerlim -10\
hardupperlim 340\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX [expr 25000.0/6.0]\
absEnc 1\
absEncHome $srce_Home\
cntsPerX [expr -8192.0/6.0]\
posit_count 12]
srce part collimator
srce long_name srce
srce home 180
srce softlowerlim -10
srce softupperlim 340
srce speed 1
srce posit_1 $srce_Home
srce posit_2 [expr $srce_Home - (1 * 5 * 8192)]
srce posit_3 [expr $srce_Home - (2 * 5 * 8192)]
srce posit_4 [expr $srce_Home - (3 * 5 * 8192)]
srce posit_5 [expr $srce_Home - (4 * 5 * 8192)]
srce posit_6 [expr $srce_Home - (5 * 5 * 8192)]
srce posit_7 [expr $srce_Home - (6 * 5 * 8192)]
srce posit_8 [expr $srce_Home - (7 * 5 * 8192)]
srce posit_9 [expr $srce_Home - (8 * 5 * 8192)]
srce posit_10 [expr $srce_Home - (9 * 5 * 8192)]
srce posit_11 [expr $srce_Home - (10 * 5 * 8192)]
srce posit_12 [expr $srce_Home - (11 * 5 * 8192)]
# Sample aperture x
Motor apx $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis E\
units mm\
hardlowerlim -260\
hardupperlim 5\
maxSpeed 5\
maxAccel 5\
maxDecel 5\
stepsPerX 2500\
absEnc 1\
absEncHome $apx_Home\
cntsPerX -819.2]
apx part collimator
apx long_name apx
apx home 0
apx softlowerlim -255
apx softupperlim 5
apx speed 5
# Sample aperture y
#Motor apz $motor_driver_type [params \
# asyncqueue mc3\
# host mc3-lyrebird\
# port pmc3-lyrebird\
# axis F\
# units mm\
# hardlowerlim -10\
# hardupperlim 10\
# maxSpeed 1\
# maxAccel 1\
# maxDecel 1\
# stepsPerX 25000\
# absEnc 1\
# absEncHome $apz_Home\
# cntsPerX -8192]
#apz part collimator
#apz long_name apz
#setHomeandRange -motor apz -home 0 -lowrange 0 -uprange 5
#apz speed 1
# Rotary attenuator
set att_factor [expr ((1.0 - (1.0)/360.0)*(3000.0/61.0))/360.0]
Motor att $motor_driver_type [params \
asyncqueue mc3\
host mc3-lyrebird\
port pmc3-lyrebird\
axis G\
units degrees\
hardlowerlim -30\
hardupperlim 7230\
maxSpeed 10\
maxAccel 1\
maxDecel 1\
stepsPerX [expr ($att_factor*25000.0)]\
absEnc 1\
absEncHome $att_Home\
cntsPerX [expr -($att_factor*8192.0)]]
att part collimator
att long_name att
setHomeandRange -motor att -home 0 -lowrange 0 -uprange 7230
att speed 5
# 2009-12-15 Attenuator wheel was re-installed 120 degrees out of whack!!!!!!
att home -120
############################
# Motor Controller 4
# Motor Controller 4
# Motor Controller 4
############################
#
# beam stop horizontal [-100,300] mm
Motor bsx $motor_driver_type [params \
asyncqueue mc4\
host mc4-lyrebird\
port pmc4-lyrebird\
axis A\
units mm\
hardlowerlim 0\
hardupperlim 317\
maxSpeed 5\
maxAccel 2\
maxDecel 5\
stepsPerX [expr -(25000.0*7.0)/5.0/1.02]\
absEnc 1\
absEncHome $bsx_Home\
cntsPerX [expr 8192.0/5.0/1.02]]
bsx part detector
bsx long_name bsx
bsx softlowerlim 0
bsx softupperlim 310
bsx speed 5
bsx home 0
# beam stop vertical [-240,100] mm
Motor bsz $motor_driver_type [params \
asyncqueue mc4\
host mc4-lyrebird\
port pmc4-lyrebird\
axis B\
units mm\
hardlowerlim 0\
hardupperlim 280\
maxSpeed 5\
maxAccel 1\
maxDecel 5\
stepsPerX [expr (25000.0*7.0)/5.0/1.02]\
absEnc 1\
absEncHome $bsz_Home\
cntsPerX [expr (8192.0*7.0)/5.0/1.02]]
bsz part detector
bsz long_name bsz
bsz softlowerlim 0
bsz softupperlim 275
bsz home 0
# Largest beamstop
Motor bs1 $motor_driver_type [params \
asyncqueue mc4\
axis C\
units degrees\
hardlowerlim 9\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs1_Home\
cntsPerX $bs_cntsPerX]
bs1 part detector
bs1 long_name bs1
bs1 softlowerlim 11
bs1 softupperlim 95
bs1 home 90
bs1 precision 0.05
Motor bs2 $motor_driver_type [params \
asyncqueue mc4\
axis D\
units degrees\
hardlowerlim 6\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs2_Home\
cntsPerX $bs_cntsPerX]
bs2 part detector
bs2 long_name bs2
bs2 softlowerlim 7
bs2 softupperlim 95
bs2 home 90
bs2 precision 0.05
Motor bs3 $motor_driver_type [params \
asyncqueue mc4\
axis E\
units degrees\
hardlowerlim 9\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs3_Home\
cntsPerX $bs_cntsPerX]
bs3 part detector
bs3 long_name bs3
bs3 softlowerlim 11
bs3 softupperlim 95
bs3 home 90
bs3 precision 0.05
Motor bs4 $motor_driver_type [params \
asyncqueue mc4\
axis F\
units degrees\
hardlowerlim 6\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs4_Home\
cntsPerX $bs_cntsPerX]
bs4 part detector
bs4 long_name bs4
bs4 softlowerlim 7
bs4 softupperlim 95
bs4 home 90
bs4 precision 0.05
Motor bs5 $motor_driver_type [params \
asyncqueue mc4\
axis G\
units degrees\
hardlowerlim 9\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs5_Home\
cntsPerX $bs_cntsPerX]
bs5 part detector
bs5 long_name bs5
bs5 softlowerlim 11
bs5 softupperlim 95
bs5 home 90
bs5 precision 0.05
Motor bs6 $motor_driver_type [params \
asyncqueue mc4\
axis H\
units degrees\
hardlowerlim 6\
hardupperlim 95\
maxSpeed 2\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs6_Home\
cntsPerX $bs_cntsPerX]
bs6 part detector
bs6 long_name bs6
bs6 softlowerlim 7
bs6 softupperlim 95
bs6 home 90
bs6 precision 0.05
# Polarizer Rotation
#Motor pol $motor_driver_type [params \
# asyncqueue mc4\
# host mc4-lyrebird\
# port pmc4-lyrebird\
# axis H\
# units degrees\
# hardlowerlim 0\
# hardupperlim 3\
# maxSpeed 1\
# maxAccel 1\
# maxDecel 5\
# stepsPerX 25000\
# absEnc 1\
# absEncHome $pol_Home\
# cntsPerX 8192]
#pol part detector
#pol long_name pol
#pol softlowerlim 0
#pol softupperlim 3
#pol home 0
proc motor_set_sobj_attributes {} {
}
# END MOTOR CONFIGURATION
# According to http://www.nexusformat.org/Design units must conform to
# http://www.unidata.ucar.edu/software/udunits/udunits-1/udunits.txt
# So we use "count" for dimensionless decimal numbers
set vc_units count
make_coll_motor_2 c1 section_1 pc1 pc2 $vc_units
make_coll_motor_1 c2 section_2 pc3 $vc_units
make_coll_motor_1 c3 section_3 pc4 $vc_units
make_coll_motor_1 c4 section_4 pc5 $vc_units
make_coll_motor_1 c5 section_5 pc6 $vc_units
make_coll_motor_1 c6 section_6 pc7 $vc_units
make_coll_motor_1 c7 section_7 pc8 $vc_units
make_coll_motor_1 c8 section_8 pc9 $vc_units
make_coll_motor_1 c9 section_9 pc10 $vc_units
unset vc_units

View File

@@ -0,0 +1,53 @@
source $cfPath(motors)/sct_positmotor_common.tcl
set port1 [portnum pmc1-lyrebird]
set port2 [portnum pmc2-lyrebird]
set port3 [portnum pmc3-lyrebird]
set port4 [portnum pmc4-lyrebird]
makesctcontroller sct_mc1 std mc1-lyrebird:$port1
makesctcontroller sct_mc2 std mc2-lyrebird:$port2
makesctcontroller sct_mc3 std mc3-lyrebird:$port3
makesctcontroller sct_mc4 std mc4-lyrebird:$port4
# label pos
#index position
set 20sample_table {
1 453.7
2 411.7
3 369.7
4 327.7
5 285.7
6 203.7
7 161.7
8 119.7
9 77.7
10 35.7
11 -46.3
12 -88.3
13 -130.3
14 -172.3
15 -214.3
16 -296.3
17 -338.3
18 -380.3
19 -422.3
20 -464.3
}
mkPosit sct_mc1 sampleNum float samx sample $20sample_table
#diameter position
set auto_ap_table {
2.5 0
5.0 -23
7.5 -47
10.0 -72
12.5 -98
15.0 -125
17.5 -153
20.0 -183
25.0 -215
30.0 -250
}
mkPosit sct_mc3 diameter float apx sample $auto_ap_table

View File

@@ -0,0 +1,3 @@
all:
clean:

View File

@@ -0,0 +1,22 @@
mot_name=xxx
mot_units=xxx
mot_long_name=xxx
#--------------- NXmonochromator
nxcrystal_mot=/$(entryName),NXentry/$(inst),NXinstrument/$(monochromator),NXcrystal/SDS $(mot_name) -type NX_FLOAT32 -attr {units,$(mot_units)} -attr {long_name,$(mot_long_name)}
#XXX add units command to configurable virtual motors.
mth=/$(entryName),NXentry/$(inst),NXinstrument/$(monochromator),NXcrystal/SDS mth -type NX_FLOAT32 -attr {units,degree} -attr {long_name,mth}
#--------------- NXsample
nxsample_mot=/$(entryName),NXentry/sample,NXsample/SDS $(mot_name) -type NX_FLOAT32 -attr {units,$(mot_units)} -attr {long_name,$(mot_long_name)}
#XXX add units command to configurable virtual motors.
sth=/$(entryName),NXentry/sample,NXsample/SDS sth -type NX_FLOAT32 -attr {units,degree} -attr {long_name,sth}
# Slit motors
nxfilter_mot=/$(entryName),NXentry/slits,NXfilter/SDS $(mot_name) -type NX_FLOAT32 -attr {units,$(mot_units)} -attr {long_name,$(mot_long_name)}
#XXX add units command to configurable virtual motors.
ss1vg=/$(entryName),NXentry/slits,NXfilter/SDS ss1vg -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss1vg}
ss1vo=/$(entryName),NXentry/slits,NXfilter/SDS ss1vo -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss1vo}
ss1hg=/$(entryName),NXentry/slits,NXfilter/SDS ss1hg -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss1hg}
ss1ho=/$(entryName),NXentry/slits,NXfilter/SDS ss1ho -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss1ho}
ss2vg=/$(entryName),NXentry/slits,NXfilter/SDS ss2vg -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss2vg}
ss2vo=/$(entryName),NXentry/slits,NXfilter/SDS ss2vo -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss2vo}
ss2hg=/$(entryName),NXentry/slits,NXfilter/SDS ss2hg -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss2hg}
ss2ho=/$(entryName),NXentry/slits,NXfilter/SDS ss2ho -type NX_FLOAT32 -attr {units,degree} -attr {long_name,ss2ho}

View File

@@ -0,0 +1,13 @@
source $cfPath(nexus)/nxscripts_common_1.tcl
proc ::nexus::isc_initialize {} {
if {0} {
variable histmem_filetype_spec
foreach spec [array names histmem_filetype_spec] {
lappend histmem_filetype_spec($spec) link {aux_data 3 LambdaA}
lappend histmem_filetype_spec($spec) link {aux_data 4 Transmission}
lappend histmem_filetype_spec($spec) link {aux_data 5 ::histogram_memory::x_bin}
lappend histmem_filetype_spec($spec) link {aux_data 6 ::histogram_memory::y_bin}
}
}
::nexus::ic_initialize
}

View File

@@ -0,0 +1 @@
Optical Components: Neutron Guides, Apertures, Polariser, Focussing Lenses and Prisms

View File

@@ -0,0 +1,94 @@
namespace eval optics {
array set AttRotLookupTable {
0 { 0.0 1 }
30 { 1.3 0.498782 }
60 { 3.3 0.176433 }
90 { 4.9 0.0761367 }
120 { 6.4 0.0353985 }
150 { 8.3 0.0137137 }
180 { 9.6 0.00614167 }
210 {11.2 0.00264554 }
240 {13.1 0.000994504 }
270 {15.0 0.000358897 }
300 {18.0 7.2845e-05 }
330 {25.0 1.67827e-06 }
}
array set EApLookupTable {
0 { 5 circ}
30 {10 circ}
60 {20 circ}
90 {30 circ}
120 {40 circ}
150 {50 circ}
180 {50 squ }
210 {open open}
240 {open open}
270 {open open}
300 {open open}
330 {open open}
}
}
proc ::optics::AttRotLookup {angle column tol} {
variable AttRotLookupTable
set catch_status [ catch {
set foundit false
foreach vangle [array names AttRotLookupTable] {
if {$vangle >= [expr {$angle-$tol}] && $vangle <= [expr {$angle+$tol}]} {
set foundit true
break
}
}
if {$foundit == true} {
switch $column {
"plex" { set index 0 }
"attfactor" { set index 1 }
default { error "$column is unknown, allowed values are plex or attfactor" }
}
return [lindex $AttRotLookupTable($vangle) $index]
} else {
return -1
}
} message ]
handle_exception $catch_status $message
}
proc ::optics::EApLookUp {angle param tol} {
variable EApLookupTable
set foundit false
if [ catch {
if {$param == "size"} {
set cgf [SplitReply [GuideConfig]]
if {[string first $cgf "g1 g2 g3 g4 g5 g6 g7 g8 g9 p1 p2 p3 p4 p5 p6 p7 p8 p9"] != -1} {
return 50
}
}
switch $param {
"size" {set index 0}
"shape" {set index 1}
default {
error "ERROR: Invalid lookup parameter $param"
}
}
foreach vangle [array names EApLookupTable] {
if {$vangle >= [expr {$angle-$tol}] && $vangle <= [expr {$angle+$tol}]} {
set foundit true
break
}
}
if {$foundit == true} {
return [lindex $EApLookupTable($vangle) $index]
} else {
switch $param {
"size" {return 0}
"shape" {return "UNKNOWN"}
}
}
} message ] {
if {$::errorCode == "NONE"} {return $message}
return -code error "$message"
}
}

View File

@@ -0,0 +1,66 @@
##
# @file
# A guide configuration table where each line describes the setup
# for a mode of operation.
# The table will have a corresponding interpretation list which provides
# commands to setup the instrument.
namespace eval optics {
##
# @brief These arrays map the component identifiers (G, MT, etc) to the
# position index for each guide motor (c1, c2 ... c9)
array set c1_map {G 1 MT 2 P 3}
array set c2_map {MT 1 G 2 A 3}
array set c3_map {MT 1 G 2 A 3}
array set c4_map {MT 1 G 2 A 3}
array set c5_map {MT 1 G 2 A 3}
array set c6_map {MT 1 G 2 A 3}
array set c7_map {MT 1 G 2 A 3}
array set c8_map {MT 1 G 2 A 3}
array set c9_map {L 1 MT 2 G 3 A 4 LP 5}
# The guide configuration table is indexed by a configuration
# identifier (ga, mt, lp, etc). Each row has two elements,
# 1. A list of components selected for each guide (MT A ... etc)
# 2. The entrance aperature position in mm
# Eg $guide_configuration(p2) returns the following list
# {{P G A A A A A A A } 6934}
array set guide_configuration {
ga {{MT A A A A A A A A } 675}
mt {{MT MT MT MT MT MT MT MT MT} 675}
lp {{MT MT MT MT MT MT MT MT LP} 675}
lens {{MT MT MT MT MT MT MT MT L } 675}
p1 {{P A MT MT MT MT MT MT MT} 4621}
p1lp {{P A MT MT MT MT MT MT LP} 4621}
p1lens {{P A MT MT MT MT MT MT L } 4621}
g1 {{G A A A A A A A A } 4929}
p2 {{P G A A A A A A A } 6934}
g2 {{G G A A A A A A A } 6934}
p3 {{P G G A A A A A A } 8949}
g3 {{G G G A A A A A A } 8949}
p4 {{P G G G A A A A A } 10955}
g4 {{G G G G A A A A A } 10955}
p5 {{P G G G G A A A A } 12943}
g5 {{G G G G G A A A A } 12943}
p6 {{P G G G G G A A A } 14970}
g6 {{G G G G G G A A A } 14970}
p7 {{P G G G G G G A A } 16971}
g7 {{G G G G G G G A A } 16971}
p8 {{P G G G G G G G A } 18937}
g8 {{G G G G G G G G A } 18937}
p9 {{P G G G G G G G G } 19925}
g9 {{G G G G G G G G G } 19925}
}
# This list maps the motor names to columns of the
# guide_configuration table.
set guide_configuration_columns {
c1 c2 c3 c4 c5 c6 c7 c8 c9
}
}
namespace eval optics {
variable guide_configuration
variable guide_configuration_columns
}

View File

@@ -0,0 +1,2 @@
fileeval $cfPath(optics)/guide_configuration.tcl
fileeval $cfPath(optics)/aperture_configuration.tcl

View File

@@ -0,0 +1,156 @@
# TODO Make readonly getset macro for AttFactor
##
# @file The velocity selector position is used as the reference for other instrument
# component positions. For simplicity we set it as the origin x=y=z=0.
##
# Note EndFacePosY and RotApPosY are surveyed positions
foreach {var lname type priv units klass} {
BeamCenterX BeamCenterX float user mm reduce
BeamCenterZ BeamCenterZ float user mm reduce
BeamStop BeamStop int user none parameter
BSdiam BSdiam float user mm parameter
DetPosYOffset DetPosYOffset float user mm parameter
EApPosY EApPosY float user mm parameter
EndFacePosY EndFacePosY float readonly mm parameter
GuideConfig GuideConfig text user none parameter
magnetic_field magnetic_field float user T sample
RotApPosY RotApPosY float readonly mm @none
SampleThickness SampleThickness float user mm sample
SamYOffset SamYOffset float user mm parameter
Transmission Transmission float user 1 parameter
TransmissionFlag TransmissionFlag int user none sample
} {
::utility::mkVar $var $type $priv $lname true $klass true true
if {$units != "none"} {
sicslist setatt $var units $units
}
}
sicslist setatt Transmission link data_set
proc sicsmsgfmt {args} {return "[info level -1] = $args"}
::utility::macro::getset float Plex {} {
return [sicsmsgfmt [ ::optics::AttRotLookup [SplitReply [att]] "plex" [SplitReply [att precision]] ]]
}
sicslist setatt Plex units mm
sicslist setatt Plex long_name Plex
sicslist setatt Plex klass parameter
::utility::macro::getset float AttFactor {} {
return [sicsmsgfmt [ ::optics::AttRotLookup [SplitReply [att]] "attfactor" [SplitReply [att precision]] ]]
}
sicslist setatt AttFactor long_name AttFactor
sicslist setatt AttFactor klass parameter
::utility::macro::getset float EApX {} {
return [sicsmsgfmt [::optics::EApLookUp [SplitReply [srce]] "size" [SplitReply [srce precision]] ]]
}
sicslist setatt EApX units mm
sicslist setatt EApX long_name EApX
sicslist setatt EApX klass parameter
::utility::macro::getset float EApZ {} {
return [sicsmsgfmt [::optics::EApLookUp [SplitReply [srce]] "size" [SplitReply [srce precision]] ]]
}
sicslist setatt EApZ units mm
sicslist setatt EApZ long_name EApZ
sicslist setatt EApZ klass parameter
::utility::macro::getset text EApShape {} {
return [sicsmsgfmt [::optics::EApLookUp [SplitReply [srce]] "shape" [SplitReply [srce precision]] ]]
}
sicslist setatt EApShape long_name EApShape
sicslist setatt EApShape klass parameter
sicslist setatt EApShape mutable false
::utility::macro::getset float L1 {} {
set efpy [SplitReply [EndFacePosY]]
set samposy [SplitReply [samy]]
set eapy [SplitReply [EApPosY]]
return [sicsmsgfmt [expr {$efpy + $samposy - $eapy}]]
}
sicslist setatt L1 long_name L1
sicslist setatt L1 klass parameter
sicslist setatt L1 units mm
::utility::macro::getset float L2 {} {
set detpy [SplitReply [det]]
set detpyos [SplitReply [DetPosYOffset]]
set sapy [SplitReply [samy]]
return [sicsmsgfmt [expr {$detpy + $detpyos - $sapy}]]
}
sicslist setatt L2 long_name L2
sicslist setatt L2 klass parameter
sicslist setatt L2 units mm
################################################################################
# INITIALISE PARAMETERS
# The collimation system aperture positions
# Reference position is outer wall of velocity selector bunker, ie EndFacePosY
array set collapposmm {
inputguide 633
apwheel 675
ap1 4929
ap2 6934
ap3 8949
ap4 10955
ap5 12943
ap6 14970
ap7 16971
ap9 19925
}
EndFacePosY 20095
RotApPosY 675
################################################################################
# Check Config
namespace eval parameters {
set paramlist {
AttFactor
BSdiam
DetPosYOffset
EApPosY
EApShape
EApX
EApZ
EndFacePosY
L1
L2
Plex
SamYOffset
Transmission
}
}
##
# @brief List undefined parameters
proc ::parameters::missingparams {} {
variable paramlist
set num 0
foreach param $paramlist {
if {[sicslist match $param] == " "} {
clientput $param
incr num
}
}
if {$num > 0} {
clientput "There are $num missing parameters"
} else {
clientput "OK"
}
}
##
# @brief Check list
proc check {args} {
switch $args {
"missing" {
::parameters::missingparams
}
}
}
publish check user

View File

@@ -0,0 +1,8 @@
set sim_mode [SplitReply [plc_simulation]]
if {$sim_mode == "false"} {
MakeAsyncQueue plc_chan SafetyPLC 137.157.204.79 31001
MakeSafetyPLC plc plc_chan 0
}
source $cfPath(plc)/plc_common_1.tcl

View File

@@ -0,0 +1,6 @@
source $cfPath(scan)/scan_common_1.tcl
proc ::scan::pre_hmm_scan_prepare {} {}
proc ::scan::isc_initialize {} {
::scan::ic_initialize
}

View File

@@ -0,0 +1,6 @@
source $cfPath(source)/source_common.tcl
proc ::source::isc_initialize {} {
::source::ic_initialize "cold"
}

View File

@@ -0,0 +1,616 @@
# TODO Check if requested tilt-angle is within range
# TODO What should be reported for the wavelength if the tilt angle is 999.99
##
# @file
# The velocity selector control is split into two objects,
# 1. velsel_poller: This object polls the velocity selector to get its
# current state. The first time that it gets valid state info it will
# register the read and write parameters for the velocity_selector object
# and create nvs_speed and nvs_lambda drivable adapters.
# 2. velocity_selector: This object manages a set of status nodes which
# correspond to the state parameters read by the velsel_poller object.
# It also provides commands to set the speed, wavelength and angle for the velocity
# selector and provides drivable interfaces for the speed and wavelength.
#
# You can drive the velocity selector speed via the driveable object called nvs_speed
# You can drive the wavelength via the driveable object called nvs_lambda
# NOTE Doesn't provide the power loss command. Do we need it?
# Test by adding the following to barebones.tcl
# InstallHdb
# source config/velocity_selector/xsct_velsel.tcl
# hfactory /velocity_selector link velocity_selector
# The velocity selector doesn't close client connections
# if the connection is broken. It only closes the connection
# when a client logs off with "#SES#bye", NOTE bye must be lowercase.
namespace eval ::scobj::velocity_selector {
variable UID
variable PWD
variable sim_mode
variable paramindex
variable paramtype
variable pollrate 7
#from NVSOptions.cpp nha
# m_dTwistAngle degrees
# m_dTwistAngle m
# m_iMaxSpeed rpm
variable m_dTwistAngle
variable m_dLength
variable m_iMaxSpeed
variable rBeamCenter
variable VNeutron
variable blocked_speeds
set sim_mode [SplitReply [velsel_simulation]]
proc AngleSpeedToWavelength {angle VsVarSpeed} {
variable m_dTwistAngle
variable m_dLength
variable m_iMaxSpeed
variable rBeamCenter
variable VNeutron
if {$VsVarSpeed < 3100} {
return -code error "Minimum speed is 3100 rpm"
}
set lambda0 [expr ($m_dTwistAngle*60.0*$VNeutron)/(360.0*$m_dLength*$m_iMaxSpeed)]
set pi [expr acos(-1)]
# set pi = 3.14159265358979;
set A [expr (2.0 * $rBeamCenter * $pi) / (60.0 * $VNeutron)]
set angle_rad [expr ($angle * $pi) / 180.0]
set lambda1 [expr ( tan($angle_rad)+($A * $m_iMaxSpeed * $lambda0) ) / ((-($A*$A) * $m_iMaxSpeed * $VsVarSpeed * $lambda0 * tan($angle_rad) )+($A * $VsVarSpeed))]
return [format "%#.5g" $lambda1]
}
proc WavelengthToSpeed {angle lambda1} {
variable m_dTwistAngle
variable m_dLength
variable m_iMaxSpeed
variable rBeamCenter
variable VNeutron
if {$lambda1 < 4.6125} {
return -code error "Minimum wavelength is 4.6125 Angstrom"
}
set lambda0 [expr ($m_dTwistAngle*60.0*$VNeutron)/(360.0*$m_dLength*$m_iMaxSpeed)]
set pi [expr acos(-1)]
# set pi = 3.14159265358979;
set A [expr (2.0 * $rBeamCenter * $pi) / (60.0 * $VNeutron)]
set angle_rad [expr ($angle * $pi) / 180.0]
set VsVarSpeed [expr ( tan($angle_rad)+($A * $m_iMaxSpeed * $lambda0) ) / ((-($A*$A) * $m_iMaxSpeed * $lambda1 * $lambda0 * tan($angle_rad) )+($A * $lambda1))]
return [expr round($VsVarSpeed)]
}
foreach {
param index type units } {
state 0 text @none
rspeed 1 float rpm
aspeed 2 float rpm
sspeed 3 float Hz
aveto 4 text @none
ploss 5 float @none
splos 6 float @none
ttang 7 float degrees
rtemp 8 float degrees
wflow 9 float @none
winlt 10 float @none
woutt 11 float @none
vacum 12 float @none
wvalv 13 text @none
vvalv 14 text @none
vibrt 15 float @none
bcuun 16 float @none
} {
set paramindex($param) $index
set paramtype($param) $type
set paramunits($param) $units
}
MakeSICSObj velsel_poller SCT_OBJECT
MakeSICSObj velocity_selector SCT_OBJECT
sicslist setatt velocity_selector klass NXvelocity_selector
sicslist setatt velocity_selector long_name velocity_selector
proc sendUID {user} {
sct send $user
return rdPwdChallenge
}
proc rdPwdChallenge {} {
set challenge [sct result]
return sndPwd
}
proc sndPwd {pwd} {
sct send $pwd
return rdPwdAck
}
proc rdPwdAck {} {
set ack [sct result]
return idle
}
##
# @brief Request a state report from the velocity selector
proc getStatus {} {
sct send "N#SOS#STATE "
return rdState
}
##
# @brief Read the current state report from the velocity selector.
proc rdState {root statuspath} {
variable paramindex
set staterep [sct result]
if {[string match {ASCERR:*} $staterep]} {
hset $root/device_error $staterep
return idle
}
if {[string match {*#SES#You are not a valid user*} $staterep]} {
return sendUID
}
if {[string match {N#SOS#*} $staterep] == 0 } {
hset $root/device_error $staterep
return idle
}
set status [lrange [split $staterep "#"] 3 end-1]
set rspeed [lindex $status $paramindex(rspeed) end]
set aspeed [lindex $status $paramindex(aspeed) end]
set speedvar [expr 0.2*$rspeed/100]
if {[hval $root/status] == "busy"} {
set target [hgetpropval $root/setspeed target]
if {$rspeed != $target} {
hset $root/device_error "Resending target speed $target"
hset $root/setspeed $target"
return idle
}
if {[expr abs($rspeed - $aspeed)] <= $speedvar} {
hset $root/status "idle"
statemon stop nvs_speed
statemon stop nvs_lambda
if [hgetpropval $root/setspeed driving] {
hsetprop $root/setspeed driving 0
hsetprop $root/setLambda driving 0
}
}
}
if {$staterep != [sct oldval]} {
set state [lindex $status $paramindex(state) end]
if {$state != [sct oldstate]} {
if {[string match {*CONTROL*} $state] && [expr abs($rspeed - $aspeed)] > $speedvar} {
# hset $root/status "busy"
} elseif {[string match {*CONTROL*} $state]==0 && $aspeed == 0} {
hset $root/status "idle"
statemon stop nvs_speed
statemon stop nvs_lambda
if [hgetpropval $root/setspeed driving] {
hsetprop $root/setspeed driving 0
hsetprop $root/setLambda driving 0
}
}
sct oldstate $state
}
if {[sct oldval] == "UNKNOWN"} {
sct_velsel_init $root
}
sct oldval $staterep
sct update $status
sct utime readtime
}
if {[hval $root/device_error] != ""} {
hset $root/device_error ""
}
return idle
}
##
# @brief This dummy read command forces a transition to a state which
# will update a parameter from the current status.
proc getpar {nextstate} {
return $nextstate
}
proc noResponse {} {
sct result
return idle
}
##
# @brief Looks up a parameter in the current status and updates the
# parameter node.
# @param statuspath, path to the poller object's status node.
# @param parindex, index of the required parameter
proc updatepar {statuspath parindex} {
set data [lindex [hval $statuspath] $parindex end]
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
}
return idle
}
proc setSpeed {vs_root statuspath nextState} {
variable paramindex
set speed [format "%5d" [sct target]]
sct send "N#SOS#SPEED $speed"
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set lambda [AngleSpeedToWavelength $angle $speed]
sct target $speed
hsetprop $vs_root/setLambda target $lambda
hset $vs_root/status "busy"
statemon start nvs_speed
statemon start nvs_lambda
if {[sct writestatus] == "start"} {
# Called by drive adapter
hsetprop $vs_root/setspeed driving 1
hsetprop $vs_root/setLambda driving 1
}
return $nextState
}
proc sendCommand {nextState} {
set state [string tolower [sct target]]
switch $state {
"idle" {
sct send "N#SOS#IDLE "
}
"brake" {
sct send "N#SOS#BRAKE "
}
"init" {
sct send "N#SOS#TTINIT"
}
default {
return idle
}
}
return $nextState
}
proc readLambda {statuspath} {
variable paramindex
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set aspeed [lindex [hval $statuspath] $paramindex(aspeed) end]
if {$aspeed >= 800} {
set lambda [AngleSpeedToWavelength $angle $aspeed]
} else {
set lambda 9999
}
if {$lambda != [sct oldval]} {
sct oldval $lambda
sct update $lambda
sct utime readtime
}
return idle
}
##
# @brief This will check if turntable operation is allowed
proc ttableCheck {statuspath nextState} {
variable paramindex
set state [lindex [hval $statuspath] $paramindex(state) end]
set aspeed [lindex [hval $statuspath] $paramindex(aspeed) end]
if {[string match {*CONTROL*} $state] || $aspeed != 0} {
error "Not allowed while the velocity selector is running"
}
return OK
}
proc is_Speed_in_blocked_range {speed} {
variable blocked_speeds
foreach {min max} $blocked_speeds {
if {$min <= $speed && $speed <= $max} {
error "Speed of $speed rpm is within the blocked range of $min to $max rpm"
}
}
return OK
}
proc get_nearest_allowed_speed {speed} {
variable blocked_speeds
set speed_ok true
foreach {min max} $blocked_speeds {
if {$min <= $speed && $speed <= $max} {
set speed_ok false
break
}
}
if {$speed_ok} {
return $speed
} else {
foreach {min max} $blocked_speeds {
if {$min <= $speed && $speed <= $max} {
if {$min == -inf} {
return [expr $max+10]
}
if {$max == inf} {
return [expr $min-10]
}
if {[expr $max - $speed] > [expr $speed - $min]} {
return [expr $min-10]
} else {
return [expr $max+10]
}
}
}
}
}
##
# @brief This will check if the requested speed is allowed
proc checkBlockedSpeeds {statuspath} {
variable paramindex
set speed [sct target]
set ttang [lindex [hval $statuspath] $paramindex(ttang) end]
if {$ttang > 90} {
error "ERROR: You must first initialise the turntable"
}
return [is_Speed_in_blocked_range $speed]
}
##
# @brief This will check if target wavelength is allowed
proc checkBlockedWavelengths {statuspath} {
variable paramindex
set lambda [sct target]
set ttang [lindex [hval $statuspath] $paramindex(ttang) end]
if {$ttang > 90} {
error "ERROR: You must first initialise the turntable"
}
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set speed [WavelengthToSpeed $angle $lambda]
return [is_Speed_in_blocked_range $speed]
}
##
# @brief Implement the checkstatus command for the drivable interface
#
# NOTE: The drive adapter initially sets the writestatus to "start" and will
# only call this when writestatus!="start"
# TODO Do we need to handle hardware faults or is the state check in rdstate enough?
proc drivestatus {} {
if [sct driving] {
return busy
} else {
return idle
}
}
proc halt {root} {
hsetprop $root/setspeed driving 0
hsetprop $root/setLambda driving 0
hset $root/status "idle"
statemon stop nvs_speed
statemon stop nvs_lambda
set speed [get_nearest_allowed_speed [hval $root/aspeed]]
broadcast halt: set speed to $speed
catch {hset $root/setspeed $speed} msg
broadcast $msg
return idle
}
proc setPar {par nextState} {
set val [sct target]
sct send "N#SOS#$par $val"
return $nextState
}
proc setLambda {vs_root statuspath nextState} {
variable paramindex
set lambda [sct target]
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set speed [WavelengthToSpeed $angle $lambda]
set fmtspeed [format "%5d" $speed]
sct send "N#SOS#SPEED $fmtspeed"
sct target $lambda
hsetprop $vs_root/setspeed target $speed
hset $vs_root/status "busy"
statemon start nvs_speed
statemon start nvs_lambda
if {[sct writestatus] == "start"} {
# Called by drive adapter
hsetprop $vs_root/setLambda driving 1
hsetprop $vs_root/setspeed driving 1
}
return $nextState
}
# Create Velocity selector control
set scobjNS ::scobj::velocity_selector
set statusPath /sics/velsel_poller/status
set velselPath /sics/velocity_selector
hfactory $statusPath plain internal text
hsetprop $statusPath read ${scobjNS}::getStatus
hsetprop $statusPath rdState ${scobjNS}::rdState $velselPath $statusPath
hsetprop $statusPath sendUID ${scobjNS}::sendUID $UID
hsetprop $statusPath rdPwdChallenge ${scobjNS}::rdPwdChallenge
hsetprop $statusPath sndPwd ${scobjNS}::sndPwd $PWD
hsetprop $statusPath rdPwdAck ${scobjNS}::rdPwdAck
hsetprop $statusPath oldval "UNKNOWN"
hsetprop $statusPath oldstate "UNKNOWN"
# Set identifier
hfactory $velselPath/ID plain spy text
hset $velselPath/ID $velsel_ID
# Abstract status info for GumTree
hfactory $velselPath/status plain spy text
hset $velselPath/status "UNKNOWN"
hsetprop $velselPath/status values busy,idle
hfactory $velselPath/device_error plain spy text
hset $velselPath/device_error ""
# Must be set by user
hfactory $velselPath/LambdaResFWHM_percent plain user float
hfactory $velselPath/geometry plain spy none
hfactory $velselPath/geometry/position plain spy none
hfactory $velselPath/geometry/position/VelSelPosX plain user float
hsetprop $velselPath/geometry/position/VelSelPosX units "mm"
hfactory $velselPath/geometry/position/VelSelPosY plain user float
hsetprop $velselPath/geometry/position/VelSelPosY units "mm"
hfactory $velselPath/geometry/position/VelSelPosZ plain user float
hsetprop $velselPath/geometry/position/VelSelPosZ units "mm"
hfactory $velselPath/geometry/position/VelSelCoordScheme plain user text
# Setup nodes for state report parameters
foreach par [lsort [array names paramindex]] {
hfactory $velselPath/$par plain spy $paramtype($par)
hsetprop $velselPath/$par read ${scobjNS}::getpar rdpar
hsetprop $velselPath/$par rdpar ${scobjNS}::updatepar $statusPath $paramindex($par)
hsetprop $velselPath/$par oldval "UNKNOWN"
if {$paramunits($par) != "@none"} {
hsetprop $velselPath/$par units $paramunits($par)
}
}
# Initialise turntable command
hfactory $velselPath/ttinit plain spy none
hsetprop $velselPath/ttinit check ${scobjNS}::ttableCheck $statusPath ignore
hsetprop $velselPath/ttinit write ${scobjNS}::sendCommand ignore
hsetprop $velselPath/ttinit ignore ${scobjNS}::noResponse
hsetprop $velselPath/ttinit values init
# Set tilt angle
# TODO Can we set "check" to test if angle is within range then chain to ttableCheck
hfactory $velselPath/set_ttang plain spy float
hsetprop $velselPath/set_ttang check ${scobjNS}::ttableCheck $statusPath ignore
hsetprop $velselPath/set_ttang write ${scobjNS}::setPar TTANGL ignore
hsetprop $velselPath/set_ttang ignore ${scobjNS}::noResponse
hsetprop $velselPath/set_ttang units "degrees"
# Get Lambda
hfactory $velselPath/Lambda plain spy float
hsetprop $velselPath/Lambda read ${scobjNS}::getpar rdpar
hsetprop $velselPath/Lambda rdpar ${scobjNS}::readLambda $statusPath
hsetprop $velselPath/Lambda oldval "UNKNOWN"
hsetprop $velselPath/Lambda units "Angstrom"
hsetprop $velselPath/Lambda permlink data_set
# Set Lambda
hfactory $velselPath/setLambda plain spy float
hsetprop $velselPath/setLambda check ${scobjNS}::checkBlockedWavelengths $statusPath
hsetprop $velselPath/setLambda write ${scobjNS}::setLambda $velselPath $statusPath ignore
hsetprop $velselPath/setLambda ignore ${scobjNS}::noResponse
hsetprop $velselPath/setLambda driving 0
#TODO WARNING remove sicsdev and type if setLambda gets a drive addapter
# hsetprop $velselPath/setLambda sicsdev "nvs_lambda"
hsetprop $velselPath/setLambda type "drivable"
hsetprop $velselPath/setLambda target 0
hsetprop $velselPath/setLambda writestatus "UNKNOWN"
hsetprop $velselPath/setLambda units "Angstrom"
# Set speed
hfactory $velselPath/setspeed plain spy int
hsetprop $velselPath/setspeed check ${scobjNS}::checkBlockedSpeeds $statusPath
hsetprop $velselPath/setspeed write ${scobjNS}::setSpeed $velselPath $statusPath ignore
hsetprop $velselPath/setspeed ignore ${scobjNS}::noResponse
hsetprop $velselPath/setspeed driving 0
hsetprop $velselPath/setspeed type "drivable"
hsetprop $velselPath/setspeed target 0
hsetprop $velselPath/setspeed writestatus "UNKNOWN"
hsetprop $velselPath/setspeed units "rpm"
# Stop velocity selector (brake or idle)
hfactory $velselPath/cmd plain spy text
hsetprop $velselPath/cmd write ${scobjNS}::sendCommand ignore
hsetprop $velselPath/cmd ignore ${scobjNS}::noResponse
hsetprop $velselPath/cmd values brake,idle
#XXX ::scobj::hinitprops velocity_selector
::scobj::set_required_props $velselPath
hsetprop $velselPath klass NXvelocity_selector
hsetprop $velselPath privilege spy
hsetprop $velselPath type part
hsetprop $velselPath control true
hsetprop $velselPath data true
hsetprop $velselPath/geometry klass NXgeometry
hsetprop $velselPath/geometry privilege spy
hsetprop $velselPath/geometry type instrument
hsetprop $velselPath/geometry data true
hsetprop $velselPath/geometry control true
hsetprop $velselPath/geometry/position klass NXtranslation
hsetprop $velselPath/geometry/position privilege spy
hsetprop $velselPath/geometry/position type instrument
hsetprop $velselPath/geometry/position data true
hsetprop $velselPath/geometry/position control true
foreach {
hpath klass control data nxsave mutable priv alias
} {
Lambda parameter true true true true user velsel_lambdaa
LambdaResFWHM_percent parameter true true true true spy velsel_lambdaresfwhm_percent
rspeed parameter true true true true spy velsel_rspeed
aspeed parameter true true true true user velsel_aspeed
ttang parameter true true true true user velsel_ttang
ttinit parameter true false false true user velsel_ttang
geometry/position/VelSelPosX parameter true true true false user VelSelPosX
geometry/position/VelSelPosY parameter true true true false user VelSelPosY
geometry/position/VelSelPosZ parameter true true true false user VelSelPosZ
geometry/position/VelSelCoordScheme parameter true true true false user VelSelCoordScheme
} {
hsetprop $velselPath/$hpath nxalias $alias
hsetprop $velselPath/$hpath klass $klass
hsetprop $velselPath/$hpath privilege $priv
hsetprop $velselPath/$hpath control $control
hsetprop $velselPath/$hpath data $data
hsetprop $velselPath/$hpath nxsave $nxsave
hsetprop $velselPath/$hpath mutable $mutable
hsetprop $velselPath/$hpath sdsinfo ::nexus::scobj::sdsinfo
}
hsetprop $velselPath/setspeed checklimits ${scobjNS}::checkBlockedSpeeds $statusPath
hsetprop $velselPath/setspeed checkstatus ${scobjNS}::drivestatus
hsetprop $velselPath/setspeed halt ${scobjNS}::halt $velselPath
hsetprop $velselPath/setLambda checklimits ${scobjNS}::checkBlockedWavelengths $statusPath
hsetprop $velselPath/setLambda checkstatus ${scobjNS}::drivestatus
hsetprop $velselPath/setLambda halt ${scobjNS}::halt $velselPath
##
# @brief This is the position of the velocity selector bunker face. It is used
# as the reference for other positions. x=y=z=0.
hset $velselPath/geometry/position/VelSelPosX 0.0
hset $velselPath/geometry/position/VelSelPosY 0.0
hset $velselPath/geometry/position/VelSelPosZ 0.0
hset $velselPath/geometry/position/VelSelCoordScheme "Cartesian"
proc sct_velsel_init {velselPath } {
variable pollrate
variable paramindex
foreach par [lsort [array names paramindex]] {
sct_velsel poll $velselPath/$par $pollrate
}
sct_velsel write $velselPath/ttinit
sct_velsel write $velselPath/set_ttang
sct_velsel poll $velselPath/Lambda $pollrate
sct_velsel write $velselPath/setLambda
sct_velsel write $velselPath/setspeed
sct_velsel write $velselPath/cmd
ansto_makesctdrive nvs_speed $velselPath/setspeed $velselPath/aspeed sct_velsel
ansto_makesctdrive nvs_lambda $velselPath/setLambda $velselPath/Lambda sct_velsel
}
if {$sim_mode == "false"} {
makesctcontroller sct_velsel astvelsel $velsel_IP:$velsel_port "" 10
sct_velsel poll $statusPath $pollrate
}
}

View File

@@ -0,0 +1,52 @@
# Set currVelSel to select either the NVS40 or NVS43
set currVelSel 43
namespace eval ::scobj::velocity_selector {
variable blocked_speeds
variable velsel_IP
variable velsel_port
# Set configuration parameters for either the NVS40 or NVS43 velocity selector
set ::currVelSel [string tolower $::currVelSel]
switch $::currVelSel {
40 {
set velsel_ID "NVS40"
set velsel_IP "137.157.202.73"
set velsel_port 10000
set m_dTwistAngle 48.30
set m_dLength 0.250
set m_iMaxSpeed 28300.0
set rBeamCenter 0.1100
set VNeutron 3955.98
set ::scobj::velocity_selector::UID "NVS"
set ::scobj::velocity_selector::PWD "NVS"
set ::scobj::velocity_selector::blocked_speeds {
-inf 3099
3600 4999
7800 10599
28301 inf
}
}
43 {
# dc2-lyrebird.nbi.ansto.gov.au
set velsel_ID "NVS43"
set velsel_IP "137.157.202.74"
set velsel_port 10000
set m_dTwistAngle 37.6
set m_dLength 0.250
set m_iMaxSpeed 21000.0
set rBeamCenter 0.1100
set VNeutron 3955.98
set ::scobj::velocity_selector::UID "NVS"
set ::scobj::velocity_selector::PWD "NVS"
set ::scobj::velocity_selector::blocked_speeds {
-inf 3099
3600 4999
7800 9699
21500 inf
}
}
}
}
source $cfPath(velsel)/sct_velsel.tcl

View File

@@ -0,0 +1,52 @@
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Required by server_config.tcl
VarMake Instrument Text Internal
Instrument lyrebird
Instrument lock
#START SERVER CONFIGURATION SECTION
source util/dmc2280/dmc2280_util.tcl
source sics_ports.tcl
source server_config.tcl
#END SERVER CONFIGURATION SECTION
########################################
# INSTRUMENT SPECIFIC CONFIGURATION
fileeval $cfPath(motors)/motor_configuration.tcl
fileeval $cfPath(source)/source.tcl
source $cfPath(hipadaba)/hipadaba_configuration.tcl
fileeval $cfPath(motors)/positmotor_configuration.tcl
fileeval $cfPath(velsel)/velsel.tcl
fileeval $cfPath(parameters)/parameters.tcl
fileeval $cfPath(plc)/plc.tcl
fileeval $cfPath(optics)/optics.tcl
fileeval $cfPath(counter)/counter.tcl
#fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl
#fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl
fileeval $cfPath(hmm)/hmm_configuration.tcl
fileeval $cfPath(nexus)/nxscripts.tcl
fileeval $cfPath(hmm)/detector.tcl
fileeval $cfPath(scan)/scan.tcl
fileeval $cfPath(commands)/commands.tcl
fileeval $cfPath(anticollider)/anticollider.tcl
#fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl
#fileeval $cfPath(environment)/temperature/sct_qlink.tcl
#fileeval $cfPath(environment)/magneticField/sct_oxford_ips.tcl
#fileeval $cfPath(environment)/environment.tcl
#fileeval $cfPath(environment)/sct_mcr500_rheometer.tcl
#fileeval $cfPath(environment)/sct_protek_common.tcl
fileeval $cfPath(beamline)/spin_flipper.tcl
source gumxml.tcl
::utility::mkVar ::anticollider::protect_detector text manager protect_detector false detector true false
::anticollider::protect_detector "true"
server_init
###########################################
# WARNING: Do not add any code below server_init, if you do SICS may fail to initialise properly.
# You can add extra-configuration code in ../extraconfig.tcl

View File

@@ -0,0 +1,2 @@
sics_ports.tcl
config

View File

@@ -0,0 +1,4 @@
# Make and configure an ANSTO beam monitor counter.
# This must be sourced before the hmm_configuration.tcl until we separate the scan setup from the hmm setup
MakeCounter bm SIM 0.0
bm SetExponent 0

View File

@@ -0,0 +1,27 @@
MakeHM hmm SIM
hmm configure HistMode Normal
hmm configure OverFlowMode Ceil
hmm configure dim0 512
hmm configure dim1 128
hmm configure rank 2
hmm configure BinWidth 4
#hmm configure BinWidth 1
hmm preset 100.
hmm CountMode Timer
hmm configure Counter counter
hmm configure init 0
hmm init
#MakeScanCommand hmscan bm scan.hdd recover.bin
namespace eval histogram_memory {
proc hs_prepare {scanobjectname userobjectname} {}
proc hs_finish {scanobjectname userobjectname} {}
proc hs_count_bm_controlled {scanobjectname userobjectname point mode preset} {}
proc hmm_initialize {} {}
proc hmm_setup {mode bankNum rankNum nyc nxc ntc} {}
}
publish ::histogram_memory::hs_prepare user
publish ::histogram_memory::hs_finish user
publish ::histogram_memory::hs_count_bm_controlled user

View File

@@ -0,0 +1,4 @@
set quieckport sics-quieck-val-lyrebird
set serverport sics-server-val-lyrebird
set interruptport sics-interrupt-val-lyrebird
set telnetport sics-telnet-val-lyrebird

View File

@@ -0,0 +1,4 @@
set quieckport sics-quieck-val-lyrebird
set serverport sics-server-val-lyrebird
set interruptport sics-interrupt-val-lyrebird
set telnetport sics-telnet-val-lyrebird

View File

@@ -0,0 +1,4 @@
set quieckport sics-quieck-lyrebird
set serverport sics-server-lyrebird
set interruptport sics-interrupt-lyrebird
set telnetport sics-telnet-lyrebird

View File

@@ -0,0 +1,19 @@
# Platypus troubleshooter setup
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
set configFileName "motor_configuration.tcl"
# These subroutines should be installed on the controllers
set contSubs(dmc2280_controller1) "#AUTO #LIMSWI #SOLCTRL #TCPERR"
set contSubs(dmc2280_controller2) "#AUTO #LIMSWI #SOLCTRL #TCPERR"
set contSubs(dmc2280_controller3) "#AUTO #HOME #LOOPER #RES #TCPERR"
set contSubs(dmc2280_controller4) "#AUTO #HOME #LIMSWI #LOOPER #TCPERR"
# These threads should be running on the controllers.
set contThreads(dmc2280_controller1) "0"
set contThreads(dmc2280_controller2) "0"
set contThreads(dmc2280_controller3) "0"
set contThreads(dmc2280_controller4) "0"

View File

@@ -195,7 +195,7 @@ sicslist setatt $setpoint_script mutable true
## TODO put all the utility macros in the utility namespace ## TODO put all the utility macros in the utility namespace
namespace eval utility { namespace eval utility {
variable instrument_names [list echidna wombat kowari quokka platypus pelican taipan] variable instrument_names [list echidna wombat kowari quokka platypus pelican taipan lyrebird]
variable sics_port variable sics_port
set base_port 60000 set base_port 60000
set currbase $base_port set currbase $base_port