Robotic fleets — worked graph designs

These designs describe intended system behavior and qualification requirements. Inspect the system atlas for named ports and relation participants.

Robotic fleet: mission allocation and local safety

Which decisions stay on the robot when fleet connectivity fails?

Inspect this design · Definition JSON · revision 57d3d7b23686

Diagram legend. Frames are named graph regions. Left/right pins show required/offered participation, not a universal schedule. Filled pins are connected; hollow pins are unbound. A junction card preserves one relation's role slots.

MarkerMeaning in this diagram
ƒ N01Pure computation
⌕ N22Query / materialized view
↗ N19Tool / external API adapter
▣ N05Actor / statechart
⊂ N33Policy / principal boundary
⚙ N15Device / platform adapter
○ P01Value / immutable snapshot
◎ P24Inspection / evidence
⇆ P02Request / response
⊂ P20Authorization request / grant
→ H02Value flow
⇆ H05Request / reply binding
⊂ H23Scoped authorization
⋂ H09Join-all

Logic and ownership

A Kotlin allocation algorithm searches feasible assignments from a versioned demand/capacity cut; local motion logic remains in the qualified robot controller.

Failure and qualification

  • Fleet approval never overrides physical interlocks or local safety limits.
  • A missed network heartbeat is an uncertain observation, not permission to continue indefinitely.
  • Hard real-time and safety certification need a qualified host and independent evidence.

Hyperedge roles

