202 lines
5.3 KiB
Tcl
202 lines
5.3 KiB
Tcl
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
|
|
|
|
proc sleep {mstime} {
|
|
set x 0
|
|
after $mstime {set x 1}
|
|
vwait x
|
|
}
|
|
|
|
# Requires a configuration array for each axis that you want to simulate.
|
|
# eg
|
|
#array set B [list AC 25000 TP 7827107 TD 25000 PA 25000 stepsperx 25000 cntsperx 8192 DC 25000 SP 25000]
|
|
# The mkSimAxes.tcl script creates files with arrays like the example above.
|
|
|
|
# Substitutes position values for _TDx and _TPx
|
|
# then evaluates the expression.
|
|
proc evaluate {args} {
|
|
regsub -all {_T[DP][ABCDEFGH]} $args {[eval [parse &]]} expression;
|
|
regsub -all {\d+(?:\.\d*)?} $expression { double(&) } expression;
|
|
return [uplevel #0 expr $expression];
|
|
}
|
|
|
|
# Evaluates a comma separated list of commands and
|
|
# returns a space separated list of values.
|
|
proc evalArgList {args} {
|
|
foreach cmd [split $args ,] {lappend values [eval [parse $cmd]]}
|
|
return $values;
|
|
}
|
|
|
|
proc dmset {cmd axis args} {
|
|
set num [scan $args {%d} val];
|
|
if {$num == 1} {
|
|
set val $args;
|
|
} else {
|
|
set val [evaluate $args]
|
|
}
|
|
set inst [string range $cmd 0 1]
|
|
switch $inst {
|
|
"PA" - "PR" {
|
|
uplevel #0 set ${axis}(MVTYPE) $inst
|
|
uplevel #0 set ${axis}($cmd) $val;
|
|
}
|
|
"JG" {
|
|
uplevel #0 set ${axis}(MVTYPE) $inst
|
|
uplevel #0 set ${axis}($cmd) $val;
|
|
# uplevel #0 set ${axis}(SP) $val;
|
|
}
|
|
"SP" - "AC" - "DC" {
|
|
uplevel #0 set ${axis}($cmd) $val;
|
|
}
|
|
default {
|
|
uplevel #0 $cmd $axis $val;
|
|
}
|
|
}
|
|
}
|
|
|
|
proc dmget {cmd axis} {
|
|
uplevel #0 set ${axis}($cmd)
|
|
}
|
|
|
|
proc dmcall {cmd paxis} {
|
|
uplevel #0 eval $cmd $paxis
|
|
}
|
|
|
|
proc DP {axis val} {
|
|
uplevel #0 eval set ${axis}(TD) $val
|
|
}
|
|
proc TS {axis} {
|
|
uplevel #0 eval set ${axis}(TS)
|
|
}
|
|
proc ST {_axis} {
|
|
upvar #0 $_axis axis;
|
|
set axis(ST) 1
|
|
while {$axis(BG) == 1} {
|
|
sleep 1000
|
|
}
|
|
}
|
|
|
|
proc SH {args} {}
|
|
proc MO {args} {}
|
|
proc LV {args} {return "FRED=1\nBARNEY=2"}
|
|
proc TI {args} {return 240}
|
|
proc XQ {args} {return 1}
|
|
|
|
proc BG {_axis} {
|
|
upvar #0 $_axis axis;
|
|
set axis(TS) 140; # moving, limit switches open
|
|
set axis(BG) 1; # motor is moving
|
|
set axis(SC) 0; # motor is running
|
|
set timeStep 0.1; # seconds
|
|
set axis(ST) 0
|
|
switch $axis(MVTYPE) {
|
|
"PA" {
|
|
set target $axis(PA);
|
|
set diff [expr $target - $axis(TD)];
|
|
set sign [expr ($axis(PA) - $axis(TD)) < 0 ? -1 : 1];
|
|
set step [expr $sign * $timeStep * $axis(SP) ];
|
|
if {[expr abs($diff) < abs($step)]} {
|
|
set step $diff;
|
|
set timeStep [expr abs($step / $axis(SP))];
|
|
}
|
|
every [expr round($timeStep * 1000)] "nextstep $_axis $step target $_axis $target $step"
|
|
}
|
|
"JG" {
|
|
set step [expr $timeStep * $axis(JG) ];
|
|
every [expr round($timeStep * 1000)] "nextstep $_axis $step jogit"
|
|
}
|
|
}
|
|
|
|
# set diff [expr $target - $axis(TD)];
|
|
# set mult [expr $axis(cntsperx).0/$axis(stepsperx)];
|
|
# set axis(TP) [expr round($diff*$mult + $axis(TP))];
|
|
# set axis(TD) $target;
|
|
}
|
|
|
|
# Don't handle _XQ _HX
|
|
proc MG {args} {
|
|
# Skip formatting
|
|
if {[string index [lindex $args 0] 0] == "F"} {
|
|
set msg [lrange $args 1 end]
|
|
} else {
|
|
set msg $args
|
|
}
|
|
# If msg starts with _ then return val for axis
|
|
if {[string index $msg 0] == "_"} {
|
|
return [evalArgList $msg];
|
|
} else {
|
|
return $msg;
|
|
}
|
|
}
|
|
|
|
|
|
proc every {ms body} {
|
|
if [eval $body] {
|
|
after $ms [list every $ms $body];
|
|
}
|
|
return;
|
|
}
|
|
|
|
proc nextstep {paxis step args} {
|
|
upvar #0 $paxis axis;
|
|
set finished false
|
|
if {($axis(ATLIM) == "upper") && ($step > 0)} {
|
|
return 0
|
|
} elseif {($axis(ATLIM) == "lower") && ($step < 0)} {
|
|
return 0
|
|
}
|
|
set mult [expr double($axis(cntsperx))/$axis(stepsperx)];
|
|
set axis(TP) [expr int($step * $mult + $axis(TP))];
|
|
set TD_POS [expr int($axis(TD) + $step)];
|
|
set axis(TD) [expr int($TD_POS)];
|
|
set currPos [expr ($axis(TP) - $axis(ABSHOME))/abs(double($axis(cntsperx)))]
|
|
if {$axis(ST) == 1} {
|
|
set axis(TS) 44; # Stopped, limit switches open
|
|
set axis(BG) 0; # motor has stopped
|
|
set axis(ST) 0; # make sure stop flag is unset
|
|
set axis(SC) 4; # motor stopped by stop command (ST)
|
|
set axis(ATLIM) false
|
|
set finished true
|
|
} elseif {$currPos >= $axis(UPLIM)} {
|
|
set axis(TS) 36; # Stopped on forward limit switch
|
|
set axis(BG) 0; # motor has stopped
|
|
set axis(ST) 0; # make sure stop flag is unset
|
|
set axis(SC) 2; # motor stopped by limit switch
|
|
set axis(ATLIM) upper
|
|
set finished true
|
|
} elseif {$currPos <= $axis(LOLIM)} {
|
|
set axis(TS) 40; # Stopped on reverse limit switch
|
|
set axis(BG) 0; # motor has stopped
|
|
set axis(ST) 0; # make sure stop flag is unset
|
|
set axis(SC) 3; # motor stopped by limit switch
|
|
set axis(ATLIM) lower
|
|
set finished true
|
|
} elseif {[eval $args]} {
|
|
# Stop if condition specified in "args" is met
|
|
# set diff [expr $target - $axis(TD)];
|
|
# set axis(TP) [expr int(round($diff*$mult + $axis(TP)))];
|
|
# set axis(TD) [expr int($target)];
|
|
set axis(TS) 44; # Stopped, limit switches open
|
|
set axis(BG) 0; # motor has stopped
|
|
set axis(ST) 0; # make sure stop flag is unset
|
|
set axis(SC) 1; # motor stopped at commanded position
|
|
set axis(ATLIM) false
|
|
set finished true
|
|
} else {
|
|
set finished false
|
|
}
|
|
if {$finished} {
|
|
set axis(MVTYPE) "unknown"
|
|
return 0
|
|
} else {
|
|
return 1
|
|
}
|
|
}
|
|
|
|
proc target {paxis target step} {
|
|
upvar #0 $paxis axis;
|
|
return [expr abs($target - $axis(TD)) < abs($step)]
|
|
}
|
|
proc jogit {} {
|
|
return false
|
|
}
|