Akshay Parkhi's Weblog

Subscribe

RDF, ROS, and Sim-to-Real: Understanding Robot Description Files

2nd March 2026

When you start working with robot simulation — whether it’s Isaac Sim, Gazebo, or MoveIt — you immediately run into a file called something.urdf. It’s one of those things that seems simple on the surface but connects to everything in the robotics stack. Here’s a clear breakdown of what URDF is, what it isn’t, and how it fits alongside ROS.

What is URDF?

URDF stands for Unified Robot Description Format. It’s an XML file that describes what a robot physically is:

  • Links — rigid bodies (the physical segments of the arm)
  • Joints — connections between links (how they move relative to each other)
  • Mass & inertia — how heavy each part is and how it resists rotation
  • Collision shapes — simplified geometry for physics engines
  • Visual meshes — detailed 3D models for rendering

The critical distinction: URDF does NOT control the robot. It only describes what the robot is. Think of it as a blueprint, not a control system.

URDF Structure: The Kinematic Tree

A URDF file defines a tree of links connected by joints:

base_link
   ↓ (joint_1: revolute)
link_1
   ↓ (joint_2: revolute)
link_2
   ↓ (joint_3: revolute)
gripper

Each link includes:

PropertyWhat It Defines
MassWeight of the link (kg)
InertiaRotational inertia tensor (3x3 matrix)
Collision meshSimplified shape for physics calculations
Visual meshDetailed 3D model for rendering (STL/DAE files)

Each joint includes:

PropertyWhat It Defines
Typerevolute, prismatic, fixed, continuous
AxisWhich axis the joint rotates/slides around
LimitsMin/max angle, max effort, max velocity
Parent linkThe link “above” in the tree
Child linkThe link “below” in the tree

Example URDF Snippet

Here’s what a simplified SO-101 arm URDF looks like:

<link name="base_link">
  <inertial>
    <mass value="1.5"/>
    <inertia ixx="0.01" ixy="0" ixz="0"
             iyy="0.01" iyz="0" izz="0.01"/>
  </inertial>
  <visual>
    <geometry>
      <mesh filename="meshes/base.stl"/>
    </geometry>
  </visual>
  <collision>
    <geometry>
      <cylinder radius="0.05" length="0.1"/>
    </geometry>
  </collision>
</link>

<joint name="joint_1" type="revolute">
  <parent link="base_link"/>
  <child link="link_1"/>
  <axis xyz="0 0 1"/>
  <limit lower="-1.57" upper="1.57"
         effort="10" velocity="2.0"/>
</joint>

This tells any simulator or visualization tool: what moves, how it moves, how heavy it is, and what shape it has.

URDF in the Robotics Ecosystem

URDF is primarily associated with the ROS (Robot Operating System) ecosystem. It enables:

  • RViz — 3D visualization of the robot model and sensor data
  • MoveIt — motion planning and inverse kinematics
  • Gazebo — physics simulation
  • Isaac Sim — NVIDIA’s simulator imports URDF and converts it to USD internally

URDF is NOT Physics

This is an important distinction. URDF describes structure. Physics engines use URDF as input to build their internal representation:

URDF (structure blueprint)
  → Physics Engine (Isaac / Gazebo / MuJoCo)
    → Internal Physics Model (collisions, gravity, friction, contacts)

The actual physics behavior — how objects collide, how friction works, how gravity affects motion — depends entirely on the simulator. Two simulators given the same URDF can produce different physics behavior because they use different solvers and contact models.

URDF vs Other Robot Description Formats

FormatUsed InPurpose
URDFROS ecosystemRobot structure (kinematic tree)
USDOmniverse / Isaac SimFull 3D scene description
MJCF (XML)MuJoCoPhysics + control definition
SDFGazeboAdvanced simulation (extends URDF)

For an SO-101 arm, the GitHub repo typically includes both SO101.urdf (for ROS tools) and SO101.xml (MJCF format for MuJoCo). Isaac Sim cannot open URDF directly as a scene file — it imports the URDF and converts it to USD internally.

Now, What About ROS?

This is where confusion often creeps in. People see URDF files, launch files, rosbag files, and assume ROS is some kind of file-based system. It’s not.

ROS is middleware — a communication framework for robots. Think of it as a message bus:

Node A (camera driver)
  publishes → /camera/image       → 30 fps live stream

Node B (motor driver)
  publishes → /joint_states       → 50 Hz joint angles
  subscribes ← /joint_commands    ← target positions

Node C (VLA controller)
  subscribes ← /camera/image
  subscribes ← /joint_states
  publishes → /joint_commands

Nodes send and receive messages via topics. This is live streaming data, not file I/O. No files are required for ROS to operate.

ROS: Streaming vs Files

Topics = Live Streams

/joint_states  →  publishing 50 times/sec  →  live data, no file
/camera/image  →  publishing 30 times/sec  →  live data, no file

This is a live data stream. No file is required.

Files Are Optional (For Recording)

If you want to record demo data, debug later, or train ML models, you use:

ros2 bag record /joint_states /camera/image

That writes the live topic stream into a file on disk. But ROS itself does not need it to function.

Where URDF Fits With ROS

URDF is separate from ROS. ROS uses URDF so it knows the robot’s structure:

  • What joints exist?
  • What are their names?
  • What are their limits?

Without URDF, ROS can still stream topics — but it won’t understand the robot’s structure. You lose visualization, motion planning, and collision checking.

ThingRequired?What It Does
ROSYes (if using ROS)Communication layer between nodes
URDFNo (optional but common)Robot structure blueprint
rosbagNoRecords topic data to disk
Launch fileNoAuto-starts multiple nodes

For the SO-101: Why URDF Matters for Sim-to-Real

If you own a real SO-101 and want to do sim-to-real transfer — train a VLA in simulation and deploy on the physical arm — URDF alignment is critical:

  • Same joint names in sim and real — so commands map correctly
  • Same joint limits — so the policy never commands impossible positions
  • Same kinematic tree — so the model’s internal representation matches reality

If your simulation URDF says joint_1 has a range of [-1.57, 1.57] radians but your real motor only supports [-1.0, 1.0], your trained policy will try to move past the physical limit. That misalignment is where sim-to-real breaks down.

URDF (shared blueprint)
  ├── Simulation (Isaac Sim / Gazebo)
  │     → trains VLA policy
  │     → uses URDF joint names + limits
  │
  └── Real Robot (SO-101 hardware)
        → executes VLA policy
        → same joint names + limits
        → policy transfers cleanly

Putting It All Together

Three separate concepts, three different roles:

URDF = Robot structure file       (what the robot IS)
ROS  = Communication layer        (how nodes TALK)
rosbag = Recording file           (saving streams to DISK)

URDF tells tools what your robot looks like. ROS lets your robot’s software components communicate in real time. Rosbag lets you record that communication for later analysis or training. They’re complementary but independent — and understanding where each one starts and stops will save you hours of confusion as you build out your robotics stack.