urkit 0.3.18__tar.gz → 0.3.19__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.18 → urkit-0.3.19}/PKG-INFO +1 -1
  2. {urkit-0.3.18 → urkit-0.3.19}/pyproject.toml +1 -1
  3. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/__init__.py +1 -1
  4. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/cli/teach.py +13 -0
  5. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/robot.py +76 -11
  6. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/PKG-INFO +1 -1
  7. {urkit-0.3.18 → urkit-0.3.19}/README.md +0 -0
  8. {urkit-0.3.18 → urkit-0.3.19}/setup.cfg +0 -0
  9. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/__main__.py +0 -0
  10. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/cli/__init__.py +0 -0
  11. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/cli/colors.py +0 -0
  12. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/cli/connection_monitor.py +0 -0
  13. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/cli/points.py +0 -0
  14. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/config.py +0 -0
  15. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/connection.py +0 -0
  16. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/exceptions.py +0 -0
  17. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/geometry.py +0 -0
  18. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/__init__.py +0 -0
  19. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/base.py +0 -0
  20. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/digital.py +0 -0
  21. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/presets.py +0 -0
  22. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/robotiq.py +0 -0
  23. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/gripper/robotiq_preamble.py +0 -0
  24. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/io.py +0 -0
  25. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/motion.py +0 -0
  26. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/points.py +0 -0
  27. {urkit-0.3.18 → urkit-0.3.19}/src/urkit/telemetry.py +0 -0
  28. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/SOURCES.txt +0 -0
  29. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/dependency_links.txt +0 -0
  30. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/entry_points.txt +0 -0
  31. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/requires.txt +0 -0
  32. {urkit-0.3.18 → urkit-0.3.19}/src/urkit.egg-info/top_level.txt +0 -0
  33. {urkit-0.3.18 → urkit-0.3.19}/tests/test_exceptions.py +0 -0
  34. {urkit-0.3.18 → urkit-0.3.19}/tests/test_geometry.py +0 -0
  35. {urkit-0.3.18 → urkit-0.3.19}/tests/test_gripper.py +0 -0
  36. {urkit-0.3.18 → urkit-0.3.19}/tests/test_gripper_factory.py +0 -0
  37. {urkit-0.3.18 → urkit-0.3.19}/tests/test_gripper_presets.py +0 -0
  38. {urkit-0.3.18 → urkit-0.3.19}/tests/test_points.py +0 -0
  39. {urkit-0.3.18 → urkit-0.3.19}/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.18
3
+ Version: 0.3.19
4
4
  Summary: Universal Robots e-Series control toolkit built on ur_rtde
5
5
  Author: URKit Contributors
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "urkit"
7
- version = "0.3.18"
7
+ version = "0.3.19"
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.18"
27
+ __version__ = "0.3.19"
28
28
 
29
29
  from urkit.config import load_config, resolve_config
