SRDF β€” Semantic Robot Description

The SRDF (Semantic Robot Description Format) layer provides data structures, a parser, and a generator for MoveIt-compatible semantic information such as planning groups, named poses, and collision filters.

Data Models

class linkforge.core.SemanticRobotDescription(robot_name='', virtual_joints=<factory>, groups=<factory>, group_states=<factory>, end_effectors=<factory>, passive_joints=<factory>, disabled_collisions=<factory>, enabled_collisions=<factory>, no_default_collision_links=<factory>, link_sphere_approximations=<factory>, joint_properties=<factory>)[source]

Bases: object

Container for all semantic information (SRDF).

This class serves as the central repository for MoveIt-compatible metadata, including planning groups, collision filters, and named poses, that complement the kinematic robot model.

Parameters:
robot_name: str = ''
virtual_joints: Sequence[VirtualJoint]
groups: Sequence[PlanningGroup]
group_states: Sequence[GroupState]
end_effectors: Sequence[EndEffector]
passive_joints: Sequence[PassiveJoint]
disabled_collisions: Sequence[CollisionPair]
enabled_collisions: Sequence[CollisionPair]
joint_properties: Sequence[JointProperty]
__post_init__()[source]

Ensure all fields are tuples.

Return type:

None

with_prefix(prefix)[source]

Create a new description with prefixed name and all sub-elements.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

SemanticRobotDescription

Returns:

A new SemanticRobotDescription instance with all elements prefixed.

merge_with(other)[source]

Merge another semantic description into this one, deduplicating elements.

Parameters:

other (SemanticRobotDescription) – The other semantic description to merge into this one.

Return type:

SemanticRobotDescription

Returns:

A new SemanticRobotDescription instance containing the combined elements.

normalized()[source]

Return a new description with all components sorted.

This ensures that structural equality checks are order-independent.

Return type:

SemanticRobotDescription

__init__(robot_name='', virtual_joints=<factory>, groups=<factory>, group_states=<factory>, end_effectors=<factory>, passive_joints=<factory>, disabled_collisions=<factory>, enabled_collisions=<factory>, no_default_collision_links=<factory>, link_sphere_approximations=<factory>, joint_properties=<factory>)
Parameters:
class linkforge.core.PlanningGroup(name, links=<factory>, joints=<factory>, chains=<factory>, subgroups=<factory>)[source]

Bases: object

A named collection of links, joints, or chains used for motion planning.

Parameters:
name: str
joints: Sequence[str]
chains: Sequence[Chain]
subgroups: Sequence[str]
__post_init__()[source]

Validate planning group.

Return type:

None

with_prefix(prefix)[source]

Create a new planning group with prefixed name and sub-elements.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

PlanningGroup

Returns:

A new PlanningGroup instance with prefixed sub-elements.

__init__(name, links=<factory>, joints=<factory>, chains=<factory>, subgroups=<factory>)
Parameters:
class linkforge.core.Chain(base_link, tip_link)[source]

Bases: object

A kinematic chain defined by a base link and a tip link.

Parameters:
  • base_link (str)

  • tip_link (str)

__post_init__()[source]

Validate chain.

Return type:

None

with_prefix(prefix)[source]

Create a new chain with prefixed base and tip links.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

Chain

Returns:

A new Chain instance with prefixed link names.

__init__(base_link, tip_link)
Parameters:
  • base_link (str)

  • tip_link (str)

class linkforge.core.GroupState(name, group, joint_values=<factory>)[source]

Bases: object

A named set of joint values for a planning group (a pose).

Parameters:
name: str
group: str
joint_values: dict[str, Any]
__post_init__()[source]

Validate and normalize group state.

Return type:

None

with_prefix(prefix)[source]

Create a new group state with prefixed name, group, and joint names.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

GroupState

Returns:

A new GroupState instance with prefixed names.

__init__(name, group, joint_values=<factory>)
Parameters:
class linkforge.core.EndEffector(name, group, parent_link, parent_group=None)[source]

Bases: object

Defines a planning group as an end effector.

Parameters:
name: str
group: str
parent_group: str | None
__post_init__()[source]

Validate end effector.

Return type:

None

with_prefix(prefix)[source]

Create a new end effector with prefixed name, group, and links.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

EndEffector

Returns:

A new EndEffector instance with prefixed names.

__init__(name, group, parent_link, parent_group=None)
Parameters:
class linkforge.core.PassiveJoint(name)[source]

Bases: object

A joint that is not actuated but exists in the kinematic chain.

Parameters:

name (str)

name: str
__post_init__()[source]

Validate passive joint.

Return type:

None

with_prefix(prefix)[source]

Create a new passive joint with a prefixed name.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

PassiveJoint

Returns:

A new PassiveJoint instance with a prefixed name.

__init__(name)
Parameters:

name (str)

class linkforge.core.VirtualJoint(name, type, parent_frame, child_link)[source]

Bases: object

Connects the robot to a fixed frame in the world.

Parameters:
name: str
type: str
parent_frame: str
__post_init__()[source]

Validate virtual joint.

Return type:

None

with_prefix(prefix)[source]

Create a new virtual joint with prefixed name and child_link.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

VirtualJoint

Returns:

A new VirtualJoint instance with prefixed names.

__init__(name, type, parent_frame, child_link)
Parameters:
class linkforge.core.CollisionPair(link1, link2, reason=None)[source]

Bases: object

Represents a collision rule between two specific links.

Parameters:
link1: str
link2: str
reason: str | None
__post_init__()[source]

Validate collision pair.

Return type:

None

with_prefix(prefix)[source]

Create a new collision pair with prefixed link names.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

CollisionPair

Returns:

A new CollisionPair instance with prefixed link names.

