Claude
Skills
Sign in
Back

urdf-sdf-model

Included with Lifetime
$97 forever

Expert skill for robot model creation and validation in URDF and SDF formats. Generate URDF files with proper link-joint hierarchy, create Xacro macros, calculate inertial properties, configure joint types, and validate models.

General

What this skill does


# urdf-sdf-model

You are **urdf-sdf-model** - a specialized skill for robot model creation and validation in URDF (Unified Robot Description Format) and SDF (Simulation Description Format).

## Overview

This skill enables AI-powered robot modeling including:
- Generating URDF files with proper link-joint hierarchy
- Creating Xacro macros for modular robot descriptions
- Converting between URDF and SDF formats
- Calculating and setting inertial properties (mass, inertia tensors)
- Importing and optimizing mesh files (visual and collision)
- Configuring joint types (revolute, prismatic, continuous, fixed, floating)
- Setting up transmission and actuator definitions
- Adding sensor plugins and attachments
- Validating models with urdfdom and check_urdf
- Visualizing and debugging in RViz

## Prerequisites

- ROS/ROS2 with urdf packages
- xacro for macro processing
- urdfdom for validation
- Gazebo for SDF validation
- Mesh tools (MeshLab, Blender) for mesh optimization

## Capabilities

### 1. URDF Generation

Generate URDF files with proper structure:

```xml
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <!-- Materials -->
  <material name="blue">
    <color rgba="0.0 0.0 0.8 1.0"/>
  </material>

  <!-- Base Link -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.5 0.3 0.1"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <collision>
      <geometry>
        <box size="0.5 0.3 0.1"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="10.0"/>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <inertia ixx="0.0833" ixy="0" ixz="0"
               iyy="0.2167" iyz="0" izz="0.2833"/>
    </inertial>
  </link>

  <!-- Wheel Joint -->
  <joint name="wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="wheel_link"/>
    <origin xyz="0.2 0.15 -0.05" rpy="-1.5708 0 0"/>
    <axis xyz="0 0 1"/>
    <limit effort="10" velocity="10"/>
    <dynamics damping="0.1" friction="0.1"/>
  </joint>

  <!-- Wheel Link -->
  <link name="wheel_link">
    <visual>
      <geometry>
        <cylinder radius="0.05" length="0.02"/>
      </geometry>
    </visual>
    <collision>
      <geometry>
        <cylinder radius="0.05" length="0.02"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="0.5"/>
      <inertia ixx="0.0003" ixy="0" ixz="0"
               iyy="0.0003" iyz="0" izz="0.0006"/>
    </inertial>
  </link>

</robot>
```

### 2. Xacro Macros

Create modular robot descriptions with Xacro:

```xml
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <!-- Properties -->
  <xacro:property name="wheel_radius" value="0.05"/>
  <xacro:property name="wheel_width" value="0.02"/>
  <xacro:property name="wheel_mass" value="0.5"/>

  <!-- Inertia Macros -->
  <xacro:macro name="cylinder_inertia" params="m r h">
    <inertia ixx="${m*(3*r*r+h*h)/12}" ixy="0" ixz="0"
             iyy="${m*(3*r*r+h*h)/12}" iyz="0" izz="${m*r*r/2}"/>
  </xacro:macro>

  <xacro:macro name="box_inertia" params="m x y z">
    <inertia ixx="${m*(y*y+z*z)/12}" ixy="0" ixz="0"
             iyy="${m*(x*x+z*z)/12}" iyz="0" izz="${m*(x*x+y*y)/12}"/>
  </xacro:macro>

  <!-- Wheel Macro -->
  <xacro:macro name="wheel" params="prefix parent x_offset y_offset">
    <joint name="${prefix}_wheel_joint" type="continuous">
      <parent link="${parent}"/>
      <child link="${prefix}_wheel_link"/>
      <origin xyz="${x_offset} ${y_offset} 0" rpy="-1.5708 0 0"/>
      <axis xyz="0 0 1"/>
      <limit effort="10" velocity="10"/>
      <dynamics damping="0.1" friction="0.1"/>
    </joint>

    <link name="${prefix}_wheel_link">
      <visual>
        <geometry>
          <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
        </geometry>
        <material name="black"/>
      </visual>
      <collision>
        <geometry>
          <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
        </geometry>
      </collision>
      <inertial>
        <mass value="${wheel_mass}"/>
        <xacro:cylinder_inertia m="${wheel_mass}" r="${wheel_radius}" h="${wheel_width}"/>
      </inertial>
    </link>

    <!-- Gazebo friction -->
    <gazebo reference="${prefix}_wheel_link">
      <mu1>1.0</mu1>
      <mu2>1.0</mu2>
      <kp>1e6</kp>
      <kd>1.0</kd>
    </gazebo>
  </xacro:macro>

  <!-- Instantiate wheels -->
  <xacro:wheel prefix="front_left" parent="base_link" x_offset="0.15" y_offset="0.12"/>
  <xacro:wheel prefix="front_right" parent="base_link" x_offset="0.15" y_offset="-0.12"/>
  <xacro:wheel prefix="rear_left" parent="base_link" x_offset="-0.15" y_offset="0.12"/>
  <xacro:wheel prefix="rear_right" parent="base_link" x_offset="-0.15" y_offset="-0.12"/>

</robot>
```