30
30
  from urkit.exceptions import (
@@ -738,9 +738,17 @@ def _submenu_goto_point(
738
738
  time.sleep(0.05)
739
739
 
740
740
  # Show dedicated moving screen with monotonic progress
741
+ # Timeout after 60s in case is_moving() stalls (heavy robot settling,
742
+ # robot already at target, etc.)
741
743
  cancelled = False
744
+ timed_out = False
742
745
  max_progress = 0.0
746
+ move_start = time.monotonic()
743
747
  while robot.is_moving():
748
+ if time.monotonic() - move_start > 60.0:
749
+ timed_out = True
750
+ break
751
+
744
752
  pct, bar = _draw_moving_screen(
745
753
  robot, name, mode_label, start_pose, target_pose, is_cartesian, max_progress
746
754
  )
@@ -758,6 +766,11 @@ def _submenu_goto_point(
758
766
  if cancelled:
759
767
  robot.stop()
760
768
  messages.append(f"Move to '{name}' cancelled")
769
+ elif timed_out:
770
+ messages.append(
771
+ f"Moved to '{name}' ({mode_label}) — "
772
+ "timeout, robot may already have been at target"
773
+ )
761
774
  else:
762
775
  messages.append(f"Moved to '{name}' ({mode_label})")
763
776
  except URKitConnectionError:
@@ -118,6 +118,10 @@ class URRobot:
118
118
  self._connection_lost = False
119
119
  self._move_frame: MoveFrame = MoveFrame.BASE
120
120
 
121
+ # Target tracking for pose-based arrival detection in is_moving()
122
+ self._move_target_pose: list[float] | None = None
123
+ self._move_target_joints: list[float] | None = None
124
+
121
125
  # Points database (internal) — optional, lazy-initialized
122
126
  self._points: Points | None = Points(points) if points is not None else None
123
127
 
@@ -1078,6 +1082,14 @@ class URRobot:
1078
1082
  vel = vel if vel is not None else self._default_vel
1079
1083
  acc = acc if acc is not None else self._default_acc
1080
1084
 
1085
+ # Store target for pose-based arrival detection
1086
+ if linear:
1087
+ self._move_target_pose = list(pose)
1088
+ self._move_target_joints = None
1089
+ else:
1090
+ self._move_target_joints = None # set below after IK
1091
+ self._move_target_pose = list(pose)
1092
+
1081
1093
  try:
1082
1094
  if linear:
1083
1095
  if not self._rtde_c.getInverseKinematicsHasSolution(pose):
@@ -1085,6 +1097,7 @@ class URRobot:
1085
1097
  self._motion.movel(pose, vel=vel, acc=acc, asynchronous=asynchronous)
1086
1098
  else:
1087
1099
  joints = self.inverse_kinematics(pose)
1100
+ self._move_target_joints = list(joints)
1088
1101
  self._motion.movej(joints, vel=vel, acc=acc, asynchronous=asynchronous)
1089
1102
  except MotionError:
1090
1103
  raise
@@ -1094,13 +1107,29 @@ class URRobot:
1094
1107
  )
1095
1108
  raise MotionError(f"Move to {target_label} failed: {e}")
1096
1109
 
1097
- def is_moving(self) -> bool:
1098
- """Check if the robot is currently moving.
1110
+ def is_moving(
1111
+ self,
1112
+ *,
1113
+ position_tolerance: float = 0.002,
1114
+ orientation_tolerance: float = 0.035,
1115
+ joint_tolerance: float = 0.01,
1116
+ ) -> bool:
1117
+ """Check if the robot has arrived at the last move target.
1118
+
1119
+ Compares current TCP pose (or joint angles for joint moves)
1120
+ to the target stored by ``move_to()``. Returns False when
1121
+ within tolerance.
1099
1122
 
1100
- Returns True if any joint or TCP velocity is non-zero.
1123
+ Args:
1124
+ position_tolerance: Max distance in meters to consider
1125
+ "arrived" (default 2 mm).
1126
+ orientation_tolerance: Max rotation error in radians to
1127
+ consider "arrived" (default ~2 degrees).
1128
+ joint_tolerance: Max per-joint error in radians for joint
1129
+ moves (default ~0.6 degrees).
1101
1130
 
1102
1131
  Returns:
1103
- True if moving, False if stopped.
1132
+ True if still moving toward target, False if arrived.
1104
1133
 
1105
1134
  Example:
1106
1135
  >>> robot.move_to("home", asynchronous=True)
@@ -1109,15 +1138,38 @@ class URRobot:
1109
1138
  >>> print("Done!")
1110
1139
  """
1111
1140
  try:
1112
- joint_vel = self._rtde_r.getActualQd()
1113
- tcp_speed = self._rtde_r.getActualTCPSpeed()
1141
+ # Joint-based: compare current joints to target
1142
+ if self._move_target_joints is not None:
1143
+ current = self._rtde_r.getActualQ()
1144
+ target = self._move_target_joints
1145
+ for c, t in zip(current, target):
1146
+ if abs(c - t) > joint_tolerance:
1147
+ return True
1148
+ self._move_target_joints = None
1149
+ self._move_target_pose = None
1150
+ return False
1114
1151
 
1115
- joint_moving = any(abs(v) > 0.0001 for v in joint_vel)
1116
- tcp_moving = any(abs(v) > 0.0001 for v in tcp_speed[:3]) or any(
1117
- abs(v) > 0.0001 for v in tcp_speed[3:]
1118
- )
1152
+ # Pose-based: compare current TCP pose to target
1153
+ if self._move_target_pose is not None:
1154
+ current = self._rtde_r.getActualTCPPose()
1155
+ target = self._move_target_pose
1156
+ dx = current[0] - target[0]
1157
+ dy = current[1] - target[1]
1158
+ dz = current[2] - target[2]
1159
+ dist = (dx * dx + dy * dy + dz * dz) ** 0.5
1160
+
1161
+ d_rx = abs(current[3] - target[3])
1162
+ d_ry = abs(current[4] - target[4])
1163
+ d_rz = abs(current[5] - target[5])
1164
+ orient_err = max(d_rx, d_ry, d_rz)
1165
+
1166
+ if dist <= position_tolerance and orient_err <= orientation_tolerance:
1167
+ self._move_target_pose = None
1168
+ return False
1169
+ return True
1119
1170
 
1120
- return joint_moving or tcp_moving
1171
+ # No target set — assume not moving
1172
+ return False
1121
1173
  except Exception:
1122
1174
  return False
1123
1175
 
@@ -1136,6 +1188,10 @@ class URRobot:
1136
1188
  self._rtde_c.stopL(5.0, True)
1137
1189
  except Exception:
1138
1190
  pass
1191
+
1192
+ # Clear move targets so is_moving() falls back to velocity check
1193
+ self._move_target_pose = None
1194
+ self._move_target_joints = None
1139
1195
  try:
1140
1196
  self._rtde_c.stopJ(5.0, True)
1141
1197
  except Exception:
@@ -1225,10 +1281,19 @@ class URRobot:
1225
1281
  current = list(self._rtde_r.getActualTCPPose())
1226
1282
  target = transform_pose_delta(current, final_delta, effective_frame)
1227
1283
 
1284
+ # Store target for arrival detection
1285
+ if linear:
1286
+ self._move_target_pose = list(target)
1287
+ self._move_target_joints = None
1288
+ else:
1289
+ self._move_target_pose = list(target)
1290
+ self._move_target_joints = None
1291
+
1228
1292
  if linear:
1229
1293
  self._motion.movel(target, vel=vel, acc=acc, asynchronous=asynchronous)
1230
1294
  else:
1231
1295
  joints = self.inverse_kinematics(target)
1296
+ self._move_target_joints = list(joints)
1232
1297
  self._motion.movej(joints, vel=vel, acc=acc, asynchronous=asynchronous)
1233
1298
  except MotionError:
1234
1299
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urkit
3
- Version: 0.3.18
3
+ Version: 0.3.19
4
4
  Summary: Universal Robots e-Series control toolkit built on ur_rtde
5
5
  Author: URKit Contributors
6
6
  License: MIT
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