Skip to main content
Get your first rfx policy running in minutes. This guide takes you from installation through recording demos to deploying a trained policy.

Prerequisites

Python 3.13+

rfx requires Python 3.13 or later

Rust toolchain

Install via rustup.rs
1
Install rfx
2
Install the rfx SDK using uv (recommended) or pip:
3
uv
uv pip install rfx-sdk
pip
pip install rfx-sdk
4
For development or source installation, see the Installation guide.
5
Verify your setup
6
Run the doctor command to check your installation:
7
rfx doctor
8
This checks for:
9
  • Core dependencies (tinygrad, numpy, PyYAML)
  • Optional packages (torch, lerobot, opencv)
  • Rust extension build
  • Available simulation backends
  • Connected hardware
  • 10
    Write a simple policy
    11
    A policy is any callable that takes observations and returns actions. Create my_policy.py:
    12
    import torch
    import rfx
    
    @rfx.policy
    def hold_position(obs):
        """Hold the robot still."""
        return torch.zeros(1, 64)  # 64-dim action space
    
    13
    For named joint control instead of raw tensor indices:
    14
    @rfx.policy
    def grasp(obs):
        return rfx.MotorCommands(
            {"gripper": 0.8, "wrist_pitch": -0.2},
            config=rfx.SO101_CONFIG,
        ).to_tensor()
    
    15
    Test without hardware
    16
    Use MockRobot to validate your policy before deploying to real hardware:
    17
    rfx deploy my_policy.py --robot so101 --mock --duration 5
    
    18
    The mock robot runs a simple physics simulation with the same observe(), act(), reset() interface as real hardware.
    19
    Deploy to real hardware
    20
    Once you have a trained policy checkpoint, deploy it to hardware:
    21
    # From a local checkpoint
    rfx deploy runs/my-policy --robot so101
    
    # From HuggingFace Hub
    rfx deploy hf://rfx-community/go2-walk-v1 --robot go2
    
    # Control the duration
    rfx deploy runs/my-policy --robot so101 --duration 30
    
    22
    Always test with --mock first to validate policy outputs and control loop timing before deploying to real hardware.
    23
    Record demonstrations
    24
    Collect teleoperation data for training:
    25
    rfx record --robot so101 --repo-id my-org/demos --episodes 10
    
    26
    This creates a LeRobot-compatible dataset that you can use for training.
    27
    Recording controls:
    28
  • Enter - Start/stop recording
  • h - Send robot to home position
  • q - Quit and save
  • Complete example

    Here’s a full workflow from policy definition to deployment:
    deploy_example.py
    import torch
    import torch.nn as nn
    import rfx
    from rfx.config import SO101_CONFIG
    
    class SimpleVLA(nn.Module):
        """Minimal MLP: obs["state"] → action."""
    
        def __init__(self, state_dim: int, action_dim: int):
            super().__init__()
            self.net = nn.Sequential(
                nn.Linear(state_dim, 256),
                nn.ReLU(),
                nn.Linear(256, 256),
                nn.ReLU(),
                nn.Linear(256, action_dim),
            )
    
        def forward(self, obs: dict) -> torch.Tensor:
            return self.net(obs["state"])
    
    # Create robot (mock or real)
    robot = rfx.MockRobot(state_dim=12, action_dim=6)
    # robot = rfx.RealRobot.from_config(SO101_CONFIG, port="/dev/ttyACM0")
    
    # Create policy
    policy = SimpleVLA(robot.max_state_dim, robot.max_action_dim)
    policy.eval()
    
    # Deploy
    stats = rfx.run(robot, policy, rate_hz=50, duration=10)
    
    print(f"Completed {stats.iterations} steps")
    print(f"Average period: {stats.avg_period_s * 1000:.2f}ms")
    print(f"Jitter p95: {stats.p95_jitter_s * 1000:.2f}ms")
    
    Run it:
    # Test in mock mode
    python deploy_example.py
    
    # Or use the CLI
    uv run deploy_example.py --mock --duration 10
    

    The robot interface

    Every robot in rfx implements the same three methods:
    obs = robot.observe()    # {"state": Tensor(1, 64), "images": ...}
    robot.act(action)        # Tensor(1, 64)
    robot.reset()
    
    This works identically for:
    • rfx.RealRobot - Hardware via serial/ethernet
    • rfx.SimRobot - Genesis, MJX, or other backends
    • rfx.MockRobot - Zero-dependency physics model

    Next steps

    Installation

    Learn about all installation methods and optional dependencies

    Python SDK

    Explore the full Python API reference

    SO-101 Setup

    Configure and calibrate your SO-101 arm

    Simulation

    Set up Genesis, MJX, or other sim backends

    Build docs developers (and LLMs) love