Status: design-complete (2026-05-31) — the canonical action representation +
Envelope, the quaternion pose representation with single-scalar geodesic orientation error, the under-constrained-orientation residual rule, rest-at-goal terminal semantics, the determinism boundary (Class 2-strict generation / Class 2-loose contact-dynamics execution), multi-embodiment coordination, capability negotiation, the grasp-force / stability derivations, and trajectory generation + time-scaling are specified. The02group of § Open issues is closed (12/12) — and with it the entire cross-chapter Open-issues TODO (01/03/04/05/02all resolved). The normativeΣ-generator construction is fixed in § Appendix A. Remaining before freeze: the JSON Schema.
This chapter defines:
- The canonical embodiment-agnostic action representation
- The embodiment descriptor schema (
schemas/embodiment-descriptor.schema.json) - The deterministic retargeting algorithm
retarget(skill, embodiment) -> canonical_actions - The safety envelope semantics and how envelope constraints flow from Skill ISA into per-embodiment action parameters
The whitepaper states the retargeting contract as five binding invariants (I1–I5). This chapter is their machine-checkable form: it mechanizes the same contract as the finer obligations CA1c–CA4c (canonical-action) and RD1c–RD4c (retarget-determinism), with two invariants whose home is an adjacent chapter. The correspondence (derived; I2–I4 each span more than one obligation, so treat this table as the traceability map, not a one-to-one rename):
| Whitepaper invariant | Mechanized by |
|---|---|
| I1 — Determinism | RD1c (generation byte-determinism, unconditional) + RD2c (the Class 2-loose realized-execution boundary for contact dynamics) |
| I2 — Embodiment-respect | CA1c (pose reachability decidable) + CA4c (envelope clamped to the embodiment's declared limits) + the 03 capability_absent gate |
| I3 — Composability (rest-stable) | the 01 compositional algebra's rest-stable composition validity — not a 02 obligation; recorded here so the invariant is traceable |
| I4 — Failure-mode preservation | CA4c (an action exceeding a declared limit is malformed, never silently relaxed) + the binary capability_absent gate (an explicit refusal rather than a degraded sequence). RD4c uncertainty-robust routing is the embodiment-respect complement (I2), not a failure-mode obligation |
| I5 — Extension-namespace isolation | the 06 extension registry pass-through + unknown-tag rejection (03) |
I1–I5 is the authoritative public statement of the contract; CA*c / RD*c are the same contract at the granularity a conformance test reads. The two label systems are not competing claims.
A canonical action is the embodiment-agnostic instruction retarget emits — the one representation a conformant driver (03) consumes. It is a tuple:
CanonicalAction := (
target_frame: FrameRef, # the controlled frame this action moves (01 frame model)
target_pose: Pose6D, # goal pose of target_frame (§ Pose representation)
force_budget: Option<Force>, # driven-force ceiling (force category); None for pure motion
timing: TimingHints, # nominal duration + timing mode (§ Terminal semantics; Unit 4 time-scaling)
tactile_target: Option<TactileTarget>, # contact-confirmation criterion (04); None when no contact intended
monitors: set<Monitor>, # StopConditions + feature events the action watches (01 / 04)
safety_envelope: Envelope, # the safety constraints in force throughout (below)
)
The field types are owned elsewhere — Pose6D / TactileTarget and the StopCondition (01) / ForceEvent (04) a Monitor wraps — so this chapter fixes how a skill's parameters are compiled into the tuple and how the tuple is made deterministic, not the types themselves. monitors is the canonical-action home of the feature-monitoring seam every other chapter left to 02: a StopCondition or a ForceEvent the action watches is emitted here as a Monitor, with its threshold / signature evaluated per the 01 / 04 definitions.
The safety_envelope carries the safety constraints in force for the action — the per-embodiment instantiation of the primitive's Skill ISA safety envelope (01), with every bound clamped to the embodiment's declared limits (03):
Envelope := {
motion_bounds: { v_max, a_max, w_max, … }, # kinematic caps (reach / transport), clamped to embodiment.limits.*
force_profile: Option<ForceProfile>, # the force / torque trajectory bound (force category); interval-checked by 05 ENV4
clearance: Length, # min clearance to the collision model, with the exempt / augment sets (03)
compliance: Option<Compliance>, # the requested compliance mode + direction (03)
stop_time: Duration, # max time to reach a safe state on a breach (embodiment.limits.stop_time)
}
The envelope is the data the 05 envelope classes (05 § The envelope-class taxonomy) sample against: motion_bounds for the interval-invariant class, force_profile for the force / torque-trajectory class. How each bound is derived — min_holding_force, the dynamic-stability a_max clamp, the reaction-load limit — is § Grasp-force and stability derivations (later unit).
Pose6D is a rigid-body pose: a position in R³ (metres) plus an orientation as a unit quaternion. This is the ROS 2-aligned representation (geometry_msgs/Pose parity, consistent with the ROS 2-compatible driver protocol of 03); SE(3) is the group beneath it (used for composition and frame chaining), and the unit quaternion is the canonical serialization. The choice is provider-neutral (Principle 4): no embodiment's orientation convention is privileged.
The single-scalar geodesic orientation error. The representation is chosen so that orientation error reduces to one scalar — the requirement that makes pose_not_reached decidable. For target orientation q_t and current q_c (unit quaternions):
θ_orient = 2 · arccos( |⟨q_t, q_c⟩| ) # geodesic angle on SO(3), in [0, π]
is the geodesic rotation between them; the |·| resolves the quaternion double-cover so q and −q denote one orientation. A pose is reached iff position error ≤ the primitive's position_tolerance and θ_orient ≤ its orientation_tolerance; pose_not_reached is the negation. The single scalar θ_orient is what every primitive's terminal postcondition and orientation_tolerance (01) compare against.
Under-constrained-orientation residual rule (decided). When a primitive constrains fewer than three orientation axes — reach.align with a subset of axes, place.orient with one OrientationSpec constraint — the remaining orientation freedom is resolved by the minimum geodesic rotation from the current orientation: among all orientations satisfying the declared constraints, retarget selects the one nearest (smallest θ_orient) to the frame's current orientation. The rule applies uniformly wherever orientation is under-constrained, which is what makes the resolution deterministic (binding for retarget determinism, 05 Class 2) rather than an arbitrary pick from the satisfying set.
v0.1 guarantees rest-at-goal: every motion primitive terminates at rest (zero commanded velocity) at its goal pose. The terminal-postcondition envelope class (05) and every reach primitive's "terminating at rest" postcondition (01) depend on it. To leave room for non-stop trajectory blending in a future version without breaking the guarantee (Principle 5), the canonical action's timing reserves a stop_at_goal: bool (default true): v0.1 fixes it true; a later version may set it false to blend one primitive's goal into the next's start without resting, and the change is additive — a v1.x driver implementing only stop_at_goal = true stays conformant.
- CA1c — pose reachability decidable.
pose_not_reachedis decided from the position error and the single-scalar geodesic orientation errorθ_orient = 2·arccos|⟨q_t, q_c⟩|against the primitive'sposition_tolerance/orientation_tolerance. - CA2c — under-constrained residual determinism. Where orientation is under-constrained,
retargetresolves the residual as the minimum geodesic rotation from the current orientation, uniformly and deterministically. - CA3c — rest-at-goal. Every motion primitive terminates at rest at its goal in v0.1 (
stop_at_goal = true); the reservedstop_at_goalfield admits future non-stop blending additively without breaking the guarantee. - CA4c — envelope clamping. Every
Envelopebound is the primitive's Skill ISA safety-envelope constraint clamped to the embodiment's declaredembodiment.limits.*; an action whose bound exceeds a declared limit is malformed.
Pose6D,TactileTarget,StopCondition, the per-primitive tolerances and safety envelopes the tuple andEnvelopecarry —01-skill-isa.md/04-tactile-manifold.md.- The embodiment limits every
Envelopebound clamps to —03-driver-interface.md§ Capability manifest. - The derivations of the force / acceleration bounds (
min_holding_force, dynamic-stabilitya_max, reaction-load) — § Grasp-force and stability derivations (later unit). TimingHintsand time-scaling — § Trajectory generation and timing (later unit).
retarget(skill, embodiment) must be deterministic: identical inputs produce identical canonical-action sequences, byte-for-byte. The determinism requirement is binding because conformance testing (05-conformance.md) compares observed retargeting output against frozen fixtures. Determinism applies to the generation of the canonical action; whether the realized execution of that action is reproducible is a separate question, bounded next.
retarget generation is byte-deterministic unconditionally. The realized execution of an action is not always reproducible, and the boundary is where conformance splits (05 § The determinism floor):
- Kinematic primitives —
reach, and any action executed by position / velocity control against free space — have a reproducible realized execution: Class 2-strict (bit-identical).reach.scan's sweep setΣis the archetype — a purely-kinematic function of its inputs (§ Trajectory generation and timing). - Contact-dynamics primitives — every
forceprimitive (compliant search executes against contact dynamics) and the passive-drive modesin_hand.pivot(drive = gravity | external)(the outcome depends on embodiment dynamics, not just the canonical action) — have a realized execution that is not byte-reproducible. Their canonical-action generation is still Class 2-strict; only the realized-execution check is Class 2-loose (semantic equivalence within a per-skill ε), with the tolerance loosened accordingly — parallel toreach.scan's purely-kinematic contract as the strict archetype.
Making the boundary explicit is what keeps a passive or compliant primitive from being failed for not reproducing a contact-dynamics trajectory it was never deterministic in.
Single-embodiment retarget is byte-deterministic (above). transport.handoff between two parties exceeds that boundary:
- Bimanual handoff (within one embodiment) closes inside one
retargetrun — both effectors are planned together, so it is fully deterministic and fully specified in-spec (the two-party continuity GC6 in05, theEffectorRefin03). - Inter-robot handoff coordinates two
retargetruns, one per embodiment, exceeding single-embodiment byte determinism. v0.1 specifies the handoff semantics (the GC6 two-party continuity invariant and theEffectorRefaddressing) and the two-party determinism boundary (each run is deterministic, but the cross-run interleaving is not held to single-embodiment byte reproducibility); it defers the inter-robot coordination protocol — the wire mechanism two embodiments use to synchronize the dual-grasp window — as a named v0.1 deferral. Bimanual is the fully-specified case; inter-robot is semantics-now, mechanism-later.
retarget selects a capable embodiment for a task. Beyond the binary presence / absence gate (03's capability_absent), negotiation matches a task's geometry uncertainty against an embodiment's declared robustness: an uncertain-geometry task is routed to an envelope-capable embodiment, using the robustness grasp.envelope declares (a compliant / caging grasp tolerates pose uncertainty a precision pinch cannot). Uncertainty-robust routing is the retarget-side complement to 03's static gate — the gate decides can this embodiment do it at all, negotiation decides which capable embodiment is robust enough for this task's uncertainty.
- RD1c — generation determinism.
retargetgenerates the canonical action byte-for-byte deterministically for identical inputs, unconditionally (the strict floor on generation). - RD2c — realized-execution boundary. A primitive whose realized execution runs against contact dynamics (
forcecompliant search;in_hand.pivotpassive drive) is held to Class 2-loose on realized execution (semantic equivalence within a per-skill ε), never byte-reproducibility; its canonical-action generation stays Class 2-strict. - RD3c — bimanual vs. inter-robot. Bimanual handoff closes within one embodiment's
retarget(fully deterministic, in-spec); inter-robot handoff's two-party determinism semantics are specified and its coordination protocol is a named v0.1 deferral. - RD4c — uncertainty-robust routing. Capability negotiation routes an uncertain-geometry task to an envelope-capable embodiment by matching the task's geometry uncertainty against the embodiment's declared
grasp.enveloperobustness, beyond the binarycapability_absentgate.
- The Class 2-strict / Class 2-loose conformance split and the per-skill ε-table —
05-conformance.md§ The determinism floor. - The two-party continuity invariant (GC6) and the
EffectorRefaddressing the handoff semantics build on —05-conformance.md/03-driver-interface.md. grasp.envelope's declared robustness the routing reads —01-skill-isa.md/03-driver-interface.md.
The Envelope (§ Canonical action representation) carries force and acceleration bounds; this section is where they are derived. Four quantities, all computed deterministically from the grasp's StabilityMetadata (01 § Grasp state model), the object mass, the grasp geometry, and a declared friction coefficient — never runtime-measured, so retarget generation stays byte-deterministic (RD1c). They share one underlying quantity: the grasp's holding capacity.
A grasp's holding capacity is the maximum external load it can resist before the object moves in-grasp, and it is directional — capacity differs by axis and by closure type (01 StabilityMetadata.closure / secured_dof):
- a force-closure grasp resists load by friction: capacity along an axis ≈
μ · Σ(normal forces) · geometry factor, bounded by the available grip force; - a form-closure grasp resists load by shape along its
stable_directions(high capacity there, ~none in the free directions); - a support grasp bears load through the support polygon (balance), with capacity set by the CoM margin, not grip.
The four derivations below all compare a load against this capacity along the relevant axis. The capacity model is schematic and provider-neutral (Principle 4): RFL fixes the dependency — capacity is a function of closure, secured DOF, grip / normal force, geometry, and friction — not a single vendor's friction law.
min_holding_force is the grip force below which the object falls under its own weight — the static floor. It is derived from the object weight (target.estimated_mass), the grasp mode (which fixes how capacity scales with grip — force vs. form vs. support), the friction coefficient, and the load direction (gravity relative to the grasp's secured directions): the grip must produce holding capacity ≥ the gravity load along the unsecured axes. For a force-closure pinch it is roughly m·g / (μ · geometry); for a form or support grasp the shape or balance bears the weight and the grip minimum is lower. It is the floor the grasp-continuity invariant checks (05 GC1) and that grasp.adjust maintains.
Under acceleration the object's inertial load (m·a) adds to gravity (m·g); the grasp holds iff the combined load stays within holding capacity along the load direction. The dynamic-stability limit is the largest acceleration a_max at which inertial + gravity load ≤ holding capacity — solved from StabilityMetadata (secured_dof / closure / flags) + object mass + grasp geometry. It clamps max_acceleration in the Envelope.motion_bounds of every transport primitive (the dynamic counterpart of min_holding_force, and the core of transport safety). A transport.carry's acceleration is clamped below this to reserve margin for its disturbance_budget (05 ENV3).
A force primitive applies force to a target, and the reaction loads the grasp: an insertion's axial reaction, a press's normal reaction. The reaction must not exceed holding capacity along the reaction axis, or the held part slips before the task completes. The reaction-load limit is derived from StabilityMetadata + grasp geometry along the reaction axis, and bounds the force budget so the task completes without in-grasp slip. Two generalizations:
- Rotational capacity (
force.screw/force.unscrew): the reaction is a torque about the tool axis; the grasp must resist it with rotational holding capacity (the form / friction resistance to twist), or the tool spins in-grasp. - Periodic-reversal load (
force.scrub): the tangential reaction reverses each stroke; the tool must be retained at every reversal, where the load direction flips — capacity must hold in both tangential directions, not just one.
force.screw (and later force.cut) transmit force / torque to the target through a held tool — a driver, a cutter. Two consequences for retarget:
- The tool is the force-transmission path, and its grasp bears the reaction. The reaction-load limit applies to the tool's grasp (tool-grasp-under-reaction-load), not the target's — the grip on the driver must resist the driving torque, or the driver slips in-hand. The canonical action represents the held tool as the transmission path so the reaction loads the right grasp.
- Coupled DOF.
force.screwcouples rotation to axial advance atthread_pitch(one turn ↔thread_pitchof advance);retargetexpands this coupling into the canonical action as a linked DOF, and a decoupling — advance without turn, or turn without advance — is a failure signal (a cross-thread or a stripped fastener), not a free parameter.
- GF1c —
min_holding_forcederivation.min_holding_forceis derived deterministically from object weight, grasp mode, friction, and load direction; it is the floor the grasp-continuity invariant (05GC1) checks and thatgrasp.adjustmaintains. - GF2c — dynamic-stability clamp.
max_accelerationis clamped to the largest acceleration at which inertial + gravity load stays within holding capacity along the load direction, derived fromStabilityMetadata+ mass + geometry; applied to everytransportprimitive'smotion_bounds. - GF3c — reaction-load limit. A
forceprimitive's reaction may not exceed holding capacity along the reaction axis (linear), the rotational capacity about the tool axis (torque reaction), or be lost at a periodic reversal (scrub); the limit is derived and the primitive aborts before in-grasp slip. - GF4c — tool-mediated transmission and coupling. Force through a held tool loads the tool's grasp (tool-grasp-under-reaction-load);
force.screw's rotation↔advance coupling atthread_pitchis expanded into the canonical action, and a decoupling (advance without turn, or vice versa) is a failure signal.
StabilityMetadata(closure/secured_dof/flags), the grasp modes, and theforce-category force budgets these derivations bound —01-skill-isa.md.- The friction coefficient and object mass the derivations consume (declared contact / target properties; the perception that estimates them is out of scope) —
01-skill-isa.md§ type system. - The interval force / torque-trajectory verification that checks the realized profile against the derived bound —
05-conformance.md§ ENV4.
Two parts of retarget generate a path or a timing rather than compile a single pose — the scan sweep set Σ and the time-scaling of a trajectory. Both are deterministic generators: pure functions of their declared inputs, so generation stays Class 2-strict (RD1c) even though one of them (time-scaling) feeds a contact-bearing transport whose realized execution may be Class 2-loose.
reach.scan covers a region by a generated sweep set Σ — the ordered sensor poses whose union observes the region. Σ is a deterministic function of (region, pattern, standoff, coverage_overlap, fov):
- the observation footprint at the surface is
2 · standoff · tan(half_fov)(thefovfrom03's sensor descriptor, thestandofffrom the primitive); - the pass spacing is the footprint reduced by
coverage_overlap; - the pattern lays the passes out:
raster= parallel passes at the spacing;spiral= an in / out spiral for a centered region;arc= a swept arc about a pivot;waypoints= the caller's ordered poses (the degenerate generator,Σ= the waypoints).
The four generators are normative — a normative appendix fixes the exact construction — so Σ is byte-reproducible across implementations (reach.scan C2, 05 Class 2). RFL fixes the geometric coverage construction; the perception that interprets what the sweep observes is out of scope (the reach.scan / sense.inspect capturability boundary, 04).
transport.follow_trajectory(timing_mode = time_scalable) takes a caller-supplied path (a Trajectory, 01) and re-times it — slowing the timing while preserving the path shape — until its curvature-and-speed profile fits within two bounds:
- the dynamic grasp-stability limit (the
a_maxof § Grasp-force and stability derivations) — the held object must not slip under the trajectory's accelerations; - the embodiment's kinematic limits (
v/a/ jerk,03).
A trajectory that is safe slowly but would exceed dynamic stability at full speed is slowed, not rejected — the geometric route is unchanged, only the velocity profile along it is scaled down. The algorithm is deterministic: identical (path, dynamic-stability limit, kinematic limits) yield identical timing, preserving retarget determinism (RD1c). Preserving path shape is the contract — time-scaling never alters the geometric path, only its parameterization in time.
- TG1c — normative sweep set. The sweep set
Σforpattern ∈ {raster, spiral, arc, waypoints}is a deterministic function of(region, pattern, standoff, coverage_overlap, fov)per § Appendix A — Normative sweep-pattern generators; identical inputs yield a byte-identicalΣ(reach.scanC2). - TG2c — time-scaling determinism and shape preservation.
time_scalablere-times a trajectory — preserving the geometric path shape — until its curvature-and-speed profile fits within the dynamic-stability limit and the embodiment's kinematic limits; the re-timing is a deterministic function of(path, limits)and never alters the path.
- The
TrajectoryandScanRegiontypes, andreach.scan/transport.follow_trajectory—01-skill-isa.md. - The
fovand kinematic limits the generators consume —03-driver-interface.md§ Sensor descriptor / § Capability manifest. - The dynamic grasp-stability
a_maxtime-scaling fits within — § Grasp-force and stability derivations. - The exact per-pattern
Σconstruction — § Appendix A — Normative sweep-pattern generators (this chapter).
These issues surfaced during reach / grasp primitive design and are now addressed in the Skill ISA type system and the grasp state model (01-skill-isa.md). Detail lives in the spec body; retained here as a design-history trail.
SurfaceTarget/ObjectTarget/FeatureRef/ScanRegiontypes →01§ Skill ISA type system. Perception-derived target types are defined (fields +UncertaintyBound); the perception that produces them stays out of scope.ObjectTargetcenter-of-mass →01type system (center_of_massfield).- Grasp stability metadata in the result schema (
closure,stable_directions) →01§ Grasp state model. Applied retroactively tograsp.pinch/grasp.power. - Stability-metadata generalization (form-held vs friction-held vs balance-held DOF) →
01StabilityMetadata.secured_dof. - Third closure type
support→01StabilityMetadata.closure ∈ {force, form, support}. - Extrinsic / surface-bound flags,
compliant,rotation_constrained,residual_mobility→01StabilityMetadata.flags/ fields. - Active-grasp state model and
GraspRef→01§ Grasp state model (GraspState, lifecycle FSM, transition table). - "Grasp core" abstraction structuring →
01Category 2 intro (core + contact-pattern delta documented; the full DRY rewrite of each primitive remains a pre-freeze formatting pass, not a semantic gap).
All groups resolved (2026-05-31). Every item below is marked
[resolved → … § …]: the03,01,04, and05chapter groups and this chapter's own02group are all closed. The section is retained as the cross-chapter design-history trail. The normativeΣ-generator construction is now fixed in § Appendix A. Remaining pre-freeze work is implementation artifacts — the JSON Schema and the per-skill ε-tolerance table — not open design questions.
Frame-declaration layer resolved (2026-05-30). The embodiment frame model —
known_frames/control_frames, the well-knownworld/base/taskreference frames, per-control-frametool_axis, the role tags{grasp, sensor, support, tactile}, the fivedefault_*_framefields, the<rfl:capabilities>binding, and conformance obligations F1–F4 — is now specified in03§ Embodiment frame model. The remaining items below are the per-category capability flags, limits, collision-model, and sensor/tool/safety descriptors that build on it.
Capability-manifest skeleton resolved (2026-05-30). The generic manifest structure the per-category declarations below instantiate is now specified in
03§ Capability manifest: primitive capabilities (keyed by ISA primitive ID;reach.*is the unkeyed baseline; grasp modes aregrasp.<mode>sub-capabilities), auxiliary capabilities (compliance/tactile_sensing/tool_safety/human_collaboration_safety, with value domains), the flatembodiment.limits.*namespace with the capability→limit completeness rule, the uniformcapability_absentvalidation gate, static manifest acquisition, the reservedtiersyntax, and conformance obligations M1–M4. The per-category items below now reduce to enumerating which flags / limits each category contributes to this skeleton.
Control-frame declaration[resolved →03§ Embodiment frame model]:control_framesset anddefault_control_framefield; retargeting mapscontrolled_frame → embodiment native frame. Non-anthropomorphic embodiments may expose several control frames.[resolved →default_tool_axis(per control frame)03]: used byreach.approach/reach.alignand theforcefamily. Resolves to the activecontrolled_frame'stool_axis.[resolved →default_sensor_frame+ per-sensorfov/bore_axis/max_sweep_rate03§ Sensor descriptor]: the frame-keyedembodiment.sensors[sensor_frame]map (bore_axis, the angularfovas{h_angle, v_angle}about the bore axis,working_range,max_sweep_rate,modalities), the non-contact-vs-contact scope split (contact-sensor fields stay in04), and the determinism ofΣfrom declaredfov.default_sensor_frameitself was resolved in § Embodiment frame model.[resolved →tracking_bandwidthinembodiment.limits03§ Reach baseline limits]: declared among the reach-baseline motion limits; gatesreach.hover(track_target)and itstrack_lostmode.Collision-model target exclusion[resolved →03§ Collision model]: the clearance query takes anexemptset (per-primitive:target/region/against_surface/setdown_surface/support_object) and a dualaugmentset (the freed object ingrasp.release).Swept-volume clearance query[resolved →03§ Collision model]: the query answersat_pose/corridor/sweptgeometries, all mandatory; swept-volume covers in-place rotation and trajectories, with self-collision checked.Per-grasp-mode descriptor fields[resolved →03§ Grasp-mode capabilities and limits]: the eight mode capabilities (grasp.pinch/power/hook/tripod/lateral/platform/pin/envelope, canonical dotted keys for the Skill ISA's*_graspspellings), the sharedgrip_force_max/v_graspvs. per-mode payload / size limits (payload_grasp_*,payload_support,hook_load_capacity,enclosure_span,precision_object_size_max,lateral_grasp_max_thickness,enclosure_range), the frame-keyedgrasp_envelope(frame)andsupport_polygon(support_frame)geometry, and the tactile-preferred-not-required policy.default_grasp_frame/default_support_framewere resolved earlier in § Embodiment frame model.In-hand descriptor fields[resolved →03§ In-hand capabilities and limits]: categoryin_hand(no base primitive) + the seven sub-capabilities, the sharedw_inhand_max/v_inhand_max, and the grasp-mode-keyed range mapsinhand_rotation_range[grasp_mode]/inhand_translation_range[grasp_mode]. Slide's closed-loop slip sensing stays with04; DOF-admissibility with01.Transport descriptor fields[resolved →03§ Transport capabilities and limits]: categorytransport(= basemove_to_pose) + the five sub-capabilities, the generalv_cartesian_max/a_cartesian_max(reach-introduced), and the transport-specificcograsp_force_budget(handoff) /stability_margin(carry). Held-object inclusion was resolved in § Collision model (effector_with_held); the dynamic-stabilitymax_accelerationclamp and time-scaling stay with02; inter-robot handoff (EffectorRef+ coordination channel) remains open as the multi-embodiment item below.Gravity-direction declaration[resolved →03§ Gravity declaration]:embodiment.world.gravityis an optional world-frame acceleration vector (direction + magnitude); the±gravitydefaults resolve from it deterministically; a gravity-free environment (absent / zero) makes the gravity-defaulted directions required and disablesdrive = gravityprimitives. The dynamic-stability gravity term and mass↔weight reconciliation stay with02/01respectively.Place descriptor field[resolved →03§ Place capabilities]: categoryplace+ the six sub-capabilities as a composite category — each presupposes the composedtransport.lower/grasp.release(andin_handfororient), adds no new force-dynamics axis, and introduces no new limit. The supported-state / recursive-stack / containment predicates stay with01.Compliance capability + force descriptor fields[resolved →03§ Compliance capability + § Force capabilities and limits]: compliance (the{passive, active, virtual}domain vs.{passive, active, auto}request, normal-direction-compliance withnormal_compliance_range, the rigid-only gate) and the tenforcesub-capabilities withoscillation_maxas the sole new limit (force budgets are target-clamped parameters). Tool-mediated force / thread coupling, hybrid-axis encoding, and the force-trajectory envelope stay with02/05.Sense descriptor fields[resolved →03§ Sense capabilities]: categorysense(no base primitive) + the five sub-capabilities, each with a sensing requirement referenced to04/ the sensor descriptor;max_probe_forceis target-derived (not an embodiment limit) andsenseadds no new limit.default_tactile_framewas resolved in § Embodiment frame model; the disturb threshold is a perception-derived target property; the measurement-non-disturbance invariant stays with05/04.- Hybrid force/position control + contour following:
force.wipe/force.scrubcontrol force along the surface normal and position along the tangent simultaneously (the classic hybrid controller).retargetmust encode which axes are force-controlled vs position-controlled in the canonical action. Contour following needs declared normal-direction compliance whose range bounds the surface height variation the primitive can accommodate. [Normal-direction-compliance capability +normal_compliance_rangeresolved →03§ Compliance capability; the canonical-action force-vs-position axis encoding remains owned by02.] Oscillation descriptor + wear/heat limit[resolved →03§ Force capabilities and limits]:embodiment.limits.oscillation_max(Frequency, Hz) isforce.scrub's new limit; the optional wear/heat budget that bounds sustained abrasion is deployment-declared.[resolved →EffectorRefand multi-embodiment addressing03§ Multi-embodiment addressing]:EffectorRefas localframe_name| remoteembodiment_id:frame_name(the cross-embodiment generalization ofFrameRef), the stableembodiment.id, thecoordination_channelcapability for inter-robot handoff, and the bimanual-vs-inter-robot split. The coordination protocol and two-party determinism stay with02(multi-embodiment-coordination item below); discovery / registry is a deployment concern.
Interval-invariant test class[resolved →05§ The envelope-class taxonomy]: one of the four envelope classes — sustained primitives (reach.hover;transport.carry) sample the maintained invariant at every step over the interval, distinct from the terminal-postcondition endpoint check; adisturbance-rejectinginterval test injects calibrated disturbances up todisturbance_budget(ENV2 / ENV3). Interval sampling runs on the04manifold timebase for fixture determinism.Grasp-continuity envelope class[resolved →05§ Grasp-continuity modes, Base continuity]: the held → held invariant "a securing contact set holds the object at ≥min_holding_forceat every sampled instant", verified from the force trace (GC1); the base mode of the most elaborate envelope class.Hold-test canonicalization + closure branching[resolved →05§ Grasp-continuity modes, The hold test and closure branching]: the hold test (calibrated sub-budget perturbation → retention) is the operational definition of closure, with the perturbation profile branched onclosure ∈ {force: omnidirectional, form: load-direction, support: level-gentle}(GC2) — one canonical procedure across all ten grasp modes.Non-degenerate-triangle confirmation[resolved →05§ Closure, stability, and composition verification, Non-degenerate tripod]: agrasp.precision_tripodis confirmed only when its three contacts form a non-collinear triangle above a minimum-area threshold (else the claimedrotation_constrainedis absent) — STB1.Support-grasp safe state[resolved →05§ Closure, stability, and composition verification, Support-grasp safe state]: asupport/balance_heldgrasp's safe response is a controlled lowering to the nearest surface minimizing fall height, never an open-release (STB2).Reversibility spectrum + persistent state change[resolved →05§ Reversibility and irreversible-operation safety, The reversibility spectrum]: primitives are positioned reversible / semi-reversible-persistent / irreversible, safety weight rising with irreversibility (REV1);force.snap_engageis semi-reversible — engagement-confirmation (confirm_held) + a documentedsnap_disengagereverse path (REV2); the spectrum is open at both ends for06extensions.Irreversible-operation safety class[resolved →05§ Reversibility and irreversible-operation safety, The irreversible-operation safety class]: an irreversible operation (force.cut) runs only under a strictly bounded action path, pre-execution confirmation of the path and the material beyond it, and precise partial / irreversible-state reporting on failure (REV3) — the precedent for future irreversible extensions (weld, adhesive).Tool-safety capability[declaration →03§ Safety capabilities; conformance bench resolved →05§ Hazardous-operation conformance benches]: hazardous tools (cutters inforce.cut) require the declaredtool_safetycapability (03:hazard_class+standard, the hazardous-tool gate) and the instrumented bench (05: shear measurement, separation detection, hard-inclusion injection → safe arrest) — HAZ1 / HAZ2. A primitive wielding a hazardous tool must not run without the capability.Human-collaboration safety + handover conformance[declaration →03§ Safety capabilities; dummy-hand bench resolved →05§ Hazardous-operation conformance benches]:place.hand_torequires the declaredhuman_collaboration_safetycapability (03:standard+max_interaction_force/weight_transfer_threshold) and the instrumented dummy-hand bench (05: release only after weight transfer, exchanged force ≤max_interaction_force, compliant yielding) — HAZ3 (ISO 10218 / 13482, L4).Force-trajectory envelope class[resolved →05§ The envelope-class taxonomy, The force/torque-trajectory class]: the fourth envelope class — theforcecategory's profile bounded interval-sampled against per-axis budgets (a mid-motion spike is a violation), generalized to a torque trajectory about an axis forforce.screw/force.unscrew(ENV4). The terminating breakaway / detent events are evaluated on the same sampled trajectory (04§ Force events).Composition validity by grasp stability class[resolved →05§ Closure, stability, and composition verification, Composition validity by stability class]: the stability-class → permitted-successor table —surface_boundforbids free transport,form_held/rotation_constrainedDOF forbid the correspondingin_handop,supportforbids free transport + open-release — a static validation atop the01lifecycle table, the conformance complement of01's DOF-admissibility rule (STB3).Gaiting + make-before-break continuity verification[resolved →05§ Grasp-continuity modes, Make-before-break and gaiting]: continuity holds iff at every instant the union of engaged contacts (old, new, or both) satisfiesmin_holding_force, and a regrasp confirms the new grasp before releasing the old (GC3); the most general form of the class, of which base continuity is the degenerate case.Controlled-under-actuation continuity mode[resolved →05§ Grasp-continuity modes, Controlled under-actuation]: a pivot releases exactly the named DOF (under-constrained) while all others secure at ≥min_holding_force, and re-secures it at completion (GC4) — continuity preserved through a relaxed, not swapped, constraint.Bounded continuity-exception subclass[resolved →05§ Grasp-continuity modes, Bounded continuity-exception]:in_hand.flip's continuity suspension is a bounded subclass — unsecured window ≤max_release_time, re-catch withincatch_envelope, safe-landing fallback insafe_drop_zone(GC5) — distinct from the continuity-preserving modes.Two-party / co-grasp continuity[resolved →05§ Grasp-continuity modes, Two-party co-grasp]: at every instant at least one party secures the object at ≥min_holding_force, and the combined force stays ≤cograsp_force_budgetin the dual-grasp window (GC6); bimanual is fully verifiable, inter-robot coordination stays a02open issue.[resolved →momentary_releaseaudit propagation05§ Audit and transparency]:in_hand.flipsetsmomentary_release = true, persisted and propagated downstream so the L4 / L8 loops can trace every continuity break (AUD2). Generalized: the audit record carries each result's evidence-bearingVerdict, its04fidelity tier on a degraded confirmation, and a freeing operation's freed-part disposition (AUD1 / AUD3) — RFL produces the evidence (01/04),05persists and propagates it; the L4 / L8 loops themselves stay in the strategy / governance docs.
Tactile-absent confirmation proxy[resolved →04§ Graceful degradation and the force/position proxy]: the proxy is the conjunction of position-convergence (grasp_width ≈ target cross-section, not past it — the empty-close guard) and force-rise-and-hold; per-grasp-mode proxy expansions are tabulated. Force-closure confirmation is proxy-degradable; slip / deformation are proxy-irreducible and degrade to reactive-only at a lower fidelity tier — never a tactile hard-reject (the orthogonaltool_safety/human_collaboration_safetycapabilities own the hard gates; risk-acceptance of a tier is the L4 decision).Bend / crease indicator[resolved →04§ Deformation, Crush vs. bend discrimination]:bending(BendState:flexing/crease_axis/curvature) is a curvature-about-a-crease-line signal, discriminated fromdeformation_rate(symmetric bulk compression / crush) by the contact distribution shape — a pressure gradient indicates curling, uniform compression indicates crush. Backsgrasp.lateral'sbend_abort; the shape indicator is proxy-irreducible (the declaredmax_contact_force/ bend limit stays proxy-enforceable, the shape early-warning degrades to reactive-only).Intended-rolling vs gross-slip discrimination[resolved →04§ Slip, Rolling discriminator]: the generalintended-slip modelclassifies an observedSlipState(stage/direction/rate) against the command's expected slip;roll's model is the rolling kinematics, so slip that skids beyond the migration rate, runs off the roll tangent, or persists at ω = 0 isgross_slip, while migration consistent with the commanded ω is controlled.Intended-slip vs drop-slip discrimination + closed-loop slip sensing[resolved →04§ Slip, Sliding discriminator + Closed-loop slip sensing]:slide's model is directional — theslide_directionslip component is intended feed, an orthogonal-DOF component beyond tolerance isdrop_slip(discrimination by direction, not rate). Closed-loop slip sensing is theslipfeature at loop-rate temporal resolution; absent, displacement tracking still runs (position proxy) but drop-slip detection degrades to reactive-only gross-escape atproxy_reactivetier (the irreducible-guard rule).Breakaway detection[resolved →04§ Force events, Breakaway]: abreakawayis aforce_derivativefall past a declared negative-rate threshold plus a settled lower effort level; it fires on the leading edge so the effector arrests without follow-through lurch, and recurs asforce.unscrew'storque_drop. Unified with detent under theForceEventtype (the manifold resolution of theStopConditioneffort_dropvariant).Detent / snap detection[resolved →04§ Force events, Detent vs. bottoming-out]: adetentis a rise-then-drop effort signature while motion continues (the click / snap); a monotone rise to a plateau is bottoming-out, never reported as actuation success. Resolves theStopConditiondetentvariant; the multi-rate temporal-alignment timebase (common monotonic timebase + slowest-contributing-feature grid) that makesForceEventdetection deterministic is defined in the same section, resolving the chapter's second skeleton open issue.Freed-part handling[resolved →04§ Freed-part handling at constraint release]: the freeing moment is aForceEvent(breakaway forforce.unscrew, cut-completion forforce.cut) read as a constrained → free transition; on it a disposition contract binds —retainedorsafe_zone_release(zone), never an uncontrolled drop — the same guarantee asin_hand.flip'ssafe_drop_zoneandplace.discard. The freed part hands off to the collision augment set (03) and world-state (01); the contract binds even under degraded reactive-only detection.Tactile-target representation under TactileManifold (general).[resolved →04§ TheTactileTargettype]: aTactileTargetis a conjunction ofTactileClauses (feature, comparator,threshold, site-quantifier) evaluated over the abstract site model (04§ Site model) against the closed-core feature taxonomy; the grasp primitives'autospellings are its canonical expansions, and an unsatisfiable target degrades to the force/position proxy rather than failing. The feature-field model, the closed-core + registry field-set decision, the contact-sensor descriptorembodiment.tactile[tactile_frame], and per-feature uncertainty are specified in the same chapter.Measurement non-disturbance invariant[resolved →04§ Sensing-scope contracts, Measurement non-disturbance] (verification owned by05): the contact-sensing scope — contact force suppressed below the target's disturb threshold (a target property), the dual offorce's budget (drive-up-to vs. suppress-below);presence = falseis a valid measurement, never a fabricated reading. The suppression constraint is proxy-degradable to a force cap; the target-unchanged-across-measurement bench stays with05.Observation-capturability contract[resolved →04§ Sensing-scope contracts, Observation-capturability]: the non-contact-sensing scope —capturable = in_fov ∧ unoccluded ∧ in_range, decided from03'sfov/working_range; occlusion / out-of-range is reported unobservable, never a confident reading from a bad view. Unified with non-disturbance under one RFL / perception boundary: RFL guarantees a measurement was physically valid to take, never its interpretation (perception / VLA).
[resolved →reactive-body envelope precedence01§ Predicates, verdicts, and three-valued control flow]: a concurrent envelope violation takes precedence over a cleanuntilcompletion, deterministically.[resolved →StatePredicatetype +sense.verifyas the algebraPredicate01§ Predicates, verdicts, and three-valued control flow]:Predicate≡StatePredicate(one type) evaluating to aVerdict; two paths — internal-state predicates evaluate directly, perception-dependent ones viasense.verify(the general evaluator). The verdict drivesreactive/branch/force.scrubstate_change.Three-valued verdict in control flow[resolved →01§ Predicates, verdicts, and three-valued control flow]:branchgains an optionalunknownarm (absent → escalate, never coerce);reactive'suntilterminates only on a confidenttrue, soindeterminatenever silently completes.Verdict honesty + evidence audit[resolved →01§ Predicates, verdicts, and three-valued control flow]:Verdictassertstrue/falseonly aboveconfidence_threshold, elseindeterminate, and always carriesevidence. RFL owns producing the evidence-bearing verdict; the L4 / L8 audit loops that consume the persisted evidence stay with05.Start-in-contact + break-contact envelope clause[resolved →01§ World-state model, Shared break-contact clause]: thebreak_contactpostcondition + directional force-monotonicity, factored out as one clause shared byreach.retract/grasp.release/place.put_down.Supported-state predicate[resolved →01§ World-state model]:supported(object)= CoM inside its contact polygon (thegrasp.platformCoM-over-polygon test on a resting object); gatesgrasp.release/place.*.Recursive (stack) stability predicate + world-state support tracking[resolved →01§ World-state model]: the world-state model tracks support relations ("A rests on B");stack_stableapplies the supported-state predicate recursively over the tracked chain (each level's CoM in the level-below polygon, combined CoM in the base polygon).Containment predicate + container geometry[resolved →01§ World-state model]:GeometryRefgains a container aspect (opening + interior);contained(object, container)gatesplace.insert_loose; theinsert_loosevsinsert_fitselection criterion is "opening clearance > object cross-section".Last-resort[resolved →flipadmissibility01§ Composition validity, Last-resort admissibility]: the "does a continuity-preserving alternative exist?" check is part of composition validity;flipis admissible only whenrotate/roll/regraspcannot achieve the reorientation.Place ↔ in_hand reverse-dependency composition[resolved →01§ Composition validity, Reverse-dependency composition]: the "compose a prerequisite primitive first" pattern — the planner inserts anin_handreorientation beforeplace.orientso its precondition holds, each primitive single-responsibility.Stability-metadata-driven admissibility[resolved →01§ Composition validity, DOF-admissibility]: one rule — anin_handoperation moves a DOF only if it isfriction_held, neverform_held/rotation_constrained— with the per-primitive*_inadmissiblemodes as its instances.[resolved →ContactConfigtype01§ Spatial, motion, and structural types]: effector-region → object-surface mapping;autoor explicit forin_hand.regrasp/grasp.*.Rollable-geometry in[resolved →GeometryRef01§ Object reference, geometry, and measurement]:GeometryRefexposes a rolling-surface aspect (cylinder / sphere / cone section + rolling axis) forin_hand.roll; container geometry stays with the containment (world-state) item.[resolved →SlideStoptype01§ Stop / completion conditions]: a restriction of the unifiedStopConditionfamily (reached(distance) | landmark(tactile) | landmark(external)).[resolved →Regiontype01§ Spatial, motion, and structural types]: base spatial-extent type (geometry + frame);ScanRegionis now aRegionplus a sweepkind.[resolved →Trajectorytype01§ Spatial, motion, and structural types]: ordered waypoints / spline + timing; shares the pose-sequence backbone withreach.scan'sΣbut stays caller-specified (Σ is02-generated).[resolved →MoveSpectype01§ Spatial, motion, and structural types]:to_pose(Pose6D) | trajectory(Trajectory)fortransport.carry.[resolved →OrientationSpectype01§ Spatial, motion, and structural types]: a set of(object_axis → Direction)constraints forplace.orient; functional-label-to-geometry conversion is the caller's.[resolved →Measurementtype01§ Object reference, geometry, and measurement]: thesenseoutput type (optional presence / location / normal / stiffness / mass / center_of_mass / pose / predicate_result + uncertainty); populatesObjectTargetfields viaLetBind.predicate_resultreferences the three-valuedVerdictdefined with the algebra.[resolved →ObjectReftype + resolution flow01§ Object reference, geometry, and measurement]: the unresolved object identity;ObjectRef → sense.locate → Measurement(pose) → ObjectTarget.Precision honesty + uncertainty matching[resolved →01§ Composition validity,LetBindflow checks]: at aLetBindcarrying asense.locatepose, the algebra checksmeasured uncertainty ≤ the primitive's target-resolution bound; a pose is never stamped with unachieved precision.Sense → ObjectTarget measured-value supply (observe-act closed loop)[resolved →01§ Composition validity,LetBindflow checks]: aMeasurement'smass/center_of_mass/posepopulate the matchingObjectTargetfields via the binding, after which the downstream precondition (estimated_mass ≤ payload, …) is checkable — the primitive-level L1 Data loop.[resolved →SeatingSpectype + seating/jam discrimination01§ Stop / completion conditions]: a restriction of theStopConditionfamily (effort_rise(force) | reached(depth) | all_of{effort_rise, reached(depth)}); the force-at-state seating/jam rule is theall_ofconjunction (effort rise at depth = seated; without depth = jam). The detection informs04/05.[resolved →StopConditiontype family01§ Stop / completion conditions]: the seven named stop types (SlideStop/SeatingSpec/PullStop/ScrewStop/ActuationSpec/CutStop/ScrubStop) are unified into oneStopConditionfamily (reached/effort_rise/effort_drop/detent/count/elapsed/landmark/predicate/all_of/any_of), each a restriction of it; theall_ofconjunction carries the force-at-state seating/jam rule;predicate(StatePredicate)is the force↔sense coupling point. Theeffort_drop/detentdetection stays with04;StatePredicateitself with the algebra item; the canonical-action encoding with02.New-[resolved →GraspRefsupersession01§ Composition validity,GraspRefsupersession + § Grasp state model]:in_hand.regrasp/transport.handoffsupersede the originatingGraspRef; the stale handle is invalidated and a later use is a composition error caught at validation (dangling-reference prevention).
Pose representation choice (SE(3) / quat+t / axis-angle)[resolved → § Pose representation and orientation error]:Pose6Dis position (R³) + unit quaternion (ROS 2geometry_msgs/Poseparity; SE(3) the group beneath). The single-scalar geodesic orientation errorθ_orient = 2·arccos|⟨q_t, q_c⟩|makespose_not_reacheddecidable (CA1c).Under-constrained-orientation residual rule (decided)[resolved → § Pose representation and orientation error]: among orientations satisfying the declared constraints,retargetpicks the minimum-geodesic-rotation one from the current orientation, uniformly — deterministic, binding forretargetdeterminism (CA2c).Rest-at-goal vs. trajectory blending[resolved → § Terminal semantics — rest-at-goal]: v0.1 guarantees rest-at-goal;timingreservesstop_at_goal: bool(defaulttrue) so future non-stop blending is additive without breaking the guarantee (CA3c, Principle 5).Normative sweep-pattern generators[resolved → § Trajectory generation and timing, Normative sweep-pattern generators]:Σforpattern ∈ {raster, spiral, arc, waypoints}is a deterministic, byte-reproducible function of(region, pattern, standoff, coverage_overlap, fov)— footprint2·standoff·tan(half_fov), spacing reduced by overlap (TG1c); the exact per-pattern construction is fixed in § Appendix A — Normative sweep-pattern generators.[resolved → § Grasp-force and stability derivations,min_holding_forcederivationmin_holding_force]: derived deterministically from object weight, grasp mode, friction, and load direction against the grasp's directional holding capacity; the static floor the grasp-continuity invariant (05GC1) checks andgrasp.adjustmaintains (GF1c).Dynamic grasp-stability limit derivation[resolved → § Grasp-force and stability derivations, Dynamic stability]: the largest acceleration at which inertial + gravity load stays within holding capacity, fromStabilityMetadata+ mass + geometry; clampsmax_accelerationin everytransportprimitive'sEnvelope.motion_bounds(GF2c) — the dynamic counterpart ofmin_holding_force.Grasp-under-reaction-load[resolved → § Grasp-force and stability derivations, Reaction-load limit]: aforceprimitive's reaction may not exceed holding capacity along the reaction axis, the rotational capacity about the tool axis (torque reaction, screw/unscrew), or be lost at a periodic reversal (scrub); derived and aborted-before-slip (GF3c).Tool-mediated force + coupled-motion constraint[resolved → § Grasp-force and stability derivations, Tool-mediated force and coupled motion]: a force transmitted through a held tool loads the tool's grasp (tool-grasp-under-reaction-load);force.screw's rotation↔advance coupling atthread_pitchis expanded into the canonical action, and a decoupling (advance without turn, or vice versa) is a failure signal (GF4c).Uncertainty-robustness in capability negotiation[resolved → § Capability negotiation and routing]: negotiation matches a task's geometry uncertainty against an embodiment's declaredgrasp.enveloperobustness, routing uncertain-geometry tasks to envelope-capable embodiments — the retarget-side complement to03's binarycapability_absentgate (RD4c).Passive-drive determinism boundary[resolved → § The determinism boundary]:retargetgeneration is byte-deterministic unconditionally, but the realized execution of a contact-dynamics primitive (in_hand.pivotpassive drive; allforcecompliant search) is not — it is held to Class 2-loose (semantic equivalence within a per-skill ε) on realized execution, Class 2-strict on generation (RD2c). Parallel toreach.scan's purely-kinematic strict archetype.Multi-embodiment coordination + determinism[resolved → § Multi-embodiment coordination]: bimanual handoff closes within oneretarget(fully deterministic, in-spec); inter-robot handoff's two-party determinism semantics (GC6 +EffectorRef) are specified and its coordination protocol (the dual-grasp-window wire mechanism) is a named v0.1 deferral (RD3c). Semantics-now, mechanism-later.Time-scaling semantics[resolved → § Trajectory generation and timing, Time-scaling]:transport.follow_trajectory(timing_mode = time_scalable)re-times a trajectory (preserving path shape, slowing not rejecting) until its curvature-and-speed profile fits within the dynamic-stability limit and the embodiment's kinematic limits; a deterministic function of(path, limits)that preservesretargetdeterminism (TG2c).
This appendix fixes the exact construction of the scan sweep set Σ for each pattern, making Σ a byte-reproducible function of (region, pattern, standoff, coverage_overlap, fov) (TG1c; reach.scan C2). The construction is normative: a conformant retarget produces the identical Σ for identical inputs. RFL fixes the geometric coverage; the perception that interprets the captured observations is out of scope (04).
All patterns share a setup, computed in the region's reference frame (Region = geometry + frame, 01):
- Footprint. The
fov(03§ Sensor descriptor — an angular field{h_angle, v_angle}about the bore axis) and thestandoffgive a rectangular observation footprint on the surface:f_u = 2 · standoff · tan(h_angle / 2),f_v = 2 · standoff · tan(v_angle / 2). - Pass spacing. Reduced by overlap:
s_u = f_u · (1 − coverage_overlap),s_v = f_v · (1 − coverage_overlap), withcoverage_overlap ∈ [0, 1). - Surface parameterization. A surface
ScanRegionis parameterized over its axis-aligned bounding rectangle[0, U] × [0, V]in the region frame (the bounds computed deterministically from the region geometry). A station at parameter(u, v)maps to a sensor pose: position= surface_point(u, v) + standoff · n̂(u, v)(outward normal); orientation=the sensorbore_axisanti-parallel ton̂, with the bore frame's secondary axis aligned to the+udirection (a fixed roll convention, so the pose is fully determined).
Σ is the ordered list of these poses; the order is the scan path (a continuous sweep). Counts use ceil and centered placement so coverage is symmetric and complete.
Parallel passes across the surface, serpentine-ordered:
n_v = ceil(V / s_v) # number of passes
v_k = (k + 0.5) · V / n_v, k = 0 … n_v−1
n_u = ceil(U / s_u) # stations per pass
u_j = (j + 0.5) · U / n_u, j = 0 … n_u−1
Σ = [ pose(u_j, v_k) ] with j ascending on even k, descending on odd k # boustrophedon
The serpentine (boustrophedon) order makes Σ a continuous path — each pass starts where the previous ended — minimizing transit and fixing the order deterministically.
An Archimedean spiral outward from the surface centroid, for a centered region:
s = min(s_u, s_v) # isotropic pass spacing
r(θ) = (s / 2π) · θ # radial pitch per turn = s
stations at constant arc-length step Δℓ = s, from θ = 0 outward
until r(θ) exceeds the region's bounding radius
Σ = [ pose at polar (r(θ), θ) ] # CCW from the centroid, by convention
The fixed start (centroid), fixed radial pitch (s), fixed arc-length step, and fixed direction (CCW) make the spiral byte-reproducible.
A swept arc at fixed radius about a declared pivot (e.g. circumferential inspection of a cylindrical surface):
radius = standoff # sensor sweeps at standoff from the pivot
Δθ = s_u / standoff # angular step so the footprint advances by s_u along the arc
n = ceil(arc_extent / Δθ)
θ_i = arc_start + (i + 0.5) · arc_extent / n, i = 0 … n−1
Σ = [ pose on the arc at θ_i, bore pointing at the pivot ]
The degenerate generator: the caller supplies the ordered poses and Σ is exactly them, verbatim. standoff / coverage_overlap / fov are ignored — the caller owns coverage. This is the escape hatch for coverage geometries the three parametric patterns do not capture, kept deterministic because the poses are given, not generated.
A surface ScanRegion uses the generators directly. A path region sweeps stations spaced s_u along the given path (a one-dimensional raster). A volume region is covered as a deterministic stack of surface layers at depth intervals s_v along the volume's principal axis, each layer a surface sweep — so the volume reduces to repeated surface coverage. The per-kind reduction keeps one parametric construction rather than three.