Step 4 - Define Platform
The cleaner now has a provided simulator, a gateway subsystem, component subsystems, and a browser view. This step turns that collection into a reusable platform and adds the compound subsystem layer that applications will call.
The general R2Kernel composition model is this.
robot = platform + application + deployment
deployment = what runs, where it runs, and how it connects
In this tutorial, that model is applied to the cleaner like this.
platform = the cleaner's reusable body, component set, gateway set, and robot-level abilities
application = one behavior that runs on that robot, such as teleop or radar cleaning
The platform does not choose teleop or radar. It declares the robot shape and robot-level abilities that those applications can run on. The concrete running pieces are still subsystems, but this step starts from the reusable platform identity instead of from individual processes.
Run This Stage
From the installed root.
cd /opt/r2kernel
r2kernel launch run tutorials/subsystems/compound.cleaner \
--instance compound.cleaner \
--bind mobility=component.mobile.mobile_base \
--bind manipulation=component.manipulation.manipulator \
--bind gripper=component.gripper.gripper \
--bind perception=component.perception.perception \
--bind digital_io=gateway.device_gateway.digital_io \
--detach
Expected terminal output shape.
Launched package tutorial.robot_cleaner.cleaner_compound
mode: detached
instance: compound.cleaner
Bindings:
digital_io -> gateway.device_gateway.digital_io
gripper -> component.gripper.gripper
manipulation -> component.manipulation.manipulator
mobility -> component.mobile.mobile_base
perception -> component.perception.perception
Open the browser with the same host rule from Step 1. For a local browser and runtime, use the following.
http://127.0.0.1:8091/
For a remote runtime host, use the following.
http://<runtime-host>:8091/
The world is still visible, but no top-level app is running yet. This stage checks that the reusable platform stack can exist before any specific application is attached.
This still uses r2kernel launch run, so the required interfaces are connected
with explicit --bind options. The deployment command is introduced below as
validation/planning first, then as full execution in the application step.
1. Open The Robot Manifest
nano tutorials/robot/r2kernel.robot.yaml
This file is the platform provider's manifest. It is not stored inside
subsystems/compound.cleaner because it describes the app-less platform, not
only the compound subsystem implementation.
The manifest begins with the reusable robot identity.
kind: r2kernel.robot
version: 1
robot:
name: cleaner_2d
model: tutorial-cleaner-2d
profiles:
- tutorial.robot_cleaner.cleaner_2d.v1
The profiles field stores optional platform compatibility labels. It lets an
application say "I run on this class of robot" when that matters, but the
primary compatibility surface is still the capability list declared later in
this manifest.
2. Declare Spatial Ports And Mounts
The robot manifest names reusable parts, slots, and capabilities. Concrete frame topology belongs to the subsystem manifests that implement the platform.
Open the mobile component manifest.
nano tutorials/subsystems/component.mobile/subsystem.yaml
spatial:
participation: required
ports:
reference:
direction: export
semantic: odometry_reference
frame: world
body:
direction: export
semantic: mobile_body
frame: cleaner_base
component.mobile_base.v1 requires these spatial ports. The component spec
defines their portable meaning, while this subsystem chooses the concrete local
frame names.
Open the compound manifest.
nano tutorials/subsystems/compound.cleaner/subsystem.yaml
Its mounts connect bound component ports.
spatial:
participation: required
mounts:
- name: arm_on_body
parent:
requirement: mobility
port: body
child:
requirement: manipulation
port: base
transform:
translation: [0.0, 0.0, 0.0]
rotation_xyzw: [0.0, 0.0, 0.0, 1.0]
The mount uses logical requirement names rather than concrete subsystem names. It remains valid when deployment selects another compatible mobile or manipulator component. The mobile and manipulator implementations report their changing transforms through the SDK. R2Kernel combines those dynamic transforms with the compound's static mounts.
After this stage is running, inspect the graph.
r2kernel frame graph
r2kernel frame lookup component.mobile/world component.manipulation/cleaner_gripper
3. Bind Software Roles To Robot Slots
The robot slots say which public contracts and subsystem roles are required.
slots:
actuator_gateway:
role: gateway
part: device_bus
contract: api.actuator.servo.v1
digital_output_gateway:
role: gateway
part: device_bus
contract: api.io.digital.output.v1
perception_gateway:
role: gateway
part: radar
contract: api.perception.query.v1
mobile_base_controller:
role: component
part: base
contract: component.mobile_base.v1
manipulator_controller:
role: component
part: arm
contract: component.manipulator.v1
gripper_controller:
role: component
part: gripper
contract: component.gripper.v1
perception_controller:
role: component
part: radar
contract: component.perception.v1
cleaner_compound:
role: compound
part: compound_logic
This is where component.mobile becomes the mobile-base component subsystem for
this platform, and gateway.device_gateway can become the lower gateway
boundary for several gateway slots. The robot manifest names the slots; the
deployment later chooses the concrete instances and the specific provided
interface that satisfies each slot.
The slot contracts are public R2Kernel specs. Simulator-only actions such as resetting the arena or spawning trash are not robot slots; they stay in the provided simulator support API.
4. Declare Robot Capabilities
Capabilities are the application-facing promises of the platform.
capabilities:
mobility.body_motion:
capability: capability.r2kernel.mobility.body_motion.v1
implementation:
kind: compound_subsystem
subsystem: compound.cleaner
interface: mobility
contract: capability.r2kernel.mobility.body_motion.v1
features:
- manual_drive
- planar_drive
- stop
perception.object_detection:
capability: capability.r2kernel.perception.object_detection.v1
implementation:
kind: compound_subsystem
subsystem: compound.cleaner
interface: perception_query
contract: capability.r2kernel.perception.object_detection.v1
features:
- front_scan
- planar_360_scan
The cleaner exposes application-facing capabilities through the compound subsystem.
| Robot capability | Semantic contract | Why applications care |
|---|---|---|
mobility.body_motion |
capability.r2kernel.mobility.body_motion.v1 |
command bounded body-frame motion |
trash_disposal.collect |
capability.tutorial.robot_cleaner.trash_disposal.v1 |
coordinate reach, grip, stow, and burn inside this tutorial package |
trash_disposal.burn |
capability.tutorial.robot_cleaner.trash_disposal.v1 |
expose cleaner-specific disposal behavior instead of raw IO |
perception.object_detection |
capability.r2kernel.perception.object_detection.v1 |
query semantic object detections |
Trash disposal is deliberately package-local. It demonstrates how a product can define specialized behavior without presenting it as an official R2Kernel capability.
The provided 2D arena is intentionally not a robot capability. It is tutorial
infrastructure behind gateway.device_gateway, similar to a simulator or vendor
device API behind a real gateway.
5. Compare Application Requirements
Each application declares the robot capabilities it needs, and may also include platform compatibility labels when it intentionally targets a robot family. Teleop needs mobility, manipulation, gripper, and trash-disposal capabilities.
nano tutorials/subsystems/app.cleaner.teleop/subsystem.yaml
Radar also requires trash scanning.
nano tutorials/subsystems/app.cleaner.radar/subsystem.yaml
This is the important separation.
platform says what the robot can provide
application says what kind of robot it needs
deployment proves the two fit together
6. Validate Deployment Plans
Each cleaner deployment binds one application to the same standard-contract platform.
r2kernel deploy plan tutorials/deployments/teleop.deployment.yaml
r2kernel deploy plan tutorials/deployments/radar.deployment.yaml
Expected shape for teleop.
Deployment is valid: tutorials/deployments/teleop.deployment.yaml
Robot: cleaner_2d
Application: cleaner_teleop
Instances: 7
Bindings: 11
The stage and application manifests use managed packages. Source scripts can still be opened and edited. Platform bring-up uses deployment reconciliation, while the teleop browser controls use the installed package runtime path because managed package frontend URLs are instance-scoped.
Cleaner Robot Graph After This Step
The cleaner is now a reusable platform. The next step attaches applications to that platform and makes it move.
Continue to Step 5 - Run Applications.