Creating SRDF Files for MoveIt2 Planning Groups and IK: A Complete Guide

The Text-to-CAD repository provides a self-contained Python implementation that parses Semantic Robot Description Format (SRDF) files and exposes the information needed by the MoveIt2 motion-planning server for inverse kinematics and trajectory planning.

Creating SRDF files for MoveIt2 planning groups and IK is essential for setting up semantic robot descriptions that enable collision-aware motion planning. The earthtojake/text-to-cad repository contains a production-ready SRDF parser and MoveIt2 server integration that handles everything from XML parsing to runtime configuration injection. This guide walks through the complete workflow—parsing SRDF files, structuring planning groups, and feeding that data into MoveIt2 for pose solving and path planning.

SRDF Parsing Architecture

The SRDF parsing layer lives in skills/srdf/scripts/srdf/source.py. This module transforms raw XML-based .srdf files into a strongly-typed SrdfSource dataclass that MoveIt2 can consume.

Core Data Structures

The parser defines a frozen dataclass hierarchy for immutable SRDF representations:

  • SrdfChain – Serial kinematic chains within a planning group
  • SrdfPlanningGroup – Named collections of joints, links, chains, and subgroups
  • SrdfEndEffector – Link-to-effector mappings for IK targets
  • SrdfGroupState – Named joint value presets (numeric and finite constraints)
  • SrdfDisabledCollisionPair – Collision exclusions with heuristic sources (adjacent, sampled, etc.)
  • SrdfSource – Root container with file references, robot name, URDF linkage, and all parsed elements

Parsing Workflow

