i_corrector.hpp¶
ICorrector — the WRITE seam: one source of ABSOLUTE position fixes (V5 GPS, AprilTag PnP, LIDAR scan-match).
This header declares 2 types (10 members).
Extracted from include/shulib/localization/i_corrector.hpp — this page is that header's documentation, reformatted, so it cannot disagree with the code. Prose about how to think about the API lives in the user guide; worked recipes live in the cookbook; this page is the complete, mechanical list of what exists.
Contents¶
class ICorrector~ICorrectorICorrectorICorrector (overload 2)ICorrector (overload 3)operator=operator= (overload 2)proposenameclass NullCorrectorproposename
class ICorrector¶
One source of ABSOLUTE field-pose fixes — V5 GPS, AprilTag PnP, LIDAR scan-match. PULL, not push: the Localizer calls propose() once per tick with its odom-predicted pose, and nothing here ever writes into the estimator. An implementation owns ALL of its own mess — HAL access, frame/lever-arm/PnP reduction, latency, staleness, gating — so the Localizer stays geometry-free and the trust math stays in one place. Pure with respect to its injected HAL handle, which is what makes a corrector host-testable against a fake.
class, declared at include/shulib/localization/i_corrector.hpp:25.
ICorrector::~ICorrector¶
Polymorphic-base boilerplate: the destructor is virtual so a concrete corrector held as ICorrector&/ICorrector* destroys correctly, and DECLARING it is what suppresses the implicit copy/move, which are re-defaulted below. The base carries no state of its own. Ownership stays with the CALLER either way: the Localizer takes a NON-OWNING span<ICorrector* const> (at most kMaxCorrectors, each checked non-null at construction), so every corrector must outlive the Localizer it was handed to.
function, declared at include/shulib/localization/i_corrector.hpp:33.
ICorrector::ICorrector¶
Covered by the comment on ~ICorrector — one comment documents this run of special members.
function, declared at include/shulib/localization/i_corrector.hpp:34.
ICorrector::ICorrector (overload 2)¶
Covered by the comment on ~ICorrector — one comment documents this run of special members.
function, declared at include/shulib/localization/i_corrector.hpp:35.
ICorrector::ICorrector (overload 3)¶
Covered by the comment on ~ICorrector — one comment documents this run of special members.
function, declared at include/shulib/localization/i_corrector.hpp:36.
ICorrector::operator=¶
Covered by the comment on ~ICorrector — one comment documents this run of special members.
function, declared at include/shulib/localization/i_corrector.hpp:37.
ICorrector::operator= (overload 2)¶
Covered by the comment on ~ICorrector — one comment documents this run of special members.
function, declared at include/shulib/localization/i_corrector.hpp:38.
ICorrector::propose¶
Propose an absolute fix given the odom-predicted pose this tick. MUST be non-throwing and MUST return {valid=false} when it has no usable fix (off-strip GPS, no tag) — never a zero-confidence pull. dt is the tick duration (seconds).
function, declared at include/shulib/localization/i_corrector.hpp:43.
ICorrector::name¶
Stable id for telemetry / per-source dead-reckon accounting.
function, declared at include/shulib/localization/i_corrector.hpp:47.
class NullCorrector¶
The M2 placeholder: a registered source that never has a fix. Lets the fusion pipeline run and be tested end-to-end (it just always dead-reckons) before any real corrector exists, and keeps the seam visibly wired for telemetry. M3 replaces it with GpsCorrector/AprilTagCorrector.
class, declared at include/shulib/localization/i_corrector.hpp:53.
NullCorrector::propose¶
[[nodiscard]] CorrectionProposal propose(const math::Pose2d& /*predicted*/, units::Time /*dt*/) override
Always declines — a default-constructed proposal, so valid == false and selfAudit.reason == None. Both arguments are ignored, and the estimator dead-reckons this tick exactly as it would with no corrector registered at all.
function, declared at include/shulib/localization/i_corrector.hpp:58.
NullCorrector::name¶
"null". Because this corrector never proposes and never self-audits, the Localizer never reads it — the id exists so the seam is visibly wired, not to label a record.
function, declared at include/shulib/localization/i_corrector.hpp:64.
Design commentary, from the header¶
The header opens with the reasoning behind these shapes. It is reproduced here in full because a reference that only lists signatures teaches nobody why.
The header’s own reasoning — 10 lines
ICorrector — the WRITE seam: one source of ABSOLUTE position fixes (V5 GPS, AprilTag PnP, LIDAR
scan-match) (master plan §6/§8). It is PULL, not push: the Localizer calls propose() each tick
with the odom-PREDICTED pose and the tick dt, and the corrector returns a CorrectionProposal
(or {valid=false}). The corrector owns ALL of its mess — HAL access, frame/lever-arm/PnP
reduction, latency, staleness, gating — so the Localizer stays geometry-free and the trust math
stays in one place. Pure w.r.t. its injected HAL handle; host-testable with a fake.
At M2 the registered list is empty or holds only NullCorrector (below); GpsCorrector /
AprilTagCorrector are concrete at M3 behind THIS exact signature, with no caller change.
Last updated 2026-08-15 — published from the main release branch, commit fa545ff. This site tracks releases, so between them it can lag the repository — that lag is deliberate, and it is what keeps the development log off the public site. For the current state of the code, see the repository.