Quickstart
Use Shaper to identify a vibration model, verify vibration reduction, and shape outgoing joint trajectories before sending them to the robot.
Step 1: Setup the SDK
Go over the First Steps from Get Started to generate your API token and robot ID and install the Reforge Robotics SDK.
You will need:
- The robot IP address.
- The Reforge API token.
- The Reforge robot ID.
- The robot SDK token, if the robot manufacturer requires one.
- The local PC IP address, if the robot SDK requires an explicit local address.
Step 2: Calibrate and Identify the Shaper Model
From the repository root, run calibration with automatic cloud identification:
bashpython3 -m robot.run calibrate \ <ROBOT_IP> \ --type shaper \ --local_ip <LOCAL_IP> \ --sdk_token <ROBOT_SDK_TOKEN> \ --robot_id <REFORGE_ROBOT_ID> \ --freq 250 \ --identify <REFORGE_API_TOKEN>
If your robot SDK does not require --local_ip or --sdk_token, omit those arguments.
The command stores calibration data under src/robot/data/ and downloads identified models into src/robot/models/current/shaper.
Step 3: Run the Vibration Test
Use the calibration data folder from Step 2:
bashpython3 -m robot.run vibration_test \ <ROBOT_IP> \ <LOCAL_DATA_FOLDER> \ --local_ip <LOCAL_IP> \ --sdk_token <ROBOT_SDK_TOKEN> \ --freq 250
The vibration test runs uncompensated and compensated moves, records accelerometer data, and prints the vibration-reduction result.
For the full workflow and expected result plot, see Calibration and Identification - Shaper.
Step 4: Use the Shaper During Control
Load src/robot/models/current/shaper, shape a desired joint trajectory, and send the shaped positions, velocities, and accelerations to the robot SDK:
pythonimport numpy as np import robot_sdk # Replace with the SDK package for the robot you are using. from reforge_core.control.shaper import ShaperInterface sample_time_s = 0.004 shaper = ShaperInterface( # Match the period used by the robot command loop. sample_time=sample_time_s, # Use the models produced by calibration and identification. model_directory="src/robot/models/current/shaper", # Use the URDF for the robot you are controlling. urdf_filepath="src/robot/urdf/<robot>.urdf", # Shape the first three robot axes and keep all six joints in the output. num_axes=3, num_joints=6, ) # `desired_trajectory_rad` is the desired joint position command [N, num_joints]. desired_trajectory_rad = np.asarray(robot_sdk.get_planned_joint_trajectory()) time_vector_s = np.arange(desired_trajectory_rad.shape[0]) * sample_time_s desired_velocity_rad_s = np.gradient( desired_trajectory_rad, sample_time_s, axis=0, ) desired_acceleration_rad_s2 = np.gradient( desired_velocity_rad_s, sample_time_s, axis=0, ) shaped_trajectory = shaper.process_trajectory( command=desired_trajectory_rad, command_dot=desired_velocity_rad_s, command_ddot=desired_acceleration_rad_s2, time_vector=list(time_vector_s), vibration_shaping_weight=1.0, vibration_weight_transition_s=0.0, residual_shaping_strategy=None, finalize_tail=False, ) # Send these arrays to the robot manufacturer's SDK at the configured sample time. robot_sdk.send_joint_trajectory( positions=shaped_trajectory.positions, velocities=shaped_trajectory.velocities, accelerations=shaped_trajectory.accelerations, sample_time=sample_time_s, )
This quickstart shows the full offline trajectory path. For residual-tail shaping, sample-by-sample streaming control, and the complete runnable example, see Control.