commands_common.tcl
Added histmem and runscan command hmm_configuration_common_1.tcl Set histmem_cmd status feedback to IDLE on COUNTEND event nxscripts_common_1.tcl When saving a set of files the time-stamp is offset from the time the first file is created. scan_common_1.tcl The hmscan hook functions now set feedback on the runscan_cmd sct_positmotor_common.tcl Added mk_sct_positmotor command to create a script context controller which runs a motor to an indexed position. Added positmotor_configuration.tcl to echidna, wombat, kowari, quokka, platypus. sans/config/motors/positmotor_configuration.tcl Has an example of a positmotor configuration for the sample changer sanx/quokka_configuration.tcl Setup feedback nodes for AttRotDeg and RotApDeg. motor_utility.tcl Added reldrive and relrun commands along with getmotpar convenience command. r2725 | ffr | 2008-10-27 15:55:48 +1100 (Mon, 27 Oct 2008) | 26 lines
This commit is contained in:
committed by
Douglas Clowes
parent
7ded983eba
commit
81f98bd337
190
site_ansto/instrument/config/motors/sct_positmotor_common.tcl
Normal file
190
site_ansto/instrument/config/motors/sct_positmotor_common.tcl
Normal file
@@ -0,0 +1,190 @@
|
||||
namespace eval ::sobj::positmotor {
|
||||
variable posit_table
|
||||
variable posit_indices
|
||||
# TODO Add a script to edit the posit_table and attach it to indexed nodes with read and write actions.
|
||||
|
||||
proc abort_on_invalid_posindex {pos} {
|
||||
variable posit_indices
|
||||
|
||||
set pos0 [lindex $posit_indices 0]
|
||||
set posend [lindex $posit_indices end]
|
||||
if {$pos < $pos0 || $pos > $posend} {
|
||||
return -code error "ERROR: Indexed position must be between $pos0 and $posend"
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Convert an indexed position to a physical motor position
|
||||
proc pos2val {pos} {
|
||||
variable posit_table
|
||||
|
||||
if [ catch {
|
||||
abort_on_invalid_posindex $pos
|
||||
set bot [expr int(floor($pos))]
|
||||
set top [expr int(ceil($pos))]
|
||||
set fract [expr fmod($pos,1)]
|
||||
set val [expr $fract * ($posit_table($top) - $posit_table($bot)) + $posit_table($bot)]
|
||||
} message ] {
|
||||
return -code error $message
|
||||
} else {
|
||||
return $val
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Convert a physical motor position to and indexed position
|
||||
proc val2pos {val precision} {
|
||||
variable posit_table
|
||||
variable posit_indices
|
||||
|
||||
set val [expr double($val)]
|
||||
set pos0 [lindex $posit_indices 0]
|
||||
set posend [lindex $posit_indices end]
|
||||
if {$val < [expr $posit_table($pos0) - $precision]} {return -$pos0}
|
||||
if {$val > [expr $posit_table($posend) + $precision]} {return -$posend}
|
||||
if [catch {
|
||||
set ibot $pos0
|
||||
set itop [lindex $posit_indices 1]
|
||||
while {$val > [expr $posit_table($itop) + $precision]} {
|
||||
incr ibot
|
||||
incr itop
|
||||
}
|
||||
set bot [expr $posit_table($ibot)]
|
||||
set top [expr $posit_table($itop)]
|
||||
if {[expr $bot - $precision] <= $val && $val <= [expr $bot + $precision]} {
|
||||
set pos $ibot
|
||||
} elseif {[expr $top - $precision] <= $val && $val <= [expr $top + $precision]} {
|
||||
set pos $itop
|
||||
} else {
|
||||
# set pos [format "%.3f" [expr int(($val -$bot)/$precision)*$precision/($top - $bot) + $ibot]]
|
||||
set pos [expr int(($val -$bot)/$precision)*$precision/($top - $bot) + $ibot]
|
||||
}
|
||||
} errmsg] {
|
||||
return -code error $errmsg
|
||||
} else {
|
||||
return $pos
|
||||
}
|
||||
}
|
||||
|
||||
proc rd_index {par motor} {
|
||||
sct result [SplitReply [$motor]]
|
||||
return state_reading_index
|
||||
}
|
||||
|
||||
proc state_reading_index {path par} {
|
||||
variable posit_table
|
||||
sct writestatus replyreceived
|
||||
set rply [val2pos [sct result] [hval $path/motprecision]]
|
||||
set data $rply
|
||||
# broadcast state_reading_index update parameter $par $data
|
||||
if {$data != [sct oldval] || [sct force_update] } {
|
||||
# if {[status] == "status = Driving" && [hval $path/state] == "idle"} {
|
||||
# hset $path/state busy
|
||||
# }
|
||||
sct oldval $data
|
||||
sct update $data
|
||||
sct force_update False
|
||||
sct utime readtime
|
||||
}
|
||||
if {[hval $path/state] == "stopping"} {
|
||||
hset $path/state idle
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
# Convert position index to a physical position before running the motor
|
||||
proc w_index {sct_controller path par motor} {
|
||||
variable posit_table
|
||||
|
||||
# broadcast w_index
|
||||
if [ catch {
|
||||
set val [pos2val [sct target] ]
|
||||
hset $path/state busy
|
||||
run $motor $val
|
||||
$sct_controller poll $path 1
|
||||
} errmsg ] {
|
||||
error $errmsg
|
||||
return idle
|
||||
} else {
|
||||
return idle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# TODO Check thread 0 and motion control disabled?
|
||||
proc check_motor {} {
|
||||
# broadcast check_motor
|
||||
set val [sct target]
|
||||
return OK
|
||||
}
|
||||
|
||||
proc setposindex {posindex val} {
|
||||
variable posit_table
|
||||
|
||||
set posit_table($posindex) $val
|
||||
}
|
||||
|
||||
proc mk_sct_positmotor {sct_controller motname param axis posit_list} {
|
||||
variable posit_table
|
||||
variable posit_indices
|
||||
|
||||
array set posit_table $posit_list
|
||||
set posit_indices [lsort [array names posit_table]]
|
||||
|
||||
|
||||
if [ catch {
|
||||
set ns ::sobj::positmotor
|
||||
set parnode ${motname}_motor
|
||||
MakeSICSObj $parnode SCT_MOTOR
|
||||
# Make setable position parameter and poll it.
|
||||
set posindex_node /sics/${parnode}/${param}
|
||||
hfactory $posindex_node plain spy float
|
||||
hsetprop $posindex_node read ${ns}::rd_index $param $motname
|
||||
hsetprop $posindex_node state_reading_index ${ns}::state_reading_index $posindex_node $param
|
||||
hsetprop $posindex_node write ${ns}::w_index $sct_controller $posindex_node $param $motname
|
||||
hsetprop $posindex_node check ${ns}::check_motor
|
||||
|
||||
hsetprop $posindex_node oldval UNKNOWN
|
||||
hsetprop $posindex_node force_update True
|
||||
# hsetprop $posindex_node motprecision [SplitReply [samx precision]]
|
||||
hfactory $posindex_node/motprecision script "getmotpar samx precision" "samx precision " float 1
|
||||
|
||||
hfactory $posindex_node/lookup_table plain spy none
|
||||
hsetprop $posindex_node/lookup_table numpos [llength $posit_indices]
|
||||
foreach posindex $posit_indices {
|
||||
hfactory $posindex_node/lookup_table/$posindex script "${ns}::pos2val $posindex" "${ns}::setposindex $posindex " float 1
|
||||
}
|
||||
|
||||
hfactory $posindex_node/state plain spy text
|
||||
hset $posindex_node/state idle
|
||||
|
||||
proc ${motname}_MOTEND {} [subst -nocommands {
|
||||
if { [hval $posindex_node/state] == "busy"} {
|
||||
$sct_controller poll $posindex_node 5
|
||||
hset $posindex_node/state stopping
|
||||
}
|
||||
}]
|
||||
publish ${ns}::${motname}_MOTEND user
|
||||
|
||||
scriptcallback connect $motname MOTEND ${ns}::${motname}_MOTEND
|
||||
|
||||
$sct_controller poll $posindex_node
|
||||
$sct_controller write $posindex_node
|
||||
|
||||
} message ] {
|
||||
return -code error $message
|
||||
}
|
||||
}
|
||||
|
||||
namespace export mk_sct_positmotor
|
||||
}
|
||||
namespace import ::sobj::positmotor::*
|
||||
##
|
||||
# Eg
|
||||
# hfactory /controllers plain spy none
|
||||
#
|
||||
# makesctcontroller /controllers/sct_mc1 std localhost:62034
|
||||
#
|
||||
# mk_sct_positmotor sct_mc1 phi phi_posindex A
|
||||
# mk_sct_positmotor sct_mc1 chi B { 1 0 2 15 3 20 }
|
||||
|
||||
Reference in New Issue
Block a user