namespace eval wiggle { } proc stdConfig::wiggle {} { controller syncedprot 10 obj wiggle -drive out prop checklimits wiggle::checklimits prop halt wiggle::halt prop write wiggle::write prop status idle prop read stdConfig::complete kids "wiggle settings" { node period par 2 node eperiod upd prop label "effective period" node amp par 0.001 prop label amplitude node n par 10 node shape par 6 prop help "4 for saw tooth, 6 for sine-like" node maxramp par 0.5 } } proc wiggle::checklimits {} { return 0 } proc wiggle::waitext {} { if {[result mf external] == 2} { return 0 } if {[result mf external] != 1} { mf external 1 } return 1 } proc wiggle::write {} { sct status run # wiggle around target [Tesla] with amplitude +- /wiggle/amp [Tesla] # minimum period 2 sec # number of times /wiggle/n sct cnt 0 sct oldramp [result mf ramp] set amp [hvali [sct]/amp] set period [hvali [sct]/period] set maxr [hvali [sct]/maxramp] set shape [hvali [sct]/shape] if {$period < 2} { set period 2 } set ramp [expr $amp * $shape * 60.0 / $period] if {$ramp > $maxr} { set period [expr $period * $ramp / $maxr] set ramp $maxr } # clientput "ramp $ramp period $period" hupdate [sct]/eperiod $period mf ramp $ramp mf persmode 0 set mf1 [expr [sct target] + $amp] run mf $mf1 clientput "run mf to $mf1" [sct controller] poll [sct] [expr $period * 0.5] progress wiggle::saw return idle } proc wiggle::saw {} { if {[sct status] ne "run"} { return unpoll } if {[wiggle::waitext]} { return idle } set amp [hvali [sct]/amp] set cnt [sct cnt] sct cnt [expr $cnt + 1] set maxcnt [expr 2 * [hvali [sct]/n]] # clientput "cnt$cnt" if {$cnt >= $maxcnt} { mf external 3 mf ramp [sct oldramp] run mf [sct target] sct status idle return unpoll } if {$cnt == 0} { mf send A1 return idle } if {$cnt % 2} { set f [expr [sct target] - $amp] } else { set f [expr [sct target] + $amp] } clientput "mf send J[format %.5f $f]" mf send J[format %.5f $f] return idle } proc wiggle::halt {} { mf external 3 mf ramp [sct oldramp] run mf [sct target] sct status idle return idle }