RelationPatternParticipants, preserving role positions
capacityH02 — Value flow {#h02--value-flow}provider[0]: capacity.snapshot; consumer[0]: planner.capacity
planH02 — Value flow {#h02--value-flow}provider[0]: planner.mission; consumer[0]: mission.proposal
deliveryH05 — Request / reply binding {#h05--request--reply-binding}provider[0]: mission.assign; consumer[0]: robot.mission
safeH23 — Scoped authorization {#h23--scoped-authorization}provider[0]: safety.grant; consumer[0]: robot.motion
actuatorH05 — Request / reply binding {#h05--request--reply-binding}provider[0]: actuator.move; consumer[0]: robot.actuate
allocationH09 — Join-all {#h09--join-all}demand[0]: planner.demand; supply[1]: capacity.supply; assignment[2]: mission.assignment

Kotlin common declaration

Import dev.shibasis.reaktor.portgraph.definition.* for this structural declaration. Behavior stays in ordinary Kotlin and binds through qualified runtime ports and adapters. Declaring a graph does not activate a system.

graphDefinition("robot-allocation", "57d3d7b236867fdf1b2251c728a4569af7de18a8d9ad26114db789c675957c96") {
    region("fleet", "Fleet coordination")
    region("robot", "Robot-local execution")
    node("planner", "Fleet mission planner", "N01", "fleet", ports = listOf(
        PortDefinition("capacity", "P01", "FleetCapacityV1", PortPolarity.Require),
        PortDefinition("mission", "P01", "MissionProposalV1", PortPolarity.Offer),
        PortDefinition("demand", "P24", "DemandRefV1", PortPolarity.Neutral)
    ))
    node("capacity", "Robot capacity view", "N22", "fleet", ports = listOf(
        PortDefinition("snapshot", "P01", "FleetCapacityV1", PortPolarity.Offer),
        PortDefinition("supply", "P24", "SupplyRefV1", PortPolarity.Neutral)
    ))
    node("mission", "Mission service", "N19", "fleet", ports = listOf(
        PortDefinition("proposal", "P01", "MissionProposalV1", PortPolarity.Require),
        PortDefinition("assign", "P02", "MissionAssignV1", PortPolarity.Offer),
        PortDefinition("assignment", "P24", "AssignmentRefV1", PortPolarity.Neutral)
    ))
    node("robot", "Robot mission actor", "N05", "robot", ports = listOf(
        PortDefinition("mission", "P02", "MissionAssignV1", PortPolarity.Require),
        PortDefinition("motion", "P20", "MotionGrantV1", PortPolarity.Require),
        PortDefinition("actuate", "P02", "MotionCommandV1", PortPolarity.Require)
    ))
    node("safety", "Local safety controller", "N33", "robot", ports = listOf(
        PortDefinition("grant", "P20", "MotionGrantV1", PortPolarity.Offer)
    ))
    node("actuator", "Actuator adapter", "N15", "robot", ports = listOf(
        PortDefinition("move", "P02", "MotionCommandV1", PortPolarity.Offer)
    ))
    relation("capacity", "H02",
        Incidence("capacity", "snapshot", "provider", 0),
        Incidence("planner", "capacity", "consumer", 0)
    )
    relation("plan", "H02",
        Incidence("planner", "mission", "provider", 0),
        Incidence("mission", "proposal", "consumer", 0)
    )
    relation("delivery", "H05",
        Incidence("mission", "assign", "provider", 0),
        Incidence("robot", "mission", "consumer", 0)
    )
    relation("safe", "H23",
        Incidence("safety", "grant", "provider", 0),
        Incidence("robot", "motion", "consumer", 0)
    )
    relation("actuator", "H05",
        Incidence("actuator", "move", "provider", 0),
        Incidence("robot", "actuate", "consumer", 0)
    )
    relation("allocation", "H09",
        Incidence("planner", "demand", "demand", 0),
        Incidence("capacity", "supply", "supply", 1),
        Incidence("mission", "assignment", "assignment", 2)
    )
}

Robotic fleet: sensor fusion, native kernels and clock domains

How are measurements from different clocks combined?

Inspect this design · Definition JSON · revision dfacbbe033ef

Diagram legend. Frames are named graph regions. Left/right pins show required/offered participation, not a universal schedule. Filled pins are connected; hollow pins are unbound. A junction card preserves one relation's role slots.

MarkerMeaning in this diagram
⚙ N15Device / platform adapter
≈ N07Stream operator
◆ N16Native resource / engine
▰ N21Database / state authority
⌕ N22Query / materialized view
≋ P06Credit-controlled stream
◎ P24Inspection / evidence
⇆ P02Request / response
Δ P09Mutation / conditional update
○ P01Value / immutable snapshot
→ H02Value flow
⇆ H05Request / reply binding
◷ H31Clock / time alignment

Logic and ownership

Kotlin selects an aligned sample window and invokes a qualified native kernel. Pose estimates retain covariance and source timestamps.

Failure and qualification

  • A timestamp field alone does not establish a common clock or bounded drift.
  • Drop, extrapolate or mark stale samples according to an explicit fusion policy.
  • Native buffer ownership and device deadlines remain local even when fleet telemetry is remote.

Hyperedge roles

RelationPatternParticipants, preserving role positions
lidarH02 — Value flow {#h02--value-flow}provider[0]: lidar.sample; consumer[0]: align.lidar
imuH02 — Value flow {#h02--value-flow}provider[0]: imu.sample; consumer[0]: align.imu
fuseH05 — Request / reply binding {#h05--request--reply-binding}provider[0]: fusion.compute; consumer[0]: align.kernel
poseH02 — Value flow {#h02--value-flow}provider[0]: fusion.pose; consumer[0]: pose.update
publishH02 — Value flow {#h02--value-flow}provider[0]: pose.snapshot; consumer[0]: fleet.pose
timeH31 — Clock / time alignment {#h31--clock--time-alignment}lidarClock[0]: lidar.clock; imuClock[1]: imu.clock; alignment[2]: align.policy

Kotlin common declaration

Import dev.shibasis.reaktor.portgraph.definition.* for this structural declaration. Behavior stays in ordinary Kotlin and binds through qualified runtime ports and adapters. Declaring a graph does not activate a system.

graphDefinition("robot-localization", "dfacbbe033effb48f24871959b0d63e24d4975710abc57260e01495a8c739d80") {
    region("fleet", "Fleet coordination")
    region("robot", "Robot-local execution")
    node("lidar", "Lidar adapter", "N15", "robot", ports = listOf(
        PortDefinition("sample", "P06", "LidarSampleV1", PortPolarity.Offer),
        PortDefinition("clock", "P24", "ClockRefV1", PortPolarity.Neutral)
    ))
    node("imu", "IMU adapter", "N15", "robot", ports = listOf(
        PortDefinition("sample", "P06", "ImuSampleV1", PortPolarity.Offer),
        PortDefinition("clock", "P24", "ClockRefV1", PortPolarity.Neutral)
    ))
    node("align", "Clock alignment", "N07", "robot", ports = listOf(
        PortDefinition("lidar", "P06", "LidarSampleV1", PortPolarity.Require),
        PortDefinition("imu", "P06", "ImuSampleV1", PortPolarity.Require),
        PortDefinition("kernel", "P02", "FusionStepV1", PortPolarity.Require),
        PortDefinition("policy", "P24", "TimeAlignmentV1", PortPolarity.Neutral)
    ))
    node("fusion", "Native fusion kernel", "N16", "robot", ports = listOf(
        PortDefinition("compute", "P02", "FusionStepV1", PortPolarity.Offer),
        PortDefinition("pose", "P09", "PoseEstimateV1", PortPolarity.Offer)
    ))
    node("pose", "Pose authority", "N21", "robot", ports = listOf(
        PortDefinition("update", "P09", "PoseEstimateV1", PortPolarity.Require),
        PortDefinition("snapshot", "P01", "PoseSnapshotV1", PortPolarity.Offer)
    ))
    node("fleet", "Fleet pose subscriber", "N22", "fleet", ports = listOf(
        PortDefinition("pose", "P01", "PoseSnapshotV1", PortPolarity.Require)
    ))
    relation("lidar", "H02",
        Incidence("lidar", "sample", "provider", 0),
        Incidence("align", "lidar", "consumer", 0)
    )
    relation("imu", "H02",
        Incidence("imu", "sample", "provider", 0),
        Incidence("align", "imu", "consumer", 0)
    )
    relation("fuse", "H05",
        Incidence("fusion", "compute", "provider", 0),
        Incidence("align", "kernel", "consumer", 0)
    )
    relation("pose", "H02",
        Incidence("fusion", "pose", "provider", 0),
        Incidence("pose", "update", "consumer", 0)
    )
    relation("publish", "H02",
        Incidence("pose", "snapshot", "provider", 0),
        Incidence("fleet", "pose", "consumer", 0)
    )
    relation("time", "H31",
        Incidence("lidar", "clock", "lidarClock", 0),
        Incidence("imu", "clock", "imuClock", 1),
        Incidence("align", "policy", "alignment", 2)
    )
}