Merged 2.4 branch

r2828 | ffr | 2009-11-25 09:56:49 +1100 (Wed, 25 Nov 2009) | 2 lines
This commit is contained in:
Ferdi Franceschini
2009-11-25 09:56:49 +11:00
committed by Douglas Clowes
parent c58ee9fbcb
commit 2ec6505ef8
71 changed files with 2237 additions and 1528 deletions

View File

@@ -6,6 +6,7 @@ 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/scan/scan_common_1.hdd
config/scan/scan_common_1.tcl
@@ -13,4 +14,6 @@ config/nexus/nxscripts_common_1.tcl
config/commands/commands_common.tcl
config/motors/sct_positmotor_common.tcl
config/environment/temperature/sct_julabo_lh45.tcl
config/environment/temperature/config/lakeshore340_common.tcl
config/environment/temperature/lakeshore340_common.tcl
config/environment/temperature/sct_lakeshore_3xx.tcl
config/motors/sct_jogmotor_common.tcl

View File

@@ -15,20 +15,22 @@ proc ::histogram_memory::init_OAT_TABLE {} {
OAT_TABLE -set X { 191.5 190.5 } NXC 192 Y { -0.5 0.5 } NYC 192 T { 0 20000 } NTC 1
} message ] {
if {$::errorCode=="NONE"} {return $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 oat_nyc_eff 127
hmm configure oat_nxc_eff 127
hmm configure $INST_NYC 127
hmm configure $INST_NXC 127
}
BAT_TABLE -init
CAT_TABLE -init
@@ -52,7 +54,6 @@ proc ::histogram_memory::isc_initialize {} {
::nexus::data alias ::histogram_memory::vertical_axis ::histogram_memory::y_pixel_offset
::nexus::data alias ::histogram_memory::horizontal_axis ::histogram_memory::x_pixel_offset
} message ] {
if {$::errorCode=="NONE"} {return $message}
return -code error $message
}
}

View File

