This release is a pre-release and may not be stable for production use.
TacStack
English | 简体中文
Cross-sensor tactile semantics and runtime for robotics. TacStack keeps raw tactile data intact and layers a unified Observation, model interface and Event contract on top, steadily lowering the cost of bringing up and using different tactile sensors.
Status: Phase 4 done / Phase 5 (first live sensor) in preparation. The
offline loop works end to end — dataset → TactileObservation → MCAP / Rerun
replay → contact / slip events (builtin or ONNX scoring) → benchmark report.
Observation streams export to and replay from LeRobot v3.0 dataset directories
(taxel features), riding that ecosystem's tooling directly. Protocol layers
for five real sensors are implemented and tested offline
(Verified sensor protocols): four serial codecs
verified byte-for-byte against their vendor manuals, plus the Meta DIGIT
vision-tactile identity / semantics layer. Live adapters land with the
hardware (Phase 5). ROS2 integration is not implemented yet; the
bundled dataset fixture is synthetic (tests/fixtures/README.md).
Getting started
Requires Python 3.12+ and uv. Install from source for now; no PyPI package yet.
git clone https://github.com/mailes/TacStack.git
cd TacStack
uv sync
uv run tacstack version
uv run tacstack contract-demo
uv run tacstack demo
uv run python examples/contract_demo.py
contract-demo prints one JSON event flagged synthetic: true. It downloads no
data and touches no hardware.
The same Observation contract also replays real Open-X-Tactile episodes from a local tar or extracted directory (CI and the example below use only the bundled synthetic fixture):
uv run tacstack dataset list tests/fixtures/open_x_tactile/demo_wipe.tar
uv run tacstack dataset inspect tests/fixtures/open_x_tactile/demo_wipe.tar --task Wipe_Demo --episode 0
uv run tacstack dataset convert tests/fixtures/open_x_tactile/demo_wipe.tar --task Wipe_Demo --episode 0 --out demo.mcap
uv run python examples/replay_open_x_tactile.py
from tacstack import TactileEvent
sample = TactileEvent(
timestamp_ns=0,
sensor_id="synthetic",
kind="contact_begin",
probability=1.0,
model_id="contract-example",
latency_ms=0.0,
)
Verified sensor protocols
Five real sensor protocol layers ship hardware-free. Four are pure codec layers — frame building and parsing, checksums, register decoding — verified byte-for-byte against the worked example frames in their vendor manuals. The fifth is the Meta DIGIT vision-tactile layer: device identity, raw-frame to observation mapping and reference-frame contact / slip tracking. All are pinned by unit tests with no hardware required. Live capture adapters plus live record / replay / inference are the Phase 5 deliverables once the hardware arrives.
| Sensor | Output | Link | Codec | Notes |
|---|---|---|---|---|
| M0404S serial matrix kit | 4×4 resistive matrix, 16 taxels | UART 115200 8N1, active push | adapters/real_sensor/m0404s.py |
35-byte frames, additive checksum |
| PaXini PX-6AX GEN3 | per-point 3-axis force + resultant, 0.1 N/LSB | UART 921600, request–response | adapters/real_sensor/paxini.py |
register protocol, two's-complement LRC |
| PaXini PX6D | six-axis F/T wrench (Fx, Fy, Fz, Mx, My, Mz), float32 | USB / RS485 (CAN shares the command set) | adapters/real_sensor/px6d.py |
auto-report up to 1 kHz; request CRC8 recovered from manual samples |
| PaXini PX3Q | 3-axis joint torque Mx / My / Mz in N·m (30 / 50 / 100 N·m full scale by model) | USB / RS485, 921600 8N1 | adapters/real_sensor/px3q.py |
1 kHz sampling; CAN envelope documented but deferred, USB-first |
| Meta DIGIT | 320×240 RGB gel image (vision-based tactile) | USB UVC, QVGA 60 fps (default) / VGA 30 fps | adapters/real_sensor/digit.py |
open hardware; identity + semantics layer, live capture lands with hardware |
Request-frame checksums are pinned by the manuals' example frames. Where a rule cannot be recovered from documentation alone (the response-frame CRC on PX6D / PX3Q), parsing stays lenient and the open gap is recorded in the module docstring until captured hardware traffic settles it. Selection criteria and buy-time caveats live in docs/plans/sensor-procurement.zh-CN.md.
Project layout
src/tacstack/
core/ # data structures, basic validation, debug serialization
adapters/ # base protocol; open_x_tactile + mcap replay + real_sensor codecs + DIGIT semantics implemented
runtime/ # model protocol; buffer / ONNX backend reserved
models/ # contact / slip reserved
integrations/ # MCAP export + Rerun replay + LeRobot v3.0 dataset export implemented; ROS2 reserved
benchmark/ # evaluation tooling reserved
cli/ # version / contract-demo / dataset / replay / annotate / model run / benchmark
examples/ # runnable contract_demo and replay_open_x_tactile
tests/ # unit / integration / fixtures
docs/ # architecture, interfaces, roadmap, ADR (Chinese for now)
scripts/ # development tools (fixture generator)
.github/workflows/ci.yml
Development checks
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest -m "not hardware"
uv build
uv run pre-commit install
Next steps
- Bring up the first real sensor end to end — live adapter, live record / replay / inference, 30-minute stability (Phase 5).
- Docs, external Quickstart and the v0.1 release (Phase 6).
Runnable walkthroughs: Tutorial 1 - offline pipeline and Tutorial 2 - visualize & annotate. See also the roadmap, architecture, concepts, adapter guide, runtime, benchmark and the contribution guide. Most of these docs are Chinese for now; English translations will follow before the v0.1 release.
Principles and license
Raw-first · Semantics-first · Edge-first · Integration-first. Core depends on neither ROS2, cloud services nor training frameworks; reuse the existing storage and visualization ecosystems.
Apache-2.0, see LICENSE. Dataset, model and third-party SDK licenses must be verified separately.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tacstack-0.1.0a1.tar.gz.
File metadata
- Download URL: tacstack-0.1.0a1.tar.gz
- Upload date:
- Size: 1.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be66f2c0024fc00f012649352385343290574e67ac9ca46d734d5151e59b5f38
|
|
| MD5 |
c9ec22e69c743a922f6ff33f854791ca
|
|
| BLAKE2b-256 |
c2b30852331e6e27616314804286bb80c6b8faa8da948be69c63acec110f4fe4
|
Provenance
The following attestation bundles were made for tacstack-0.1.0a1.tar.gz:
Publisher:
publish.yml on mailes/TacStack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tacstack-0.1.0a1.tar.gz -
Subject digest:
be66f2c0024fc00f012649352385343290574e67ac9ca46d734d5151e59b5f38 - Sigstore transparency entry: 2758097501
- Sigstore integration time:
-
Permalink:
mailes/TacStack@13729ce80129427abe5c213c911f3ff1aa138ad6 -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/mailes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@13729ce80129427abe5c213c911f3ff1aa138ad6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tacstack-0.1.0a1-py3-none-any.whl.
File metadata
- Download URL: tacstack-0.1.0a1-py3-none-any.whl
- Upload date:
- Size: 79.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59002f2fc31c708e7baba44443c3bd0e8a62ea74a36c80f27d2e8a85ae278939
|
|
| MD5 |
31490c4a661aa5c19f6a6816838f2ed0
|
|
| BLAKE2b-256 |
82cb5be4fdfc746c286ed7c27bac3726791c54e84318137c163d360212a4879b
|
Provenance
The following attestation bundles were made for tacstack-0.1.0a1-py3-none-any.whl:
Publisher:
publish.yml on mailes/TacStack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tacstack-0.1.0a1-py3-none-any.whl -
Subject digest:
59002f2fc31c708e7baba44443c3bd0e8a62ea74a36c80f27d2e8a85ae278939 - Sigstore transparency entry: 2758097631
- Sigstore integration time:
-
Permalink:
mailes/TacStack@13729ce80129427abe5c213c911f3ff1aa138ad6 -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/mailes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@13729ce80129427abe5c213c911f3ff1aa138ad6 -
Trigger Event:
push
-
Statement type: