Add a PID function for each variable
This commit is contained in:
@ -51,6 +51,7 @@ FunctionTypes = [
|
||||
'write_function',
|
||||
'fetch_function',
|
||||
'check_function',
|
||||
'pid_function',
|
||||
'checkrange_function',
|
||||
]
|
||||
|
||||
@ -123,6 +124,7 @@ reserved = {
|
||||
'WRITE_COMMAND' : 'WRITE_COMMAND',
|
||||
'WRITE_FUNCTION' : 'WRITE_FUNCTION',
|
||||
'CHECK_FUNCTION' : 'CHECK_FUNCTION',
|
||||
'PID_FUNCTION' : 'PID_FUNCTION',
|
||||
'CHECKRANGE_FUNCTION' : 'CHECKRANGE_FUNCTION',
|
||||
'CHECKLIMITS_FUNCTION' : 'CHECKLIMITS_FUNCTION',
|
||||
'CHECKSTATUS_FUNCTION' : 'CHECKSTATUS_FUNCTION',
|
||||
@ -356,6 +358,7 @@ def p_var_typ_ass(p):
|
||||
| WRITE_COMMAND EQUALS TEXT_STRING
|
||||
| WRITE_FUNCTION EQUALS id_or_str
|
||||
| CHECK_FUNCTION EQUALS id_or_str
|
||||
| PID_FUNCTION EQUALS id_or_str
|
||||
| CHECKRANGE_FUNCTION EQUALS id_or_str
|
||||
| CHECKLIMITS_FUNCTION EQUALS id_or_str
|
||||
| CHECKSTATUS_FUNCTION EQUALS id_or_str
|
||||
@ -467,6 +470,7 @@ def p_code_type(p):
|
||||
| FETCH_FUNCTION
|
||||
| WRITE_FUNCTION
|
||||
| CHECK_FUNCTION
|
||||
| PID_FUNCTION
|
||||
| CHECKRANGE_FUNCTION
|
||||
| CHECKLIMITS_FUNCTION
|
||||
| CHECKSTATUS_FUNCTION
|
||||
@ -948,6 +952,33 @@ def put_halt_function(MyDriver, func):
|
||||
txt += ['}']
|
||||
emit(txt)
|
||||
|
||||
def put_pid_function(MyDriver, func):
|
||||
txt = ['']
|
||||
txt += ['# pid function for PID control']
|
||||
txt += ['proc %s::%s {tc_root sp pv} {' % (MyDriver['namespace'], func)]
|
||||
txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}"' % func]
|
||||
txt += [' sct pid_error [expr ${sp} - ${pv}]']
|
||||
txt += [' set p_value [expr [sct pid_pvalue] * [sct pid_error]]']
|
||||
txt += [' set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])]']
|
||||
txt += [' sct pid_deriv [sct pid_error]']
|
||||
txt += [' sct pid_integ [expr [sct pid_integ] + [sct pid_error]]']
|
||||
txt += [' if { [sct pid_integ] > [sct pid_imax] } {']
|
||||
txt += [' sct pid_integ [sct pid_imax]']
|
||||
txt += [' }']
|
||||
txt += [' if { [sct pid_integ] < -[sct pid_imax] } {']
|
||||
txt += [' sct pid_integ -[sct pid_imax]']
|
||||
txt += [' }']
|
||||
txt += [' set i_value [expr [sct pid_ivalue] * [sct pid_integ]]']
|
||||
txt += [' set pid [expr ${p_value} + ${i_value} + ${d_value}]']
|
||||
if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0:
|
||||
txt += ['# hook code starts']
|
||||
txt += MyDriver['Funcs'][func]['text']
|
||||
txt += ['# hook code ends']
|
||||
txt += [' sct pid_output ${pid}']
|
||||
txt += [' return ${pid}']
|
||||
txt += ['}']
|
||||
emit(txt)
|
||||
|
||||
def put_create_node(MyDriver):
|
||||
txt = ['']
|
||||
txt += ['##']
|
||||
@ -1126,6 +1157,20 @@ def put_group(MyDriver, MyGroup):
|
||||
msg = 'Driveable: %s does not have required attribute: %s' % (nodename, attr)
|
||||
print 'Warning:', msg
|
||||
txt += [' # Warning: ' + msg]
|
||||
# Check PID attributes are present if required
|
||||
if 'pid_function' in MyVar:
|
||||
for attr in ('pid_pvalue',
|
||||
'pid_ivalue',
|
||||
'pid_dvalue',
|
||||
'pid_imax',
|
||||
'pid_error',
|
||||
'pid_deriv',
|
||||
'pid_integ',
|
||||
):
|
||||
if attr not in MyVar['Property']:
|
||||
msg = 'PID: %s does not have required attribute: %s' % (nodename, attr)
|
||||
print 'Warning:', msg
|
||||
txt += [' # Warning: ' + msg]
|
||||
txt += [' hfactory ${scobj_hpath}/%s plain %s %s' % (nodename, MyVar['priv'], MyVar['type'])]
|
||||
if MyVar['readable'] > 0:
|
||||
readable_or_writeable = True
|
||||
@ -1364,6 +1409,8 @@ def put_standard_code(MyDriver):
|
||||
put_checkstatus_function(MyDriver, func);
|
||||
elif theFunc['type'] == 'halt_function':
|
||||
put_halt_function(MyDriver, func);
|
||||
elif theFunc['type'] == 'pid_function':
|
||||
put_pid_function(MyDriver, func);
|
||||
|
||||
def generate_driver(MyDriver):
|
||||
global NumberOfLinesOut
|
||||
|
Reference in New Issue
Block a user