| name | sdf |
| description | SDFormat/SDF model and world generation, validation, and simulator handoff. Use for `.sdf` files, SDFormat XML, Python `gen_sdf()` sources, models, worlds, links, joints, poses, frames, inertials, visual/collision geometry, mesh URIs, sensors, lights, physics, plugins, includes, Gazebo, CAD Explorer static SDF review, or simulator-specific metadata. Do not use for signed-distance-field geometry. |
SDF
Use this skill when the deliverable is an SDFormat document or a Python gen_sdf() source. SDFormat describes simulator and world behavior: models, worlds, frames, poses, links, joints, inertials, visuals, collisions, sensors, lights, physics, plugins, includes, and simulator metadata.
This skill is for SDFormat, not signed-distance-field geometry.
Core rules
- Treat the Python file defining
gen_sdf() as source of truth. Treat configured .sdf files as generated artifacts unless the user explicitly asks for direct XML editing.
- Identify the target consumer before editing: Gazebo/libsdformat version, another simulator, visualization-only tooling, model package, or world handoff.
- Decide document kind: model-level SDF, world-level SDF, or model-in-world. Prefer model-level SDF for reusable robot/object exports.
- Use SI units unless the target explicitly requires otherwise: meters, kilograms, seconds, radians.
- Prefer
version="1.12" for new outputs unless the target consumer constrains the version.
- Establish the design ledger before writing poses, frames, joint axes, mesh scales, inertials, sensors, or plugins. Use
references/design-ledger.md and references/llm-guardrails.md.
- Do not infer spatial transforms from visual impression alone. Derive poses, axes, scale, mass, inertia, and frame names from upstream source data, drawings, simulator documentation, measured values, or explicit assumptions.
- Prefer helper functions and named constants over large XML string literals. Hidden numbers are a common SDF failure mode.
- Generate only explicit targets with
scripts/sdf or the repository's existing SDF launcher. Do not run directory-wide generation.
- Regenerate upstream geometry, mesh, robot-description, render, topology, or package assets with their owning workflows before regenerating SDF that references them.
- After generation, run available checks: bundled validation, optional
gz sdf --check, simulator load, joint motion, plugin/sensor startup, and $render handoff when available.
- Report assumptions, skipped checks, unresolved resource paths, and target-specific compatibility risks.
Scope
Use this skill for SDFormat outputs and generators. Do not use it for signed-distance-field modeling, raw geometry generation, planning semantics, or to paper over incorrect upstream robot/source data unless the task is explicitly simulator-only.
Workflow
- Locate the
gen_sdf() source and intended .sdf output.
- Read or create the design ledger.
- Read
references/frame-semantics.md before editing any <pose>, <frame>, joint axis, relative_to, expressed_in, nested scope, sensor frame, or plugin frame.
- Edit the generator source, not generated XML.
- Use optional builder helpers when they make the generated structure clearer; raw ElementTree is still allowed.
- Regenerate the explicit target.
- Treat bundled validation as a guardrail, not simulator proof.
- Run target-consumer smoke tests when available.
- After creating or modifying
.sdf output, always hand the explicit generated path to $render when available; $render checks/reuses a live viewer and returns a link. CAD Explorer does not execute SDF plugins or read file-authored motion metadata.
- For visual feedback during generation review, prefer
$render snapshots over opening the viewer manually or using Playwright. Use still snapshots only; SDF review should not generate GIFs.
- Report checks run, checks skipped, and assumptions.
Commands
Run with the project or workspace Python environment.
python scripts/sdf path/to/source.py
python scripts/sdf path/to/source.py -o path/to/output.sdf
python scripts/sdf path/to/a.py=out/a.sdf path/to/b.py=out/b.sdf
Plain Python targets write sibling .sdf files beside their sources. -o / --output is valid only with one plain target. SOURCE.py=OUTPUT.sdf supports custom multi-target destinations.
If the runtime supports optional external checking:
python scripts/sdf path/to/source.py --gz-check auto
python scripts/sdf path/to/source.py --gz-check required
python scripts/sdf path/to/source.py --gz-check never
gz sdf --check is optional target-consumer validation. It should be reported as skipped when unavailable unless explicitly required.
Required report shape
When finishing an SDF task, include a compact report:
Generated: path/to/model.sdf from path/to/model.py
Checks run:
- bundled SDF validation: passed
- gz sdf --check: skipped, gz not installed
- simulator load: skipped, target simulator unavailable
- visual review: render viewer link returned; snapshot run/skipped
Assumptions:
- Assumed mesh units are meters.
- Assumed lidar frame is coincident with lidar_link.
Risks:
- Camera plugin filename was not verified in the target simulator environment.
References
- Generation command:
references/gen-sdf.md
- Generator contract:
references/generator-contract.md
- SDF workflow:
references/sdf-workflow.md
- Builder helpers:
references/builder-helpers.md
- LLM guardrails:
references/llm-guardrails.md
- Design ledger:
references/design-ledger.md
- Frame semantics:
references/frame-semantics.md
- Validation scope:
references/validation.md
- Smoke tests:
references/smoke-tests.md
- Interoperability notes:
references/interoperability.md
- Examples:
references/examples.md
- Runtime notes and current limitations:
references/implementation-notes.md