Reforge SDK (reforge-core)
Reforge SDK is the independently built Python package that powers Reforge calibration and model-based vibration control.
This README is intended for PyPI distribution of reforge-core.
What This Package Provides
Calibration module (reforge_core.calibration)
The calibration module provides the cloud interface used after a robot calibration run:
- Uploads calibration data artifacts
- Triggers identification or fine-tuning jobs in Reforge Cloud API
- Polls job status and downloads generated model artifacts
- Extracts returned model files for control use
Primary entry point:
reforge_core.calibration.api.ReforgeAPIManager
Control module (reforge_core.control)
The control module provides vibration-aware command shaping for robot trajectories:
- Loads per-axis model files generated by calibration/identification
- Computes shaping parameters from current robot state
- Shapes single commands or full trajectories
- Returns shaped positions, velocities, and accelerations for execution
Primary entry points:
reforge_core.control.python.covalent_wrapper.ShaperInterfacereforge_core.control.python.covalent_wrapper.RobotState
Interface with reforge-interface (src/robot)
Reforge SDK is designed to be consumed by the reforge-interface repository, where robot-specific integration lives.
Expected responsibilities in reforge-interface/src/robot:
- Robot transport and SDK communication loop
- Sensor acquisition (joint encoders, TCP accelerometer)
- Calibration routine execution and local data storage
- Invocation of Reforge SDK calibration + control APIs
Typical artifact flow:
src/robot/run.pyruns calibration and stores local data (for example undersrc/robot/data/<date>).ReforgeAPIManageruploads the data and requests model generation.- Returned model artifacts are saved for runtime control (commonly under
src/robot/models/current). ShaperInterfaceloads those models and the robot URDF to shape outgoing joint commands before they are sent through the robot driver insrc/robot.
In this architecture, reforge-interface/src/robot owns robot I/O and execution, while reforge-core owns calibration-cloud orchestration and shaping logic.
Usage
- Ensure you have the requirements:
- An accelerometer/IMU located at the tool center point (TCP) that can measure data in the x-, y-, and z-coordinates of the end-effector’s inertial frame of reference (or the robot base’s inertial frame).
- Encoders in each joint that can accurately measure the current joint position of the robot at a rate of 200 Hz or higher.
- A real-time SDK to access data from IMU and encoders and to command the joint motors with time-domain angular motor positions.
- A Universal Robot Description File (URDF) that describes the robot’s kinematics and dynamics (dynamics optional but preferred).
- Integrate the robot’s SDK/URDF and build the project.
- Pull the Reforge repository from Github and add your robot's SDK to
requirements.txt
git clone https://github.com/reforge-robotics/reforge-interface.git
cd reforge-interface
- Add the robot's URDF to
src/robot/urdf - Build the project
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install --no-cache-dir .
-
Integrate your robot's SDK in
src/robot/robot_interface.py -
Test robot connection
python3 -m robot.run connect_test <robot_ip> --local_ip <local_ip> --sdk_token <robot_sdk_token>
- Run the calibration and identification of models
- Run with automatic identification
python3 -m robot.run calibrate <robot_ip> --local_ip <local_ip> --sdk_token <robot_sdk_token> --robot_id <reforge_robot_id> --freq 250 --identify <reforge_api_token>
- Run joint-tracker calibration and save joint models
python3 -m robot.run calibrate <robot_ip> --type joint_tracker --local_ip <local_ip> --sdk_token <robot_sdk_token> --robot_id <reforge_robot_id> --identify <reforge_api_token>
- Run shaper calibration with an MPC-compensated joint-tracker prepass, then stop before shaper identification
python3 -m robot.run calibrate <robot_ip> --type shaper --with_joint_tracker_mpc --local_ip <local_ip> --sdk_token <robot_sdk_token> --robot_id <reforge_robot_id> --joint_tracker_api_token <joint_tracker_api_token>
- Run shaper calibration with an MPC-compensated joint-tracker prepass, then run shaper identification with the same API token
python3 -m robot.run calibrate <robot_ip> --type shaper --with_joint_tracker_mpc --local_ip <local_ip> --sdk_token <robot_sdk_token> --robot_id <reforge_robot_id> --identify <shared_api_token>
- Run shaper calibration with an MPC-compensated joint-tracker prepass, then run shaper identification with separate API tokens
python3 -m robot.run calibrate <robot_ip> --type shaper --with_joint_tracker_mpc --local_ip <local_ip> --sdk_token <robot_sdk_token> --robot_id <reforge_robot_id> --joint_tracker_api_token <joint_tracker_api_token> --identify <shaper_api_token>
- Run calibration first, then run identification
python3 -m robot.run calibrate <robot_ip> --local_ip <local_ip> --sdk_token <robot_sdk_token>
python3 -m robot.run identify <reforge_api_token> <reforge_robot_id> <local_data_location>
- Run test to verify the calibration
python3 -m robot.run vibration_test <robot_ip> <local_data_location> --local_ip <local_ip> --sdk_token <robot_sdk_token>
The robot will go through a random series of motion pairs, one uncompensated and one compensated, store the accelerometer data from the motion tests, and print out a log with the test results.
Shaper Calibration Rollout Notes
Shaper calibration records base-joint grid sweeps by default. Existing six-DOF
robots still use --base_joints=1 unless a different value is passed, but that
one-base default now records j0 base-angle coverage in addition to the normal
full-axis shaper sweeps.
For multi-base robots, pass --base_joints <count> to configure the number of
consecutive base joints starting at joint index 0. Base-joint limits are read
from the URDF when available. If a requested base joint has no URDF limit, pass
one --base_joint_limits LOWER,UPPER value for that joint. Calibration setup
fails if the requested base-joint axes do not match the expected
world-z-parallel base-joint definition.
Use --test-mode to traverse the planned calibration poses without running sine
sweeps or writing acquisition artifacts. The CLI prints the planned run count
before motion; review it because calibration duration grows quickly as
--base_joints increases. Data recorded above 500 Hz is saved to calibration
CSV artifacts downsampled to 500 Hz.
New shaper datasets and model bundles are schema-versioned. New one-base models
use the runtime feature schema j0_rad;v_deg;r_mm;inertia; multi-base models
add one base-angle feature per consecutive base joint before v_deg, r_mm,
and inertia. Older model bundles without feature metadata continue to load
through the legacy [v_deg, r_mm, inertia] fallback.
When resuming calibration from a later pose, preserve the earlier pose artifacts in the same data folder. Existing prior-pose CSV artifacts are treated as completed run data during rollout validation, even if the resumed manifest only marks later runs as completed.
Minimal Usage Sketch
from reforge_core.calibration.api import ReforgeAPIManager
from reforge_core.control.python.covalent_wrapper import ShaperInterface, RobotState
# Calibration/model generation
api = ReforgeAPIManager(reforge_api_token="<token>", robot_id="<robot_id>")
api.run_cloud_model_generation(data_folder="src/robot/data/<YYYY-MM-DD>")
# Runtime shaping
shaper = ShaperInterface(
sample_time=0.005,
model_directory="src/robot/models/current",
urdf_filepath="src/robot/urdf/<robot>.urdf",
num_axes=3,
num_joints=6,
tcp_payload_mass_kg=2.4, # Attached tool/workpiece mass [kg].
)
state = RobotState(joint_angles=...) # numpy array
shaped = shaper.shape_sample(..., state)
# Update the existing Shaper before inference after a payload change.
shaper.set_tcp_payload_mass_kg(1.1)
The payload must be finite and nonnegative. A numeric
process_trajectory(..., tcp_payload_mass_kg=...) override is applied before
that trajectory and persists for later calls; omitting it preserves the current
payload.
Installation
pip install reforge-core
Build From Source With the Complete Native Shaper Backend
Use this path when developing reforge-core locally or when
ShaperInterface should default to the complete native backend. The complete
backend is only available when the installed _native_shaper extension was
built with the native solver/backend targets enabled.
Run these commands from the repository root, not from src/core_sdk:
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip setuptools wheel
python -m pip install \
scikit-build-core \
cmeel-eigen==3.4.1 \
cmeel-urdfdom-headers==3.0.0 \
pybind11 \
nlohmann-json==3.12.0 \
pin==4.0.0
Install rustup if it is not already on PATH, then install the exact Rust
toolchain required by the locked Clarabel native solver wrapper:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustup toolchain install 1.84.1
Force a clean editable rebuild of the SDK package. The -e src/core_sdk
argument is intentional; installing from the repository root does not build the
reforge-core package.
RUSTUP_TOOLCHAIN=1.84.1 \
python -m pip install \
--no-cache-dir \
--force-reinstall \
--no-build-isolation \
--no-deps \
--config-settings=build-dir=/tmp/reforge-core-sdk-native-build \
-e src/core_sdk
Use a fresh build directory if you repeat the build after changing native sources or CMake options.
Verify that the installed extension exposes the complete backend:
python - <<'PY'
from reforge_core.control import _native_shaper
print("complete_backend_available:", _native_shaper.complete_backend_available)
print("has NativeShaper:", hasattr(_native_shaper, "NativeShaper"))
PY
The expected output is:
complete_backend_available: True
has NativeShaper: True
If complete_backend_available is False, the active environment is still
using a partial _native_shaper build. Re-run the editable install with a fresh
--config-settings=build-dir=... value and confirm that rustc +1.84.1 --version reports Rust 1.84.1.
Optional Extras
reforge-core keeps the base install focused on the shared calibration and
control stack. Optional feature dependencies are exposed through extras:
pip install reforge-core[kinecal]installs the additional packages required for thereforge_core.kinecalpackage.pip install reforge-core[joint_tracker]installs the additional packages required for thereforge_core.control.joint_trackerpackage.pip install reforge-core[all]installs all optional runtime feature dependencies currently defined by this package.pip install reforge-core[dev]installs development tooling plus the same optional runtime dependencies included byall.
Release files for reforge-core 2.0.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reforge_core-2.0.16.tar.gz | 1.3 MB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reforge_core-2.0.16-cp311-cp311-manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64 | Details |
| reforge_core-2.0.16-cp311-cp311-macosx_14_0_arm64.whl | CPython 3.11 | CPython 3.11 | macOS 14.0+ ARM64 | Details |
Total release size: 21.0 MB
Release files / reforge_core-2.0.16.tar.gz
| Download URL | reforge_core-2.0.16.tar.gz |
|---|---|
| Size | 1.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fcc8f55818af3b3b5301aad6de2115548e5f204976a82dbcfc9c1b56b4688bc4
|
|
BLAKE2b-256 checksum How to use checksums |
79c5c1ec17c6babfbe0a7abd9f73cf34c253650cec0ef95989c97320be6c40a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / reforge_core-2.0.16-cp311-cp311-manylinux_2_28_x86_64.whl
| Download URL | reforge_core-2.0.16-cp311-cp311-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 15.3 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0c6a57e3362d6ee2d71f830fa7c9775745eb0880bc4f875b70a08a49ec46668b
|
|
BLAKE2b-256 checksum How to use checksums |
f8c5e8705cbba59b10e49921633dee3aa39549dc4aefe9abaa57d3f832220642
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / reforge_core-2.0.16-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | reforge_core-2.0.16-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
073025ca1c2f187a003b9d78aada1b77e64dcd12ace210cc06cd657ea47ccca0
|
|
BLAKE2b-256 checksum How to use checksums |
2ba1aae9d40227d838e25c02b14910eabcb49c3c841dda1c3a1a5b1c7512bed4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|