__init__(link1, link2, reason=None)
Parameters:
class linkforge.core.LinkSphereApproximation(link, spheres=<factory>)[source]

Bases: object

Sphere-based collision geometry for a link.

Parameters:
spheres: Sequence[SrdfSphere]
with_prefix(prefix)[source]

Create a new approximation with a prefixed link name.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

LinkSphereApproximation

Returns:

A new LinkSphereApproximation instance with a prefixed link name.

__init__(link, spheres=<factory>)
Parameters:
class linkforge.core.SrdfSphere(center_x, center_y, center_z, radius)[source]

Bases: object

A collision sphere approximation.

Parameters:
center_x: float
center_y: float
center_z: float
radius: float
__init__(center_x, center_y, center_z, radius)
Parameters:
class linkforge.core.JointProperty(joint_name, property_name, value)[source]

Bases: object

Key-value metadata for a joint.

Parameters:
  • joint_name (str)

  • property_name (str)

  • value (str)

joint_name: str
property_name: str
value: str
with_prefix(prefix)[source]

Create a new joint property with a prefixed joint name.

Parameters:

prefix (str) – The namespace prefix to apply.

Return type:

JointProperty

Returns:

A new JointProperty instance with a prefixed joint name.

__init__(joint_name, property_name, value)
Parameters:
  • joint_name (str)

  • property_name (str)

  • value (str)


SRDF Parser

class linkforge.core.SRDFParser(max_file_size=104857600, sandbox_root=None, resource_resolver=None)[source]

Bases: RobotXMLParser[SemanticRobotDescription]

Semantic Robot Description Format (SRDF) Parser.

This parser converts SRDF XML content into a structured SemanticRobotDescription model. It supports MoveIt-specific tags such as planning groups, end effectors, and collision disabling.

Parameters:
__init__(max_file_size=104857600, sandbox_root=None, resource_resolver=None)[source]

Initialize SRDF parser.

Parameters:
  • max_file_size (int) – Maximum allowed file size in bytes.

  • sandbox_root (Path | None) – Optional root directory for security sandbox.

  • resource_resolver (IResourceResolver | None) – Optional resolver for URIs.

parse_string(content, **_kwargs)[source]

Parse SRDF content from a string.

Parameters:
  • content (str) – The raw SRDF XML string.

  • **kwargs – Additional options for future extensions.

  • _kwargs (Any)

Return type:

SemanticRobotDescription

Returns:

A SemanticRobotDescription model representing the SRDF.

Raises:
parse(filepath, **_kwargs)[source]

Load and parse an SRDF file from disk.

Parameters:
  • filepath (Path) – Path to the .srdf file.

  • **kwargs – Additional options (unused).

  • _kwargs (Any)

Return type:

SemanticRobotDescription

Returns:

A SemanticRobotDescription model.

Raises:

SRDF Generator

class linkforge.core.SRDFGenerator(pretty_print=True, srdf_path=None)[source]

Bases: RobotXMLGenerator

Semantic Robot Description Format (SRDF) generator.

Parameters:
__init__(pretty_print=True, srdf_path=None)[source]

Initialize SRDF generator.

Parameters:
  • pretty_print (bool) – If True, format XML with indentation for readability (default: True)

  • srdf_path (Path | None) – Path where SRDF will be saved.

generate(robot, validate=True, **kwargs)[source]

Generate SRDF XML string from robot.

Parameters:
  • robot (Robot) – Robot model with semantic description.

  • validate (bool) – Whether to validate robot structure before generation.

  • **kwargs (Any) – Additional generation options (passed to serializer).

Return type:

str

Returns:

SRDF XML as formatted string with proper indentation

generate_robot_element(robot)[source]

Generate SRDF XML Element tree from robot.

Parameters:

robot (Robot)

Return type:

Element


Usage Examples

Parse an existing SRDF file

from linkforge.core import SRDFParser
from pathlib import Path

srdf = SRDFParser().parse(Path("my_robot.srdf"))

print(f"Planning groups: {len(srdf.groups)}")
for group in srdf.groups:
    print(f"  {group.name}: {len(group.links)} links, {len(group.joints)} joints")

Build SRDF programmatically

from linkforge.core import (
    SemanticRobotDescription,
    PlanningGroup,
    GroupState,
    CollisionPair,
)

srdf = SemanticRobotDescription(
    robot_name="my_arm",
    groups=[
        PlanningGroup(
            name="arm",
            links=["base_link", "link1", "link2"],
            joints=["joint1", "joint2"],
        )
    ],
    group_states=[
        GroupState(name="home", group="arm", joint_values={"joint1": 0.0, "joint2": 0.0})
    ],
    disabled_collisions=[
        CollisionPair(link1="base_link", link2="link1", reason="Adjacent"),
    ],
)

Generate SRDF XML

from linkforge.core import SRDFGenerator

generator = SRDFGenerator()
srdf_string = generator.generate(srdf)

with open("my_robot.srdf", "w") as f:
    f.write(srdf_string)

Round-trip (parse β†’ modify β†’ re-generate)

from linkforge.core import SRDFParser, SRDFGenerator, CollisionPair
from pathlib import Path
import dataclasses

original = SRDFParser().parse(Path("robot.srdf"))

# Add a new collision exclusion
updated = dataclasses.replace(
    original,
    disabled_collisions=[
        *original.disabled_collisions,
        CollisionPair(link1="hand_link", link2="wrist_link", reason="Adjacent"),
    ],
)

output = SRDFGenerator().generate(updated)
Path("robot_updated.srdf").write_text(output)

Note

SRDF data is also produced automatically by RobotBuilder.export_srdf() when you use the group() and disable_collisions() helper methods. Direct use of the parser and generator is mainly needed when working with existing SRDF files. See the Composer reference for the higher-level API.