Skip to main content

botrail-logo

Beyond motion planning. Build robot cells as code. One source of truth from layout to I/O list — verified deterministically on every change.

Documentation: https://botrail.github.io/botrail/ · Live Demo: https://botrail.github.io/botrail/demo/

botrail-demo botrail-demo-line

pip install botrail, a few lines of Python, and you get an interactive 3D studio in your browser for building robot cells — robots, obstacles, conveyors, sensors, and PLC-style sequences. The core is written in Rust — no ROS, no system dependencies, no GPU.

A cell in botrail is text (Python / .botrail JSON / USD): it diffs in git, it bakes into a bit-identical timeline every run, and it regression-tests in CI. Motions are planned, not taught point by point, so moving a pallet or a sensor doesn't break the cell — re-simulate and read the new cycle time.

Highlights

  • Robots from URDF, Xacro, or USD — including Isaac Sim articulations (bt.Robot.from_usd("franka.usd")), rendered at full visual fidelity with three-usd-robot. Mimic joints (URDF <mimic>, USD PhysxMimicJointAPI) are followed, so a two-finger gripper costs one DOF, not two. Multiple robots per cell, with tick-checked inter-robot collisions and zone interlocks.
  • USD scene import (usda/usdc/usdz, references, variants, instancing) — stages become obstacles and named mount frames, normalized to meters / Z-up.
  • Environments that behave — a PLC-style step sequencer (entry actions + transition conditions on a fixed scan cycle), zone/beam sensors, conveyors and linear axes, and conveyor tracking: taught poses ride the moving part, so the belt never stops for the pick.
  • Deterministic bakesimulate_sequence() turns Scene + Sequence into a bit-identical SequenceTimeline: cycle time, step spans, signal waveforms, object tracks.
  • Assertable timelinesstep_span() / signal() / min_clearance() turn a bake into pytest-able cell checks (cycle budgets, sensor timing, safety margins) that run in CI.
  • Open deliverables — USD animation (plays in usdview / Omniverse / Blender), CSV/JSON, robot programs (URScript), Python code generation — and Isaac Sim recordings play back through the same pipeline.
  • Engineering documents, derived — bill of materials, plan-view layout sheet (SVG / DXF), I/O list and controller topology, and a cell report (cycle times, clearance, I/O counts, scenario matrix, footprint, file digests) all come out of the same script as the simulation, so a layout edit changes exactly the documents it touches — and never lets them disagree.
  • Interactive posing — draggable TCP gizmo with live IK, joint sliders.
  • Collision checking — primitives and STL/OBJ meshes (cached VHACD convex decomposition), live highlighting, clearance readout.
  • Motion planning & authoring — RRT-Connect with time parameterization, waypoint motions with Cartesian-line segments and path constraints, trajectory playback in the studio.
  • Portable projects — save/load .botrail files (meshes and USD stages bundled), regenerate any scene as a Python script.
  • Runs entirely in the browser — the wasm build serves the full studio as a static page, no server; drop a USD file straight into the viewport.

Try it

