urkit 0.3.22__tar.gz → 0.3.23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {urkit-0.3.22 → urkit-0.3.23}/PKG-INFO +11 -1
- {urkit-0.3.22 → urkit-0.3.23}/README.md +10 -0
- {urkit-0.3.22 → urkit-0.3.23}/pyproject.toml +1 -1
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/__init__.py +1 -1
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/motion.py +57 -4
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/robot.py +16 -2
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/PKG-INFO +11 -1
- {urkit-0.3.22 → urkit-0.3.23}/setup.cfg +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/__main__.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/cli/__init__.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/cli/colors.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/cli/connection_monitor.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/cli/points.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/cli/teach.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/config.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/connection.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/exceptions.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/geometry.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/__init__.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/base.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/digital.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/presets.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/robotiq.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/gripper/robotiq_preamble.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/io.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/points.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit/telemetry.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/SOURCES.txt +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/dependency_links.txt +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/entry_points.txt +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/requires.txt +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/src/urkit.egg-info/top_level.txt +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_exceptions.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_geometry.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_gripper.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_gripper_factory.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_gripper_presets.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_move_sequence.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_points.py +0 -0
- {urkit-0.3.22 → urkit-0.3.23}/tests/test_robot_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.23
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -506,6 +506,16 @@ robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
|
506
506
|
# Full speed vector
|
|
507
507
|
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
508
508
|
|
|
509
|
+
# Abort after 10s or 200mm of travel, whichever comes first
|
|
510
|
+
robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2)
|
|
511
|
+
|
|
512
|
+
# Returns True if contact detected, False if timeout/max_distance hit
|
|
513
|
+
for _ in range(3):
|
|
514
|
+
if robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2):
|
|
515
|
+
break # contact detected
|
|
516
|
+
# No contact — back off and retry
|
|
517
|
+
robot.move_by(z=0.01)
|
|
518
|
+
|
|
509
519
|
# Manual zero (e.g. before custom force-based logic)
|
|
510
520
|
robot.zero_ft_sensor()
|
|
511
521
|
```
|
|
@@ -480,6 +480,16 @@ robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
|
480
480
|
# Full speed vector
|
|
481
481
|
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
482
482
|
|
|
483
|
+
# Abort after 10s or 200mm of travel, whichever comes first
|
|
484
|
+
robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2)
|
|
485
|
+
|
|
486
|
+
# Returns True if contact detected, False if timeout/max_distance hit
|
|
487
|
+
for _ in range(3):
|
|
488
|
+
if robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2):
|
|
489
|
+
break # contact detected
|
|
490
|
+
# No contact — back off and retry
|
|
491
|
+
robot.move_by(z=0.01)
|
|
492
|
+
|
|
483
493
|
# Manual zero (e.g. before custom force-based logic)
|
|
484
494
|
robot.zero_ft_sensor()
|
|
485
495
|
```
|
|
@@ -9,6 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
import io
|
|
11
11
|
import logging
|
|
12
|
+
import math
|
|
12
13
|
import os
|
|
13
14
|
import sys
|
|
14
15
|
import time
|
|
@@ -278,7 +279,9 @@ class Motion:
|
|
|
278
279
|
threshold: float = 5.0,
|
|
279
280
|
acceleration: float = 0.1,
|
|
280
281
|
zero_first: bool = True,
|
|
281
|
-
|
|
282
|
+
timeout: float | None = None,
|
|
283
|
+
max_distance: float | None = None,
|
|
284
|
+
) -> bool:
|
|
282
285
|
"""Move until contact is detected via TCP force sensing.
|
|
283
286
|
|
|
284
287
|
Runs a 500 Hz control loop that sends ``speedL()`` commands and
|
|
@@ -300,15 +303,30 @@ class Motion:
|
|
|
300
303
|
zero_first: If True (default), zero the FT sensor before reading
|
|
301
304
|
the baseline. Set to False if you need absolute force values
|
|
302
305
|
rather than delta from zero.
|
|
306
|
+
timeout: Maximum time in seconds before aborting. If exceeded,
|
|
307
|
+
returns ``False``. Set to ``None`` (default) for no time limit.
|
|
308
|
+
max_distance: Maximum TCP travel distance in meters before aborting.
|
|
309
|
+
If exceeded, returns ``False``. Set to ``None`` (default) for
|
|
310
|
+
no distance limit.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
``True`` if contact was detected, ``False`` if timeout or
|
|
314
|
+
max_distance was reached without contact.
|
|
303
315
|
|
|
304
316
|
Raises:
|
|
305
|
-
MotionError: If the command fails
|
|
317
|
+
MotionError: If the command fails (connection lost, E-stop,
|
|
318
|
+
protective stop, invalid params).
|
|
306
319
|
|
|
307
320
|
Example:
|
|
308
321
|
>>> # Move straight down until contact (zeros FT sensor first)
|
|
309
322
|
>>> motion.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
310
323
|
>>> # Move down while rotating, higher threshold
|
|
311
324
|
>>> motion.move_until_contact([0, 0, -0.02, 0, 0.1, 0], threshold=10.0)
|
|
325
|
+
>>> # Retry loop with guards
|
|
326
|
+
>>> for _ in range(3):
|
|
327
|
+
... if motion.move_until_contact([0, 0, -0.02, 0, 0, 0], timeout=10.0, max_distance=0.2):
|
|
328
|
+
... break
|
|
329
|
+
... # No contact — reposition and retry
|
|
312
330
|
"""
|
|
313
331
|
if len(speed_vector) != 6:
|
|
314
332
|
raise MotionError(
|
|
@@ -316,11 +334,16 @@ class Motion:
|
|
|
316
334
|
)
|
|
317
335
|
if threshold <= 0:
|
|
318
336
|
raise MotionError(f"Threshold must be > 0, got {threshold}.")
|
|
337
|
+
if timeout is not None and timeout <= 0:
|
|
338
|
+
raise MotionError(f"Timeout must be > 0, got {timeout}.")
|
|
339
|
+
if max_distance is not None and max_distance <= 0:
|
|
340
|
+
raise MotionError(f"max_distance must be > 0, got {max_distance}.")
|
|
319
341
|
|
|
342
|
+
contact_detected = False
|
|
320
343
|
try:
|
|
321
344
|
logger.debug(
|
|
322
|
-
"move_until_contact: speed_vector=%s, threshold=%.2f",
|
|
323
|
-
speed_vector, threshold,
|
|
345
|
+
"move_until_contact: speed_vector=%s, threshold=%.2f, timeout=%s, max_distance=%s",
|
|
346
|
+
speed_vector, threshold, timeout, max_distance,
|
|
324
347
|
)
|
|
325
348
|
|
|
326
349
|
# Zero FT sensor to clear gravity bias before reading baseline
|
|
@@ -331,7 +354,34 @@ class Motion:
|
|
|
331
354
|
# Baseline force reading before the loop
|
|
332
355
|
baseline = list(self._rtde_r.getActualTCPForce())
|
|
333
356
|
|
|
357
|
+
# Track timeout and distance guards
|
|
358
|
+
start_time = time.monotonic() if timeout is not None else None
|
|
359
|
+
start_pose = list(self._rtde_r.getActualTCPPose())[:3] if max_distance is not None else None
|
|
360
|
+
|
|
334
361
|
while True:
|
|
362
|
+
# Check time timeout
|
|
363
|
+
if start_time is not None and timeout is not None:
|
|
364
|
+
elapsed = time.monotonic() - start_time
|
|
365
|
+
if elapsed >= timeout:
|
|
366
|
+
logger.info(
|
|
367
|
+
"move_until_contact timed out after %.1fs (limit: %.1fs)",
|
|
368
|
+
elapsed, timeout,
|
|
369
|
+
)
|
|
370
|
+
break
|
|
371
|
+
|
|
372
|
+
# Check distance timeout
|
|
373
|
+
if start_pose is not None and max_distance is not None:
|
|
374
|
+
current_pose = list(self._rtde_r.getActualTCPPose())[:3]
|
|
375
|
+
distance = math.sqrt(
|
|
376
|
+
sum((current_pose[i] - start_pose[i]) ** 2 for i in range(3))
|
|
377
|
+
)
|
|
378
|
+
if distance >= max_distance:
|
|
379
|
+
logger.info(
|
|
380
|
+
"move_until_contact exceeded max_distance: %.3fm travelled (limit: %.3fm)",
|
|
381
|
+
distance, max_distance,
|
|
382
|
+
)
|
|
383
|
+
break
|
|
384
|
+
|
|
335
385
|
if not self._rtde_c.isConnected():
|
|
336
386
|
raise MotionError(
|
|
337
387
|
"RTDE connection lost during move_until_contact. "
|
|
@@ -363,6 +413,7 @@ class Motion:
|
|
|
363
413
|
if any(
|
|
364
414
|
abs(current[i] - baseline[i]) > threshold for i in range(6)
|
|
365
415
|
):
|
|
416
|
+
contact_detected = True
|
|
366
417
|
break
|
|
367
418
|
|
|
368
419
|
with _suppress_rtde_stderr():
|
|
@@ -378,6 +429,8 @@ class Motion:
|
|
|
378
429
|
except Exception:
|
|
379
430
|
pass
|
|
380
431
|
|
|
432
|
+
return contact_detected
|
|
433
|
+
|
|
381
434
|
def move_velocity(
|
|
382
435
|
self,
|
|
383
436
|
speed_vector: list[float],
|
|
@@ -1614,13 +1614,15 @@ class URRobot:
|
|
|
1614
1614
|
threshold: float = 5.0,
|
|
1615
1615
|
acceleration: float = 0.1,
|
|
1616
1616
|
zero_first: bool = True,
|
|
1617
|
+
timeout: float | None = None,
|
|
1618
|
+
max_distance: float | None = None,
|
|
1617
1619
|
speed_x: float = 0.0,
|
|
1618
1620
|
speed_y: float = 0.0,
|
|
1619
1621
|
speed_z: float = 0.0,
|
|
1620
1622
|
speed_rx: float = 0.0,
|
|
1621
1623
|
speed_ry: float = 0.0,
|
|
1622
1624
|
speed_rz: float = 0.0,
|
|
1623
|
-
) ->
|
|
1625
|
+
) -> bool:
|
|
1624
1626
|
"""Move until contact is detected via TCP force sensing.
|
|
1625
1627
|
|
|
1626
1628
|
Runs an interruptible control loop — press Ctrl+C to stop at any time.
|
|
@@ -1636,9 +1638,17 @@ class URRobot:
|
|
|
1636
1638
|
acceleration: Acceleration limit passed to ``speedL()`` in m/s².
|
|
1637
1639
|
zero_first: If True (default), zero the FT sensor before reading
|
|
1638
1640
|
the baseline. Set to False if you need absolute force values.
|
|
1641
|
+
timeout: Maximum time in seconds before aborting. Set to ``None``
|
|
1642
|
+
(default) for no time limit.
|
|
1643
|
+
max_distance: Maximum TCP travel distance in meters before aborting.
|
|
1644
|
+
Set to ``None`` (default) for no distance limit.
|
|
1639
1645
|
speed_x, speed_y, speed_z: Linear speed components in m/s.
|
|
1640
1646
|
speed_rx, speed_ry, speed_rz: Angular speed components in rad/s.
|
|
1641
1647
|
|
|
1648
|
+
Returns:
|
|
1649
|
+
``True`` if contact was detected, ``False`` if timeout or
|
|
1650
|
+
max_distance was reached without contact.
|
|
1651
|
+
|
|
1642
1652
|
Example:
|
|
1643
1653
|
>>> # Move straight down until contact
|
|
1644
1654
|
>>> robot.move_until_contact(speed_z=-0.02)
|
|
@@ -1646,6 +1656,8 @@ class URRobot:
|
|
|
1646
1656
|
>>> robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
1647
1657
|
>>> # Higher threshold for heavier contact
|
|
1648
1658
|
>>> robot.move_until_contact(speed_z=-0.02, threshold=10.0)
|
|
1659
|
+
>>> # Abort after 10s or 200mm, whichever comes first
|
|
1660
|
+
>>> robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2)
|
|
1649
1661
|
"""
|
|
1650
1662
|
self._check_connection()
|
|
1651
1663
|
self._disable_freedrive_guard()
|
|
@@ -1655,11 +1667,13 @@ class URRobot:
|
|
|
1655
1667
|
else:
|
|
1656
1668
|
final_vector = [speed_x, speed_y, speed_z, speed_rx, speed_ry, speed_rz]
|
|
1657
1669
|
|
|
1658
|
-
self._motion.move_until_contact(
|
|
1670
|
+
return self._motion.move_until_contact(
|
|
1659
1671
|
final_vector,
|
|
1660
1672
|
threshold=threshold,
|
|
1661
1673
|
acceleration=acceleration,
|
|
1662
1674
|
zero_first=zero_first,
|
|
1675
|
+
timeout=timeout,
|
|
1676
|
+
max_distance=max_distance,
|
|
1663
1677
|
)
|
|
1664
1678
|
|
|
1665
1679
|
def move_velocity(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.23
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -506,6 +506,16 @@ robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
|
506
506
|
# Full speed vector
|
|
507
507
|
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
508
508
|
|
|
509
|
+
# Abort after 10s or 200mm of travel, whichever comes first
|
|
510
|
+
robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2)
|
|
511
|
+
|
|
512
|
+
# Returns True if contact detected, False if timeout/max_distance hit
|
|
513
|
+
for _ in range(3):
|
|
514
|
+
if robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2):
|
|
515
|
+
break # contact detected
|
|
516
|
+
# No contact — back off and retry
|
|
517
|
+
robot.move_by(z=0.01)
|
|
518
|
+
|
|
509
519
|
# Manual zero (e.g. before custom force-based logic)
|
|
510
520
|
robot.zero_ft_sensor()
|
|
511
521
|
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|