urkit 0.3.12__tar.gz → 0.3.14__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.12 → urkit-0.3.14}/PKG-INFO +10 -7
- {urkit-0.3.12 → urkit-0.3.14}/README.md +9 -6
- {urkit-0.3.12 → urkit-0.3.14}/pyproject.toml +1 -1
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/__init__.py +1 -1
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/motion.py +16 -3
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/points.py +1 -1
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/robot.py +47 -47
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/PKG-INFO +10 -7
- {urkit-0.3.12 → urkit-0.3.14}/setup.cfg +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/__main__.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/cli/__init__.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/cli/colors.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/cli/connection_monitor.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/cli/points.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/cli/teach.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/config.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/connection.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/exceptions.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/geometry.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/__init__.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/base.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/digital.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/presets.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/robotiq.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/gripper/robotiq_preamble.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/io.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit/telemetry.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/SOURCES.txt +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/dependency_links.txt +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/entry_points.txt +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/requires.txt +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/src/urkit.egg-info/top_level.txt +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_exceptions.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_geometry.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_gripper.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_gripper_factory.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_gripper_presets.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/tests/test_points.py +0 -0
- {urkit-0.3.12 → urkit-0.3.14}/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.14
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -447,24 +447,27 @@ robot.move_relative(delta_z=0.05, frame=MoveFrame.TOOL) # 5cm along tool Z
|
|
|
447
447
|
robot.move_relative([0, 0.01, 0, 0, 0, 0])
|
|
448
448
|
```
|
|
449
449
|
|
|
450
|
-
#### Sequences
|
|
450
|
+
#### Sequences
|
|
451
451
|
|
|
452
452
|
```python
|
|
453
|
+
# Chain multiple moves into one call
|
|
453
454
|
robot.move_sequence(["a", "b", "c"])
|
|
454
|
-
robot.move_sequence(["a", "b", "c"], blend_radius=0.02)
|
|
455
455
|
```
|
|
456
456
|
|
|
457
457
|
#### Contact Detection
|
|
458
458
|
|
|
459
459
|
```python
|
|
460
|
-
#
|
|
461
|
-
robot.move_until_contact(
|
|
460
|
+
# Move straight down until contact (zeros FT sensor automatically)
|
|
461
|
+
robot.move_until_contact(speed_z=-0.02)
|
|
462
462
|
|
|
463
463
|
# Custom threshold (default: 5.0 N/Nm)
|
|
464
|
-
robot.move_until_contact(
|
|
464
|
+
robot.move_until_contact(speed_z=-0.02, threshold=10.0)
|
|
465
465
|
|
|
466
466
|
# Skip zeroing if you need absolute force values
|
|
467
|
-
robot.move_until_contact(
|
|
467
|
+
robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
468
|
+
|
|
469
|
+
# Full speed vector
|
|
470
|
+
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
468
471
|
|
|
469
472
|
# Manual zero (e.g. before custom force-based logic)
|
|
470
473
|
robot.zero_ft_sensor()
|
|
@@ -421,24 +421,27 @@ robot.move_relative(delta_z=0.05, frame=MoveFrame.TOOL) # 5cm along tool Z
|
|
|
421
421
|
robot.move_relative([0, 0.01, 0, 0, 0, 0])
|
|
422
422
|
```
|
|
423
423
|
|
|
424
|
-
#### Sequences
|
|
424
|
+
#### Sequences
|
|
425
425
|
|
|
426
426
|
```python
|
|
427
|
+
# Chain multiple moves into one call
|
|
427
428
|
robot.move_sequence(["a", "b", "c"])
|
|
428
|
-
robot.move_sequence(["a", "b", "c"], blend_radius=0.02)
|
|
429
429
|
```
|
|
430
430
|
|
|
431
431
|
#### Contact Detection
|
|
432
432
|
|
|
433
433
|
```python
|
|
434
|
-
#
|
|
435
|
-
robot.move_until_contact(
|
|
434
|
+
# Move straight down until contact (zeros FT sensor automatically)
|
|
435
|
+
robot.move_until_contact(speed_z=-0.02)
|
|
436
436
|
|
|
437
437
|
# Custom threshold (default: 5.0 N/Nm)
|
|
438
|
-
robot.move_until_contact(
|
|
438
|
+
robot.move_until_contact(speed_z=-0.02, threshold=10.0)
|
|
439
439
|
|
|
440
440
|
# Skip zeroing if you need absolute force values
|
|
441
|
-
robot.move_until_contact(
|
|
441
|
+
robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
442
|
+
|
|
443
|
+
# Full speed vector
|
|
444
|
+
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
442
445
|
|
|
443
446
|
# Manual zero (e.g. before custom force-based logic)
|
|
444
447
|
robot.zero_ft_sensor()
|
|
@@ -7,6 +7,7 @@ velocity and acceleration override.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import io
|
|
10
11
|
import logging
|
|
11
12
|
import os
|
|
12
13
|
import sys
|
|
@@ -511,14 +512,26 @@ class Motion:
|
|
|
511
512
|
else:
|
|
512
513
|
raise MotionError(f"Unknown freedrive mode: {mode}")
|
|
513
514
|
|
|
514
|
-
|
|
515
|
-
|
|
515
|
+
center = list(self._rtde_r.getActualTCPPose())
|
|
516
|
+
# Capture stderr from ur_rtde C++ library to surface robot errors
|
|
517
|
+
stderr_buf = io.StringIO()
|
|
518
|
+
old_stderr = sys.stderr
|
|
519
|
+
sys.stderr = stderr_buf
|
|
520
|
+
try:
|
|
521
|
+
success = self._rtde_c.freedriveMode(free_axes, center)
|
|
522
|
+
finally:
|
|
523
|
+
sys.stderr = old_stderr
|
|
524
|
+
stderr_text = stderr_buf.getvalue().strip()
|
|
525
|
+
|
|
516
526
|
if not success:
|
|
527
|
+
detail = stderr_text if stderr_text else "no detail from robot"
|
|
517
528
|
raise MotionError(
|
|
518
|
-
f"freedriveMode returned false (mode={mode.name})"
|
|
529
|
+
f"freedriveMode returned false (mode={mode.name}): {detail}"
|
|
519
530
|
)
|
|
520
531
|
self._freedrive_active = True
|
|
521
532
|
logger.info("Freedrive mode enabled (%s)", mode.name)
|
|
533
|
+
except MotionError:
|
|
534
|
+
raise
|
|
522
535
|
except Exception as e:
|
|
523
536
|
raise MotionError(
|
|
524
537
|
f"Failed to enable freedrive mode: {e}"
|
|
@@ -119,7 +119,7 @@ class Points:
|
|
|
119
119
|
else:
|
|
120
120
|
self._path = Path(path).resolve()
|
|
121
121
|
self._path.parent.mkdir(parents=True, exist_ok=True)
|
|
122
|
-
self._conn = sqlite3.connect(str(self._path))
|
|
122
|
+
self._conn = sqlite3.connect(str(self._path), check_same_thread=False)
|
|
123
123
|
_init_db(self._conn)
|
|
124
124
|
|
|
125
125
|
def _close(self) -> None:
|
|
@@ -16,6 +16,7 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from rtde.control_interface import RTDEControlInterface
|
|
17
17
|
from rtde.receive_interface import RTDEReceiveInterface
|
|
18
18
|
|
|
19
|
+
from urkit.config import resolve_config
|
|
19
20
|
from urkit.connection import (
|
|
20
21
|
_check_remote_mode,
|
|
21
22
|
_connect_dashboard,
|
|
@@ -25,7 +26,13 @@ from urkit.connection import (
|
|
|
25
26
|
_try_recover_safety,
|
|
26
27
|
_validate_connection,
|
|
27
28
|
)
|
|
28
|
-
from urkit.exceptions import
|
|
29
|
+
from urkit.exceptions import (
|
|
30
|
+
GripperError,
|
|
31
|
+
MotionError,
|
|
32
|
+
PointError,
|
|
33
|
+
RtdeRegisterConflictError,
|
|
34
|
+
URKitConnectionError as ConnectionError,
|
|
35
|
+
)
|
|
29
36
|
from urkit.geometry import MoveFrame, transform_pose_delta
|
|
30
37
|
from urkit.gripper.base import Gripper
|
|
31
38
|
from urkit.gripper.presets import DigitalGripperConfig, GripperPreset, PRESETS
|
|
@@ -189,8 +196,6 @@ class URRobot:
|
|
|
189
196
|
|
|
190
197
|
# Connect RTDE — retry, the Secondary Interface may need time to
|
|
191
198
|
# release registers after program stop or boot.
|
|
192
|
-
from urkit.exceptions import RtdeRegisterConflictError
|
|
193
|
-
|
|
194
199
|
rtde_attempts = 2
|
|
195
200
|
for attempt in range(1, rtde_attempts + 1):
|
|
196
201
|
try:
|
|
@@ -371,15 +376,12 @@ class URRobot:
|
|
|
371
376
|
speed: 80
|
|
372
377
|
default_vel: 0.5
|
|
373
378
|
default_acc: 0.3
|
|
374
|
-
rtde_frequency: 500
|
|
375
379
|
|
|
376
380
|
Example:
|
|
377
381
|
>>> robot = URRobot.from_config("config.yaml")
|
|
378
382
|
>>> robot = URRobot.from_config("config.yaml", ip="10.0.0.50")
|
|
379
383
|
>>> robot = URRobot.from_config({"robot_ip": "192.168.1.50", "points_path": "points.db", "gripper": "2f-85"})
|
|
380
384
|
"""
|
|
381
|
-
from urkit.config import resolve_config
|
|
382
|
-
|
|
383
385
|
if isinstance(config, str):
|
|
384
386
|
resolved = resolve_config(config)
|
|
385
387
|
if resolved is None:
|
|
@@ -433,7 +435,9 @@ class URRobot:
|
|
|
433
435
|
nested_cfg = cfg.get("gripper_config") or {}
|
|
434
436
|
for key in gripper_overrides:
|
|
435
437
|
if key not in gripper_kwargs:
|
|
436
|
-
|
|
438
|
+
value = nested_cfg.get(key, cfg.get(key)) # type: ignore
|
|
439
|
+
if value is not None:
|
|
440
|
+
gripper_kwargs[key] = value
|
|
437
441
|
|
|
438
442
|
return cls(
|
|
439
443
|
ip=resolved_ip,
|
|
@@ -1197,28 +1201,20 @@ class URRobot:
|
|
|
1197
1201
|
acc: float | None = None,
|
|
1198
1202
|
asynchronous: bool = False,
|
|
1199
1203
|
) -> None:
|
|
1200
|
-
"""Move through a sequence of points
|
|
1204
|
+
"""Move through a sequence of points.
|
|
1201
1205
|
|
|
1202
|
-
Executes
|
|
1203
|
-
|
|
1204
|
-
rounds corners instead of stopping at each intermediate waypoint —
|
|
1205
|
-
the same blending you set on the UR teach pendant.
|
|
1206
|
-
|
|
1207
|
-
The first and last points always use a blend radius of 0 so the
|
|
1208
|
-
robot stops cleanly at the start and end of the sequence.
|
|
1206
|
+
Executes each target in order using individual moveL/moveJ calls.
|
|
1207
|
+
Convenience method to condense multiple moves into one call.
|
|
1209
1208
|
|
|
1210
1209
|
Args:
|
|
1211
1210
|
targets: List of saved point names or raw poses
|
|
1212
1211
|
[x, y, z, rx, ry, rz].
|
|
1213
1212
|
linear: If True (default), use Cartesian linear moves (moveL).
|
|
1214
1213
|
If False, use joint-space moves (moveJ).
|
|
1215
|
-
blend_radius:
|
|
1216
|
-
at each point). Typical values: 0.001-0.1 (1mm-100mm).
|
|
1217
|
-
Applied to intermediate points only.
|
|
1214
|
+
blend_radius: Currently ignored. Kept for API compatibility.
|
|
1218
1215
|
vel: Velocity override. Falls back to default_vel.
|
|
1219
1216
|
acc: Acceleration override. Falls back to default_acc.
|
|
1220
|
-
asynchronous:
|
|
1221
|
-
returns immediately (default False).
|
|
1217
|
+
asynchronous: Currently ignored.
|
|
1222
1218
|
|
|
1223
1219
|
Raises:
|
|
1224
1220
|
MotionError: If the sequence fails or fewer than 2 targets.
|
|
@@ -1227,10 +1223,6 @@ class URRobot:
|
|
|
1227
1223
|
Example:
|
|
1228
1224
|
>>> # Move through waypoints, stop at each
|
|
1229
1225
|
>>> robot.move_sequence(["a", "b", "c"])
|
|
1230
|
-
>>> # Smooth path with 2cm corner blending
|
|
1231
|
-
>>> robot.move_sequence(["a", "b", "c"], blend_radius=0.02)
|
|
1232
|
-
>>> # Joint-space sequence with blending
|
|
1233
|
-
>>> robot.move_sequence(["a", "b", "c"], linear=False, blend_radius=0.05)
|
|
1234
1226
|
"""
|
|
1235
1227
|
self._check_connection()
|
|
1236
1228
|
self._disable_freedrive_guard()
|
|
@@ -1243,32 +1235,23 @@ class URRobot:
|
|
|
1243
1235
|
v = vel if vel is not None else self._default_vel
|
|
1244
1236
|
a = acc if acc is not None else self._default_acc
|
|
1245
1237
|
|
|
1246
|
-
# Import here to avoid hard dependency at module level.
|
|
1247
|
-
from rtde_control import Path, PathEntry # noqa: N812
|
|
1248
|
-
|
|
1249
|
-
path = Path()
|
|
1250
|
-
move_type = PathEntry.MoveL if linear else PathEntry.MoveJ
|
|
1251
|
-
|
|
1252
1238
|
for i, target in enumerate(targets):
|
|
1253
1239
|
point = self._lookup_point(target)
|
|
1254
|
-
# First and last points: no blending (stop cleanly).
|
|
1255
|
-
# Intermediate points: use the configured blend radius.
|
|
1256
|
-
r = blend_radius if (0 < i < len(targets) - 1) else 0.0
|
|
1257
|
-
entry_data = list(point.pose) + [v, a, r]
|
|
1258
|
-
path.add_entry(
|
|
1259
|
-
PathEntry(move_type, PathEntry.PositionTcpPose, entry_data)
|
|
1260
|
-
)
|
|
1261
1240
|
label = (
|
|
1262
1241
|
f"'{target}'" if isinstance(target, str) else str(target[:3])
|
|
1263
1242
|
)
|
|
1264
1243
|
logger.info(
|
|
1265
|
-
"move_sequence: %s (
|
|
1244
|
+
"move_sequence: %s (%d/%d)", label, i + 1, len(targets)
|
|
1266
1245
|
)
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1246
|
+
try:
|
|
1247
|
+
if linear:
|
|
1248
|
+
self._rtde_c.moveL(list(point.pose), v, a)
|
|
1249
|
+
else:
|
|
1250
|
+
self._rtde_c.moveJ_IK(
|
|
1251
|
+
list(point.pose), self._rtde_r.getActualQ(), v, a
|
|
1252
|
+
)
|
|
1253
|
+
except Exception as e:
|
|
1254
|
+
raise MotionError(f"move_sequence failed at target {i}: {e}")
|
|
1272
1255
|
|
|
1273
1256
|
def zero_ft_sensor(self) -> None:
|
|
1274
1257
|
"""Zero the robot's force/torque sensor.
|
|
@@ -1285,11 +1268,17 @@ class URRobot:
|
|
|
1285
1268
|
|
|
1286
1269
|
def move_until_contact(
|
|
1287
1270
|
self,
|
|
1288
|
-
speed_vector: list[float],
|
|
1271
|
+
speed_vector: list[float] | None = None,
|
|
1289
1272
|
*,
|
|
1290
1273
|
threshold: float = 5.0,
|
|
1291
1274
|
acceleration: float = 0.1,
|
|
1292
1275
|
zero_first: bool = True,
|
|
1276
|
+
speed_x: float = 0.0,
|
|
1277
|
+
speed_y: float = 0.0,
|
|
1278
|
+
speed_z: float = 0.0,
|
|
1279
|
+
speed_rx: float = 0.0,
|
|
1280
|
+
speed_ry: float = 0.0,
|
|
1281
|
+
speed_rz: float = 0.0,
|
|
1293
1282
|
) -> None:
|
|
1294
1283
|
"""Move until contact is detected via TCP force sensing.
|
|
1295
1284
|
|
|
@@ -1299,23 +1288,34 @@ class URRobot:
|
|
|
1299
1288
|
Args:
|
|
1300
1289
|
speed_vector: 6-element speed vector
|
|
1301
1290
|
``[vx, vy, vz, vRoll, vPitch, dYaw]`` in m/s and rad/s.
|
|
1291
|
+
Mutually exclusive with individual speed_* parameters.
|
|
1302
1292
|
threshold: Force/torque delta (N or Nm) that triggers contact.
|
|
1303
1293
|
Contact fires when any wrench component changes by more
|
|
1304
1294
|
than this value from the baseline reading.
|
|
1305
1295
|
acceleration: Acceleration limit passed to ``speedL()`` in m/s².
|
|
1306
1296
|
zero_first: If True (default), zero the FT sensor before reading
|
|
1307
1297
|
the baseline. Set to False if you need absolute force values.
|
|
1298
|
+
speed_x, speed_y, speed_z: Linear speed components in m/s.
|
|
1299
|
+
speed_rx, speed_ry, speed_rz: Angular speed components in rad/s.
|
|
1308
1300
|
|
|
1309
1301
|
Example:
|
|
1310
|
-
>>> # Move straight down until contact
|
|
1302
|
+
>>> # Move straight down until contact
|
|
1303
|
+
>>> robot.move_until_contact(speed_z=-0.02)
|
|
1304
|
+
>>> # Using full speed vector
|
|
1311
1305
|
>>> robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
1312
1306
|
>>> # Higher threshold for heavier contact
|
|
1313
|
-
>>> robot.move_until_contact(
|
|
1307
|
+
>>> robot.move_until_contact(speed_z=-0.02, threshold=10.0)
|
|
1314
1308
|
"""
|
|
1315
1309
|
self._check_connection()
|
|
1316
1310
|
self._disable_freedrive_guard()
|
|
1311
|
+
|
|
1312
|
+
if speed_vector is not None:
|
|
1313
|
+
final_vector = speed_vector
|
|
1314
|
+
else:
|
|
1315
|
+
final_vector = [speed_x, speed_y, speed_z, speed_rx, speed_ry, speed_rz]
|
|
1316
|
+
|
|
1317
1317
|
self._motion.move_until_contact(
|
|
1318
|
-
|
|
1318
|
+
final_vector,
|
|
1319
1319
|
threshold=threshold,
|
|
1320
1320
|
acceleration=acceleration,
|
|
1321
1321
|
zero_first=zero_first,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.14
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -447,24 +447,27 @@ robot.move_relative(delta_z=0.05, frame=MoveFrame.TOOL) # 5cm along tool Z
|
|
|
447
447
|
robot.move_relative([0, 0.01, 0, 0, 0, 0])
|
|
448
448
|
```
|
|
449
449
|
|
|
450
|
-
#### Sequences
|
|
450
|
+
#### Sequences
|
|
451
451
|
|
|
452
452
|
```python
|
|
453
|
+
# Chain multiple moves into one call
|
|
453
454
|
robot.move_sequence(["a", "b", "c"])
|
|
454
|
-
robot.move_sequence(["a", "b", "c"], blend_radius=0.02)
|
|
455
455
|
```
|
|
456
456
|
|
|
457
457
|
#### Contact Detection
|
|
458
458
|
|
|
459
459
|
```python
|
|
460
|
-
#
|
|
461
|
-
robot.move_until_contact(
|
|
460
|
+
# Move straight down until contact (zeros FT sensor automatically)
|
|
461
|
+
robot.move_until_contact(speed_z=-0.02)
|
|
462
462
|
|
|
463
463
|
# Custom threshold (default: 5.0 N/Nm)
|
|
464
|
-
robot.move_until_contact(
|
|
464
|
+
robot.move_until_contact(speed_z=-0.02, threshold=10.0)
|
|
465
465
|
|
|
466
466
|
# Skip zeroing if you need absolute force values
|
|
467
|
-
robot.move_until_contact(
|
|
467
|
+
robot.move_until_contact(speed_z=-0.02, zero_first=False)
|
|
468
|
+
|
|
469
|
+
# Full speed vector
|
|
470
|
+
robot.move_until_contact([0, 0, -0.02, 0, 0, 0])
|
|
468
471
|
|
|
469
472
|
# Manual zero (e.g. before custom force-based logic)
|
|
470
473
|
robot.zero_ft_sensor()
|
|
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
|