ワンクリックで
urdf-fundamentals
Core URDF/Xacro syntax, joint types, kinematic structures, and URDF validation for robot descriptions
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Core URDF/Xacro syntax, joint types, kinematic structures, and URDF validation for robot descriptions
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | urdf-fundamentals |
| description | Core URDF/Xacro syntax, joint types, kinematic structures, and URDF validation for robot descriptions |
This skill provides comprehensive guidance on creating, structuring, and validating URDF (Unified Robot Description Format) files for robot descriptions.
Use this skill when:
Every URDF file has this basic structure:
<?xml version="1.0"?>
<robot name="robot_name">
<!-- Define links (rigid bodies) -->
<link name="base_link">
<!-- Visual geometry for rendering -->
<visual>
<geometry>
<box size="0.5 0.3 0.1"/>
</geometry>
<material name="blue">
<color rgba="0 0 1 1"/>
</material>
</visual>
<!-- Collision geometry for physics -->
<collision>
<geometry>
<box size="0.5 0.3 0.1"/>
</geometry>
</collision>
<!-- Inertial properties for dynamics -->
<inertial>
<mass value="5.0"/>
<inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.1"/>
</inertial>
</link>
<!-- Define joints (connections between links) -->
<joint name="base_to_wheel" type="continuous">
<parent link="base_link"/>
<child link="wheel_link"/>
<origin xyz="0.2 0.2 0" rpy="0 1.57 0"/>
<axis xyz="0 1 0"/>
</joint>
<!-- Define other links -->
<link name="wheel_link">
<!-- ... geometry ... -->
</link>
</robot>
<link> - Represents a rigid body in the robot:
name - Unique identifier<visual>, <collision>, <inertial> elements<joint> - Represents a connection between two links:
name - Unique identifiertype - Joint type (revolute, continuous, prismatic, fixed, etc.)<parent> - Parent link name<child> - Child link name<origin> - Relative position and orientation<axis> - Direction and rotation/translation axis<limit> - Joint constraints (for movable joints)<origin> - Specifies relative pose:
xyz - Position (x, y, z in meters)rpy - Orientation (roll, pitch, yaw in radians)Used for display and rendering:
<link name="example_link">
<visual>
<!-- Geometry type and dimensions -->
<geometry>
<box size="x y z"/>
<!-- or -->
<cylinder radius="r" length="l"/>
<!-- or -->
<sphere radius="r"/>
<!-- or -->
<mesh filename="package://robot_name/meshes/part.stl" scale="0.001 0.001 0.001"/>
</geometry>
<!-- Optional: Position and orientation within link -->
<origin xyz="0 0 0" rpy="0 0 0"/>
<!-- Optional: Material coloring -->
<material name="blue">
<color rgba="0 0 1 1"/> <!-- R G B Alpha (0-1) -->
</material>
</visual>
</link>
Geometry types:
<box size="x y z"/> - Rectangular box in meters<cylinder radius="r" length="l"/> - Cylinder with radius and length in meters<sphere radius="r"/> - Sphere with radius in meters<mesh filename="path" scale="sx sy sz"/> - External 3D mesh file (STL, DAE, OBJ)Material colors (RGBA):
rgba="1 0 0 1" - Redrgba="0 1 0 1" - Greenrgba="0 0 1 1" - Bluergba="1 1 1 1" - Whitergba="0 0 0 1" - BlackUsed for physics simulation and collision detection. Should typically be simpler than visual geometry:
<link name="complex_part">
<visual>
<!-- Detailed visual mesh -->
<geometry>
<mesh filename="package://robot/meshes/detailed_part.stl"/>
</geometry>
</visual>
<collision>
<!-- Simplified collision boxes -->
<geometry>
<box size="0.5 0.3 0.1"/>
</geometry>
</collision>
</link>
Best practices:
<link name="gripper">
<collision>
<origin xyz="0 0 0"/>
<geometry><box size="0.1 0.2 0.05"/></geometry>
</collision>
<collision>
<origin xyz="0.08 0.1 0"/>
<geometry><box size="0.04 0.1 0.05"/></geometry>
</collision>
</link>
Define mass and rotational inertia for dynamics simulation:
<link name="base_link">
<inertial>
<!-- Mass in kilograms -->
<mass value="5.0"/>
<!-- Inertia tensor (moment of inertia) -->
<!-- ixx, iyy, izz = rotational inertia about x, y, z axes -->
<!-- ixy, ixz, iyz = products of inertia (usually 0 for symmetric objects) -->
<inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.2"/>
<!-- Optional: Center of mass offset from link origin -->
<origin xyz="0 0 0.05" rpy="0 0 0"/>
</inertial>
</link>
Computing inertia:
I = (1/12) * m * (h^2 + d^2) where h, d are dimensionsI_x = I_y = (1/12) * m * (3*r^2 + h^2), I_z = (1/2) * m * r^2I = (2/5) * m * r^2Simplified approach: If exact inertia is unknown, use rough estimates:
<inertial>
<mass value="1.0"/>
<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
No movement - connects two links rigidly:
<joint name="fixed_joint" type="fixed">
<parent link="base_link"/>
<child link="sensor_link"/>
<origin xyz="0.1 0 0.05" rpy="0 0 0"/>
</joint>
Use for:
Rotational movement with limits (like a door hinge):
<joint name="shoulder_joint" type="revolute">
<parent link="base_link"/>
<child link="arm_link"/>
<origin xyz="0 0 0.3" rpy="0 0 0"/>
<axis xyz="0 1 0"/> <!-- Rotate around Y axis -->
<limit lower="-1.57" upper="1.57" effort="50" velocity="1.0"/>
</joint>
Parameters:
<axis> - Rotation axis (unit vector, typically one value = 1)<limit>:
lower, upper - Min/max angles in radianseffort - Maximum torque in Newton-metersvelocity - Maximum angular velocity in rad/sCommon axes:
xyz="1 0 0" - Rotate around X (roll)xyz="0 1 0" - Rotate around Y (pitch)xyz="0 0 1" - Rotate around Z (yaw)Unlimited rotation (like a wheel):
<joint name="wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="wheel_link"/>
<origin xyz="0.2 0.15 0" rpy="0 1.57 0"/>
<axis xyz="0 1 0"/>
</joint>
Use for:
Note: No <limit> element needed
Linear sliding movement (like a piston):
<joint name="linear_actuator" type="prismatic">
<parent link="base_link"/>
<child link="piston_link"/>
<origin xyz="0 0 0" rpy="0 0 0"/>
<axis xyz="0 0 1"/> <!-- Move along Z axis -->
<limit lower="0" upper="0.2" effort="100" velocity="0.1"/>
</joint>
Parameters:
<axis> - Direction of movement (unit vector)<limit>:
lower, upper - Min/max position in meterseffort - Maximum force in Newtonsvelocity - Maximum linear velocity in m/sMovement in a 2D plane (advanced, less common)
Free 6-DOF movement (for flying robots or underwater vehicles)
Always specify limits for revolute joints:
<!-- Limited rotation: safe joint -->
<joint name="elbow" type="revolute">
<axis xyz="0 1 0"/>
<limit lower="-2.0" upper="2.0" effort="30" velocity="1.5"/>
<!-- Can rotate -2 to +2 radians (~-114 to +114 degrees) -->
<!-- Max torque: 30 Nm, Max speed: 1.5 rad/s -->
</joint>
If you forget limits: Many simulators will refuse to load the file!
A robot is organized as a tree of links connected by joints:
base_link (root)
|
| shoulder_joint (revolute)
|
arm_link
|
| elbow_joint (revolute)
|
forearm_link
|
| wrist_joint (revolute)
|
hand_link
URDF representation:
<robot name="robot_arm">
<!-- Root link -->
<link name="base_link">
<visual>
<geometry><box size="0.3 0.3 0.1"/></geometry>
</visual>
</link>
<!-- First joint and child link -->
<joint name="shoulder_joint" type="revolute">
<parent link="base_link"/>
<child link="arm_link"/>
<origin xyz="0 0 0.15"/>
<axis xyz="0 0 1"/>
<limit lower="-1.57" upper="1.57" effort="50" velocity="1"/>
</joint>
<link name="arm_link">
<visual>
<geometry><cylinder radius="0.05" length="0.4"/></geometry>
</visual>
</link>
<!-- Continue chain... -->
</robot>
base_link base_link (root)
/ | \ \
/ | \ \
fl_hip fr_hip rl_hip rr_hip
/ / / /
fl_udeg fr_uleg rl_uleg rr_uleg
/ / / /
fl_leg fr_leg rl_leg rr_leg
<origin>The xyz and rpy in <origin> define the transform from parent to child:
<joint name="example" type="fixed">
<parent link="base_link"/>
<child link="camera_link"/>
<origin xyz="0.1 0 0.2" rpy="0 0 0"/>
<!-- camera_link is positioned 0.1m forward, 0.2m up from base_link -->
<!-- With no rotation -->
</joint>
Three rotations applied in order: X (roll), Y (pitch), Z (yaw):
<!-- 90 degree pitch (rotate around Y axis) -->
<origin xyz="0 0 0" rpy="0 1.57 0"/>
<!-- 45 degree roll and yaw (rotate around X and Z) -->
<origin xyz="1 2 3" rpy="0.785 0 0.785"/>
Converting degrees to radians: radians = degrees * π / 180
These are different:
<link name="camera">
<visual>
<!-- Position of visual geometry WITHIN the link -->
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry><box size="0.05 0.05 0.05"/></geometry>
</visual>
</link>
<joint name="camera_mount" type="fixed">
<!-- Position of camera_link RELATIVE TO parent (base_link) -->
<origin xyz="0.1 0 0.2" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="camera"/>
</joint>
Mesh files and resources use package-relative paths:
<!-- Correct: package:// URI (portable across machines) -->
<mesh filename="package://my_robot/meshes/wheel.stl"/>
<!-- Wrong: Absolute path (not portable) -->
<mesh filename="/home/user/ros_ws/my_robot/meshes/wheel.stl"/>
<!-- Wrong: Relative path (fragile) -->
<mesh filename="meshes/wheel.stl"/>
The extension finds packages by:
package.xml filesBest practice: Always use package:// URIs in your URDF files.
Typical project structure:
my_robot/
├── package.xml
├── urdf/
│ └── my_robot.urdf (or .xacro)
└── meshes/
├── base.stl
├── wheel.stl
└── gripper/
├── finger_left.stl
└── finger_right.stl
References in URDF:
<mesh filename="package://my_robot/meshes/base.stl"/>
<mesh filename="package://my_robot/meshes/wheel.stl"/>
<mesh filename="package://my_robot/meshes/gripper/finger_left.stl"/>
Mesh units may differ from URDF (which uses meters):
<!-- STL exported in millimeters, convert to meters -->
<mesh filename="package://my_robot/meshes/part.stl" scale="0.001 0.001 0.001"/>
<!-- Scale by 50% -->
<mesh filename="package://my_robot/meshes/part.stl" scale="0.5 0.5 0.5"/>
For complex geometry that cannot be created with basic shapes (boxes, cylinders, spheres), use OpenSCAD:
⚠️ IMPORTANT: Unit Mismatch
0.001 to convert mm → mWorkflow:
.scad file with your geometry logic in millimeters (e.g., meshes/robot_foot.scad).scad → .stl when saved.stl file in your URDF/Xacro (not the .scad)scale="0.001 0.001 0.001" to convert from mm to metersExample:
Create meshes/robot_foot.scad (dimensions in millimeters):
// robot_foot.scad - Complex foot geometry
// All dimensions are in MILLIMETERS
module robot_foot(length=100, width=50, height=20) {
difference() {
// Main foot body: 100mm × 50mm × 20mm
cube([length, width, height]);
// Mounting holes: 5mm radius
translate([20, width/2, 0])
cylinder(h=height, r=5);
translate([length-20, width/2, 0])
cylinder(h=height, r=5);
}
}
// Generate foot with dimensions in mm
robot_foot(length=120, width=60, height=25);
Reference in URDF (with 0.001 scale to convert mm → m):
<link name="foot">
<visual>
<geometry>
<!--
Reference the generated STL file (not the .scad).
Scale 0.001 converts from OpenSCAD millimeters to URDF meters.
The foot will be 0.12m × 0.06m × 0.025m in the robot.
-->
<mesh filename="package://my_robot/meshes/robot_foot.stl" scale="0.001 0.001 0.001"/>
</geometry>
</visual>
<collision>
<geometry>
<mesh filename="package://my_robot/meshes/robot_foot.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
Important notes:
scale="0.001 0.001 0.001" when referencing OpenSCAD-generated STL files.scad) stays in millimeters - this is standard CAD convention.stl file in URDF, never the .scad.scad file is the source; the .stl is what renders.scad file, the extension automatically regenerates the .stl.scad files can referenceError: "Duplicate link/joint name"
Error: "Parent link not found"
<!-- Wrong: Parent link doesn't exist -->
<joint name="wheel" type="continuous">
<parent link="baes_link"/> <!-- Typo! -->
<child link="wheel"/>
</joint>
Error: "Joint limits missing"
<!-- Wrong: revolute joint without limits -->
<joint name="arm" type="revolute">
<axis xyz="0 1 0"/>
<!-- Missing <limit> tag -->
</joint>
<!-- Correct: Always specify limits -->
<joint name="arm" type="revolute">
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="1.57" effort="50" velocity="1"/>
</joint>
Error: "Mesh file not found"
Follow ROS naming standards:
<!-- ✓ Good: lowercase with underscores -->
<link name="base_link"/>
<link name="left_front_wheel"/>
<joint name="base_to_wheel"/>
<joint name="shoulder_joint"/>
<!-- ✗ Bad: CamelCase or mixed case -->
<link name="BaseLink"/>
<link name="leftFrontWheel"/>
<joint name="baseToWheel"/>
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Root link representing the robot base -->
<link name="base_link">
<visual>
<geometry>
<!-- 50cm wide, 30cm deep, 10cm tall -->
<box size="0.5 0.3 0.1"/>
</geometry>
<material name="base_color">
<color rgba="0.8 0.8 0.8 1"/> <!-- Light gray -->
</material>
</visual>
<!-- Collision geometry approximates base as simple box -->
<collision>
<geometry>
<box size="0.5 0.3 0.1"/>
</geometry>
</collision>
</link>
<!-- Front-left wheel connection -->
<joint name="base_to_fl_wheel" type="continuous">
<parent link="base_link"/>
<child link="fl_wheel"/>
<!-- Position: 0.15m forward, 0.15m left, 0.05m down from base center -->
<origin xyz="0.15 0.15 -0.05" rpy="0 1.5708 0"/>
<!-- Wheel rotates around Y axis (left-right) -->
<axis xyz="0 1 0"/>
</joint>
<link name="fl_wheel">
<visual>
<geometry>
<!-- 10cm diameter wheel, 5cm wide -->
<cylinder radius="0.05" length="0.05"/>
</geometry>
<material name="black">
<color rgba="0.1 0.1 0.1 1"/>
</material>
</visual>
</link>
</robot>
The extension includes a custom 3D viewer for mesh files:
.stl, .dae, .glb, .gltf files in 3D| Joint Type | Movement | Use Case |
|---|---|---|
| Fixed | None | Sensors, non-moving attachments |
| Revolute | Rotational (limited) | Robot arms, articulated segments |
| Continuous | Rotational (unlimited) | Wheels, rotating shafts |
| Prismatic | Linear (limited) | Actuators, sliding mechanisms |
| Planar | 2D planar | Advanced wheeled robots |
| Floating | Free 6-DOF | Flying/underwater robots |
✅ DO:
base_link as the rootpackage:// URIs for mesh files❌ DON'T:
Use this skill when modifying OpenSCAD files where the user wants to use the customizer features (parameter parsing, UI generation, and conversion to STL/SVG/GLB with parameter overrides).
Use this skill when modifying OpenSCAD files (*.scad)
Use when creating URDF or Xacro files which require non-trivial geometry
Discover, recommend, and install OpenSCAD libraries for your projects. Use when: needing geometry functions, seeking existing modules before creating, managing library dependencies, or exploring what libraries are available in your workspace.
Guide for creating appropriate geometry in URDF files - basic shapes vs OpenSCAD vs mesh files
Convert URDF files to Xacro format with macros for reusable components like wheels, sensors, and repeated geometry