Skip to content

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 Librux 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/librux
librux 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 librux 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/librux.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: librux.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. Read The Kinematic Shape

The same manifest records the simple 2D robot structure.

parts:
  base:
    kind: mobile_base
    frame: cleaner_base
  arm:
    kind: planar_manipulator
    mount: cleaner_base
    tool_frame: cleaner_gripper
  gripper:
    kind: gripper
    mount: cleaner_gripper
  radar:
    kind: planar_radar
    mount: cleaner_base
  device_bus:
    kind: simulated_device_bus
    frame: world
  arena:
    kind: provided_2d_arena
    frame: world
  compound_logic:
    kind: compound_layer
    frame: cleaner_base

This is not physics simulation. It is a manifest-level description that lets tools, diagrams, and validators understand what the platform is made of.

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 Librux 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.teleop:
    capability: capability.mobility.teleop.v1
    implementation:
      kind: compound_subsystem
      subsystem: compound.cleaner
      interface: mobility
      contract: capability.mobility.teleop.v1
    features:
      - manual_drive
      - planar_drive
      - stop
  perception.trash_scan:
    capability: capability.perception.trash_detection.v1
    implementation:
      kind: compound_subsystem
      subsystem: compound.cleaner
      interface: perception_query
      contract: capability.perception.trash_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.teleop capability.mobility.teleop.v1 move the robot in the arena
trash_disposal.collect capability.cleaning.trash_disposal.v1 coordinate reach, grip, stow, and burn
trash_disposal.burn capability.cleaning.trash_disposal.v1 expose disposer behavior instead of raw IO
perception.trash_scan capability.perception.trash_detection.v1 detect trash

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.

librux deploy plan tutorials/deployments/teleop.deployment.yaml
librux 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

flowchart TB Platform["cleaner_2d<br/>platform"] App["Application selected by deployment"] Mobile["mobile_base_controller"] Arm["manipulator_controller"] Grip["gripper_controller"] Radar["perception_controller"] Compound["compound.cleaner"] Gateway["device_gateway"] Platform --> Mobile Platform --> Arm Platform --> Grip Platform --> Radar Platform --> Compound Platform --> Gateway App -. "requires capabilities" .-> Platform App --> Compound Compound --> Mobile Compound --> Arm Compound --> Grip Compound --> Radar

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.