Parsers

URDF, XACRO, and SRDF parsers for converting files into Python objects.

URDF Parser

URDFParser Class

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

Bases: RobotXMLParser[Robot]

Refined URDF Parser using a class-based interface.

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

Initialize parser.

Parameters:
  • max_file_size (int) – Maximum allowed file size in bytes (default: 100MB)

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

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

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

Parse URDF file into a Robot model using iterative parsing.

This implementation uses iterparse to maintain O(1) memory complexity even for massive URDF files.

Parameters:
  • filepath (Path) – Path to the input file

  • **kwargs – Additional parsing options

  • _kwargs (Any)

Return type:

Robot

Returns:

The generic Robot model (Intermediate Representation)

Raises:
parse_string(content, source_directory=None, **_kwargs)[source]

Parse URDF from string.

Parameters:
  • content (str) – URDF XML content as string

  • source_directory (Path | None) – Base directory for relative mesh path resolution

  • **kwargs – Additional parsing options

  • _kwargs (Any)

Return type:

Robot

Returns:

The generic Robot model (Intermediate Representation)

Raises:

XACRO Parser

XACROParser Class

The XACROParser provides native, pure-Python resolution of XACRO files. It handles macros, properties, math expressions, and conditional blocks without external ROS dependencies.

class linkforge.core.XACROParser[source]

Bases: object

Independent XACRO resolution utility.

This class acts as a pre-processor for URDF/SRDF files that use the XACRO templating system. It resolves templates into plain XML strings.

resolve(filepath, **kwargs)[source]

Resolve a XACRO file into a plain XML string.

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

  • **kwargs (Any) – Custom arguments and properties for resolution. - search_paths: List of paths to search for includes. - start_dir: Base directory for relative includes. - All other keys are passed as $(arg) values.

Return type:

str

Returns:

The fully resolved XML as a string.

Raises:

XacroResolver Class (Internal)

The internal engine used by XACROParser for hierarchical property resolution and macro substitution.

class linkforge.core.XacroResolver(search_paths=None, max_depth=2000, start_dir=None)[source]

Bases: object

Lightweight XACRO resolver with macro and math support.

Parameters:
__init__(search_paths=None, max_depth=2000, start_dir=None)[source]

Initialize the XACRO resolver.

Parameters:
  • search_paths (list[Path] | None) – List of additional directories to search for includes.

  • max_depth (int) – Maximum recursion depth for macro expansions and includes.

  • start_dir (Path | None) – Base directory for resolving package:// URIs and relative paths.

resolve_file(filepath)[source]

Resolve a XACRO file and return the final XML string.

Parameters:

filepath (Path) – Path to the XACRO file to resolve.

Return type:

str

Returns:

The fully resolved XML as a string.

Raises:
resolve_string(xml_string)[source]

Resolve a XACRO string and return the final XML string.

Parameters:

xml_string (str) – The XACRO XML content as a string.

Return type:

str

Returns:

The fully resolved XML as a string.

Raises:

RobotXacroError – If XML is malformed or resolution fails

resolve_element(element)[source]

Process a single element recursively, tracking depth.

Parameters:

element (Element) – The XML element to resolve.

Return type:

Element

Returns:

The resolved XML element or a container.

Raises:

RobotXacroRecursionError – If maximum recursion depth is exceeded

Note

Structural Caching: XacroResolver implements a two-phase approach for large modular robot cascades. In the Structural Phase, all xacro:include tags are resolved once into an in-memory template tree. In the Evaluation Phase, arguments and conditional blocks are injected into the cached tree. This means a single Xacro file can be evaluated many times with different parameters (e.g., different prefix= values for two arms) without re-reading or re-parsing any files.

RobotXMLParser Class (Base)

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

Bases: RobotParser[T], Generic[T]

Abstract base class for XML-based robotics format parsers.

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

Initialize base XML 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_xacro(filepath, **kwargs)[source]

Resolve XACRO then parse the resulting XML string.

This is a convenience wrapper around XACROParser.resolve() + parse_string().

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

  • **kwargs (Any) – Arguments passed to both the resolver and the format parser.

Return type:

TypeVar(T)

Returns:

The parsed robot model (T).

Raises:

SRDF Parser

The SRDF parser is documented with the rest of the SRDF layer (models, parser, generator) on the dedicated SRDF reference page.

Usage Examples

Parse XACRO File

To resolve a XACRO file into a plain XML string (format-agnostic):

from linkforge.core import XACROParser
from pathlib import Path

# Returns a plain XML string
xml_string = XACROParser().resolve(Path("robot.urdf.xacro"))

To parse a XACRO file directly into a Robot model (canonical usage):

from linkforge.core import URDFParser
from pathlib import Path

# Natively resolves XACRO then parses URDF
robot = URDFParser().parse_xacro(Path("robot.urdf.xacro"))
print(f"Loaded robot: {robot.name}")

Parse URDF File

from linkforge.core import URDFParser
from pathlib import Path

robot = URDFParser().parse(Path("my_robot.urdf"))
print(f"Loaded robot: {robot.name}")

Parse URDF String

from linkforge.core import URDFParser

urdf_content = """<?xml version="1.0"?>
<robot name="simple_robot">
  <link name="base_link"/>
</robot>"""

robot = URDFParser().parse_string(urdf_content)

Robustness & Security

The parser includes professional-grade protections for production robotics:

  • Duplicate Name Resolution: Re-names conflicting link/joint names (e.g., link_duplicate_1) to preserve kinematic tree integrity while alerting the user.

  • DoS Protection: Enforces a maximum XML depth of 2,000 levels and file size (100 MB) to prevent β€œXML Bomb” attacks.

  • O(1) Memory Efficiency: All core parsers use iterative processing to handle massive robot descriptions with a constant, low memory footprint.

  • Path Sandboxing: Validates all mesh paths to prevent directory traversal and ensure assets remain within authorized project folders.

  • Secured Math Environment: XACRO expressions are evaluated in a hardened sandbox that prevents access to dangerous Python built-ins or private __dunder__ methods.

  • XACRO Debugging Support: Natively evaluates and routes xacro.warning(), xacro.error(), xacro.fatal(), and xacro.message() calls to the LinkForge Python logger.

  • Resilient Skip: Malformed geometry or broken joint references are logged as warnings, allowing the rest of the robot to load successfully.