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.
| Marker | Meaning in this diagram |
|---|---|
| ƒ N01 | Pure computation |
| ⌕ N22 | Query / materialized view |
| ↗ N19 | Tool / external API adapter |
| ▣ N05 | Actor / statechart |
| ⊂ N33 | Policy / principal boundary |
| ⚙ N15 | Device / platform adapter |
| ○ P01 | Value / immutable snapshot |
| ◎ P24 | Inspection / evidence |
| ⇆ P02 | Request / response |
| ⊂ P20 | Authorization request / grant |
| → H02 | Value flow |
| ⇆ H05 | Request / reply binding |
| ⊂ H23 | Scoped authorization |
| ⋂ H09 | Join-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
| Relation | Pattern | Participants, preserving role positions |
|---|---|---|
| capacity | H02 — Value flow {#h02--value-flow} | provider[0]: capacity.snapshot; consumer[0]: planner.capacity |
| plan | H02 — Value flow {#h02--value-flow} | provider[0]: planner.mission; consumer[0]: mission.proposal |
| delivery | H05 — Request / reply binding {#h05--request--reply-binding} | provider[0]: mission.assign; consumer[0]: robot.mission |
| safe | H23 — Scoped authorization {#h23--scoped-authorization} | provider[0]: safety.grant; consumer[0]: robot.motion |
| actuator | H05 — Request / reply binding {#h05--request--reply-binding} | provider[0]: actuator.move; consumer[0]: robot.actuate |
| allocation | H09 — 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.
| Marker | Meaning in this diagram |
|---|---|
| ⚙ N15 | Device / platform adapter |
| ≈ N07 | Stream operator |
| ◆ N16 | Native resource / engine |
| ▰ N21 | Database / state authority |
| ⌕ N22 | Query / materialized view |
| ≋ P06 | Credit-controlled stream |
| ◎ P24 | Inspection / evidence |
| ⇆ P02 | Request / response |
| Δ P09 | Mutation / conditional update |
| ○ P01 | Value / immutable snapshot |
| → H02 | Value flow |
| ⇆ H05 | Request / reply binding |
| ◷ H31 | Clock / 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
| Relation | Pattern | Participants, preserving role positions |
|---|---|---|
| lidar | H02 — Value flow {#h02--value-flow} | provider[0]: lidar.sample; consumer[0]: align.lidar |
| imu | H02 — Value flow {#h02--value-flow} | provider[0]: imu.sample; consumer[0]: align.imu |
| fuse | H05 — Request / reply binding {#h05--request--reply-binding} | provider[0]: fusion.compute; consumer[0]: align.kernel |
| pose | H02 — Value flow {#h02--value-flow} | provider[0]: fusion.pose; consumer[0]: pose.update |
| publish | H02 — Value flow {#h02--value-flow} | provider[0]: pose.snapshot; consumer[0]: fleet.pose |
| time | H31 — 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)
)
}