mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 13:01:14 +00:00
[AZ-619] Phase A: build_pre_constructed seeds c13_fdr + clock
Adds airborne_bootstrap.build_pre_constructed(config) returning a dict with the two foundational keys: a per-binary shared FdrClient under "c13_fdr" (via make_fdr_client with the new AIRBORNE_MAIN_PRODUCER_ID constant) and a fresh WallClock under "clock". Phases B..F (AZ-620..AZ-624) extend this function additively without breaking the AZ-619 contract. The c13_fdr instance is identity-stable across calls (per the make_fdr_client per-producer cache) so callers can call build_pre_constructed twice and get the same FdrClient back - AC-619.2. Replay-mode override is unchanged: compose_root merges replay_components over pre_constructed so the WallClock here is replaced by TlogDerivedClock in replay binaries (existing contract documented in compose_root's docstring). Tests: 5 new unit tests under tests/unit/runtime_root/ test_az619_pre_constructed_phase_a.py, all passing. AZ-591 not regressed (12/12 in the combined run). Spec moved to _docs/02_tasks/done/. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -51,8 +51,10 @@ from __future__ import annotations
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import Mapping
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, Final
|
||||
|
||||
from gps_denied_onboard.clock.wall_clock import WallClock
|
||||
from gps_denied_onboard.fdr_client.client import make_fdr_client
|
||||
from gps_denied_onboard.runtime_root import register_strategy
|
||||
from gps_denied_onboard.runtime_root.matcher_factory import build_matcher_strategy
|
||||
from gps_denied_onboard.runtime_root.pose_factory import build_pose_estimator
|
||||
@@ -66,12 +68,27 @@ if TYPE_CHECKING:
|
||||
from gps_denied_onboard.config import Config
|
||||
|
||||
__all__ = [
|
||||
"AIRBORNE_MAIN_PRODUCER_ID",
|
||||
"AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS",
|
||||
"AirborneBootstrapError",
|
||||
"build_pre_constructed",
|
||||
"register_airborne_strategies",
|
||||
]
|
||||
|
||||
|
||||
AIRBORNE_MAIN_PRODUCER_ID: Final[str] = "airborne_main"
|
||||
"""Producer ID for the per-binary shared FdrClient placed under
|
||||
``pre_constructed['c13_fdr']``.
|
||||
|
||||
Per-component callers can still obtain their own FdrClient via
|
||||
``make_fdr_client(<their_slug>, config)`` — the cache in
|
||||
:mod:`gps_denied_onboard.fdr_client.client` ensures one instance per
|
||||
``producer_id``. The ``"airborne_main"`` instance is the one passed via
|
||||
``pre_constructed`` for the wrappers that accept ``fdr_client=`` as a
|
||||
kwarg.
|
||||
"""
|
||||
|
||||
|
||||
_LOG = logging.getLogger("gps_denied_onboard.runtime_root.airborne_bootstrap")
|
||||
|
||||
|
||||
@@ -365,6 +382,30 @@ _AIRBORNE_REGISTRATIONS: tuple[
|
||||
)
|
||||
|
||||
|
||||
def build_pre_constructed(config: "Config") -> dict[str, Any]:
|
||||
"""Build the airborne ``pre_constructed`` dict for :func:`compose_root`.
|
||||
|
||||
AZ-619 (Phase A) lands the foundational keys ``c13_fdr`` and ``clock``.
|
||||
Phases B..F (AZ-620..AZ-624) extend this function to populate the
|
||||
remaining 10 keys in :data:`AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS`.
|
||||
|
||||
Returns a fresh dict on each call. The ``c13_fdr`` instance is cached
|
||||
inside :func:`make_fdr_client` (per-producer cache) so two calls within
|
||||
the same process return dicts where ``pre_constructed['c13_fdr']`` is
|
||||
the SAME object — AC-619.2. ``clock`` is a fresh :class:`WallClock`
|
||||
each call (stateless; the cache would be a no-op).
|
||||
|
||||
Replay-mode override: :func:`compose_root` merges ``replay_components``
|
||||
over ``pre_constructed`` so the :class:`WallClock` here is replaced by
|
||||
the replay branch's :class:`TlogDerivedClock`. That's intentional and
|
||||
matches the contract in :func:`compose_root`'s docstring.
|
||||
"""
|
||||
return {
|
||||
"c13_fdr": make_fdr_client(AIRBORNE_MAIN_PRODUCER_ID, config),
|
||||
"clock": WallClock(),
|
||||
}
|
||||
|
||||
|
||||
def register_airborne_strategies() -> None:
|
||||
"""Register every airborne (component, strategy) pair into ``_STRATEGY_REGISTRY``.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user