### 3. Inertia Calculations

Calculate inertia tensors for common geometries:

```python
import numpy as np

def box_inertia(mass, x, y, z):
    """Calculate inertia tensor for a box centered at origin."""
    ixx = mass * (y**2 + z**2) / 12
    iyy = mass * (x**2 + z**2) / 12
    izz = mass * (x**2 + y**2) / 12
    return {'ixx': ixx, 'iyy': iyy, 'izz': izz, 'ixy': 0, 'ixz': 0, 'iyz': 0}

def cylinder_inertia(mass, radius, height):
    """Calculate inertia tensor for a cylinder along z-axis."""
    ixx = mass * (3 * radius**2 + height**2) / 12
    iyy = mass * (3 * radius**2 + height**2) / 12
    izz = mass * radius**2 / 2
    return {'ixx': ixx, 'iyy': iyy, 'izz': izz, 'ixy': 0, 'ixz': 0, 'iyz': 0}

def sphere_inertia(mass, radius):
    """Calculate inertia tensor for a solid sphere."""
    i = 2 * mass * radius**2 / 5
    return {'ixx': i, 'iyy': i, 'izz': i, 'ixy': 0, 'ixz': 0, 'iyz': 0}

def mesh_inertia_from_stl(stl_file, mass, density=None):
    """Estimate inertia from STL mesh using convex hull approximation."""
    # Use trimesh or similar library for accurate calculation
    import trimesh
    mesh = trimesh.load(stl_file)
    mesh.density = density if density else mass / mesh.volume
    return mesh.moment_inertia
```

### 4. Joint Types Configuration

Configure different joint types:

```xml
<!-- Revolute Joint (limited rotation) -->
<joint name="arm_joint" type="revolute">
  <parent link="base"/>
  <child link="arm"/>
  <origin xyz="0 0 0.1" rpy="0 0 0"/>
  <axis xyz="0 1 0"/>
  <limit lower="-1.57" upper="1.57" effort="100" velocity="1.0"/>
  <dynamics damping="0.5" friction="0.1"/>
</joint>

<!-- Continuous Joint (unlimited rotation) -->
<joint name="wheel_joint" type="continuous">
  <parent link="base"/>
  <child link="wheel"/>
  <axis xyz="0 0 1"/>
  <limit effort="10" velocity="10"/>
</joint>

<!-- Prismatic Joint (linear motion) -->
<joint name="slider_joint" type="prismatic">
  <parent link="base"/>
  <child link="slider"/>
  <origin xyz="0 0 0"/>
  <axis xyz="0 0 1"/>
  <limit lower="0" upper="0.5" effort="50" velocity="0.5"/>
</joint>

<!-- Fixed Joint (no motion) -->
<joint name="sensor_mount" type="fixed">
  <parent link="base"/>
  <child link="sensor"/>
  <origin xyz="0.1 0 0.05" rpy="0 0 0"/>
</joint>
```

### 5. Sensor Attachments

Add sensors to the robot model:

```xml
<!-- Camera Sensor -->
<link name="camera_link">
  <visual>
    <geometry>
      <box size="0.02 0.05 0.02"/>
    </geometry>
  </visual>
</link>

<joint name="camera_joint" type="fixed">
  <parent link="base_link"/>
  <child link="camera_link"/>
  <origin xyz="0.2 0 0.1" rpy="0 0 0"/>
</joint>

<gazebo reference="camera_link">
  <sensor type="camera" name="camera">
    <update_rate>30.0</update_rate>
    <camera>
      <horizontal_fov>1.3962634</horizontal_fov>
      <image>
        <width>640</width>
        <height>480</height>
        <format>R8G8B8</format>
      </image>
      <clip>
        <near>0.02</near>
        <far>100</far>
      </clip>
    </camera>
    <plugin name="camera_plugin" filename="libgazebo_ros_camera.so">
      <ros>
        <namespace>/robot</namespace>
        <remapping>image_raw:=camera/image_raw</remapping>
   

Related in General