Metadata-Version: 2.3
Name: pylekiwi
Version: 0.13.2
Summary: Python package for controlling the LeKiwi robot
Author: neka-nat
Author-email: neka-nat <nekanat.stock@gmail.com>
Requires-Dist: eclipse-zenoh>=1.5.1
Requires-Dist: gunicorn>=23.0.0
Requires-Dist: kinpy>=0.5.6
Requires-Dist: loguru>=0.7.3
Requires-Dist: mesop>=1.1.0
Requires-Dist: numpy>=1.26.4
Requires-Dist: opencv-python-headless>=4.11.0.86
Requires-Dist: pydantic>=2.11.10
Requires-Dist: rustypot>=1.3.0
Requires-Dist: typer>=0.19.2
Requires-Dist: pynput>=1.8.1 ; extra == 'client'
Requires-Dist: rerun-sdk>=0.28.1 ; extra == 'client'
Requires-Python: >=3.11
Provides-Extra: client
Description-Content-Type: text/markdown

# pylekiwi
[![PyPI version](https://badge.fury.io/py/pylekiwi.svg)](https://badge.fury.io/py/pylekiwi)

Python package for controlling the LeKiwi robot.

![lekiwi](assets/lekiwi.jpg)

## Quick Start

### Web UI

Log into the robot and run the following command:

```bash
ssh <your robot ip>
sudo chmod 666 <your_follower_robot_serial_port>
uvx pylekiwi webui --serial-port <your_follower_robot_serial_port>
```

Then, open a web browser and navigate to `http://<your robot ip>:8080` to see the web UI.

![web ui](assets/webui.png)

### Leader and Follower/Client Nodes

Run the following command to start the follower node (host) on the robot (Respberry Pi):

```bash
ssh <your robot ip>
sudo chmod 666 <your_follower_robot_serial_port>
uvx pylekiwi host --serial-port <your_follower_robot_serial_port>
```

The host defaults to camera index `0` for `base` and `2` for `arm`. If the
images are swapped, specify the assignments when starting the host:

```bash
uvx pylekiwi host --serial-port <your_follower_robot_serial_port> --base-camera-id 2 --arm-camera-id 0
```

Both options also accept device paths. On Linux, use the actual links under
`/dev/v4l/by-id/` to keep the assignments when `/dev/videoN` numbering changes.
If identical cameras do not have unique IDs, use `/dev/v4l/by-path/` links and
keep each camera connected to the same USB port:

```bash
ls -l /dev/v4l/by-id/ /dev/v4l/by-path/
uvx pylekiwi host --serial-port <your_follower_robot_serial_port> \
  --base-camera-id /dev/v4l/by-id/<base-camera-link> \
  --arm-camera-id /dev/v4l/by-id/<arm-camera-link>
```

Run the following command to start the leader node (client) on the remote machine:

```bash
sudo chmod 666 <your_leader_robot_serial_port>
uvx --from 'pylekiwi[client]' pylekiwi leader --serial-port <your_leader_robot_serial_port>
```

Use `pylekiwi client` on the remote machine for one-off remote operations without
starting the continuous `leader` controller.

Available command groups:

- `state`: read the current remote robot state
- `capture`: save one JPEG from the `base` or `arm` camera
- `pose`: go to, save, list, or delete named arm poses
- `position` / `inching`: move the end effector in the base frame
- `grasp` / `release`: close or open the gripper
- `arm`: inspect modeled link frames or toggle arm torque
- `calibrate`: inspect, back up, zero, or restore remote arm calibration

Common examples:

Inspect state or capture images:

```bash
uvx pylekiwi client state
uvx pylekiwi client capture --camera base --output photo.jpg
uvx pylekiwi client capture --camera arm --output wrist.jpg
```

Move the arm or gripper:

```bash
uvx pylekiwi client pose go <preset_name>
uvx pylekiwi client pose go "10,20,30,40,50"
uvx pylekiwi client position --x-mm 180 --y-mm 0 --z-mm 120
uvx pylekiwi client inching --x-mm 10 --z-mm -5
uvx pylekiwi client grasp
uvx pylekiwi client release
```

Manage presets or maintenance:

```bash
uvx pylekiwi client pose save <name>
uvx pylekiwi client pose list
uvx pylekiwi client pose delete <name>
uvx pylekiwi client arm off
uvx pylekiwi client arm on
uvx pylekiwi client calibrate status
uvx pylekiwi client calibrate backup
```

Inspect modeled frames:

```bash
uvx pylekiwi client arm links actual --frame lekiwi_chassis
uvx pylekiwi client arm links actual --frame lekiwi_base_camera_mount
uvx pylekiwi client arm links actual --frame lekiwi_base_camera_optical
uvx pylekiwi client arm links actual --frame wrist_camera_mount
```

The `lekiwi_chassis` and `lekiwi_base_camera_mount` frames are now seeded from the
public LeKiwi CAD/URDF rather than placeholders. `lekiwi_base_camera_mount` tracks
the upstream CAD camera-body link, and `lekiwi_base_camera_optical` adds an
approximate lens-center frame derived from the CAD mesh.

Referenced LeKiwi CAD sources:
- Public Fusion 360 CAD: <https://a360.co/4k1P8yO>
- Upstream LeKiwi URDF exported from CAD: <https://github.com/SIGRobotics-UIUC/LeKiwi/blob/main/URDF/LeKiwi.urdf>

If automatic discovery does not work across machines, you can connect explicitly to the robot:

```bash
# On the robot (Raspberry Pi)
uvx pylekiwi host --serial-port <your_follower_robot_serial_port> --listen-host 0.0.0.0 --listen-port 7447

# On the remote machine, add --host/--port before the client subcommand
uvx --from 'pylekiwi[client]' pylekiwi leader --serial-port <your_leader_robot_serial_port> --host <your robot ip> --port 7447
uvx pylekiwi client --host <your robot ip> --port 7447 state
uvx pylekiwi client --host <your robot ip> --port 7447 capture --camera base --output photo.jpg
uvx pylekiwi client --host <your robot ip> --port 7447 position --x-mm 180 --y-mm 0 --z-mm 120
```

For timestamped camera observations, command expiry, and IK usage, see
[Robot control](docs/robot-control.md).
