Skip to content

Commit be4d133

Browse files
committed
PD controller structure
1 parent 3fe1a79 commit be4d133

File tree

2 files changed

+54
-40
lines changed

2 files changed

+54
-40
lines changed

rotary_encoder/motorencoder.py

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -132,49 +132,23 @@ def reset_state(self):
132132
self._ticks_counter = 0
133133
self._is_moving = False # resetting moving flag
134134

135-
# CALLBACK
136-
""" The callback function rotary_callback is called on FALLING_EDGE by the
137-
rotary_decoder with a parameter value of 1 (1 new tick)
138-
139-
- Gearbox ratio: 120:1 (1 wheel revolution = 120 motor revolution)
140-
- Encoder ratio: 16:1 encoder ticks for 1 motor revolution
141-
- 1 wheel revolution = 120 * 16 = 1920 ticks
142-
- R = 30mm - 1 wheel revolution = 2πR = 2 * π * 30mm = 188.5mm
143-
- 1920 ticks = 188.5mm
144-
- 1 tick = 0.0981mm
145-
- 1 tick : 0.0981mm = x : 1000mm -> x = 10193 ticks approximately
146-
So 0.0981 is the ticks->distance(mm) conversion coefficient
147-
148-
The callback function calculates current velocity by taking groups of
149-
ticks_threshold ticks"""
150-
151-
"""
152-
# callback function
153-
# it calculates velocity via approssimation
154-
# it doeas a mean on current time passed and actual distance travelled
155-
# NOT USEFUL FOR VELOCITY REGULATION since we need to know the current
156-
# velocity updated each time
157-
def rotary_callback(self, tick):
158-
self._motor_lock.acquire()
159-
160-
# on first movement
161-
if(self._distance == 0):
162-
self._start_timer = time() # clock started
163-
164-
165-
self._ticks += tick # updating ticks
166-
self._distance = self._ticks * 0.0981 # (mm) travelled
135+
# adjust power for velocity control loop
136+
def adjust_power(self, power):
137+
self._motor_lock.acquire() # acquiring lock
167138

168-
# velocity calculation
169-
self._current_timer = time()
139+
self._power = power # setting current power
170140

171-
elapse = self._current_timer - self._start_timer
172-
if(elapse != 0):
173-
self._encoder_speed = self._distance / elapse #(mm/s)
141+
# adjusting power forward
142+
if (self._direction == 1):
143+
self._pi.set_PWM_dutycycle(self._forward_pin, abs(power))
144+
# adjusting power bacakward
145+
else:
146+
self._pi.set_PWM_dutycycle(self._backward_pin, abs(power))
174147

148+
# releasing lock on motor
175149
self._motor_lock.release()
176-
"""
177150

151+
# CALLBACK
178152
# callback function
179153
def rotary_callback(self, tick):
180154
self._motor_lock.acquire()

rotary_encoder/wheelsaxel.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,50 @@ def control_distance(self, power_left=100, power_right=100, target_distance=0):
101101
self._left_motor.control(power_left)
102102
self._right_motor.control(power_right)
103103

104+
#PID parameters
105+
# assuming that power_right is equal to power_left and that coderbot
106+
# moves at 11.5mm/s at full PWM duty cycle
107+
TARGET = 0.95 * power_right #velocity [mm/s]
108+
KP = 0.02 #proportional coefficient
109+
KI = 0.005
110+
SAMPLETIME = 0.05
111+
left_speed = TARGET
112+
right_speed = left_speed
113+
integral_error = 0
114+
104115
# moving for certaing amount of distance
105-
# threshold value avoid to stop it after
106116
while(abs(self.distance()) < target_distance):
107-
pass # busy waiting
117+
# PI controller
118+
119+
# relative error
120+
left_error = TARGET - self._left_motor.speed()
121+
right_error = TARGET - self._right_motor.speed()
122+
123+
left_speed += (left_error * KP) - (integral_error * KI)
124+
right_speed += (right_error * KP) + (integral_error * KI)
125+
126+
# conrispondent new power
127+
left_power = max(min(100 * left_speed / 95, 100), 0)
128+
right_power = max(min(100 * right_speed / 95, 100), 0)
129+
130+
print("Left SPEED: %f" % (self._left_motor.speed()))
131+
print("Right SPEED: %f" % (self._right_motor.speed()))
132+
print("Left POWER: %f" % (left_power))
133+
print("Right POWER: %f" % (right_power))
134+
135+
# adjusting power on each motors
136+
self._left_motor.adjust_power(left_power)
137+
self._right_motor.adjust_power(right_power)
138+
139+
140+
integral_error += (left_speed - right_speed)
141+
142+
# restoring factor
143+
left_speed = TARGET
144+
right_speed = TARGET
145+
146+
# checking each SAMPLETIME seconds
147+
sleep(SAMPLETIME)
108148

109149
# robot arrived
110150
self.stop()

0 commit comments

Comments
 (0)