This document provides a comprehensive minimal guide for adding a new robot to the SAGE project. We use the Fourier GR1T2 robot as an example throughout this guide.
- Isaac Sim installed and configured
- Access to robot URDF files and meshes
- Basic familiarity with Isaac Sim interface
Throughout this document:
<REPO_ROOT>refers to your SAGE project root directory- GR1T2 is used as the example robot name throughout the guide
Important: When following this guide for your robot, replace:
<REPO_ROOT>with your actual project pathgr1t2with your robot name (lowercase) in all configurations, commands, and file paths
Example:
- If your project is at
/home/user/sage/and your robot is "atlas" - Then
<REPO_ROOT>/configs/gr1t2_valid_joints.txtbecomes/home/user/sage/configs/atlas_valid_joints.txt
All robot assets are stored under the <REPO_ROOT>/assets folder. The robot asset must be in USD format for compatibility with Isaac Sim.
Tip: If your robot is available in the Isaac Sim Robot Assets, use it directly with the corresponding placeholder. Otherwise, proceed with the conversion steps below.
The robot asset needs to be in USD format. Isaac Sim provides various tools to import from different robot representations, including URDF, MJCF, and direct import from selective CAD platforms. For details, please refer to the official Isaac Sim documentation.
Example with GR1T2: The GR1T2 model can be retrieved from Fourier's GitHub repository.
- Download the robot model (e.g., GR1T2 URDF and mesh files)
- Place the model files in a temporary folder
- Open Isaac Sim and use the URDF Importer:
- Go to
File > Import - Select your URDF file (e.g.,
GR1T2_nohand.urdf) - Configure import settings in Options:
- Set Output Directory to
<REPO_ROOT>/assets - Select Reference Model
- Select Moveable Base
- Configure Joint & Drives and Colliders properties if necessary
- Set Output Directory to
- Go to
- Click Import and wait for the process to complete
Figure 1: URDF Import Settings in Isaac Sim
After converting to USD format, use Isaac Sim's Asset Validator to check for critical issues:
- Open Isaac Sim
- Load your USD asset (
<REPO_ROOT>/assets/GR1T2_nohand/GR1T2_nohand.usd) - Run Asset Validator:
- Go to
Window > Asset Validator(or first enable it inWindow > Extensions) - Select the validation to run
- Click "Analyze"
- Fix any critical errors that appear (typically related to materials, physics properties, or joint configurations)
- Save the file for any changes
- Go to
Figure 2: Asset Validator Results
Critical Step: You need to identify all joint names to be used for later configuration.
- Load the USD asset in Isaac Sim
- Open the Stage panel (
Window > Stage) - Navigate through the robot hierarchy and note down all joint names that will be used for motion
- With the latest version of URDF Importer, all joints are organized under the
jointsscope - Expand the robot hierarchy to see all available joints
- With the latest version of URDF Importer, all joints are organized under the
Example for GR1T2:
left_shoulder_pitch_joint
left_shoulder_roll_joint
left_shoulder_yaw_joint
left_elbow_pitch_joint
...
Figure 3: Robot Joint Hierarchy in Stage Panel
Test the robot positioning to ensure it spawns correctly above the ground:
- Create a new scene in Isaac Sim (
File > New) - Add Physics Scene (
Create > Physics > Physics Scene) - Add Ground Plane (
Create > Physics > Ground Plane) - Add your robot USD as a reference:
- Method 1:
File > Add Referenceand select your USD file - Method 2: Drag and drop from the Content panel
- Method 1:
- Adjust initial position in the Transform properties:
- Set X and Y to
0.0 - Gradually increase Z value until robot is slightly above ground
- Set X and Y to
- Run physics simulation (
Spacebaror play button) to verify:- Robot doesn't fall through the ground
- Robot doesn't clip into the ground plane
- Record the optimal Z-offset value for use in Step 2
Figure 4: Robot Z-Offset Testing
Locate the ROBOT_CONFIGS dictionary in <REPO_ROOT>/sage/assets.py and add your robot entry:
ROBOT_CONFIGS = {
# ... existing robots ...
# Add your new robot here:
"gr1t2": {
"usd_path": "assets/GR1T2_nohand/GR1T2_nohand.usd",
"offset": (0.0, 0.0, 0.96),
"default_kp": 100.0,
"default_kd": 2.0,
"default_control_freq": 50,
},
}Configuration Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| Dictionary Key | str |
Yes | Robot identifier (lowercase, used as the robot name) | "gr1t2" |
usd_path |
str |
Yes | Path to USD file (relative to <REPO_ROOT> or use {ISAAC_NUCLEUS_DIR} placeholder) |
"assets/GR1T2_nohand/GR1T2_nohand.usd" |
offset |
tuple[float, float, float] |
Yes | Position offset (x, y, z) in meters (from Step 1.4) |
(0.0, 0.0, 0.96) |
prim_path |
str |
No | USD prim path for the robot | "/World/Robot" (default) |
default_kp |
float |
Yes* | Default proportional gain for PD controller | 100.0 |
default_kd |
float |
Yes* | Default derivative gain for PD controller | 2.0 |
default_control_freq |
int |
Yes* | Default control frequency in Hz for motion playback | 50 |
* Required unless overridden via command-line arguments (--kp, --kd, --control-freq)
Important Notes:
- Dictionary key: Use lowercase for consistency (e.g.,
"gr1t2"not"GR1T2"). This becomes the robot name - USD Path Options:
- Relative path:
"assets/your_robot/robot.usd"- For local assets in the repository - Nucleus path with placeholder:
"{ISAAC_NUCLEUS_DIR}/Robots/Manufacturer/Model/robot.usd"- For assets on Isaac Sim Nucleus server - The
{ISAAC_NUCLEUS_DIR}placeholder is automatically resolved at runtime
- Relative path:
- Offset values: Use the Z-offset value you determined in Step 1.4
- Control Parameters: The framework uses a priority system for control parameters:
- Command-line arguments (
--kp,--kd,--control-freq) take highest priority - Robot configuration defaults are used if arguments are not provided
- An error is raised if neither is configured
- Command-line arguments (
Create a configuration file that specifies which joints should be controlled during simulation.
Create a new file: <REPO_ROOT>/configs/gr1t2_valid_joints.txt
Note: Replace
gr1t2with your robot name. The config file should be named<your_robot_name>_valid_joints.txt
Format: One joint name per line, exactly as they appear in the USD asset:
left_shoulder_pitch_joint
left_shoulder_roll_joint
left_shoulder_yaw_joint
left_elbow_pitch_joint
left_wrist_roll_joint
right_shoulder_pitch_joint
right_shoulder_roll_joint
right_shoulder_yaw_joint
right_elbow_pitch_joint
right_wrist_roll_joint
Important Guidelines:
- Include only the joints you want to actively control
- Use exact joint names from Step 1.3
- The system will automatically find and map these joint names to the robot
Motion files contain the joint trajectories that your robot will follow during simulation.
Create the following directory structure:
<REPO_ROOT>/
└── motion_files/
└── gr1t2/ # Robot name folder (replace "gr1t2" with your robot name)
├── custom/ # Custom motion category
│ └── custom_motion.txt
└── amass/ # AMASS-derived motions
├── punch_left01_poses_action_sequence.txt
└── walk_sequence_poses_action_sequence.txt
To perform a quick test, follow the process below to create your custom motion file at <REPO_ROOT>/motion_files/gr1t2/custom/custom_motion.txt.
Header Line: Comma-separated joint names (must match your USD joint names)
left_shoulder_pitch_joint, left_shoulder_roll_joint, left_shoulder_yaw_joint, ...
Data Lines: Target joint positions in radians for each timestep
0.0, -0.1, 0.2, 0.5, 0.0, 0.0, 0.1, -0.2, -0.5, 0.0
0.1, -0.15, 0.25, 0.6, 0.0, 0.0, 0.15, -0.25, -0.6, 0.0
0.2, -0.2, 0.3, 0.7, 0.0, 0.0, 0.2, -0.3, -0.7, 0.0
...
Key Points:
- Each line after the header represents one timestep
- Values must be in radians (not degrees)
- Number of values per line must match the number of joints in header
If you're adding a new motion source category, update the argument parser in <REPO_ROOT>/scripts/run_simulation.py:
- Locate the
mainfunction and find themotion-sourceargument - Add your new motion source to the choices list:
parser.add_argument(
"--motion-source",
type=str,
choices=["amass", "custom", "your_new_source"], # Add your source here
required=True,
help="Source of the motion",
)After completing all steps, test your robot integration:
cd <REPO_ROOT>
${ISAACSIM_PATH}/python.sh scripts/run_simulation.py \
--robot-name gr1t2 \
--motion-source custom \
--motion-files motion_files/gr1t2/custom/custom_motion.txt \
--valid-joints-file configs/gr1t2_valid_joints.txt \
--output-folder output \
--fix-rootNote: Replace
gr1t2in the command with your robot name and update the motion file path accordingly.
Check that:
- Robot spawns correctly above the ground
- All specified joints move according to the motion file
- No error messages about missing joints
- Output files are generated in
<REPO_ROOT>/output/sim/gr1t2/custom/custom_motion/(path will use your robot name)joint_list.txt: Lists controlled jointscontrol.csv: Command positions over timestate_motor.csv: Actual joint states over time