@@ -293,6 +293,10 @@ def createPidLayout(self):
293293 self .pid_no_zero_box .setChecked (False )
294294 self .pid_no_zero_box .stateChanged .connect (self .updateClosedLoop )
295295 layout_structure .addWidget (self .pid_no_zero_box )
296+ self .negate_control_box = QCheckBox ("Negate control output" , self )
297+ self .negate_control_box .setChecked (False )
298+ self .negate_control_box .stateChanged .connect (self .updateClosedLoop )
299+ layout_structure .addWidget (self .negate_control_box )
296300 layout_pid .addRow (layout_structure )
297301
298302 layout_k = QHBoxLayout ()
@@ -566,7 +570,7 @@ def computeController(self):
566570 #TODO:find a better solution
567571 self .ki /= 5.0
568572 static_gain = sum (self .num ) / sum (self .den )
569- self .kff = 1 / static_gain
573+ self .kff = max ( 1 / static_gain , 0.0 )
570574
571575 self .updateKIDSliders ()
572576 self .updateClosedLoop ()
@@ -607,7 +611,14 @@ def updateClosedLoop(self):
607611
608612 id_control = ctrl .summing_junction (inputs = ['e' , 'i_out' , 'd_out' ], output = 'id_out' )
609613 p_control = ctrl .TransferFunction ([kc ], [1 ], dt , inputs = 'id_out' , outputs = 'pid_out' )
610- sum_control = ctrl .summing_junction (inputs = ['pid_out' , 'ff_out' ], output = 'u' )
614+ sum_control = ctrl .summing_junction (inputs = ['pid_out' , 'ff_out' ], output = 'control_out' )
615+
616+ if self .negate_control_box .isChecked ():
617+ output_sign = - 1.0
618+ else :
619+ output_sign = 1.0
620+
621+ out_sign = ctrl .TransferFunction (output_sign , 1.0 , dt , inputs = 'control_out' , outputs = 'u' )
611622
612623 remove_zero = self .pid_no_zero_box .isChecked ()
613624 no_derivative_kick = True
@@ -620,14 +631,14 @@ def updateClosedLoop(self):
620631 # Derivative on feedback only to remove the "derivative kick"
621632 d_control = ctrl .TransferFunction (- derivative_num , derivative_den , dt , inputs = 'y' , outputs = 'd_out' )
622633
623- closed_loop = ctrl .interconnect ([delays , sampler , sum_feedback , feedforward , sum_control , p_control , i_control , d_control , id_control , plant ], inputs = 'r' , outputs = 'y' )
634+ closed_loop = ctrl .interconnect ([delays , sampler , sum_feedback , feedforward , sum_control , p_control , i_control , d_control , id_control , out_sign , plant ], inputs = 'r' , outputs = 'y' )
624635
625636 t_out ,y_out = ctrl .step_response (closed_loop , T = np .arange (0 ,2 ,dt ))
626637
627638 # Add disturbance
628639 sum_feedback_no_ref = ctrl .summing_junction (inputs = ['-y' ], output = 'e' )
629- sum_control_with_disturbance = ctrl .summing_junction (inputs = ['pid_out' , 'disturbance' ], output = 'u ' )
630- disturbance_loop = ctrl .interconnect ([sampler , sum_feedback_no_ref , sum_control_with_disturbance , p_control , i_control , d_control , id_control , plant ], inputs = 'disturbance' , outputs = 'y' )
640+ sum_control_with_disturbance = ctrl .summing_junction (inputs = ['pid_out' , 'disturbance' ], output = 'control_out ' )
641+ disturbance_loop = ctrl .interconnect ([sampler , sum_feedback_no_ref , sum_control_with_disturbance , p_control , i_control , d_control , id_control , out_sign , plant ], inputs = 'disturbance' , outputs = 'y' )
631642 d = np .zeros_like (t_out )
632643 d [t_out >= 1.0 ] = - 0.05 #TODO: parameterize
633644 _ , y_d = ctrl .forced_response (disturbance_loop , t_out , d )
0 commit comments