A reinforcement-learning and deployment pipeline for legged robots, built on NVIDIA Isaac Lab, Isaac Sim, and ROS 2.
IsaacLegs facilitates the deployment of policies trained in Isaac Lab onto robots inside the Isaac Sim digital twin using ROS. It currently supports the Unitree Go2 quadruped and the Unitree G1 humanoid, including a 29-DOF configuration, with additional robots coming soon.
The framework provides ready-to-use digital twins that integrate robot state, sensor streams, and control interfaces within Isaac Sim, with support for creating custom digital twins for additional robot platforms. Robots can be deployed into a variety of NVIDIA simulation environments, referenced from Isaac Asset or Custom Environments.
The controller is designed to work with different robot platforms through ROS 2 interfaces, making it easy to support additional robots, sensors, and policies.
- How to train a policy — train in Isaac Lab and export the deployable artifacts.
- How to create a digital twin — import the robot, set drive gains, wire the ROS 2 action graphs.
- How to use the policy controller for a custom robot — use general controller to deploy your policy.
- Locomotion policy training in Isaac Lab (Go2, G1, G1 29-DOF) ✅
- Ready-to-use ROS 2 digital twins in Isaac Sim ✅
- Robot-agnostic policy controller ✅
- Onboard sensor integration (camera, 3D LiDAR) ✅
- Deployment into stock NVIDIA simulation environments ✅
- RViz configuration for all robots
- SLAM and navigation
- Imitation learning projects
Policies trained in Isaac Lab, and deployed in Isaac Sim digital twins across different environments.
![]() Go2 — Warehouse |
![]() G1 — Flat ground |
![]() G1 (29-DOF) — Simple room |
![]() Go2 — Camera + 3D LiDAR in RViz |
| Component | Version | Notes |
|---|---|---|
| Ubuntu | 22.04 | |
| Isaac Sim | ≥ 5.0.0 | the simulator and digital-twin runtime |
| Isaac Lab | ≥ 0.46.2 | needed only to train policies — its pip install also pulls in Isaac Sim |
| ROS 2 | Humble | |
| Python | 3.10 |
A CUDA-capable NVIDIA GPU is required for Isaac Sim.
A complete run consists of the digital twin in Isaac Sim and the policy controller in ROS 2. The steps below take you from a fresh clone to a walking robot.
git clone https://github.com/gholibqasobov/IsaacLegs.git ~/IsaacLegs
cd ~/IsaacLegs
# Install ROS 2 package dependencies
rosdep update
rosdep install --from-paths src --ignore-src -r -y
# The policy controller runs a TorchScript policy
pip install torch
colcon build --symlink-install
source install/setup.bash # re-run in every new shelllaunch_scene.py opens the Isaac Sim GUI with a ready-to-run robot and environment. Run the script from the Isaac Sim Python environment using the option that matches your installation:
If you have a conda with IsaacSim/IaacLab installed:
conda activate env_isaaclab
cd ~/IsaacLegs
python isaacsim_envs/gui/launch_scene.py --go2 --warehouse --playOr use Isaac Sim's bundled interpreter (python.sh):
cd ~/IsaacLegs
~/isaacsim/python.sh isaacsim_envs/gui/launch_scene.py --go2 --warehouse --playAdjust ~/isaacsim to match your Isaac Sim installation path. The same approach applies to all other Isaac Sim scripts.
Options. Pick one robot, optionally one environment, plus any run flags — e.g. --go2 --warehouse --play.
- Robot:
--go2·--g1·--g1_29dof - Environment:
--flat_grid·--flat_plane·--rough_plane·--simple_room·--warehouse·--full_warehouse --play— start simulating immediately; Otherwise press ▶ Play in the GUI.--headless— run without a GUI window.--list— print the available scenes and environments, then exit.
See Supported robots & environments for previews and details.
In a second terminal (with the workspace sourced):
ros2 launch fullbody_controller go2.launch.py # also: g1.launch.py, g1_29dof.launch.pyStart order matters for humanoids. A G1 will fall in the moments before the policy engages. Launch the scene without
--play, start the controller, then press ▶ Play — or start the controller first and launch with--play. Quadrupeds (Go2) are forgiving either way.
Parameters (-p name:=value on ros2 run, or name:=value on ros2 launch):
policy_path— path to the TorchScript policy (.pt); defaults to the shipped checkpoint.io_descriptors_path— override the descriptor location (default: next to the policy).decimation(default1) — run the policy every Nth tick (50 Hz sensors → 50 Hz control at 1).warmup_sec(default0.0) — seconds spent easing into the policy's default pose before engaging it.warmup_interpolate(defaultTrue) — interpolate from the spawn pose to default (no violent snap).
Drive it by publishing a velocity, or interactively from the keyboard:
ros2 run teleop_twist_keyboard teleop_twist_keyboard
# or
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.3}, angular: {z: 0.3}}" -r 10Inspect what's flowing over ROS 2:
ros2 topic list
ros2 topic echo /joint_statesPolicy directories are under
src/fullbody_controller/policy/
| Preview | Environment | Flag |
|---|---|---|
![]() |
Flat grid | --flat_grid |
![]() |
Flat plane | --flat_plane |
![]() |
Simple room | --simple_room |
![]() |
Warehouse | --warehouse |
![]() |
Full warehouse | --full_warehouse |
Adding a stock world is a one-line edit to the ENVIRONMENTS dict in
launch_scene.py:
ENVIRONMENTS = {
# ...
"my_world": "/Isaac/Environments/.../my_world.usd",
}Published by the simulation (action graphs):
| Topic | Type |
|---|---|
joint_states |
sensor_msgs/JointState |
joint_command |
sensor_msgs/JointState |
imu |
sensor_msgs/Imu |
odom |
nav_msgs/Odometry |
clock |
rosgraph_msgs/Clock |
/rgb, /depth |
sensor_msgs/Image |
/scan, /point_cloud |
sensor_msgs/{LaserScan,PointCloud2} |
If IsaacLegs is useful to you, please consider giving it a ⭐ — it helps others find the project and motivates further development. Found a bug, have a feature in mind, or want a new robot or environment supported? Open an issue or start a discussion — feedback and contributions are very welcome.
Apache-2.0. See individual package headers.
NVIDIA Isaac Lab and Isaac Sim, Unitree Robotics, and the RSL-RL project.