Run the bundled demos — a Franka Panda in a small USD factory cell (the first run downloads NVIDIA's official Franka asset, ~10 MB):

python examples/demo.py           # interactive studio: pose, plan, play
python examples/sequence_demo.py  # 13-step cell: conveyor feed → tracked pick
                                  # → pallet; prints the cycle time, exports USD
python examples/dual_cell_demo.py # two arms sharing one infeed, arbitrated by a
                                  # zone interlock; --clash shows what happens
                                  # without it
python examples/sweep_demo.py     # parameter sweep: belt speed × lane position
                                  # vs cycle time and clearance (no downloads)
python examples/cell_deliverables_demo.py  # the whole document set from one
                                  # script: layout SVG/DXF, BOM, I/O list, robot
                                  # program, USD, cell report (no downloads)
python examples/play_record.py \
       cell_dual.usda             # replay a baked USD in the studio (any of
                                  # the recordings above; omit for cell_seq)

Or try the browser-only build (deployed from main, or build it locally):

./scripts/build_wasm_demo.sh          # needs wasm-pack + wasm32 target
python -m http.server -d studio/dist-wasm 8899

Quickstart

import botrail as bt

robot = bt.Robot.from_urdf("robot.urdf")   # or from_xacro(...) / from_usd(...)
scene = bt.Scene(robot)

scene.load_usd("cell.usda", prefix="env")                # obstacles + frames
scene.set_robot_base_pose(*scene.frame("env/World/mount"))
scene.add_box("table", size=(0.6, 0.6, 0.05), position=(0.4, 0.0, 0.0))

bt.studio(scene)  # opens the 3D studio in your browser

Everything you do in the studio is mirrored in Python, and vice versa:

scene.set_tcp_target((0.3, 0.1, 0.5))         # live IK, pushed to the browser
scene.in_collision()                          # False
scene.min_obstacle_distance()                 # clearance in meters

traj = scene.plan_to_pose((0.4, 0.1, 0.3))    # IK, then RRT-Connect + time param
traj.export_csv("motion.csv", dt=0.008)

scene.save_project("cell.botrail")            # meshes/USD bundled when needed
print(scene.generate_python())                # script reproducing the scene

Verify the cell, not just the trajectory

Give the environment behavior, write the process as steps, and bake:

scene.add_box("crate", size=(0.04, 0.04, 0.04), position=(-0.5, 0.6, 0.3))
scene.add_conveyor("belt", zone_position=(-0.2, 0.6, 0.3),
                   zone_size=(1.2, 0.3, 0.3), velocity=(0.25, 0.0, 0.0),
                   running=False)
scene.add_beam_sensor("eye", frm=(0.0, 0.4, 0.3), to=(0.0, 0.8, 0.3))
scene.add_segment("approach", goal=[0.6, -0.5, 0.8, 0.0, 0.4, 0.0])

sq = scene.sequence("cycle")
sq.step("feed", actions=[bt.seq.start("belt")], transition=bt.seq.signal("eye"))
sq.step("stop", actions=[bt.seq.stop("belt")])
sq.step("pick", actions=[bt.seq.motion("approach")])

tl = scene.simulate_sequence("cycle")   # deterministic: bit-identical every run
print(tl.duration)                      # cycle time in seconds
tl.export_usd("cycle.usda", fps=60)     # replay in usdview / Omniverse / Blender

Because the bake is deterministic, the same numbers are regression tests — the workflow botrail exists for:

def test_cell_cycle():
    tl = build_cell().simulate_sequence("cycle")
    assert tl.duration <= 8.0                # cycle-time budget
    assert tl.step_span("feed").end <= 2.0   # the crate arrives on time
    assert tl.signal("eye").rising_edges()   # the handshake happened
    assert tl.min_clearance() > 0.05         # closest approach, meters

Move the beam sensor 0.25 m downstream and the cycle grows by exactly 1.0 s — a layout edit becomes a failing test instead of a shop-floor surprise. This repository runs such a cell in its own CI (python/tests/test_cell_regression.py), and examples/sweep_demo.py runs the same loop as a parameter study — bt.sweep bakes the cell over a grid and tables it (belt speed moves the cycle; lane position eats the clearance), bt.optimize searches the grid for the fastest cycle that keeps its clearance — with no random number anywhere.

Hand over the cell

The documents a cell is delivered as come out of the same script — none of them is typed in beside the model:

scene.set_part("belt", manufacturer="MISUMI", model="GVL-1200")   # what things *are*
scene.export_bom("bom.csv")               # bill of materials, merged and counted
scene.export_layout("layout.dxf")         # plan-view sheet for the 2D CAD (.svg for the review)
scene.export_io_list("io.csv")            # I/O list for the electrical drawing
tl.export_script("cell.script")           # the robot program, with the same DI/DO numbers

report = scene.cell_report({"cycle": tl}, deliverables=["bom.csv", "layout.dxf", "io.csv"])
report.save("cell_report.md")             # cycle time, clearance, I/O, BOM totals,
                                          # footprint — and the SHA-256 of each file

Because they are derived, they cannot disagree with each other or with the bake, and a layout edit changes exactly the documents it touches: examples/cell_deliverables_demo.py writes the whole set, and python/tests/test_deliverables.py pins which files a moved sensor or an added fence panel changes — by name.

The same loop runs without writing Python — the entry an agent's iteration and a CI job share:

botrail check cell.py                                  # load, lint, count → JSON (exit 1 on errors)
botrail simulate cell.py --scenarios --report r.json   # bake the matrix → the cell report
botrail export cell.py --out deliverables/ --all       # the whole document set, hashed into the report
botrail schema > project.schema.json                   # the .botrail JSON Schema, from the Rust types

Development

Requirements: Rust (stable), Python >= 3.9, maturin, uv, Node 20+ with pnpm.

./scripts/build_studio.sh                 # build the studio UI into the package
uv venv .venv && source .venv/bin/activate
maturin develop --uv
python examples/demo.py

Tests:

cargo test                                # Rust workspace
python -m pytest python/tests             # Python bindings

Docs (mkdocs, published at the link above):

uv pip install --group docs
mkdocs serve                              # needs `maturin develop` first

Contributor notes are in the Contributing page.

License

botrail 0.6.0 and later is source-available under your choice of the PolyForm Small Business License 1.0.0 or the PolyForm Noncommercial License 1.0.0. Use not permitted by either license requires a separate commercial license from 株式会社UnRobotics.

See the license notice, included license texts, commercial licensing information, and licensing FAQ. Versions v0.5.0 and earlier remain under the MIT License terms shipped with those releases.

Redistributions must preserve these notices:

Required Notice: Copyright (c) 2026 k-tanaka and botrail contributors.

Required Notice: botrail is licensed by 株式会社UnRobotics (https://www.un-robotics.com/).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

botrail-0.6.0.tar.gz (673.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

botrail-0.6.0-cp39-abi3-win_amd64.whl (6.7 MB view details)

Uploaded CPython 3.9+Windows x86-64

botrail-0.6.0-cp39-abi3-manylinux_2_35_x86_64.whl (7.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.35+ x86-64

botrail-0.6.0-cp39-abi3-macosx_11_0_arm64.whl (6.6 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file botrail-0.6.0.tar.gz.

File metadata

  • Download URL: botrail-0.6.0.tar.gz
  • Upload date:
  • Size: 673.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for botrail-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4af3ad0cfd1a1fa21a9648ee32870de38ecc6ad9508d82eadd9a371cf10da89c
MD5 860cf389c01a7f96b3190bcce5338dc1
BLAKE2b-256 f15c5777ceaba929e090dbb050405d5320e4f1db4a69fb663960a87726e39d32

See more details on using hashes here.

Provenance

The following attestation bundles were made for botrail-0.6.0.tar.gz:

Publisher: release.yml on botrail/botrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file botrail-0.6.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: botrail-0.6.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 6.7 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for botrail-0.6.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a250d8bfd5c5adc1109c1a7820fcd5689a2d5c3442ab57a39402bbf8ba1bd14f
MD5 e4f6c06ff5de6d0fe908186a0bd7a48d
BLAKE2b-256 21b0811f04ead805c2d306e7908a5b14cde2b242347c2cb6e84bebb90b60442e

See more details on using hashes here.

Provenance

The following attestation bundles were made for botrail-0.6.0-cp39-abi3-win_amd64.whl:

Publisher: release.yml on botrail/botrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file botrail-0.6.0-cp39-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for botrail-0.6.0-cp39-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 7654d316e16f67531ab4a13c5ff19a5260a6747be9421084cd4f91411dc44027
MD5 38c12517ecc65a096de304d75a2cc6bd
BLAKE2b-256 802980fe431ce60842ee5fc6da9b9d47eb716d3e42b230e0302ff2a7ce15ac5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for botrail-0.6.0-cp39-abi3-manylinux_2_35_x86_64.whl:

Publisher: release.yml on botrail/botrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file botrail-0.6.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for botrail-0.6.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7ecf94b9673c9b54d71fd414d915f987c74efab5df2ec2b75cfb58a69779499f
MD5 b9a7c15ac6443a0bc5f800649f2e2f3d
BLAKE2b-256 c7d6bdc50b89bdb75690fac1cb0c1a15caae6b9b80f7a1810d0166c19291d2a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for botrail-0.6.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on botrail/botrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.8.0

4 files

0.7.0

4 files

This release

0.6.0 This release

4 files

0.4.0

5 files

0.3.0

4 files

0.2.0

4 files

0.1.1

4 files

0.1.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page