urkit 0.3.15__tar.gz → 0.3.17__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.
Files changed (39) hide show
  1. {urkit-0.3.15 → urkit-0.3.17}/PKG-INFO +18 -1
  2. {urkit-0.3.15 → urkit-0.3.17}/README.md +17 -0
  3. {urkit-0.3.15 → urkit-0.3.17}/pyproject.toml +1 -1
  4. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/__init__.py +1 -1
  5. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/config.py +47 -0
  6. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/robot.py +125 -8
  7. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/PKG-INFO +18 -1
  8. {urkit-0.3.15 → urkit-0.3.17}/setup.cfg +0 -0
  9. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/__main__.py +0 -0
  10. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/cli/__init__.py +0 -0
  11. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/cli/colors.py +0 -0
  12. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/cli/connection_monitor.py +0 -0
  13. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/cli/points.py +0 -0
  14. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/cli/teach.py +0 -0
  15. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/connection.py +0 -0
  16. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/exceptions.py +0 -0
  17. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/geometry.py +0 -0
  18. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/__init__.py +0 -0
  19. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/base.py +0 -0
  20. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/digital.py +0 -0
  21. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/presets.py +0 -0
  22. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/robotiq.py +0 -0
  23. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/gripper/robotiq_preamble.py +0 -0
  24. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/io.py +0 -0
  25. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/motion.py +0 -0
  26. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/points.py +0 -0
  27. {urkit-0.3.15 → urkit-0.3.17}/src/urkit/telemetry.py +0 -0
  28. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/SOURCES.txt +0 -0
  29. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/dependency_links.txt +0 -0
  30. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/entry_points.txt +0 -0
  31. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/requires.txt +0 -0
  32. {urkit-0.3.15 → urkit-0.3.17}/src/urkit.egg-info/top_level.txt +0 -0
  33. {urkit-0.3.15 → urkit-0.3.17}/tests/test_exceptions.py +0 -0
  34. {urkit-0.3.15 → urkit-0.3.17}/tests/test_geometry.py +0 -0
  35. {urkit-0.3.15 → urkit-0.3.17}/tests/test_gripper.py +0 -0
  36. {urkit-0.3.15 → urkit-0.3.17}/tests/test_gripper_factory.py +0 -0
  37. {urkit-0.3.15 → urkit-0.3.17}/tests/test_gripper_presets.py +0 -0
  38. {urkit-0.3.15 → urkit-0.3.17}/tests/test_points.py +0 -0
  39. {urkit-0.3.15 → urkit-0.3.17}/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.15
3
+ Version: 0.3.17
4
4
  Summary: Universal Robots e-Series control toolkit built on ur_rtde
5
5
  Author: URKit Contributors
6
6
  License: MIT
@@ -502,6 +502,23 @@ robot.get_speed_slider() # read current slider (0.0-1.0)
502
502
 
503
503
  The speed slider controls the pendant's speed multiplier. It's global, persistent, and affects all motion commands.
504
504
 
505
+ #### Changing Default Speed & Acceleration
506
+
507
+ Override the constructor defaults at runtime — all subsequent moves pick up the new values:
508
+
509
+ ```python
510
+ robot.set_speed(0.1) # slow for precision work
511
+ robot.move_to("insert")
512
+ robot.set_speed(0.5) # back to normal
513
+
514
+ robot.set_acc(0.05) # gentle acceleration
515
+
516
+ robot.default_vel # read current velocity (m/s)
517
+ robot.default_acc # read current acceleration (m/s²)
518
+ ```
519
+
520
+ Soft warnings log when values exceed typical robot limits (> 2 m/s for velocity, > 6 m/s² for acceleration). The controller may clamp aggressive values based on payload and configuration.
521
+
505
522
  #### Inverse Kinematics
506
523
 
507
524
  ```python
@@ -476,6 +476,23 @@ robot.get_speed_slider() # read current slider (0.0-1.0)
476
476
 
477
477
  The speed slider controls the pendant's speed multiplier. It's global, persistent, and affects all motion commands.
478
478
 
479
+ #### Changing Default Speed & Acceleration
480
+
481
+ Override the constructor defaults at runtime — all subsequent moves pick up the new values:
482
+
483
+ ```python
484
+ robot.set_speed(0.1) # slow for precision work
485
+ robot.move_to("insert")
486
+ robot.set_speed(0.5) # back to normal
487
+
488
+ robot.set_acc(0.05) # gentle acceleration
489
+
490
+ robot.default_vel # read current velocity (m/s)
491
+ robot.default_acc # read current acceleration (m/s²)
492
+ ```
493
+
494
+ Soft warnings log when values exceed typical robot limits (> 2 m/s for velocity, > 6 m/s² for acceleration). The controller may clamp aggressive values based on payload and configuration.
495
+
479
496
  #### Inverse Kinematics
480
497
 
481
498
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "urkit"
7
- version = "0.3.15"
7
+ version = "0.3.17"
8
8
  description = "Universal Robots e-Series control toolkit built on ur_rtde"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -24,7 +24,7 @@ Quick start::
24
24
 
25
25
  from __future__ import annotations
26
26
 
27
- __version__ = "0.3.15"
27
+ __version__ = "0.3.17"
28
28
 
29
29
  from urkit.config import load_config, resolve_config
30
30
  from urkit.exceptions import (
@@ -14,6 +14,53 @@ Usage::
14
14
  from urkit import URRobot
15
15
  robot = URRobot.from_config("config.yaml")
16
16
  robot = URRobot.from_config("config.yaml", ip="10.0.0.50") # override IP
17
+
18
+ Config YAML format
19
+ ------------------
20
+
21
+ Minimal config::
22
+
23
+ robot_ip: 192.168.1.50
24
+
25
+ Built-in gripper preset (string)::
26
+
27
+ robot_ip: 192.168.1.50
28
+ gripper: hand-e
29
+ gripper_config:
30
+ force: 50
31
+
32
+ Custom gripper with payload + TCP offset (dict)::
33
+
34
+ robot_ip: 192.168.1.50
35
+ gripper:
36
+ mass: 0.5
37
+ center_of_gravity: [0.0, 0.0, 0.0]
38
+ tcp_offset: [0.0, 0.0, 0.175, 0.0, 0.0, 0.0]
39
+ backend: none
40
+
41
+ Override physical properties on a built-in preset::
42
+
43
+ robot_ip: 192.168.1.50
44
+ gripper: hand-e
45
+ gripper_config:
46
+ mass: 1.5
47
+ center_of_gravity: [0.0, 0.0, 0.08]
48
+
49
+ Full config reference::
50
+
51
+ robot_ip: 192.168.1.50 # required
52
+ points_path: points.db # optional, SQLite waypoint DB
53
+ gripper: hand-e # preset name, dict, or omit
54
+ gripper_config: # optional overrides
55
+ mass: 1.0 # kg
56
+ center_of_gravity: [0, 0, 0] # [x, y, z] in meters
57
+ tcp_offset: [0, 0, 0.1, 0, 0, 0] # [x, y, z, rx, ry, rz]
58
+ force: 100 # 0-100
59
+ speed: 100 # 0-100
60
+ max_mm: 50 # finger travel
61
+ default_vel: 0.5 # m/s
62
+ default_acc: 0.3 # m/s²
63
+ expert_mode: false # show advanced CLI commands
17
64
  """
18
65
 
19
66
  from __future__ import annotations
@@ -6,6 +6,7 @@ and named point management into a single high-level interface.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ from dataclasses import replace
9
10
  import logging
10
11
  import sys
11
12
  import time
@@ -360,27 +361,36 @@ class URRobot:
360
361
  points: Path to points database. Overrides ``points_path`` from config.
361
362
  gripper: A GripperPreset, DigitalGripperConfig, a preset name
362
363
  string (e.g. ``"hand-e"``, ``"2f-85"``, ``"digital"``),
363
- or ``None``. Overrides the ``gripper`` key from config.
364
+ a dict defining a custom gripper, or ``None``. Overrides
365
+ the ``gripper`` key from config.
364
366
  default_vel: Default linear velocity (m/s).
365
367
  default_acc: Default linear acceleration (m/s²).
366
368
  gripper_kwargs: Overrides for gripper preset values
367
- (e.g. ``max_mm``, ``force``, ``speed``, ``pin``).
369
+ (e.g. ``max_mm``, ``force``, ``speed``, ``pin``,
370
+ ``mass``, ``center_of_gravity``, ``tcp_offset``).
368
371
 
369
372
  Config file keys::
370
373
 
374
+ # Built-in preset (string)
371
375
  robot_ip: 192.168.1.50
372
376
  points_path: points.db
373
377
  gripper: hand-e
374
378
  gripper_config:
379
+ mass: 1.5
375
380
  force: 50
376
- speed: 80
377
- default_vel: 0.5
378
- default_acc: 0.3
381
+
382
+ # Custom gripper (dict) — arbitrary payload + TCP offset
383
+ robot_ip: 192.168.1.50
384
+ gripper:
385
+ mass: 0.5
386
+ center_of_gravity: [0.0, 0.0, 0.0]
387
+ tcp_offset: [0.0, 0.0, 0.175, 0.0, 0.0, 0.0]
388
+ backend: none
379
389
 
380
390
  Example:
381
391
  >>> robot = URRobot.from_config("config.yaml")
382
392
  >>> robot = URRobot.from_config("config.yaml", ip="10.0.0.50")
383
- >>> robot = URRobot.from_config({"robot_ip": "192.168.1.50", "points_path": "points.db", "gripper": "2f-85"})
393
+ >>> robot = URRobot.from_config({"robot_ip": "192.168.1.50", "gripper": {"name": "tool", "mass": 0.5, "center_of_gravity": [0, 0, 0], "tcp_offset": [0, 0, 0.1, 0, 0, 0], "backend": "none"}})
384
394
  """
385
395
  if isinstance(config, str):
386
396
  resolved = resolve_config(config)
@@ -413,6 +423,18 @@ class URRobot:
413
423
  if gripper_source is not None:
414
424
  if isinstance(gripper_source, (GripperPreset, DigitalGripperConfig)):
415
425
  resolved_gripper = gripper_source
426
+ elif isinstance(gripper_source, dict):
427
+ # Custom gripper defined inline in YAML as a dict
428
+ resolved_gripper = GripperPreset(
429
+ name=str(gripper_source.get("name", "custom")),
430
+ mass=float(gripper_source.get("mass", 0.0)),
431
+ center_of_gravity=list(gripper_source.get("center_of_gravity", [0.0, 0.0, 0.0])),
432
+ tcp_offset=list(gripper_source.get("tcp_offset", [0.0, 0.0, 0.0, 0.0, 0.0, 0.0])),
433
+ backend=str(gripper_source.get("backend", "none")),
434
+ max_mm=int(gripper_source.get("max_mm", 50)),
435
+ force=int(gripper_source.get("force", 100)),
436
+ speed=int(gripper_source.get("speed", 100)),
437
+ )
416
438
  elif isinstance(gripper_source, str):
417
439
  key = gripper_source.strip().upper()
418
440
  preset = PRESETS.get(key)
@@ -431,9 +453,31 @@ class URRobot:
431
453
 
432
454
  # Merge config gripper overrides into gripper_kwargs.
433
455
  # Check nested gripper_config first, then top-level for backwards compat.
434
- gripper_overrides = ("max_mm", "force", "speed", "pin", "close_on_high")
435
456
  nested_cfg = cfg.get("gripper_config") or {}
436
- for key in gripper_overrides:
457
+
458
+ # Physical properties override the GripperPreset directly via replace()
459
+ physical_overrides = ("mass", "center_of_gravity", "tcp_offset")
460
+ for key in physical_overrides:
461
+ if key not in gripper_kwargs:
462
+ value = nested_cfg.get(key, cfg.get(key)) # type: ignore
463
+ if value is not None:
464
+ gripper_kwargs[key] = value
465
+
466
+ # Apply physical overrides to the resolved preset
467
+ if isinstance(resolved_gripper, GripperPreset):
468
+ apply_replace: dict[str, object] = {}
469
+ if "mass" in gripper_kwargs:
470
+ apply_replace["mass"] = float(gripper_kwargs.pop("mass"))
471
+ if "center_of_gravity" in gripper_kwargs:
472
+ apply_replace["center_of_gravity"] = list(gripper_kwargs.pop("center_of_gravity"))
473
+ if "tcp_offset" in gripper_kwargs:
474
+ apply_replace["tcp_offset"] = list(gripper_kwargs.pop("tcp_offset"))
475
+ if apply_replace:
476
+ resolved_gripper = replace(resolved_gripper, **apply_replace) # type: ignore[arg-type]
477
+
478
+ # Standard gripper kwargs (passed to Gripper.create)
479
+ standard_overrides = ("max_mm", "force", "speed", "pin", "close_on_high")
480
+ for key in standard_overrides:
437
481
  if key not in gripper_kwargs:
438
482
  value = nested_cfg.get(key, cfg.get(key)) # type: ignore
439
483
  if value is not None:
@@ -1372,6 +1416,79 @@ class URRobot:
1372
1416
  """Get the current speed slider setting (0.0–1.0)."""
1373
1417
  return self._telemetry.get_speed_slider()
1374
1418
 
1419
+ # ------------------------------------------------------------------
1420
+ # Velocity / acceleration defaults
1421
+ # ------------------------------------------------------------------
1422
+
1423
+ @property
1424
+ def default_vel(self) -> float:
1425
+ """Current default velocity (m/s) for motion commands."""
1426
+ return self._default_vel
1427
+
1428
+ @property
1429
+ def default_acc(self) -> float:
1430
+ """Current default acceleration (m/s²) for motion commands."""
1431
+ return self._default_acc
1432
+
1433
+ def set_speed(self, vel: float) -> None:
1434
+ """Change the default velocity for subsequent motions.
1435
+
1436
+ Updates both the URRobot-level default and the internal
1437
+ Motion instance so that ``move_to``, ``move_relative``, etc.
1438
+ pick up the new value when no per-call override is given.
1439
+
1440
+ Args:
1441
+ vel: Linear velocity in m/s (must be > 0).
1442
+
1443
+ Raises:
1444
+ MotionError: If vel is <= 0.
1445
+
1446
+ Example:
1447
+ >>> robot.set_speed(0.1) # slow for precision
1448
+ >>> robot.move_to("insert")
1449
+ >>> robot.set_speed(0.5) # back to normal
1450
+ """
1451
+ if vel <= 0:
1452
+ raise MotionError(f"vel must be > 0, got {vel}.")
1453
+ if vel > 2.0:
1454
+ logger.warning(
1455
+ "set_speed(%s): %.1f m/s exceeds typical TCP speed limits "
1456
+ "(UR3e/5e/10e: ~1–2 m/s). The controller may clamp this value.",
1457
+ vel,
1458
+ vel,
1459
+ )
1460
+ self._default_vel = vel
1461
+ self._motion._default_vel = vel
1462
+
1463
+ def set_acc(self, acc: float) -> None:
1464
+ """Change the default acceleration for subsequent motions.
1465
+
1466
+ Updates both the URRobot-level default and the internal
1467
+ Motion instance so that ``move_to``, ``move_relative``, etc.
1468
+ pick up the new value when no per-call override is given.
1469
+
1470
+ Args:
1471
+ acc: Linear acceleration in m/s² (must be > 0).
1472
+
1473
+ Raises:
1474
+ MotionError: If acc is <= 0.
1475
+
1476
+ Example:
1477
+ >>> robot.set_acc(0.05) # gentle acceleration
1478
+ >>> robot.move_to("insert")
1479
+ """
1480
+ if acc <= 0:
1481
+ raise MotionError(f"acc must be > 0, got {acc}.")
1482
+ if acc > 6.0:
1483
+ logger.warning(
1484
+ "set_acc(%s): %.1f m/s² is high. The controller may clamp "
1485
+ "this value based on payload and configuration.",
1486
+ acc,
1487
+ acc,
1488
+ )
1489
+ self._default_acc = acc
1490
+ self._motion._default_acc = acc
1491
+
1375
1492
  # ------------------------------------------------------------------
1376
1493
  # Kinematics
1377
1494
  # ------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urkit
3
- Version: 0.3.15
3
+ Version: 0.3.17
4
4
  Summary: Universal Robots e-Series control toolkit built on ur_rtde
5
5
  Author: URKit Contributors
6
6
  License: MIT
@@ -502,6 +502,23 @@ robot.get_speed_slider() # read current slider (0.0-1.0)
502
502
 
503
503
  The speed slider controls the pendant's speed multiplier. It's global, persistent, and affects all motion commands.
504
504
 
505
+ #### Changing Default Speed & Acceleration
506
+
507
+ Override the constructor defaults at runtime — all subsequent moves pick up the new values:
508
+
509
+ ```python
510
+ robot.set_speed(0.1) # slow for precision work
511
+ robot.move_to("insert")
512
+ robot.set_speed(0.5) # back to normal
513
+
514
+ robot.set_acc(0.05) # gentle acceleration
515
+
516
+ robot.default_vel # read current velocity (m/s)
517
+ robot.default_acc # read current acceleration (m/s²)
518
+ ```
519
+
520
+ Soft warnings log when values exceed typical robot limits (> 2 m/s for velocity, > 6 m/s² for acceleration). The controller may clamp aggressive values based on payload and configuration.
521
+
505
522
  #### Inverse Kinematics
506
523
 
507
524
  ```python
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