@@ -16,7 +16,8 @@ class WheelsAxel:
1616
1717 def __init__ (self , pi , enable_pin ,
1818 left_forward_pin , left_backward_pin , left_encoder_feedback_pin_A , left_encoder_feedback_pin_B ,
19- right_forward_pin , right_backward_pin , right_encoder_feedback_pin_A , right_encoder_feedback_pin_B ):
19+ right_forward_pin , right_backward_pin , right_encoder_feedback_pin_A , right_encoder_feedback_pin_B ,
20+ pid_params ):
2021
2122 # state variables
2223 self ._is_moving = False
@@ -36,6 +37,12 @@ def __init__(self, pi, enable_pin,
3637 right_encoder_feedback_pin_A ,
3738 right_encoder_feedback_pin_B )
3839
40+ self .pid_kp = pid_params [0 ]
41+ self .pid_kd = pid_params [1 ]
42+ self .pid_ki = pid_params [2 ]
43+ self .pid_max_speed = pid_params [3 ]
44+ self .pid_sample_time = pid_params [4 ]
45+
3946 # other
4047 #self._wheelsAxle_lock = threading.RLock() # race condition lock
4148
@@ -118,70 +125,75 @@ def control_distance(self, power_left=100, power_right=100, target_distance=0):
118125 #PID parameters
119126 # assuming that power_right is equal to power_left and that coderbot
120127 # moves at 11.5mm/s at full PWM duty cycle
121- MAX_SPEED = 180
122- target_speed_left = (MAX_SPEED / 100 ) * power_left #velocity [mm/s]
123- target_speed_right = (MAX_SPEED / 100 ) * power_right # velocity [mm/s]
128+
129+ target_speed_left = (self . pid_max_speed / 100 ) * power_left #velocity [mm/s]
130+ target_speed_right = (self . pid_max_speed / 100 ) * power_right # velocity [mm/s]
124131
125132 # SOFT RESPONSE
126- #KP = 0.04 #proportional coefficient
127- #KD = 0.02 # derivative coefficient
128- #KI = 0.005 # integral coefficient
133+ # KP = 0.04 #proportional coefficient
134+ # KD = 0.02 # derivative coefficient
135+ # KI = 0.005 # integral coefficient
129136
130137 # MEDIUM RESPONSE
131- KP = 0.4 #proportional coefficient
132- KD = 0.1 # derivative coefficient
133- KI = 0.02 # integral coefficient
138+ # KP = 0.9 # proportional coefficient
139+ # KD = 0.1 # derivative coefficient
140+ # KI = 0.05 # integral coefficient
134141
135142 # STRONG RESPONSE
136- #KP = 0.9 # proportional coefficient
137- #KD = 0.05 # derivative coefficient
138- #KI = 0.03 # integral coefficient
139-
140- SAMPLETIME = 0.01
143+ # KP = 0.9 # proportional coefficient
144+ # KD = 0.05 # derivative coefficient
145+ # KI = 0.03 # integral coefficient
141146
142147 left_derivative_error = 0
143148 right_derivative_error = 0
144149 left_integral_error = 0
145150 right_integral_error = 0
151+ left_prev_error = 0
152+ right_prev_error = 0
146153 # moving for certaing amount of distance
147154 logging .info ("moving? " + str (self ._is_moving ) + " distance: " + str (self .distance ()) + " target: " + str (target_distance ))
148155 while (abs (self .distance ()) < abs (target_distance ) and self ._is_moving == True ):
149156 # PI controller
150157 logging .debug ("speed.left: " + str (self ._left_motor .speed ()) + " speed.right: " + str (self ._right_motor .speed ()))
151158 if (abs (self ._left_motor .speed ()) > 10 and abs (self ._right_motor .speed ()) > 10 ):
152159 # relative error
153- left_error = (target_speed_left - self ._left_motor .speed ()) / target_speed_left * 100.0
154- right_error = (target_speed_right - self ._right_motor .speed ()) / target_speed_right * 100.0
160+ left_error = float (target_speed_left - self ._left_motor .speed ()) / target_speed_left
161+ right_error = float (target_speed_right - self ._right_motor .speed ()) / target_speed_right
155162
156- left_correction = (left_error * KP ) + (left_derivative_error * KD ) + (left_integral_error * KI )
157- right_correction = (right_error * KP ) + (right_derivative_error * KD ) + (right_integral_error * KI )
163+ left_correction = (left_error * self . pid_kp ) + (left_derivative_error * self . pid_kd ) + (left_integral_error * self . pid_ki )
164+ right_correction = (right_error * self . pid_kp ) + (right_derivative_error * self . pid_kd ) + (right_integral_error * self . pid_ki )
158165
159- corrected_power_left = power_left + left_correction - right_correction
160- corrected_power_right = power_right + right_correction - left_correction
166+ corrected_power_left = power_left + ( left_correction * power_left )
167+ corrected_power_right = power_right + ( right_correction * power_right )
161168
162169 #print("LEFT correction: %f" % (left_error * KP + left_derivative_error * KD + left_integral_error * KI))
163170 #print("RIGHT correction: %f" % (right_error * KP + right_derivative_error * KD + right_integral_error * KI))
164171
165172 # conrispondent new power
166- power_left_norm = max (min (corrected_power_left , 100 ), 0 )
167- power_right_norm = max (min (corrected_power_right , 100 ), 0 )
173+ power_left_norm = max (min (corrected_power_left , power_left ), 0 )
174+ power_right_norm = max (min (corrected_power_right , power_right ), 0 )
168175
169- logging .info ("ls:" + str (int (self ._left_motor .speed ())) + " rs: " + str (int (self ._right_motor .speed ())) +
170- " le:" + str (int (left_error )) + " re: " + str (int (right_error )) +
176+ logging .debug ("ls:" + str (int (self ._left_motor .speed ())) + " rs: " + str (int (self ._right_motor .speed ())) +
177+ " le:" + str (left_error ) + " re: " + str (right_error ) +
178+ " ld:" + str (left_derivative_error ) + " rd: " + str (right_derivative_error ) +
179+ " li:" + str (left_integral_error ) + " ri: " + str (right_integral_error ) +
171180 " lc: " + str (int (left_correction )) + " rc: " + str (int (right_correction )) +
172181 " lp: " + str (int (power_left_norm )) + " rp: " + str (int (power_right_norm )))
173182
174183 # adjusting power on each motors
175184 self ._left_motor .adjust_power (power_left_norm * left_direction )
176185 self ._right_motor .adjust_power (power_right_norm * right_direction )
177186
178- left_derivative_error = left_error
179- right_derivative_error = right_error
180- left_integral_error += left_error
181- right_integral_error += right_error
187+ left_derivative_error = (left_error - left_prev_error ) / self .pid_sample_time
188+ right_derivative_error = (right_error - right_prev_error ) / self .pid_sample_time
189+ left_integral_error += (left_error * self .pid_sample_time )
190+ right_integral_error += (right_error * self .pid_sample_time )
191+
192+ left_prev_error = left_error
193+ right_prev_error = right_error
182194
183195 # checking each SAMPLETIME seconds
184- sleep (SAMPLETIME )
196+ sleep (self . pid_sample_time )
185197
186198 logging .info ("control_distance.stop, target dist: " + str (target_distance ) +
187199 " actual distance: " + str (self .distance ()) +
0 commit comments