Tutorial 1: First Ground Robot
This tutorial explains the smallest useful registration shape for a ground robot in HORUS MR.
Design rule
Start by making one robot correct. Only after that should you scale the same definition to a fleet.
Goal
By the end of this step, you should understand:
- what a
Robotobject is representing - which fields are identity versus behavior
- why
workspace_scaleandkeep_alivematter at registration time - how one robot scales cleanly into a fleet
Build the smallest useful robot
Start with identity and body bounds only:
from horus.robot import Robot, RobotDimensions, RobotType
robot = Robot(
name="atlas",
robot_type=RobotType.WHEELED,
dimensions=RobotDimensions(length=0.8, width=0.55, height=0.45),
)
Then opt into the operator-facing management surface:
robot.configure_robot_manager()
Finally, register the robot into the workspace:
from horus.robot import register_robots
success, result = register_robots(
[robot],
workspace_scale=0.1,
keep_alive=True,
)
What each part means
name: This is the runtime identity of the robot in HORUS. Use a stable name that matches the rest of your ROS graph. Topic naming, TF naming, and operator-facing selection all become easier when the SDK name matches the robot namespace you already use.robot_type: HORUS uses this to decide which operator actions make sense.WHEELEDexposes the normal ground-robot flow,DRONEkeepsTake OffandLand, andLEGGEDmaps those controls toStand UpandSit Down.dimensions: These are the simplest body bounds the app can use before you move to a URDF-backed robot description. They affect interaction volume, visibility, and basic spatial reasoning in the workspace.configure_robot_manager(): This declares that the robot should expose the normal Robot Manager panel in HORUS MR.workspace_scale=0.1: This tells HORUS how large the workspace should be relative to the source ROS world. In the curated examples,0.1is the standard mini-map scale.keep_alive=True: This keeps the registration client alive after publishing. In practice, this is the normal mode because it supports session continuity, ACK tracking, and multi-operator replay semantics.
Assembly order that scales well
Use this order when building a new registration from scratch:
- define
Robot(name, robot_type, dimensions) - enable Robot Manager if operators should interact with it
- add cameras and other sensors
- add teleop and task contracts
- add DataViz layers
- move to URDF only after the simpler version is already correct
That order keeps failures easy to isolate.
How to validate this step
Use the full reference workflow only after you understand the contract fragments above:
# Terminal A
python3 python/examples/legacy/fake_tf_ops_suite.py
# Terminal B
python3 python/examples/ops_registration.py
What you should see in HORUS MR
- the robots appear after workspace acceptance
- selecting one robot opens one Robot Manager, not all of them
- the robot identity is stable across reopen or reconnect cycles
What comes next
The robot exists now, but it is still not useful for sensing or operator intervention. Continue with Tutorial 2: Cameras and views.