Skip to content

Commit 4e16995

Browse files
authored
Merge pull request #85 from kensthilaire/main
Extended DifferentialDrive class to use IMU and PID to drive straight when using arcade drive
2 parents 00c2cc7 + 2987ea0 commit 4e16995

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

XRPLib/differential_drive.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ def __init__(self, left_motor: EncodedMotor, right_motor: EncodedMotor, imu: IMU
5050
self.wheel_diam = wheel_diam
5151
self.track_width = wheel_track
5252

53+
self.heading_pid = None
54+
self.current_heading = None
55+
self.reset_heading = True
56+
self.turning = False
57+
58+
if self.imu:
59+
# if the IMU is initialized, then create a PID controller that can be used
60+
# to maintain a constant heading when driving
61+
self.heading_pid = PID( kp = 0.075, kd=0.001, )
62+
5363
def set_effort(self, left_effort: float, right_effort: float) -> None:
5464
"""
5565
Set the raw effort of both motors individually
@@ -110,7 +120,33 @@ def arcade(self, straight:float, turn:float):
110120
scale = max(abs(straight), abs(turn))/(abs(straight) + abs(turn))
111121
left_speed = (straight - turn)*scale
112122
right_speed = (straight + turn)*scale
113-
self.set_effort(left_speed, right_speed)
123+
124+
if not self.heading_pid:
125+
# if not using IMU assist to maintain heading, just pass down the left and right motor
126+
# speeds to control movement
127+
self.set_effort(left_speed, right_speed)
128+
else:
129+
# else if IMU assist is enabled, then use the IMU with PID to
130+
# maintain a constant heading while driving.
131+
if turn == 0:
132+
# straight drive requested, then maintain the current heading
133+
if self.turning:
134+
# if previously turning, then clear the turn indicator and reset the course heading
135+
self.reset_heading = True
136+
self.turning = False
137+
138+
if self.reset_heading:
139+
self.reset_heading = False
140+
self.current_heading = self.imu.get_yaw()
141+
142+
# use the PID to set the heading correction based on the current heading
143+
heading_correction = self.heading_pid.update(self.current_heading - self.imu.get_yaw())
144+
145+
self.set_effort(left_speed - heading_correction, right_speed + heading_correction)
146+
else:
147+
# set the turning indicator and apply the left and right speeds
148+
self.turning = True
149+
self.set_effort(left_speed, right_speed)
114150

115151
def reset_encoder_position(self) -> None:
116152
"""

0 commit comments

Comments
 (0)