Skip to content

Bring your own robot

The reusable cloud workflow is publish, inspect, reference, run. You upload a self-contained USD or URDF package once; Simulo validates it and assigns an immutable catalog version that any later job can pin.

Keep the entry and every referenced mesh, texture, or USD layer under one package root. The client never collects a dependency from outside that root.

my-arm/
├── robot.usda
├── geometry.usda
└── textures/
└── arm.png

If the directory contains more than one possible entry, name it explicitly with --entry.

Terminal window
simulo asset publish ./my-arm --kind robot --name my-arm --entry robot.usda

The command packages the dependency closure, uploads it, and follows the validation job unless you pass --detach. A version number is assigned only after the package passes. To exercise the same cloud validator without publishing a version first:

Terminal window
simulo asset validate ./my-arm --kind robot --entry robot.urdf
Terminal window
simulo asset inspect robot/my-arm:v1
simulo asset inspect robot/my-arm:v1 --report my-arm.validation.json

Check the resolved entry, joint names, degree-of-freedom count, collision shapes, units, mass, and settle/actuation outcomes before adapting the task. See Asset Validation for report semantics.

Define the handle at module level so discovery sees it while importing the app:

import simulo
my_arm = simulo.Asset.from_registry("robot/my-arm:v1")
class ReachTask(simulo.Task):
observation_dim = 12
action_dim = 6
def build(self, scene: simulo.Scene) -> None:
scene.add(simulo.Terrain.plane(name="ground"), at="/", per_environment=False)
self.robot = simulo.Robot(asset=my_arm, initial_pose=simulo.Pose.identity())
scene.add(self.robot, at="/World/Robot")

Nothing loads on your machine: Asset.from_registry(...) is a lightweight handle during discovery. The submitted job resolves and mounts the validated package in execution.

Run with the asset-integrity gates enabled:

Terminal window
simulo run app.py --frozen --strict-assets

--frozen proves every asset ref includes :vN; --strict-assets refuses deprecated or runtime-unvalidated versions instead of accepting their warning.

Replacing the model is necessary but not sufficient. A cartpole task is written around cartpole’s joints and dimensions. Update at least:

  • on_start — resolve your robot’s real joint names with self.robot.find_joints(...).
  • observation_dim and action_dim — match the values your task produces and consumes.
  • get_observations, apply_actions, get_dones, and reset_idx — use the new joints, limits, and termination rules.
  • Reward logic — score the behavior you actually want from this embodiment.

The facts from asset inspect are the reliable starting point; do not copy a DOF count from an unrelated example.

If a suitable robot already exists in the global catalog, use its explicit global ref instead:

Terminal window
simulo asset list --global --kind robot
cartpole = simulo.Asset.from_registry("simulo/robot/cartpole:v1")

For catalog discovery and lifecycle commands, see Browse & manage assets.