Skip to content

Genbot

genbot is a CLI tool that takes a robot CAD model from OnShape, downloads its URDF via onshape-to-robot, post-processes it for Gazebo, and generates two ready-to-build ROS 2 packages (_description and _bringup).

It can be run locally or through the Generate/Update Robot from OnShape GitHub Actions workflow.

All commands follow this pattern:

Inside devcontainer
PYTHONPATH=.github python3 -m genbot <command> [args]

For commands that call the OnShape API, pass your credentials:

Inside devcontainer
ONSHAPE_API_KEY=<key> ONSHAPE_API_SECRET=<secret> PYTHONPATH=.github python3 -m genbot <command> [args]

Create .github/genbot/onshape.env with:

Inside devcontainer
ONSHAPE_API_KEY=your_key_here
ONSHAPE_API_SECRET=your_secret_here

Then you can just run genbot <command> [args] — the alias handles the rest.

Downloads from OnShape and generates both packages from scratch. Registers the robot in robots.json. Reduces STL triangle counts by default.

Inside devcontainer
genbot create <robot_name> <onshape_url> [--attach-to-world] [--no-reduce] [--output-dir DIR]
OptionDescription
--attach-to-worldAdd a fixed joint from base_link to the world (for stationary robots)
--no-reduceSkip STL triangle decimation
--output-dirWrite packages to a different directory

Re-downloads from OnShape and replaces only the geometry URDF and meshes. The control xacro, bringup package, and manual edits are preserved. Reads the OnShape URL from robots.json.

Inside devcontainer
genbot update <robot_name> [--no-reduce] [--output-dir DIR]

Downloads raw URDF + assets into .github/genbot/tests/<robot_name>/ (gitignored) without generating ROS 2 packages. Useful for inspecting what onshape-to-robot produces.

Inside devcontainer
# First time (saves URL to robots.json)
genbot raw <robot_name> <onshape_url>
# Subsequent times (URL read from robots.json)
genbot raw <robot_name>

Runs the full post-processing and package generation on a local URDF file. No API keys needed.

Inside devcontainer
# From a previous `genbot raw` download
genbot local <robot_name>
# From a specific URDF file
genbot local <robot_name> path/to/robot.urdf [--assets path/to/meshes]

Both packages are written from scratch:

<robot>_description/
urdf/<robot>.urdf ← Post-processed geometry URDF
urdf/<robot>_control.urdf.xacro ← Generated ros2_control block
meshes/ ← STL mesh files (reduced)
CMakeLists.txt, package.xml
<robot>_bringup/
launch/<robot>.launch.py ← Launch orchestration
config/<robot>.controller.yaml ← Controller definitions
config/<robot>.rviz ← RViz config template
CMakeLists.txt, package.xml

Only these files are replaced:

<robot>_description/urdf/<robot>.urdf ← New geometry
<robot>_description/meshes/* ← New meshes (old deleted first)

Everything else is untouched — your control xacro edits, launch file customizations, and controller config are safe.

  1. Go to Actions > Generate/Update Robot from OnShape
  2. Click Run workflow and fill in:
InputDescription
modecreate or update
robot_nameRobot identifier (e.g. arm)
onshape_urlOnShape document URL (required for create, ignored for update)
attach_to_worldFix robot base to the world

The workflow runs genbot with credentials from repository secrets and opens a PR on branch genbot/<mode>-<robot_name>.

Required repository secrets:

SecretDescription
ONSHAPE_ACCESS_KEYOnShape API key
ONSHAPE_SECRET_KEYOnShape API secret

When genbot processes a URDF from OnShape, it performs several transformations:

  1. Xacro namespace injection — wraps the URDF with xacro support so it can include the control xacro
  2. Mesh path rewriting — updates all <mesh> tags to use package://<robot>_description/meshes/ paths
  3. Joint/link extraction — identifies all joints and links for control generation
  4. Control xacro generation — creates a ros2_control hardware interface block with position command interfaces and position/velocity state interfaces for every joint
  5. World base link — optionally adds a fixed joint from base_link to world for stationary robots

The robot registry at the repo root tracks all generated robots:

[
{
"name": "arm",
"url": "https://trickfire.onshape.com/documents/...",
"world_base_link": true
}
]

This file is written by create and raw, and read by update to look up the OnShape URL.

All source lives in .github/genbot/:

FileResponsibility
__init__.pyPath constants (REPO_ROOT, TEMPLATES, ROBOTS_JSON)
__main__.pyEntry point for python -m genbot
cli.pyArgument parsing and command dispatch
commands.pyImplementation of create, local, raw, update
onshape.pyOnShape URL parsing + onshape-to-robot integration
urdf.pyURDF post-processing (xacro, mesh paths, control generation)
ros_packages.pyPackage scaffolding from templates
template.py__ROBOT__ token replacement in template files
reduce_stl.pySTL decimation via open3d
credentials.pyReads API keys from environment
registry.pyrobots.json read/write
log.pyLogging helpers
templates/Template files for generated packages