Layered Escort Architecture

CellularSheaves.ControlSheaves.Layered.LayeredEscortProblemMethod
LayeredEscortProblem(spec, bindings, target_trajectories; dt=0.05, steps=200, target_velocities=nothing, target_accelerations=nothing, initial_positions=nothing)

High-level constructor that automatically builds F, f, PfF, and structured fiber bases from spec.

bindings is a NestedSystems.SystemBinding resolved against spec (see NestedSystems.resolve_dynamics(::LayeredEscortSpec, ::SystemBinding)) — a single root-level SystemBinding(dynamics=dyn) binds every agent to the same model, matching the old HomogeneousDynamics(dyn) behaviour exactly.

Each agent's initial position resolves in three tiers, most specific first:

  1. AgentBinding.initial_position from bindings (a per-agent override)
  2. initial_positions[i] (this constructor's own field, if supplied)
  3. the "airstrip" default (NestedSystems._default_initial_position) — agents lined up along the first position coordinate with fixed spacing, at a common hover altitude, deliberately distinct from the target formation so the control law's convergence into formation is visible in the simulation rather than starting there already.

Existing callers that pass initial_positions and no per-agent bindings see unchanged behaviour: resolve_dynamics only fills in a position when bindings supplies one, so tier 2 governs whenever tier 1 is absent.

source
CellularSheaves.ControlSheaves.Layered.LayeredEscortSpecType
LayeredEscortSpec(rings::Vector{RingSpec}, supports::Vector{SupportSpec}; D::Int=4, affine::Bool=true)

Full multi-team topology specification for arbitrary escort rings and support edge pools.

D is the stalk dimension (default 4). When affine=true (default), stalks carry D-1 homogeneous-affine translation coordinates plus one homogeneous row (e.g. D=4 for SE(3) 3D translation, D=3 for planar 2D translation). When affine=false, stalks are D plain Euclidean coordinates with no translation offsets representable (ring/support radii must be 0).

source
CellularSheaves.ControlSheaves.Layered.RingSpecType
RingSpec(target_id::Int, n_agents::Int, radius::Float64; observers::Vector{Int}=[1])

Specification for an escort ring around a target vertex. observers names which ring agents (by local index 1:n_agents) are directly pinned to the target; any subset of ring agents may observe the target, defaulting to just the first agent.

source
CellularSheaves.ControlSheaves.Layered.SupportSpecType
SupportSpec(src_ring::Int, tgt_ring::Int, n_agents::Int; src_observers::Vector{Int}=[1], tgt_observers::Vector{Int}=[1])

Specification for a support pool of agents bridging Escort Ring src_ring and Escort Ring tgt_ring. src_observers/tgt_observers name which support-pool agents (by local index 1:n_agents) are directly pinned to the src_ring/tgt_ring target respectively. Defaults to the first agent in the pool observing both targets.

source
CellularSheaves.ControlSheaves.Layered._flat_childrenMethod
_flat_children(spec::LayeredEscortSpec) -> Vector{Tuple{Symbol,UnitRange{Int},Int}}

Every ring and support pod of spec, named :ring1, :ring2, … / :support1, :support2, … matching the ordering of spec.rings / spec.supports, together with its global agent-index range and its own agent count. Order matches spec.ring_node_ranges followed by spec.support_node_ranges — the same order run_layered_escort_simulation iterates.

source
CellularSheaves.ControlSheaves.Layered._resolve_flat_bindingsMethod
_resolve_flat_bindings(spec, ctx) -> Vector{Tuple{Symbol,Int,Int,AgentBinding}}

Walk spec's implicit depth-1 tree folding ctx's cascade, exactly like resolve_dynamics(::LayeredEscortSpec, ::SystemBinding), but stop before applying any initial-position default — callers get the raw folded AgentBinding (dynamics guaranteed non-nothing, K_lqr still possibly nothing, initial_position still possibly nothing) together with (child_name, local_idx, global_idx).

This is the shared core both resolve_dynamics (which defaults straight to the airstrip position) and LayeredEscortProblem's three-tier fallback (which checks initial_positions before the airstrip) build on, so the precedence for dynamics/K_lqr cannot drift between the two call sites.

source
CellularSheaves.ControlSheaves.NestedSystems.resolve_dynamicsMethod
resolve_dynamics(spec::LayeredEscortSpec, ctx::SystemBinding) -> Vector{ResolvedAgent}

Resolve dynamics bindings for a flat layered escort specification, treating it as a depth-1 tree: each escort ring and each support pod is a child of a single implicit root.

Children are addressed by the conventional names :ring1, :ring2, … and :support1, :support2, …, matching the ordering of spec.rings and spec.supports. Per-agent overrides use the agent's local index within its ring or pod, consistent with RingSpec.observers.

Agents come back in global agent-index order, matching spec.ring_node_ranges followed by spec.support_node_ranges — the same ordering run_layered_escort_simulation iterates. Precedence and field independence are identical to the tree-shaped NestedSystems.resolve_dynamics(::NestedSystemSpec, ::SystemBinding): this reuses that same _fold/_fold_system cascade rather than re-deriving the precedence rule.

source