# How to Create Robot URDF Files with build123d

> Learn to effortlessly create robot URDF files using build123d. The text-to-cad repository converts Python scripts into annotated URDFs and mesh assets, streamlining robotics simulation.

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

---

**The text-to-cad repository provides a `buildI23d` CLI entry point that converts Python scripts containing a `gen_urdf()` function into fully annotated URDF files and mesh assets for robotics simulation.**

The *earthtojake/text-to-cad* project streamlines robot modeling by combining the **build123d** CAD workflow with an automated URDF generation pipeline. By writing a simple Python script that defines a `gen_urdf()` function, you can generate valid URDF descriptions compatible with ROS 2 and MoveIt. This guide explains the exact file structure, CLI commands, and integration points implemented in the source code.

## Understanding the build123d URDF Architecture

The URDF generation system in `text-to-cad` is organized into three distinct layers that keep user logic separate from CAD backend operations.

### User Script Layer

At the top level, you write a Python script that declares the robot’s geometry and joints. The system expects this script to define a function named `gen_urdf()` that returns a dictionary describing the robot structure. The source parser located in [`skills/urdf/scripts/urdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/source.py) loads your script, validates the envelope, and extracts this function using AST inspection via [`cadpy/metadata.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/metadata.py).

### URDF Skill Layer

The middle layer handles CLI argument parsing and orchestration. The [`skills/urdf/scripts/urdf/cli.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/cli.py) module processes the `--script` and `--output-dir` arguments, while [`skills/urdf/scripts/urdf/__main__.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/__main__.py) registers the console script entry point named `buildI23d`. This layer ensures the user script contains the required `gen_urdf` definition before invoking the backend.

### CAD Backend Layer

The final layer generates physical assets. The [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) module constructs the URDF XML document, writes mesh files, and delegates assembly export tasks to [`packages/cadpy/src/cadpy/assembly_export.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/assembly_export.py). After generation, [`packages/cadpy/src/cadpy/catalog.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/catalog.py) updates the model catalog so the Viewer can locate the new URDF automatically.

## Writing the gen_urdf() Function

To create a valid robot description, your script must expose a `gen_urdf()` function that returns a dictionary with specific keys for links, joints, and metadata.

Here is the minimal required structure:

```python

# my_robot.py

def gen_urdf():
    return {
        "name": "my_robot",
        "links": [
            {"name": "base_link", "mesh": "base.stl"},
        ],
        "joints": [
            {
                "name": "joint1",
                "parent": "base_link",
                "child": "link1",
                "type": "revolute",
                "origin": {"xyz": [0, 0, 0.1], "rpy": [0, 0, 0]},
                "axis": [0, 0, 1],
                "limits": {"lower": -1.57, "upper": 1.57},
            },
        ],
    }

```

The dictionary must include the robot `name`, a list of `links` containing mesh references, and a list of `joints` defining parent-child relationships, joint types, and motion limits.

## Running the buildI23d CLI

Once your script is ready, use the `buildI23d` command-line tool to generate the URDF. This entry point is defined in [`skills/urdf/scripts/urdf/__main__.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/__main__.py) and accepts the script path and output directory as arguments.

Execute the generator using the module syntax:

```bash
python -m skills.urdf.scripts.urdf.cli \
    --script my_robot.py \
    --output-dir models/my_robot

```

Or call the registered executable directly after installing the package:

```bash
buildI23d -s path/to/robot_script.py -o models/robot

```

The tool validates the script by checking for the `gen_urdf` function in the AST, then writes `<script-name>.urdf` to the output directory alongside any referenced mesh files.

## Mesh Generation and Asset Management

During execution, [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) creates the URDF XML and exports mesh geometries to the filesystem. The generator places all auxiliary assets in the same model folder as the URDF file, ensuring relative paths remain valid. After file creation, [`packages/cadpy/src/cadpy/catalog.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/catalog.py) registers the new URDF path in the repository’s model index, enabling automatic loading by the Viewer component without manual path configuration.

## Integrating with MoveIt 2

Generated URDF files are immediately compatible with ROS 2 robotics stacks. The repository includes utilities in [`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) for loading these descriptions into MoveIt 2.

```python
from pathlib import Path
from moveit2_server.moveit_py import _robot_description_for_moveit

urdf_path = Path("models/my_robot/my_robot.urdf")
description_xml = _robot_description_for_moveit(urdf_path)

# Pass description_xml to a MoveIt2 RobotModelLoader

```

This integration expects the URDF to follow the standard format produced by the `buildI23d` pipeline, with all mesh paths resolved relative to the URDF location.

## Summary

- The **buildI23d** CLI entry point in [`skills/urdf/scripts/urdf/__main__.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/__main__.py) drives the entire generation process.
- User scripts must define a `gen_urdf()` function returning a dictionary with robot links, joints, and metadata.
- The CAD backend in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) handles XML construction and mesh export.
- Output files are automatically registered in the model catalog via [`packages/cadpy/src/cadpy/catalog.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/catalog.py).
- Generated URDFs are compatible with MoveIt 2 through the helper utilities in [`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).

## Frequently Asked Questions

### What is the difference between build123d and the buildI23d command?

**build123d** refers to the CAD modeling workflow and library concepts used in the repository, while **buildI23d** is the specific console script entry point registered in [`skills/urdf/scripts/urdf/__main__.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/__main__.py). The `buildI23d` command is the executable interface that parses your Python script and triggers the URDF generation pipeline.

### What data structure must the gen_urdf() function return?

The function must return a Python dictionary containing at minimum the keys `name` (string), `links` (list of dictionaries with `name` and optional `mesh`), and `joints` (list of dictionaries defining `parent`, `child`, `type`, `origin`, `axis`, and `limits`). This structure is validated by the AST inspector in [`cadpy/metadata.py`](https://github.com/earthtojake/text-to-cad/blob/main/cadpy/metadata.py) before generation proceeds.

### Where are the generated mesh files stored?

Mesh files referenced in your `gen_urdf()` return value are written to the same directory specified by the `--output-dir` argument, alongside the generated `.urdf` file. The [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) module ensures all paths in the final XML are relative to this output folder.

### Can I use this tool without ROS or MoveIt?

Yes. The output from `buildI23d` is a standard URDF file and associated mesh assets. While the repository provides integration utilities for MoveIt 2 in [`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), the generated files are pure text and mesh data compatible with any robotics simulator or visualization tool that supports the URDF format.