From 81a425e293f63da6c1d3ceee002e23e615e93c9e Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 27 Oct 2014 15:01:23 +1100 Subject: [PATCH] Revert "Anticollider changes from Platypus" This reverts commit f47c6fec812eece9f68c7bee2bcc314bcadf32ca. --- .../anticollider/anticollider_common.tcl | 118 ++++++++++++------ 1 file changed, 83 insertions(+), 35 deletions(-) diff --git a/site_ansto/instrument/config/anticollider/anticollider_common.tcl b/site_ansto/instrument/config/anticollider/anticollider_common.tcl index bde0f0c9..209a3522 100644 --- a/site_ansto/instrument/config/anticollider/anticollider_common.tcl +++ b/site_ansto/instrument/config/anticollider/anticollider_common.tcl @@ -1,10 +1,6 @@ # 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 { @@ -13,19 +9,54 @@ 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 prog - set prog "" + variable veto_rules - 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 { + 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 } - lappend prog $line + } + catch { + close $fh } } @@ -33,7 +64,7 @@ proc ::anticollider::loadscript {args} { # @brief Compile compile an anticollider declaration into a veto region table # for the anticollider script. # -# @param vprog, an anticollider declaration as a list of quote enclosed lines. +# @param veto_rules, an anticollider declaration as a list of quote enclosed lines. # @return Generates the ::anticollider::veto_region lookup table. # # Example\n @@ -44,14 +75,16 @@ 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 {vprog} { +proc ::anticollider::genveto {veto_rules} { variable veto_region array unset veto_region set lnum 1 - foreach line $vprog { + foreach line $veto_rules { 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} { @@ -88,16 +121,14 @@ 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::acscript {args} { +proc ::anticollider::veto_region_acscript {args} { variable veto_region - if {[::anticollider::enable $args] == "false"} { - foreach {regmot target} $args { - anticollision add 0 $regmot $target - } - return - } + set catch_status [ catch { foreach {regmot target} $args { + if { ! [info exists veto_region($regmot)] } { + continue + } foreach row $veto_region($regmot) { if { [lindex $row 1] == "@and"} { set forbid [lindex $row 0] @@ -116,7 +147,6 @@ proc ::anticollider::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]" } } @@ -126,17 +156,14 @@ proc ::anticollider::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] { @@ -144,7 +171,6 @@ proc ::anticollider::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)" } @@ -156,8 +182,9 @@ proc ::anticollider::acscript {args} { } } } - anticollision add 0 $regmot $target } + } message ] + handle_exception $catch_status $message } ## @@ -166,16 +193,37 @@ proc ::anticollider::init {} { variable evp variable veto_region - if [ catch { - ::anticollider::genveto $::anticollider::prog + 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 foreach motor [array names veto_region] { anticollision register $motor } - } message ] { - clientput [info level 0] ERROR: $message - if {$::errorCode=="NONE"} {return $message} - return -code error $message - } + } 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 } publish ::anticollider::acscript user