General implementation of position control of a turtleBot (Burger) in NVIDIA IsaacSim environment controlled via ROS2 Jazzy using PID controller..
This repository serves as a personal log of my journey learning ROS 2 Jazzy running on Ubuntu WSL2, integrated with NVIDIA Isaac Sim 5.1.0 running natively on Windows 11.
The goal of this project is to bypass standard "toy" examples and build a solid understanding of robotics software architecture. Specifically, we load a raw 3D model of a robot, manually configure its Odometry (sensors) and Differential Drive (actuators) via OmniGraph, and control it autonomously to a target coordinate using a custom-built, full PID Controller.
- Windows 11 Setup:
- NVIDIA Isaac Sim installed.
- WSL2 (Ubuntu) Setup:
- ROS 2 Jazzy installed.
- Open your WSL2 terminal and source your ROS 2 environment:
source /opt/ros/jazzy/setup.bash
- Launch Isaac Sim: Open a PowerShell terminal in Windows and run the selector script:
C:\isaacsim\isaac-sim.selector.bat - Enable ROS 2 Bridge: Once Isaac Sim is open, go to the top menu bar:
Window -> Extensions. Search forros2and enable the ROS 2 Bridge (ensure it's set to Autoload).
- Load a basic ground plane:
Create -> Physics -> Ground Plane(or load your preferred grid environment). - Load the raw robot asset: Drag and drop the
turtlebot.usdinto the stage.- Note: At this stage, this
.usdfile is strictly a 3D visual and physical model. It has no Action Graphs (no software hooks for ROS 2 to talk to). We have to build them manually.
- Note: At this stage, this
We need the robot to broadcast its
-
Go to the top menu:
Tools -> Robotics -> ROS2 Omnigraph -> Odometry publisher. -
In the properties of this new graph, set the Chassis Frame ID to
base_footprint. -
Verify the Connection:
- Press Play in Isaac Sim to start the physics simulation.
- Open your WSL2 terminal and run:
ros2 topic list
- You should see
/odomin the list. Troubleshooting: If it doesn't appear, open the Odometry graph and verify thatChildFrameIdand the input topic are correctly set toodom.
-
Verify in RViz2:
- In WSL2, run
ros2 run rviz2 rviz2. - Change the Fixed Frame to
odom. - Add an Odometry display and subscribe to
/odom. You should see the red arrow dynamically appearing, tracking the robot's state.
- In WSL2, run
We need a way for ROS 2 to send velocity commands (/cmd_vel) to the physics engine to spin the wheels. I built an Action Graph based on the official NVIDIA ROS 2 Drive TurtleBot Tutorial.
- Create a new Action Graph (e.g.,
cmdVel). - Add the required nodes to map the ROS 2
Twistmessage to the physics joints. - Joint Mapping:
- Use two
Constant Tokennodes containing the exact names of the robot's joints:wheel_left_jointandwheel_right_joint. - Feed these two tokens into a
Make Arraynode.
- Use two
- Articulation Controller:
- Link the array to the
Joint Namesinput of anArticulation Controllernode. - Set the target of the Articulation Controller to the
turtlebot3_burgerprim in your stage.
- Link the array to the
- Differential Controller Parameters:
To make the physics match reality, I configured the Differential Controller node with the physical specifications of a TurtleBot3 Burger:
maxAngularSpeed: 1.0 rad/smaxLinearSpeed: 0.22 m/swheelDistance: 0.16 mwheelRadius: 0.025 m
Instead of teleoperating the robot with a keyboard, I wrote a custom ROS 2 Python Node to act as a Full PID Controller.
-
Feedback Loop: The script subscribes to
/odom. By reading the exact timestamp from the ROS 2 message header, it calculates a mathematically accurate$\Delta t$ (dt) for discrete-time control integration. -
Error Calculation: It calculates the Euclidean distance error (
$v$ ) and Heading error ($\omega$ ) relative to a desired$(X, Y)$ target. - Control Action: It calculates Proportional, Integral (with anti-windup clamping to prevent runaway accumulation), and Derivative responses.
- Non-Holonomic Logic: A programmatic rule ensures the robot turns to face the target before applying forward velocity.
-
Actuation: The final
$v$ and$\omega$ are published directly to/cmd_vel, driving the Isaac Sim Action Graph.
To run the controller:
python3 full_pid_ctrl.pyWhen the simulation runs, the PID controller elegantly drives the Turtlebot to the target coordinate, slowing down smoothly as the proportional error decreases, and settling exactly on the target with zero steady-state error.
To verify the quality of the controller, the python script logs the telemetry and plots it using matplotlib.

End of log.
