699 lines
22 KiB
Tcl
699 lines
22 KiB
Tcl
# Table Source Document: 998-0234-004 Rev A.doc
|
|
# Speed (RPM) {veto {KpCW KpCCW} {KiCW KiCCW} {KthCW KthCCW}
|
|
# NOTE: You can use the motor direction register value to lookup the gains because motdir=0 is CW and motdir=1 is CCW
|
|
# TEST
|
|
global SCode ECode fcRPM fcPHASE
|
|
array set SCode {
|
|
OKOK 1
|
|
HWIdle 2
|
|
HWBusy 3
|
|
HWFault 4
|
|
HWPosFault 5
|
|
HWCrash 6
|
|
NOMEMORY 7
|
|
HWNoBeam 8
|
|
HWPause 9
|
|
HWWarn 10
|
|
HWRedo 11
|
|
}
|
|
array set ECode {
|
|
MOTREDO -1
|
|
MOTFAIL 0
|
|
MOTOK 1
|
|
}
|
|
set fcRPM 0
|
|
set fcPHASE 1
|
|
|
|
proc handle_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 "([info level -1]) $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"
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace eval ::chopper {
|
|
variable ch1_gains
|
|
variable ch2_gains
|
|
variable ch3_gains
|
|
variable speedMult
|
|
variable CW 0 CCW 1
|
|
variable PROPGAIN 1 INTGAIN 2 PHGAIN 3
|
|
variable POSDIR
|
|
set POSDIR $CW
|
|
|
|
array set ch1_gains {
|
|
24000 { 350 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
21000 { 400 { 10 15 } { 10 13 } { 2.33 13 } }
|
|
18000 { 450 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
15000 { 550 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
12000 { 650 { 12 12 } { 10 10 } { 10 10 } }
|
|
9000 { 950 { 10 10 } { 10 10 } { 10 10 } }
|
|
6000 { 1350 { 10 10 } { 10 10 } { 10 10 } }
|
|
3600 { 2310 { 5 5 } { 5 5 } { 5 5 } }
|
|
3000 { 2750 { 5 5 } { 5 5 } { 2.33 2.33 } }
|
|
}
|
|
|
|
array set ch2_gains {
|
|
24000 { 350 { 15 15 } { 13 13 } { 13 13 } }
|
|
21000 { 400 { 15 15 } { 13 13 } { 13 13 } }
|
|
18000 { 450 { 15 15 } { 13 13 } { 13 13 } }
|
|
15000 { 550 { 15 15 } { 13 13 } { 13 13 } }
|
|
12000 { 650 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
9000 { 950 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
6000 { 1350 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
3000 { 2750 { 5 5 } { 5 5 } { 2 2 } }
|
|
}
|
|
|
|
array set ch3_gains {
|
|
24000 { 350 { 15 10 } { 13 10 } { 13 2.33 } }
|
|
21000 { 400 { 15 10 } { 13 10 } { 13 2.33 } }
|
|
18000 { 450 { 15 10 } { 13 10 } { 13 2.33 } }
|
|
15000 { 550 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
12000 { 650 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
9000 { 950 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
6000 { 1350 { 10 10 } { 10 10 } { 2.33 2.33 } }
|
|
3000 { 2750 { 5 5 } { 5 5 } { 2 2 } }
|
|
}
|
|
|
|
set i 0
|
|
foreach mult {
|
|
1.0/12 1.0/11 1.0/10 1.0/9 1.0/8
|
|
1.0/7 1.0/6 1.0/5 1.0/4 1.0/3
|
|
1.0/2 1 1.5 2 2.5
|
|
3 3.5 4 4.5 5
|
|
5.5 6 6.5 7 7.5
|
|
8 8.5 9 9.5 10
|
|
10.5 11 11.5 12 12.5
|
|
13 13.5 14 14.5 15
|
|
16 17 18 19 20
|
|
21 22 23 24 25
|
|
26 27 28 29 30
|
|
} {
|
|
set speedMult($i) [expr double($mult)]
|
|
incr i
|
|
}
|
|
|
|
proc Echeck_ChSpeed {ch speed} {
|
|
set minSpeed 3000
|
|
array set vetoRange {min 9000 max 11000}
|
|
|
|
if {$ch != 1 && $ch != 2 && $ch != 3} {
|
|
return -code error "Chopper number ($ch) must be 1, 2, or 3"
|
|
}
|
|
if { ![string is double $speed] } {
|
|
return -code error "Speed ($speed) is not a valid number"
|
|
} elseif {$speed < $minSpeed} {
|
|
return -code error "Speed ($speed) should be >= $minSpeed"
|
|
} elseif {$speed >= $vetoRange(min) && $speed <= $vetoRange(max)} {
|
|
return -code error "Speed ($speed) is in the vetoed range: $vetoRange(min), $vetoRange(max)"
|
|
}
|
|
}
|
|
|
|
proc Echeck_gainDir {gain dir} {
|
|
variable CW
|
|
variable CCW
|
|
variable PROPGAIN
|
|
variable INTGAIN
|
|
variable PHGAIN
|
|
|
|
if {$gain != $INTGAIN && $gain != $PROPGAIN && $gain != $PHGAIN} {
|
|
return -code error "gain identifier ($gain) should be $PROPGAIN (PROPGAIN), $INTGAIN (INTGAIN), or $PHGAIN (PHGAIN)"
|
|
}
|
|
if {$dir != $CW && $dir != $CCW} {
|
|
return -code error "direction identifier ($dir) should be $CW {CW} or $CCW {CCW}"
|
|
}
|
|
}
|
|
|
|
proc findGainIndex {ch speed} {
|
|
variable ch1_gains
|
|
variable ch2_gains
|
|
variable ch3_gains
|
|
|
|
# Check argument and return error otherwise return veto window
|
|
set catch_status [ catch {
|
|
Echeck_ChSpeed $ch $speed
|
|
set speed [expr int($speed)]
|
|
set ch [expr int($ch)]
|
|
switch $ch {
|
|
1 { set gainTable ch1_gains }
|
|
2 { set gainTable ch2_gains }
|
|
3 { set gainTable ch3_gains }
|
|
}
|
|
set speeds [lsort -integer [array names $gainTable]]
|
|
set lower 0
|
|
set upper [expr [llength $speeds] - 1]
|
|
while {1} {
|
|
if {[expr $upper - $lower] == 1} {
|
|
if { $speed < [lindex $speeds $upper] } {
|
|
return "$gainTable [lindex $speeds $lower]"
|
|
} else {
|
|
return "$gainTable [lindex $speeds $upper]"
|
|
}
|
|
}
|
|
set mid [expr int(($lower + $upper)/2.0)]
|
|
if {$speed < [lindex $speeds $mid]} {
|
|
set upper $mid
|
|
} else {
|
|
set lower $mid
|
|
}
|
|
}
|
|
} message ]
|
|
handle_exception $catch_status $message
|
|
}
|
|
|
|
proc getGain {gain ch speed dir} {
|
|
variable ch1_gains
|
|
variable ch2_gains
|
|
variable ch3_gains
|
|
variable CW
|
|
variable CCW
|
|
variable INTGAIN
|
|
variable PROPGAIN
|
|
variable PHGAIN
|
|
|
|
set catch_status [ catch {
|
|
Echeck_ChSpeed $ch $speed
|
|
Echeck_gainDir $gain $dir
|
|
set gain [expr int($gain)]
|
|
set dir [expr int($dir)]
|
|
set speed [expr int($speed)]
|
|
set ch [expr int($ch)]
|
|
switch $ch {
|
|
1 { set gainTable ch1_gains }
|
|
2 { set gainTable ch2_gains }
|
|
3 { set gainTable ch3_gains }
|
|
}
|
|
foreach sp [lsort -integer -decreasing [array names $gainTable]] {
|
|
if {$sp <= $speed} {
|
|
return [lindex [set ${gainTable}($sp)] $gain $dir]
|
|
}
|
|
}
|
|
error "Failed when looking up integral gain for speed $speed"
|
|
} message ]
|
|
handle_exception $catch_status $message
|
|
}
|
|
|
|
|
|
#TODO Define a run function which looks up parameters from hdb tree and calls the setSpeed function
|
|
# pDriv->GetPosition = GetTclPos;
|
|
# pDriv->RunTo = TclRun;
|
|
# pDriv->GetStatus = TclStat;
|
|
# pDriv->GetError = TclError;
|
|
# pDriv->TryAndFixIt = TclFix;
|
|
# pDriv->SetDriverPar = TclSetPar;
|
|
# pDriv->GetDriverPar = TclGetPar;
|
|
# pDriv->Halt = TclHalt;
|
|
# pDriv->KillPrivate = KillTCL;
|
|
variable chPath "/instrument/fermi_chopper"
|
|
|
|
proc getSpeed {ch} {
|
|
variable chPath
|
|
|
|
set rSpeed [hval $chPath/$ch/rotation_speed]
|
|
return $rSpeed
|
|
}
|
|
|
|
proc findSpeedMult {sprat} {
|
|
variable speedMult
|
|
|
|
set lower 0
|
|
set upper [expr [array size speedMult] - 1]
|
|
while {1} {
|
|
if {[expr ($upper - $lower)] == 1} {
|
|
if { [ expr ($sprat - $speedMult($lower)) ] <= [expr ($speedMult($upper) - $sprat)] } {
|
|
return $speedMult($lower)
|
|
} else {
|
|
return $speedMult($upper)
|
|
}
|
|
}
|
|
set mid [expr int( ($upper + $lower) / 2.0)]
|
|
if { $sprat < $speedMult($mid) } {
|
|
set upper $mid
|
|
} else {
|
|
set lower $mid
|
|
}
|
|
}
|
|
}
|
|
|
|
proc listAllowedSpeeds {ref_period_50ns} {
|
|
variable speedMult
|
|
|
|
set ref_speed_rpm [ expr { 60.0 / ($ref_period_50ns * 50e-9) } ]
|
|
set len [array size speedMult]
|
|
for {set i 0} {$i < $len} {incr i} {
|
|
lappend speeds [format "%.2f" [expr $ref_speed_rpm * $speedMult($i)]]
|
|
}
|
|
return $speeds
|
|
}
|
|
|
|
proc get_setrefSpeedRPM {hpath node addr name {target ""}} {
|
|
if {$target == ""} {
|
|
set ref_period_50ns [ hval $hpath/$node/ref_period ]
|
|
set ref_speed_rpm [ expr { 60.0 / ($ref_period_50ns * 50e-9) } ]
|
|
return $ref_speed_rpm
|
|
} else {
|
|
set ref_period_50ns [expr {60.0 / ($target * 50e-9)} ]
|
|
hset $hpath/$node/control/set_ref_period $ref_period_50ns
|
|
return $target
|
|
}
|
|
}
|
|
##
|
|
# Return nearest allowed speed to target speed
|
|
proc abspermittedSpeed {hpath node addr name target} {
|
|
set ref_period_50ns [ hval $hpath/$node/ref_period ]
|
|
# set ref_period_50ns 333333.33333334
|
|
set ref_speed_rpm [ expr { 60.0 / ($ref_period_50ns * 50e-9) } ]
|
|
set speed [expr abs($target)]
|
|
set sprat [expr {$speed / $ref_speed_rpm}]
|
|
set mult [findSpeedMult $sprat]
|
|
set allowed_speed [expr $mult * $ref_speed_rpm]
|
|
return $allowed_speed
|
|
}
|
|
|
|
proc setSpeed {hpath node addr name target} {
|
|
global SCode
|
|
variable CW
|
|
variable CCW
|
|
variable ch1_gains
|
|
variable ch2_gains
|
|
variable ch3_gains
|
|
|
|
set currspeed [hval $hpath/$node/rotation_speed]
|
|
set currdir [hval $hpath/$node/motdir]
|
|
if {$target >= 0} {
|
|
if {$currdir != $CW && $currspeed != 0} {
|
|
clientput "ERROR: Tried to change direction when speed != 0. Set motor to idle first."
|
|
return $SCode(HWFault)
|
|
}
|
|
set dir $CW
|
|
} else {
|
|
if {$currdir != $CCW && $currspeed != 0} {
|
|
clientput "ERROR: Tried to change direction when speed != 0. Set motor to idle first."
|
|
return $SCode(HWFault)
|
|
}
|
|
set dir $CCW
|
|
}
|
|
|
|
set allowed_speed [abspermittedSpeed $hpath $node $addr $name $target]
|
|
foreach {gainTable index} [findGainIndex $addr $allowed_speed] {}
|
|
set row [array get $gainTable $index]
|
|
set vetowin [lindex $row 1 0]
|
|
set propGain [lindex $row 1 1 $dir]
|
|
set intGain [lindex $row 1 2 $dir]
|
|
set phGain [lindex $row 1 3 $dir]
|
|
|
|
hset $hpath/$node/control/set_motor_dir $dir
|
|
hset $hpath/$node/control/set_vetowin50 [expr $vetowin/50.0]
|
|
hset $hpath/$node/control/set_prop_gain $propGain
|
|
hset $hpath/$node/control/set_int_gain $intGain
|
|
hset $hpath/$node/control/set_phase_gain $phGain
|
|
hset $hpath/$node/control/set_rotspeed $allowed_speed
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
proc get_setPeriod {hpath node addr name {target ""}} {
|
|
global SCode
|
|
if {$target == ""} {
|
|
set refPeriod [hval $hpath/$node/ref_period]
|
|
return $refPeriod
|
|
} else {
|
|
hset $hpath/$node/control/set_ref_period $target
|
|
return $target
|
|
}
|
|
}
|
|
|
|
proc get_setMode {hpath node addr name {target ""}} {
|
|
global SCode
|
|
if {$target == ""} {
|
|
set mode [hval $hpath/$node/mode]
|
|
return $mode
|
|
} else {
|
|
hset $hpath/$node/control/set_mode $target
|
|
return $target
|
|
}
|
|
}
|
|
|
|
proc get_setRefDelay {hpath node addr name {target ""}} {
|
|
global SCode
|
|
if {$target == ""} {
|
|
set delay [hval $hpath/$node/ref_delay]
|
|
return $delay
|
|
} else {
|
|
hset $hpath/$node/control/set_ref_delay $target
|
|
return $target
|
|
}
|
|
}
|
|
|
|
proc get_setSettleTime {hpath node addr name {settle ""}} {
|
|
global SCode
|
|
if {$settle == ""} {
|
|
return [hgetpropval $hpath/$node settletime]
|
|
} else {
|
|
hsetprop $hpath/$node settletime $settle
|
|
return $settle
|
|
}
|
|
}
|
|
|
|
proc imot_SGetpos {hpath node addr name} {
|
|
global SCode
|
|
variable CW
|
|
variable CCW
|
|
variable POSDIR
|
|
|
|
set chpath ${hpath}/$node/rotation_speed
|
|
set speed [hval $chpath]
|
|
if {[hval $hpath/$node/motdir] == $POSDIR} {
|
|
return $speed
|
|
} else {
|
|
return -$speed
|
|
}
|
|
}
|
|
|
|
proc imot_SRun {hpath node addr name target} {
|
|
global SCode
|
|
set catch_status [ catch {
|
|
if {[hval $hpath/$node/control/device_error] != ""} {
|
|
hset $hpath/$node/control/device_error ""
|
|
}
|
|
# imot_status clears the abort flag, but this only happens if imot_status
|
|
# is being checked because of a "run" or "drive" when a stop is sent.
|
|
hsetprop $hpath/$node abort 0
|
|
set ret [setSpeed $hpath $node $addr $name $target]
|
|
if {$ret != $SCode(OKOK)} {
|
|
return $ret
|
|
}
|
|
hset $hpath/$node/control/start 1
|
|
# Disable idle if set
|
|
if {[hval $hpath/$node/idle_toggle] == 1} {
|
|
hset $hpath/$node/control/idle_toggle 1
|
|
}
|
|
hsetprop $hpath/$node/control timecheck -1
|
|
set readtime [hgetpropval $hpath read_time]
|
|
hsetprop $hpath lastupdate $readtime
|
|
return $SCode(OKOK)
|
|
} message ]
|
|
handle_exception $catch_status $message
|
|
}
|
|
|
|
proc imot_Status {hpath node addr name} {
|
|
global SCode
|
|
set catch_status [ catch {
|
|
if [hgetpropval $hpath/$node abort] {
|
|
hsetprop $hpath/$node abort 0
|
|
set errStr "ERROR: User requested stop. Aborting operation"
|
|
clientput $errStr
|
|
hsetprop $hpath/$node errmsg $errStr
|
|
return $SCode(HWFault)
|
|
}
|
|
set devErr [hval $hpath/$node/control/device_error]
|
|
if {$devErr != ""} {
|
|
set errStr "ERROR: Drive request failed. Aborting operation: device_error = $devErr"
|
|
clientput $errStr
|
|
hsetprop $hpath/$node errmsg $errStr
|
|
return $SCode(HWFault)
|
|
}
|
|
if [hpropexists $hpath geterror] {
|
|
clientput "WARNING: [hgetpropval $hpath geterror]"
|
|
}
|
|
set readtime [hgetpropval $hpath read_time]
|
|
set lastupdate [hgetpropval $hpath lastupdate]
|
|
if {$readtime <= $lastupdate} {
|
|
return $SCode(HWBusy)
|
|
}
|
|
hsetprop $hpath lastupdate $readtime
|
|
set up_to_speed [hval $hpath/$node/system_status/up_to_speed]
|
|
set phase_locked [hval $hpath/$node/system_status/phase_locked]
|
|
set timecheck [hgetpropval $hpath/$node/control timecheck]
|
|
set timeout [hgetpropval $hpath/$node settletime]
|
|
if {[hval $hpath/$node/mode] == 0} {
|
|
# RPM mode
|
|
set locked $up_to_speed
|
|
} else {
|
|
# PHASE mode
|
|
set locked $phase_locked
|
|
}
|
|
if {$locked} {
|
|
if {$timecheck == -1} {
|
|
hsetprop $hpath/$node/control timecheck $readtime
|
|
return $SCode(HWBusy)
|
|
} elseif {[expr $readtime - $timecheck] > $timeout} {
|
|
return $SCode(HWIdle)
|
|
} else {
|
|
return $SCode(HWBusy)
|
|
}
|
|
} else {
|
|
if {$timecheck != -1} {
|
|
hsetprop $hpath/$node/control timecheck $readtime
|
|
}
|
|
return $SCode(HWBusy)
|
|
}
|
|
} message ]
|
|
handle_exception $catch_status $message
|
|
}
|
|
|
|
proc imot_Halt {hpath node addr name} {
|
|
global SCode
|
|
# Don't halt the choppers just because someone sent INT1712 to interrupt a scan.
|
|
if { [GetInt] == "continue" } {
|
|
hset $hpath/$node/control/stop 1
|
|
hsetprop $hpath/$node abort 1
|
|
}
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
proc imot_GetError {hpath node addr name} {
|
|
global SCode
|
|
return [hgetpropval $hpath/$node errmsg]
|
|
}
|
|
|
|
proc imot_SFixit {hpath node addr name icode fVal} {
|
|
global ECode
|
|
|
|
return $ECode(MOTFAIL)
|
|
}
|
|
# Implementation of phase motor interface
|
|
proc imot_PhGetPos {hpath node addr name} {
|
|
set delay [hval $hpath/$node/ref_delay]
|
|
return $delay
|
|
}
|
|
|
|
proc imot_PhRun {hpath node addr name target} {
|
|
global SCode
|
|
|
|
if {[hval $hpath/$node/control/device_error] != ""} {
|
|
hset $hpath/$node/control/device_error ""
|
|
}
|
|
hset $hpath/$node/control/set_ref_delay $target
|
|
hsetprop $hpath/$node/control timecheck -1
|
|
set readtime [hgetpropval $hpath read_time]
|
|
hsetprop $hpath lastupdate $readtime
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
proc imot_PhFixit {hpath node addr name icode fVal} {
|
|
global SCode
|
|
|
|
return $SCode(MOTFAIL)
|
|
}
|
|
|
|
proc get_phase_acc {ch} {
|
|
variable chPath
|
|
|
|
set phase_acc [hval $chPath/$ch/phase_acc]
|
|
return $phase_acc
|
|
}
|
|
|
|
proc get_phase_rep {ch} {
|
|
variable chPath
|
|
|
|
set phase_rep [hval $chPath/$ch/phase_rep]
|
|
return $phase_rep
|
|
}
|
|
|
|
proc get_phase_ok {ch} {
|
|
variable chPath
|
|
|
|
set phase_ok [hval $chPath/$ch/phase_ok]
|
|
return $phase_ok
|
|
}
|
|
|
|
##
|
|
# @brief Returns the permitted speed as a multiple of the reference period
|
|
# @target 0, Lists permitted speeds as multiples of the reference speed.
|
|
# speed, Returns nearest permitted speed to the given speed.
|
|
proc permSpd {hpath node addr name target} {
|
|
global SCode
|
|
|
|
set ref_period_50ns [ hval $hpath/$node/ref_period ]
|
|
if {$target == 0} {
|
|
return "[listAllowedSpeeds $ref_period_50ns]"
|
|
}
|
|
set allowed_speed [abspermittedSpeed $hpath $node $addr $name $target]
|
|
if {$target > 0} {
|
|
return $allowed_speed
|
|
} else {
|
|
return -$allowed_speed
|
|
}
|
|
}
|
|
|
|
proc start {hpath node addr name} {
|
|
global SCode
|
|
hset $hpath/$node/control/start 1
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
# Speed motor stop
|
|
proc stop {hpath node addr name} {
|
|
global SCode
|
|
hset $hpath/$node/control/stop 1
|
|
hsetprop $hpath/$node abort 1
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
proc reset {hpath node addr name} {
|
|
global SCode
|
|
hset $hpath/$node/control/reset 1
|
|
return $SCode(OKOK)
|
|
}
|
|
|
|
proc idle {hpath node addr name} {
|
|
global SCode
|
|
hset $hpath/$node/control/idle_toggle 1
|
|
hsetprop $hpath/$node abort 1
|
|
return $SCode(OKOK)
|
|
}
|
|
}
|
|
|
|
|
|
proc mkFSpeedMot {fmot hdbroot chnode addr lowlim uplim} {
|
|
clientput [info level 0]
|
|
Motor $fmot tclmot [subst {\
|
|
getpos "::chopper::imot_SGetpos $hdbroot $chnode $addr"\
|
|
run "::chopper::imot_SRun $hdbroot $chnode $addr"\
|
|
status "::chopper::imot_Status $hdbroot $chnode $addr"\
|
|
halt "::chopper::imot_Halt $hdbroot $chnode $addr"\
|
|
geterror "::chopper::imot_GetError $hdbroot $chnode $addr"\
|
|
fixit "::chopper::imot_SFixit $hdbroot $chnode $addr"\
|
|
refspeed "::chopper::get_setrefSpeedRPM $hdbroot $chnode $addr"\
|
|
refperiod "::chopper::get_setPeriod $hdbroot $chnode $addr"\
|
|
mode "::chopper::get_setMode $hdbroot $chnode $addr"\
|
|
refdelay "::chopper::get_setRefDelay $hdbroot $chnode $addr"\
|
|
settle "::chopper::get_setSettleTime $hdbroot $chnode $addr"\
|
|
setspeed "::chopper::setSpeed $hdbroot $chnode $addr"\
|
|
permspd "::chopper::permSpd $hdbroot $chnode $addr"\
|
|
start "::chopper::start $hdbroot $chnode $addr"\
|
|
stop "::chopper::stop $hdbroot $chnode $addr"\
|
|
idle "::chopper::idle $hdbroot $chnode $addr"\
|
|
}]
|
|
sicslist setatt $fmot mtype tclmot
|
|
hsetprop $hdbroot/$chnode abort 0
|
|
$fmot movecount 5000
|
|
$fmot hardlowerlim $lowlim
|
|
$fmot hardupperlim $uplim
|
|
$fmot softlowerlim $lowlim
|
|
$fmot softupperlim $uplim
|
|
$fmot settle 30
|
|
$fmot precision 1
|
|
$fmot maxretry 0
|
|
sicslist setatt $fmot units rpm
|
|
sicslist setatt $fmot klass fermi_chopper
|
|
sicslist setatt $fmot long_name $fmot
|
|
}
|
|
|
|
proc mkFPhaseMot {fmot hdbroot chnode addr lowlim uplim} {
|
|
clientput [info level 0]
|
|
Motor $fmot tclmot [subst {\
|
|
getpos "::chopper::imot_PhGetPos $hdbroot $chnode $addr"\
|
|
run "::chopper::imot_PhRun $hdbroot $chnode $addr"\
|
|
status "::chopper::imot_Status $hdbroot $chnode $addr"\
|
|
halt "::chopper::imot_Halt $hdbroot $chnode $addr"\
|
|
geterror "::chopper::imot_GetError $hdbroot $chnode $addr"\
|
|
fixit "::chopper::imot_PhFixit $hdbroot $chnode $addr"\
|
|
refspeed "::chopper::get_setrefSpeedRPM $hdbroot $chnode $addr"\
|
|
refperiod "::chopper::get_setPeriod $hdbroot $chnode $addr"\
|
|
mode "::chopper::get_setMode $hdbroot $chnode $addr"\
|
|
refdelay "::chopper::get_setRefDelay $hdbroot $chnode $addr"\
|
|
settle "::chopper::get_setSettleTime $hdbroot $chnode $addr"\
|
|
setspeed "::chopper::setSpeed $hdbroot $chnode $addr"\
|
|
phase_acc "::chopper::get_phase_acc $hdbroot $chnode $addr"\
|
|
phase_rep "::chopper::get_phase_rep $hdbroot $chnode $addr"\
|
|
phase_ok "::chopper::get_phase_ok $hdbroot $chnode $addr"\
|
|
start "::chopper::start $hdbroot $chnode $addr"\
|
|
stop "::chopper::stop $hdbroot $chnode $addr"\
|
|
idle "::chopper::idle $hdbroot $chnode $addr"\
|
|
}]
|
|
sicslist setatt $fmot mtype tclmot
|
|
hsetprop $hdbroot/$chnode abort 0
|
|
$fmot movecount 5000
|
|
$fmot hardlowerlim $lowlim
|
|
$fmot hardupperlim $uplim
|
|
$fmot softlowerlim $lowlim
|
|
$fmot softupperlim $uplim
|
|
$fmot settle 30
|
|
$fmot precision 50
|
|
$fmot maxretry 0
|
|
sicslist setatt $fmot units ns
|
|
sicslist setatt $fmot klass fermi_chopper
|
|
sicslist setatt $fmot long_name $fmot
|
|
}
|
|
|
|
##
|
|
# @brief Make the fermichopper driver, and speed motors for the master and
|
|
# slave choppers. NOTE: You can make just one chopper motor.
|
|
#
|
|
# @param mSpdmot, Name of master chopper speed motor
|
|
# @param sSpdmot, Name of slave chopper speed motor
|
|
# @param sPhmot, Name of slave chopper phase motor
|
|
# @param master, Master chopper hdb node name
|
|
# @param maddr, Master chopper modbus address
|
|
# @param slave, Slave chopper hdb node name
|
|
# @param saddr, Slave chopper modbus address
|
|
proc mkFermiMotors { master maddr {slave "EMPTY"} {saddr "EMPTY"} } {
|
|
set mSpdmot ${master}s
|
|
set mPhmot ${master}p
|
|
set sSpdmot ${slave}s
|
|
set sPhmot ${slave}p
|
|
if {$slave != "EMPTY"} {
|
|
# Make master and slave choppers
|
|
set hdbPath [mkChoppers " $master $maddr $slave $saddr"]
|
|
mkFSpeedMot $sSpdmot $hdbPath $slave $saddr -24000 24000
|
|
mkFPhaseMot $sPhmot $hdbPath $slave $saddr 0 166.6667e6
|
|
} else {
|
|
set hdbPath [mkChoppers " $master $maddr"]
|
|
}
|
|
# Create Master Chopper Speed motor object
|
|
mkFSpeedMot $mSpdmot $hdbPath $master $maddr -24000 24000
|
|
mkFPhaseMot $mPhmot $hdbPath $master $maddr 0 166.6667e6
|
|
}
|
|
|
|
## Example for making a master and slave chopper motor
|
|
# mkFermiMotors mch 2 sch 3
|
|
# mchs mode $fcPHASE
|
|
# schs mode $fcPHASE
|
|
## Example which just makes one chopper motor
|
|
# mkFermiMotors mch 2
|
|
# mchs mode $fcPHASE
|