精简仓库结构并增强任务链路:归档双目可选后端、新增LOS判据与自定义返航

归档 legacy/:stereo_yolo/stereo_ranger/target_tracker 三包 + 175 条测试 + demo/配置/权重/三份规格;运行链路不再依赖,默认 pytest 446 条,归档测试按需运行。

目标有效性第二判据改为 LOS 运动学一致性(pod_bridge/los_consistency.py),删除 require_vision;pod_locked() 叠加该判据,状态机随之后退重搜。

自定义返航(task_runner/return_home.py):保持转场高度回起飞点 → 恢复初始航向 → 垂直降落,不再爬 RTL_RETURN_ALT;未起飞/无起飞点/超时/异常仍退回 PX4 原生 RTL。

任务链安全兜底:主循环异常→紧急返航、stop 幂等、landing_stop 保留遥测、in_air 流复用+超时、解锁/起飞与吊舱识别仅执行一次、rtl_timeout 上限。

入口共享件拆到 utils/sitl_support.py;pod_sitl_test.py→l1_sitl_test.py;删除旧架构 test.py;相机脚本移入 tools/。

新增 .gitignore 并剔除历史误跟踪的 59 个 .pyc;requirements 按实际依赖重写;文档全面对齐,新增 legacy/README.md 与 tools/README.md。
This commit is contained in:
keita
2026-10-21 14:48:41 +08:00
parent 53fdd3b13f
commit df91b1110e
159 changed files with 6121 additions and 1617 deletions
+82 -1
View File
@@ -1,7 +1,7 @@
"""log_test.py —— 任务日志模块单元测试。
覆盖:open 建目录/写表头、事件 JSONL、遥测 CSV、telemetry_every_n 节流、
disabled 时零副作用、close 收尾。
disabled 时零副作用、close 收尾、简洁任务简报(task_brief.log)。
"""
import csv
@@ -121,3 +121,84 @@ def test_append_keeps_existing_rows(tmp_path):
assert len(rows) == 2
assert rows[0]["state"] == "wait"
assert rows[1]["state"] == "goto"
# --- 简洁任务简报(task_brief.log)-------------------------------------------
def test_brief_log_lines_and_summary(tmp_path):
logger = TaskLogger(_cfg(tmp_path))
logger.open()
logger.log_event(1000, "state", from_state="wait", to_state="wait",
reason="任务启动")
logger.log_event(2000, "state", from_state="wait", to_state="arm_takeoff",
reason="收到地面坐标")
logger.log_event(3000, "command", name="rtl")
logger.log_event(4000, "fc_status", severity="WARNING", text="Low battery\t")
logger.log_event(5000, "takeoff", altitude_m=5.0)
logger.log_event(6000, "rtl")
logger.log_telemetry(1000, TelemetryRecord(
state="wait", relative_altitude_m=0.0, distance_to_target_m=33.5))
logger.log_telemetry(1100, TelemetryRecord(
state="arm_takeoff", relative_altitude_m=5.2, distance_to_target_m=20.0))
logger.log_telemetry(1200, TelemetryRecord(
state="arm_takeoff", relative_altitude_m=5.0,
distance_to_target_m=float("inf")))
logger.close()
text = (tmp_path / "task_brief.log").read_text(encoding="utf-8")
assert "任务开始" in text
assert "[00:00.0] 任务启动(当前: 待命)" in text
assert "[00:01.0] 阶段: 待命 → 起飞(收到地面坐标)" in text
assert "[00:02.0] 地面站命令: rtl" in text
assert "[00:03.0] 飞控 WARNING: Low battery" in text # 尾随 tab 已 strip
assert "[00:04.0] 起飞至 5.0 m" in text
assert "[00:05.0] 开始返航" in text
assert "本次运行汇总" in text
assert "时长 0.2s" in text # 最后一行遥测的 t_s
assert "最高 5.2m" in text
assert "最近距目标 20.0m" in text # inf 不计入
assert "事件 6 条" in text
assert "状态链 待命→起飞" in text
def test_brief_required_no_file_when_disabled_or_closed(tmp_path):
logger = TaskLogger(_cfg(tmp_path, enabled=False))
logger.open()
logger.log_event(1000, "rtl")
logger.close()
assert not (tmp_path / "task_brief.log").exists()
# --- 遥测落盘节流(2026-10-15:主循环 20Hz 不得每行同步 flush)----------------
def test_telemetry_buffered_until_flush_interval(tmp_path):
"""telemetry_flush_ms 内只写不 flush;close 兜底落盘,一行不丢。"""
logger = TaskLogger(_cfg(tmp_path, telemetry_flush_ms=1000))
logger.open()
rec = TelemetryRecord(state="track")
logger.log_telemetry(1000, rec) # 首行:落盘一次并打戳
for i in range(1, 19): # 其后 19 行都在 1s 内 → 不再 flush
logger.log_telemetry(1000 + i * 50, rec)
logger.close()
with open(tmp_path / "task_telemetry.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
assert len(rows) == 19
def test_telemetry_flush_zero_flushes_every_row(tmp_path):
"""telemetry_flush_ms=0 保留旧的「每行立即 flush」行为(兼容/调试)。"""
logger = TaskLogger(_cfg(tmp_path, telemetry_flush_ms=0))
logger.open()
logger.log_telemetry(1000, TelemetryRecord(state="goto"))
assert logger._last_tel_flush_ms == 1000
logger.close()
def test_events_still_flushed_immediately(tmp_path):
"""事件(阶段切换)仍即时落盘:地面站页面实时性不受遥测节流影响。"""
logger = TaskLogger(_cfg(tmp_path, telemetry_flush_ms=10_000))
logger.open()
logger.log_event(1000, "state", from_state="goto", to_state="search")
with open(tmp_path / "task_events.jsonl", encoding="utf-8") as f:
lines = [json.loads(x) for x in f if x.strip()]
assert len(lines) == 1
logger.close()