namespace eval nvstep { } proc stdConfig::nvstep {} { variable name controller syncedprot pollperiod 1 1 obj NvStep wr prop write nvstep::setmode prop read nvstep::read prop enum fixed=0,controlled=1,automatic=2,close=3,open=4 prop write nvstep::write prop lastpulse 0 prop filter 0 prop closetest 0 default 0 kids "needle value" { node motpos upd node flow upd node set out default 2.5 prop check nvstep::checkset prop write stdSct::complete prop label "flow set" node flowmax par 20 prop label "flow maximum" node ctrl -none kids "control parameters" { node prop par 50 node int par 15 node delay par 5 node dif upd node lim upd node tol upd } node autoflow -none kids "autoflow control parameters" { flow::make flow::tmts {result tt set/reg} } } } proc nvstep::checkset {} { sct update [sct target] set s [hvali [sct parent]] if {[hvali /cc/fa] == 0 || ($s != 1 && $s != 2)} { hset [sct parent] 1 } } proc nvstep::write {} { switch {[sct target]} { 3 { nvmot [hvali /nvmot/posclosed] sct closetest 1 } 4 { nvmot [hvali /nvmot/posopen] } } sct update [sct target] return idle } proc nvstep::transf {flow} { if {$flow > 1} { set flow [expr 2 - 1.0 / $flow] } return $flow } proc nvstep::poll {} { hupdate [sct]/motpos [hvali /nvmot/pos] set now [DoubleTime] set delta [expr $now - [silent 0 sct lastpoll]] sct lastpoll $now if {$delta > 1} { set delta 1 } set umsg "automatic needle valve not activated - set temperature undefined" switch [hvali [sct]] { 1 - 2 { if {[hvali [sct]] == 1} { set soll [hvali [sct]/set] hupdate [sct]/autoflow/flowtarget $soll } else { flow::task [sct]/autoflow [hvali [sct]/set] [hvali [sct]/flowmax] set soll [hvali [sct]/autoflow/flowset] if {[hgetpropval [sct]/autoflow/getTset t_set_undefined]} { if {[hvali [sct]/status] ne $umsg} { clientput "ERROR: $umsg" } hupdate [sct]/status $umsg } } set ist [hvali [sct]/flow] set soll2 [expr $soll + [hvali [sct]/ctrl/tol]] set soll [nvstep::transf $soll] set tol [expr [nvstep::transf $soll2] - $soll] set ist [nvstep::transf $ist] set dif [expr $soll - $ist] set lim [hvali [sct]/ctrl/lim] set int [hvali [sct]/ctrl/int] set lim [expr $lim * exp(-$delta/$int)] if {abs($dif) > $tol + $lim} { set lim [expr abs($dif) * exp($delta*[hvali [sct]/ctrl/delay]/double($int)) - $tol] set step [expr $dif * [hvali [sct]/ctrl/prop]] run nvmot [expr [hvali /nvmot] + $step] } hupdate [sct]/ctrl/dif [expr log(abs($dif)/$tol + 1e-3)] hupdate [sct]/ctrl/tol [expr log($lim/$tol + 1.0)] hupdate [sct]/ctrl/lim $lim sct lastmode [hvali [sct]] } 0 - 3 - 4 { # fixed, close, open if {[hvali [sct]] == 3 && [sct closetest]} { if {[hgetpropval /nvmot status] ne "run"} { if {[hvali /nvmot] < [hvali /nvmot/posopen] + [hvali /nvmot/precision]} { hupdate [sct]/status "needle valve not fully closed" } sct closetest 0 } } switch -- [hvali /cc/fm] { 2 - 4 { # closing or closed sct update 3 } 1 - 3 { # opening or opened sct update 4 } default { # sct update 0 } } logsetup [sct]/set clear logsetup [sct]/autoflow/flowtarget clear return idle } } if {[hvali [sct]/status] eq $umsg && \ ([sctval [sct]] != 2 || [hgetpropval [sct]/autoflow/getTset t_set_undefined] == 0)} { hsetprop [sct]/autoflow/getTset t_set_undefined 0 hupdate [sct]/status "" } return idle } proc nvstep::read {} { hsetprop /cc/fa nvpath [sct] _cc updatescript /cc/fa nvstep::updatemode hsetprop /cc/f nvpath [sct] hsetprop /cc/f nvctrl [sct controller] _cc updatescript /cc/f nvstep::updateflow return unpoll } proc nvstep::updateflow {value} { set filter [lrange "[silent $value sct filter] $value" end-9 10] sct filter $filter # filter out values which are within the 3 highest or 3 lowest values # out of 10 last values (i.e. within 5 seconds) set m 3 set filter [lsort -real $filter] if {[llength $filter] < 10} { set flow $value } else { set min [lindex $filter $m] set max [lindex $filter end-$m] set flow [silent 0 hvali [sct nvpath]/flow] if {$max < $flow} { set flow $max } elseif {$min > $flow} { set flow $min } } if {$flow < -50} { set flow -62.5 } # clientput "flow $value $flow" updateval_e [sct nvpath]/flow $flow -62.5 no_sensor [sct nvctrl] queue [sct nvpath] read nvstep::poll }