remove quokka stuff

r3094 | jgn | 2011-04-08 12:15:13 +1000 (Fri, 08 Apr 2011) | 1 line
This commit is contained in:
Jing Chen
2011-04-08 12:15:13 +10:00
committed by Douglas Clowes
parent 665adbf4a6
commit cf9a94abd3
9 changed files with 0 additions and 1479 deletions

View File

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

View File

@@ -1,418 +0,0 @@
##
# @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

@@ -1,18 +0,0 @@
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

@@ -1,183 +0,0 @@
##
# @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

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

View File

@@ -1,22 +0,0 @@
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

@@ -1,156 +0,0 @@
# 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

@@ -1,616 +0,0 @@
# 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

@@ -1,52 +0,0 @@
# 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-taipan.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