Skip to content

Commit 5d7683c

Browse files
authored
Refactor wait_for_arrival() to include timeout (#233)
* adds 10ms pause within wait_for_arrive(); set's old firmware coordinate after limit hit * adds timeouts to Driver.wait_for_arrival() incase no movement occurs * pylama * adds tests * pylama * attach robot to instrumentMotor and Mosfet incase user switches between firmware version
1 parent 8559fde commit 5d7683c

File tree

5 files changed

+66
-28
lines changed

5 files changed

+66
-28
lines changed

api/opentrons/drivers/smoothie_drivers/v1_2_0/driver.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,12 @@ def detect_limit_hit(self, msg):
289289
"""
290290
if '!!' in msg or 'limit' in msg:
291291
log.debug('home switch hit')
292+
time.sleep(0.5)
292293
self.flush_port()
293294
self.calm_down()
295+
self.set_position(
296+
**self.get_position().get('current', {l: 0 for l in 'xyzab'})
297+
)
294298
raise RuntimeWarning('Robot Error: limit switch hit')
295299

296300
def set_coordinate_system(self, mode):
@@ -371,10 +375,13 @@ def flip_coordinates(self, coordinates, mode='absolute'):
371375
return coordinates
372376

373377
def wait_for_arrival(self, tolerance=0.1):
374-
arrived = False
375378
coords = self.get_position()
376-
while not arrived:
379+
380+
prev_max_diff = 0
381+
did_move_timestamp = time.time()
382+
while True:
377383
self.check_paused_stopped()
384+
self.connection.serial_pause()
378385
coords = self.get_position()
379386
diff = {}
380387
for axis in coords.get('target', {}):
@@ -390,12 +397,14 @@ def wait_for_arrival(self, tolerance=0.1):
390397
the robot's physical resolution is found with:
391398
1mm / config_steps_per_mm
392399
"""
393-
if dist_head < tolerance:
394-
if abs(diff['a']) < tolerance and abs(diff['b']) < tolerance:
395-
arrived = True
396-
else:
397-
arrived = False
398-
return arrived
400+
max_diff = max(dist_head, abs(diff['a']), abs(diff['b']))
401+
if max_diff < tolerance:
402+
return
403+
if max_diff != prev_max_diff:
404+
did_move_timestamp = time.time()
405+
prev_max_diff = max_diff
406+
if time.time() - did_move_timestamp > 1.0:
407+
raise RuntimeError('Expected robot to move, please reconnect')
399408

400409
def home(self, *axis):
401410
axis_to_home = ''
@@ -413,12 +422,6 @@ def home(self, *axis):
413422
raise RuntimeWarning(
414423
'HOMING ERROR: Check switches are being pressed and connected')
415424
if res == 'ok':
416-
# the axis aren't necessarily set to 0.0
417-
# values after homing, so force it
418-
pos_args = {}
419-
for l in axis_to_home:
420-
pos_args[l] = 0
421-
422425
arguments = {
423426
'name': 'home',
424427
'axis': axis_to_home,
@@ -428,6 +431,11 @@ def home(self, *axis):
428431
}
429432
}
430433
trace.EventBroker.get_instance().notify(arguments)
434+
# the axis aren't necessarily set to 0.0
435+
# values after homing, so force it
436+
pos_args = {}
437+
for l in axis_to_home:
438+
pos_args[l] = 0
431439
return self.set_position(**pos_args)
432440
else:
433441
return False

api/opentrons/drivers/smoothie_drivers/v2_0_0/driver.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,11 @@ def flip_coordinates(self, coordinates, mode='absolute'):
295295
def wait_for_arrival(self, tolerance=0.5):
296296
target = self.get_target_position()
297297

298+
prev_max_diff = 0
299+
did_move_timestamp = time.time()
298300
while True:
299301
self.check_paused_stopped()
302+
self.connection.serial_pause()
300303

301304
current = self.get_current_position()
302305
diff = {}
@@ -307,8 +310,15 @@ def wait_for_arrival(self, tolerance=0.5):
307310
diff_a = abs(diff.get('a', 0))
308311
diff_b = abs(diff.get('b', 0))
309312

310-
if max(diff_head, diff_a, diff_b) < tolerance:
313+
max_diff = max(diff_head, diff_a, diff_b)
314+
315+
if max_diff < tolerance:
311316
return
317+
if max_diff != prev_max_diff:
318+
did_move_timestamp = time.time()
319+
prev_max_diff = max_diff
320+
if time.time() - did_move_timestamp > 1.0:
321+
raise RuntimeError('Expected robot to move, please reconnect')
312322

313323
def home(self, *axis):
314324

