Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[Electron Kiosk Shell](electron-kiosk-shell.md#browser-local-state-breaking-on-first-electron-launch).

### Fixed
- **Doc paths named from the Python package resolve again.** The K-LD7
OPS-bin penalty warning, the cloud client and session-logger comments,
and the two-ray module docstring pointed at flat `docs/*.md` files that
moved in the docs restructure. A new test scans `src/openflight` for
`docs/…​.md` references and fails on any that do not exist.
- **`openflight-cloud` honors `--config`/`--log-dir` before the subcommand.**
The subcommand's defaults overwrote options given before it, so
`openflight-cloud --log-dir X push` scanned the default session directory.
Expand Down
2 changes: 1 addition & 1 deletion src/openflight/cloud/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
the network.

The contract lives entirely in this module; nothing here imports FlightWeb
code. See docs/openflight-cloud-uploader-spec.md.
code. See docs/reference/cloud-uploader-spec.md.
"""

import json
Expand Down
2 changes: 1 addition & 1 deletion src/openflight/kld7/radc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1901,7 +1901,7 @@ def extract_launch_angle(
"[RADC] OPS-bin penalty: %d/%d frames (%.0f%%) > %d "
"bins from expected bin %d (peak bins: %s, weight "
"/%.1f). High rate suggests a radar mounting or "
"clutter issue — see docs/kld7-troubleshooting.md.",
"clutter issue — see docs/legacy/troubleshooting.md.",
penalty_count,
len(clean_bins),
pct,
Expand Down
18 changes: 9 additions & 9 deletions src/openflight/kld7/two_ray.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""Two-ray multipath demodulation estimator for vertical launch angle.

Live port of the validated offline pipeline
(scripts/analysis/kld7_subframe_stft.py; findings in
docs/kld7-subframe-stft-findings.md). Each ~28.6 ms RADC frame is split
into overlapping sub-frame windows; the per-sub-frame Rx2/Rx1 phasor
ratios are fit to a two-ray (ball + floor image) interference model,
recovering the ball's true elevation through ground multipath instead of
averaging across it. Impact time is anchored by the multipath-immune F1B
range progression (range = tee distance at impact), so the estimator is
robust to host/OPS clock offsets.
Live port of the validated offline sub-frame STFT pipeline (the two-ray
model is explained in docs/legacy/launch-angle-explained.md, section 4).
Each ~28.6 ms RADC frame is split into overlapping sub-frame windows;
the per-sub-frame Rx2/Rx1 phasor ratios are fit to a two-ray (ball +
floor image) interference model, recovering the ball's true elevation
through ground multipath instead of averaging across it. Impact time is
anchored by the multipath-immune F1B range progression (range = tee
distance at impact), so the estimator is robust to host/OPS clock
offsets.

Validated offline: 2.64 deg MAE pooled PW-4i vs TrackMan (2026-06-08
sessions, angle offset 3.5), 3.16 deg blind on a drift-era holdout.
Expand Down
2 changes: 1 addition & 1 deletion src/openflight/session_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SessionMetadata:
# Globally unique session identity for cloud sync dedupe. The
# timestamp-based session_id stays for filenames and display; this
# UUID travels inside the data so renamed/copied session files keep
# their identity (see docs/cloud-sync-design.md).
# their identity (see docs/reference/cloud-uploader-spec.md).
session_uuid: str = ""
format_version: int = SESSION_FORMAT_VERSION
app_version: str = ""
Expand Down
40 changes: 40 additions & 0 deletions tests/test_doc_references.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Doc paths mentioned from the Python package must exist.

Log messages, docstrings, and comments under ``src/openflight`` point users
at ``docs/...md`` pages. The docs restructure moved those pages into
sectioned directories and several pointers were left naming files that no
longer exist (see the kld7 OPS-bin penalty warning, which sent users to a
404 for months). This test fails on any such reference so a future docs
move cannot silently strand them again.
"""

import re
from pathlib import Path

import pytest

REPO_ROOT = Path(__file__).resolve().parent.parent
PACKAGE_ROOT = REPO_ROOT / "src" / "openflight"
DOC_REF = re.compile(r"docs/[A-Za-z0-9_./-]+\.md")


def _doc_references() -> list[tuple[str, str]]:
found: list[tuple[str, str]] = []
for path in sorted(PACKAGE_ROOT.rglob("*.py")):
text = path.read_text(encoding="utf-8")
for match in sorted(set(DOC_REF.findall(text))):
found.append((str(path.relative_to(REPO_ROOT)), match))
return found


_REFERENCES = _doc_references()


def test_package_mentions_at_least_one_doc():
"""Guard against the scan silently matching nothing."""
assert _REFERENCES, "expected src/openflight to reference docs/*.md somewhere"


@pytest.mark.parametrize(("source", "doc"), _REFERENCES, ids=[f"{s}:{d}" for s, d in _REFERENCES])
def test_referenced_doc_exists(source, doc):
assert (REPO_ROOT / doc).is_file(), f"{source} points at {doc}, which does not exist"
Loading