quokka config/environment/environment.tcl
Move the select_environment_controller function from quokka_configuration.tcl to here. SICS-402 Implement Quokka spin flipper control server_config.tcl Added rfgen_simulation variable r2932 | ffr | 2010-05-22 17:01:09 +1000 (Sat, 22 May 2010) | 8 lines
This commit is contained in:
committed by
Douglas Clowes
parent
b8811330f1
commit
88eefb0064
349
site_ansto/instrument/sans/config/beamline/sct_flipper.tcl
Normal file
349
site_ansto/instrument/sans/config/beamline/sct_flipper.tcl
Normal file
@@ -0,0 +1,349 @@
|
||||
##
|
||||
# @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 tuining parameter should be set to 0 for the users.
|
||||
|
||||
namespace eval ::scobj::rfgen {
|
||||
# Control states
|
||||
variable RAMPIDLE 0
|
||||
variable RAMPSTOP 1
|
||||
variable RAMPSTART 2
|
||||
variable RAMPBUSY 3
|
||||
variable RAMPTOZERO 4
|
||||
}
|
||||
|
||||
##
|
||||
# @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 stateArr(curr) [string trimleft $stateArr(curr) 0]
|
||||
}
|
||||
if {$stateArr(freq) != 0} {
|
||||
set stateArr(freq) [string trimleft $stateArr(freq) 0]
|
||||
}
|
||||
if {$stateArr(voltage) != 0} {
|
||||
set stateArr(voltage) [string trimleft $stateArr(voltage) 0]
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# @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
|
||||
|
||||
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 "|="]
|
||||
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
|
||||
}
|
||||
return stateChange
|
||||
}
|
||||
|
||||
##
|
||||
# @brief State transition function
|
||||
proc ::scobj::rfgen::stateFunc {} {
|
||||
variable RAMPIDLE
|
||||
variable RAMPSTOP
|
||||
variable RAMPSTART
|
||||
variable RAMPBUSY
|
||||
variable RAMPTOZERO
|
||||
|
||||
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
|
||||
}
|
||||
$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 ""
|
||||
|
||||
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}]
|
||||
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
|
||||
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)
|
||||
|
||||
sct_rfgen write /sics/$pa(NAME)/set_current
|
||||
sct_rfgen write /sics/$pa(NAME)/set_frequency
|
||||
}
|
||||
|
||||
# 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"} {
|
||||
sct_rfgen poll /sics/$pa(NAME) $pa(INTERVAL)
|
||||
sct_rfgen write /sics/$pa(NAME)/set_flip_on
|
||||
}
|
||||
}
|
||||
18
site_ansto/instrument/sans/config/beamline/spin_flipper.tcl
Normal file
18
site_ansto/instrument/sans/config/beamline/spin_flipper.tcl
Normal file
@@ -0,0 +1,18 @@
|
||||
fileeval $cfPath(beamline)/sct_flipper.tcl
|
||||
|
||||
# NOTE: opCurr is 10 * your operating current, ie if the current is 7.1 then opCurr = 71
|
||||
::scobj::rfgen::mkFlipper {
|
||||
name "flipper"
|
||||
address 1
|
||||
opCurr 71
|
||||
opFreq 407
|
||||
IP 137.157.202.86
|
||||
PORT 4001
|
||||
tuning 1
|
||||
interval 5
|
||||
currtol 1
|
||||
compCurr 1
|
||||
guideCurr 1
|
||||
thickness 1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
proc select_environment_controller {envtemp} {
|
||||
if [ catch {
|
||||
puts "selecting $envtemp for environment control"
|
||||
switch $envtemp {
|
||||
"lh45" {
|
||||
add_lh45 tc1 ca5-quokka 4003 1
|
||||
}
|
||||
"rhqc" {
|
||||
puts "Configuring RHQC"
|
||||
::environment::temperature::add_ls340 tc1 137.157.202.85 1
|
||||
tc1 controlsensor sensorB
|
||||
puts "Added tc1 with [tc1 controlsensor]"
|
||||
::environment::temperature::add_ls340 tc2 137.157.202.85 2
|
||||
tc2 controlsensor sensorD
|
||||
puts "Added tc2 with [tc2 controlsensor]"
|
||||
}
|
||||
"11TMagnet" {
|
||||
puts "Configuring 11TMagnet"
|
||||
::environment::temperature::add_ls340 tc1 137.157.202.85 1
|
||||
tc1 controlsensor sensorA
|
||||
}
|
||||
default {
|
||||
clientput "No temperature controller configured"
|
||||
}
|
||||
}
|
||||
} msg ] {
|
||||
puts "Failed to configure $envtemp: $msg"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user