Distribution. The primary public distribution point for this repository is GitHub: https://github.com/limx-tron2/tron2-rl-deploy-python. The internal LimX GitLab is a mirror; open issues, PRs, and security reports on the GitHub repository.
Reinforcement-learning deployment / inference stack (Python) for
the TRON2A humanoid — Sole-Foot (SF_TRON2A) and Wheel-Foot
(WF_TRON2A) variants. Loads ONNX policies via onnxruntime and
drives joint targets through the LimX low-level SDK, either against
the MuJoCo simulator or against a physical robot.
This project is licensed under the Apache License, Version 2.0
(January 2004). See the LICENSE file for the full text.
SPDX identifier: Apache-2.0.
NOTICE— required attribution notice.THIRD_PARTY_NOTICES.md— per-item provenance for the checked-in ONNX weights, thelimxsdk-lowlevelsubmodule, Python runtime dependencies (onnxruntime,numpy,scipy,pyyaml,pygame), and documentation media.MODEL_CARD.md— model card for the four ONNX files undercontrollers/model/.SECURITY.md— how to report a vulnerability, plus the real-hardware safety notice.CONTRIBUTING.md— dev setup (pip,ruff), verification steps, DCO sign-off, and the model-provenance rule.CHANGELOG.md— release notes and pending owner sign-off items.
Included in this repository:
- Python controller entry point (
main.py) and per-variant controllers (controllers/SolefootController.py,controllers/WheelfootController.py). - Runtime configuration (
controllers/model/*/params.yaml). - Four ONNX inference blobs (
policy.onnx,encoder.onnxforSF_TRON2AandWF_TRON2A) — pending provenance sign-off; seeMODEL_CARD.mdandTHIRD_PARTY_NOTICES.md§2. - Vendor SDK submodule reference (
limxsdk-lowlevel/) — pending SDK owner / legal clearance; do not move the pin without written sign-off.
Not included — by design:
- No PyTorch / training checkpoints (
.pt,.pth,.ckpt,.safetensors). - No SDK binaries (
.so,.dll,.dylib,.lib,.whl) — install the LimX SDK wheel yourself from the vendoredlimxsdk-lowlevel/submodule. - No firmware, no factory calibration values, no per-serial calibration files.
- No rosbag / MCAP / trajectory captures.
- No customer- or site-specific configuration.
- No pre-baked robot IP. The
<robot-ip>token used in the §4 examples below is a placeholder — substitute your own robot or simulator address before running. Nothing in this repository's source hard-codes a private IP. The internal-only siblingtron2-rl-deploy-rosretains a documentation-example literal10.192.1.2in its source / launch files, declared in that repo'sSECURITY.md; this repository intentionally does not.
Real-hardware notice. This is not a simulation-only demo.
main.pyopens an SDK connection to whatever IP you pass, and the controller writes joint torques that a real robot will execute. ReadSECURITY.mdbefore you point this code at a physical machine.
main.py: controller entry point (auto-selects the SF / WF controller based onROBOT_TYPE).controllers/SolefootController.py:SF_TRON2Ainference and control logic.controllers/WheelfootController.py:WF_TRON2Ainference and control logic.controllers/model/<ROBOT_TYPE>/: per-variant model and configuration directory.limxsdk-lowlevel/: LimX SDK sources and examples.
pip install -U pip
pip install numpy scipy pyyaml onnxruntime pygameInstall the wheel that matches your system architecture:
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
# x86_64 example
pip install limxsdk-lowlevel/python3/amd64/limxsdk-*-py3-none-any.whl
# aarch64 example
pip install limxsdk-lowlevel/python3/aarch64/limxsdk-*-py3-none-any.whlModel files must be placed per robot variant at:
controllers/model/SF_TRON2A/policy.onnxcontrollers/model/SF_TRON2A/encoder.onnxcontrollers/model/SF_TRON2A/params.yamlcontrollers/model/WF_TRON2A/policy.onnxcontrollers/model/WF_TRON2A/encoder.onnxcontrollers/model/WF_TRON2A/params.yaml
cd tron2-rl-deploy-python
export ROBOT_TYPE=SF_TRON2A
# or: export ROBOT_TYPE=WF_TRON2ABy default, connect to a local simulator (127.0.0.1):
python3 main.pySpecify a robot or SDK target IP:
# NOTE: <robot-ip> is a placeholder token — substitute your own
# robot / simulator IP before running. Nothing in this repo's
# source hard-codes a private IP. (The internal-only sibling
# tron2-rl-deploy-ros retains a documentation-example literal
# 10.192.1.2 in its source / launch files, declared in that
# repo's SECURITY.md.)
python3 main.py <robot-ip>Make sure the simulator side and the controller side use the same
ROBOT_TYPE:
- Simulator side:
tron2-mujoco-sim/simulator.py - Controller side:
tron2-rl-deploy-python/main.py
We recommend starting the simulator first, then the controller.
-
L1 + Y: switch to WALK -
L1 + X: switch back to IDLE -
R1: clear velocity command -
Open a Bash terminal.
-
Run robot-joystick:
./pointfoot-mujoco-sim/robot-joystick/robot-joystick
Suspend the robot before starting the controller when deploying on real hardware.
ROBOT_TYPE not set: runexport ROBOT_TYPE=...first.Model not found: check that all files are present undercontroller/model/<ROBOT_TYPE>/.No module named limxsdk: the SDK wheel is not installed in the current Python environment.RobotState has not been received yet: usually means the simulator is not running, or the two sides have mismatchedROBOT_TYPE.
The commands below are the same ones CI runs (see
.github/workflows/ci.yml); running them
locally before opening a PR saves review round-trips. None of them
require a physical robot.
# 1. Byte-compile every Python file (catches syntax errors,
# does not require the SDK wheel).
python -m compileall -q main.py controllers/
# 2. Lint (recommended).
pip install ruff
ruff check .
# 3. Dry-run import — exercises module-level side effects without
# calling robot.init. Requires the LimX SDK wheel installed.
python -c "import controllers"
# 4. YAML sanity for every params file.
python -c "import yaml, glob
for p in glob.glob('controllers/model/*/params.yaml'):
yaml.safe_load(open(p)); print('OK', p)"
# 5. ONNX sanity (loads the graph; does not run inference).
python -c "import onnx, glob
for p in glob.glob('controllers/model/*/*.onnx'):
onnx.checker.check_model(onnx.load(p)); print('OK', p)"Before ever running against a physical robot, verify the full control loop against the LimX MuJoCo simulator:
- Start the simulator (
tron2-mujoco-sim/simulator.py) with the sameROBOT_TYPEyou plan to use. - Leave the controller's target IP at its default
127.0.0.1(this is whatmain.pyuses when no argument is passed). - Run
python3 main.pyand confirm the observation stream, action outputs, and joystick binds all behave as expected in simulation.
Only after sim-only verification passes should you consider a
real-hardware run — and only with the robot suspended / mounted,
per SECURITY.md.
If you use this deployment stack in academic or public work, please cite the repository:
@misc{limx_tron2_rl_deploy_python_2026,
title = {tron2-rl-deploy-python: TRON2 RL deployment (Python)},
author = {LimX Dynamics},
year = {2026},
howpublished = {\url{https://github.com/limx-tron2/tron2-rl-deploy-python}}
}
- Bug reports / feature requests: GitHub Issues.
- Questions / integration help: GitHub Discussions.
- Security reports / robot-safety incidents: email
contact@limxdynamics.com; seeSECURITY.md. - Company / commercial contact: https://www.limxdynamics.com.