@@ -1,5 +1,5 @@
# $Revision: 1.27 $
# $Date: 2009-03-30 23:16:53 $
# $Revision: 1.28 $
# $Date: 2009-11-24 22:56:48 $
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
# Last revision by: $Author: ffr $
@@ -73,11 +73,14 @@ set att_Home 24782942
set bsx_Home 7831707
set bsz_Home 10143000
set bs5_Home 0
set bs4_Home 0
set bs3_Home 0
set bs2_Home 0
set bs1_Home 0
set bs1_Home 19027
set bs2_Home 5721
set bs3_Home 15844
set bs4_Home 23089
set bs5_Home 2293
set bs6_Home 12597
set bs_cntsPerX [expr 32768.0/360.0]
set bs_stepsPerX [expr -25000.0*160.0/360.0]
set pol_Home 7500000
# early Guide mesaurements
@@ -389,7 +392,7 @@ det precision 1
det softlowerlim 350
det softupperlim 19330
det home 350.5
det speed 20
det speed 40
det Blockage_Fail 0
# Detector translation across beam [-50,450] mm
@@ -681,11 +684,11 @@ Motor pc10 $motor_driver_type [params \
absEncHome $pc10_Home\
cntsPerX $coll_CntsPerX\
posit_count 5]
pc10 posit_1 [expr $pc10_Empty + 81920]
pc10 posit_1 26197033
pc10 posit_2 [expr $pc10_Empty]
pc10 posit_3 [expr $pc10_Guide]
pc10 posit_4 [expr $pc10_Aperture]
pc10 posit_5 [expr $pc10_Aperture - 81920]
pc10 posit_5 25730100
pc10 part collimator
pc10 long_name pc10
setHomeandRange -motor pc10 -home 0 -lowrange 190 -uprange 190
@@ -829,8 +832,8 @@ Motor bsx $motor_driver_type [params \
units mm\
hardlowerlim -200\
hardupperlim 200\
maxSpeed 1\
maxAccel 1\
maxSpeed 5\
maxAccel 2\
maxDecel 5\
stepsPerX [expr -(25000.0*7.0)/5.0/1.02]\
absEnc 1\
@@ -840,6 +843,7 @@ bsx part detector
bsx long_name bsx
bsx softlowerlim -200
bsx softupperlim 200
bsx speed 5
bsx home 0
# beam stop vertical [-240,100] mm
@@ -864,38 +868,148 @@ bsz softlowerlim -240
bsz softupperlim 80
bsz home 0
if {1} {
# largest to smallest
# MakeActionObject obj aQ JG-speed upsw downsw axis
MakeActionObject bs1 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs1gear/360.0] 8 4 C
MakeActionObject bs2 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs2gear/360.0] 8 4 D
MakeActionObject bs3 mc4 [expr $bs34sign*$bs_steps_per_rev*$bs3gear/360.0] 4 8 E
MakeActionObject bs4 mc4 [expr $bs34sign*$bs_steps_per_rev*$bs4gear/360.0] 4 8 F
MakeActionObject bs5 mc4 [expr $bs125sign*$bs_steps_per_rev*$bs5gear/360.0] 8 4 G
}
# Polarizer Rotation
Motor pol $motor_driver_type [params \
# Largest beamstop
Motor bs1 $motor_driver_type [params \
asyncqueue mc4\
axis C\
units degrees\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs1_Home\
cntsPerX $bs_cntsPerX]
bs1 part detector
bs1 long_name bs1
bs1 softlowerlim 0
bs1 softupperlim 90
bs1 home 0
sicslist setatt bs1 link parameters_group
Motor bs2 $motor_driver_type [params \
asyncqueue mc4\
axis D\
units degrees\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs2_Home\
cntsPerX $bs_cntsPerX]
bs2 part detector
bs2 long_name bs2
bs2 softlowerlim 0
bs2 softupperlim 90
bs2 home 0
sicslist setatt bs2 link parameters_group
Motor bs3 $motor_driver_type [params \
asyncqueue mc4\
axis E\
units degrees\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs3_Home\
cntsPerX $bs_cntsPerX]
bs3 part detector
bs3 long_name bs3
bs3 softlowerlim 0
bs3 softupperlim 90
bs3 home 0
sicslist setatt bs3 link parameters_group
Motor bs4 $motor_driver_type [params \
asyncqueue mc4\
axis F\
units degrees\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs4_Home\
cntsPerX $bs_cntsPerX]
bs4 part detector
bs4 long_name bs4
bs4 softlowerlim 0
bs4 softupperlim 90
bs4 home 0
sicslist setatt bs4 link parameters_group
Motor bs5 $motor_driver_type [params \
asyncqueue mc4\
axis G\
units degrees\
hardlowerlim 0\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $bs5_Home\
cntsPerX $bs_cntsPerX]
bs5 part detector
bs5 long_name bs5
bs5 softlowerlim 0
bs5 softupperlim 90
bs5 home 0
sicslist setatt bs5 link parameters_group
Motor bs6 $motor_driver_type [params \
asyncqueue mc4\
host mc4-quokka\
port pmc4-quokka\
axis H\
units degrees\
hardlowerlim 0\
hardupperlim 3\
hardupperlim 90\
maxSpeed 1\
maxAccel 1\
maxDecel 5\
stepsPerX 25000\
maxDecel 1\
stepsPerX $bs_stepsPerX\
absEnc 1\
absEncHome $pol_Home\
cntsPerX 8192]
pol part detector
pol long_name pol
pol softlowerlim 0
pol softupperlim 3
pol home 0
absEncHome $bs6_Home\
cntsPerX $bs_cntsPerX]
bs6 part detector
bs6 long_name bs6
bs6 softlowerlim 0
bs6 softupperlim 90
bs6 home 0
sicslist setatt bs6 link parameters_group
# Polarizer Rotation
#Motor pol $motor_driver_type [params \
# asyncqueue mc4\
# host mc4-quokka\
# port pmc4-quokka\
# 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 {} {
}

View File

