Add a PID function for each variable
This commit is contained in:
@ -51,6 +51,7 @@ FunctionTypes = [
|
|||||||
'write_function',
|
'write_function',
|
||||||
'fetch_function',
|
'fetch_function',
|
||||||
'check_function',
|
'check_function',
|
||||||
|
'pid_function',
|
||||||
'checkrange_function',
|
'checkrange_function',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -123,6 +124,7 @@ reserved = {
|
|||||||
'WRITE_COMMAND' : 'WRITE_COMMAND',
|
'WRITE_COMMAND' : 'WRITE_COMMAND',
|
||||||
'WRITE_FUNCTION' : 'WRITE_FUNCTION',
|
'WRITE_FUNCTION' : 'WRITE_FUNCTION',
|
||||||
'CHECK_FUNCTION' : 'CHECK_FUNCTION',
|
'CHECK_FUNCTION' : 'CHECK_FUNCTION',
|
||||||
|
'PID_FUNCTION' : 'PID_FUNCTION',
|
||||||
'CHECKRANGE_FUNCTION' : 'CHECKRANGE_FUNCTION',
|
'CHECKRANGE_FUNCTION' : 'CHECKRANGE_FUNCTION',
|
||||||
'CHECKLIMITS_FUNCTION' : 'CHECKLIMITS_FUNCTION',
|
'CHECKLIMITS_FUNCTION' : 'CHECKLIMITS_FUNCTION',
|
||||||
'CHECKSTATUS_FUNCTION' : 'CHECKSTATUS_FUNCTION',
|
'CHECKSTATUS_FUNCTION' : 'CHECKSTATUS_FUNCTION',
|
||||||
@ -356,6 +358,7 @@ def p_var_typ_ass(p):
|
|||||||
| WRITE_COMMAND EQUALS TEXT_STRING
|
| WRITE_COMMAND EQUALS TEXT_STRING
|
||||||
| WRITE_FUNCTION EQUALS id_or_str
|
| WRITE_FUNCTION EQUALS id_or_str
|
||||||
| CHECK_FUNCTION EQUALS id_or_str
|
| CHECK_FUNCTION EQUALS id_or_str
|
||||||
|
| PID_FUNCTION EQUALS id_or_str
|
||||||
| CHECKRANGE_FUNCTION EQUALS id_or_str
|
| CHECKRANGE_FUNCTION EQUALS id_or_str
|
||||||
| CHECKLIMITS_FUNCTION EQUALS id_or_str
|
| CHECKLIMITS_FUNCTION EQUALS id_or_str
|
||||||
| CHECKSTATUS_FUNCTION EQUALS id_or_str
|
| CHECKSTATUS_FUNCTION EQUALS id_or_str
|
||||||
@ -467,6 +470,7 @@ def p_code_type(p):
|
|||||||
| FETCH_FUNCTION
|
| FETCH_FUNCTION
|
||||||
| WRITE_FUNCTION
|
| WRITE_FUNCTION
|
||||||
| CHECK_FUNCTION
|
| CHECK_FUNCTION
|
||||||
|
| PID_FUNCTION
|
||||||
| CHECKRANGE_FUNCTION
|
| CHECKRANGE_FUNCTION
|
||||||
| CHECKLIMITS_FUNCTION
|
| CHECKLIMITS_FUNCTION
|
||||||
| CHECKSTATUS_FUNCTION
|
| CHECKSTATUS_FUNCTION
|
||||||
@ -948,6 +952,33 @@ def put_halt_function(MyDriver, func):
|
|||||||
txt += ['}']
|
txt += ['}']
|
||||||
emit(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):
|
def put_create_node(MyDriver):
|
||||||
txt = ['']
|
txt = ['']
|
||||||
txt += ['##']
|
txt += ['##']
|
||||||
@ -1126,6 +1157,20 @@ def put_group(MyDriver, MyGroup):
|
|||||||
msg = 'Driveable: %s does not have required attribute: %s' % (nodename, attr)
|
msg = 'Driveable: %s does not have required attribute: %s' % (nodename, attr)
|
||||||
print 'Warning:', msg
|
print 'Warning:', msg
|
||||||
txt += [' # 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'])]
|
txt += [' hfactory ${scobj_hpath}/%s plain %s %s' % (nodename, MyVar['priv'], MyVar['type'])]
|
||||||
if MyVar['readable'] > 0:
|
if MyVar['readable'] > 0:
|
||||||
readable_or_writeable = True
|
readable_or_writeable = True
|
||||||
@ -1364,6 +1409,8 @@ def put_standard_code(MyDriver):
|
|||||||
put_checkstatus_function(MyDriver, func);
|
put_checkstatus_function(MyDriver, func);
|
||||||
elif theFunc['type'] == 'halt_function':
|
elif theFunc['type'] == 'halt_function':
|
||||||
put_halt_function(MyDriver, func);
|
put_halt_function(MyDriver, func);
|
||||||
|
elif theFunc['type'] == 'pid_function':
|
||||||
|
put_pid_function(MyDriver, func);
|
||||||
|
|
||||||
def generate_driver(MyDriver):
|
def generate_driver(MyDriver):
|
||||||
global NumberOfLinesOut
|
global NumberOfLinesOut
|
||||||
|
Reference in New Issue
Block a user