Skip to content

Commit 272bb7c

Browse files
committed
Actually applying PID changes. Renamed symbols
1 parent 926360d commit 272bb7c

File tree

2 files changed

+73
-68
lines changed

2 files changed

+73
-68
lines changed

XRPLib/differential_drive.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,20 @@ def straight(self, distance: float, max_effort: float = 0.5, timeout: float = No
145145
distance *= -1
146146

147147
time_out = Timeout(timeout)
148-
startingLeft = self.get_left_encoder_position()
149-
startingRight = self.get_right_encoder_position()
148+
starting_left = self.get_left_encoder_position()
149+
starting_right = self.get_right_encoder_position()
150150

151151

152152
if main_controller is None:
153153
main_controller = PID(
154154
kp = 0.04,
155155
ki = 0.0125,
156156
kd = 0.025,
157-
minOutput = 0.225,
158-
maxOutput = 0.5,
159-
maxIntegral = 35,
157+
min_output = 0.225,
158+
max_output = 0.5,
159+
max_integral = 35,
160160
tolerance = 0.1,
161-
toleranceCount = 3,
161+
tolerance_count = 3,
162162
)
163163

164164
# Secondary controller to keep encoder values in sync
@@ -176,13 +176,13 @@ def straight(self, distance: float, max_effort: float = 0.5, timeout: float = No
176176
while True:
177177

178178
# calculate the distance traveled
179-
leftDelta = self.get_left_encoder_position() - startingLeft
180-
rightDelta = self.get_right_encoder_position() - startingRight
181-
distTraveled = (leftDelta + rightDelta) / 2
179+
left_delta = self.get_left_encoder_position() - starting_left
180+
right_delta = self.get_right_encoder_position() - starting_right
181+
dist_traveled = (left_delta + right_delta) / 2
182182

183183
# PID for distance
184-
distanceError = distance - distTraveled
185-
effort = main_controller.update(distanceError)
184+
distance_error = distance - dist_traveled
185+
effort = main_controller.update(distance_error)
186186

187187
if main_controller.is_done() or time_out.is_done():
188188
break
@@ -192,7 +192,7 @@ def straight(self, distance: float, max_effort: float = 0.5, timeout: float = No
192192
# record current heading to maintain it
193193
current_heading = self.imu.get_yaw()
194194
else:
195-
current_heading = ((rightDelta-leftDelta)/2)*360/(self.track_width*math.pi)
195+
current_heading = ((right_delta-left_delta)/2)*360/(self.track_width*math.pi)
196196

197197
headingCorrection = secondary_controller.update(initial_heading - current_heading)
198198

@@ -232,20 +232,20 @@ def turn(self, turn_degrees: float, max_effort: float = 40, timeout: float = Non
232232
turn_degrees *= -1
233233

234234
time_out = Timeout(timeout)
235-
startingLeft = self.get_left_encoder_position()
236-
startingRight = self.get_right_encoder_position()
235+
starting_left = self.get_left_encoder_position()
236+
starting_right = self.get_right_encoder_position()
237237

238238
if main_controller is None:
239239
main_controller = PID(
240240
kp = 0.02,
241241
ki = 0.005,
242242
kd = 0.012,
243-
minOutput = 0.35,
244-
maxOutput = max_effort,
245-
maxDerivative = 0.5,
246-
maxIntegral = 50,
243+
min_output = 0.35,
244+
max_output = max_effort,
245+
max_derivative = 0.5,
246+
max_integral = 50,
247247
tolerance = 0.5,
248-
toleranceCount = 2
248+
tolerance_count = 2
249249
)
250250

251251
# Secondary controller to keep encoder values in sync
@@ -260,25 +260,25 @@ def turn(self, turn_degrees: float, max_effort: float = 40, timeout: float = Non
260260
while True:
261261

262262
# calculate encoder correction to minimize drift
263-
leftDelta = self.get_left_encoder_position() - startingLeft
264-
rightDelta = self.get_right_encoder_position() - startingRight
265-
encoderCorrection = secondary_controller.update(leftDelta + rightDelta)
263+
left_delta = self.get_left_encoder_position() - starting_left
264+
right_delta = self.get_right_encoder_position() - starting_right
265+
encoder_correction = secondary_controller.update(left_delta + right_delta)
266266

267267
if use_imu and (self.imu is not None):
268268
# calculate turn error (in degrees) from the imu
269-
turnError = turn_degrees - self.imu.get_yaw()
269+
turn_error = turn_degrees - self.imu.get_yaw()
270270
else:
271271
# calculate turn error (in degrees) from the encoder counts
272-
turnError = turn_degrees - ((rightDelta-leftDelta)/2)*360/(self.track_width*math.pi)
272+
turn_error = turn_degrees - ((right_delta-left_delta)/2)*360/(self.track_width*math.pi)
273273

274274
# Pass the turn error to the main controller to get a turn speed
275-
turnSpeed = main_controller.update(turnError)
275+
turn_speed = main_controller.update(turn_error)
276276

277277
# exit if timeout or tolerance reached
278278
if main_controller.is_done() or time_out.is_done():
279279
break
280280

281-
self.set_speed(-turnSpeed - encoderCorrection, turnSpeed - encoderCorrection)
281+
self.set_speed(-turn_speed - encoder_correction, turn_speed - encoder_correction)
282282

283283
time.sleep(0.01)
284284

XRPLib/pid.py

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,45 @@ def __init__(self,
1111
kp = 1.0,
1212
ki = 0.0,
1313
kd = 0.0,
14-
minOutput = 0.0,
15-
maxOutput = 1.0,
16-
maxDerivative = None,
14+
min_output = 0.0,
15+
max_output = 1.0,
16+
max_derivative = None,
17+
max_integral = None,
1718
tolerance = 0.1,
18-
toleranceCount = 1
19+
tolerance_count = 1
1920
):
2021
"""
2122
:param kp: proportional gain
2223
:param ki: integral gain
2324
:param kd: derivative gain
24-
:param minOutput: minimum output
25-
:param maxOutput: maximum output
26-
:param maxDerivative: maximum derivative (change per second)
25+
:param min_output: minimum output
26+
:param max_output: maximum output
27+
:param max_derivative: maximum derivative (change per second)
28+
:param max_integral: maximum integral windup allowed (will cap integral at this value)
2729
:param tolerance: tolerance for exit condition
28-
:param numTimesInTolerance: number of times in tolerance for exit condition
30+
:param tolerance_count: number of times the error needs to be within tolerance for is_done to return True
2931
"""
3032
self.kp = kp
3133
self.ki = ki
3234
self.kd = kd
33-
self.minOutput = minOutput
34-
self.maxOutput = maxOutput
35-
self.maxDerivative = maxDerivative
35+
self.min_output = min_output
36+
self.max_output = max_output
37+
self.max_derivative = max_derivative
38+
self.max_integral = max_integral
3639
self.tolerance = tolerance
37-
self.toleranceCount = toleranceCount
40+
self.tolerance_count = tolerance_count
3841

39-
self.prevError = 0
40-
self.prevIntegral = 0
41-
self.prevOutput = 0
42+
self.prev_error = 0
43+
self.prev_integral = 0
44+
self.prev_output = 0
4245

43-
self.startTime = None
44-
self.prevTime = None
46+
self.start_time = None
47+
self.prev_time = None
4548

4649
# number of actual times in tolerance
4750
self.times = 0
4851

4952
def _handle_exit_condition(self, error: float):
50-
5153
if abs(error) < self.tolerance:
5254
# if error is within tolerance, increment times in tolerance
5355
self.times += 1
@@ -65,43 +67,47 @@ def update(self, error: float) -> float:
6567
:return: The system output from the controller, to be used as an effort value or for any other purpose
6668
:rtype: float
6769
"""
68-
currentTime = time.ticks_ms()
69-
if self.prevTime is None:
70+
current_time = time.ticks_ms()
71+
if self.prev_time is None:
7072
# First update after instantiation
71-
self.startTime = currentTime
73+
self.start_time = current_time
7274
timestep = 0.01
7375
else:
7476
# get time delta in seconds
75-
timestep = time.ticks_diff(currentTime, self.prevTime) / 1000
76-
self.prevTime = currentTime # cache time for next update
77+
timestep = time.ticks_diff(current_time, self.prev_time) / 1000
78+
self.prev_time = current_time # cache time for next update
7779

7880
self._handle_exit_condition(error)
7981

80-
integral = self.prevIntegral + error * timestep
81-
derivative = (error - self.prevError) / timestep
82+
integral = self.prev_integral + error * timestep
83+
84+
if self.max_integral is not None:
85+
integral = max(-self.max_integral, min(self.max_integral, integral))
86+
87+
derivative = (error - self.prev_error) / timestep
8288

8389
# derive output
8490
output = self.kp * error + self.ki * integral + self.kd * derivative
85-
self.prevError = error
86-
self.prevIntegral = integral
91+
self.prev_error = error
92+
self.prev_integral = integral
8793

8894
# Bound output by minimum
8995
if output > 0:
90-
output = max(self.minOutput, output)
96+
output = max(self.min_output, output)
9197
else:
92-
output = min(-self.minOutput, output)
98+
output = min(-self.min_output, output)
9399

94100
# Bound output by maximum
95-
output = max(-self.maxOutput, min(self.maxOutput, output))
101+
output = max(-self.max_output, min(self.max_output, output))
96102

97103
# Bound output by maximum acceleration
98-
if self.maxDerivative is not None:
99-
lowerBound = self.prevOutput - self.maxDerivative * timestep
100-
upperBound = self.prevOutput + self.maxDerivative * timestep
101-
output = max(lowerBound, min(upperBound, output))
104+
if self.max_derivative is not None:
105+
lower_bound = self.prev_output - self.max_derivative * timestep
106+
upper_bound = self.prev_output + self.max_derivative * timestep
107+
output = max(lower_bound, min(upper_bound, output))
102108

103109
# cache output for next update
104-
self.prevOutput = output
110+
self.prev_output = output
105111

106112
return output
107113

@@ -110,12 +116,11 @@ def is_done(self) -> bool:
110116
:return: if error is within tolerance for numTimesInTolerance consecutive times, or timed out
111117
:rtype: bool
112118
"""
113-
114-
return self.times >= self.toleranceCount
119+
return self.times >= self.tolerance_count
115120

116121
def clear_history(self):
117-
self.prevError = 0
118-
self.prevIntegral = 0
119-
self.prevOutput = 0
120-
self.times = 0
121-
self.prevTime = None
122+
self.prev_error = 0
123+
self.prev_integral = 0
124+
self.prev_output = 0
125+
self.prev_time = None
126+
self.times = 0

0 commit comments

Comments
 (0)