@@ -37,7 +37,7 @@ index position
mk_sct_positmotor sct_mc1 parameter samx changer_position samplenum 20SAMPLES $20sample_table
set auto_ap_table {
thickness_mm position
diameter position
2.5 0
5.0 -23
7.5 -47

View File

@@ -1,5 +1,6 @@
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}
@@ -7,5 +8,6 @@ proc ::nexus::isc_initialize {} {
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

@@ -2,7 +2,6 @@
# @brief We can't change the coordinate scheme at runtime because this would require
# restructuring the hdb tree, but we should save it.
foreach {var lname nxname} {
VelSelCoordScheme VelSelCoordScheme coordinate_scheme
SApCoordScheme SApCoordScheme coordinate_scheme
EApCoordScheme EApCoordScheme coordinate_scheme
SampleCoordScheme SampleCoordScheme coordinate_scheme
@@ -18,11 +17,13 @@ foreach {var lname nxname} {
##
# @brief User privilege text variables
#
foreach {var lname type nxname priv units klass} {
SApShape SApShape text shape user none parameter
BSShape BSShape text shape user none parameter
SampleThickness thickness float thickness user mm sample
TransmissionFlag transmission_flag int transmission user none sample
foreach {var lname type priv units klass} {
SApShape SApShape text user none parameter
BSShape BSShape text user none parameter
SampleThickness thickness float user mm sample
TransmissionFlag transmission_flag int user none sample
magnetic_field magnetic_field float user T sample
lambda lambda float user Ao data
} {
::utility::mkVar $var $type $priv $lname true $klass true true
if {$units != "none"} {
@@ -34,9 +35,6 @@ foreach {var lname type nxname priv units klass} {
# @brief 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.
foreach {var lname nxname units klass} {
VelSelPosXmm VelSelPosXmm x mm @none
VelSelPosYmm VelSelPosYmm y mm @none
VelSelPosZmm VelSelPosZmm z mm @none
EndFacePosYmm EndFacePosYmm y mm parameter
RotApPosYmm RotApPosYmm y mm @none
} {
@@ -222,22 +220,11 @@ foreach {pname motor units} {
${pname}_status "IDLE"
}
################################################################################
##
# @brief This is the position of the velocity selector bunker face. It is used
# as the reference for other positions. x=y=z=0.
#::hdb::MakeVelocity_Selector velocity_selector {
# wavelength LambdaA
# wavelength_spread LambdaResFWHM_percent
# coordinate_scheme VelSelCoordScheme
# position {VelSelPosXmm VelSelPosYmm VelSelPosZmm}
#}
::hdb::MakeAperture sample_aperture {
shape SApShape
size {SApXmm SApZmm}
coordinate_scheme SApCoordScheme
position {SApPosXmm SApPosYmm SApPosZmm}
refpos {VelSelPosXmm EndFacePosYmm VelSelPosZmm}
}
::hdb::MakeAperture entrance_aperture {
@@ -245,7 +232,6 @@ foreach {pname motor units} {
size {EApXmm EApYmm EApZmm}
coordinate_scheme EApCoordScheme
position EApPosYmm
refpos VelSelPosYmm
}
::hdb::MakeAperture rotary_aperture {
@@ -253,27 +239,23 @@ foreach {pname motor units} {
size {RotApXmm RotApZmm}
position RotApPosYmm
orientation RotApDeg
refpos VelSelPosYmm
}
#::hdb::MakeGeometry sample_geometry sample {
# coordinate_scheme SampleCoordScheme
# position {SamplePosXmm SamplePosYmm SamplePosZmm}
# orientation {SampleTiltXDeg SampleTiltYDeg SampleRotDeg}
# refpos {VelSelPosXmm EndFacePosYmm VelSelPosZmm}
#}
::hdb::MakeGeometry detector_geometry detector {
coordinate_scheme DetCoordScheme
position {DetPosXmm DetPosYmm}
offset DetPosYOffsetmm
refpos {VelSelPosXmm EndFacePosYmm}
}
::hdb::MakeGeometry collimator_geometry collimator {
coordinate_scheme CollCoordScheme
position EndFacePosYmm
refpos VelSelPosYmm
}
::hdb::MakeGeometry beamstop_geometry beam_stop {
@@ -298,9 +280,6 @@ array set collapposmm {
ap9 19925
}
VelSelPosXmm 0.0
VelSelPosYmm 0.0
VelSelPosZmm 0.0
EndFacePosYmm 20095
RotApPosYmm 675
@@ -399,17 +378,3 @@ proc check {args} {
}
publish check user
foreach {pname bsname} {
beamstop110 bs1
beamstop88 bs2
beamstop66 bs3
beamstop44 bs4
beamstop22 bs5
} {
::utility::macro::getset text $pname {} [subst -nocommands {
return [$bsname status]
}]
sicslist setatt $pname long_name $pname
sicslist setatt $pname mutable false
sicslist setatt $pname klass derived_parameter
}

View File

@@ -1,31 +1,96 @@
# TODO Check if requested tilt-angle is within range
##
# @file
# The velocity selector control is split into two objects,
# 1. velsel_poller: This object polls the velocity selector to get its
# current state.
# 2. velsel: This object provides manages a set of status nodes which
# 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 and angle for the velocity
# selector.
# 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/velsel/sct_velsel.tcl
# hfactory /velsel link velsel
# 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.
makesctcontroller sct_velsel astvelsel 137.157.202.73:10000 "" 10
sct_velsel transact "NVS"
sct_velsel transact "NVS"
namespace eval ::scobj::velsel {
namespace eval ::scobj::velocity_selector {
variable UID
variable PWD
variable sim_mode
variable paramindex
variable paramtype
variable pollrate
set pollrate 7
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)]
}
array set paramindex {
state 0
@@ -66,27 +131,98 @@ namespace eval ::scobj::velsel {
bcuun float
}
MakeSICSObj velsel_poller SCT_OBJECT
MakeSICSObj velsel SCT_OBJECT
sicslist setatt velsel klass NXvelocity_selector
sicslist setatt velsel long_name velsel
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 "#SOS#STATE "
return rdStatus
return rdState
}
##
# @brief Read the current state report from the velocity selector.
proc rdStatus {} {
set data [sct result]
if {$data != [sct oldval]} {
sct oldval $data
set status [lrange [split $data "#"] 3 end-1]
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 {#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/setLambdaA 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/setLambdaA 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
}
@@ -116,13 +252,27 @@ namespace eval ::scobj::velsel {
return idle
}
proc setSpeed {nextState} {
proc setSpeed {vs_root statuspath nextState} {
variable paramindex
set speed [format "%5d" [sct target]]
sct send "#SOS#SPEED $speed"
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set lambda [AngleSpeedToWavelength $angle $speed]
sct target $speed
hsetprop $vs_root/setLambdaA 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/setLambdaA driving 1
}
return $nextState
}
proc setState {nextState} {
proc sendCommand {nextState} {
set state [string tolower [sct target]]
switch $state {
"idle" {
@@ -131,61 +281,327 @@ namespace eval ::scobj::velsel {
"brake" {
sct send "#SOS#BRAKE "
}
"init" {
sct send "#SOS#TTINIT"
}
default {
return idle
return idle
}
}
return $nextState
}
hfactory /sics/velsel_poller/status plain internal text
hsetprop /sics/velsel_poller/status read ::scobj::velsel::getStatus
hsetprop /sics/velsel_poller/status rdStatus ::scobj::velsel::rdStatus
hsetprop /sics/velsel_poller/status oldval UNKNOWN
proc readLambda {statuspath} {
variable paramindex
sct_velsel poll /sics/velsel_poller/status $pollrate halt read
hfactory /sics/velsel/LambdaA plain user float
hfactory /sics/velsel/LambdaResFWHM_percent plain user float
foreach par [lsort [array names paramindex]] {
hfactory /sics/velsel/$par plain spy $paramtype($par)
hsetprop /sics/velsel/$par read ::scobj::velsel::getpar rdpar
hsetprop /sics/velsel/$par rdpar ::scobj::velsel::updatepar /sics/velsel_poller/status $paramindex($par)
hsetprop /sics/velsel/$par oldval UNKNOWN
sct_velsel poll /sics/velsel/$par $pollrate
set angle [lindex [hval $statuspath] $paramindex(ttang) end]
set aspeed [lindex [hval $statuspath] $paramindex(aspeed) end]
set lambda [AngleSpeedToWavelength $angle $aspeed]
if {$lambda != [sct oldval]} {
sct oldval $lambda
sct update $lambda
sct utime readtime
}
return idle
}
hfactory /sics/velsel/setspeed plain spy $paramtype($par)
hsetprop /sics/velsel/setspeed write ::scobj::velsel::setSpeed ignore
hsetprop /sics/velsel/setspeed ignore ::scobj::velsel::noResponse
sct_velsel write /sics/velsel/setspeed
##
# @brief This will check if turntable operation is allowed
proc ttableCheck {statuspath nextState} {
variable paramindex
hfactory /sics/velsel/setstate plain spy $paramtype($par)
hsetprop /sics/velsel/setstate write ::scobj::velsel::setState ignore
hsetprop /sics/velsel/setstate ignore ::scobj::velsel::noResponse
sct_velsel write /sics/velsel/setstate
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
}
::scobj::hinitprops velsel
hsetprop /sics/velsel klass NXvelocity_selector
hsetprop /sics/velsel privilege spy
hsetprop /sics/velsel type part
::scobj::set_required_props /sics/velsel
foreach {hpath klass priv alias} {
LambdaA parameter user velsel_lambdaa
LambdaResFWHM_percent parameter user velsel_lambdaresfwhm_percent
rspeed parameter user velsel_rspeed
aspeed parameter user velsel_aspeed
ttang parameter user velsel_ttang
} {
hsetprop /sics/velsel/$hpath nxalias $alias
hsetprop /sics/velsel/$hpath klass $klass
hsetprop /sics/velsel/$hpath privilege $priv
hsetprop /sics/velsel/$hpath control true
hsetprop /sics/velsel/$hpath data true
hsetprop /sics/velsel/$hpath nxsave true
hsetprop /sics/velsel/$hpath mutable true
hsetprop /sics/velsel/$hpath sdsinfo ::nexus::scobj::sdsinfo
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/setLambdaA 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 "#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 "#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/setLambdaA 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"
# 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/VelSelPosXmm plain user float
hfactory $velselPath/geometry/position/VelSelPosYmm plain user float
hfactory $velselPath/geometry/position/VelSelPosZmm plain user float
hfactory $velselPath/geometry/position/VelSelCoordScheme plain user text
# Get parameters from state report
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"
}
# 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
# Get Lambda
hfactory $velselPath/LambdaA plain spy float
hsetprop $velselPath/LambdaA read ${scobjNS}::getpar rdpar
hsetprop $velselPath/LambdaA rdpar ${scobjNS}::readLambda $statusPath
hsetprop $velselPath/LambdaA oldval "UNKNOWN"
# Set Lambda
hfactory $velselPath/setLambdaA plain spy float
hsetprop $velselPath/setLambdaA check ${scobjNS}::checkBlockedWavelengths $statusPath
hsetprop $velselPath/setLambdaA write ${scobjNS}::setLambda $velselPath $statusPath ignore
hsetprop $velselPath/setLambdaA ignore ${scobjNS}::noResponse
hsetprop $velselPath/setLambdaA driving 0
#TODO WARNING remove sicsdev and type if setLambdaA gets a drive addapter
# hsetprop $velselPath/setLambdaA sicsdev "nvs_lambda"
hsetprop $velselPath/setLambdaA type "drivable"
hsetprop $velselPath/setLambdaA target 0
hsetprop $velselPath/setLambdaA writestatus "UNKNOWN"
# 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"
# 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} {
LambdaA 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/VelSelPosXmm parameter true true true false user VelSelPosXmm
geometry/position/VelSelPosYmm parameter true true true false user VelSelPosYmm
geometry/position/VelSelPosZmm parameter true true true false user VelSelPosZmm
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/setLambdaA checklimits ${scobjNS}::checkBlockedWavelengths $statusPath
hsetprop $velselPath/setLambdaA checkstatus ${scobjNS}::drivestatus
hsetprop $velselPath/setLambdaA 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/VelSelPosXmm 0.0
hset $velselPath/geometry/position/VelSelPosYmm 0.0
hset $velselPath/geometry/position/VelSelPosZmm 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/LambdaA $pollrate
sct_velsel write $velselPath/setLambdaA
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/setLambdaA $velselPath/LambdaA sct_velsel
}
if {$sim_mode == "false"} {
makesctcontroller sct_velsel astvelsel $velsel_IP:$velsel_port "" 10
sct_velsel poll $statusPath $pollrate
}
}

View File

@@ -1,20 +1,48 @@
puts "velsel.tcl NOT YET AVAILABLE"
if 0 {
set velsel_controller(host) 137.157.202.70
set velsel_controller(port) 10000
set velsel_controller(user) NVS
set velsel_controller(password) NVS
set currVelSel "two"
namespace eval ::scobj::velocity_selector {
variable blocked_speeds
variable velsel_IP
variable velsel_port
# Velocity Selector
MakeTCPSelector velsel [params \
Host $velsel_controller(host) \
Port $velsel_controller(port) \
User $velsel_controller(user) \
Password $velsel_controller(password) \
]
velsel add 3600 4900
velsel add 7800 10500
velsel add 30000 30000
set ::currVelSel [string tolower $::currVelSel]
switch $::currVelSel {
"one" {
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.110
set ::scobj::velocity_selector::UID "NVS"
set ::scobj::velocity_selector::PWD "NVS"
set VNeutron 3955.98
set ::scobj::velocity_selector::blocked_speeds {
-inf 3099
3600 4999
7800 10599
28301 inf
}
}
"two" {
# dc2-quokka.nbi.ansto.gov.au
set velsel_IP "137.157.202.74"
set velsel_port 10000
set m_dTwistAngle 37.6
set m_dLength 0.250
set m_iMaxSpeed 21500.0
set rBeamCenter 0.1170
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