Skip to content

Commit 1ac33cf

Browse files
authored
New firmware support (#190)
* New firmware * Changes for new PID * Remove bias test, as no longer exists * Update pwm params * Test down to 10ms interval * Lower speed to improve positioning accuracy
1 parent 9c1dbb9 commit 1ac33cf

File tree

5 files changed

+69
-29
lines changed

5 files changed

+69
-29
lines changed

buildhat/data/firmware.bin

192 Bytes
Binary file not shown.

buildhat/data/signature.bin

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
�kt�Cr�>_iۼ*����c=Y옢3#��lw!H�w�F�Z2y���4���9��d鱾o
1+
Q#�E]��]-.T~�駶�e[yE�V}A5�L��}���A�$I!�u�9Nzw`��l�@eK��;�{E�

buildhat/data/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1670596313
1+
1674818421

buildhat/motors.py

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ def __init__(self, port):
2727
self._default_speed = 20
2828
self._currentspeed = 0
2929
self.plimit(0.7)
30-
self.bias(0.3)
3130

3231
def set_default_speed(self, default_speed):
3332
"""Set the default speed of the motor
@@ -79,10 +78,10 @@ def bias(self, bias):
7978
8079
:param bias: Value 0 to 1
8180
:raises MotorError: Occurs if invalid bias value passed
82-
"""
83-
if not (bias >= 0 and bias <= 1):
84-
raise MotorError("bias should be 0 to 1")
85-
self._write(f"port {self.port} ; bias {bias}\r")
81+
82+
.. deprecated:: 0.6.0
83+
""" # noqa: RST303
84+
raise MotorError("Bias no longer available")
8685

8786

8887
class MotorRunmode(Enum):
@@ -118,14 +117,22 @@ def __init__(self, port):
118117
self._combi = "1 0 2 0 3 0"
119118
self._noapos = False
120119
self.plimit(0.7)
121-
self.bias(0.3)
120+
self.pwmparams(0.65, 0.01)
121+
self._rpm = False
122122
self._release = True
123123
self._bqueue = deque(maxlen=5)
124124
self._cvqueue = Condition()
125125
self.when_rotated = None
126126
self._oldpos = None
127127
self._runmode = MotorRunmode.NONE
128128

129+
def set_speed_unit_rpm(self, rpm=False):
130+
"""Set whether to use RPM for speed units or not
131+
132+
:param rpm: Boolean to determine whether to use RPM for units
133+
"""
134+
self._rpm = rpm
135+
129136
def set_default_speed(self, default_speed):
130137
"""Set the default speed of the motor
131138
@@ -200,11 +207,13 @@ def _run_positional_ramp(self, pos, newpos, speed):
200207
:param newpos: New motor postion in decimal rotations (from preset position)
201208
:param speed: -100 to 100
202209
"""
203-
# Collapse speed range to -5 to 5
204-
speed *= 0.05
210+
if self._rpm:
211+
speed = self._speed_process(speed)
212+
else:
213+
speed *= 0.05 # Collapse speed range to -5 to 5
205214
dur = abs((newpos - pos) / speed)
206215
cmd = (f"port {self.port}; select 0 ; selrate {self._interval}; "
207-
f"pid {self.port} 0 1 s4 0.0027777778 0 5 0 .1 3; "
216+
f"pid {self.port} 0 1 s4 0.0027777778 0 5 0 .1 3 0.01; "
208217
f"set ramp {pos} {newpos} {dur} 0\r")
209218
ftr = Future()
210219
self._hat.rampftr[self.port].append(ftr)
@@ -258,9 +267,14 @@ def run_to_position(self, degrees, speed=None, blocking=True, direction="shortes
258267
self._run_to_position(degrees, speed, direction)
259268

260269
def _run_for_seconds(self, seconds, speed):
270+
speed = self._speed_process(speed)
261271
self._runmode = MotorRunmode.SECONDS
272+
if self._rpm:
273+
pid = f"pid_diff {self.port} 0 5 s2 0.0027777778 1 0 2.5 0 .4 0.01; "
274+
else:
275+
pid = f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100 0.01;"
262276
cmd = (f"port {self.port} ; select 0 ; selrate {self._interval}; "
263-
f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
277+
f"{pid}"
264278
f"set pulse {speed} 0.0 {seconds} 0\r")
265279
ftr = Future()
266280
self._hat.pulseftr[self.port].append(ftr)
@@ -309,10 +323,15 @@ def start(self, speed=None):
309323
else:
310324
if not (speed >= -100 and speed <= 100):
311325
raise MotorError("Invalid Speed")
326+
speed = self._speed_process(speed)
312327
cmd = f"port {self.port} ; set {speed}\r"
313328
if self._runmode == MotorRunmode.NONE:
329+
if self._rpm:
330+
pid = f"pid_diff {self.port} 0 5 s2 0.0027777778 1 0 2.5 0 .4 0.01; "
331+
else:
332+
pid = f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100 0.01; "
314333
cmd = (f"port {self.port} ; select 0 ; selrate {self._interval}; "
315-
f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
334+
f"{pid}"
316335
f"set {speed}\r")
317336
self._runmode = MotorRunmode.FREE
318337
self._currentspeed = speed
@@ -401,10 +420,23 @@ def bias(self, bias):
401420
402421
:param bias: Value 0 to 1
403422
:raises MotorError: Occurs if invalid bias value passed
423+
424+
.. deprecated:: 0.6.0
425+
""" # noqa: RST303
426+
raise MotorError("Bias no longer available")
427+
428+
def pwmparams(self, pwmthresh, minpwm):
429+
"""PWM thresholds
430+
431+
:param pwmthresh: Value 0 to 1, threshold below, will switch from fast to slow, PWM
432+
:param minpwm: Value 0 to 1, threshold below which it switches off the drive altogether
433+
:raises MotorError: Occurs if invalid values are passed
404434
"""
405-
if not (bias >= 0 and bias <= 1):
406-
raise MotorError("bias should be 0 to 1")
407-
self._write(f"port {self.port} ; bias {bias}\r")
435+
if not (pwmthresh >= 0 and pwmthresh <= 1):
436+
raise MotorError("pwmthresh should be 0 to 1")
437+
if not (minpwm >= 0 and minpwm <= 1):
438+
raise MotorError("minpwm should be 0 to 1")
439+
self._write(f"port {self.port} ; pwmparams {pwmthresh} {minpwm}\r")
408440

409441
def pwm(self, pwmv):
410442
"""PWM motor
@@ -453,6 +485,13 @@ def _wait_for_nonblocking(self):
453485
"""Wait for nonblocking commands to finish"""
454486
Device._instance.motorqueue[self.port].join()
455487

488+
def _speed_process(self, speed):
489+
"""Lower speed value"""
490+
if self._rpm:
491+
return speed / 60
492+
else:
493+
return speed
494+
456495

457496
class MotorPair:
458497
"""Pair of motors
@@ -473,6 +512,7 @@ def __init__(self, leftport, rightport):
473512
self._rightmotor = Motor(rightport)
474513
self.default_speed = 20
475514
self._release = True
515+
self._rpm = False
476516

477517
def set_default_speed(self, default_speed):
478518
"""Set the default speed of the motor
@@ -481,6 +521,15 @@ def set_default_speed(self, default_speed):
481521
"""
482522
self.default_speed = default_speed
483523

524+
def set_speed_unit_rpm(self, rpm=False):
525+
"""Set whether to use RPM for speed units or not
526+
527+
:param rpm: Boolean to determine whether to use RPM for units
528+
"""
529+
self._rpm = rpm
530+
self._leftmotor.set_speed_unit_rpm(rpm)
531+
self._rightmotor.set_speed_unit_rpm(rpm)
532+
484533
def run_for_rotations(self, rotations, speedl=None, speedr=None):
485534
"""Run pair of motors for N rotations
486535

test/motors.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def test_rotations(self):
2424
def test_nonblocking(self):
2525
"""Test motor nonblocking mode"""
2626
m = Motor('A')
27+
m.set_default_speed(10)
2728
last = 0
2829
for delay in [1, 0]:
2930
for _ in range(3):
@@ -44,7 +45,9 @@ def test_nonblocking(self):
4445
def test_nonblocking_multiple(self):
4546
"""Test motor nonblocking mode"""
4647
m1 = Motor('A')
48+
m1.set_default_speed(10)
4749
m2 = Motor('B')
50+
m2.set_default_speed(10)
4851
last = 0
4952
for delay in [1, 0]:
5053
for _ in range(3):
@@ -118,13 +121,6 @@ def test_plimit(self):
118121
self.assertRaises(MotorError, m.plimit, -1)
119122
self.assertRaises(MotorError, m.plimit, 2)
120123

121-
def test_bias(self):
122-
"""Test setting motor bias"""
123-
m = Motor('A')
124-
m.bias(0.5)
125-
self.assertRaises(MotorError, m.bias, -1)
126-
self.assertRaises(MotorError, m.bias, 2)
127-
128124
def test_pwm(self):
129125
"""Test PWMing motor"""
130126
m = Motor('A')
@@ -157,11 +153,6 @@ def handle_motor(speed, pos, apos):
157153
m.run_for_seconds(5)
158154
self.assertGreater(handle_motor.evt, 0.8 * ((1 / ((m.interval) * 1e-3)) * 5))
159155

160-
handle_motor.evt = 0
161-
m.interval = 5
162-
m.run_for_seconds(5)
163-
self.assertGreater(handle_motor.evt, 0.8 * ((1 / ((m.interval) * 1e-3)) * 5))
164-
165156
def test_none_callback(self):
166157
"""Test setting empty callback"""
167158
m = Motor('A')
@@ -234,7 +225,7 @@ def test_dual_interval(self):
234225
"""Test dual motor interval"""
235226
m1 = Motor('A')
236227
m2 = Motor('B')
237-
for interval in [10, 5]:
228+
for interval in [20, 10]:
238229
m1.interval = interval
239230
m2.interval = interval
240231
count = 1000

0 commit comments

Comments
 (0)