diff --git a/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl b/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl index c682daaf..e04f25c9 100644 --- a/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl @@ -84,6 +84,39 @@ proc return_non_numeric {val} { return -9999 } } + +proc posname {pmot} { + set pos [ SplitReply [$pmot] ] + set tol [ SplitReply [$pmot precision] ] + set pnames [SplitReply [$pmot position_names]] + set positions [SplitReply [$pmot positions]] + set first_pos [lindex $positions 0] + set last_pos [lindex $positions end] + + if {[expr abs($pos - $first_pos)] < $tol} { + return [lindex $pnames 0] + } elseif {$pos < $first_pos} { + return "before_[lindex $pnames 0]" + } + + if {[expr abs($pos - $last_pos)] < $tol} { + return [lindex $pnames end] + } elseif {$pos > $last_pos} { + return "after_[lindex $pnames end]" + } + + set next_index 1 + foreach name [lrange $pnames 0 end-1] posit [lrange $positions 0 end-1] { + if {[expr abs($pos - $posit)] <= $tol} { + return $name + } elseif {$pos > [expr {$posit + $tol}] && $pos < [expr {[lindex $positions $next_index] - $tol}]} { + return "between_${name}_[lindex $pnames $next_index]" + } + incr next_index + } +} +publish posname user + # Length of a guide ::utility::mkVar lenguide float user lenguide true instrument true true # Space between guides @@ -122,6 +155,7 @@ proc nguide { {num "REPORTNUM"} {sel_ap_name "NONE"} {aprest_name "NONE"}} { set state $FINDFIRST set apdrvlist {} set pcdrvlist {} + set ap_target_list {} if {$num != "REPORTNUM"} { if {$num >= 0 && $num < 8} { if { $sel_ap_name == "NONE" || $aprest_name == "NONE" } { @@ -162,37 +196,8 @@ proc nguide { {num "REPORTNUM"} {sel_ap_name "NONE"} {aprest_name "NONE"}} { } else { error "$EMSG(invalidarg)" } - } - for {set n 1} {$n <= 8} {incr n} { - set currpos [SplitReply [pc$n]] - set table_guideunit [SplitReply [pc$n posit2unit $guideposit]] - set table_appunit [SplitReply [pc$n posit2unit $apposit]] - switch $state [subst { - $FINDFIRST { - if {[expr {abs($currpos - $table_appunit)}] <= $tol} { - continue - } elseif {[expr {abs($currpos - $table_guideunit)}] <= $tol} { - incr ng - set state $COUNT - } else { - return "$EMSG(misaligned)" - } - } - $COUNT { - if {[expr {abs($currpos - $table_guideunit)}] <= $tol} { - incr ng - } else { - # ERROR There shouldn't be any gaps in the selection - return "$EMSG(gaps)" - } - } - }] - } - if {$CheckDrive} { - if {$ng != $num} { - error "$EMSG(drivefailed)" - } elseif {$num >= 0 && $num < 8} { - set ap_target_list {} + # Select Apertures + if {$num >= 0 && $num < 8} { set sel_ap_pos [SplitReply [ ap$last ]] set req_sel_ap_pos [ SplitReply [ ap$last posit2unit $sel_ap_name ] ] set sel_ap_prec [ SplitReply [ap$last precision] ] @@ -210,21 +215,72 @@ proc nguide { {num "REPORTNUM"} {sel_ap_name "NONE"} {aprest_name "NONE"}} { if {[llength $ap_target_list] > 0} { pdrive {*}$ap_target_list } - foreach {ap_mot ap_name} $ap_target_list { - if { [expr abs($req_pos - $sel_pos)] > $prec } { - error "$EMSG(apfailed): $ap_mot" - } - } } } - return "[lindex [info level 0] 0] = $ng" + + # Check guide alignment + set ap_posname_list {} + for {set n 1} {$n <= 8} {incr n} { + set currpos [SplitReply [pc$n]] + set table_guideunit [SplitReply [pc$n posit2unit $guideposit]] + set table_appunit [SplitReply [pc$n posit2unit $apposit]] + + switch $state [subst { + $FINDFIRST { + if {[expr {abs($currpos - $table_appunit)}] <= $tol} { + set ap_posname_list {[linsert $ap_posname_list 0 ap${n}=[posname ap$n]]} + continue + } elseif {[expr {abs($currpos - $table_guideunit)}] <= $tol} { + incr ng + set state $COUNT + } else { + clientput "$EMSG(misaligned)" + break + } + } + $COUNT { + if {[expr {abs($currpos - $table_guideunit)}] <= $tol} { + incr ng + } else { + # ERROR There shouldn't be any gaps in the selection + clientput "$EMSG(gaps)" + break + } + } + }] + } + + if {$CheckDrive} { + set drive_ok true + if {$ng != $num} { + set drive_ok false + clientput "$EMSG(drivefailed): Failed to selected guides" + } + foreach {ap_mot ap_name} $ap_target_list { + set pos [SplitReply [$ap_mot]] + set tol [SplitReply [$ap_mot precision]] + set target [SplitReply [$ap_mot posit2unit $ap_name]] + if {[expr {abs($pos - $target)}] > $tol} { + set drive_ok false + clientput "$EMSG(drivefailed): Apertures off target" + break + } + } + if {$drive_ok} { + clientput "nguide finished successfully" + } else { + clientput "nguide finished with errors" + } + } + return "[lindex [info level 0] 0] = $ng $ap_posname_list" } message ] handle_exception $catch_status $message } publish nguide user ::utility::macro::getset float gs_nguide { {num "REPORTNUM"} {ap "NONE"} {aprest "NONE"}} { - return_non_numeric [nguide $num $ap $aprest] + # Just return number of selected guides from HDB node + return_non_numeric [lrange [nguide $num $ap $aprest] 2 2] } sicslist setatt gs_nguide klass instrument sicslist setatt gs_nguide long_name nguide