@@ -293,6 +293,10 @@ def createPidLayout(self):
293
293
self .pid_no_zero_box .setChecked (False )
294
294
self .pid_no_zero_box .stateChanged .connect (self .updateClosedLoop )
295
295
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 )
296
300
layout_pid .addRow (layout_structure )
297
301
298
302
layout_k = QHBoxLayout ()
@@ -566,7 +570,7 @@ def computeController(self):
566
570
#TODO:find a better solution
567
571
self .ki /= 5.0
568
572
static_gain = sum (self .num ) / sum (self .den )
569
- self .kff = 1 / static_gain
573
+ self .kff = max ( 1 / static_gain , 0.0 )
570
574
571
575
self .updateKIDSliders ()
572
576
self .updateClosedLoop ()
@@ -607,7 +611,14 @@ def updateClosedLoop(self):
607
611
608
612
id_control = ctrl .summing_junction (inputs = ['e' , 'i_out' , 'd_out' ], output = 'id_out' )
609
613
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' )
611
622
612
623
remove_zero = self .pid_no_zero_box .isChecked ()
613
624
no_derivative_kick = True
@@ -620,14 +631,14 @@ def updateClosedLoop(self):
620
631
# Derivative on feedback only to remove the "derivative kick"
621
632
d_control = ctrl .TransferFunction (- derivative_num , derivative_den , dt , inputs = 'y' , outputs = 'd_out' )
622
633
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' )
624
635
625
636
t_out ,y_out = ctrl .step_response (closed_loop , T = np .arange (0 ,2 ,dt ))
626
637
627
638
# Add disturbance
628
639
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' )
631
642
d = np .zeros_like (t_out )
632
643
d [t_out >= 1.0 ] = - 0.05 #TODO: parameterize
633
644
_ , y_d = ctrl .forced_response (disturbance_loop , t_out , d )
0 commit comments