Metadata-Version: 2.4
Name: hex_util_msg
Version: 0.0.1a3
Summary: HEXFELLOW Util Message
Author-email: Dong Zhaorui <dzr159@gmail.com>
Maintainer-email: jecjune <zejun.chen@hexfellow.com>, Dong Zhaorui <dzr159@gmail.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/hexfellow/hex_util_msg
Project-URL: Repository, https://github.com/hexfellow/hex_util_msg.git
Project-URL: Bug Tracker, https://github.com/hexfellow/hex_util_msg/issues
Project-URL: Documentation, https://github.com/hexfellow/hex_util_msg/wiki
Keywords: hex,util,message
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: flatbuffers>=25.0.0
Requires-Dist: numpy>=2.0.0
Dynamic: license-file

# hex_util_msg

[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](LICENSE)

HEXFELLOW utility message library — a set of [FlatBuffers](https://flatbuffers.dev/) message definitions and Python builder/parser helpers for robotics, teleoperation, and image transport.

## Features

- **Zero-copy deserialization** via FlatBuffers for high-performance message passing
- **Four message namespaces**: `msg_basic`, `msg_robot`, `msg_image`, `msg_teleop`
- **High-level builder API**: `build_*` / `parse_*` function pairs that convert between `bytes` and plain Python `dict` / `numpy` objects
- **NumPy integration**: array fields are serialized and deserialized as `numpy` arrays

## Installation

```bash
pip install hex_util_msg
```

Or install from source in editable mode:

```bash
git clone https://github.com/hexfellow/hex_util_msg.git
cd hex_util_msg
pip install -e .
```

### Dependencies

| Package | Version |
|---------|---------|
| `flatbuffers` | >= 25.0.0 |
| `numpy` | >= 2.0.0 |

## Quick Start

### Basic Types

```python
from hex_util_msg.builder_basic import (
    build_hex_float64, parse_hex_float64,
    build_hex_string, parse_hex_string,
    build_hex_float64_array, parse_hex_float64_array,
)

# Scalar
buf = build_hex_float64(ts_ns=1_000_000, data=3.14)
msg = parse_hex_float64(buf)
# msg == {"ts_ns": 1000000, "data": 3.14}

# String
buf = build_hex_string(ts_ns=1_000_000, data="hello")
msg = parse_hex_string(buf)
# msg == {"ts_ns": 1000000, "data": "hello"}

# Array
buf = build_hex_float64_array(ts_ns=1_000_000, data=[1.0, 2.0, 3.0])
msg = parse_hex_float64_array(buf)
# msg == {"ts_ns": 1000000, "data": array([1., 2., 3.])}
```

### Robot Messages

```python
import numpy as np
from hex_util_msg.builder_robot import (
    build_hex_arm_state, parse_hex_arm_state,
    build_hex_arm_ctrl, parse_hex_arm_ctrl,
)
from hex_util_msg.msg_robot import HexArmCtrlMode

# Build arm state
buf = build_hex_arm_state(
    ts_ns=123,
    jnt={"pos": [0.0, 0.25, 0.5], "vel": [0.0, 0.0, 0.0], "eff": None},
    pose={"px": 1.0, "py": 2.0, "pz": 3.0, "qx": 0.0, "qy": 0.0, "qz": 0.707, "qw": 0.707},
)
state = parse_hex_arm_state(buf)

# Build arm control
buf = build_hex_arm_ctrl(
    ts_ns=999,
    ctrl_mode=HexArmCtrlMode.mit,
    jnt={"pos": np.zeros(6), "vel": np.zeros(6), "eff": None},
    mit_tau=np.zeros(6),
    mit_kp=np.full(6, 100.0),
    mit_kd=np.full(6, 10.0),
)
ctrl = parse_hex_arm_ctrl(buf)
```

### Image Messages

```python
import numpy as np
from hex_util_msg.builder_image import build_hex_image_simple, parse_hex_image_simple
from hex_util_msg.msg_image import HexEncoding

frame = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
buf = build_hex_image_simple(
    ts_ns=1_704_000_000_000_000_000,
    encoding=HexEncoding.bgr8,
    width=640, height=480,
    data=frame,
)
msg = parse_hex_image_simple(buf)
# msg["data"] is a flat uint8 numpy array
```

### Teleop Messages

```python
from hex_util_msg.builder_teleop import (
    build_hex_teleop_joy, parse_hex_teleop_joy,
    build_hex_teleop_keyboard, parse_hex_teleop_keyboard,
)

# Joystick
buf = build_hex_teleop_joy(ts_ns=100, btn_a=True, axis_lx=0.5, axis_ly=-0.3)
joy = parse_hex_teleop_joy(buf)

# Keyboard
buf = build_hex_teleop_keyboard(ts_ns=200, key_w=True, key_a=True)
kb = parse_hex_teleop_keyboard(buf)
```

## Message Namespaces

### `msg_basic` — Scalar & Array Primitives

Every basic message carries a `ts_ns` timestamp and a `data` field.

| Scalar types | Array types |
|---|---|
| `HexBool` | `HexBoolArray` |
| `HexInt8` / `HexUint8` | `HexInt8Array` / `HexUint8Array` |
| `HexInt16` / `HexUint16` | `HexInt16Array` / `HexUint16Array` |
| `HexInt32` / `HexUint32` | `HexInt32Array` / `HexUint32Array` |
| `HexInt64` / `HexUint64` | `HexInt64Array` / `HexUint64Array` |
| `HexFloat32` / `HexFloat64` | `HexFloat32Array` / `HexFloat64Array` |
| `HexString` | `HexStringArray` |

### `msg_robot` — Robot State & Control

| Message | Description |
|---|---|
| `HexJnt` | Joint data (pos/vel/eff arrays) |
| `HexPose` | 7-DoF pose struct (px, py, pz, qx, qy, qz, qw) |
| `HexArmState` | Arm state with jnt + pose |
| `HexArmCtrl` | Arm control with ctrl_mode, jnt, pose, MIT/limit params |
| `HexGripState` | Gripper state with jnt |
| `HexGripCtrl` | Gripper control with ctrl_mode, jnt, force, MIT params |
| `HexRgbCtrl` | RGB LED control (r/g/b uint8 arrays) |

**Control modes** (`HexArmCtrlMode`): `mit`, `comp`, `pos`, `pose`, `pos_plan`, `pose_plan`

**Gripper modes** (`HexGripCtrlMode`): `mit`, `pos`, `force`

### `msg_image` — Image Transport

| Message | Description |
|---|---|
| `HexImageSimple` | Image with encoding, dimensions, and raw byte data |

**Encodings** (`HexEncoding`): `bgr8`, `jpg`, `mono16`, `png`

### `msg_teleop` — Teleoperation Input

| Message | Description |
|---|---|
| `HexTeleopHello` | Hello device with trigger, axes (x/y), buttons (w/x/y/z) |
| `HexTeleopJoy` | Joystick with 10 buttons, 6 axes, and hat |
| `HexTeleopKeyboard` | Keyboard with 26 key states (a–z) |

## Project Structure

```
hex_util_msg/
├── hex_util_msg/              # Python package
│   ├── __init__.py
│   ├── builder_basic.py       # build/parse for msg_basic
│   ├── builder_image.py       # build/parse for msg_image
│   ├── builder_robot.py       # build/parse for msg_robot
│   ├── builder_teleop.py      # build/parse for msg_teleop
│   ├── msg_basic/             # generated FlatBuffers code
│   ├── msg_image/             # generated FlatBuffers code
│   ├── msg_robot/             # generated FlatBuffers code
│   └── msg_teleop/            # generated FlatBuffers code
├── msgs/                      # FlatBuffers schema sources (.fbs)
│   ├── msg_basic/
│   ├── msg_image/
│   ├── msg_robot/
│   └── msg_teleop/
├── tests/                     # pytest test suite
├── generate.sh                # regenerate Python code from .fbs schemas
├── pyproject.toml
└── LICENSE
```

## Regenerating Code from Schemas

If you modify `.fbs` files under `msgs/`, regenerate the Python bindings:

```bash
# Requires flatc (FlatBuffers compiler) on PATH
./generate.sh
```

This will remove existing generated directories and re-run `flatc --python` for all namespaces.

## Testing

```bash
pip install pytest
pytest tests/ -v
```

## License

Apache License 2.0 — see [LICENSE](LICENSE) for details.
