CodeTheRobot

ROS 2 Lyrical Luth · Lesson 18 of 86

URDF robot description

Links, joints, joint types, limits and validating a description.

Estimated time · 60–90 min

Learning goals

What you will understand

  • Explain urdf robot description in your own words
  • Use it in a small robotics example
  • Verify the result instead of assuming it worked

Understand the idea first

The mental model

URDF is an XML description of a robot's structure: links (rigid bodies) connected by joints (fixed, revolute, continuous, prismatic). The tree has exactly one root link. Joints define the parent, child, origin, axis and limits.

Check a file with check_urdf and view the tree with urdf_to_graphviz. A URDF alone does not move anything: robot_state_publisher turns it plus joint values into TF frames. Use metres, kilograms and radians throughout.

Guided lesson

Work through these steps

  1. 1.

    Source the ROS 2 Lyrical environment in a fresh terminal.

  2. 2.

    Read the urdf robot description example and identify what each line does.

  3. 3.

    Build only the affected package, source the workspace overlay, and run the example.

  4. 4.

    Inspect the result from a second terminal with the ros2 CLI or RViz2 and compare it with the expected result.

Worked example

Read it before you run it

<robot name="mini_arm">
<!-- Root element naming the robot. -->
  <link name="base_link"/>
<!-- The fixed base of the robot. -->
  <link name="upper_arm"/>
<!-- A moving link. -->
  <joint name="shoulder" type="revolute">
<!-- A joint that rotates within limits. -->
    <parent link="base_link"/>
<!-- Connected to the base... -->
    <child link="upper_arm"/>
<!-- ...and moves the upper arm. -->
    <origin xyz="0 0 0.1" rpy="0 0 0"/>
<!-- Joint sits 10 cm above the base with no rotation offset. -->
    <axis xyz="0 0 1"/>
<!-- Rotate about the Z axis. -->
    <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
<!-- Range in rad, maximum torque in N·m, speed in rad/s. -->
  </joint>
<!-- End of the joint. -->
</robot>
<!-- End of the robot. -->

What the example is doing

  1. 1.The ros2 commands query the running graph; they do not prove that a node's internal behavior is correct.
  2. 2.Build from the workspace root, then source install/setup.bash so the shell can discover the new package.
  3. 3.Use a second sourced terminal to inspect nodes and interfaces while the example runs.

Watch it run · Robot arm

See what this code does

The terminal types this lesson's practice solution and runs it. The scene shows the kind of robot behaviour that code drives. It plays by itself and loops.

tip x110 y58ROBOT ARM

Demo for URDF robot description. Expected result: robot name is: mini_arm

Practice code

Now type it yourself

Copy the starter into your ROS 2 package, replace every TODO, then build with colcon build and run it from a sourced terminal.

<robot name="mini_arm">
  <link name="base_link"/>
  <link name="upper_arm"/>
  <link name="forearm"/>
  <joint name="shoulder" type="revolute">
    <parent link="base_link"/>
    <child link="upper_arm"/>
    <axis xyz="0 0 1"/>
    <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
  </joint>
  <!-- TODO: add a revolute joint "elbow" from upper_arm to forearm about the Y axis with the same limits -->
</robot>

Expected output

robot name is: mini_arm
Stuck? Show the full solution (try it yourself first)
<robot name="mini_arm">
  <link name="base_link"/>
  <link name="upper_arm"/>
  <link name="forearm"/>
  <joint name="shoulder" type="revolute">
    <parent link="base_link"/>
    <child link="upper_arm"/>
    <axis xyz="0 0 1"/>
    <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
  </joint>
  <joint name="elbow" type="revolute">
    <parent link="upper_arm"/>
    <child link="forearm"/>
    <axis xyz="0 1 0"/>
    <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
  </joint>
</robot>

Expected result

How you know it worked

  • ROS_DISTRO is lyrical in every terminal used for the exercise.
  • The complete package from the exercise builds and the expected graph entity appears in a second terminal.

Practical exercise

Apply the lesson

Write a URDF for a two-link arm with shoulder and elbow joints, validate it with check_urdf, generate the graph with urdf_to_graphviz, and view it in RViz2.

Before you continue

  • ROS_DISTRO reports lyrical in every terminal you used
  • The example builds and runs without errors
  • You checked the result with a ros2 command, RViz2 or a test, not just by reading the code

If something goes wrong

ros2 cannot find a package or executable.

Source /opt/ros/lyrical/setup.bash, build from the workspace root, then source install/setup.bash in that terminal.

Nodes run but cannot discover each other.

Confirm both terminals use Lyrical, the same ROS_DOMAIN_ID, and compatible network/discovery settings.