3 # Put loco on track segment X5 ish, facing anticlockwise
4 # ./measure-speeds /dev/railway 2 0 `seq 1 126` |tee santafe.speeds
8 # ./measure-speeds /dev/railway 1 1 `seq 1 126` 2>&1 | perl -pe '$|=1; s/\r/\n/g' | 3<&0 tclsh8.3 <(echo 'set f [open /dev/fd/3]; proc cm {} { clock clicks -milliseconds }; set z [cm]; while {[gets $f l]>=0} { puts [format "%-10s %s" [expr {[cm]-$z}] $l] }')
10 load chiark_tcl_hbytes-1.so
12 proc debug_r {m} { puts -nonewline stderr "$m\r" }
13 proc debug {m} { puts stderr $m }
17 puts -nonewline $rwy [hbytes h2raw $str]
21 global port rwy buf last_fast_speed noise funcs_msgs loco
22 set rwy [open $port r+]
23 fconfigure $rwy -blocking no -buffering none -encoding binary \
29 fileevent $rwy readable readable
33 for {set i 0} {$i < 256} {incr i} { append noise \\x [hbytes random 1] }
34 # foreach f {funcs0to4 funcs5to8} {
36 foreach f {funcs5to8} {
37 set m [exec ./hostside-old -s/dev/stdout $f $loco 0x1fff]
38 set m [hbytes raw2h $m]
39 lappend funcs_msgs ffff$m {}
46 append buf [hbytes raw2h [read $rwy]]
47 while {[regexp {^((?:[89a-f].)*[0-7].)(.*)$} $buf dummy msg buf]} {
52 proc settle-cancel-after {} {
55 after cancel $settle_after
61 global until detend settle_detend settle_time settle_after
64 if {[lsearch $settle_detend $msg]<0} { debug_r "o $msg"; return }
67 set settle_after [after $settle_time { set until 1}]
73 if {[lsearch $detend $msg]<0} { debug_r "I $msg"; return }
83 puts stderr "huh? $msg"
97 proc speed-msg {speed} {
99 list speed126 $loco [expr {abs($speed)}] [expr {$speed<0 != $reverse}]
102 proc run-until {speed new_detend} {
103 global loco until detend settle_time settle_detend
104 set detend $new_detend
107 catch { unset until }
108 xmit [speed-msg $speed]
112 proc run-until-not {speed new_detend new_settle} {
113 global loco until detend settle_time settle_detend
114 set detend $new_detend
115 set settle_detend $new_detend
116 hbytes xor settle_detend 0800
117 set settle_time $new_settle
118 catch { unset until }
119 xmit [speed-msg $speed]
123 proc instruct-speed-for {speed ms} {
124 global loco until detend settle_detend
125 catch { unset until }
128 xmit [speed-msg $speed]
129 after $ms { set until 1 }
133 proc instruct-stop-for {ms} {
134 instruct-speed-for 0 $ms
138 global errorInfo errorCode
139 puts stderr "----------\nBGERROR\n$m\n$errorInfo\n$errorCode\n----------"
142 proc xmit-now {until_funcs} {
143 global xmit_after xmit_msg funcs_msgs
145 if {![incr until_funcs -1]} {
146 set funcs_msg [lindex $funcs_msgs 0]
147 set funcs_msgs [lreplace $funcs_msgs 0 0]
148 lappend funcs_msgs $funcs_msg
153 set xmit_after [after 10 xmit-now $until_funcs]
156 global xmit_msg xmit_after detend settle_detend settle_time funcs_msgs
157 set msg [eval [list exec ./hostside-old -s/dev/stdout] $nmral]
158 set xmit_msg [hbytes raw2h $msg]
159 debug "> $xmit_msg $nmral (E $detend $settle_detend $settle_time) \[$funcs_msgs]"
160 catch { after cancel $xmit_after }
165 clock clicks -milliseconds
168 proc now-ms-click {{returnthis {}}} {
169 if {[string length $returnthis]} { return $returnthis }
172 # set f [open |[list sh -c {"$@" >/dev/dsp} x printf $noise]]
173 # fileevent $f readable [list close $f]
177 proc record-mm-per-s {how speed mm ms} {
178 debug " $how $speed: $mm / $ms"
179 set mmpers [expr {$mm*1.0/$ms}]
180 puts [format "%s %3d %g" $how $speed $mmpers]
182 proc timing-start {{now {}}} {
184 set start [now-ms-click $now]
186 proc timing-finish {{now {}}} {
188 set finish [now-ms-click $now]
189 return [expr {$finish-$start}]
192 proc goto-slow-start-position {speed} {
193 global last_fast_speed
194 if {$last_fast_speed >= 0} {
195 run-until -100 {9804 980a}
196 set last_fast_speed -1
198 run-until -40 {9802 9804}
199 run-until-not -40 9804 600
200 instruct-speed-for -40 [expr {$speed*$speed}]
201 instruct-stop-for 1000
204 proc begin-slow-test {speed} {
205 debug "==================== $speed S ===================="
206 goto-slow-start-position $speed
207 run-until $speed 9804
210 proc slow-speed-test {speed} {
211 begin-slow-test $speed
213 run-until $speed 980a
214 record-mm-per-s S $speed 231 [timing-finish]
215 instruct-stop-for 100
218 proc slow-stop-test {speed} {
219 begin-slow-test $speed
223 proc finish-stop-test {} {
233 proc prepare-fast-test {speed} {
234 global last_fast_speed
235 debug "==================== $speed F ===================="
237 set acceltime [expr {abs($last_fast_speed-$speed)*100}]
239 set finish [expr {$start + $acceltime}]
241 # we go round and round, keeping track of roughly where we
242 # are, until there has been enough time to get the speed right
243 run-until $speed 9809
244 run-until $speed 9814
245 set deficit [expr {$finish - [now-ms]}]
247 if {$deficit < 0} break
249 set last_fast_speed $speed
252 proc fast-speed-test {speed} {
253 prepare-fast-test $speed
255 set mslaps 0; set mmlaps 0
257 run-until $speed 9804
258 set now [now-ms-click]
260 incr mslaps [timing-finish $now]
262 debug "++ $mmlaps / $mslaps"
266 run-until $speed 980a
268 incr ms [timing-finish]
271 run-until-not $speed 980a 600
273 record-mm-per-s F $speed $mm $ms
274 if {$mslaps} { record-mm-per-s L $speed $mmlaps $mslaps }
277 proc fast-stop-test {speed} {
278 prepare-fast-test $speed
279 run-until $speed 9804
283 proc run-test {how speed} {
285 slow-$how-test $speed
287 fast-$how-test $speed
291 set port [lindex $argv 0]
292 set loco [lindex $argv 1]
293 set reverse [lindex $argv 2]
297 foreach s [lrange $argv 3 end] {
298 if {[regexp {^s(\d+)} $s dummy s]} {
304 instruct-stop-for 1000
306 instruct-stop-for 500