The read_srdf_source(path) function orchestrates parsing through these steps:

  1. Extension validation – Ensures the file path ends in .srdf
  2. XML root extraction – Validates the <robot> element and extracts robot_name
  3. Child tag iteration – Dispatches to specialized parsers for each SRDF element type
  4. Duplicate detection – _raise_on_duplicates catches naming conflicts early
  5. URDF resolution – _linked_urdf_ref handles both current (https://text-to-cad.dev/srdf) and legacy (https://text-to-cad.dev/explorer) namespaces

The resulting SrdfSource contains absolute and relative paths for hashing, planning group definitions, end-effector specifications, and collision policies.

MoveIt2 Server Integration

The runtime integration copies the parser logic into viewer/moveit2_server/moveit2_server/srdf_source.py and adds two critical utilities for MoveIt2 configuration.

Path Resolution and Security

_resolve_srdf_urdf_path converts relative URDF references into absolute filesystem paths while protecting against directory traversal attacks. This ensures that SRDF files can reference URDFs portably across different deployment environments.

Inventory Generation

_srdf_inventory_from_source serializes the SrdfSource into a JSON-compatible payload that matches MoveIt2's expected configuration schema. This includes:

  • Planning group hierarchies with joint and link names
  • End-effector parent and group mappings
  • Group state presets for common robot configurations
  • Disabled collision pairs for adjacent links

Request Handling Pipeline

The dispatcher in viewer/moveit2_server/moveit2_server/dispatcher.py processes SRDF-related JSON-RPC requests:

  1. Request type detection – Recognizes srdf.solvePose and srdf.planToPose methods
  2. Context extraction – Retrieves srdfPath from the request context
  3. Source loading – Calls read_srdf_source to parse the SRDF file
  4. Inventory validation – _validate_srdf_inventory ensures schema compliance
  5. Command building – _build_command embeds the inventory into request metadata

Finally, viewer/moveit2_server/moveit2_server/moveit_py.py assembles the MoveIt2 configuration dictionary, automatically injecting robot_description_semantic with the SRDF content when present.

Practical Code Examples

Parsing an SRDF File Manually

from pathlib import Path
from srdf.source import read_srdf_source

# Load and parse an SRDF file

srdf_path = Path("samples/robot.srdf")
srdf = read_srdf_source(srdf_path)

# Inspect planning group structure

print(f"Robot name: {srdf.robot_name}")
print("Planning groups:")
for grp in srdf.planning_groups:
    print(f"  – {grp.name}: joints={grp.joint_names}, links={grp.link_names}")
    

# Access end-effector definitions

for ee in srdf.end_effectors:
    print(f"End effector '{ee.name}' on link '{ee.parent_link}'")

Using SRDF Data in a MoveIt2 Request

import json
from moveit2_server.context import build_context_from_request

# Construct a JSON-RPC request for IK solving

request = {
    "id": "req-1",
    "type": "srdf.solvePose",
    "payload": {
        "file": "robot.srdf",
        "srdfPath": "/absolute/path/to/robot.srdf",
        "planningGroups": ["arm"],
        "ikGoal": {
            "position": [0.1, 0.2, 0.3],
            "orientation": [0, 0, 0, 1]
        },
    },
    "context": {}
}

# Build enriched context with full SRDF inventory

context = build_context_from_request(request)
print(json.dumps(context, indent=2))

The output includes srdfInventory, urdfPath, and robot_description_semantic fields ready for MoveIt2 initialization.

Running the Test Suite


# Execute all repository tests

./scripts/test/test.sh

# Run SRDF-specific unit tests only

python -m unittest tests/python/skills/srdf/test_source.py

# Validate MoveIt2 integration

python -m unittest tests/python/viewer/moveit2_server/test_moveit_py_adapter.py

SRDF File Structure Reference

A valid SRDF for MoveIt2 planning groups and IK requires these key elements:

<?xml version="1.0" encoding="UTF-8"?>
<robot name="my_robot" xmlns="https://text-to-cad.dev/srdf">
    
    <!-- URDF reference for geometry and kinematics -->
    <urdf package="my_robot_description" file="urdf/robot.urdf"/>
    
    <!-- Planning group definition -->
    <group name="arm">
        <chain base_link="base_link" tip_link="tool0"/>
    </group>
    
    <!-- End effector for IK targets -->
    <end_effector name="gripper" parent_link="tool0" group="arm"/>
    
    <!-- Named configuration states -->
    <group_state name="home" group="arm">
        <joint name="joint1" value="0.0"/>
    </group_state>
    
    <!-- Collision exclusions -->
    <disable_collisions link1="base_link" link2="link1" reason="adjacent"/>
    
</robot>

The chain element is preferred for defining serial manipulators because it automatically derives joint and link membership from the URDF kinematic tree.

Key Implementation Files

File Purpose
skills/srdf/scripts/srdf/source.py Core parser with dataclass definitions, XML validation, and duplicate detection
viewer/moveit2_server/moveit2_server/srdf_source.py Runtime parser copy with path resolution and inventory serialization
viewer/moveit2_server/moveit2_server/dispatcher.py Request routing for srdf.solvePose and srdf.planToPose methods
viewer/moveit2_server/moveit2_server/moveit_py.py MoveIt2 configuration builder with automatic SRDF injection
tests/python/skills/srdf/test_source.py Unit tests covering valid SRDF, legacy namespace support, and error conditions
tests/python/viewer/moveit2_server/test_moveit_py_adapter.py Integration test validating end-to-end SRDF-to-MoveIt2 configuration

Summary

  • SRDF parsing in source.py converts XML to typed SrdfSource objects with full validation and duplicate detection
  • Planning groups are defined via group elements containing joints, links, chains, or subgroups
  • End effectors map IK targets to specific links within planning groups
  • MoveIt2 integration automatically resolves URDF paths, builds inventory payloads, and injects robot_description_semantic
  • Legacy namespace support ensures backward compatibility with older https://text-to-cad.dev/explorer SRDF files

Frequently Asked Questions

What SRDF elements are required for MoveIt2 inverse kinematics?

At minimum, you need a group defining your kinematic chain and an end_effector specifying the IK target link. The chain element is recommended for serial manipulators because it automatically populates joint and link membership from URDF parent-child relationships. According to the earthtojake/text-to-cad source code, the parser enforces unique names across all elements through _raise_on_duplicates.

How does the parser handle URDF references in SRDF files?

The _linked_urdf_ref helper in source.py reads namespaced urdf elements supporting both current (https://text-to-cad.dev/srdf) and legacy (https://text-to-cad.dev/explorer) XML namespaces. The MoveIt2 server then uses _resolve_srdf_urdf_path to convert these package-relative or absolute references into validated filesystem paths with traversal protection.

Can I use group states for pre-defined robot configurations?

Yes. group_state elements define named joint value sets that MoveIt2 can use as motion planning start or goal states. The parser validates that joint values are numeric and finite, rejecting NaN or infinite entries. These states appear in the serialized inventory as presets for the specified planning group.

What happens if my SRDF contains duplicate planning group names?

The parser raises a descriptive error before any MoveIt2 interaction occurs. The _raise_on_duplicates function scans all named elements—groups, end effectors, and group states—and fails fast with the duplicate identifier and element type. This prevents subtle runtime failures in the motion planning server.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →