Create object when in simulation mode nxscripts_common_1.tcl Set units attributes on script context objects data sans aperture_configuration.tcl Update rotary attenuator lookup table. Set parameters when motors positions are within tolerance of the lookup table positions. sans, parameters.tcl sct_velsel.tcl Set units and update parameter names to be consistent quokka_configuration.tcl Add convenience command to load environment controllers. server_config.tcl Make sure that controllers are properly generated when loading them from the ext raconfig.tcl. r2881 | ffr | 2010-01-29 16:50:51 +1100 (Fri, 29 Jan 2010) | 20 lines
616 lines
20 KiB
Tcl
616 lines
20 KiB
Tcl
# 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"
|
|
|
|
# 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
|
|
}
|
|
}
|