api/opentrons/robot/robot.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ class InstrumentMosfet(object):
2424
Provides access to MagBead's MOSFET.
2525
"""
2626

27-
def __init__(self, driver, mosfet_index):
28-
self.motor_driver = driver
27+
def __init__(self, this_robot, mosfet_index):
28+
self.robot = this_robot
2929
self.mosfet_index = mosfet_index
3030

3131
def engage(self):
3232
"""
3333
Engages the MOSFET.
3434
"""
35-
self.motor_driver.set_mosfet(self.mosfet_index, True)
35+
self.robot._driver.set_mosfet(self.mosfet_index, True)
3636

3737
def disengage(self):
3838
"""
3939
Disengages the MOSFET.
4040
"""
41-
self.motor_driver.set_mosfet(self.mosfet_index, False)
41+
self.robot._driver.set_mosfet(self.mosfet_index, False)
4242

4343
def wait(self, seconds):
4444
"""
@@ -49,15 +49,15 @@ def wait(self, seconds):
4949
seconds : int
5050
Number of seconds to pause for.
5151
"""
52-
self.motor_driver.wait(seconds)
52+
self.robot._driver.wait(seconds)
5353

5454

5555
class InstrumentMotor(object):
5656
"""
5757
Provides access to Robot's head motor.
5858
"""
59-
def __init__(self, driver, axis):
60-
self.motor_driver = driver
59+
def __init__(self, this_robot, axis):
60+
self.robot = this_robot
6161
self.axis = axis
6262

6363
def move(self, value, mode='absolute'):
@@ -71,15 +71,15 @@ def move(self, value, mode='absolute'):
7171
mode : {'absolute', 'relative'}
7272
"""
7373
kwargs = {self.axis: value}
74-
self.motor_driver.move_plunger(
74+
self.robot._driver.move_plunger(
7575
mode=mode, **kwargs
7676
)
7777

7878
def home(self):
7979
"""
8080
Home plunger motor.
8181
"""
82-
self.motor_driver.home(self.axis)
82+
self.robot._driver.home(self.axis)
8383

8484
def wait(self, seconds):
8585
"""
@@ -90,7 +90,7 @@ def wait(self, seconds):
9090
seconds : int
9191
Number of seconds to pause for.
9292
"""
93-
self.motor_driver.wait(seconds)
93+
self.robot._driver.wait(seconds)
9494

9595
def speed(self, rate):
9696
"""
@@ -100,7 +100,7 @@ def speed(self, rate):
100100
----------
101101
rate : int
102102
"""
103-
self.motor_driver.set_plunger_speed(rate, self.axis)
103+
self.robot._driver.set_plunger_speed(rate, self.axis)
104104
return self
105105

106106

@@ -296,7 +296,7 @@ def get_mosfet(self, mosfet_index):
296296

297297
motor_obj = self.INSTRUMENT_DRIVERS_CACHE.get(key)
298298
if not motor_obj:
299-
motor_obj = InstrumentMosfet(self._driver, mosfet_index)
299+
motor_obj = InstrumentMosfet(self, mosfet_index)
300300
self.INSTRUMENT_DRIVERS_CACHE[key] = motor_obj
301301
return motor_obj
302302

@@ -314,7 +314,7 @@ def get_motor(self, axis):
314314

315315
motor_obj = self.INSTRUMENT_DRIVERS_CACHE.get(key)
316316
if not motor_obj:
317-
motor_obj = InstrumentMotor(self._driver, axis)
317+
motor_obj = InstrumentMotor(self, axis)
318318
self.INSTRUMENT_DRIVERS_CACHE[key] = motor_obj
319319
return motor_obj
320320

api/tests/opentrons/drivers/smoothie_drivers/v1_2_0/test_motor.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ def setUp(self):
3030

3131
self.motor = self.robot._driver
3232

33+
def test_is_simulating(self):
34+
self.assertTrue(self.motor.is_simulating())
35+
3336
def test_reset(self):
3437
self.motor.reset()
3538
self.assertFalse(self.motor.is_connected())
@@ -280,6 +283,13 @@ def test_wait_for_arrival(self):
280283
self.motor.move_head(z=30)
281284
self.motor.wait_for_arrival()
282285

286+
old_coords = dict(self.motor.connection.serial_port.coordinates)
287+
vs = self.motor.connection.serial_port
288+
for ax in vs.coordinates['target'].keys():
289+
vs.coordinates['target'][ax] += 10
290+
self.assertRaises(RuntimeError, self.motor.wait_for_arrival)
291+
vs.coordinates = old_coords
292+
283293
def test_move_relative(self):
284294
self.motor.home()
285295
self.motor.move_head(x=100, y=100, z=100)

api/tests/opentrons/drivers/smoothie_drivers/v2_0_0/test_motor.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def setUp(self):
2929

3030
self.motor = self.robot._driver
3131

32+
def test_is_simulating(self):
33+
self.assertTrue(self.motor.is_simulating())
34+
3235
def test_reset(self):
3336
self.motor.reset()
3437
self.assertFalse(self.motor.is_connected())
@@ -288,6 +291,13 @@ def test_wait_for_arrival(self):
288291
self.motor.move_head(z=30)
289292
self.motor.wait_for_arrival()
290293

294+
old_coords = dict(self.motor.connection.serial_port.coordinates)
295+
vs = self.motor.connection.serial_port
296+
for ax in vs.coordinates['target'].keys():
297+
vs.coordinates['target'][ax] += 10
298+
self.assertRaises(RuntimeError, self.motor.wait_for_arrival)
299+
vs.coordinates = old_coords
300+
291301
def test_move_relative(self):
292302
self.motor.home()
293303
self.motor.move_head(x=100, y=100, z=100)

0 commit comments

Comments
 (0)