Slight change to the way we do PID in SCT files

This commit is contained in:
Douglas Clowes
2014-09-30 17:24:58 +10:00
parent 5bedffc9c3
commit c6abb1fabd
3 changed files with 103 additions and 19 deletions

View File

@ -20,6 +20,11 @@ driver hiden_xcs = {
group_property 'nxsave' = 'true' group_property 'nxsave' = 'true'
property 'klass' = 'environment' property 'klass' = 'environment'
property 'sdsinfo' = '::nexus::scobj::sdsinfo' property 'sdsinfo' = '::nexus::scobj::sdsinfo'
var auto = {
type = int;
allowed = '0,1';
value = 0;
}
var enabled = { var enabled = {
permlink = 'G.X02' permlink = 'G.X02'
type = int; type = int;
@ -64,12 +69,15 @@ driver hiden_xcs = {
property pid_error = 0 property pid_error = 0
property pid_deriv = 0 property pid_deriv = 0
property pid_integ = 0 property pid_integ = 0
property pid_pvalue = 0.2 property pid_pvalue = 0.1
property pid_ivalue = 0.1 property pid_ivalue = 0.1
property pid_dvalue = 0.0 property pid_dvalue = 0.0
property pid_imax = 30 property pid_imax = 50
} }
var setpoint = { var setpoint = {
readable = 1;
read_command = '@'
fetch_function = getTarget
permlink = 'G.SP01' permlink = 'G.SP01'
driveable = flow/sensor driveable = flow/sensor
write_function = write_flow write_function = write_flow
@ -96,19 +104,22 @@ driver hiden_xcs = {
property pid_error = 0 property pid_error = 0
property pid_deriv = 0 property pid_deriv = 0
property pid_integ = 0 property pid_integ = 0
property pid_pvalue = 0.2 property pid_pvalue = 1.0
property pid_ivalue = 0.1 property pid_ivalue = 0.10
property pid_dvalue = 0.0 property pid_dvalue = 0.0
property pid_imax = 30 property pid_imax = 20
} }
var setpoint = { var setpoint = {
readable = 1;
read_command = '@'
fetch_function = getTarget
permlink = 'G.SP02' permlink = 'G.SP02'
driveable = humidity/sensor driveable = humidity/sensor
write_function = write_humidity write_function = write_humidity
checkrange_function = chkrange_function checkrange_function = chkrange_function
value = 50 value = 50
lowerlimit = 10 lowerlimit = 0
upperlimit = 90 upperlimit = 100
tolerance = 1 tolerance = 1
} }
} }
@ -140,6 +151,14 @@ driver hiden_xcs = {
# Code lines start with '@' which is stripped before being emitted into generated driver # Code lines start with '@' which is stripped before being emitted into generated driver
# The code is emitted at the appropriate place in the given function # The code is emitted at the appropriate place in the given function
# #
code getTarget = {
@ if { [hpropexists [sct] target] } {
@ sct result [sct target]
@ } else {
@ sct result [hval [sct]]
@ }
@ set cmd "@@NOSEND@@"
}
code read_function read_digital = { code read_function read_digital = {
@ if { [string equal -nocase -length 5 "${data}" "DOUT ="] } { @ if { [string equal -nocase -length 5 "${data}" "DOUT ="] } {
@ set result [scan "${data}" "DOUT = %d OK" val] @ set result [scan "${data}" "DOUT = %d OK" val]
@ -222,6 +241,10 @@ driver hiden_xcs = {
} }
code pid_function pid_humidity = { code pid_function pid_humidity = {
@ if { ![hval ${tc_root}/auto] } {
@ set pid 0.0
@ sct pid_integ 0.0
@ }
@ set sign 1 @ set sign 1
@ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { @ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
@ set sign [expr -${sign}] @ set sign [expr -${sign}]
@ -252,6 +275,10 @@ driver hiden_xcs = {
} }
code pid_function pid_flow = { code pid_function pid_flow = {
@ if { ![hval ${tc_root}/auto] } {
@ set pid 0.0
@ sct pid_integ 0.0
@ }
@ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { @ foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
@ if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } { @ if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } {
@ hsetprop ${node} bias_flow ${pid} @ hsetprop ${node} bias_flow ${pid}
@ -266,6 +293,7 @@ driver hiden_xcs = {
code write_function write_digital = { code write_function write_digital = {
} }
code write_function write_twelve = { code write_function write_twelve = {
@ if { [hpropexists [sct] base] } { @ if { [hpropexists [sct] base] } {
@ set base [sct base] @ set base [sct base]

View File

@ -176,6 +176,35 @@ proc ::scobj::hiden_xcs::fetch_flow {tc_root nextState cmd_str} {
handle_exception ${catch_status} ${catch_message} handle_exception ${catch_status} ${catch_message}
} }
# function to request the read of a parameter on a device
proc ::scobj::hiden_xcs::getTarget {tc_root nextState cmd_str} {
set catch_status [ catch {
debug_log ${tc_root} 1 "getTarget tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set cmd "${cmd_str}"
# getTarget hook code starts
if { [hpropexists [sct] target] } {
sct result [sct target]
} else {
sct result [hval [sct]]
}
set cmd "@@NOSEND@@"
# getTarget hook code ends
if { [hpropexists [sct] geterror] } {
debug_log ${tc_root} 9 "[sct] error: [sct geterror]"
error "[sct geterror]"
}
debug_log ${tc_root} 1 "getTarget sct send ${cmd}"
if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {
sct send "${cmd}"
}
return ${nextState}
} catch_message ]
handle_exception ${catch_status} ${catch_message}
}
# function to request the read of a parameter on a device # function to request the read of a parameter on a device
proc ::scobj::hiden_xcs::getValue {tc_root nextState cmd_str} { proc ::scobj::hiden_xcs::getValue {tc_root nextState cmd_str} {
set catch_status [ catch { set catch_status [ catch {
@ -254,16 +283,20 @@ proc ::scobj::hiden_xcs::pid_flow {tc_root sp pv} {
set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] set p_value [expr {[sct pid_pvalue] * [sct pid_error]}]
set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}]
sct pid_deriv [sct pid_error] sct pid_deriv [sct pid_error]
sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] sct pid_integ [expr {[sct pid_integ] + [sct pid_error] * [sct pid_ivalue]}]
if { [sct pid_integ] > [sct pid_imax] } { if { [sct pid_integ] > [sct pid_imax] } {
sct pid_integ [sct pid_imax] sct pid_integ [sct pid_imax]
} }
if { [sct pid_integ] < -[sct pid_imax] } { if { [sct pid_integ] < -[sct pid_imax] } {
sct pid_integ -[sct pid_imax] sct pid_integ -[sct pid_imax]
} }
set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] set i_value [sct pid_integ]
set pid [expr {${p_value} + ${i_value} + ${d_value}}] set pid [expr {${p_value} + ${i_value} + ${d_value}}]
# pid_flow hook code starts # pid_flow hook code starts
if { ![hval ${tc_root}/auto] } {
set pid 0.0
sct pid_integ 0.0
}
foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } { if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } {
hsetprop ${node} bias_flow ${pid} hsetprop ${node} bias_flow ${pid}
@ -289,16 +322,20 @@ proc ::scobj::hiden_xcs::pid_humidity {tc_root sp pv} {
set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] set p_value [expr {[sct pid_pvalue] * [sct pid_error]}]
set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}]
sct pid_deriv [sct pid_error] sct pid_deriv [sct pid_error]
sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] sct pid_integ [expr {[sct pid_integ] + [sct pid_error] * [sct pid_ivalue]}]
if { [sct pid_integ] > [sct pid_imax] } { if { [sct pid_integ] > [sct pid_imax] } {
sct pid_integ [sct pid_imax] sct pid_integ [sct pid_imax]
} }
if { [sct pid_integ] < -[sct pid_imax] } { if { [sct pid_integ] < -[sct pid_imax] } {
sct pid_integ -[sct pid_imax] sct pid_integ -[sct pid_imax]
} }
set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] set i_value [sct pid_integ]
set pid [expr {${p_value} + ${i_value} + ${d_value}}] set pid [expr {${p_value} + ${i_value} + ${d_value}}]
# pid_humidity hook code starts # pid_humidity hook code starts
if { ![hval ${tc_root}/auto] } {
set pid 0.0
sct pid_integ 0.0
}
set sign 1 set sign 1
foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] {
set sign [expr -${sign}] set sign [expr -${sign}]
@ -757,6 +794,19 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
set scobj_hpath /sics/${name} set scobj_hpath /sics/${name}
hfactory ${scobj_hpath}/auto plain user int
hsetprop ${scobj_hpath}/auto control true
hsetprop ${scobj_hpath}/auto data true
hsetprop ${scobj_hpath}/auto mutable true
hsetprop ${scobj_hpath}/auto nxsave true
hsetprop ${scobj_hpath}/auto values 0,1
hsetprop ${scobj_hpath}/auto oldval 0
hset ${scobj_hpath}/auto 0
hsetprop ${scobj_hpath}/auto klass "environment"
hsetprop ${scobj_hpath}/auto sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/auto type "part"
hsetprop ${scobj_hpath}/auto nxalias "${name}_auto"
hfactory ${scobj_hpath}/enabled plain user int hfactory ${scobj_hpath}/enabled plain user int
hsetprop ${scobj_hpath}/enabled read ${ns}::getValue ${scobj_hpath} read_digital {?DOUT,2} hsetprop ${scobj_hpath}/enabled read ${ns}::getValue ${scobj_hpath} read_digital {?DOUT,2}
hsetprop ${scobj_hpath}/enabled read_digital ${ns}::read_digital ${scobj_hpath} hsetprop ${scobj_hpath}/enabled read_digital ${ns}::read_digital ${scobj_hpath}
@ -1021,15 +1071,17 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/flow/sensor pid_deriv "0" hsetprop ${scobj_hpath}/flow/sensor pid_deriv "0"
hsetprop ${scobj_hpath}/flow/sensor pid_dvalue "0.0" hsetprop ${scobj_hpath}/flow/sensor pid_dvalue "0.0"
hsetprop ${scobj_hpath}/flow/sensor pid_error "0" hsetprop ${scobj_hpath}/flow/sensor pid_error "0"
hsetprop ${scobj_hpath}/flow/sensor pid_imax "30" hsetprop ${scobj_hpath}/flow/sensor pid_imax "50"
hsetprop ${scobj_hpath}/flow/sensor pid_integ "0" hsetprop ${scobj_hpath}/flow/sensor pid_integ "0"
hsetprop ${scobj_hpath}/flow/sensor pid_ivalue "0.1" hsetprop ${scobj_hpath}/flow/sensor pid_ivalue "0.1"
hsetprop ${scobj_hpath}/flow/sensor pid_pvalue "0.2" hsetprop ${scobj_hpath}/flow/sensor pid_pvalue "0.1"
hsetprop ${scobj_hpath}/flow/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/flow/sensor sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/flow/sensor type "part" hsetprop ${scobj_hpath}/flow/sensor type "part"
hsetprop ${scobj_hpath}/flow/sensor nxalias "${name}_flow_sensor" hsetprop ${scobj_hpath}/flow/sensor nxalias "${name}_flow_sensor"
hfactory ${scobj_hpath}/flow/setpoint plain user float hfactory ${scobj_hpath}/flow/setpoint plain user float
hsetprop ${scobj_hpath}/flow/setpoint read ${ns}::getTarget ${scobj_hpath} rdValue {@}
hsetprop ${scobj_hpath}/flow/setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/flow/setpoint write ${ns}::write_flow ${scobj_hpath} noResponse {} hsetprop ${scobj_hpath}/flow/setpoint write ${ns}::write_flow ${scobj_hpath} noResponse {}
hsetprop ${scobj_hpath}/flow/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/flow/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/flow/setpoint check ${ns}::checkrange ${scobj_hpath} hsetprop ${scobj_hpath}/flow/setpoint check ${ns}::checkrange ${scobj_hpath}
@ -1056,6 +1108,7 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/flow/sensor 1 ${sct_controller} poll ${scobj_hpath}/flow/sensor 1
${sct_controller} poll ${scobj_hpath}/flow/setpoint 1
${sct_controller} write ${scobj_hpath}/flow/setpoint ${sct_controller} write ${scobj_hpath}/flow/setpoint
} else { } else {
::scobj::hiden_xcs::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for hiden_xcs" ::scobj::hiden_xcs::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for hiden_xcs"
@ -1081,15 +1134,17 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/humidity/sensor pid_deriv "0" hsetprop ${scobj_hpath}/humidity/sensor pid_deriv "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_dvalue "0.0" hsetprop ${scobj_hpath}/humidity/sensor pid_dvalue "0.0"
hsetprop ${scobj_hpath}/humidity/sensor pid_error "0" hsetprop ${scobj_hpath}/humidity/sensor pid_error "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_imax "30" hsetprop ${scobj_hpath}/humidity/sensor pid_imax "20"
hsetprop ${scobj_hpath}/humidity/sensor pid_integ "0" hsetprop ${scobj_hpath}/humidity/sensor pid_integ "0"
hsetprop ${scobj_hpath}/humidity/sensor pid_ivalue "0.1" hsetprop ${scobj_hpath}/humidity/sensor pid_ivalue "0.1"
hsetprop ${scobj_hpath}/humidity/sensor pid_pvalue "0.2" hsetprop ${scobj_hpath}/humidity/sensor pid_pvalue "1.0"
hsetprop ${scobj_hpath}/humidity/sensor sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/humidity/sensor sdsinfo "::nexus::scobj::sdsinfo"
hsetprop ${scobj_hpath}/humidity/sensor type "part" hsetprop ${scobj_hpath}/humidity/sensor type "part"
hsetprop ${scobj_hpath}/humidity/sensor nxalias "${name}_humidity_sensor" hsetprop ${scobj_hpath}/humidity/sensor nxalias "${name}_humidity_sensor"
hfactory ${scobj_hpath}/humidity/setpoint plain user float hfactory ${scobj_hpath}/humidity/setpoint plain user float
hsetprop ${scobj_hpath}/humidity/setpoint read ${ns}::getTarget ${scobj_hpath} rdValue {@}
hsetprop ${scobj_hpath}/humidity/setpoint rdValue ${ns}::rdValue ${scobj_hpath}
hsetprop ${scobj_hpath}/humidity/setpoint write ${ns}::write_humidity ${scobj_hpath} noResponse {} hsetprop ${scobj_hpath}/humidity/setpoint write ${ns}::write_humidity ${scobj_hpath} noResponse {}
hsetprop ${scobj_hpath}/humidity/setpoint noResponse ${ns}::noResponse ${scobj_hpath} hsetprop ${scobj_hpath}/humidity/setpoint noResponse ${ns}::noResponse ${scobj_hpath}
hsetprop ${scobj_hpath}/humidity/setpoint check ${ns}::chkrange_function ${scobj_hpath} hsetprop ${scobj_hpath}/humidity/setpoint check ${ns}::chkrange_function ${scobj_hpath}
@ -1102,8 +1157,8 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
hsetprop ${scobj_hpath}/humidity/setpoint data true hsetprop ${scobj_hpath}/humidity/setpoint data true
hsetprop ${scobj_hpath}/humidity/setpoint mutable true hsetprop ${scobj_hpath}/humidity/setpoint mutable true
hsetprop ${scobj_hpath}/humidity/setpoint nxsave true hsetprop ${scobj_hpath}/humidity/setpoint nxsave true
hsetprop ${scobj_hpath}/humidity/setpoint lowerlimit 10 hsetprop ${scobj_hpath}/humidity/setpoint lowerlimit 0
hsetprop ${scobj_hpath}/humidity/setpoint upperlimit 90 hsetprop ${scobj_hpath}/humidity/setpoint upperlimit 100
hsetprop ${scobj_hpath}/humidity/setpoint tolerance 1 hsetprop ${scobj_hpath}/humidity/setpoint tolerance 1
hsetprop ${scobj_hpath}/humidity/setpoint permlink data_set "G[format "%02d" ${id}]SP02" hsetprop ${scobj_hpath}/humidity/setpoint permlink data_set "G[format "%02d" ${id}]SP02"
hsetprop ${scobj_hpath}/humidity/setpoint @description "G[format "%02d" ${id}]SP02" hsetprop ${scobj_hpath}/humidity/setpoint @description "G[format "%02d" ${id}]SP02"
@ -1116,6 +1171,7 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name device_class simulation_
if {[string equal -nocase "${simulation_flag}" "false"]} { if {[string equal -nocase "${simulation_flag}" "false"]} {
${sct_controller} poll ${scobj_hpath}/humidity/sensor 1 ${sct_controller} poll ${scobj_hpath}/humidity/sensor 1
${sct_controller} poll ${scobj_hpath}/humidity/setpoint 1
${sct_controller} write ${scobj_hpath}/humidity/setpoint ${sct_controller} write ${scobj_hpath}/humidity/setpoint
} else { } else {
::scobj::hiden_xcs::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for hiden_xcs" ::scobj::hiden_xcs::sics_log 9 "simulation_flag=${simulation_flag} => No poll/write for hiden_xcs"

View File

@ -1217,14 +1217,14 @@ def put_pid_function(MyDriver, func):
txt += [' set p_value [expr {[sct pid_pvalue] * [sct pid_error]}]'] txt += [' set p_value [expr {[sct pid_pvalue] * [sct pid_error]}]']
txt += [' set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}]'] txt += [' set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}]']
txt += [' sct pid_deriv [sct pid_error]'] txt += [' sct pid_deriv [sct pid_error]']
txt += [' sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}]'] txt += [' sct pid_integ [expr {[sct pid_integ] + [sct pid_error] * [sct pid_ivalue]}]']
txt += [' if { [sct pid_integ] > [sct pid_imax] } {'] txt += [' if { [sct pid_integ] > [sct pid_imax] } {']
txt += [' sct pid_integ [sct pid_imax]'] txt += [' sct pid_integ [sct pid_imax]']
txt += [' }'] txt += [' }']
txt += [' if { [sct pid_integ] < -[sct pid_imax] } {'] txt += [' if { [sct pid_integ] < -[sct pid_imax] } {']
txt += [' sct pid_integ -[sct pid_imax]'] txt += [' sct pid_integ -[sct pid_imax]']
txt += [' }'] txt += [' }']
txt += [' set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}]'] txt += [' set i_value [sct pid_integ]']
txt += [' set pid [expr {${p_value} + ${i_value} + ${d_value}}]'] txt += [' set pid [expr {${p_value} + ${i_value} + ${d_value}}]']
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
txt += ['# %s hook code starts' % func] txt += ['# %s hook code starts' % func]