Skills & Market
Skills are reusable, named behaviors that run on any robot. They register with
a decorator and are discovered via the ohho market CLI. A skill's tools are
gated by the robot's capabilities — a skill that needs manipulation won't run
on a robot without an arm.
Built-in skills
| Skill | Requires | Description |
|---|---|---|
patrol |
base.drive |
Drive a square patrol pattern |
wave |
manipulation |
Wave the arm gripper |
stop |
— | Emergency stop the robot |
status |
— | Print telemetry and connection status |
List and run skills
These two commands exited 0. ohho market run omnibot patrol did not exit in the check, so it is not listed.
ohho market list
ohho market run omnibot status
Use skills in Python
from ohho.market import run_skill, list_skills, get_skill
# List all registered skills
for s in list_skills():
print(f"{s.name}: {s.description}")
# Run a skill
result = run_skill("patrol", bot, side=2.0, speed=0.15)
# Check if a skill can run on a robot
skill = get_skill("wave")
if skill.can_run(bot):
skill.run(bot, reps=5)
Write your own skill
Use the @skill decorator to register a reusable behavior:
from ohho.market import skill
@skill("dance", "Make the robot dance in a circle", requires=["base.drive"])
def dance(robot, speed=0.2, turns=4):
import time
for _ in range(turns):
robot.drive(vx=speed, w=0.8)
time.sleep(3.14)
robot.stop()
return f"danced {turns} turns at {speed} m/s"
Then use it:
A custom skill was not part of the checked run. ohho market list and ohho market run omnibot status are in Install.
Or in Python:
from ohho.market import run_skill
run_skill("dance", bot, speed=0.3, turns=2)
Capability gating
Skills declare which capabilities they requires. When you run a skill on a
robot that lacks those capabilities, you get a clear error:
from ohho.market import run_skill, SkillRequirementsNotMet
try:
run_skill("wave", dog) # Go2 has no manipulation
except SkillRequirementsNotMet as e:
print(e)
# skill 'wave' requires capabilities: ['manipulation'].
# Robot 'unitree-go2' has: ['base.drive', 'base.holonomic_drive', ...]
The Skill dataclass
from ohho.market import Skill, register_skill
custom = Skill(
name="inspect",
description="Drive forward and report obstacles",
handler=lambda robot: robot.drive(vx=0.1),
requires=["base.drive"],
author="your-name",
version="1.0.0",
tags=["inspection", "safety"],
)
register_skill(custom)
Next
- Architecture — how skills fit into the engine
- Contributing — add your own robot