From 9350f4023be8dca8804246ca716072b8971cc9cc Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 22 Oct 2014 12:11:01 +1100 Subject: [PATCH] Anticollider changes from Platypus --- .../anticollider/anticollider_common.tcl | 118 ++++++------------ 1 file changed, 35 insertions(+), 83 deletions(-) diff --git a/site_ansto/instrument/config/anticollider/anticollider_common.tcl b/site_ansto/instrument/config/anticollider/anticollider_common.tcl index 209a3522..bde0f0c9 100644 --- a/site_ansto/instrument/config/anticollider/anticollider_common.tcl +++ b/site_ansto/instrument/config/anticollider/anticollider_common.tcl @@ -1,6 +1,10 @@ # Author: Ferdi Franceschini (ffr@ansto.gov.au) # TODO Handle sequencing when simultaneously moving multiple axes +# TODO Handle functional dependencies (just write your own tcl script) +# or get the generic acscript to call a user proc +# FIXME The anticollider module does not report the error messages from the +# anticollision script, we currently get around this by using broadcast. AntiCollisionInstall namespace eval anticollider { @@ -9,54 +13,19 @@ namespace eval anticollider { array unset ::anticollider::veto_region array set ::anticollider::veto_region "" -# Don't show 'acscript' call on error. This is done by the anticollider -# module. -proc handle_acscript_exception {status message args} { - switch $status { - 0 { - # TCL_OK, This is raised when you just drop out of the - # bottom of a 'catch' command. - return -code ok - } - 1 { - # TCL_ERROR - return -code error "$message: $args" - } - 2 { - # TCL_RETURN - return -code return "$message" - } - 3 { - # TCL_BREAK - return -code break - } - 4 { - # TCL_CONTINUE - return -code continue - } - default { - # Propogate user defined return codes with message - return -code $status "$message" - } - } -} ## # @brief Load an anticollider script proc ::anticollider::loadscript {args} { - variable veto_rules + variable prog + set prog "" - catch { - set fh [open $::cfPath(anticollider)/[lindex $args 0] RDONLY ] - while {[gets $fh line] >= 0} { - # Skip empty lines and comments - if [regexp {^\s*$|^ *#} $line] { - continue - } - lappend veto_rules $line + set fh [open $::cfPath(anticollider)/[lindex $args 0] RDONLY ] + while {[gets $fh line] >= 0} { + # Skip empty lines and comments + if [regexp {^\s*$|^ *#} $line] { + continue } - } - catch { - close $fh + lappend prog $line } } @@ -64,7 +33,7 @@ proc ::anticollider::loadscript {args} { # @brief Compile compile an anticollider declaration into a veto region table # for the anticollider script. # -# @param veto_rules, an anticollider declaration as a list of quote enclosed lines. +# @param vprog, an anticollider declaration as a list of quote enclosed lines. # @return Generates the ::anticollider::veto_region lookup table. # # Example\n @@ -75,16 +44,14 @@ proc ::anticollider::loadscript {args} { # for sphi forbid { {0 5} {10 15} } when schi in { {5 10} {15 20} }\n # forbid {-inf 5} when mtth in {0 10} for sphi\n # forbid {0 10} for samx whenall { samrot in {0 5} samy in {0 15} }\n -proc ::anticollider::genveto {veto_rules} { +proc ::anticollider::genveto {vprog} { variable veto_region array unset veto_region set lnum 1 - foreach line $veto_rules { + foreach line $vprog { array unset vp array set vp $line - clientput "::anticollider::veto_rule: $line" - if [info exists vp(whenall)] { foreach {mot in range} $vp(whenall) { # if {[llength [join $range]] != 2} { @@ -121,14 +88,16 @@ proc ::anticollider::enable {args} { # # The ::anticollider::veto_region is a hash indexed by the names of the motors # which have been registered with the anticollision module. -proc ::anticollider::veto_region_acscript {args} { +proc ::anticollider::acscript {args} { variable veto_region - set catch_status [ catch { - foreach {regmot target} $args { - if { ! [info exists veto_region($regmot)] } { - continue + if {[::anticollider::enable $args] == "false"} { + foreach {regmot target} $args { + anticollision add 0 $regmot $target } + return + } + foreach {regmot target} $args { foreach row $veto_region($regmot) { if { [lindex $row 1] == "@and"} { set forbid [lindex $row 0] @@ -147,6 +116,7 @@ proc ::anticollider::veto_region_acscript {args} { } else { foreach {min max} $forbid {} if {$min <= $target && $target <= $max} { + broadcast "ERROR:The range ($forbid) is forbidden for $regmot when [lindex $row 2]" error "ERROR:The range ($forbid) is forbidden for $regmot when [lindex $row 2]" } } @@ -156,14 +126,17 @@ proc ::anticollider::veto_region_acscript {args} { if {$obstrange == "@all"} { foreach {min max} [join $forbidden_range] { if {$min <= $target && $target <= $max} { + broadcast "ERROR: $regmot target ($target) is in the forbidden region ($forbidden_range)" error "ERROR: $regmot target ($target) is in the forbidden region ($forbidden_range)" } } } else { + broadcast "ERROR: veto table must use @all with @any" error "ERROR: veto table must use @all with @any" } } else { if {$obstrange == "@all"} { + broadcast "ERROR: veto table must use @any with @all" error "ERROR: veto table must use @any with @all" } else { foreach {lower upper} [join $obstrange] { @@ -171,6 +144,7 @@ proc ::anticollider::veto_region_acscript {args} { if {$lower <= $pos && $pos <= $upper} { foreach {min max} [join $forbidden_range] { if {$min <= $target && $target <= $max} { + broadcast "ERROR:The range $min to $max is forbidden for $regmot when $obstmot is in this region ($obstrange)" error "ERROR:The range $min to $max is forbidden for $regmot when $obstmot is in this region ($obstrange)" } @@ -182,9 +156,8 @@ proc ::anticollider::veto_region_acscript {args} { } } } + anticollision add 0 $regmot $target } - } message ] - handle_exception $catch_status $message } ## @@ -193,37 +166,16 @@ proc ::anticollider::init {} { variable evp variable veto_region - set catch_status [ catch { - if { ![info exists ::anticollider::veto_rules] } { - return - } - clientput Load anticollider rules: - if { [info procs ::anticollider::load_acrules] == "::anticollider::load_acrules" } { - ::anticollider::load_acrules - } - ::anticollider::genveto $::anticollider::veto_rules + if [ catch { + ::anticollider::genveto $::anticollider::prog foreach motor [array names veto_region] { anticollision register $motor } - } message ] - handle_exception $catch_status $message -} - -lappend ::anticollider::scripts ::anticollider::veto_region_acscript -proc ::anticollider::acscript {args} { - set catch_status [ catch { - if {[::anticollider::enable $args] == "false"} { - return - } else { - foreach {regmot target} $args { - anticollision add 0 $regmot $target - } - } - foreach script $::anticollider::scripts { - $script {*}$args - } - } message ] - handle_acscript_exception $catch_status $message + } message ] { + clientput [info level 0] ERROR: $message + if {$::errorCode=="NONE"} {return $message} + return -code error $message + } } publish ::anticollider::acscript user