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

> Master SRDF files for MoveIt2 planning groups and IK. This guide details parsing SRDFs with Text-to-CAD for seamless motion planning and inverse kinematics.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-08-03

---

**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`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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

```python
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

```python
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

```bash

# 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
<?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`](https://github.com/earthtojake/text-to-cad/blob/main/skills/srdf/scripts/srdf/source.py) | Core parser with dataclass definitions, XML validation, and duplicate detection |
| [`viewer/moveit2_server/moveit2_server/srdf_source.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/srdf_source.py) | Runtime parser copy with path resolution and inventory serialization |
| [`viewer/moveit2_server/moveit2_server/dispatcher.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/dispatcher.py) | Request routing for `srdf.solvePose` and `srdf.planToPose` methods |
| [`viewer/moveit2_server/moveit2_server/moveit_py.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/moveit_py.py) | MoveIt2 configuration builder with automatic SRDF injection |
| [`tests/python/skills/srdf/test_source.py`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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`](https://github.com/earthtojake/text-to-cad/blob/main/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.