Programmatically generate URDF and Xacro robot description files
Project description
urdfgenpy
A Python library for programmatically generating URDF (Unified Robot Description Format) and Xacro robot description files.
Features
- Build robot kinematic trees with links, joints, and materials using a clean Python API
- Geometry primitives: Box, Cylinder, Sphere
- Automatic inertia calculation from geometry and mass
- Convenience helpers:
Origin.above()(lift geometry to sit on a plane),Origin.wheel()(orient cylinder as a wheel) - Export to
.urdfor.xacro- format is inferred from the file extension - ASCII kinematic tree visualisation with
robot.print_tree()/robot.tree_string()
Installation
pip3 install urdfgenpy
Or from source:
git clone https://github.com/svaibhav101/urdfgenpy
cd urdfgenpy
pip3 install -e ".[dev,docs]"
Quick Start
from urdfgenpy import (
Robot, Link, Joint, JointLimit, JointDynamics,
Box, Cylinder, Sphere,
Origin, Material, Visual, Collision, Inertial,
)
# --- Materials ---
grey = Material("grey", rgba=(0.5, 0.5, 0.5, 1.0))
blue = Material("blue", rgba=(0.0, 0.3, 0.8, 1.0))
# --- Base link: flat box ---
base_box = Box(length=0.2, width=0.2, height=0.05)
base_link = Link("base_link")
base_link.add_visual(Visual(geometry=base_box, origin=Origin.above(base_box), material=grey))
base_link.add_collision(Collision(geometry=base_box, origin=Origin.above(base_box)))
base_link.set_inertial(Inertial.from_geometry(mass=1.0, geometry=base_box))
# --- Shoulder link: upright cylinder ---
shoulder_cyl = Cylinder(radius=0.04, length=0.15)
shoulder_link = Link("shoulder_link")
shoulder_link.add_visual(Visual(geometry=shoulder_cyl, origin=Origin.above(shoulder_cyl), material=blue))
shoulder_link.add_collision(Collision(geometry=shoulder_cyl, origin=Origin.above(shoulder_cyl)))
shoulder_link.set_inertial(Inertial.from_geometry(mass=0.5, geometry=shoulder_cyl))
# --- Joint ---
joint = Joint(
name="base_shoulder_joint",
joint_type="revolute",
parent="base_link",
child="shoulder_link",
origin=Origin(xyz=(0.0, 0.0, 0.05)),
axis=(0.0, 0.0, 1.0),
limit=JointLimit(lower=-3.14, upper=3.14, effort=50.0, velocity=2.0),
dynamics=JointDynamics(damping=0.5, friction=0.01),
)
# --- Assemble and export ---
robot = Robot("my_robot")
robot.add_material(grey).add_material(blue)
robot.add_link(base_link).add_link(shoulder_link)
robot.add_joint(joint)
robot.save("my_robot.urdf") # or .xacro
robot.print_tree()
API Reference
Robot
| Method | Description |
|---|---|
add_link(link) |
Add a Link; returns self for chaining |
add_joint(joint) |
Add a Joint; validates parent/child exist |
add_material(material) |
Register a global Material |
to_urdf(output_path=None) |
Return URDF XML string; optionally write file |
to_xacro(output_path=None) |
Return Xacro XML string; optionally write file |
save(output_path) |
Write .urdf or .xacro based on extension |
tree_string() |
Plain-text ASCII kinematic tree |
save_tree(output_path) |
Write tree_string() to file |
print_tree() |
Print coloured ASCII tree to stdout |
Geometry
| Class | Parameters |
|---|---|
Box(length, width, height) |
Axis-aligned box |
Cylinder(radius, length) |
Cylinder along Z-axis |
Sphere(radius) |
Sphere |
Origin
Origin(xyz=(0,0,0), rpy=(0,0,0)) # explicit
Origin.above(geometry, xy=(0,0), rpy=...) # lift so bottom sits at z=0
Origin.wheel(xy=(0,0), z=0) # -pi/2 roll, cylinder becomes wheel
Inertial
Inertial.from_geometry(mass, geometry) # auto-compute from Box/Cylinder/Sphere
Inertial.from_box(mass, length, w, h)
Inertial.from_cylinder(mass, radius, length)
Inertial.from_sphere(mass, radius)
Inertial(mass, matrix=InertiaMatrix(...)) # manual
Joint
Joint(
name, joint_type, # "fixed" | "revolute" | "continuous" | "prismatic" | ...
parent, child, # link names
origin=Origin(),
axis=(1, 0, 0),
limit=JointLimit(lower, upper, effort, velocity), # optional
dynamics=JointDynamics(damping, friction), # optional
mimic=JointMimic(joint, multiplier, offset), # optional
)
Examples
Install the package first, then run any example directly:
pip3 install -e ".[dev]"
python examples/simple_arm.py # 4-DOF serial arm
python examples/hobu.py # multi-link mobile base with wheels
python examples/base.py # minimal single-link robot
Each script writes its output files (.urdf, .xacro, _tree.txt) into a
subdirectory named after the robot.
Running Tests
pip3 install -e ".[dev]"
pytest
Run with coverage:
pytest --cov=urdfgenpy --cov-report=term-missing
Building Documentation
pip3 install -e ".[docs]"
cd docs
make html
# open docs/_build/html/index.html
Project Structure
urdfgenpy/
├── src/urdfgenpy/ # library source
│ ├── robot.py # Robot class
│ ├── link.py # Link class
│ ├── joint.py # Joint, JointLimit, JointDynamics, JointMimic
│ ├── geometry.py # Box, Cylinder, Sphere
│ ├── inertia.py # InertiaMatrix and inertia helpers
│ ├── elements.py # Origin, Material, Visual, Collision, Inertial
│ └── exporters/ # URDFExporter, XacroExporter
├── tests/ # pytest test suite (77 tests)
├── docs/ # Sphinx documentation source
├── examples/ # standalone usage examples
│ ├── simple_arm.py # 4-DOF serial arm
│ ├── hobu.py # multi-link mobile base with wheels
│ └── base.py # minimal single-link example
└── pyproject.toml # project metadata and tool config
Roadmap
See docs/source/roadmap.md for the full list. Top items:
| Priority | Feature |
|---|---|
| High | DH parameters -> skeleton URDF/Xacro - generate kinematic chain from a DH table |
| High | URDF parser - round-trip import of existing .urdf files |
| High | Model validation - positive-definite inertia check, joint-limit sanity |
| Medium | SDF export - Gazebo Simulation Description Format |
| Medium | Mesh-based inertia - auto-compute from .stl/.obj + density |
| Medium | Sensor elements - <camera>, <lidar>, <imu> tags |
| Low | ROS 2 scaffolding - generate package.xml + CMakeLists.txt |
| Low | Visualiser - quick matplotlib / rerun 3-D preview |
License
urdfgenpy is made available under the MIT License. For more details, see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file urdfgenpy-0.3.0.tar.gz.
File metadata
- Download URL: urdfgenpy-0.3.0.tar.gz
- Upload date:
- Size: 21.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96b479e037ec0aafcfcbdf0a1dab5cdf2d8ba3ab1c9631f5590191b4ce95a25b
|
|
| MD5 |
17197c836801b8d2abf13cf0eaf743a3
|
|
| BLAKE2b-256 |
e9cb25dfbbbf3b550bfb4bb7cd6efed224acbce2e599e7c725f6a5cf75c92e8c
|
File details
Details for the file urdfgenpy-0.3.0-py3-none-any.whl.
File metadata
- Download URL: urdfgenpy-0.3.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b380b7b7cea835235a536c1bb083a20212ccb21e29f321be6adaf9b2d9d7d373
|
|
| MD5 |
8a81fb3fab0857ac7f160fc9f79f9b35
|
|
| BLAKE2b-256 |
84e20aed1bde386c8f308c586ec356b051d97d995185652a4010594dea0d7269
|