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.
Files changed (41) hide show
  1. {urkit-0.3.26 → urkit-0.4.1}/PKG-INFO +140 -65
  2. {urkit-0.3.26 → urkit-0.4.1}/README.md +139 -64
  3. {urkit-0.3.26 → urkit-0.4.1}/pyproject.toml +1 -1
  4. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/__init__.py +1 -1
  5. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/__main__.py +22 -1
  6. urkit-0.4.1/src/urkit/cli/init.py +83 -0
  7. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/teach.py +146 -32
  8. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/motion.py +34 -14
  9. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/robot.py +232 -292
  10. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/telemetry.py +0 -16
  11. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/PKG-INFO +140 -65
  12. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/SOURCES.txt +1 -0
  13. {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper_presets.py +1 -1
  14. {urkit-0.3.26 → urkit-0.4.1}/tests/test_move_sequence.py +49 -38
  15. {urkit-0.3.26 → urkit-0.4.1}/tests/test_robot_integration.py +17 -23
  16. {urkit-0.3.26 → urkit-0.4.1}/setup.cfg +0 -0
  17. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/__init__.py +0 -0
  18. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/colors.py +0 -0
  19. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/connection_monitor.py +0 -0
  20. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/cli/points.py +0 -0
  21. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/config.py +0 -0
  22. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/connection.py +0 -0
  23. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/exceptions.py +0 -0
  24. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/geometry.py +0 -0
  25. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/__init__.py +0 -0
  26. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/base.py +0 -0
  27. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/digital.py +0 -0
  28. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/presets.py +0 -0
  29. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/robotiq.py +0 -0
  30. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/gripper/robotiq_preamble.py +0 -0
  31. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/io.py +0 -0
  32. {urkit-0.3.26 → urkit-0.4.1}/src/urkit/points.py +0 -0
  33. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/dependency_links.txt +0 -0
  34. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/entry_points.txt +0 -0
  35. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/requires.txt +0 -0
  36. {urkit-0.3.26 → urkit-0.4.1}/src/urkit.egg-info/top_level.txt +0 -0
  37. {urkit-0.3.26 → urkit-0.4.1}/tests/test_exceptions.py +0 -0
  38. {urkit-0.3.26 → urkit-0.4.1}/tests/test_geometry.py +0 -0
  39. {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper.py +0 -0
  40. {urkit-0.3.26 → urkit-0.4.1}/tests/test_gripper_factory.py +0 -0
  41. {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.26
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
  [![PyPI](https://img.shields.io/pypi/v/urkit.svg)](https://pypi.org/project/urkit/)
30
30
 
31
- **URKit** is a Python toolkit for [Universal Robots](https://www.universal-robots.com/) e-Series robots that makes the common stuff simple and gets out of the way for everything else.
31
+ **URKit** makes it easy to get a Universal Robots e-Series robot moving from Python.
32
32
 
33
- Built on [`ur_rtde`](https://sdurobotics.gitlab.io/ur_rtde/), it packages the operations you reach for most: connecting, moving to named points, gripper control, telemetry, and I/O, while exposing the raw RTDE interfaces for anything deeper.
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 — this project is in early development and changes frequently.
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**: `☰` → `System` → `System` → `Network`. Set a static IP on the robot and a matching one on your PC. Both addresses must share the same first three octets (the network), with a different last octet (the host). For example:
80
- - **Robot**: `192.168.1.50` / Subnet `255.255.255.0`
81
- - **PC**: `192.168.1.1` / Netmask `255.255.255.0`
82
- - Verify with `ping 192.168.1.50`. Connect via direct Ethernet cable or a switch.
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. **Teach points.** Use the CLI to position the robot and save named waypoints.
108
- 2. **Write code.** Create a robot, move to points by name, apply offsets, run sequences.
109
- 3. **Iterate.** Add more points, tweak your code, repeat.
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
- URKit searches for `config.yaml` in the current working directory, or an explicit path via `--config`.
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 two CLI tools: **teach** for interactive robot control, and **points** for browsing saved waypoints.
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 (OFF → ALL → XYZ+Rz)</td></tr>
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 — Space cancels the move and returns to the menu.
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 `get_tcp_pose()` directly.
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
- pose = robot.get_pose("pick")
527
- pose = robot.get_pose("pick", offset=[0, 0, 0.05, 0, 0, 0]) # with offset
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 (recommended)
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** — a saved point that defines your preferred arm configuration. The robot then stays close to that posture for all moves.
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 — no elbow flipping
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:** Almost always. If you've ever seen the robot move in a way that looked "wrong" or flipped its elbow unexpectedly, this is what fixes it. Set it once in config.yaml and forget about 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 — swap grippers and your saved points stay valid.
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 — use one or the other.
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
- robot.move_relative(delta_y=0.01) # 1cm along Y
607
- robot.move_relative(delta_z=0.05, frame=MoveFrame.TOOL) # 5cm along tool Z
608
- robot.move_relative([0, 0.01, 0, 0, 0, 0]) # full 6-element delta
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
- 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.
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 **IK reference** (recommended), 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. This keeps the arm configuration consistent throughout the sequence:
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"]) # chained IK, no elbow flipping
701
+ robot.move_sequence(["a", "b", "c"], blend_radius=0.02) # 2cm blend
625
702
  ```
626
703
 
627
- With **blend_radius**, the robot rounds corners instead of stopping at each waypoint:
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
- `move_sequence` requires at least 2 targets. Without `ik_reference`, it falls back to individual `moveL` calls (legacy behavior, no blending).
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 — back off and retry
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 + Rz rotation
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.set_speed_slider(0.5) # 50% velocity cap
691
- robot.get_speed_slider() # read current slider (0.0-1.0)
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 — all subsequent moves pick up the new values:
775
+ Override the constructor defaults at runtime. All subsequent moves pick up the new values:
699
776
 
700
777
  ```python
701
- robot.set_speed(0.1) # slow for precision work
778
+ robot.default_vel = 0.1 # slow for precision work
702
779
  robot.move_to("insert")
703
- robot.set_speed(0.5) # back to normal
780
+ robot.default_vel = 0.5 # back to normal
704
781
 
705
- robot.set_acc(0.05) # gentle acceleration
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.get_tcp_pose() # [x, y, z, rx, ry, rz]
721
- joints = robot.get_joint_positions() # [j0..j5]
722
- force = robot.get_tcp_force() # [fx, fy, fz, mx, my, mz]
723
- mode = robot.get_robot_mode() # "REMOTE_CONTROL", "SERVOING", etc.
724
- payload = robot.get_payload() # kg
725
- robot.current_point() # {"pose": [...], "joints": [...]}
726
- robot.is_protective_stopped() # bool
727
- robot.is_emergency_stopped() # bool
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 — tighter joint tolerance
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.set_tcp_offset([0, 0, 0.15, 0, 0, 0])
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