urkit 0.3.26__tar.gz → 0.4.1__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.26 → urkit-0.4.1}/PKG-INFO +140 -65
- {urkit-0.3.26 → urkit-0.4.1}/README.md +139 -64
- {urkit-0.3.26 → urkit-0.4.1}/pyproject.toml +1 -1
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/__init__.py +1 -1
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/__main__.py +22 -1
- urkit-0.4.1/src/urkit/cli/init.py +83 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/teach.py +146 -32
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/motion.py +34 -14
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/robot.py +232 -292
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/telemetry.py +0 -16
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/PKG-INFO +140 -65
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/SOURCES.txt +1 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper_presets.py +1 -1
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_move_sequence.py +49 -38
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_robot_integration.py +17 -23
- {urkit-0.3.26 → urkit-0.4.1}/setup.cfg +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/__init__.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/colors.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/connection_monitor.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/points.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/config.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/connection.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/exceptions.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/geometry.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/__init__.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/base.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/digital.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/presets.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/robotiq.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/robotiq_preamble.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/io.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit/points.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/dependency_links.txt +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/entry_points.txt +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/requires.txt +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/top_level.txt +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_exceptions.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_geometry.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper_factory.py +0 -0
- {urkit-0.3.26 → urkit-0.4.1}/tests/test_points.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: urkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Universal Robots e-Series control toolkit built on ur_rtde
|
|
5
5
|
Author: URKit Contributors
|
|
6
6
|
License: MIT
|
|
@@ -28,9 +28,27 @@ Requires-Dist: rich>=15
|
|
|
28
28
|
|
|
29
29
|
[](https://pypi.org/project/urkit/)
|
|
30
30
|
|
|
31
|
-
**URKit**
|
|
31
|
+
**URKit** makes it easy to get a Universal Robots e-Series robot moving from Python.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## What it is
|
|
34
|
+
|
|
35
|
+
A thin layer over [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/) that handles the common stuff: connecting, teaching named points, moving between them, gripper control, telemetry. Raw RTDE interfaces are exposed for anything deeper.
|
|
36
|
+
|
|
37
|
+
No .urp files, no Dashboard API, no extra programs to run on the robot. Just connect over the network and go. Handles power-on, brake release, and RTDE setup in the constructor so you don't have to.
|
|
38
|
+
|
|
39
|
+
Comes with an interactive teach pendant CLI for positioning the robot and saving waypoints, plus a Python API for scripting motion, gripper control, I/O, and telemetry.
|
|
40
|
+
|
|
41
|
+
## When to use this
|
|
42
|
+
|
|
43
|
+
Projects where the robot is part of something bigger. Computer vision, machine learning, sensor fusion, data logging. If your project lives in Python, keep the robot control in Python too.
|
|
44
|
+
|
|
45
|
+
Built for labs and research setups where you need to get the robot moving fast and integrate it with other software. Not designed as a drop-in replacement for Polyscope in production cells, but perfectly capable for anything that runs from a PC.
|
|
46
|
+
|
|
47
|
+
## How it works
|
|
48
|
+
|
|
49
|
+
Use the CLI to position the robot and save named waypoints. Then reference them by name in your code: move to points, apply offsets, run sequences. Points are stored in a local SQLite database, no robot-side setup needed.
|
|
50
|
+
|
|
51
|
+
The typical workflow: teach points with the pendant, write a few lines of Python to string them together, run it. Add vision, add sensors, add logic. The robot is just one component in your pipeline.
|
|
34
52
|
|
|
35
53
|
---
|
|
36
54
|
|
|
@@ -38,12 +56,14 @@ Built on [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/), it packages the op
|
|
|
38
56
|
|
|
39
57
|
- [Quick Start](#quick-start)
|
|
40
58
|
- [Configuration](#configuration)
|
|
59
|
+
- [Create a Config File](#create-a-config-file)
|
|
41
60
|
- [Location](#location)
|
|
42
61
|
- [Keys](#keys)
|
|
43
62
|
- [Gripper Config](#gripper-config)
|
|
44
63
|
- [Saving Config](#saving-config)
|
|
45
64
|
- [Programmatic](#programmatic)
|
|
46
65
|
- [Interactive CLI](#interactive-cli)
|
|
66
|
+
- [Init](#init)
|
|
47
67
|
- [Teach Mode](#teach-mode)
|
|
48
68
|
- [Points Explorer](#points-explorer)
|
|
49
69
|
- [Key Map](#key-map)
|
|
@@ -70,16 +90,39 @@ Built on [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/), it packages the op
|
|
|
70
90
|
pip install -U urkit
|
|
71
91
|
```
|
|
72
92
|
|
|
73
|
-
The `-U` (upgrade) flag ensures you always get the latest version
|
|
93
|
+
The `-U` (upgrade) flag ensures you always get the latest version. This project is in early development and changes frequently.
|
|
74
94
|
|
|
75
95
|
Requires Python 3.8+ and a Universal Robots e-Series (UR3e to UR30).
|
|
76
96
|
|
|
77
97
|
### Robot Setup (one-time)
|
|
78
98
|
|
|
79
|
-
1. **Network**:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
1. **Network**: Connect your PC to the robot via Ethernet cable (direct) or a switch.
|
|
100
|
+
|
|
101
|
+
First, configure the robot: `☰` → `System` → `System` → `Network`. Set a static IP, e.g., `192.168.1.50` / Subnet `255.255.255.0`.
|
|
102
|
+
|
|
103
|
+
Then set a matching static IP on your PC. The exact IP can be anything, as long as the first three octets match the robot's network and the last octet is different:
|
|
104
|
+
|
|
105
|
+
**Linux**:
|
|
106
|
+
- Open `Settings` → `Network` → click the gear icon next to `Wired`
|
|
107
|
+
- Go to `IPv4` tab → change `Automatic (DHCP)` to `Manual`
|
|
108
|
+
- Enter Address: `192.168.1.1`, Netmask: `255.255.255.0`
|
|
109
|
+
- Click `Apply`, then toggle the connection off and on
|
|
110
|
+
|
|
111
|
+
**macOS**:
|
|
112
|
+
- Open `System Settings` → `Network` → click `Ethernet` (or your adapter)
|
|
113
|
+
- Click `Details...` next to the adapter name → `TCP/IP`
|
|
114
|
+
- Set `Configure IPv4` to `Manually`
|
|
115
|
+
- Enter IP: `192.168.1.1`, Subnet Mask: `255.255.255.0`
|
|
116
|
+
- Click `OK`
|
|
117
|
+
|
|
118
|
+
**Windows**:
|
|
119
|
+
- Open `Settings` → `Network & internet` → `Ethernet`
|
|
120
|
+
- Click the adapter name (e.g., `Ethernet`) at the top
|
|
121
|
+
- Under `IP settings`, click `Edit` → select `Manual`
|
|
122
|
+
- Toggle `IPv4` On, enter IP: `192.168.1.1`, Subnet mask: `255.255.255.0`
|
|
123
|
+
- Click `Save`
|
|
124
|
+
|
|
125
|
+
Verify connectivity: `ping 192.168.1.50`.
|
|
83
126
|
2. **Remote Control**: `☰` → `System` → `Remote Control`: Enable. Press the remote/local button on the pendant.
|
|
84
127
|
3. **Security**: `☰` → `Security` → `Services`: enable RTDE and disable EtherNet/IP, PROFINET, or MODBUS if they're claiming RTDE registers. Save and restart.
|
|
85
128
|
|
|
@@ -104,9 +147,20 @@ robot.gripper.open()
|
|
|
104
147
|
|
|
105
148
|
The typical workflow:
|
|
106
149
|
|
|
107
|
-
1. **
|
|
108
|
-
2. **
|
|
109
|
-
3. **
|
|
150
|
+
1. **Scaffold config.** Run `urkit init` to create a default `config.yaml`.
|
|
151
|
+
2. **Edit it.** Set your robot IP, gripper type, and other settings.
|
|
152
|
+
3. **Teach points.** Run `urkit teach` (auto-loads config) to position the robot and save waypoints.
|
|
153
|
+
4. **Write code.** Load the config and move to points by name:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from urkit import URRobot
|
|
157
|
+
|
|
158
|
+
robot = URRobot.from_config("config.yaml")
|
|
159
|
+
robot.move_to("home")
|
|
160
|
+
robot.move_to("pick", offset_z=0.05)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
5. **Iterate.** Add more points, tweak your code, repeat.
|
|
110
164
|
|
|
111
165
|
---
|
|
112
166
|
|
|
@@ -114,9 +168,21 @@ The typical workflow:
|
|
|
114
168
|
|
|
115
169
|
URKit uses a YAML config file (`config.yaml`) to persist settings between sessions.
|
|
116
170
|
|
|
171
|
+
### Create a Config File
|
|
172
|
+
|
|
173
|
+
Generate a default config with all options documented:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
urkit init # writes config.yaml in CWD
|
|
177
|
+
urkit init --output station_a.yaml # custom path
|
|
178
|
+
urkit init --force # overwrite if exists
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Edit the generated file with your robot IP and gripper settings.
|
|
182
|
+
|
|
117
183
|
### Location
|
|
118
184
|
|
|
119
|
-
|
|
185
|
+
The CLI auto-loads `config.yaml` from the current working directory. Pass `--config` for a custom path.
|
|
120
186
|
|
|
121
187
|
### Keys
|
|
122
188
|
|
|
@@ -206,7 +272,19 @@ robot = URRobot.from_config({"robot_ip": "192.168.1.50", "gripper": "2f-85"}) #
|
|
|
206
272
|
|
|
207
273
|
## Interactive CLI
|
|
208
274
|
|
|
209
|
-
URKit provides
|
|
275
|
+
URKit provides three CLI tools: **init** to scaffold a config file, **teach** for interactive robot control, and **points** for browsing saved waypoints.
|
|
276
|
+
|
|
277
|
+
### Init
|
|
278
|
+
|
|
279
|
+
Generate a default config file with all options documented:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
urkit init # writes config.yaml in CWD
|
|
283
|
+
urkit init --output station_a.yaml # custom path
|
|
284
|
+
urkit init --force # overwrite if exists
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Teach Mode
|
|
210
288
|
|
|
211
289
|
### Teach Mode
|
|
212
290
|
|
|
@@ -309,7 +387,8 @@ All movement and orientation keys support **hold-to-repeat**.
|
|
|
309
387
|
<td align="center" style="width:34%">
|
|
310
388
|
<table>
|
|
311
389
|
<tr><th>Key</th><th>Action</th></tr>
|
|
312
|
-
<tr><td><code>F</code></td><td>Freedrive (
|
|
390
|
+
<tr><td><code>F</code></td><td>Freedrive toggle (ALL ↔ XYZ)</td></tr>
|
|
391
|
+
<tr><td><code>3</code></td><td>Freedrive axis menu (toggle individual axes)</td></tr>
|
|
313
392
|
<tr><td><code>M</code></td><td>Toggle frame (BASE / TOOL)</td></tr>
|
|
314
393
|
<tr><td><code>N</code></td><td>Go To mode (Cartesian / Joint)</td></tr>
|
|
315
394
|
<tr><td><code>T</code></td><td>Open TCP orient submenu (6 directions)</td></tr>
|
|
@@ -502,11 +581,11 @@ while robot.is_moving():
|
|
|
502
581
|
time.sleep(0.01)
|
|
503
582
|
```
|
|
504
583
|
|
|
505
|
-
**Teach pendant Go To** uses this pattern internally
|
|
584
|
+
**Teach pendant Go To** uses this pattern internally. Space cancels the move and returns to the menu.
|
|
506
585
|
|
|
507
586
|
#### Pose Format
|
|
508
587
|
|
|
509
|
-
A pose is `[x, y, z, rx, ry, rz]`: position in meters and orientation as a **rotation vector** (axis-angle in radians). This is not RPY (roll/pitch/yaw). The teach pendant displays RPY in degrees, which is a different representation. Values you see on the pendant won't match `
|
|
588
|
+
A pose is `[x, y, z, rx, ry, rz]`: position in meters and orientation as a **rotation vector** (axis-angle in radians). This is not RPY (roll/pitch/yaw). The teach pendant displays RPY in degrees, which is a different representation. Values you see on the pendant won't match `get_current_point()` directly.
|
|
510
589
|
|
|
511
590
|
#### Offsets
|
|
512
591
|
|
|
@@ -523,8 +602,8 @@ robot.move_to("pick", offset=[0, 0, 0.05, 0, 0.1, 0]) # full with rotation
|
|
|
523
602
|
Get a pose without moving. Useful for logging, comparisons, or custom motion:
|
|
524
603
|
|
|
525
604
|
```python
|
|
526
|
-
|
|
527
|
-
|
|
605
|
+
point = robot.get_point("pick")
|
|
606
|
+
point = robot.get_point("pick", offset=[0, 0, 0.05, 0, 0, 0]) # with offset
|
|
528
607
|
robot.move_to(pose) # move to the resolved pose later
|
|
529
608
|
```
|
|
530
609
|
|
|
@@ -540,11 +619,11 @@ robot.move_relative(delta_z=0.05) # 5cm along tool Z
|
|
|
540
619
|
- **BASE** (default): delta relative to robot base
|
|
541
620
|
- **TOOL**: delta relative to TCP orientation
|
|
542
621
|
|
|
543
|
-
#### IK Reference
|
|
622
|
+
#### IK Reference
|
|
544
623
|
|
|
545
624
|
**Problem:** When the robot has multiple valid joint configurations to reach the same TCP pose (e.g., elbow up vs. elbow down), it can unexpectedly flip its posture between moves. This is called an **IK ambiguity** and it causes "weird" movements where the robot takes a strange path or flips its wrist.
|
|
546
625
|
|
|
547
|
-
**Solution:** Set an **IK reference posture
|
|
626
|
+
**Solution:** Set an **IK reference posture**, a saved point that defines your preferred arm configuration. The robot then stays close to that posture for all moves.
|
|
548
627
|
|
|
549
628
|
```python
|
|
550
629
|
# 1. Put the robot in your preferred posture (e.g., "home")
|
|
@@ -552,7 +631,7 @@ robot.move_relative(delta_z=0.05) # 5cm along tool Z
|
|
|
552
631
|
# 3. Set as IK reference:
|
|
553
632
|
robot.ik_reference = "home"
|
|
554
633
|
|
|
555
|
-
# Now all moves stay close to that posture
|
|
634
|
+
# Now all moves stay close to that posture, no elbow flipping
|
|
556
635
|
robot.move_to("pick")
|
|
557
636
|
robot.move_to("place")
|
|
558
637
|
robot.move_relative(delta_z=-0.05)
|
|
@@ -565,7 +644,7 @@ robot_ip: 192.168.1.50
|
|
|
565
644
|
ik_reference: home # prevents weird elbow/wrist flips
|
|
566
645
|
```
|
|
567
646
|
|
|
568
|
-
**How it works:** The robot's inverse kinematics solver uses the reference posture as a bias (`qnear`). The TCP still reaches the exact same pose, but the arm configuration (elbow up/down, wrist orientation) stays consistent with your reference.
|
|
647
|
+
**How it works:** The robot's inverse kinematics solver uses the reference posture as a bias (`qnear`). The TCP still reaches the exact same pose, but the arm configuration (elbow up/down, wrist orientation) stays consistent with your reference. Under the hood, poses are resolved to joint angles and sent as `moveJ` instead of `moveL`.
|
|
569
648
|
|
|
570
649
|
**Per-move override:**
|
|
571
650
|
|
|
@@ -575,11 +654,16 @@ robot.move_to("weird_pose", ik_reference=None) # one move without it
|
|
|
575
654
|
robot.move_to("back", ik_reference="current") # use current joints
|
|
576
655
|
```
|
|
577
656
|
|
|
578
|
-
**When to use it:**
|
|
657
|
+
**When to use it:**
|
|
658
|
+
|
|
659
|
+
- **Use it** for sequences of positional moves between waypoints: pick/place paths, assembly sequences, anything where the robot travels between distant points. It prevents elbow/wrist flipping.
|
|
660
|
+
- **Don't use it** for rotation-heavy movements (orientation adjustments, fine-tuning angles). The `qnear` seed can push joints into unexpected configs for pure rotations, and you lose the controller's native Cartesian trajectory planner (lookahead, smoothing). Set `ik_reference=None` for these moves.
|
|
661
|
+
|
|
662
|
+
Default is `None` (controller handles IK natively). Set it globally when most of your moves are positional, and override per-move when you need rotations.
|
|
579
663
|
|
|
580
664
|
#### Point Management
|
|
581
665
|
|
|
582
|
-
Points are stored in the active TCP frame, so they work with any tool
|
|
666
|
+
Points are stored in the active TCP frame, so they work with any tool. Swap grippers and your saved points stay valid.
|
|
583
667
|
|
|
584
668
|
```python
|
|
585
669
|
robot.save_point("here")
|
|
@@ -598,42 +682,32 @@ robot.move_relative(delta_z=0.05, frame=MoveFrame.TOOL) # 5cm along tool Z
|
|
|
598
682
|
robot.move_relative([0, 0.01, 0, 0, 0, 0]) # full 6-element delta
|
|
599
683
|
```
|
|
600
684
|
|
|
601
|
-
Individual delta parameters (`delta_x`, `delta_y`, `delta_z`, `delta_rx`, `delta_ry`, `delta_rz`) are mutually exclusive with the `delta` list
|
|
685
|
+
Individual delta parameters (`delta_x`, `delta_y`, `delta_z`, `delta_rx`, `delta_ry`, `delta_rz`) are mutually exclusive with the `delta` list. Use one or the other.
|
|
602
686
|
|
|
603
687
|
#### Sequences
|
|
604
688
|
|
|
605
689
|
```python
|
|
606
|
-
|
|
607
|
-
robot.
|
|
608
|
-
robot.
|
|
690
|
+
# Both styles work:
|
|
691
|
+
robot.move_sequence("a", "b", "c") # variadic
|
|
692
|
+
robot.move_sequence(["a", "b", "c"]) # list
|
|
609
693
|
```
|
|
610
694
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
#### Sequences
|
|
614
|
-
|
|
615
|
-
```python
|
|
616
|
-
# Chain multiple moves into one call
|
|
617
|
-
robot.move_sequence(["a", "b", "c"])
|
|
618
|
-
```
|
|
695
|
+
`move_sequence` builds a path from all targets and executes it in a single call with blending. Requires at least 2 targets. Two modes:
|
|
619
696
|
|
|
620
|
-
With
|
|
697
|
+
**With `ik_reference`** (positional paths): All poses resolve to joints using chained inverse kinematics. The first pose resolves relative to the reference, the second relative to the first's resolved joints, and so on. Executed as a single `moveJ(path)` call. Keeps the arm configuration consistent (no elbow flipping):
|
|
621
698
|
|
|
622
699
|
```python
|
|
623
700
|
robot.ik_reference = "home"
|
|
624
|
-
robot.move_sequence(["a", "b", "c"]) #
|
|
701
|
+
robot.move_sequence(["a", "b", "c"], blend_radius=0.02) # 2cm blend
|
|
625
702
|
```
|
|
626
703
|
|
|
627
|
-
|
|
704
|
+
**Without `ik_reference`** (Cartesian path): Builds a blended `moveL(path)`. The controller handles IK natively, better for rotation-heavy sequences where `ik_reference` causes unexpected joint behavior:
|
|
628
705
|
|
|
629
706
|
```python
|
|
630
|
-
robot.move_sequence(
|
|
631
|
-
["a", "b", "c"],
|
|
632
|
-
blend_radius=0.02, # 2cm blend between waypoints
|
|
633
|
-
)
|
|
707
|
+
robot.move_sequence(["a", "b", "c"], blend_radius=0.02) # blended Cartesian path
|
|
634
708
|
```
|
|
635
709
|
|
|
636
|
-
|
|
710
|
+
Before sending any move, it checks that each pose has a valid IK solution. Unreachable poses raise `MotionError`. If a named point doesn't exist, it raises `PointError` instead of silently falling back.
|
|
637
711
|
|
|
638
712
|
#### Contact Detection
|
|
639
713
|
|
|
@@ -657,7 +731,7 @@ robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2)
|
|
|
657
731
|
for _ in range(3):
|
|
658
732
|
if robot.move_until_contact(speed_z=-0.02, timeout=10.0, max_distance=0.2):
|
|
659
733
|
break # contact detected
|
|
660
|
-
# No contact
|
|
734
|
+
# No contact, back off and retry
|
|
661
735
|
robot.move_relative(delta_z=0.01)
|
|
662
736
|
|
|
663
737
|
# Manual zero (e.g. before custom force-based logic)
|
|
@@ -676,33 +750,36 @@ robot.move_velocity([0, 0, -0.02, 0, 0, 0], duration=1.0)
|
|
|
676
750
|
from urkit import FreedriveMode
|
|
677
751
|
|
|
678
752
|
robot.enable_freedrive() # all 6 axes free
|
|
679
|
-
robot.enable_freedrive(FreedriveMode.XYZ) # linear axes
|
|
680
|
-
robot.enable_freedrive(FreedriveMode.ROTATION) # rotation only
|
|
753
|
+
robot.enable_freedrive(FreedriveMode.XYZ) # linear axes only (X, Y, Z)
|
|
754
|
+
robot.enable_freedrive(FreedriveMode.ROTATION) # rotation only (Roll, Pitch, Yaw)
|
|
755
|
+
robot.enable_freedrive([1, 1, 1, 1, 0, 0]) # custom: X+Y+Z+Roll+Pitch
|
|
681
756
|
robot.disable_freedrive() # disable before sending motion commands
|
|
682
757
|
robot.is_freedrive_active # check state
|
|
683
758
|
```
|
|
684
759
|
|
|
760
|
+
**Teach pendant:** Press `F` to toggle freedrive (ALL ↔ XYZ). Press `3` to open the axis selection menu arrow keys navigate, space toggles each axis on/off, enter applies.
|
|
761
|
+
|
|
685
762
|
#### Speed Control
|
|
686
763
|
|
|
687
764
|
```python
|
|
688
765
|
robot.stop() # stop current move immediately (stopL + stopJ)
|
|
689
766
|
robot.speed_stop() # stop velocity-controlled motion (not E-stop)
|
|
690
|
-
robot.
|
|
691
|
-
robot.
|
|
767
|
+
robot.speed_slider = 0.5 # 50% velocity cap
|
|
768
|
+
robot.speed_slider # read current slider (0.0-1.0)
|
|
692
769
|
```
|
|
693
770
|
|
|
694
771
|
The speed slider controls the pendant's speed multiplier. It's global, persistent, and affects all motion commands.
|
|
695
772
|
|
|
696
773
|
#### Changing Default Speed & Acceleration
|
|
697
774
|
|
|
698
|
-
Override the constructor defaults at runtime
|
|
775
|
+
Override the constructor defaults at runtime. All subsequent moves pick up the new values:
|
|
699
776
|
|
|
700
777
|
```python
|
|
701
|
-
robot.
|
|
778
|
+
robot.default_vel = 0.1 # slow for precision work
|
|
702
779
|
robot.move_to("insert")
|
|
703
|
-
robot.
|
|
780
|
+
robot.default_vel = 0.5 # back to normal
|
|
704
781
|
|
|
705
|
-
robot.
|
|
782
|
+
robot.default_acc = 0.05 # gentle acceleration
|
|
706
783
|
|
|
707
784
|
robot.default_vel # read current velocity (m/s)
|
|
708
785
|
robot.default_acc # read current acceleration (m/s²)
|
|
@@ -717,16 +794,14 @@ joints = robot.inverse_kinematics([0.5, 0, 0.3, 0, 0, 0])
|
|
|
717
794
|
### Telemetry
|
|
718
795
|
|
|
719
796
|
```python
|
|
720
|
-
pose = robot.
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
robot.
|
|
726
|
-
robot.is_protective_stopped()
|
|
727
|
-
robot.is_emergency_stopped()
|
|
728
|
-
robot.is_remote_mode() # bool — check remote control state
|
|
729
|
-
robot.get_polyscope_version() # e.g. "5.25.0" or None
|
|
797
|
+
pose = robot.get_current_point() # [x, y, z, rx, ry, rz]
|
|
798
|
+
pose = robot.get_current_point(offset_z=0.05) # with offset
|
|
799
|
+
joints = robot.get_joint_positions() # [j0..j5]
|
|
800
|
+
force = robot.get_tcp_force() # [fx, fy, fz, mx, my, mz]
|
|
801
|
+
mode = robot.get_robot_mode() # "REMOTE_CONTROL", "SERVOING", etc.
|
|
802
|
+
payload = robot.payload # kg
|
|
803
|
+
robot.is_protective_stopped() # bool
|
|
804
|
+
robot.is_emergency_stopped() # bool
|
|
730
805
|
```
|
|
731
806
|
|
|
732
807
|
#### Arrival Detection
|
|
@@ -744,7 +819,7 @@ while robot.is_moving():
|
|
|
744
819
|
while robot.is_moving(position_tolerance=0.001, orientation_tolerance=0.017):
|
|
745
820
|
time.sleep(0.01)
|
|
746
821
|
|
|
747
|
-
# Joint moves
|
|
822
|
+
# Joint moves, tighter joint tolerance
|
|
748
823
|
while robot.is_moving(joint_tolerance=0.001):
|
|
749
824
|
time.sleep(0.01)
|
|
750
825
|
```
|
|
@@ -825,7 +900,7 @@ The constructor handles all of this automatically. Use these methods when you ne
|
|
|
825
900
|
TCP and payload can be set manually (gripper presets do this automatically):
|
|
826
901
|
|
|
827
902
|
```python
|
|
828
|
-
robot.
|
|
903
|
+
robot.tcp_offset = [0, 0, 0.15, 0, 0, 0]
|
|
829
904
|
robot.set_payload(1.5, [0, 0, 0.05]) # mass (kg), center of gravity [x, y, z]
|
|
830
905
|
```
|
|
831
906
|
|