11 Commits
Author SHA1 Message Date
Horldsence 27f4d6e0d8 123 2026-09-13 08:52:23 +08:00
Horldsence dec57e3e29 123 2026-09-13 08:52:21 +08:00
Horldsence 71688b2ab2 082928 2026-09-13 08:29:30 +08:00
sloray f71d7d9288 Merge branch 'q3-bayes-no-ml' of git.simba-robotics.com:HelixCopex/mcm-26-b into q3-bayes-no-ml 2026-09-12 17:21:45 +08:00
sloray 102ca032fb 1 2026-09-12 17:21:41 +08:00
Horldsence a1500d25c1 q3 q4 baseline 2026-09-12 17:01:49 +08:00
Horldsence 892451dca9 baseline 2026-09-12 16:58:25 +08:00
sloray 1fa2264a17 Merge branch 'q3-bayes-no-ml' of git.simba-robotics.com:HelixCopex/mcm-26-b into q3-bayes-no-ml 2026-09-12 15:27:13 +08:00
sloray c2d1230562 1 2026-09-12 15:25:16 +08:00
Horldsence 45e48d4c91 yes fuking shit 2026-09-12 14:48:43 +08:00
Horldsence 61fd22598a revert: 移除全部机器学习代码,回退到无 ML 版本
删除 RL/HRL/训练前端及其文档、脚本、测试与依赖:
- src/mcm26b/{rl,hrl,training_ui}/、planner/{rl,hrl}_loop.py、process_control.py
- project/(PPO 策略、训练、环境、评估)
- scripts/{train_rl,train_hrl_*,benchmark_rl,benchmark_hrl,pretrain_*_expert 等}
- tests/{test_rl*,test_hrl*,test_training_ui*}、tests/js/training_ui_harness.cjs
- docs/{algo-rl,hrl-*,training-ui*} 与相关计划条目、论文 PDF 回退

CLI 恢复为 grid/seven/bayes + directional,移除 --strategy rl|hrl、
--q4-strategy、--rl-model、--hrl-* 等参数;pyproject 删除 rl 依赖组与
PyTorch CUDA index,uv.lock 同步重生成。

保留此后的非 ML 改动(referee 回放、Q1/Q3 脚本、代码清理等)。
验证:pytest 232 passed;Q3/Q4 --self-test 全清通过。
2026-09-12 08:47:51 +08:00
210 changed files with 46860 additions and 13916 deletions
Vendored
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -1,87 +0,0 @@
# 分层强化学习(HRL)实施计划 — 2026 高教社杯 B 题第三、四问
## 0. 现状与复用决策
仓库已有生产级基建,**全部复用、不重写**:
| 现有组件 | 位置 | 用途 |
|---|---|---|
| `SimulatorClient`(HTTP+JSON、幂等重试、截止时钟、JSONL 日志) | `src/mcm26b/protocol/` | 模拟器对接(prompt 第 1 步已完成) |
| 本地评测机(内存回环,一局秒级) | `referee/` + `harness.LocalSimTransport` | 本地简化环境内核 |
| 网格幸存集滤波(真源保留定理已证明) | `src/mcm26b/particles.py` | 每频道信念后验 |
| 凸候选集 + 五状态机 | `src/mcm26b/belief/` | 频道状态观测 |
| 信息增益选点、TSP 2-opt、六边形覆盖、清除证书、后备清除 | `src/mcm26b/planner/` | 候选生成器 + 证书审批兜底 + 启发式基线 |
| 单步 MaskablePPO 全套(特征/掩码/BC/训练/审计) | `src/mcm26b/rl/` + `scripts/` | 代码模式模板 + 端到端对照基线 |
**改进方向**(来自 v2 审计文档已知局限):单步 RL 只做选点、学不到全场调度;Q4 后备清除偏多、尾部退化(13778s→11797s,距 4000s 目标远)。HRL 高层正是补**跨频道全场调度**决策。
**已确认的三个决策**:① 代码集成到 `src/mcm26b/hrl/`(README 给出与 prompt 目录树的映射表);② 低层为字面 8 方向 PPO + 直线控制器对照(诚实预期:部署时只提交终点,低层对虚拟时间增益≈0,价值在架构完整性与消融验证);③ 本次跑通全流程 + 短程训练(1–2h),完整课程训练交付脚本由用户自行启动。
## 1. 新建文件
```
src/mcm26b/hrl/
├── __init__.py
├── constants.py # HRL 接口常量:N_CANDIDATES=96、观测维度,feature_version=3
├── candidates.py # 高层候选生成:待清除源/信息增益探索点/覆盖验证点/Q4 扇区探测点 + 动作掩码
├── features.py # 高层观测(20 频道×14 统计 + 全局标量 + 96×6 候选特征 ≈864 维)、低层观测
├── policy.py # HighLevelPolicy/LowLevelPolicy 加载器(沿用 PointSelectionPolicy 元数据校验模式)
├── low_level_env.py # 低层训练环境:随机起点→子目标,Discrete(8),逐步计费,奖励=−Δd−转向+到达
├── hierarchical_env.py # 高层整场环境:10–16 源,动作=子目标槽位,内嵌低层执行器,域随机化+课程参数
└── executor.py # 子目标执行器:低层 PPO 步进(本地计费)或直线控制器(可切换),终点提交模拟器
scripts/
├── train_hrl_low.py # 低层:BC 克隆直线控制器热启动 → MaskablePPO 微调;直线对照评估
├── train_hrl_high.py # 高层:4 阶段课程(--stage --resume --timesteps),SubprocVecEnv 并行
├── pretrain_hrl_expert.py # 可选:从 BayesLoop 调度器克隆 (obs, 子目标) 对热启动高层
├── tune_hrl.py # Optuna TPE(prompt §10 搜索空间,预算 15–20 trials,初值复用 bayes 已调参数)
├── benchmark_hrl.py # 配对消融:HRL vs bayes/directional/单步 PPO,dev(700-702)/val(91000-91005)/stress 固定场景
└── ablate_hrl.py # 四项消融:无信息增益奖励/无动作掩码/无课程/无粒子滤波
src/mcm26b/planner/hrl_loop.py # HRLLoop 运行时闭环(Q3/Q4),保留证书审批与异常留痕
src/mcm26b/cli.py # 新增 --strategy hrl / --q4-strategy hrl / --hrl-model
tests/test_hrl.py # 特征布局、掩码、环境形状、奖励恒等式、训练-部署观测一致性
docs/hrl.md # 设计文档 + prompt 目录树映射表
docs/paper/ 增补 # 算法流程图、伪代码、超参表、训练曲线
```
## 2. 核心设计
**高层动作空间** Discrete(96) + 掩码:槽位按固定顺序填充(已定位待清除源 ≤16 → PF 驱动探索点 → 覆盖网格未验证点 → Q4 扇区探测点),空槽/已清除频道/接收盘外候选掩码 −∞。
**高层观测**(≈864 维,参照 v2 的 401 维布局模式):20 频道 × 14 特征(六状态 one-hot、MEC μx/μy、σx/σy/ρ、log 幸存格数、期望信息增益、距离、频道号)+ 全局 8 维(位置、时间比例、已清除数、最近检测结果编码/示向度/距离)+ 96×6 候选特征。
**step 语义**:高层选子目标 → executor 步进(低层 8 方向,每步 ≤100m,本地按 Δd/5 计费;部署时仅终点调模拟器)→ 按子目标类型执行 /measure 或 /clear → belief+PF 更新 → 奖励。
**奖励**:`r = −Δ虚拟耗时/100 + 100·清除 + 5·新检测 + w_info·ΔH − 冗余惩罚`,主口径与目标函数(虚拟时间)一致;w_info 可消融。
**课程 4 阶段**(prompt §7.1):1 源/5 频道/无噪 → 3 源/10 频道/±0.5° → 8 源/16 频道/±1° → 10–16 源/20 频道/±1°;每阶段迁移上阶段权重,Q4 从 Q3 权重微调(定向比例递增),域随机化贯穿(源位置/频道/r_eff/朝向/噪声种子)。
**运行时闭环 HRLLoop**:初始覆盖相位(快速发现信号)→ 主循环高层决策(证书达标自动 /clear,与 BayesLoop 同语义)→ 全清即 /exit。不触碰候选集更新与清除判定的守恒性(真源保留定理依赖),异常留痕兜底保留。
## 3. 实施顺序(对应 prompt §12)
1. `constants.py` + `candidates.py` + `features.py`(候选/掩码/观测)+ 单元测试
2. `low_level_env.py` + `train_hrl_low.py`:低层短程训练,验证收敛到近直线(报告与直线最优的差距)
3. `hierarchical_env.py` + `executor.py` + `hierarchical_env` 单元测试(奖励恒等式:回合回报 = f(虚拟时间、清除数))
4. `train_hrl_high.py` + 课程 + 域随机化 + SubprocVecEnv;`pretrain_hrl_expert.py` BC 热启动
5. 短程课程训练(每阶段 2–5 万步,总计 1–2h),产出训练曲线
6. `hrl_loop.py` + CLI 接入,`--local-judge` 本地演练验证全清正确性
7. `benchmark_hrl.py` 配对对比(沿用 benchmark_rl.py 的 all_valid 有效口径)+ `ablate_hrl.py` 四项消融
8. `tune_hrl.py` 受限 Optuna;产出最佳超参表
9. 本地 referee 演练 ×3/题,表 1 格式结果(案例编码/清除数/平均定位清除时间/程序运行时间),日志 JSONL 原样归档 `output/hrl/`
10. `docs/hrl.md`、README 更新、论文素材(流程图/伪代码/超参表/对比分析,含"为什么分层 PPO、为什么非端到端、为什么非多智能体"论证)
## 4. 验收标准
- 全部 pytest 通过(现有 243 项 + 新增 HRL 测试)
- `benchmark_hrl.py` 输出 all_valid=true(真值全清、缺席无误判、零异常、正常 exit、计时复算一致)
- 短程训练下 Q4 HRL 相对 directional 有可测改进方向(对标单步 RL 的 −14.38%);Q3 如实报告与 bayes 的差距(v2 审计口径:Q3 RL 无稳定增益)
- 所有实验固定种子、命令可复现;消融表含均值±方差(≥5 种子)
- 完整训练只需用户执行 `scripts/train_hrl_high.py --full` 级别的命令
## 5. 风险与对策
- **高层整场回合过长(100–200 决策步)不收敛** → γ=1 + 密集 Δcost 奖励 + BC 从 bayes 调度器热启动
- **低层增益≈0** → 如实消融报告(直线对照差异≈0),论文定位为架构必要性验证而非性能来源
- **Q3 可能无增益** → 与 v2 口径一致如实报告,主打 Q4 调度收益;两种策略可共存(HRL 不改默认策略,仅在胜出后由用户决定切换默认)
+40 -29
View File
@@ -3,14 +3,23 @@
统一框架:有界误差几何定位、主动选点、带覆盖证明的搜索、按真实动作耗时调度。
分析依据 `issue/B题.pdf`、附件1《模拟器使用说明》、附件2《通信接口说明及编程指南》。
**文档总入口:[docs/README.md](docs/README.md)**(分类索引、阅读顺序与口径登记)。
- [总体思路与流程图(四问主线、端到端流程图、执行时间速查)](docs/总体思路与流程图.md)
- [执行时间与执行步骤(计时模型、状态机、附件示例推演、实测分解)](docs/执行时间与执行步骤.md)
- [几何计算示意图册(逐图说明:角域交会、覆盖、最小命中集)](docs/几何计算示意图册.md)
- [论文插图清单与复现方式](docs/figures/README.md)(`uv run python scripts/make_figures.py`)
- [四问建模分析与 P0–P7 实施计划](docs/B题建模分析与实施计划.md)
- [协议规则表、字段表与状态机(P0 交付)](docs/协议规则表与状态机.md)
- [问题一完整解答](docs/问题一解答.md)
- [问题三搜索与总耗时改进方案(含七点覆盖证明和自建消融)](docs/algo-3.md)
- [问题3/4 强化学习选点(PPO + CUDA)](docs/algo-rl.md)
- [强化学习审核、修复与独立验证(2026-09-11)](docs/强化学习适用性审核与改进-20260911.md)
- [HRL 优化方案与 Sol 执行指南(含当前缺口、命令和验收门槛)](docs/hrl-sol-execution.md)
- [HRL P0+P1 执行报告(本轮实际命令、smoke 与多轮本地测试)](docs/hrl-p1-execution-report.md)
- [问题一算法说明(当前实现口径)](docs/algo-1.md)
- [问题二算法说明(保证接收的第二点选择)](docs/algo-2.md)
- [问题三算法说明(七点覆盖证明、贝叶斯闭环与滚动调度)](docs/algo-3.md)
- [问题四算法说明(定向覆盖最小命中集、联合信念与后备清除)](docs/algo-4.md)
- [第三、四问系统性架构优化与运行提速方案(运行历史复核、最小命中集、联合信念)](docs/第三四问架构优化与运行提速方案.md)
- [第三、四问图论与动态规划优化方案(定点实测、路由 gap、定向定位 DP、证书硬化)](docs/第三四问图论与动态规划优化方案.md)
- [1-4 问最优与基线实现对比框架](project/README.md)(`uv run python -m project.run`,结果在 `project/results/`)
- [最优与基线实现对比(论文口径说明)](docs/最优与基线实现对比.md)
- [论文](docs/paper/main.tex)
## 项目结构
@@ -25,13 +34,16 @@ src/mcm26b/
├── belief/ # P3 逐频道候选集合 K_c:保守外包多边形 + 半平面裁剪(已完工)
├── coverage/ # P4 49点覆盖账本(网格生成 + 逐频道记录)
├── planner/ # P3 保证接收盘选点器 / P4 全向闭环 / P5 混合源定向闭环(已完工)
│ # P6b RL 接入:planner/rl_loop.py(PPO 选点,惰性加载 torch)
├── rl/ # P6b 强化学习扩展:训练环境、观测/候选特征、PPO 模型加载(可选依赖)
├── routing.py # 图论/DP 工具箱:Held-Karp 精确开放路径、2-opt/Or-opt、MST 下界、路由度量
├── evaluation/ # 日志复算与统计(已完工)
└── harness/ # 测试侧适配:评测机<->Transport 内存回环、故障注入、回放、场景
tests/ # pytest(含解耦守卫:运行时零导入 referee + 规则表不漂移)
project/ # 1-4 问"最优实现 / 基线实现"对比框架:逐问 optimal+baseline
# +独立参考,冻结基准集配对出数;见 project/README.md
scripts/ # 采集、基准、可视化与校核脚本(含问题四批量仿真 benchmark_q4.py、
# RL 训练 train_rl.py 与 RL 配对消融 benchmark_rl.py)
# 运行历史计时分解 analyze_run_timing.py、第四问覆盖证书 verify_q4_cover.py、
# 论文插图 make_figures.py、日志归档 archive_replay_logs.py)
docs/figures/ # 论文插图(PNG)+ manifest.json(数据来源与 sha256)+ 图清单
output/ examples/ # 演练证据、算例与生成产物
```
@@ -71,29 +83,11 @@ Python ≥ 3.10,运行时依赖仅 `requests`;测试/自检另需 `pytest`
```bash
uv sync # 安装(可编辑挂载本包与 referee)
uv sync --group rl --group dev # 追加 RL 依赖:torch(CUDA)+stable-baselines3+gymnasium
uv run pytest # 全部测试(含 referee 90 项 + 解耦守卫)
uv run python -m referee # 起本地评测机(可选,配合 WebUI 回放)
uv run mcm26b sim-check # P0 自检:复现附件计时示例 105/111/194/199
uv run mcm26b run --robot-id 2026001 --self-test # 问题3自检:随机全向场景闭环(不连官方)
uv run mcm26b run --robot-id 2026001 --self-test --problem 4 # 问题4自检:混合定向源场景
# RL 策略(需先安装 rl 依赖组并训练模型;详见 docs/algo-rl.md):
uv run python scripts/train_rl.py --problem 3 --timesteps 120000 # PPO + CUDA 训练 Q3 选点
uv run python scripts/pretrain_rl_expert.py --problem 4 --episodes 3000 # 自建模拟器专家行为克隆
uv run python scripts/train_rl.py --problem 4 --timesteps 40000 --init output/rl/q4_ppo_bc_init.zip
uv run mcm26b run --robot-id 2026001 --self-test --strategy rl # 问题3 RL 闭环
uv run mcm26b run --robot-id 2026001 --self-test --problem 4 --q4-strategy rl # 问题4 RL 闭环
uv run python scripts/benchmark_rl.py --seeds 5 # RL vs 手写策略配对消融
uv run python scripts/verify_rl_practice.py output/rl/official-practice/q4/20260911-rl-bc-01
uv run python scripts/benchmark_hrl.py --variants hrl_heuristic,bayes,directional \
--manifest output/hrl/manifests/dev.json --output output/hrl/p1-heuristic
uv run python scripts/train_hrl_high.py --problem 3 --stage 1 --timesteps 2048 \
--envs 1 --vec-env dummy --device mps --config-profile production \
--reward-profile time --model output/hrl/p1-smoke/q3.zip --eval-episodes 2
# 训练前端(本地回环 Web UI):实时进程/进度/参数收敛曲线,详见 docs/training-ui.md
uv run python -m mcm26b.training_ui --ui-port 8036 # http://127.0.0.1:8036
uv run mcm26b run --robot-id 2026001 --self-test --strategy hrl \
--hrl-model output/hrl/p1-smoke/q3.zip --hrl-device mps
# 自检默认:源数按题面 10~16 随机;实机预算 30 分钟(--real-budget-s 可改,仅自检生效);
# 找全后持续复扫未清除频道直到限时(--config 关闭 persistent_search 可回到"找全即退")
uv run mcm26b run --robot-id <队号> --log output/run/session.jsonl # 对接模拟器正式/演练
@@ -157,9 +151,26 @@ client.exit()
| P2 几何内核(角域交、直径、MEC、证书) | ✅ 完成(迁入 `mcm26b.geometry`) |
| P3 问题二选点(K1、候选区域 Q、采样评估) | ✅ 完成(belief + 选点器,测试固化) |
| P4 问题3全向闭环(49点覆盖、定位队列、清除、停止) | ✅ 官方问题3演练单案例通过(10/10全清,[验证报告](output/q3/practice/20260911-port2026/report.md)) |
| P5 问题4定向扩展(联合约束、后备清除、预算) | ✅ 自建完成(官方演练待执行) |
| P6 加速与消融 | ✅ 七点批量(`--strategy seven`,官方演练 12/12)+ 贝叶斯闭环(`--strategy bayes` 默认,自建消融 −30.0%,[算法说明](docs/algo-3-bayes.md)) |
| P6b RL 选点 | ✅ PPO+CUDA 训练环境/闭环接入/官方+自建演练验证/专家 BC 初始化(Q3 `--strategy rl`,Q4 `--q4-strategy rl`,[算法说明](docs/algo-rl.md)) |
| P5 问题4定向扩展(联合约束、后备清除、预算) | ✅ 自建完成(官方演练待执行;[算法说明](docs/algo-4.md)) |
| P6 加速与消融 | ✅ 七点批量(`--strategy seven`,官方演练 12/12)+ 贝叶斯闭环(`--strategy bayes` 默认,自建消融 −30.0%,[算法说明](docs/algo-3.md)、[设计细节](docs/algo-3-bayes.md)) |
| P7 图论/动态规划优化(S1–S5) | ✅ 已落地([实测回填](docs/第三四问图论与动态规划优化方案.md#8-本轮实测回填2026-09-12-实施结果)):路由度量入库、覆盖证书硬化(15 m/72 缺口 566→0)、Q4 后备盲清 125.7→4.3 次/局;同时修复联合信念 `no_signal` 朝向规则反向缺陷 |
### 图论/DP 轮(2026-09-12,S1–S5)要点
- **S1 度量**:`scripts/run_suite.py` 逐局新增 `route_gap_vs_offline`、
`route_lower_bound_s`(MST 下界)、`distinct_service_points`、
`coverage_actual_visited`、`probe_no_signal_ratio`、`plan_verify_wall_s`;
图算法在 `src/mcm26b/routing.py`(Held-Karp 精确 / 2-opt / Or-opt / Prim)。
- **S2 证书**:`q4_mincover_v2`(31 点,`r_design=965 m` + 前向角裕量 5°,
15 m/72 档 325.6 万 (p,h) 缺口 0,最坏命中 990 m),取代粗采样过拟合的
`q4_mincover_v1`(25 m/48 档 125 缺口)。
- **S3 探点**:默认口径改为"可见候选里移动最省"(`probe_score_mode=nearest_visible`);
后备盲清 125.7 → 4.3 次/局,Q4 core 均值 8676 → 8602 s、最坏 10891 → 9630 s。
- **S4/S5 负面结论**:后备清除 Or-opt、Held-Karp 精确任务序、路线感知探点
在本模拟器上均为净负收益,默认关闭,代码与开关保留(见方案 §8.6)。
- **正确性修复**:`belief/joint.py` 的 `no_signal` 朝向裁剪原先规则反向且漏计格内
角裕量,会删掉真源朝向档;已修复并由 `tests/test_joint_belief.py` 的随机观测
序列保留性测试固化。
## 采集与正式测试约束
-1
View File
@@ -194,7 +194,6 @@ AI 的适合用法是把这些模块逐一变成可测试程序、生成边界
| P4 全向闭环 | 49点覆盖记录、定位队列、清除、停止、日志统计 | 10/16源、边界源和错误响应案例;官方演练全清并正常退出 | 自建闭环已完成:`planner.OmnidirectionalLoop`(10/16/0 源、近边界源、预算耗尽、故障注入测试通过);官方演练全清待团队执行 |
| P5 定向扩展 | no_signal联合约束、覆盖发现、有限清除后备与预算 | 朝外边界源不漏;真源不误删;格数与退出预算检查 | 已实现:`planner.DirectionalExtension`(49点覆盖对定向源成立、保证接收盘内 no_signal 记为观测到定向、对跖+环探梯子、`fallback_clear_cells` 有限圆盘覆盖后备清除带格数/预算双硬顶);`tests/test_loop_q4.py` 全过;官方混合源演练待执行 |
| P6 加速消融 | 共享测点、自适应覆盖、目标排序、提前清除 | 配对案例全清不退化,时间/请求数改善可复算 | 可删减;闭环基线数据已可用于消融对照 |
| P6b RL 选点 | 问题3/4 测量点选择的 PPO+CUDA 训练环境与闭环接入 | 自建全清;与手写策略配对消融有可复算报告 | 已完成:`scripts/train_rl.py`/`benchmark_rl.py`,模型 `output/rl/q{3,4}_ppo.zip`,说明 `docs/algo-rl.md` |
| P7 正式与论文 | 固定版本、论文表1、日志原名、上传核查 | 问题3/4各3份正式记录与程序版本对应 | 团队后续安排;本任务不执行正式测试 |
按2026年9月10日起的剩余时间,建议10日补齐P1并衔接P3,11日完成P4自建边界案例与全向演练,12日完成P5及混合源演练;未达验收就删减P6并优先修正闭环。演练不限3次,正式机会为问题3和4各3次。团队在版本稳定后自行安排正式记录,留出失败恢复和论文整理时间。附件建议9月13日15:30前完成正式测试,17:30后不能启动新的演练或正式测试;已进入上传队列的日志仍会继续上传。此处引用所给附件安排,运行前核对模拟器界面公告;这份排期不改变当前禁止使用正式测试的限制。
+71
View File
@@ -0,0 +1,71 @@
# docs 索引
仓库文档分四类:**总览与流程**、**逐问算法**、**验证与对比**、**论文与插图**。
阅读顺序建议按下面的表格从上到下。
## 总览与流程
| 文档 | 内容 |
| --- | --- |
| [`总体思路与流程图.md`](总体思路与流程图.md) | 四问主线、端到端流程图(mermaid)、执行步骤与执行时间速查、交付物与验收锚点 |
| [`执行时间与执行步骤.md`](执行时间与执行步骤.md) | 计时模型、会话状态机与动作回合、附件示例逐步推演、实测日志分解、时间预算与安全阀 |
| [`B题建模分析与实施计划.md`](B题建模分析与实施计划.md) | 四问建模取舍与 P0–P7 实施计划(最早的设计文档) |
| [`协议规则表与状态机.md`](协议规则表与状态机.md) | 指令字段表、结果码、计时模型、状态机(P0 交付) |
## 逐问算法
| 文档 | 内容 |
| --- | --- |
| [`algo-1.md`](algo-1.md) | 问题一实现口径:半平面交、顶点对直径、直径圆充要判定、MEC 清除证书 |
| [`问题一解答.md`](问题一解答.md) | 问题一论文式解答:模型边界、算法可复现步骤、反例构造、演练验证 |
| [`algo-2.md`](algo-2.md) | 问题二:候选集 K1、保证接收盘、安全盘 B(c, 1000−a)、最坏后验选点 |
| [`algo-3.md`](algo-3.md) | 问题三:三层在线架构、七点解析覆盖、覆盖账本、任务调度与停止条件 |
| [`algo-3-bayes.md`](algo-3-bayes.md) | 问题三 `bayes` 策略:网格幸存集滤波、信息增益选点、动态 TSP、Optuna 调参 |
| [`algo-4.md`](algo-4.md) | 问题四:`forward_half_disk` 最小命中集、位置×朝向联合信念、后备盲清 |
## 优化与验证
| 文档 | 内容 |
| --- | --- |
| [`第三四问架构优化与运行提速方案.md`](第三四问架构优化与运行提速方案.md) | 运行历史复核、分层目标架构、P0–P2 优化项与实施路线 |
| [`第三四问图论与动态规划优化方案.md`](第三四问图论与动态规划优化方案.md) | 图论/DP 引入方案与实测回填(含未采用的改动与原因) |
| [`算法审核与优化-20260911.md`](算法审核与优化-20260911.md) | 一次外部口径的算法审核记录与结论 |
| [`最优与基线实现对比.md`](最优与基线实现对比.md) | 1–4 问「最优实现 / 基线实现」对比框架与结果(论文口径说明) |
| [`B题问题3-4相关论文列表.md`](B题问题3-4相关论文列表.md) | 题 3、4 相关文献清单 |
## 论文与插图
| 路径 | 内容 |
| --- | --- |
| [`paper/main.tex`](paper/main.tex) | 论文正文(`latexmk -xelatex main.tex`) |
| [`paper/README.md`](paper/README.md) | 论文编译方式、目录结构与待办标记 |
| [`figures/README.md`](figures/README.md) | 插图清单、配色与字体约定、数据来源与复现命令 |
| [`figures/manifest.json`](figures/manifest.json) | 每张图的数据来源与 sha256、生成命令 |
| [`../project/README.md`](../project/README.md) | 对比框架目录结构与运行方式 |
## 口径登记
同一事实在多份文档中出现时,以下列来源为准;发现不一致请先改文档,再复核图。
| 事实 | 权威来源 |
| --- | --- |
| 题面常量(Ω、速度、各动作耗时、源与频道范围) | `src/mcm26b/config.py`(带 `[题面]` / `[工程]` 标注) |
| 指令字段与结果码 | `src/mcm26b/protocol/rules.py` + [`协议规则表与状态机.md`](协议规则表与状态机.md) |
| 问题一数值(D、ρ、E) | `mcm26b.geometry.solve` 的返回,或 [`问题一解答.md`](问题一解答.md) |
| 覆盖计划与证书 | `src/mcm26b/guarantee/plans/*.json`(`q4_mincover_v2.json` 为默认) |
| 实测虚拟时间 | 行为日志 `virtual_time_s` 字段与 `evaluation.recompute_virtual_time` |
| 冻结基准集对比结果 | `project/results/*.md`(由 `uv run python -m project.run` 生成) |
已知的两处需要随环境更新的引用:
1. [`问题一解答.md`](问题一解答.md) 引用的 `output/q1/figures/*.png` 属于早期
离线插图(`output/` 未入库);现行插图在 [`figures/`](figures/README.md)。
2. 多份文档提到的官方演练报告位于 `output/q3/practice/`、`output/q4/`,
同样未入库;需要时用 `scripts/verify_q3_practice.py` 对留档目录复算。
## 写作约定
- 只写结论与依据,不使用比喻、排比与自评式措辞(例如「唯一权威」「关键洞察」)。
- 数字必须能在代码或数据中找到出处;图内不放标题与解释段落,
说明写在正文,图名与清单见 [`figures/README.md`](figures/README.md)。
- 中文引号统一使用「」,避免与代码中的 ASCII 引号混淆。
+225 -144
View File
@@ -1,185 +1,266 @@
# 问题一:有界测向误差下定位区域的直径与圆覆盖
# 问题一算法说明:有界测向误差下的角域交会、直径与最小包围圆
## 摘要
> 本文按**当前仓库实现**重写,替代早期只描述理论方案的版本。
> 问题一生产入口为 `src/mcm26b/geometry/localization.py::solve`,CLI 为
> `python -m mcm26b.geometry`;问题二至四只复用其中的
> `smallest_enclosing_circle` 与同一套角域半平面语义,并不直接调用
> `solve`(复用与差异见 §7)。
针对同一干扰源在多个检测点处的带误差方位观测,建立前向角域交集模型,将定位区域表示为二维线性不等式组的可行域。首先推导角域的半平面表达,给出兼顾空集、点、线段和无界区域的几何构造算法;随后证明,有界定位区域的直径必由一对顶点取得,且判断是否存在直径等于区域直径的覆盖圆,只需检验任意一组最远顶点的中点。通过符合题设测向条件的等边三角形反例,说明直径圆一般不能覆盖定位区域。进一步以最小包围圆连接定位精度和后续清除条件,并给出算法复杂度、数值处理原则及既有演练观测的复算结果。全部结论以有界误差模型为前提,不引入误差独立、正态或均匀分布假设。
## 1. 问题与实现入口
**关键词:** 交会定位;有界误差;半平面交;凸多边形直径;最小包围圆。
同一频道的同一静止干扰源,在若干检测点 $s_i=(s_{ix},s_{iy})$ 处得到示向度
$\theta_i$。题设测向误差不超过 $\pm1^\circ$,同一地点重复测量误差不变;
示向度从正东逆时针计量。问题一要求定位区域的直径,并判断“以该直径为
直径的圆”能否覆盖定位区域。
## 1. 问题界定与思路来源
题目要求由若干检测点坐标及同一干扰源的示向度,求交会定位多边形的直径,并判断以该直径为直径的圆能否覆盖定位区域。题面规定测向误差在 $[-1^\circ,1^\circ]$ 内,同一地点重复测量的误差不变;示向度从正东沿逆时针方向计量。[题面第1页、附录2第(1)、(3)项](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)
由此得到三步建模思路。第一,单次观测不能确定一条精确射线,却可以确定一个包含真实方向的角域,因此采用集合相交而非直线最小二乘。第二,角域可以写成半平面交,问题随之转化为凸几何问题。第三,“两点最远距离”和“覆盖全部位置所需半径”是不同的优化量,应分别计算直径和最小包围圆。
半平面、凸组合和凸集交运算属于标准凸分析工具,其背景见 Boyd 与 Vandenberghe 的《Convex Optimization》第2章;本文针对测向模型给出独立推导,不将一般理论本身视为新的研究贡献。[文献2](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf)
本文严格区分两个集合:问题一的 $P$ 仅表示测向角域之交;第二问及在线搜索中的 $K$ 可进一步结合源位置圆域和接收距离先验。向 $P$ 加入圆盘后,边界可能出现圆弧,不能继续把它当成原问题中的纯多边形。
## 2. 符号及基本假设
| 符号 | 含义 |
| --- | --- |
| $s_i=(s_{ix},s_{iy})$ | 第 $i$ 个检测点,坐标单位为米 |
| $\theta_i$ | 第 $i$ 次有效示向度 |
| $\delta_i$ | 误差半角,题设取 $1^\circ$ |
| $g=(x,y)$ | 未知干扰源位置 |
| $W_i$ | 第 $i$ 次测向对应的闭前向角域 |
| $P$ | 所有角域的交集 |
| $V=\{v_1,\ldots,v_m\}$ | 非空有界 $P$ 的顶点集 |
| $D(P)$ | 区域内任意两点距离的上确界 |
| $B(c,r)$ | 中心为 $c$、半径为 $r$ 的闭圆盘 |
| $\rho(P)$ | 覆盖 $P$ 的最小圆盘半径 |
假设各次有效示向度对应同一频道的同一个静止源。仅把 `direction` 观测代入角域模型,不能给 `near` 或 `no_signal` 人为赋予角度。理论推导允许 $0\le\delta_i<90^\circ$,用于讨论退化情况,题目主模型始终采用 $\delta_i=1^\circ$。
程序可额外计入两位小数舍入对应的 $0.005^\circ$ 裕量,但必须显式声明。题设的 $1^\circ$ 误差界与实现中的浮点容差是两个概念,均不能在结果解释时省略。
## 3. 由角域推导半平面约束
定义方向向量 $u(\alpha)=(\cos\alpha,\sin\alpha)$,二维叉积为 $[a,b]=a_xb_y-a_yb_x$。三角函数计算前将角度换成弧度。
令 $u_i^-=u(\theta_i-\delta_i)$、$u_i^+=u(\theta_i+\delta_i)$。当 $0<\delta_i<90^\circ$ 时,真实位置位于两条边界射线之间,等价于 $[u_i^-,g-s_i]\ge0$ 和 $[u_i^+,g-s_i]\le0$。第一条要求 $g-s_i$ 在下边界的左侧,第二条要求其在上边界的右侧。
将第一条展开,得到 $\sin(\theta_i-\delta_i)x-\cos(\theta_i-\delta_i)y\le\sin(\theta_i-\delta_i)s_{ix}-\cos(\theta_i-\delta_i)s_{iy}$。
将第二条展开,得到 $-\sin(\theta_i+\delta_i)x+\cos(\theta_i+\delta_i)y\le-\sin(\theta_i+\delta_i)s_{ix}+\cos(\theta_i+\delta_i)s_{iy}$。
同时保留前向约束 $u(\theta_i)\cdot(g-s_i)\ge0$。该约束在正半角情形下冗余,但当 $\delta_i=0$ 时,前两条只限定一条直线,加入它才得到正确的射线。角域顶点本身也包含在闭集合内,这是保守几何处理,并不表示该点仍能获得示向度。
因此,$P=\bigcap_{i=1}^{n}W_i=\{g:Ag\le b\}$。采用向量不等式后,$359^\circ$ 与 $0^\circ$ 跨界无需分段比较角度。每个 $W_i$ 是闭凸集,故 $P$ 也是闭凸集;它可能为空、为单点、为线段、为有界凸多边形,也可能无界。
## 4. 定位区域的构造与分类
### 4.1 边界交点与可行性
把约束统一写成 $a_jx+b_jy\le c_j$。两条边界的行列式为 $\Delta_{jk}=a_jb_k-a_kb_j$。当 $\Delta_{jk}\ne0$ 时,交点坐标为 $x=(c_jb_k-c_kb_j)/\Delta_{jk}$、$y=(a_jc_k-a_kc_j)/\Delta_{jk}$。保留满足全部约束的交点,再去重并构造凸包。
**命题1:** 至少有一次观测时,非空的角域交集一定存在极点,因此可通过可行边界交点枚举判空。
**证明:** 取第一个角域的轴向量 $u_1$,其中任意 $g$ 满足 $u_1\cdot(g-s_1)\ge\cos\delta_1\,\lVert g-s_1\rVert$,且 $\cos\delta_1>0$。在非空 $P$ 上最小化线性函数 $u_1\cdot(g-s_1)$;以任一可行点的函数值截取下水平集,得到非空紧集,故最小值能够取得。最小化点集位于一条支撑直线上,且有界,所以为点或线段。取该点或线段端点即得到 $P$ 的极点。二维线性约束的极点至少有两条法向量线性无关的有效边界,否则沿所有有效边界的公共切向可作双向小扰动,与极点定义矛盾。因此极点包含在上述交点枚举中。证毕。
无观测时,$P=\mathbb R^2$,应直接判为无界,不能用“没有交点”判断为空集。
### 4.2 无界性判定
对非空 $P$ 定义衰退锥 $\mathcal R=\{d:Ad\le0\}$。若存在 $d\ne0$,则任意 $g_0\in P$ 与 $t\ge0$ 都满足 $g_0+td\in P$,所以 $P$ 无界。
反之,若 $P$ 无界,可取 $g_k\in P$ 使 $\lVert g_k-g_0\rVert\to\infty$。单位向量 $(g_k-g_0)/\lVert g_k-g_0\rVert$ 存在收敛子列,极限 $d$ 满足 $\lVert d\rVert=1$。将 $Ag_k\le b$ 减去 $Ag_0$,再除以距离并取极限,得到 $Ad\le0$。因此 $P$ 有界当且仅当 $\mathcal R=\{0\}$。
本模型的衰退锥被一个小于 $180^\circ$ 的闭角域约束,若包含非零向量,必含一条极射线,该射线平行于某条有效约束边界。故只需检查每个法向量 $(a_j,b_j)$ 的两个切向方向 $(b_j,-a_j)$、$(-b_j,a_j)$ 是否满足所有齐次不等式。
### 4.3 分类约定
可行交点为空时返回空集;存在非零衰退方向时返回无界。否则求可行交点的凸包,按顶点数和仿射维数区分单点、线段和二维多边形。空集的直径在本文约定为未定义;无界集合的直径为 $+\infty$。程序使用空值及单独的无穷标志表示二者,避免写入非标准 JSON 数值。
显示窗口只用于绘图裁剪。任意大矩形都不能取代衰退锥判定,更不能把截断图形的直径称为原无界区域的直径。
## 5. 直径的顶点定理
**定理1:** 若 $P=\operatorname{conv}(V)$ 非空且有界,则 $D(P)=\max_{i,j}\lVert v_i-v_j\rVert$。
**证明:** 任取 $x,y\in P$,可写成 $x=\sum_i\lambda_i v_i$、$y=\sum_j\mu_jv_j$,其中权重非负且分别求和为1。于是 $x-y=\sum_{i,j}\lambda_i\mu_j(v_i-v_j)$。由三角不等式,$\lVert x-y\rVert\le\sum_{i,j}\lambda_i\mu_j\lVert v_i-v_j\rVert\le\max_{i,j}\lVert v_i-v_j\rVert$。最远顶点对又属于 $P$,上界可以达到,结论成立。证毕。
因此,小规模问题中直接枚举所有顶点对即可,计算复杂度为 $O(m^2)$。单点的直径为0,线段的直径为端点距离。这里的直接枚举不是近似算法;其缺点仅在于大规模时计算量较高。
## 6. 直径圆覆盖的充要条件
**定理2:** 取任意一组最远顶点 $a,b$,令 $D=\lVert a-b\rVert$、$o=(a+b)/2$。存在直径为 $D$ 的覆盖圆,当且仅当所有顶点均满足 $\lVert v_i-o\rVert\le D/2$。
**证明:** 若半径为 $D/2$、中心为 $z$ 的圆同时包含 $a,b$,则 $D\le\lVert a-z\rVert+\lVert z-b\rVert\le D$。两个不等式必须同时取等号,所以 $z$ 在两点连线上,且到两点距离相等,只能是中点 $o$。当 $D=0$ 时结论直接成立。另一方面,圆盘是凸集,包含全部顶点等价于包含它们的凸包。因此只需在这个唯一可能的圆心处检查全部顶点。证毕。
该定理不仅回答“以某条直径线段为直径的圆是否覆盖”,也回答“能否移动一个同样大小的圆使其覆盖”。若检查失败,移动圆心或更换最远顶点对均不能解决。
定义最大超出量 $E=\max_i\lVert v_i-o\rVert-D/2$。在精确算术下,$E=0$ 表示覆盖成立,$E>0$ 表示失败;不会出现严格负值,因为最远点对就在圆周上。取达到最大值的顶点,即得到一份可以独立复核的覆盖失败证据。
## 7. 符合测向条件的反例
取误差半角均为 $1^\circ$,三个检测点及读数如下。
| 检测点 | 坐标(米) | 示向度 |
| 层次 | 文件 | 内容 |
| --- | --- | --- |
| $s_1$ | $(-1000,0)$ | $1^\circ$ |
| $s_2$ | $(540,-500\sqrt3)$ | $121^\circ$ |
| $s_3$ | $(520,520\sqrt3)$ | $241^\circ$ |
| 生产内核 | `src/mcm26b/geometry/localization.py` | `Measurement`、`halfplanes`、`convex_hull`、`diameter`、`smallest_enclosing_circle`、`solve` |
| CLI | `src/mcm26b/geometry/__main__.py` | 读 JSON、可加两位小数舍入裕量、输出结果 |
| 统一入口 | `src/mcm26b/cli.py` | `mcm26b q1` |
| 对比框架 | `project/q1/{optimal,baseline,reference,cases,compare}.py` | 生产实现 / 朴素基线 / 独立大框参考解 |
| 回归 | `tests/test_geometry.py`、`tests/test_geometry_certificates.py` | 解析形状、真值保留、随机对拍、证书边界 |
| 结果 | `examples/q1/*.json`、`project/results/q1.md` | 固定解析算例与 40 个随机交会算例的配对结果 |
每个角域的下边界方向分别为 $0^\circ,120^\circ,240^\circ$。对应的三个左半平面是 $y\ge0$、$\sqrt3x+y\le40\sqrt3$、$y\le\sqrt3x$,交集为顶点 $A=(0,0)$、$B=(40,0)$、$C=(20,20\sqrt3)$ 的等边三角形。
```bash
.venv/bin/python -m mcm26b.geometry examples/q1/triangle.json
.venv/bin/python -m mcm26b.geometry examples/q1/normal.json --rounding-margin-deg 0.005
```
还需验证每个角域的另一条边不会切去这个三角形。以 $s_1$ 为例,到三个顶点的方向分别为 $0^\circ,0^\circ,\arctan(20\sqrt3/1020)$,最后一项约为 $1.945^\circ<2^\circ$,均在 $[0^\circ,2^\circ]$ 内。其余两站由绕三角形中心旋转 $120^\circ$ 的对称性成立。因此三个完整前向角域之交恰为上述三角形。
`--rounding-margin-deg` 默认 $0$;库内在线求解默认把服务器两位小数舍入的
$\le0.005^\circ$ 偏差计入有效半角,这是**实现口径**,不是题面新增误差。
问题一 CLI 只有显式传参才附加该裕量,以便同时报告纯 $1^\circ$ 与
$1.005^\circ$ 两套敏感性结果。
将真实源取为三角形中心 $g_*=(20,20\sqrt3/3)$。以第一站为例,真实方向约为 $0.649^\circ$,与 $1^\circ$ 的读数偏差小于 $1^\circ$;检测距离约为1020米,小于1500米。另两站同理。该反例符合题设方位误差和可能的有效接收半径。
## 2. 模型:把角域写成半平面交
此时 $D=40$ 米,而以 $AB$ 为直径的圆中心为 $(20,0)$,到 $C$ 的距离为 $20\sqrt3>20$ 米,不能覆盖。三角形外接圆即最小包围圆,其中心为 $(20,20\sqrt3/3)$,半径为 $40/\sqrt3\approx23.094011$ 米。这也证明了“直径不超过40米”不足以保证一次清除。
令方向向量 $u(\alpha)=(\cos\alpha,\sin\alpha)$,二维叉积
$[a,b]=a_xb_y-a_yb_x$。设误差半角为 $\delta$(题设主模型 $\delta=1^\circ$),
真实源 $g$ 属于闭前向角域
## 8. 最小包围圆及其清除含义
$$
W(s,\theta,\delta)=\{g:\ [u(\theta-\delta),g-s]\ge0,\
[u(\theta+\delta),g-s]\le0,\ u(\theta)\cdot(g-s)\ge0\}.
$$
### 8.1 存在性、唯一性与支撑点
对应实现中的三条半平面 $a x+b y\le c$ 为
定义 $f(z)=\max_{v\in V}\lVert v-z\rVert$,则 $\rho(P)=\min_z f(z)$。由于 $V$ 有限,$f$ 连续且随 $\lVert z\rVert\to\infty$ 而趋于无穷,最小值存在。
| 约束 | $a$ | $b$ | $c$ |
| --- | --- | --- | --- |
| 下边界左侧 | $\sin(\theta-\delta)$ | $-\cos(\theta-\delta)$ | $a s_x+b s_y$ |
| 上边界右侧 | $-\sin(\theta+\delta)$ | $\cos(\theta+\delta)$ | $a s_x+b s_y$ |
| 前向 | $-\cos\theta$ | $-\sin\theta$ | $a s_x+b s_y$ |
若两个不同中心 $c_1,c_2$ 都以半径 $r$ 覆盖 $V$,中点 $c$ 对每个顶点满足 $\lVert v-c\rVert^2=(\lVert v-c_1\rVert^2+\lVert v-c_2\rVert^2)/2-\lVert c_1-c_2\rVert^2/4<r^2$,与最小性矛盾。因此最小包围圆唯一。
第三条前向约束在 $0<\delta<90^\circ$ 时冗余,但在 $\delta=0$ 时必须保留,
否则两条边界只确定一条直线而非一条射线。角域顶点按闭集处理;这是保守的
几何含义,不表示边界点仍能返回方向读数。
在最优中心 $c$ 处,令 $T$ 为圆周上的顶点集。若 $c$ 不在 $T$ 的凸包中,可沿严格分离方向小幅移动中心,使所有圆周点的距离同时减小;其余有限个点有严格余量,仍被稍小圆覆盖,产生矛盾。故 $c\in\operatorname{conv}(T)$。二维凸组合经仿射相关权重消元,最多保留3个点。因此最小包围圆由至多3个圆周顶点支撑。
$P=\bigcap_i W_i$ 是有限条闭半平面之交,因而是闭凸集;可能为空、单点、
线段、有界多边形或无界多边形。实现不做正态、均匀或独立误差假设,
只使用题面给定的有界误差。
更具体地,若支撑点 $p_j$ 的权重满足 $c=\sum_j\lambda_jp_j$,则对任意 $z$ 有 $\sum_j\lambda_j\lVert p_j-z\rVert^2=r^2+\lVert c-z\rVert^2\ge r^2$。这给出了任何覆盖圆半径不能小于 $r$ 的直接证据。
## 3. 精确算法流程
### 8.2 求解方法与来源
`solve(measurements, eps)` 的步骤如下。
由支撑点性质,可以枚举单点零半径圆、两点直径圆和三点外接圆,再检查全体顶点。这是便于核查的基准方法,最坏复杂度为 $O(m^4)$。
### 3.1 坐标归一化与边界交点枚举
当前实现采用 Welzl 的随机增量算法:打乱点序,若当前圆不包含新点,则在该点成为边界点的约束下递归求解较小问题;边界点至多3个。程序用显式栈避免递归深度限制,并固定随机种子以复现结果。理论期望线性依赖随机排列分析,不等于任意固定排列的最坏时间保证。3个强制边界点应使用外接圆,不能替换成其无约束最小圆。算法来源为 Welzl 的原论文,CGAL 文档提供了定义与实现背景。[文献3](https://people.inf.ethz.ch/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf)、[文献4](https://doc.cgal.org/latest/Bounding_volumes/classCGAL_1_1Min__circle__2.html)
先对所有检测点做平移和统一缩放,使数值量级接近单位坐标;结果再换回原坐标。
### 8.3 与一次清除的关系
1. 生成 $k=3n$ 条半平面。
2. 枚举全部边界直线对($\binom{k}{2}$ 对),用行列式
$\Delta=ae-bd$ 求交点;仅在 $\Delta$ 恰为 $0$ 时跳过,近平行对也保留,
因为其交点可能是细长区域的合法远端顶点。
3. 保留满足全部约束的交点;可行性判定使用随坐标量级缩放的位置容差
`eps * max(1, |x|, |y|)`,避免大坐标下绝对残差被误判为不可行。
所有能够保证一次清除的位置构成 $C_{20}(P)=\bigcap_{g\in P}B(g,20)=\bigcap_{v\in V}B(v,20)$。第二个等号来自圆盘凸性。该集合非空当且仅当 $\rho(P)\le20$。
### 3.2 空集、有界与无界
因此,最小包围圆中心是保证清除的充分选择,但不一定是移动距离最短的选择。若后续需要优化路径,可以在 $C_{20}(P)$ 内寻找距离机器狗最近的位置。相比之下,$D(P)\le40$ 只是必要条件。
- 无观测:$P=\mathbb R^2$,返回 `unbounded`。
- 没有任何可行边界交点:返回 `empty`。
- 否则检查衰退锥 $\mathcal R=\{d:Ad\le0\}$ 是否存在非零方向。二维情况下
该锥若非零必含一条与某条有效边界平行的极射线;实现只需检查每条约束的
两个切向 $(b,-a)$、$(-b,a)$ 是否满足全部齐次不等式
$a d_x+b d_y\le 2\times10^{-14}$。阈值取得比位置容差紧得多,避免把
极细长有界区域误判成无界。
- 存在非零衰退方向时返回 `unbounded`,直径为 `null` 且显式置
`diameter_infinite=true`,不伪造有限数值。
## 9. 算法流程与计算量
### 3.3 凸包与状态分类
**算法1:角域交、直径及覆盖证据。**
将可行交点去重后,用 Andrew 单调链求凸包(逆时针、无重复首尾点)。
按顶点数与维数返回:
1. 校验观测并进行坐标平移、尺度归一化,保留原误差半角。
2. 生成每次观测的三条半平面约束。
3. 枚举非平行边界交点,保留满足全部约束的点;无观测和空集分别处理。
4. 检验非零衰退方向;存在时报告无界并停止有限圆计算。
5. 对可行点去重并求凸包,识别点、线段或多边形。
6. 枚举顶点对求直径及任意一组最远点。
7. 检查其中点到全部顶点的距离,输出最大超出量与失败顶点。
8. 求最小包围圆,换回原坐标,重新检查顶点包含性,输出清除半径余量。
| `status` | 含义 | 直径 | 最小包围圆 |
| --- | --- | --- | --- |
| `empty` | 观测不相容 | 未定义(`null`) | 不计算 |
| `unbounded` | 存在非零衰退方向 | $+\infty$(`null` + 标志) | 不计算 |
| `point` | 单点 | 0 | 半径 0 |
| `segment` | 线段 | 两端点距离 | 半径 = 直径 / 2 |
| `polygon` | 二维有界凸多边形 | 见 §3.4 | 见 §3.6 |
令半平面数 $k=3n$,顶点数为 $m$。边界交点枚举及全约束检查为 $O(k^3)$,衰退方向检查为 $O(k^2)$,交点排序上界为 $O(k^2\log k)$,直径计算为 $O(m^2)$,覆盖证据检查为 $O(m)$。随机增量最小圆在随机排列下期望为 $O(m)$;整个算法仍由半平面交点枚举主导,不能因此称为总体线性算法。
### 3.4 直径:只需枚举顶点对(已证明)
## 10. 数值实现与已有观测复核
**定理 1.** 若 $P=\operatorname{conv}(V)$ 非空有界,则
$D(P)=\max_{v_i,v_j\in V}\lVert v_i-v_j\rVert$。
数学结论使用精确不等式。浮点实现先平移、归一化,再用位置容差、平行判定阈值和衰退方向容差分别处理不同问题。接近平行或退化输入应进行精度与容差敏感性检查;任意追加一个固定小数裕量都不能替代严格的误差传播上界。
证明:任一 $x,y\in P$ 写成凸组合后,
$x-y=\sum_{i,j}\lambda_i\mu_j(v_i-v_j)$,由三角不等式有
$\lVert x-y\rVert\le\max_{i,j}\lVert v_i-v_j\rVert$,而最远顶点对本身
属于 $P$,故上界可达。实现直接枚举顶点对,复杂度 $O(m^2)$;单点返回 0,
线段返回端点距离。
当前程序输出 `diameter_circle` 中的圆心、半径、最大超出量和反例顶点,以及 `minimum_enclosing_circle`。清除判断采用 $\rho+\varepsilon_m\le20$,其中 $\varepsilon_m$ 是工程数值裕量。它是观测及几何计算可靠这一前提下的决策条件,不是一次真实清除成功记录。
### 3.5 直径圆覆盖:唯一候选圆心是直径中点(已证明)
既有官方演练案例 `U5ZW-P9KN-TCAG-R7ST` 的三次不同位置观测如下。
**定理 2.** 取任意一组最远顶点 $a,b$,$D=\lVert a-b\rVert$,
$o=(a+b)/2$。存在直径为 $D$ 的覆盖圆,当且仅当所有顶点 $v_i$ 满足
$\lVert v_i-o\rVert\le D/2$。
| 检测点 | $x$ / 米 | $y$ / 米 | 示向度 / 度 |
| --- | ---: | ---: | ---: |
| 1 | 0 | 0 | 131.52 |
| 2 | -613.7618853216 | 391.5307754525 | 34.92 |
| 3 | -314.2721344680 | 656.6833525352 | 227.19 |
证明:若半径 $D/2$ 的圆心 $z$ 同时包含 $a,b$,则
$D\le\lVert a-z\rVert+\lVert z-b\rVert\le D$,两个不等式都必须取等号,
故 $z$ 只能在两点中点。圆盘是凸集,检查全部顶点即检查整个凸包。
| 误差半角 | 直径 / 米 | 最小包围半径 / 米 | 直径圆最大超出 / 米 |
实现输出 `diameter_circle`:圆心、半径、全部顶点到圆心的最大距离、
`covers` 布尔值、最大超出量 `max_excess_m`、圆外顶点索引
`outside_vertex_indices` 和反例顶点 `witness_vertex`。`witness_vertex`
是一份可独立复核的覆盖失败证据;`max_excess_m` 不能为负,因为最远顶点
本身在圆周上(精确算术下)。
### 3.6 最小包围圆与 20 m 清除证书
对凸包求最小包围圆 $\rho(P)$。实现采用 Welzl 随机增量算法的显式栈版本:
固定随机种子使结果可复现;三个强制边界点使用外接圆;输出前再对全部
顶点复核一次。内部有 $O(m^4)$ 的 1/2/3 点支撑圆枚举参考实现
(`_enclosing_circle_reference`)用于单测对拍。
在最小包围圆中心 $m$、半径 $\rho$ 处,若
$\rho+\varepsilon_m\le20$,则可直接以 $m$ 为清除点:任意真源
$g\in P\subseteq B(m,\rho)$,到 $m$ 的距离不超过 $\rho$。实现输出
`minimum_enclosing_circle`、`guaranteed_clearable_at_mec_center` 以及
`clearance_certificate`(含数值余量和剩余裕量)。
注意:直径 $D\le40$ 只是“可能一次清除”的必要条件,**不是充分条件**;
三角形反例中 $D=40$ 而 $\rho=23.094>20$。
## 4. 伪代码
```text
solve(measurements):
if measurements 为空: return unbounded
平移/缩放,生成每条读数的三条半平面
V = []
for 每一对边界直线:
求交点 p
if p 满足全部半平面: V.append(p)
if V 为空: return empty
if 存在非零衰退切向 d: return unbounded
H = convex_hull(V)
D, (a,b) = argmax_{v_i,v_j∈H} |v_i-v_j|
o = (a+b)/2
covers = max_{v∈H} |v-o| <= D/2
输出 diameter、diameter_circle、witness
(m,rho) = Welzl_MEC(H)
输出 minimum_enclosing_circle 与 rho+eps<=20 清除证书
```
## 5. 复杂度与数值实现
| 步骤 | 复杂度 |
| --- | --- |
| 生成半平面 | $O(k)$,$k=3n$ |
| 边界交点枚举与可行性判定 | $O(k^3)$ |
| 凸包 | $O(k^2\log k)$ 最坏 |
| 直径 | $O(m^2)$ |
| 直径圆检查 | $O(m)$ |
| Welzl 最小圆 | 随机排列下期望 $O(m)$;固定排列不声称最坏线性 |
主要数值约定:
- 坐标归一化后计算,输出换回原坐标并重新复核包含性;
- 仅对**精确平行**直线对跳过求交;近平行对保留;
- 位置可行性容差随坐标幅值缩放;衰退锥判定使用独立紧阈值;
- `solve` 主动限制最多 100 个检测点,超过时要求改用半平面交算法;
- 所有输出用 `null`/显式标志表示空集和无界,不写非法 JSON 浮点数。
## 6. 已验证算例与结果
固定解析算例(`examples/q1`,当前代码实测):
| 算例 | 状态 | 直径 (m) | MEC 半径 (m) | 直径圆覆盖 | 最大超出 (m) | MEC 可直接清除 |
| --- | --- | ---: | ---: | --- | ---: | --- |
| `normal` 三点交会 | polygon | 26.986 | 13.943 | 否(2 个圆外顶点) | 3.964 | 是 |
| `triangle` 等边三角形反例 | polygon | 40.000 | 23.094 | 否(1 个圆外顶点) | 14.641 | 否 |
| `segment` 零误差退化线段 | segment | 100.000 | 50.000 | 是 | 0.000 | 否 |
| `poor` 近共线检测点 | unbounded | — | — | — | — | — |
| `empty` 不相容观测 | empty | — | — | — | — | — |
`triangle` 的三个顶点是 $(0,0)$、$(40,0)$、$(20,20\sqrt3)$:以直径
$AB$ 为直径的圆圆心 $(20,0)$、半径 20,到 $C$ 的距离为 $20\sqrt3>20$,
故不能覆盖;最小包围圆半径 $40/\sqrt3\approx23.094$,也不能一次清除。
其中 $A=(0,0)$ 坐标是浮点下的 $-6.4\times10^{-13}$,上表按解析值取整。
既有官方演练观测(案例 `U5ZW-P9KN-TCAG-R7ST`,不公开源坐标、未执行清除)
的复算结果:
| 误差半角 | 直径 (m) | MEC 半径 (m) | 直径圆最大超出 (m) |
| --- | ---: | ---: | ---: |
| $1^\circ$ | 23.996723 | 12.068583 | 0.604002 |
| $1.005^\circ$ | 24.119088 | 12.130377 | 0.608486 |
两种口径下直径圆均不覆盖区域,最小包围半径均小于20米。该演练未公开源坐标,且没有执行清除,故只用于观测交会和计算一致性复核,不能据此声称实测定位误差或全清成功率。数据见[原始三点观测](C:/Users/HelixCopex/code/MATH/output/q1/practice/U5ZW-P9KN-TCAG-R7ST_observations.json),敏感性数值见[已有复算报告](C:/Users/HelixCopex/code/MATH/output/q1/optimization_report.json)。
两种口径下直径圆都不覆盖定位区域,MEC 半径都小于 20 m,但该演练没有
真实清除动作,不能据此声称实测定位误差或全清成功率。
## 11. 结论与实现对应
`project/q1` 的 40 个随机交会算例(冻结算例与独立参考解对拍):
问题一的准确答案为:将测向角域表示为半平面交,先判断非空性及有界性,再由最远顶点对得到直径;以该直径为直径的圆一般不能覆盖定位区域,覆盖的充要条件是任意一组最远顶点的中点到全部顶点的距离均不超过半径。最小包围圆提供独立且适合后续清除的精度指标。
| 方法 | 状态准确率 | 直径平均绝对误差 | 直径圆覆盖准确率 | 平均耗时 |
| --- | ---: | ---: | ---: | ---: |
| 生产 `solve` | 100% | 0.000 m | 100% | 0.086 ms |
| 朴素基线(网格 + 包围盒对角线) | 100% | 4.583 m | 52.5% | 15.932 ms |
对应实现为 [localization.py](C:/Users/HelixCopex/code/MATH/geometry/localization.py)。在项目根目录可运行 `python -m geometry examples/q1/triangle.json`;追加 `--rounding-margin-deg 0.005` 可复算额外舍入裕量。本文整理理论与已有计算结果,不改变原始观测或既有程序。
## 7. 与问题二/三/四当前实现的复用关系和差异(核对结果)
问题一给出的几何内核是后续所有几何决策的基础,但**复用方式是“语义 + 最小圆函数”,
不是直接调用 `solve`**。代码层面的核对结果如下。
| 后续问题 | 实际复用了什么 | 实际没有复用 / 做了什么替换 |
| --- | --- | --- |
| 问题二(`planner.select_second_point`) | 同一套角域半平面语义;`smallest_enclosing_circle` 求候选集 MEC;用 MEC 半径构造保证接收盘 | 不调用 `solve`;候选集不是纯角域交,而是 $K_1=\Omega\cap W\cap B(s,1500)$;用 192 边形外包圆盘 + Sutherland–Hodgman 裁剪,而不是枚举直线交点;不计算直径,也不使用“直径中点圆”判据 |
| 问题三(`belief.CandidateRegion`、`planner.bayes_loop`) | 复用 `smallest_enclosing_circle`;角域边界公式与问题一相同;MEC 作为清除证书 | 在线信念是有界凸外包多边形,圆盘边界是外切多边形而非精确曲线;不再判无界;no_signal 的负观测由网格粒子滤波处理(问题一模型里没有负观测);不用直径,而用“MEC 半径 + 外包余量 + 工程余量 $\le20$” |
| 问题四(`planner.DirectionalExtension`、`belief.joint`) | 继续复用问题一的 MEC 与角域语义;(位置 × 朝向)联合信念也建立在同一网格上 | 定向源的 no_signal 不能排除位置,不能沿用问题一/三的纯角度或全向距离解释;覆盖语义改为 `forward_half_disk`(见 `algo-4.md`) |
代码证据:
- `src/mcm26b/belief/__init__.py` 只从 `geometry.localization` 导入
`smallest_enclosing_circle`;
- `src/mcm26b/particles.py` 同样只导入 `smallest_enclosing_circle`;
- `生产/运行代码中 `geometry.localization.solve` 的调用者只有
`geometry/__main__.py` 和 `project/q1/optimal.py`,即问题一 CLI 与其
对比框架;测试文件会直接调用它做解析与随机对拍,不在此列;
- 在线 `clip_wedge` 的半平面系数与问题一 `halfplanes` 一致,但作用在
凸多边形裁剪流程上;`solve` 的“纯角域 + 精确顶点枚举 + 无界判定”
是针对问题一的一站式分析工具,不适合直接嵌入带圆盘、负观测和状态更新
的在线闭环。
**差异一句话总结:** 问题一回答“固定角域观测下源可能在哪里、直径圆能否覆盖”,
是纯几何精确解;问题二至四把其中的角域半平面和最小圆升级为“带距离先验的
保守信念 + 主动动作 + 证据证明”的闭环,问题三再加非凸负观测,问题四再加
朝向维度。
## 8. 结论与适用边界
问题一的当前实现是:三条半平面 → 可行顶点枚举/凸包 → 衰退锥判有界 →
顶点对精确直径 → 任意直径中点唯一候选的覆盖检验 → Welzl 最小包围圆与
20 m 证书。其结论只依赖题面有界误差,不引入误差分布假设。空集、无界、
点、线段和多边形状态都有明确输出。
未解决问题一的数值敏感性时,不应把在线闭环里的外包多边形半径直接当成
问题一的精确直径;两者口径不同。反过来,在线闭环也不能把 `solve` 直接套在
$K_1$ 上,因为 $K_1$ 含圆盘和距离上界,边界可能含圆弧。
## 参考文献
1. 全国大学生数学建模竞赛组委会. 2026年高教社杯全国大学生数学建模竞赛B题:无线电干扰源的快速自动定位与清除[Z]. 2026. [本地题面](C:/Users/HelixCopex/code/MATH/issue/B题.pdf),第1页、附录2。
2. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge: Cambridge University Press, 2004. [作者公开版本](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf),第2章。用于凸几何背景,本文的题目化证明在正文给出。
3. WELZL E. Smallest enclosing disks (balls and ellipsoids)[C]//MAURER H. New Results and New Trends in Computer Science. Lecture Notes in Computer Science, vol. 555. Berlin: Springer, 1991: 359–370. [作者公开论文](https://people.inf.ethz.ch/emo/PublFiles/SmallEnclDisk_LNCS555_91.pdf)。用于随机增量最小包围圆算法来源。
4. CGAL Project. CGAL::Min_circle_2: Bounding Volumes[EB/OL]. [在线文档](https://doc.cgal.org/latest/Bounding_volumes/classCGAL_1_1Min__circle__2.html),访问日期:2026-09-10。用于最小圆及支撑点定义的交叉核对。
1. 全国大学生数学建模竞赛组委会. 2026 年高教社杯全国大学生数学建模竞赛 B 题:无线电干扰源的快速自动定位与清除[Z]. 2026. 本地题面 `issue/B题.pdf`。
2. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge University Press, 2004. 凸集、半平面与凸组合背景。
3. WELZL E. Smallest enclosing disks (balls and ellipsoids)[C]//New Results and New Trends in Computer Science, LNCS 555, 1991: 359–370. 随机增量最小包围圆。
4. 本项目. `docs/algo-2.md`(问题二当前实现). 问题二对本文半平面语义与最小圆的复用说明。
5. 本项目. `docs/algo-3.md`、`docs/algo-4.md`. 在线闭环中的保守信念、负观测与联合信念差异。
+238 -174
View File
@@ -1,248 +1,312 @@
# 问题二:具有接收保证的第二检测点选择
# 问题二算法说明:保证接收的第二检测点选择(当前实现)
## 摘要
> 本文按**当前仓库实际运行路径**重写。生产入口是
> `src/mcm26b/planner.select_second_point`,其核心选点器是
> `select_measurement_point`;`src/mcm26b/geometry/planning.py` 中的
> `first_bearing_candidate_disk` 是解析充分证书与独立校核工具,
> 并不在运行时被 `select_second_point` 调用(见 §6 核对结果)。
针对只获得一次全向干扰源示向度的情形,提出以接收保证为约束、以后验最小包围半径为主要指标的主动选点方法。首先将源位置圆域、首次角域与有效接收距离上界相交,构造包含真实源的位置候选集;随后把第二检测点的安全条件写成一族闭圆盘的交,并证明其非空性等价于候选集最小包围半径不超过最小有效接收半径。利用首次角域狭窄的题设特征,进一步推导截断角域的最小包围圆,得到半径约250米、能够直接计算的安全候选圆盘。为比较候选点的定位效果,建立兼顾 `direction` 和 `near` 的保守后验模型,推导交会角的局部几何意义,并给出采用外包多边形及观测区间划分的有限候选评估算法。严格接收保证与启发式性能优化分别陈述,不将有限采样结果解释为连续问题的全局最优解。
## 1. 问题、实现入口与交付物
**关键词:** 主动测向;鲁棒选点;安全候选区域;最坏后验半径;保守几何近似。
问题二给定一个全向干扰源的首次有效示向度 $(s,\theta)$,要求给出第二个
检测点 $q$ 的选择策略、定位效果与候选区域。两个约束必须同时满足:
## 1. 问题界定与思路来源
1. **接收保证**:$q$ 到所有仍可能为真源的位置都不超过有效接收半径下界
$R_-=1000$ m,否则第二次测量可能返回 `no_signal`,几何收益落空;
2. **定位效果**:在保证接收的候选点中,使第二次测量后的保守位置集合
尽量小。当前实现以“最坏后验最小包围半径”为主指标,以移动耗时为次指标。
题目第二问给定某全向干扰源在一个检测点处的示向度,要求提出第二检测点的选择策略、说明其定位效果并给出候选区域。这里的源类型明确为全向,不能混入第四问的朝向可见性条件。[题面第1页问题2](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)
| 层次 | 文件 | 内容 |
| --- | --- | --- |
| 在线入口 | `src/mcm26b/planner/__init__.py::select_second_point` | 由首次 `direction` 构造 $K_1$,返回 `SecondPointPlan` |
| 核心选点 | 同文件 `select_measurement_point` | 任意候选集的保证接收盘内选点 |
| 几何证书 | `src/mcm26b/geometry/planning.py::first_bearing_candidate_disk` | 截断角域解析外包圆与安全候选盘 |
| 信念构造 | `src/mcm26b/belief/__init__.py::BeliefState`、`CandidateRegion` | $K_1$ 的保守凸外包与更新 |
| 对比框架 | `project/q2/{optimal,baseline,reference,region,cases,compare}.py` | 生产选点器 / 两种朴素基线 / 保证盘内网格参考 |
| 回归 | `tests/test_planner.py`、`tests/test_geometry_certificates.py`、`tests/test_belief.py` | 接收保证、后验收缩、near 分支、解析证书 |
| 结果 | `project/results/q2.{md,json}` | 30 个随机首次示向度算例配对结果 |
本问有两个先后不同的问题:第二点是否仍能收到信号;在能收到信号的点中,如何使新测量更有价值。如果只追求较大交会角而不控制到真实源的距离,第二次测量可能返回 `no_signal`,预期几何收益无法实现。因此先构造保证接收的可行域,再优化测向后的不确定区域。
## 2. 首次观测后的候选集 $K_1$
方法来源分为三部分。候选位置集合来自题设有界误差与接收距离,沿用问题一的角域约束;安全选点来自“对每个可能源位置都满足距离条件”的鲁棒可行性;定位收益来自主动测量设计,以最坏后验半径代替未经题面支持的平均误差。凸函数与鲁棒建模的一般背景参见 Boyd 与 Vandenberghe 的《Convex Optimization》第3章、第6.4节;本题的安全圆盘公式、扇形推导及区间评估方法在下文逐步建立。[文献3](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf)
### 2.1 精确定义
需要强调:本题没有给出源位置概率分布,也没有给出可直接使用的独立高斯测向噪声模型。因此不能把卡尔曼滤波、协方差或费舍尔信息计算直接作为严格保证。交会角仍有明确几何意义,但应作为局部解释和候选筛选依据。
记首次检测点为 $s$、首次示向度为 $\theta$、误差半角
$\delta_{\rm eff}=1^\circ+0.005^\circ$(题设误差 + 两位小数舍入裕量),
有效接收半径上界 $R_+=1500$ m,源位置圆域 $\Omega=B(0,1800)$。则
## 2. 符号、题设事实与建模约定
$$
K_1=\Omega\cap W(s,\theta,\delta_{\rm eff})\cap B(s,R_+).
$$
| 符号 | 含义 |
| --- | --- |
| $s$、$\theta$ | 首次检测位置与示向度 |
| $\delta$ | 误差半角,默认 $1^\circ$ |
| $g$ | 未知的全向干扰源位置 |
| $\Omega=B(0,1800)$ | 干扰源位置圆域 |
| $R_g\in[R_-,R_+]$ | 未知有效接收半径,$R_-=1000$、$R_+=1500$ 米 |
| $K_1$ | 首次观测后的保守位置候选集 |
| $q$ | 第二检测点 |
| $\mathcal Q(K_1)$ | 对 $K_1$ 内所有位置均保证接收的第二点区域 |
| $\rho(K)$ | 非空有界集合 $K$ 的最小包围半径 |
| $J(q)$ | 第二点的最坏保守后验半径 |
真实源在合法观测下必属于 $K_1$。注意 $B(s,R_+)$ 的半径是**接收半径上界**:
`direction` 读数本身就隐含测得距离不超过 $R_+$;而 $B(s,R_-)$ 不在 $K_1$
之中,因为第二次是否收到信号正是本问要保证的事。
采用以下题设事实:有效接收半径在1000至1500米之间;检测点到全向源距离不超过5米时无法得到示向度,可直接光学定位并清除;清除距离不超过20米;机器狗移动速度为5米/秒,检测需要5秒,同一频道连续测量不发生额外频道切换。[题面附录2第(2)、(4)至(9)项](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)
### 2.2 实际保守表示
1800米圆域限制的是源位置,不是机器狗的搜索位置。检测点可以位于该圆域外;接口坐标分量的绝对值上限属于数值防护限制,不能误解成要求 $q\in\Omega$。[题面第4页](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)
在线实现不直接处理圆弧边界,而用以下外切多边形表示 $K_1$:
如果把读数舍入额外计入误差预算,可显式采用 $\delta=1.005^\circ$。下文解析推导对 $0\le\delta\le45^\circ$ 成立,但这一扩展区间不是题目误差范围。
- 先取 $\Omega$ 的 192 边外切正多边形 $P_M(0,1800)$;
- 再与 $B(s,1500)$ 的 192 边外切正多边形求交;
- 最后用 Sutherland–Hodgman 逐半平面裁剪两条测向边界。
## 3. 首次观测对应的源位置集合
设圆盘外切多边形相对圆盘的最大径向超出为 $R(1-\cos(\pi/M))$。实现把每次
圆盘裁剪的该量累加到 `CandidateRegion.slack_m`,因此维护的多边形满足
$K_1\subseteq P_{\rm out}$,且 `slack_m` 是可审计的外包半径余量。
设 $u=u(\theta)=(\cos\theta,\sin\theta)$。由第一次有效示向度,真实位置属于前向角域 $W(s,\theta,\delta)$;由已经收到信号,必有 $\lVert g-s\rVert\le R_g\le R_+$;由源位置限制,又有 $g\in\Omega$。故定义 $K_1=\Omega\cap W(s,\theta,\delta)\cap B(s,R_+)$。
这条路径与问题一的区别:问题一在纯角域上枚举边界直线交点,精确处理
空集/无界;问题二候选集一开始就被 $\Omega$ 和 $B(s,R_+)$ 限成有界集,
因此可以只用凸多边形裁剪。角域系数与问题一 `halfplanes` 完全一致:
$\sin(\theta-\delta)x-\cos(\theta-\delta)y\le c$ 与
$-\sin(\theta+\delta)x+\cos(\theta+\delta)y\le c$。
该集合为闭凸紧集。真实观测一致时 $g\in K_1$,所以它非空。首次返回 `direction` 还意味着 $\lVert g-s\rVert>5$,但若把这个开圆盘排除,会破坏凸性。本文暂不使用该排除信息,保留包含真源的凸外包集合;由此得到的保证可能更保守,不会误删真实位置。
## 3. 保证接收区域
这一区别决定了后续结论的口径:本文给出的保证对较大的 $K_1$ 中所有位置成立,因而对实际源成立;但在 $K_1$ 上定义的最坏后验指标可能比利用全部观测细节的精确模型更悲观。
### 3.1 一般集合形式
若计算得到 $K_1=\varnothing$,说明输入、频道、误差界或数值处理与题设不一致。此时应返回不一致状态,不能继续给空集计算圆心。问题一的纯角域求解器也不能直接把上述圆弧边界当作直线边界处理。
对非空紧候选集 $K$,定义
## 4. 安全候选区域的精确定义及基本性质
$$
F_K(q)=\max_{g\in K}\lVert q-g\rVert,\qquad
\mathcal Q(K)=\{q:F_K(q)\le R_-\}=\bigcap_{g\in K}B(g,R_-).
$$
### 4.1 接收距离条件
$F_K$ 是凸函数且 1-Lipschitz,$\mathcal Q(K)$ 是闭凸集。
若第二检测点满足 $\lVert q-g\rVert\le R_-$,由于 $R_g\ge R_-$,即可保证全向源信号能够接收。因此定义 $F_K(q)=\max_{g\in K}\lVert q-g\rVert$,并令 $\mathcal Q(K)=\{q:F_K(q)\le R_-\}=\bigcap_{g\in K}B(g,R_-)$。
**定理 1.** $\mathcal Q(K)\ne\varnothing$ 当且仅当
$\rho(K)=\min_q F_K(q)\le R_-$,其中 $\rho(K)$ 是 $K$ 的最小包围半径。
这里限制的是第二点到所有可能源位置的距离,而不是到第一次检测点的距离。保证接收也不等于保证返回示向度,因为距离不超过5米时可能返回 `near`;该分支的定位效果更好,不能视为策略失败。
证明:$\min_q F_K(q)$ 就是最小包围半径;存在 $q$ 使 $F_K(q)\le R_-$ 与
其最小值不超过 $R_-$ 等价。证毕。
### 4.2 凸性、稳定性和非空条件
### 3.2 多边形外包给出的充分安全盘
**命题1:** 对任意非空紧集 $K$,函数 $F_K$ 为凸函数,且满足 $\lvert F_K(q_1)-F_K(q_2)\rvert\le\lVert q_1-q_2\rVert$。
设在线维护的多边形 $P_{\rm out}\supseteq K$,其最小包围圆为
$B(m,\rho_{\rm out})$。任取
**证明:** 对每个固定的 $g$,距离函数关于 $q$ 凸;逐点取最大值保持凸性。又由三角不等式,$\lVert q_1-g\rVert\le\lVert q_2-g\rVert+\lVert q_1-q_2\rVert$,对 $g$ 取最大值得到一个方向的不等式,再交换两点即得结论。证毕。
$$
q\in B(m,\ R_- - \rho_{\rm out}-\eta),\qquad \eta=10^{-3}\ {\rm m},
$$
因此 $\mathcal Q(K)$ 是闭凸集。非空时,它包含在任一 $B(g_0,R_-)$ 内,所以也有界。
则对任意真源 $g\in K$:
**定理1:** $\mathcal Q(K)\ne\varnothing$ 当且仅当 $\rho(K)\le R_-$。
$$
\lVert q-g\rVert\le\lVert q-m\rVert+\lVert m-g\rVert
\le (R_--\rho_{\rm out}-\eta)+\rho_{\rm out}
=R_--\eta<1000.
$$
**证明:** 最小包围半径的定义为 $\rho(K)=\min_q F_K(q)$。存在 $q$ 使 $F_K(q)\le R_-$,与其最小值不超过 $R_-$ 完全等价。最小值存在,因为 $F_K$ 连续且随 $\lVert q\rVert\to\infty$ 趋于无穷。证毕。
实现中 `safe_disk_radius(region)` 直接返回
$R_--\rho_{\rm out}-10^{-3}$;因为 $\rho_{\rm out}$ 已是包含真实候选集
的多边形最小包围半径,这个盘内的点到真实源的三角不等式上界严格小于
1000 m。1 mm 的数值余量避免浮点贴边被 $r_{\rm eff}=1000$ 的源判成
`no_signal`。若该半径 $<0$,说明当前凸外包的 MEC 半径已超过 1000 m:
当 $\rho(K)=R_-$ 时,安全区域仅包含唯一最小包围圆中心;唯一性可由两个候选中心的中点距离恒等式证明,见[问题一第8节](C:/Users/HelixCopex/code/MATH/docs/algo-1.md)。因此应使用不严格不等式,不能把等号情形误判为空。
- 这**不能**证明真实 $\mathcal Q(K)$ 为空,只说明这个充分证书不够紧;
- 实现退化为探索 MEC 圆心,并在 `reason` 中明确标注“可能 `no_signal`”。
### 4.3 外包圆给出的充分区域
### 3.3 首次截断角域的解析候选盘
若已知 $K\subseteq B(c,r)$ 且 $r\le R_-$,则任意满足 $\lVert q-c\rVert\le R_--r$ 的点,都有 $\lVert q-g\rVert\le\lVert q-c\rVert+\lVert c-g\rVert\le R_-$。因此 $B(c,R_--r)\subseteq\mathcal Q(K)$。
完全去掉 $\Omega$ 后,完整的截断角域
$S=W(s,\theta,\delta)\cap B(s,R_+)$ 有一个精确最小包围圆:
这给出了容易计算的充分候选区域,但一般不等于整个安全区域。一个宽松外包圆若满足 $r>R_-$,只能说明该外包圆不能提供证书,不能证明真实的 $\mathcal Q(K)$ 为空。
$$
c=s+a\,u(\theta),\qquad a=\frac{R_+}{2\cos\delta},\qquad
S\subseteq B(c,a),
$$
## 5. 首次截断角域的解析最小包围圆
对 $0\le\delta\le45^\circ$ 成立。简证:设
$g=s+t\,u(\theta+\varphi)$,$0\le t\le R_+$,
$|\varphi|\le\delta$,则
$\lVert g-c\rVert^2=t^2+a^2-2at\cos\varphi$。固定 $\varphi$ 时该式
关于 $t$ 是凸二次函数,最大值在 $t=0$ 或 $t=R_+$ 处:前者为 $a^2$,
后者不超过 $R_+^2+a^2-2aR_+\cos\delta=a^2$(代入
$a=R_+/(2\cos\delta)$),故 $S\subseteq B(c,a)$。最小性由三点
$s$、$s+R_+u(\theta\pm\delta)$ 的加权距离恒等式给出:权重
$\lambda_\pm=1/(4\cos^2\delta)$、
$\lambda_0=1-1/(2\cos^2\delta)$ 非负且和为 1,且
$c=\lambda_0s+\lambda_+p_++\lambda_-p_-$,故任何覆盖这三点的圆半径
至少为 $a$。于是
### 5.1 坐标变换
$$
\mathcal Q_0=B(c,\ R_- - a)
$$
暂时去掉只会缩小集合的 $\Omega$ 约束,考虑完整截断角域 $S=W(s,\theta,\delta)\cap B(s,R_+)$。平移并旋转,使 $s$ 成为原点、$u$ 成为横轴。其点可写成 $g=s+t\,u(\theta+\varphi)$,其中 $0\le t\le R_+$、$-\delta\le\varphi\le\delta$。
是保证接收的充分候选区域。题设 $\delta_{\rm eff}\le1.005^\circ$ 时:
令 $a=R_+/(2\cos\delta)$,并取 $c=s+au$。
### 5.2 包含性证明
**定理2:** 对 $0\le\delta\le45^\circ$,截断角域 $S$ 的最小包围圆为 $B(c,a)$。
**证明的第一部分:** 对任意 $g\in S$,有 $\lVert g-c\rVert^2=t^2+a^2-2at\cos\varphi$。固定 $\varphi$ 时,右侧关于 $t$ 为凸二次函数,区间最大值在端点取得。当 $t=0$ 时等于 $a^2$;当 $t=R_+$ 时,由 $\cos\varphi\ge\cos\delta$ 得其不超过 $R_+^2+a^2-2aR_+\cos\delta=a^2$。故整个 $S$ 被该圆覆盖。
### 5.3 最小性证明
取角域中的三个点 $p_0=s$、$p_+=s+R_+u(\theta+\delta)$、$p_-=s+R_+u(\theta-\delta)$。它们均在 $B(c,a)$ 的圆周上。
令 $\lambda_+=\lambda_-=1/(4\cos^2\delta)$,$\lambda_0=1-1/(2\cos^2\delta)$。由于 $\delta\le45^\circ$,三权重非负且和为1,直接代入可得 $c=\lambda_0p_0+\lambda_+p_++\lambda_-p_-$。
对任意中心 $z$,利用加权距离恒等式,有 $\sum_j\lambda_j\lVert p_j-z\rVert^2=a^2+\lVert c-z\rVert^2\ge a^2$。若半径为 $r$ 的圆覆盖这三个点,则左侧不超过 $r^2$,故 $r\ge a$。任何覆盖 $S$ 的圆都必须覆盖这三个点,结合第一部分的包含性,得到最小半径恰为 $a$。当 $\delta=0$ 时两个远端点重合,结论退化为长度 $R_+$ 的线段直径圆,仍成立。证毕。
该推导不依赖源位置先验,也不依赖位置概率分布。它给出的是完整截断角域的精确最小圆;与 $\Omega$ 相交后,真实 $K_1$ 的最小圆可能更小。
## 6. 本题可直接采用的第二点候选区域
由 $K_1\subseteq S\subseteq B(c,a)$ 和第4.3节,可取 $\mathcal Q_0=B(c,b)$,其中 $c=s+au$、$a=1500/(2\cos\delta)$、$b=1000-a$。
| 误差半角 | 轴向中心距离 $a$ / 米 | 安全候选半径 $b$ / 米 |
| 误差半角 | 轴向中心距离 $a$ / m | 安全候选半径 $R_- - a$ / m |
| --- | ---: | ---: |
| $1^\circ$ | 750.114246 | 249.885754 |
| $1.005^\circ$ | 750.115391 | 249.884609 |
两种口径下 $b>0$,故本题首次有效测向后的安全候选区域可以直接证明非空。无需将“若安全区域为空就去最小圆圆心”作为正常流程的保底步骤。
该解析盘由 `first_bearing_candidate_disk` 实现并测试。它给出的是
$S$ 的最小圆;由于 $K_1\subseteq S$,$B(c,R_- - a)\subseteq\mathcal Q(K_1)$
是严格充分的。实际在线路径使用比 $S$ 更紧的 $K_1$ 凸外包,因此其安全盘
通常大于该解析下界(例:`q2-4200` 的 $\rho_{\rm out}=674.59$ m,
安全盘半径 325.41 m,而解析下界约 249.89 m)。
几何上,$\mathcal Q_0$ 位于首测示向方向前方约750米,以约250米为半径。位于圆盘轴向前后端的点、两侧横向点以及圆心都保证接收。横向点只是可供比较的候选点,并未被证明总是最优。
## 4. 实际选点算法
为抵消坐标计算和动作提交中的工程舍入,可取缩小区域 $\mathcal Q_\eta=B(c,b-\eta)$,其中 $0<\eta<b$。若圆心和提交位置合计偏差不超过 $\eta$,三角不等式保证仍有 $\lVert q-g\rVert\le1000$。例如先取 $\eta=0.01$ 米属于可调工程选择,不是题面要求,也不是未分析数值误差的自动上界。
### 4.1 入口伪代码
若有更精细的 $K_1$ 外包圆,可得到更大的充分区域;若精确处理其圆弧边界,也可直接搜索 $\mathcal Q(K_1)$。这些扩展是性能优化,不影响 $\mathcal Q_0$ 的正确性。
```text
select_second_point(client, s, theta):
region = CandidateRegion.initial(s) # Ω ∩ B(s,1500) 的外包
region.clip_wedge(s, theta, 1.005°) # 交入首次角域
return select_measurement_point(region, client.position)
## 7. “较好的定位效果”的数学定义
select_measurement_point(region, from_position):
(m, rho) = region.mec() # Welzl 最小包围圆
safe = 1000 - rho - 1e-3
if safe < 0: return MEC 圆心(探索,可能 no_signal)
候选 = {m} ∪ {m + f*safe*(cos ψ, sin ψ)}
f ∈ {0.4, 0.75, 1.0}, ψ 取 12 个均匀方向
对每个候选 q:
最坏后验 = max( 方向分支、near 分支 )
分数 = (最坏后验, 移动时间)
取分数最小的 q
用 1/4 间距加密复核 q 的最坏后验
return q、最坏后验半径、移动耗时、理由
```
### 7.1 保守后验集合
当前 `search.candidate_rings=(0.0,0.4,0.75,1.0)`、`candidate_angles=12`,
去重后实际是 **37 个候选点**(圆心 + 3 环 × 12 方向)。所有点严格属于
保证接收盘,因此第二次测量不会因距离不足返回 `no_signal`。
对候选点 $q\in\mathcal Q_0$,若返回 `direction` 及示向度 $\beta$,定义保守后验 $K_d(q,\beta)=K_1\cap W(q,\beta,\delta)$。这里继续忽略距离大于5米所提供的非凸排除信息。真实源一定属于 $K_d$。
### 4.2 最坏后验评估
若返回 `near`,定义 $K_n(q)=K_1\cap B(q,5)$,故 $\rho(K_n(q))\le5$。在此分支直接以当前位置进行光学定位和清除,满足20米的清除条件,不必强行再取得一个角度。
对候选点 $q$,最坏后验半径按以下有限枚举计算:
设圆周角距离为 $d_{\mathbb S^1}(\alpha,\beta)=\min_{k\in\mathbb Z}\lvert\alpha-\beta+360^\circ k\rvert$。对 $\lVert g-q\rVert>5$ 的候选位置,令真实方位为 $h_q(g)=\operatorname{atan2}(g_y-q_y,g_x-q_x)$。可能出现的读数集合定义为 $\mathcal B(q)=\{\beta:\exists g\in K_1,\ \lVert g-q\rVert>5,\ d_{\mathbb S^1}(\beta,h_q(g))\le\delta\}$。
1. 在候选集边界上以 `witness_spacing_m=60` m 采样见证点
$g$(`region.witnesses`,含全部顶点);
2. 对每个 $g$,真实方位 $\phi=\operatorname{bearing}(q,g)$,枚举允许的
读数区间端点 $\phi\pm\delta_{\rm eff}$;
3. 对每个端点,复制候选多边形并用 `clip_wedge(q, 读数, δ_eff)` 得到后验
凸外包,记录其 MEC 半径;
4. 额外处理 `near` 分支:以 $B(q,5)$ 裁剪候选集,若交集非空,记录其 MEC
半径;它代表“源离第二点不超过 5 m,直接光学定位清除”的分支;
5. 以上全部有效半径取最大值,就是该候选点的评估值。
这里用所有允许误差描述可能读数,不是假设各地点的误差可以随机独立重抽样。同一个位置的重复检测不产生新的独立信息;所构造的 $\mathcal Q_0$ 与首测位置相距至少约500米,天然避免原地重复测量。
该评估是**启发式上界近似**:它只对目标边界采样和读数区间端点取值,
没有覆盖连续集合上所有可能读数;但它可在候选点之间做一致比较。
1/4 间距(15 m)的加密复核只提高输出数值的可信度,不改变“采样启发式”
这一事实。定理 1 保证接收,选点最优性没有全局证明。
### 7.2 最坏后验半径指标
### 4.3 清除与 `near`
定义 $J(q)$ 为所有可能 `direction` 分支的 $\rho(K_d(q,\beta))$,以及非空 `near` 分支的 $\rho(K_n(q))$ 的上确界。等价地,它是未来所有允许观测下最坏的保守最小包围半径;不存在的观测分支不参与取最大值。
若第二次测量返回 `near`,源在 $q$ 的 5 m 内。由 `clear_certificate`:
候选集 $B(q,5)$ 的 MEC 半径至多略大于 5 m(外包多边形余量很小),
工程余量后仍远小于 20 m,因此可以在当前位置直接 `/clear`,不需要再取
第三个测向读数。若返回 `direction`,则用新角域更新 $K$ 并继续按
问题三/四的定位流程处理;后验半径若仍大于 20 m,**不能**声称两次定位
已经完成。
选点的主要目标为在安全候选区域中降低 $J(q)$。该指标直接服务于一次清除要求:若 $J(q)\le20$,则每个可能分支都有半径不超过20米的保守定位圆。它比仅比较面积更符合任务,因为面积较小的集合仍可能十分狭长。
## 5. 参数与复杂度
对于任意有效分支,后验都是 $K_1$ 的子集。集合包含关系给出 $\rho(K_2)\le\rho(K_1)$,故 $J(q)\le\rho(K_1)$。但不一定严格小于,因此不能仅由“增加一次观测”推断定位精度必然严格改善,更不能保证只需两次测向便达到20米阈值。
| 参数 | 默认值 | 作用 |
| --- | ---: | --- |
| `polygon_sides` | 192 | 圆盘外切多边形边数;$\Omega$ 处径向超出约 0.24 m |
| `bearing_rounding_margin_deg` | 0.005° | 两位小数舍入的显式裕量 |
| `witness_spacing_m` | 60 m | 粗评边界见证间距 |
| `candidate_rings` | (0, 0.4, 0.75, 1.0) | 安全盘内半径比例 |
| `candidate_angles` | 12 | 每环方向数;连同圆心共 37 个候选 |
| `near_radius_m` | 5 m | `near` 分支判定 |
| `clear_margin_m` | 0.5 m | 清除证书的额外工程余量 |
### 7.3 移动成本的引入
若候选集顶点数为 $m$、候选点数为 $N_q$、边界见证数为 $N_g$,单次选点的
粗评估约为 $O(N_qN_g\cdot{\rm clip}+N_q{\rm MEC})$,`clip` 为
Sutherland–Hodgman 裁剪的 $O(m)$ 代价;再加一次 1/4 间距加密复核。
这是明显可并行/缓存的小规模在线计算,不追求全局最优。
连续测量同一频道时,本次动作的虚拟时间增量为 $C(q)=\lVert q-s\rVert/5+5$ 秒。推荐先按后验半径择优,再在几何效果接近的候选点中比较移动成本,以避免任意混合米和秒。
## 6. 实现核对结果:文档旧说法与当前运行路径的差异
用 $\widehat J(q)$ 表示实际计算的评估量,在第10节的保守方案中取为上界 $\overline J(q)$。设有限候选点中的最小评估值为 $J_{\min}$。可先保留满足 $\widehat J(q)\le J_{\min}+\tau$ 的点,再选择其中 $C(q)$ 最小者,其中 $\tau\ge0$ 是显式给定的定位容忍量,单位为米;$\tau=0$ 对应严格的字典序选择。本文不预设一个未经实验支持的最优 $\tau$。
早期说明只写到 `geometry/planning.py` 的解析候选盘,容易让人误以为
`select_second_point` 直接调用它。当前代码的实际情况是:
## 8. 交会角的局部几何解释
- `select_second_point` 构造 `CandidateRegion`($\Omega\cap B(s,1500)$ 的
192 边形外包)并用 `clip_wedge` 交入首次角域;
- 真正的选点发生在 `select_measurement_point`:它在上述凸外包的 MEC
保证盘内做 37 点候选评估;
- `first_bearing_candidate_disk` 是解析证书函数,用于证明
$B(s+au,1000-a)$ 的充分性,并被
`tests/test_geometry_certificates.py` 以稠密角域采样校核;
- 生产路径不调用 `first_bearing_candidate_disk`,但两者给出同一性质的
保证:选出的点必能收到 `direction`/`near`。生产路径通常比解析盘更紧,
因为它利用了 $K_1$ 完整形状而不是仅用其外包扇区。
在某个假定真实位置 $g$ 附近,令两站距离为 $r_1,r_2$,真实视线单位向量为 $u_1,u_2$,对应法向量为 $n_1,n_2$。当角误差很小且位置扰动相对站距较小时,方位函数的一阶展开给出 $n_i\cdot\Delta g\approx r_i e_i$,其中 $e_i$ 用弧度表示,满足 $\lvert e_i\rvert\le\delta_{\rm rad}$。
因此,问题二的**严格保证**来自“安全盘点到候选集所有点的距离 $\le R_-$”,
解析盘是充分但不唯一的一种实现方式;**最优性**来自有限候选评估,
两者必须在说明中分开陈述。
于是局部不确定区域近似由两条带状约束限定:$\lvert n_1\cdot\Delta g\rvert\le r_1\delta_{\rm rad}$、$\lvert n_2\cdot\Delta g\rvert\le r_2\delta_{\rm rad}$。若视线交会角为 $\phi$,法向量矩阵的行列式绝对值为 $\lvert\sin\phi\rvert$。对法向坐标中的矩形作线性逆变换,得到近似面积 $A_{\rm loc}\approx4r_1r_2\delta_{\rm rad}^2/\lvert\sin\phi\rvert$。
## 7. 已验证结果
这解释了两点:近于平行或反向的视线使误差显著放大;在距离不变的局部比较下,接近直角的交会较有利。然而真实源位置未知,$r_2$ 和 $\phi$ 随 $g$ 改变,且有限角域并非无限带状区域。因此不能由该近似推出“总应横移固定距离”或“在某个假定源位置形成90度就是全局最优”。本文只将其用于优先考虑轴线两侧候选点,最终仍以后验集合指标评价。
`project/q2` 在 30 个随机首次示向度算例上,用同一 $K_1$、同一评估器
对四种方法配对比较(初始 $\rho$ 均值 681.47 m):
## 9. 圆弧先验的保守离散
| 方法 | 保证接收率 | 最坏后验均值 | 终值比 $\rho'/\rho$ | 平均移动 | 结论 |
| --- | ---: | ---: | ---: | ---: | --- |
| 生产选点器(保证盘内最小最坏后验) | **100%** | **73.89 m** | **0.104** | 170.4 s | 保证接收且后验最小 |
| 基线① 垂直 1000 m 最大交会角 | **0%** | 80.11 m | 0.116 | 200.0 s | 忽略接收距离,真源在远端必 `no_signal` |
| 基线② 直接取 MEC 圆心 | 100% | 340.75 m | 0.500 | 136.3 s | 保证接收但几乎不收缩 |
| 独立参考:保证盘内 9×9 网格枚举 | 100% | 75.63 m | 0.106 | 170.3 s | 生产采样接近网格最优 |
### 9.1 外包切线多边形
代表性单例 `q2-4200`:
直接将圆周采样点连接得到的是内接多边形,会错误排除圆盘边缘的真实位置。为了复用第一问的半平面工具,选择 $M\ge3$ 个均匀法向量 $v_j=u(2\pi j/M)$,定义 $P_M(o,R)=\{x:v_j\cdot(x-o)\le R,\ j=0,\ldots,M-1\}$。
| 指标 | 数值 |
| --- | ---: |
| $K_1$ MEC 圆心 | (1172.85, −225.68) |
| $K_1$ MEC 半径 $\rho$ | 674.59 m |
| 保证接收盘半径 | 325.41 m |
| 选中第二点 | (1257.07, 88.64) |
| 最坏后验半径 | 54.45 m |
| 移动耗时 | 181.42 s |
由柯西不等式,任意 $x\in B(o,R)$ 都满足所有约束,因此 $B(o,R)\subseteq P_M(o,R)$。相邻切线交点到圆心的距离为 $R\sec(\pi/M)$,故单个圆盘外包的最大径向超出不超过 $R[\sec(\pi/M)-1]$。
## 8. 与问题一及问题三/四的关系(核对结果)
令 $\widetilde K_1=P_M(0,1800)\cap W(s,\theta,\delta)\cap P_M(s,1500)$,便有 $K_1\subseteq\widetilde K_1$。对任何第二读数再求半平面交,仍然保留真实源。上述单圆径向误差不能未经论证直接当成最终定位半径的误差界;靠近切触或退化时尤其需要加密检查。
| 对比 | 问题一 | 问题二(本文) | 问题三/四中的去向 |
| --- | --- | --- | --- |
| 信息模型 | 纯角域 $W$ | 角域 $W$ + 距离先验 $K_1=\Omega\cap W\cap B(s,R_+)$ | 问题三在任意后验 $K_c$ 上重复使用;问题四再叠加朝向维度 |
| 求解方式 | 枚举半平面边界交点、凸包、精确直径 | 圆盘外切多边形 + Sutherland–Hodgman 裁剪 | 问题三/四沿用 `CandidateRegion` 凸外包 |
| 决策类型 | 对固定观测做几何分析 | 主动选择下一个测量点 | 问题三是多源闭环;问题四是混合源闭环 |
| 主要输出 | 直径与直径圆覆盖 | `SecondPointPlan`(位置、最坏后验、移动耗时) | 问题三把它推广到定位子过程;问题四把它作为联合信念选点的基础候选之一 |
| 保证口径 | 几何精确(在输入模型内) | 接收严格保证;最坏后验是采样启发式 | 清除证书严格;选点与调度是启发式 |
安全选点仍使用第6节的解析 $\mathcal Q_\eta$。即使粗糙外包多边形的最小圆偏大,也不能据此推翻解析安全区域的非空结论。
关键区别:
### 9.2 多边形安全区域的可选扩展
1. 问题二不直接复用问题一的 `solve`,而是复用其角域语义和
`smallest_enclosing_circle`;候选集多出圆盘和距离上界,不能当作
“纯角域问题一”处理。
2. 问题一的输出是直径和直径圆,问题二的清除判断改用最小包围半径
$\rho\le20$;直径圆本身不参与在线清除。
3. 问题三对同一个 `select_measurement_point` 做任意后验集上的复用,
但同时引入网格粒子滤波处理 $K$ 无法表示的负观测(`no_signal`);
问题二没有负观测更新,因为它假设第二次测量点已在保证接收盘内。
4. 问题四不能直接使用“安全盘内必收到信号”的结论:定向源在安全盘内
也可能因朝向遮挡返回 `no_signal`。问题四保留问题二的安全盘作为
基础候选,但新增(位置 × 朝向)联合信念来判断可见性(见
`algo-4.md`)。
若采用任意有界凸外包多边形 $\widetilde K=\operatorname{conv}\{v_j\}$,则 $\max_{g\in\widetilde K}\lVert q-g\rVert=\max_j\lVert q-v_j\rVert$,证明与第一问的凸组合论证相同。因此其保证接收区域由有限个约束 $\lVert q-v_j\rVert\le1000$ 给出,是圆盘交。
## 9. 结论
也可先解最小包围圆问题,再构造充分安全圆盘。由于 $\widetilde K$ 是外包集合,得到的区域可能更小,但其中每个点仍安全。若该离散区域为空,优先加密或回到解析候选盘,不把离散失败误报为真实问题无解。
问题二的当前实现可以概括为:
## 10. 未来读数的保守区间评估
- **候选集**:$K_1=\Omega\cap W(s,\theta,\delta_{\rm eff})\cap B(s,R_+)$,
用 192 边形外包圆盘 + 半平面裁剪保守维护;
- **保证接收**:$B(m,R_--\rho_{\rm out}-10^{-3})$ 内的点必不返回
`no_signal`;解析扇区最小圆给出可独立复核的充分候选盘
$B(s+au,1000-a)$,$a=1500/(2\cos\delta)$;
- **选点**:在保证盘内取 37 个候选,以边界见证点 × 读数端点的最坏后验
包围半径为第一指标、移动时间为第二指标,选出后再做 1/4 间距加密复核;
- **清除**:若第二次返回 `near`,直接就地清除;否则把新角域交入后验,
未达到 20 m 证书前继续测量。
直接枚举少量假定源位置和误差端点,只得到被枚举情形的最大值,可能漏掉真正最坏读数。为了使评估输出具有上界意义,可以划分全部可能方位角,而非仅点采样。
将整周按圆周意义划分为若干区间 $I_j$,中心为 $\beta_j$,宽度为 $h_j$,要求 $\delta+h_j/2<90^\circ$。跨越 $0^\circ$ 的区间按圆周距离处理。
**命题2:** 对任意 $\beta\in I_j$,有 $W(q,\beta,\delta)\subseteq W(q,\beta_j,\delta+h_j/2)$。
**证明:** 对左侧任意非顶点位置,其方向到 $\beta$ 的圆周距离不超过 $\delta$;而 $\beta$ 到区间中心的距离不超过 $h_j/2$。由圆周距离的三角不等式,其方向到中心的距离不超过两者之和。顶点在两个闭角域中均被保留。证毕。
因此定义 $U_j(q)=\widetilde K_1\cap W(q,\beta_j,\delta+h_j/2)$,则任何落在该区间的真实读数所对应的保守后验,都包含于 $U_j(q)$,从而 $\rho(K_d(q,\beta))\le\rho(U_j(q))$。
对于 `near` 分支,可以取统一上界 $\min\{5,\rho(\widetilde K_1)\}$。该上界不需要精确计算圆弧交集;即使某点实际不会触发 `near`,纳入此上界只增加保守性。
令 $\overline J(q)$ 等于所有非空 $U_j(q)$ 的最小包围半径,以及上述 `near` 上界的最大值,即得到 $J(q)\le\overline J(q)$。该结论在精确几何计算下成立。浮点实现还需给出包含性和数值误差处理,不能把无误差预算的计算值称为机器可验证的严格上界。
通过将某个角区间二分,子区间扩张后的角域包含于父区间的扩张角域,所以相应方向上界不会增大。通过保留旧切线并增加新切线,也可使外包多边形嵌套缩小。这给出稳定的自适应加密方向,但没有在本文中证明连续选点的统一收敛速率。
该评估可能较慢,实际可先用少量读数采样粗筛,再对入围点使用完整角区间上界。前一阶段仅决定计算资源分配;最后报告的保守上界必须来自完整覆盖的区间,不能来自粗筛样本最大值。
## 11. 可执行的第二点选择算法
**算法2:安全区域内的有限候选主动测向。**
1. 输入 $s,\theta,\delta$,核验首次观测为同一全向源的有效示向度,构造 $K_1$ 或其保守表示。
2. 计算 $a=1500/(2\cos\delta)$、$c=s+au(\theta)$、$b=1000-a$,选择满足误差预算的缩小半径 $b-\eta$。
3. 构造有限候选集:包含圆心 $c$,并取 $q_{\ell j}=c+r_\ell[\cos\psi_j\,u+\sin\psi_j\,u_\perp]$,其中 $0<r_\ell\le b-\eta$、$\psi_j=2\pi j/N_\psi$、$u_\perp=(-\sin\theta,\cos\theta)$。所有候选点自动满足接收距离保证。
4. 对每个候选点构造第9节的外包后验,按第10节评估 $\overline J(q)$,保存最坏角区间及对应包围圆作为评估依据。
5. 优先选择 $\overline J$ 较小的点;按预先声明的 $\tau$ 筛选近优点,再按移动检测代价选择,必要时用固定顺序消除完全同分。
6. 在现实计算预算内,对入围候选附近加密位置、细分最坏角区间并增加外包切线。保留当前已验证安全的可用点,预算耗尽时返回当前结果。
7. 在所选位置测量同一频道。若为 `near`,在当前位置清除;若为 `direction`,用实际读数更新候选集合并复算最小包围圆;若其半径仍大于20米,继续后续测向,不能宣称两次定位已经完成。
8. 若在距离保证条件下意外得到 `no_signal`,核查动作是否被接受、频道是否正确、源是否仍存在及坐标和模型是否一致。未知原因解决前不按正常 `direction` 分支更新位置候选。
例如可从3层半径、每层16个方向及1个圆心开始,共49个候选点;这是位置搜索的数值分辨率示例,与第三问49点全域覆盖网格无关,也不是已优化参数。外包切线数、角区间宽度、加密次数及 $\tau$ 均应在论文实验部分显式记录。
设候选数为 $N_q$、角区间数为 $N_\beta$、每个后验的半平面数为 $k$。复用第一问的边界枚举时,主计算量约为 $O(N_qN_\beta k^3)$,另加顶点直径或最小圆计算。该方法提供清楚的正确性结构,但需通过缓存首次约束、局部加密和计算预算控制实现成本。不能用“只需一次新的测量”忽略选点器自身的运行时间。
算法输出保证的是:所选点位于已证明安全的区域,并在给定有限候选及评估精度下按既定规则择优。本文未证明 $q\mapsto J(q)$ 是凸函数,也未证明有限候选的最优点就是整个 $\mathcal Q(K_1)$ 中的全局最优点。
## 12. 边界情形与适用范围
| 情形 | 正确处理 |
| --- | --- |
| $K_1$ 为空 | 报告模型或数据不一致,不构造虚假圆心 |
| 首次结果已经为 `near` | 直接清除,不再套用“已知示向度”的第二问流程 |
| 一般集合满足 $\rho(K)=1000$ | 安全区域为最小包围圆中心这个单点 |
| 一般集合满足 $\rho(K)>1000$ | 不存在对该集合全部位置保证接收的点;圆心仅是最小化最坏距离的探索选择 |
| 外包圆半径大于1000 | 只能判定该证书不足,不能直接判真实安全区域为空 |
| 测量轴接近 $0^\circ/360^\circ$ | 使用向量约束和圆周区间,避免角度断点错误 |
| 两次测向交会较差 | 保留完整后验并继续测量,不将小面积当成小直径 |
| 源类型为定向 | 距离证书仍成立,但接收还受朝向限制,不能直接沿用本问的接收保证 |
对于一般集合无安全点的情形,最小包围圆中心确实解 $\min_q\max_{g\in K}\lVert q-g\rVert$,但其最坏距离仍可能大于1000米。改善交会角若要求偏离该中心,还会牺牲最坏距离最优性,必须明确是另一个多目标探索策略,不能把两项互相冲突的要求同时称为已保证。
## 13. 验证设计及当前实现边界
本问的验证分为数学证书与策略性能两层。数学层检查:截断角域被解析圆覆盖;安全候选到所有允许位置的距离不超过1000米;外包离散不删除真实点;角区间扩张包含所有区间内读数。数值抽样只能辅助检查这些证明,不能取代它们。
性能层应在相同自建源位置与确定的空间误差场上,比较轴向点、两个横向点、有限候选最坏后验策略。误差场在同一位置保持固定;不得让每次调用重新独立生成误差。记录第二次测量类型、后验直径和包围半径、额外移动、计算耗时及是否达到20米清除阈值。至少包含误差边界、源域边界、接收半径1000米、近距离和近共线案例。没有这些实验前,不报告未经验证的性能提升比例。
目前 [planning.py](C:/Users/HelixCopex/code/MATH/geometry/planning.py) 中的 `first_bearing_candidate_disk` 已实现第5至6节的解析证书;问题一内核可用于纯半平面区域的顶点和最小圆计算。**本仓库第二问交付的定位是"安全选点的启发式基线"**:解析安全候选盘证书已实现并证明(选中点必能收到信号),而选点评分采用边界采样点 × 读数区间端点的有限枚举近似(含 near 分支)。第9至11节描述的完整选点器数学方案,特别是第10节覆盖全部未来读数的保守区间上界,尚未在现有仓库中实现;采样最大值只用于候选点之间的相对比较与粗筛,不得当作严格最坏情形上界报告,也没有相应正式成绩。该实现边界不影响解析候选区域的证明。
对后续实现而言,应新增接收任意半平面约束的交集入口,或使用独立的多边形裁剪函数,再复用第一问的最小包围圆。不能把圆盘先验伪装成额外测向观测传入现有 `solve(measurements)` 接口。
## 14. 结论
第二问的候选区域可以明确取为前方约750米处、半径约250米的圆盘,其解析式为 $\mathcal Q_0=B(s+au(\theta),1000-a)$,其中 $a=1500/(2\cos\delta)$。这一候选区域对题设全向源提供接收保证,且在首次有效测向条件下严格非空。
在该区域内,以最坏保守后验最小包围半径为主指标、移动代价为次指标,采用有限候选和逐步加密进行选择。交会角解释局部几何优劣,外包多边形和读数区间扩张保证不低估相关后验集合;全局最优和“两次即可清除”均不作为未经证明的结论。
严格保证与启发式性能优化在文档和代码中始终分开:接收保证有证明,
全局最优性没有证明;后者依赖自建的有限候选与固定评估口径。
## 参考文献
1. 全国大学生数学建模竞赛组委会. 2026年高教社杯全国大学生数学建模竞赛B题:无线电干扰源的快速自动定位与清除[Z]. 2026. [本地题面](C:/Users/HelixCopex/code/MATH/issue/B题.pdf),问题2、附录2及第4页坐标约束。
2. 模拟器配套材料. 附件2:模拟器通信接口说明及编程指南[Z]. 2026. [本地附件](C:/Users/HelixCopex/code/MATH/issue/附件/附件2.docx)。用于 `direction`、`near`、`no_signal` 等程序观测字段与动作接口的对应。
3. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge: Cambridge University Press, 2004. [作者公开版本](https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf),第3章、第6.4节。用于凸性及鲁棒建模的一般背景,不作为本题候选圆盘公式的出处。
4. 本项目. 问题一:有界测向误差下定位区域的直径与圆覆盖[Z]. 2026. [algo-1.md](C:/Users/HelixCopex/code/MATH/docs/algo-1.md)。用于角域半平面表示、顶点判定和最小包围圆的衔接。
**来源说明:** 第5节的截断角域最小圆及第6节的安全圆盘,是结合题设参数在本文中推导的结果;第8节的交会角关系由方位函数一阶展开推得;第9至11节是据集合包含关系构造的保守计算方案。以上陈述说明本项目的推导路径,不宣称这些一般几何思想在既有文献中首次出现。
1. 全国大学生数学建模竞赛组委会. 2026 年高教社杯全国大学生数学建模竞赛 B 题[Z]. 2026. 本地题面 `issue/B题.pdf`。
2. 模拟器配套材料. 附件 2:模拟器通信接口说明及编程指南[Z]. 2026. 本地附件 `issue/附件/附件2.docx`。
3. BOYD S, VANDENBERGHE L. Convex Optimization[M]. Cambridge University Press, 2004. 凸性、最坏情形与鲁棒可行性背景。
4. 本项目. `docs/algo-1.md`(问题一当前实现与复用差异)。
5. 本项目. `docs/algo-3.md`、`docs/algo-4.md`(选点器在后续问题中的推广与边界)。
+6
View File
@@ -1,5 +1,11 @@
# 算法说明:问题3 贝叶斯闭环(`bayes` 策略)
> **历史补充文档.** 当前规范算法、最新默认参数与现行成绩口径见
> [`algo-3.md`](algo-3.md);本文保留 2026-09-11 的设计与消融细节,
> 其中 `lambda_move_s=0.0105`、站点环半径 1200 m 等数字可能已被
> 后续回填(现行默认见 `config.BayesConfig`,λ=0.05、环半径 1159.7 m)。
> 两者冲突时以代码与 `algo-3.md` 为准。
对应实现:`src/mcm26b/particles.py`(感知层)、`src/mcm26b/planner/bayes_loop.py`
(决策层)、`scripts/benchmark_q3_bayes.py`(消融)、`scripts/tune_q3_bayes.py`
(Optuna 调参)。基线对比:`docs/algo-3.md` 的七点批量(`seven`,A2)。
+422 -380
View File
@@ -1,414 +1,456 @@
# 问题三:具有覆盖证明的多源搜索与总耗时优化
# 问题三算法说明:全向多源搜索的覆盖证明、贝叶斯闭环与任务调度(当前实现)
## 摘要
> 本文汇总当前仓库中问题三的全部实际算法,生产默认策略为
> `src/mcm26b/planner/bayes_loop.py::BayesLoop`(CLI 策略名 `bayes`)。
> `grid`(`OmnidirectionalLoop`,49 点)与 `seven`
> (`SevenBatch`,七点解析覆盖 + 本站批量)保留为可复现对照。
> 问题三当前生产不包含任何机器学习策略;历史 HRL/RL 代码已移除,
> 自建消融中手写基线稳定优于学习策略(见 `docs/第三四问架构优化与运行提速方案.md`)。
针对源数为10至16、频道互异、位置未知的全向无线电干扰源,建立“发现—定位—清除—完整性证明”的在线决策模型,以全部清除为约束、以移动、检测、换频道和清除的虚拟总耗时为优化目标。沿用问题一的角域交与最小包围圆、问题二的安全接收区域,将改进重点放在全域覆盖规模与多源任务调度。首先从官方演练日志识别移动与无源频道验证的主要开销;随后证明中心加六个环形检测点即可覆盖题设圆域,并提出同站批量扫频、发现任务入队、就近定位清除的可执行基线。进一步规划利用无信号观测维护剩余区域、复用顺路检测点、优化安全清除位置及滚动比较剩余任务耗时的方法。给出停止条件、几何保守性、算法复杂度和分阶段验收方案。12个自建场景的配对消融表明,七点批量策略全部清除成功,平均逐局虚拟时间降幅为58.55%;该结果用于选择下一步实现方向,不作为官方成绩或全局最优性证明。
## 1. 问题定位与策略族
**关键词:** 全向源搜索;覆盖证书;集合定位;任务调度;虚拟总耗时;滚动规划。
问题三中每局有 $10\sim16$ 个全向干扰源,位置未知、频道互异(1..20),
源位于 $\Omega=B(0,1800)$ 内;有效接收半径 $r_{\rm eff}$ 未知,但满足
$1000\le r_{\rm eff}\le1500$ m。策略端只能看到协议响应
(`direction` / `near` / `no_signal`),目标是发现、定位并清除全部源,
使虚拟总耗时尽量小,同时给出“不存在漏源”的证明或明确未完成。
> **延伸实现(2026-09-11)**:本文规划的无信号负观测更新、开放路径 2-opt
> 任务排序等已落地为贝叶斯闭环策略 `bayes`(网格幸存集滤波 + 信息增益
> 选点 + 滚动任务调度,参数经 Optuna 回填),自建消融相对本文七点批量
> 策略平均虚拟时间再降 30.0%(均值 3726s)。设计、严格性证明与消融数据
> 见 [algo-3-bayes.md](algo-3-bayes.md)。
| 策略 | 类 | 发现保证 | 定位/决策 | 角色 |
| --- | --- | --- | --- | --- |
| `grid` | `OmnidirectionalLoop` | 700 m 方格 49 点,单元对角 $700\sqrt2\approx989.95\le1000$ | 发现后立即就近定位,无信息增益 | 历史基线 |
| `seven` | `SevenBatch` | 原点 + 半径 1200 m 六等分环,解析覆盖界 968.90 m | 本站先扫频,再按候选集 MEC 圆心最近服务队列 | A2 中间对照 |
| `bayes` | `BayesLoop` | 七站环(默认半径 1159.7 m,界 984.54 m)+ PF 负观测 | 网格粒子滤波 + 信息增益选点 + 滚动任务排序 | **生产默认** |
## 1. 问题界定与思路来源
七站族还有 `SevenImmediate`(A1,发现即离站)与 `SevenSweep`
(A3,先扫完全域再统一服务)。它们的差异只在发现/定位的调度顺序,
七点覆盖证明与距离语义相同。
第三问要求在不知道干扰源位置和具体数量的条件下,自动发现并清除全部全向源,尽量缩短总时间。每个频道最多一个源,因此本题的数据关联由频道确定;机器狗无需解决无法区分多个信号身份的问题。源位于半径1800米的圆域内,最小有效接收半径为1000米。这两个尺度之间的关系使稀疏、有证明的覆盖成为可能。[题面](C:/Users/HelixCopex/code/MATH/issue/B题.pdf)、[接口规则](C:/Users/HelixCopex/code/MATH/docs/协议规则表与状态机.md)
### 1.1 统一计时模型
本文与前两问分工如下:问题一回答“当前观测允许源在哪里、能否一次清除”;问题二回答“下一次去哪里测才安全且有效”;问题三回答“先搜哪些位置、扫哪些频道、何时中断搜索去清除,以及何时能够确信任务结束”。全局调度会调用前两问的几何内核,但不能只把第二问的局部精度目标逐个重复就视为总时间优化。
忽略微秒量化时,一次动作回合的虚拟耗时为
参考本项目[问题3—4论文列表](C:/Users/HelixCopex/code/MATH/docs/B题问题3-4相关论文列表.md),选取并核对以下相关思想。
$$
T=\frac{L}{5}+5N_m+N_s+5N_c^++3N_c^-,
$$
| 来源 | 本文借鉴的内容 | 与本题的区别 |
其中 $L$ 为移动距离(速度 5 m/s),$N_m$ 为检测次数,$N_s$ 为换频次数,
$N_c^+$ 为成功清除次数,$N_c^-$ 为失败清除次数。`/clear` 本身不切换
测向频道,`/exit` 不增加虚拟时间,访问顺序是起点固定、终点自由的**开放
路径问题**,不是必须回到原点的 TSP 回路。官方内部按整数微秒累计,项目用
`evaluation.recompute_virtual_time` 逐动作复算并校验。
## 2. 三层在线架构
`BayesLoop` 在 `OmnidirectionalLoop` 的会话/预算/收尾骨架上重构为三层:
1. **保证层**:七点覆盖账本 `CoverageLedger` + 解析覆盖定理;负责
“全测无信号 $\Rightarrow$ 该频道不存在源”。
2. **信念层**:
- 凸候选集 `CandidateRegion`(正观测方向/近距离约束,用于清除证书);
- 网格幸存集 `ChannelParticles`(正/负观测统一更新,用于缺席证明、
跳测与信息增益);
- 两者同读一套响应流,任何一方证毕即结束该频道。
3. **决策层**:统一任务表(站点扫频 / 定位测量 / 清除),开放路径
最近邻 + 2-opt 滚动重排;每执行一个任务后用真实响应重规划。
问题三不复用问题四的(位置 × 朝向)联合信念;`no_signal` 在全向源上
可以排除 $B(s,1000)$。
## 3. 证据层:逐频道候选集与负观测
### 3.1 凸候选集 `CandidateRegion`
对每个已收到过有效信号的频道 $c$ 维护凸多边形 $P_c^{\rm out}$:
- 初始为 $\Omega$ 的 192 边外切正多边形;
- 每次 `direction`:
1. 与 $B(s,1500)$(192 边外切多边形)求交;
2. 与角域 $W(s,\theta,\delta_{\rm eff})$ 求交,$\delta_{\rm eff}=1^\circ+0.005^\circ$;
- `near`:与 $B(s,5)$ 外切多边形求交;
- `no_signal`:**不收缩凸候选集**。对全向源,负观测信息由 `ChannelParticles`
处理;让凸表示保留所有正观测候选,可以避免因模型误差误删真源。
圆盘外切多边形的径向超出逐次累加到 `slack_m`,所有裁剪容差只向
“保留更多候选”的方向倾斜,因此真源始终包含在 $P_c^{\rm out}$ 内。
清除证书使用 $P_c^{\rm out}$ 的最小包围圆 $B(m_c,\rho_c)$:
$$
\rho_c+\text{slack}_c+0.5\le20
\quad\Longrightarrow\quad
\text{在 }m_c\text{ 处一次 `/clear` 必命中真源}.
$$
其中 $0.5$ m 是工程余量,slack 是外包多边形的半径余量;该判据是保守的
充分条件,而不是“必须达到的最优半径”。
### 3.2 网格幸存集 `ChannelParticles`
每个频道维护 $\Omega$ 外扩裕量上的方格网格,间距
$h=14.65$ m,约 4.7 万格;Voronoi 裕量
$$
m=\frac{\sqrt2}{2}h\approx10.359\ {\rm m}
$$
是格心到格内任一点的最大距离。所有删除判定都内缩 $m$:**只有整个格子与
可行集不相交时才删除该格**。
| 观测 | 位置/距离更新 | 实现 |
| --- | --- | --- |
| Bayram、Vander Hook、Isler,2016,列表第10项 | 联合规划测向位置和访问顺序,同时计入移动时间与测量时间 | 原文以GDOP描述不确定度;其近似比不能转移为本文有界角域和清除任务的近似保证 |
| Olofsson等,2020,列表第22项 | 根据已观测区域分配后续搜索资源,在有限预算下规划路径 | 原文使用PHD和期望发现数;本文用确定性的逐频道剩余区域,不用概率很小替代无源证明 |
| Perera等,2023,列表第4项 | 将稀疏覆盖路线与无线电源定位结合,并分别评价路径与采样代价 | 原文依赖RSSI;本题接口没有RSS/RSSI数值,不能直接使用其估计器 |
| `no_signal` @ $s$ | 距离 $>r_{\rm eff}\ge1000$,删除格心距 $s\le1000-m$ 的格 | `_kill_disk(s,1000-m)` |
| `direction` @ $s$,读数 $\theta$ | 距离 $\le1500$;角向偏差不超过 $\delta_{\rm eff}$ + 格内角裕量 | 先删距 $s>1500+m$ 的格,再删角向超出的格 |
| `near` @ $s$ | 距离 $\le5$ | 删格心距 $s>5+m$ 的格 |
上述内容分别见[大学研究记录及论文摘要](https://experts.umn.edu/en/publications/gathering-bearing-data-for-target-localization-6/)、[作者公开论文](https://torarnj.folk.ntnu.no/AURO2020a.pdf)、[arXiv原文入口](https://arxiv.org/abs/2312.03493)。这里只迁移任务组织方法,以下七点几何证明和题目化调度公式在本文独立推导。
**定理(真源保留).** 真源 $P$ 所在格的格心 $g$ 满足
$|g-P|\le m$;与真值一致的观测不会让该格与可行集完全不相交,因此
“整格不相交”判定永不删除该格。于是:
论文列表中建议的RSS梯度逼近不能直接用于本题:`/measure` 只返回无信号、近距离或示向度,没有连续场强值。Atanasov等的源搜索也依赖场信号、随机梯度或测量模型,其收敛结论不证明本题仅测向闭环收敛。[原论文摘要](https://arxiv.org/abs/1402.0051) 本文也不假定源位置均匀分布、每次误差独立重抽样或某一交会角在所有场景下最优。
- **缺席证明**:幸存集为空 $\Longrightarrow$ 可行集为空
$\Longrightarrow$ 该频道无源;
- **跳测规则**:若某测点到所有幸存格心的最小距离 $>1500+m$,则在该点
测量必为 `no_signal` 且不产生任何新排除,可直接跳过,省 5 秒检测和
1 秒换频;
- **PF 清除证书**:若幸存集 MEC 半径 $\rho_{\rm pf}$ 满足
$\rho_{\rm pf}+m+0.5\le20$,则以该 MEC 圆心清除必命中真源。
## 2. 现有方案的实测瓶颈
`BayesLoop` 在每次测量后同步更新凸候选集与 PF,PF 只在频道尚未
CLEARED/ABSENT 时接收新证据。
官方问题3演练 `DHFK-PHD2-SR2P-FXK9` 已证明现有实现能在该局全清10个源,完整数据见[演练验证报告](C:/Users/HelixCopex/code/MATH/output/q3/practice/20260911-port2026/report.md)。该局在策略运行结束后才读取官方源数,源真值没有进入决策。
### 3.3 数量上界证明
| 分项 | 本局数值 | 对改进的含义 |
| --- | ---: | --- |
| 总虚拟时间 | 16217.454814秒 | 作为官方基线,不与自建场景混算 |
| 移动距离 / 耗时 | 64737.274米 / 12947.454814秒 | 移动约占79.84%,应优先减少站点和往返 |
| 检测次数 / 耗时 | 540次 / 2700秒 | 无源频道各扫49点,共490次,占全部检测90.74% |
| 换频道耗时 | 520秒 | 可以优化,但节省一次换频仅相当于少走5米 |
| 清除耗时 | 50秒,10次全部成功 | 清除可靠性已得到单局支持,无需先追求更小定位半径 |
| 最后一个源清除时刻 | 8454.332399秒 | 其后7763.122415秒用于剩余任务,约占总时间47.87% |
题面给定每局源总数 $10\sim16$ 且每频道至多一个源。若
`DETECTED`/`CLEARED` 的不同频道数达到 16,则所有仍未出现有效信号的
`UNKNOWN` 频道都不可能有源,可直接标记为 `ABSENT`,证据来源记为
`count_bound`。这条规则与位置无关,是严格计数证明,不需要等七站扫完。
`summary.completion_basis` 会区分 `count_cap` 与 `per_channel_proof`,
避免把“达到数量上界”误读成“逐频道缺席证明”。
现有 `OmnidirectionalLoop._coverage_phase` 的结构还引入额外往返:在一个覆盖站按频道扫描,遇到 `direction` 就立即定位清除,再回原覆盖站继续下一频道。由原始动作日志统计,从非网格点返回网格检测点共10次,累计约9996.714米、1999.343秒。这是实际行程分类,不能全部当成可直接删除的收益,因为改序后仍需访问下一任务;但它明确说明同站任务应先批量处理。
## 4. 发现保证:七点解析覆盖与覆盖账本
当前49点网格同时服务第三问和第四问。它的定向覆盖证明要求更强的几何条件;第三问无需为未知发射朝向付出同样的采样代价。改进第三问时,应显式区分全向策略和第四问策略,不能全局替换公用网格。
### 4.1 `full_disk` 语义
## 3. 状态、信息与优化目标
全向源在测点 $s$ 返回 `no_signal`,意味着真实距离严格大于
$r_{\rm eff}\ge1000$。因此若集合 $S$ 满足
### 3.1 符号与可用信息
$$
\Omega\subseteq\bigcup_{s\in S}B(s,1000),
$$
| 符号 | 含义 |
则任何合法源必在某个 $s\in S$ 的 1000 m 内,在该点不可能返回
`no_signal`。于是“某频道在全部 $S$ 点都测得 `no_signal`”构成严格的
缺席证明。
`CoverageLedger` 按 `(channel, point_index)` 二维记录,只有所有点都已测
(或显式跳过)才允许 `coverage_complete(channel)=True`;“路过某点”不算
“测过某频道”。
### 4.2 七点构造与解析界
取原点加半径 $a$ 的六等分环:
$$
S(a)=\{(0,0)\}\cup\left\{a(\cos(k\pi/3),\sin(k\pi/3)):\ k=0,\dots,5\right\}.
$$
**定理 1.** 当 $0<a/\sqrt3\le R$ 时,
$$
\max_{g\in\Omega}\min_{s\in S(a)}\lVert g-s\rVert
\le D(a):=
\max\left\{\frac a{\sqrt3},\ \sqrt{R^2+a^2-\sqrt3Ra}\right\},
$$
其中 $R=1800$。证明:任意 $g=(r\cos\varphi,r\sin\varphi)$ 与最近环站的
夹角不超过 $\pi/6$。若 $r\le a/\sqrt3$,选原点;否则选最近环站,由
余弦定理和 $\cos\varphi\ge\cos(\pi/6)=\sqrt3/2$ 得
$\lVert g-s\rVert^2\le r^2+a^2-\sqrt3ar$。右端关于 $r$ 是凸二次函数,
在区间端点取最大值,分别得 $a^2/3$ 和 $R^2+a^2-\sqrt3Ra$。证毕。
代入可验证:$a=1200$ 时 $D=968.901572$ m;当前 `bayes` 默认
`station_ring_radius_m=1159.7` m 时 $D=984.539136$ m;两者都小于 1000,
从站上有 15.5 m 以上的几何余量。$a$ 的可行下界为
$a_{\min}\approx1122.955832$ m(零余量)或 $1125.254906$ m(1 m 余量)。
七点巡回长度 $6a$;$a=1200$ 时纯覆盖路线约 7200 m。
### 4.3 49 点基线
网格 $S=\{(700i,700j):i,j\in[-3,3]\}$ 覆盖 $[-2100,2100]^2\supseteq\Omega$;
每个单元的对角线 $700\sqrt2\approx989.95\le1000$,因此任意源都在某个
网格点的 1000 m 内。该证明不需要朝向信息,对问题三的七点方案是更强的
充分条件,但会发现阶段检测次数多一个数量级(频道 × 49 次);问题四仍
需要它作为 legacy 对照(见 `algo-4.md`)。
### 4.4 计划可验证性
`guarantee/cover.py` 提供两套校核:
- `verify_full_disk(points)`:在 $\Omega$ 内按网格采样,校核
“每个采样位置都在某个点的 1000 m 内”;
- `verify_forward_half_disk(...)`:第四问语义,问题三不使用。
七点计划走解析证明;49 点计划走 `full_disk` 校核。运行期不使用未校核的
点集来宣称“已证明无源”。
## 5. 定位与清除
### 5.1 问题二选点器的推广(基线与安全后备)
`planner.select_measurement_point` 对**任意** `CandidateRegion` 工作:
给定当前后验外包多边形 $P$,令其 MEC 为 $B(m,\rho)$,则安全接收盘为
$$
B\left(m,\ 1000-\rho-10^{-3}\right)
$$
($\rho>1000$ 时退化为探索 MEC 圆心,可能 `no_signal`)。盘内取
37 个候选点(圆心 + 3 环 × 12 方向),以“边界见证点 × 读数区间端点 +
near 分支”的最坏后验 MEC 半径为主指标、移动时间为次指标;选出后再按
1/4 间距加密复核。该函数最初为问题二实现,在问题三中服务于
`SevenBatch`、`OmnidirectionalLoop` 的定位子循环,以及 `BayesLoop`
的阻塞式安全后备 `_localize_and_clear`。
### 5.2 `bayes` 的信息增益选点
`BayesLoop._select_point` 在 PF 幸存集上选择定位测点,候选集分两种:
- 凸候选集安全盘非空:取 `select_measurement_point` 的环形候选,并额外
加入以当前位置到 MEC 圆心方向为轴的对称候选,以及零移动的当前位置;
- $\rho>1000$、无保证安全盘:取 PF MEC 的 $1.0/1.5/2.0$ 倍探索环和
PF MEC 圆心。
对候选 $q$,默认评分模式 `entropy` 是期望对数幸存占比:
$$
\text{score}(q)=
\mathbb E[\log(\text{后验幸存占比})]
+\lambda\left(\frac{\lVert p-q\rVert}{5}
+\frac{\lVert q-m_{\rm MEC}\rVert}{5}\right),
\qquad \lambda=0.05.
$$
其中期望对代表假设(从幸存格均匀抽样)和 $r_{\rm eff}\sim U(1000,1500)$
解析积分:
- `no_signal` 分支(概率 $(d-1000)/500$):幸存格收缩到
$B(q,1000-m)$ 之外;
- `direction` 分支:以代表点方位为期望读数,用 $\pm\delta_{\rm eff}$
角域裁剪后的子采样估计幸存占比;
- `near` 分支($d\le5+m$):后验为 5 m 盘,占比趋近零。
可选 `score_mode=radius` 直接最小化期望后验 MEC 半径。
`score_subsample=800`、`mc_representatives=7` 是工程参数;均匀源分布、
零误差代表读数和 $r_{\rm eff}$ 均匀分布都只是**选点评分假设**,不参与
任何安全证明。安全证明只使用题面给定的 $\pm1.005^\circ$ 角域与距离界。
当前配置中以下“更强的耦合”均已实现但实测为净负收益,默认关闭:
`fuse_localize_into_tour=False`(站点顺带定位)、`exact_order_limit=0`
(Held-Karp 精确任务序)、`route_aware_probe=False`(路线感知探点)。
代码与开关保留,便于复现与后续研究。
### 5.3 清除动作
`BayesLoop._best_certificate` 的优先级:
1. **凸证书**:`clear_certificate(region)`;
2. **PF 证书**(`grid_cert_enabled=True`):负观测挖洞使 PF 幸存集更紧时,
若 PF MEC 半径 $+m+0.5\le20$,用 PF MEC 圆心作为清除点。
得到证书后,`_near_clear_target` 还会把清除点从证书圆心向当前位置方向
平移一小段:设当前证书半径 $r$、限值 $limit$,最多平移
$\Delta=\min(\text{当前距离},limit-r-10^{-6})$,新目标点仍保证所有候选
源在 $r+\Delta\le limit$ 内。该平移可省去最后一段接近路程,不放松证书。
定位子循环每频道最多 `max_localize_steps=8` 次追加测量;若在安全接收盘内
出现 `no_signal`,记录异常 `no_signal_in_safe_disk`,不静默忽略。
## 6. 决策层:统一任务表与滚动重排
### 6.1 任务类型
`BayesLoop._build_tasks` 在每次决策点构建:
| 任务 | 位置 | 服务时间 | 触发条件 |
| --- | --- | --- | --- |
| `station` | 七站之一 | $5\times$待测频道数 + 换频 | 该站仍有 `UNKNOWN` 频道未测,且跳测规则未排除 |
| `locate` | 信息增益选点 | 5 s + 可能的换频 | 频道 `DETECTED` 且暂无清除证书,且未委托给站点 |
| `clear` | 证书中心(可平移) | 5 s 成功(失败 3 s) | 频道有清除证书且未处于“清除失败后待补测”状态 |
站点任务的服务时间计算当前频道优先:若机器人当前测向频道包含在待测集合,
则少一次换频。清除动作不改变测向频道。
### 6.2 跳测规则
`guaranteed_no_signal(station)`:若该频道所有幸存格心到站点的距离都
大于 $1500+m$,则该次测量必为 `no_signal` 且不会产生新排除,任务构造时
直接跳过。跳测缓存按 PF `version` 生效;幸存集单调收缩,因此判定单调。
这条规则是负观测给问题三带来的主要检测节省之一。
### 6.3 开放路径排序
任务表规模通常为 6~12 项,代价包含移动、检测、换频,终点自由。默认:
1. 最近邻构造初始序;
2. 开放路径 2-opt 改进,最多 `two_opt_passes=4` 轮;
3. 换频代价按实际频道状态沿路径逐步传递,而不是固定服务费;
4. 执行排序后的**第一个任务**,拿到响应后立即回到决策点重新构建/排序
(滚动时域)。
可选的 Held-Karp 精确 DP(含“已访问集合 × 结束时频道”状态)与
`route_aware_probe` 路线感知精修均已实现;在当前冻结基准集上,
精确 DP 与 2-opt 差距在噪声内(甚至略差),默认关闭。
### 6.4 已停靠位置的机会测量
`_measure_at_stop` 在每次决策点评估当前位置是否值得顺带补测已发现频道:
只对尚未在该 0.5 m 点测过、无证书、到凸候选集所有顶点距离均不超过
$1000-10^{-3}$ m、且预测后验半径至少收缩
`opportunistic_radius_ratio=0.5` 的频道追加一次测量。每次仍支付 5 秒与
实际换频成本,只是省去移动;它不是“免费检测”。
## 7. 停止、预算与异常收尾
### 7.1 完成证明
循环停止后,`summary.completed` 的依据分两类:
- `count_cap`:清除数达到 16(题面源数上界);
- `per_channel_proof`:每个频道状态都是 `CLEARED` 或 `ABSENT`。
缺席证据在 `summary.absence_evidence` 中逐频道记录来源:
| 证据 | 条件 | 严格性 |
| --- | --- | --- |
| `pf_empty` | 某频道 PF 幸存集为空 | 严格(Voronoi 真源保留) |
| `coverage` | 七点/49 点全部测得 `no_signal`(或计划上显式跳过) | 严格(解析/校核覆盖) |
| `count_bound` | 已有 16 个不同频道的有效存在证据 | 严格(题面数量上界) |
`persistent_search` **默认 False**:一旦“每频道已清除或证明不存在”就立即
`/exit`,因为虚拟时间是成绩口径。显式 `--persistent` 会继续复扫未清除
频道直到清除数达 16、实机预算耗尽或虚拟安全余量不足;历史官方演练证明
无条件复扫会浪费大量时间,因此该项目只作为可审计的保险开关保留。
### 7.2 预算与中断
- 虚拟安全余量 `virtual_reserve_s=10000` s:剩余虚拟时间不足以完成
一个保守单动作上界时停止发起新动作,避免触及 100 小时上限;
- 现实预算以服务器 `/enter` 返回的 `remaining_real_duration_s` 为准;
`DeadlineExceeded` 时 stop_reason 记为 `real_budget_exhausted`;
- 传输、协议或守恒性异常都会尽力 `/exit` 并输出未完成 summary,
不静默丢会话;`completed=False` 与具体 `stop_reason` 同时留档。
## 8. 基线与自建消融
### 8.1 调度变体
| 版本 | 发现/定位关系 | 说明 |
| --- | --- | --- |
| A0 `grid` | 49 点,发现后立即离站定位 | 历史生产基线 |
| A1 `SevenImmediate` | 七点,发现后立即离站定位 | 只替换覆盖点 |
| A2 `SevenBatch` | 七点,本站先扫完再按最近候选圆心服务队列 | 中间对照,曾用于官方演练 |
| A3 `SevenSweep` | 七点,先扫完全部必要站点再统一服务 | 批量调度的另一极端 |
A2 相对 A0 的收益主要来自“减少站间往返 + 每站批量扫频 + 无源频道只需
7 次而不是 49 次检测”。在早期 12 个自建场景上,A0/A1/A2/A3 平均虚拟
时间分别为 13788.04 / 7476.09 / 5496.20 / 6094.73 秒,A2 逐局平均降幅
58.55%;更晚的 14 场景消融中,`bayes` 相对 A2 再降 30.0%
(3726.2 s vs 5352.7 s)。这些数字来自自建模拟器与固定误差场,不是官方成绩。
### 8.2 冻结基准集当前结果
`project/q3` 在 18 个冻结 core 场景(seeds 100–105 × 10/13/16 源,
`harness/suites.py` 版本化清单)上的配对结果:
| 方法 | 有效局 | 全清率 | 虚拟时间均值 | 中位 | 最大 | 检测均值 | 请求均值 | 位移均值 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| `bayes` | 18/18 | 100% | **3188.7 s** | 3111.3 s | 3663.7 s | 111.1 | 124.1 | 12338 m |
| `seven` | 18/18 | 100% | 5361.7 s | 5367.5 s | 6462.4 s | 100.8 | 113.8 | 23508 m |
| `grid` | 18/18 | 100% | 14935.7 s | 15275.1 s | 16691.4 s | 430.6 | 443.6 | 61550 m |
配对变化:`bayes` 相对 `grid` 虚拟时间 **−78.4%**,18/18 场景更快;
所有 54 局零缺席误判、零异常、正常退出且计时复算一致。另有边界场景
(源在 $\Omega$ 边界、$r_{\rm eff}=1000$)验证七点覆盖的扇区接缝。
### 8.3 官方演练记录(历史口径)
- 旧 49 点实现通过官方问题三演练案例 `DHFK-PHD2-SR2P-FXK9`:
10/10 全清、540 次检测、10 次清除,虚拟总时间 16217.45 s,
现实 7.629 s;
- A2 七点批量通过官方案例 `J4ER-Y9EP-Q379-UPFA`:12/12 全清、
109 次检测、虚拟 5232.13 s、现实 3.406 s;
- 后续一次官方问题三演练(`3BW5-9R54-NZNA-MYB9`)记录 13/13 全清、
虚拟 4058.71 s。
以上案例的源场景、实现版本、误差场均不同,不能直接横向比较,也不能把
历史官方数字当成当前 `bayes` 同案例重跑结果。当前默认 `bayes` 的官方向
成绩仍需新的演练验证。
## 9. 复杂度、参数与保守性边界
| 模块 | 计算量(近似) |
| --- | --- |
| $\Omega=B(0,R)$,$R=1800$ | 源位置区域,单位米 |
| $R_-=1000$,$R_+=1500$ | 有效接收半径下界、上界 |
| $p,f,t$ | 当前机器人位置、测向频道、官方虚拟时刻 |
| $K_c$ | 已发现频道 $c$ 的保守位置候选集 |
| $E_c$ | 尚未发现频道 $c$ 仍可能存在源的位置集合 |
| $\mathcal U,\mathcal D,\mathcal L,\mathcal C,\mathcal A$ | 未发现、待定位、可保证清除、已清除、已证明无源频道集 |
| $\mathcal P$ | 曾获得有效存在证据的不同频道集,包含已清除频道 |
| $\delta=1.005^\circ$ | 题设1°误差加两位小数舍入裕量 |
| $S$ | 具有全域覆盖证明的检测站集合 |
| $L,N_m,N_s,N_c^+,N_c^-$ | 移动长度、检测数、换频数、成功与失败清除数 |
源静止、同位置同频道的测向误差固定。只有该频道实际收到的观测才能更新其状态;经过一个位置不代表在那里扫过所有频道。不同频道的无信号证据不能互相替代。
### 3.2 统一的时间口径
忽略微秒量化时,整局虚拟耗时为
$$T=\frac{L}{5}+5N_m+N_s+5N_c^++3N_c^-.$$
`/clear` 的目标频道不改变测向机频道,因而不引入换频代价;`/exit` 不要求回到原点,也不增加虚拟时间。因此访问顺序是从当前位置出发、终点自由的**开放路径**问题,不能默认使用需要返回起点的旅行商回路。
官方内部按微秒累计,验收时按每次移动耗时量化到整数微秒,再累加检测、换频和清除的整数秒。连续实数公式用于规划,逐动作微秒公式用于复算。原演练汇总的541处偏差已查明为累计浮点与微秒精度口径不同,详见[独立审计](C:/Users/HelixCopex/code/MATH/output/q3/practice/20260911-port2026/verification.json)。
优化目标按优先级定义为:保持真源候选和有效完成条件;在现实1200秒、虚拟360000秒上限内全清;在可完成策略中降低 $T$。现实计算和网络耗时单独约束,不加进虚拟时间公式。由于源场景和误差场未知,理想模型可写为对允许场景集合 $\Xi$ 的 $\inf_\pi\sup_{\xi\in\Xi}T(\pi,\xi)$,但本文不声称解出了这个连续在线极小极大问题,也不声称已证明任意合法场景都能在两个预算内完成。
## 4. 逐频道证据与安全停止
### 4.1 观测更新
首次 `direction` 在 $s$ 返回 $\theta$ 时,建立
$$K_c=\Omega\cap B(s,R_+)\cap W(s,\theta,\delta).$$
以后每次有效测向再交入相应距离上界和角域。`near` 时交入 $B(s,5)$,当前检测点本身就满足20米清除条件。角域的半平面表达、保守圆盘外包和最小包围圆计算沿用[问题一](C:/Users/HelixCopex/code/MATH/docs/algo-1.md)、[问题二](C:/Users/HelixCopex/code/MATH/docs/algo-2.md)。
全向源在 $s$ 返回 `no_signal`,意味着若该频道仍存在未清除源,则其距离严格大于实际接收半径,进而大于1000米。因此对未发现频道可维护
$$E_c=\Omega\setminus\bigcup_{s\in\mathcal N_c}B(s,R_-),$$
其中 $\mathcal N_c$ 只含该频道实际测得无信号的位置。有限精度实现可只排除 $B(s,R_- -\eta)$,$\eta>0$ 是有依据的数值裕量;少删不会漏源。该负观测更新仅用于第三问,不能直接用于第四问的定向源。
圆盘差通常非凸。不能把扣除圆盘后的集合强行表示成单个凸多边形,更不能丢弃狭窄或小面积分量。第一阶段保留当前凸定位内核,仅在未知频道的覆盖账本中使用负观测;后续如把无信号用于已发现源的精定位,应使用多片区域或再取保守凸外包。
### 4.2 完成与计数推理
安全停止条件是 $\mathcal C\cup\mathcal A=\{1,\ldots,20\}$,且本局 `/exit` 已被接受。无源证明可来自完整覆盖、剩余集合的可靠判空,或下述数量上界。
由于每频道至多一个源且总数不超过16,当 $|\mathcal P|=16$ 时,所有未出现过有效信号的频道即可由数量上界判为无源,**不必等待16个都清除才停止扫未知频道**。随后仍须清除 $\mathcal P\setminus\mathcal C$,不能直接退出。成功清除16个则立即满足全清条件。
只发现或清除10个不够,因为10是下界。反过来,若无源证据已排除10个频道,则其余10个频道都必须有源,但仍需获取其定位观测;这种计数推理不能替代位置搜索。若已知存在与无源证据互相矛盾,或可存在频道数不足10,应报告协议、模型或数值不一致,不能把矛盾解释为成功。
## 5. 用七个检测站替代49点网格
### 5.1 布点
取原点及半径 $a$ 圆周上的六个等角点:
$$S(a)=\{(0,0)\}\cup\{a(\cos(k\pi/3),\sin(k\pi/3)):k=0,\ldots,5\}.$$
推荐首个工程版本固定 $a=1200$ 米。站点坐标为 $(0,0)$、$(1200,0)$、$(600,\pm600\sqrt3)$、$(-600,\pm600\sqrt3)$、$(-1200,0)$。这些点全部位于源圆域内;允许域外检测这一规则仍然保留,但本方案不需要依赖它。
### 5.2 连续覆盖证明
**定理1:** 若 $0<a/\sqrt3\le R$,则 $S(a)$ 对 $B(0,R)$ 的覆盖距离满足
$$\max_{g\in\Omega}\min_{s\in S(a)}\|g-s\|\le D(a):=\max\left\{\frac a{\sqrt3},\sqrt{R^2+a^2-\sqrt3Ra}\right\}.$$
**证明:** 任意 $g$ 写成极坐标 $(r,\theta)$。它与最近环上站点的夹角 $\varphi$ 不超过 $\pi/6$。令 $r_0=a/\sqrt3$。若 $r\le r_0$,选择原点,距离至多 $r_0$。若 $r\in[r_0,R]$,选择最近环站,有
$$\|g-s\|^2=r^2+a^2-2ar\cos\varphi\le r^2+a^2-\sqrt3ar.$$
右侧关于 $r$ 为凸二次函数,在闭区间最大值出现在端点。代入 $r_0$ 得 $a^2/3$,代入 $R$ 得第二项平方,从而得到结论。证毕。
代入 $R=1800$、$a=1200$,得到 $r_0=692.820323$ 米,$D(a)=968.901572$ 米,距离接收下界有31.098428米余量。因此每个合法全向源至少可在七站之一被检测到,不依赖位置概率、源数或源频道。
这是连续圆域的证明,不是“抽样没看到空洞”。此外用130501个极坐标采样点复算,最大最近站距为968.901572米,与解析值一致;该数值检查仅辅助发现公式或实现错误,见[覆盖校核数据](C:/Users/HelixCopex/code/MATH/output/q3/search-ablation/benchmark.json)。
**推论:** 对某频道七站全部测得无信号,就能证明该频道不存在源。若真实有源,覆盖定理给出一个距其小于1000米的站,在该站不可能返回无信号,矛盾。对已发现或已清除频道可以停止剩余覆盖检测,必须在逐频道账本中保存其原因。
### 5.3 环半径与时间的权衡
在本七点族内,若要求覆盖距离至多 $d\le1000$,外边界约束为
$$a^2-\sqrt3Ra+R^2-d^2\le0,$$
同时要求 $a/\sqrt3\le d$。当 $d\ge R/2$ 时,环半径的外边界允许区间为
$$R\cos(\pi/6)-\sqrt{d^2-R^2/4}\le a\le R\cos(\pi/6)+\sqrt{d^2-R^2/4}.$$
只按1000米边界、零裕量计算,最小 $a$ 约为1122.955832米;保留1米覆盖裕量时为1125.254906米。1200米不是最短路线的解析最优参数,而是在站距与覆盖裕量之间采用的透明工程选择。较小 $a$ 缩短站间路线,却改变后续发现时的交会几何和定位路程;应在独立场景上比较,不能仅由扫描路长选全局最优值。
从原点先到任一环站,再依次访问相邻五站,不返回原点,纯站间路长为 $6a=7200$ 米。每站最坏扫描20个频道,发现阶段最多140次检测,顺序扫描的换频次数至多139。因此这一**不含定位清除插入**的纯覆盖路线有上界
$$T_{\rm cover}\le7200/5+140\times5+139=2279\text{秒}.$$
不能把2279秒当成全清总耗时上界;定位插入还会改变站间行程。对本次官方案例的10个无源频道,完整覆盖所需检测可从490次降为70次,差420次、2100秒检测时间。这是覆盖账本的解析差额,不是已在相同官方案例实测的新算法收益。
七点既未被证明是最少站数,也未被证明在全部可行布点中路线最短。第四问边界朝外的定向源可看不到这些内侧站点,所以该定理仅进入第三问专用策略。
## 6. 同站批量扫频与定位任务队列
### 6.1 先完成本站,再离站
推荐的第一阶段策略如下:到达一个覆盖站,先对尚需在该站搜索的全部未知频道各测一次。若当前测向频道在待测集合中,将其排第一以节省一次换频,其余频道按固定顺序扫描。`direction` 只更新候选集并加入定位队列;`near` 可以在当前站立即清除,因为不需增加移动。完成本站的频道批次后,再决定离站执行哪些定位任务。
这保留每次请求的串行语义,也避免“查出一个频道—离站—返回—再查下一个频道”的结构性往返。全局频道分组,即先把某频道扫遍全域再换下一频道,虽然省换频,却可能把路径重复十余遍;每次检测移动只有超过5米,其耗时就已超过一次换频,应以空间批处理优先。
### 6.2 队列中的基本排序
第一版对待定位队列按当前点到候选集最小包围圆中心的距离选择最近频道,完成该频道的安全测向和清除后重新排序,然后访问仍有未知频道待测的最近覆盖站。圆心距离只是一种便宜的排序代理,不是实际完成该频道的精确剩余成本。
相比按频道编号处理,重新排序能考虑清除后的新位置;相比扫完七站才定位,同站发现后的批量服务能避免把所有局部信息拖到远处再处理。第12节的消融支持先采用这一方案,但最近优先没有全局最优或对所有场景更快的保证。
同一轮每个待定位频道最多调用一次既有定位子循环;该子循环每轮最多追加8次检测。未解决的频道保留在队列,不能忙等或重复清除同一份失败证书。覆盖阶段结束后再处理未解决任务;预算不足时明确记为未完成。
### 6.3 后续将队列代价改成“插入耗时”
设当前点为 $p$,下一计划覆盖站为 $b$。若某待清除目标允许的位置集合为 $\mathcal C_c$,其插入路径代价可写为
$$\Delta L_c=\min_{q\in\mathcal C_c}\bigl(\|p-q\|+\|q-b\|\bigr)-\|p-b\|.$$
再加5秒清除时间,即可与直接前往下一覆盖站比较。待定位目标用一次或两次安全测向的短程预演估计对应代价。存在多个目标时,采用最近插入、开放路径2-opt或限宽束搜索重排;测量产生新候选集后只执行当前最佳方案的第一步,再重规划。缺少未来目标真值时,这些都是显式的在线启发式。
“把所有新发现目标都做完再去下一站”是第一版规则,后续可允许代价过高的目标暂存,但要设置可审计的最大延后次数,并在搜索终止后清空队列,防止某个难目标长期得不到处理。
## 7. 无信号区域复用与自适应跳站
七点是固定的完成保证,负观测区域允许进一步减少实际检测。在定位、清除行程的已到达位置,可以评估是否顺路测量少量未知频道;每个额外频道仍需5秒,不能把“已到达”解释为“免费探测”。
### 7.1 具有保守性的区域表示
对每个未知频道以方形单元并集 $\widetilde E_c$ 外包 $E_c$。初始保留与 $\Omega$ 可能相交的单元。设单元中心为 $z$、半对角线为 $h$,只有满足 $\|z\|-h>1800$ 的单元才可直接判为域外;边界相交不确定时继续保留或细分。
一次该频道无信号观测位于 $s$,若整个单元满足
$$\|z-s\|+h\le1000-\eta,$$
则单元全部落入保证可收盘,可以安全删除。不得只检查单元中心,也不得用近似覆盖面积达到100%作为判空证据。若单元仍与真实残余相交,就保留它,直至可给出整单元删除证书。
**命题2:** 以上规则维持 $E_c\subseteq\widetilde E_c$,故 $\widetilde E_c=\varnothing$ 足以证明无源。反过来,$\widetilde E_c\ne\varnothing$ 可能只是离散保守性,不能据此断言有源。
七点有31.098米几何余量;可使最终方格边长不超过20米,其直径不超过28.285米。对任意与 $\Omega$ 相交的单元,取其中一个域内点,该点距某站不超过968.902米;单元全部点距该站不超过997.186米。因此在工程裕量小于约2.81米且正确处理边界相交的情况下,七站无信号足以最终删除这些单元。这里用整单元的最大距离证书;若只用 $\|z-s\|+h$ 的较松证书仍未通过,继续细分或直接使用七点账本证明,不错误地停在粗格残片上。
### 7.2 候选点与频道选择
新增候选点来自:未完成的七个锚点、当前位置、已规划的定位点/清除点、残余区域边界附近点。对 $q$ 和频道集合 $F$,定义
$$G(q,F)=\sum_{c\in F}\operatorname{area}\bigl(\widetilde E_c\cap B(q,1000-\eta)\bigr),$$
并以 $G(q,F)/(\|p-q\|/5+5|F|+N_{\rm switch}(F))$ 作为探索排序指标。面积是搜索潜力代理,不是发现概率或保证的信息增益;面积计算可近似,但只影响候选排序。无源判定仍由整区域覆盖证书给出。对极小、线状或退化残余,还要保留单元数、最远未覆盖距离及锚点完成优先级,不能因面积接近零而永久忽略。
在当前位置按每个候选频道的 $G(q,\{c\})$ 与5秒检测、可能1秒换频排序,只有优于当前预演方案时才添加。未来站点若要删除,必须重新证明该频道的剩余 $\widetilde E_c$ 被保留站点的保证接收盘覆盖;一次扫描所得“没有发现”只删该次盘内区域,不能整片按经验跳过。
### 7.3 完备后备
七点中未完成的“站点—频道”记录始终保留。自适应探索若连续不产生新的可靠覆盖、计算超时或动态证书不确定,则恢复固定七点访问。设置有限的额外探测额度或要求每次替换都完成至少一个新的覆盖记录,使启发式不能无限拖延覆盖完成。
这给出确定性的搜索后备:自适应部分只允许节省已证明冗余的动作,不允许删除尚未证明冗余的覆盖责任。该设计尚未进入当前生产实现,也未包含在第12节的七点消融中。
## 8. 定位和清除也应优化剩余时间
### 8.1 定位到“够清除”就停止
设保守多边形 $\widetilde K_c$ 的最小包围圆为 $B(m_c,\rho_c)$。清除阈值使用 $r_{\rm safe}=20-\varepsilon$,其中 $\varepsilon$ 覆盖实际计算和坐标提交误差。若 $\rho_c\le r_{\rm safe}$,就具有一次清除证书;没有必要为了获得更小半径继续增加检测或横移。
外包多边形本身已经包含真集,它的多余面积使决策更保守;不能把“外包多边形与原圆盘的径向差”未经传播分析当作浮点误差保证。现有实现还扣除了 `slack_m` 和工程清除余量,本次消融完整保留其行为;后续统一外包与数值误差口径时另行验收。
### 8.2 在所有保证清除点中选择短路径位置
若 $V_c$ 为 $\widetilde K_c$ 的顶点,则
$$\mathcal C_c=\bigcap_{v\in V_c}B(v,r_{\rm safe})$$
是凸集,非空当且仅当 $\rho(\widetilde K_c)\le r_{\rm safe}$。圆盘凸性保证覆盖全部顶点等价于覆盖整个多边形,故任意 $q\in\mathcal C_c$ 都能清除真源。
无后续任务时,选择 $\arg\min_{q\in\mathcal C_c}\|q-p\|$;已计划下一站 $b$ 时选择 $\arg\min_{q\in\mathcal C_c}(\|p-q\|+\|q-b\|)$。两者都是凸优化问题,可用二阶锥形式表达,也可在圆盘交的候选边界上求解后逐顶点复核。
轻量实现可先使用内部安全圆盘 $B(m_c,r_{\rm safe}-\rho_c)\subseteq\mathcal C_c$:将 $p$ 投影到该圆盘即可得到一个不远于前往 $m_c$ 的保证清除点。这只是对该充分圆盘的最近点,并非对整个 $\mathcal C_c$ 最优。若圆盘半径为0就退化到 $m_c$。
### 8.3 安全测点的目标由半径改为任务耗时
问题二提供的安全区域为 $\mathcal Q(K_c)=\bigcap_{g\in K_c}B(g,1000)$,可用解析盘或保守多边形构造充分区域。选点仍必须先满足接收保证,不能为走近一个猜测坐标而接受未经评估的失联风险。
在可安全测量的候选点中,使用以秒计量的短程代价
$$J_H(q)=\frac{\|p-q\|}{5}+5+\mathbf1_{f\ne c}+\max_{z\in\mathcal Z(q)}\widehat V_{H-1}(K_c\mid q,z;q,c),$$
其中 $z$ 包含 `near` 及允许的示向度,$\widehat V$ 估计完成该源及返回后续任务的时间。若某分支已能保证清除,其终端代价包括移动至 $\mathcal C_c$ 的时间和5秒清除;若未能清除,可继续一层安全测向,或赋予经过标定的剩余定位代价。未来测点、清除位置与访问顺序共同影响 $\widehat V$。
这个形式解释了为什么“后验半径更小”不一定“完成更快”:走远很久将半径降到5米,可能劣于近处测量后已经达到19米。所有实际比较项统一为秒,避免随意相加米、面积和时间。有限候选和有限视野只给出预演策略的启发式排序。
若要把 $\max_z$ 报告为严格上界,必须采用问题二第10节覆盖全部读数的角区间扩张,并对区域误差与终端代价也作保守上界。当前“边界位置采样×误差端点”并无该保证,不能仅因取了样本最大值就声称最坏总时间已受控。推荐先保留现有局部选点,验证搜索调度收益,再单独启用这一成本模型。
## 9. 保守性、有限结束与预算边界
**命题3(不漏发现):** 固定七点对每个仍未知频道完成扫描,或由可靠的残余覆盖/数量证书替代相应扫描,必能发现所有合法全向源。
**证明:** 固定点由定理1保证;动态替代保持该频道覆盖域包含所有仍可能位置;数量证书只在已有16个不同源的存在证据时排除其他频道。因此真源不可能被当作无源跳过。证毕。
**命题4(证书清除):** 若维护的外包集合包含真源,实际提交点满足对该外包的20米清除约束,则在题设规则下 `/clear` 必成功。几何证书通过而官方失败时必须记录异常并检查模型、数值及协议状态,不能在同一证书上循环重试。
上述命题不证明任意安全测点序列都会有限步收缩到20米。现有每轮8次测量是工程限额,不能作为收敛定理。拟在后续增加有限后备:对已发现频道的有界外包区域,用边长20米方格的中心覆盖所有相交格,任意格内点至格心不超过 $10\sqrt2<20$ 米;遍历该有限清除候选即可在模型成立时清除源。单元相交计算必须向保留更多格的方向保守。
后备仅在定位停滞时使用,并须先检查实际枚举格数、路径和预算。设当前到首格及格间的计划路长为 $L_f$,共 $M_f$ 格,最迟第 $M_f$ 格成功的虚拟耗时上界为
$$T_f\le L_f/5+3(M_f-1)+5.$$
使用相交格数硬顶、现实高分位单请求估计 $M_f\,t_{\rm RTT}^{95}$ 加退出预留,以及虚拟剩余预算共同筛选。现有第四问中的后备格算法可供复用,但不能跳过第三问的验证。硬顶或预算不允许时,保留“未完成”,不将耗尽预算说成证明无源。
因此本文区分三层结论:覆盖与证书的数学安全性;预算足够且正确遍历有限后备时的有限完成性;现实/虚拟双预算内的性能,目前由实验评价,尚无所有合法场景的统一完成上界。
## 10. 推荐算法与伪代码
**算法3A:七点覆盖+同站批量扫频+就近定位清除(优先落地版本)。**
```text
读取第三问参数,生成七点 S(1200),初始化逐频道观测和覆盖账本
调用 /enter,记录官方时间预算
while 尚有未知频道的站点记录未完成:
若预算不足:标记未完成,转退出
选择仍有未知频道待测的最近站点 s
在 s 批量测量待查频道(当前测向频道若在其中,优先测)
no_signal:记录该频道在 s 的覆盖证据
direction:更新该频道 K,加入待定位队列
near:在 s 清除并依据响应更新状态
对本站结束后的待定位队列:
按当前位置到候选圆心距离选最近频道
调用问题二安全选点与问题一清除证书完成其定位子循环
清除成功后重新排序;未完成者保留,单轮不无限重试
若已清除16个:结束任务
根据逐频道七点账本标记无源;继续处理尚未清除的已发现频道
仅在全频道均已清除/有无源证明时标记完成
调用 /exit;退出响应失败单独记录,不能宣称正常结束
```
**算法3B:在3A之上逐项增加的完整改进规划。** 每次 `direction/near` 更新存在集合 $\mathcal P$,达到16时提前结束未知频道搜索;在各实际测量点更新负观测区域并进行有证书的站点替代;用插入耗时比较“先搜下一站”与“先做某个源”;对候选路线重排;以预计剩余时间选择安全测点,在可清除区域中选择省路位置;定位停滞时按预算调用有限后备。每执行一个动作就用真实响应更新状态,禁止整段盲执行预测的后续动作。
```mermaid
flowchart TD
A[进入并读取预算] --> B[更新逐频道证据与完成条件]
B -->|已全清且无遗漏证明完整| X[退出并保存日志]
B -->|预算不足| Y[按未完成退出]
B -->|仍有任务| C[候选覆盖站与定位清除任务]
C --> D[比较短程总耗时并保持覆盖责任]
D --> E[同站批量扫描或执行一次定位清除动作]
E --> F[接收官方响应并验证候选及证书]
F --> B
```
第一版和后续规划分别命名,防止把3B尚未实现的负观测跳站、时间型选点和后备算法算进3A的测试成绩。
## 11. 计算量与工程实现
七点固定账本最多 $7\times20=140$ 个布尔记录。最近站选择检查7个点,每次按至多20个频道统计待测项;16个源的贪心任务队列重排规模很小。固定站路线的开放路径最优排序如需精确解,可使用子集动态规划,规模为 $O(k^2 2^k)$、$k\le7$;但加入观测依赖的定位任务后不再是同一个静态问题。
定位计算仍主要消耗在多个候选点、候选源见证点、读数分支的几何裁剪和最小圆计算。假设候选测点 $Q$ 个、读数区间 $B$ 个、外包顶点 $V$ 个,单层保守评估包含 $QB$ 次裁剪和最小圆计算,可表示为 $O(QB[V+T_{\rm MEC}(V)])$;两层分支不能简单称为线性。复用候选集缓存、先粗筛少量入围点,再完整区间验证,能够控制现实计算预算。
残余区域若使用 $H$ 个单元,20频道掩码空间为 $O(20H)$,一次频道负观测朴素检查 $O(H)$;可以预计算七锚点的单元覆盖掩码,并通过空间索引限制动态点的更新范围。分辨率只控制证书的保守程度,不得因内存不足删除尚未证实的残余格。
| 模块 | 当前事实 | 建议改动 |
| --- | --- | --- |
| `coverage` | 共用49点与逐频道账本 | 新增第三问七点构造;保留第四问网格及其独立证明 |
| `planner.OmnidirectionalLoop` | 发现后立即离站定位 | 把“本站扫频”与“队列服务”拆开,引入第三问策略选项 |
| `belief` | 无信号不裁剪候选 | 增加第三问独立残余覆盖层,避免破坏第四问朝向语义 |
| `geometry/planning`、`planner` | 有安全选点与最小圆证书 | 后续增加最近安全清除点和时间型候选评分 |
| `evaluation` | 浮点累计、固定微秒容差 | 单独兼容官方逐步微秒时钟和自建连续时钟,保留两种原始口径 |
| `protocol` | 串行、幂等、预算退出、JSONL日志 | 延用;增加的动作仍走同一客户端,不能并发测多个频道 |
实际路径分别位于 [coverage](C:/Users/HelixCopex/code/MATH/src/mcm26b/coverage/__init__.py)、[planner](C:/Users/HelixCopex/code/MATH/src/mcm26b/planner/__init__.py)、[belief](C:/Users/HelixCopex/code/MATH/src/mcm26b/belief/__init__.py)、[evaluation](C:/Users/HelixCopex/code/MATH/src/mcm26b/evaluation/__init__.py)。前两问文档中部分旧路径仍写为根目录 `geometry`,复用时以当前 `src/mcm26b/geometry` 为准。
## 12. 已完成的自建配对消融
### 12.1 实验口径
为验证优先级,新增独立脚本 [benchmark_q3_search.py](C:/Users/HelixCopex/code/MATH/scripts/benchmark_q3_search.py),只连接进程内 `LocalSimulator`,不连接官方端口、不修改生产策略。数据保存在 [search-ablation](C:/Users/HelixCopex/code/MATH/output/q3/search-ablation/benchmark.json),同时逐局保存源场景、固定误差场种子、接受动作日志与哈希。
共12个场景:源数10和16各一组,每组包含 `random_omni_scene` 种子0、1、2、3、4的5个场景,以及1个源位于1800米边界、接收半径均为1000米的场景。随机生成器径向采样不是圆域面积均匀分布,并特意含近边界源,不将其称为真实场景分布。各变体使用同一局源坐标、接收半径、频道和固定空间误差场;不同位置的合成误差机制不代表官方误差场。边界例包含扇区接缝附近的源。
比较四种版本,均沿用现有安全选点与清除内核、舍入裕量0.005°和8次追加检测限额:
| 版本 | 唯一涉及的搜索与调度变化 |
| PF 更新 | 与删除格/角向扫描的幸存格数相关;粗格索引与向量化(numpy 可选)控制常数 |
| 七点覆盖 | 最多 $7\times20=140$ 个 `(站, 频道)` 记录 |
| 任务排序 | 最近邻 $O(n^2)$ + 2-opt $O(n^2)$/轮;精确 DP 为 $O(2^nn\cdot|C|)$,默认关闭 |
| 凸候选集 | 192 边形外切 + $O(m)$ Sutherland–Hodgman 裁剪;MEC 用 Welzl |
| 选点评分 | $O(N_q\times(\text{子采样}))$;候选约 37 个,子采样 800 |
保守性边界:
- 所有“证毕”结论依赖题面观测语义和保守外包/内缩;若接口语义、
接收半径范围或误差界改变,必须重新校核;
- 性能结论依赖自建场景分布、固定误差场和排序启发式,不构成对全部合法
场景的最坏时间保证;
- PF 的均匀先验与信息增益评分是选点启发式,不是官方概率模型;
- `persistent_search` 关闭时,如果官方场景违反题面数量上界或存在模型外
行为,不能由本算法保证发现;官方接口语义变化时必须记录异常而不是
强行把未完成解释为成功。
## 10. 与问题一、二、四当前实现的复用关系和差异(核对结果)
| 复用/差异 | 具体情况 |
| --- | --- |
| A0:49点即时定位 | 当前生产基线 |
| A1:七点即时定位 | 只把覆盖点换成七点,仍发现即离站 |
| A2:七点本站批量 | 本站扫频完成后,按最近候选圆心服务队列;当前频道优先 |
| A3:七点全域先扫 | 扫完所有必要覆盖站后,再按最近候选圆心定位;near仍原地清除 |
| 问题一几何内核 | `belief/__init__.py` 与 `particles.py` 只从 `geometry.localization` 导入 `smallest_enclosing_circle`;在线 `clip_wedge` 复刻同一半平面公式,但工作在凸多边形裁剪流程,不调用 `solve` |
| 问题二选点器 | `select_measurement_point` 直接从问题二推广而来,问题三用它做基线定位与安全后备;`safe_disk_radius` 同样复用 |
| 问题一没有的 | 负观测 `no_signal`、PF 非凸挖洞、覆盖缺席证明、数量上界、任务排序、滚动时域、预算/异常治理 |
| 问题二没有的 | 多频道数据关联、发现覆盖、清除动作、在线顺序决策;问题二只做一次第二点选择 |
| 问题四的差异 | 问题四不能用七点 `full_disk` 缺席证明;`no_signal` 可能由朝向遮挡造成,因此改用 `forward_half_disk` 31 点覆盖 +(位置 × 朝向)联合信念 + 预算化后备清除(见 `algo-4.md`) |
A2/A3都包含当前频道优先这一小优化,因此A1与A2之差不是“纯粹只改变一个排序变量”的严格单因素实验。后续应再拆分消融换频顺序。3B的动态残余区域、16个已发现源提前停止搜索、时间型选点、最近安全清除点及后备均未在这组实验启用。
一句话概括:**问题三 = 问题一的保守几何 + 问题二的保证接收选点 + 逐频道非凸负观测 + 覆盖/数量缺席证明 + 开放路径滚动调度**。
### 12.2 全部12个场景结果
## 11. 复现与参考
| 版本 | 全清且正常完成 | 平均虚拟时间 / 秒 | 平均检测数 | 平均移动距离 / 米 | 平均逐局时间降幅 |
| --- | ---: | ---: | ---: | ---: | ---: |
| A0 | 12/12 | 13788.04 | 418.00 | 56183.95 | — |
| A1 | 12/12 | 7476.09 | 100.42 | 34146.70 | 43.25% |
| A2 | 12/12 | 5496.20 | 100.92 | 24177.66 | **58.55%** |
| A3 | 12/12 | 6094.73 | 101.67 | 27164.04 | 53.90% |
```bash
# 冻结基准集:bayes vs seven_batch(runner 内置策略名)
uv run python scripts/run_suite.py --problem 3 --suite core --jobs 6 \
--variants bayes,seven_batch --label q3-core
每个版本共清除156个源,48局合计624个源全部清除,无失败清除、无错误缺席判定、无定位异常。A2相对A0的逐局降幅范围为37.50%至70.84%。降幅按 $\frac1n\sum_i(1-T_{A2,i}/T_{A0,i})$ 计算,不能与两个均值之比混称同一个指标。
# 项目对比框架(含 grid 基线,生成 project/results/q3.{md,json})
uv run python -m project.run --question 3
另以保存的自建场景真值独立复核48局动作日志,逐步检查正观测后的候选保留真源、清除证书及实际清除距离、全清集合、计时、检测数、退出响应与日志哈希,全部通过,见[证据复核结果](C:/Users/HelixCopex/code/MATH/output/q3/search-ablation/evidence-audit.json)。这些真值只用于离线验收,不进入策略。
| 源数(每组6场景) | A0平均时间 / 秒 | A1平均时间 / 秒 | A2平均时间 / 秒 | A3平均时间 / 秒 |
| --- | ---: | ---: | ---: | ---: |
| 10 | 15516.58 | 6313.47 | **4836.11** | 5467.38 |
| 16 | 12059.50 | 8638.71 | **6156.28** | 6722.08 |
10源时,未知频道的无源证明开销较大,所以七点替换收益明显;16源时,可通过清除数量上界提前停止,原网格未必扫完,但批量调度仍显著减少移动。A1与A2检测数相近,A2平均移动距离进一步下降,表明减少往返比单纯少测一次更有价值。这组自建证据支持优先实现A2,而非先投入复杂概率图、强化学习或全局非线性优化。
四版本平均本地计算墙钟约1.7至1.8秒/局,记录在数据中;它不含官方网络、真实程序截止或官方UI开销,不能当作新方案官方现实耗时。原官方动作日志只能验证旧路径上的响应,不能用它推断新测点的读数。只有在官方新演练执行新策略后,才能报告官方提速。
### 12.3 复现
```powershell
.venv/Scripts/python.exe scripts/benchmark_q3_search.py --seeds 0,1,2,3,4
# 回归测试
uv run pytest tests/test_particles.py tests/test_bayes_loop_q3.py \
tests/test_planner.py tests/test_coverage_plan.py tests/test_safety_valves.py -q
```
也可使用 `uv run python` 调用同一脚本。输出包含原始逐局数据,失败不会从汇总中剔除。当前实验是小规模方案筛选,不能证明所有合法场景、所有固定误差场或不同环半径下的性能。
主要文件:
## 13. 分阶段改进与验收计划
- `src/mcm26b/planner/bayes_loop.py`:`bayes` 决策层;
- `src/mcm26b/planner/__init__.py`:`OmnidirectionalLoop`、问题二选点器、清除证书;
- `src/mcm26b/planner/seven.py`:七点策略族与覆盖校验;
- `src/mcm26b/particles.py`:网格幸存集与信息增益;
- `src/mcm26b/belief/__init__.py`:凸候选集;
- `src/mcm26b/coverage/__init__.py`、`src/mcm26b/guarantee/cover.py`:覆盖账本与校核;
- `src/mcm26b/routing.py`:开放路径 DP/2-opt/MST 下界;
- `src/mcm26b/planner/bayes_loop.py::_exact_order`:可选 Held-Karp。
| 阶段 | 交付 | 必须通过的验收 |
| --- | --- | --- |
| I:七点+本站批量 | 将A2接入第三问CLI选项,保留A0可切换;原始日志格式兼容 | 七点连续覆盖证明与坐标误差预算;10/16源及边界例全清;第四问覆盖策略未被改动 |
| II:存在计数与扫频次序 | $|\mathcal P|=16$ 提前停止未知频道扫描;同站频道优先独立消融 | 已发现数、已清除数不混淆;发现10个不能停;clear不改变测向频道 |
| III:残余覆盖与顺路观测 | 保守单元账本、负观测复用、有证书跳站 | 边界及单元接缝不漏;未知频道各有独立覆盖责任;启发式停滞自动恢复七点 |
| IV:时间型局部动作 | 最近安全清除点、短程任务预演、插入排序 | 实际提交点满足全部外包顶点约束;near和跨0°读数正确;采样评分不冒充严格上界 |
| V:定位停滞与预算后备 | 有界区域有限清除覆盖,明确上限与退出 | 清除格子覆盖全部候选;格数/两种时间预算不足均记未完成;故障与失败可回放 |
每个阶段都在相同场景和同一固定误差场上进行配对比较。建议将种子0—4保留为本次开发集;最终验证另生成独立种子100—199,并分别覆盖10至16个源、接收半径1000和1500米、边界源、团簇源、同站near、接近共线读数、误差恰在±1°及空间相关误差场。所有超时、矛盾和未全清样例进入结果表,不允许只报成功局。
主要指标为全清且正常退出比例、平均/中位/P95/最大虚拟总时间、移动长度、检测数、换频数、清除失败数、证明无源的成本;同时报告最后清除时刻、现实计算时间与总请求数。小样本不确定性用逐局配对差分及其范围表达,增加样本后可在声明抽样假设的前提下给出区间估计;不从当前12例推出总体成功率为100%。
官方验收继续使用 socket 接口,逐条保存请求响应,最后保存官方结果及加密日志;优先使用官方支持的同案例复现功能进行配对,如果无法复现同一案例,就分别报告案例差异,不将两次随机局的时间差当成纯算法收益。本轮只完成方案研究与自建实验,没有再次启动官方演练。
## 14. 结论与实现边界
第三问首先应把覆盖责任从49点缩减为已证明足够的七点,并将覆盖站内扫频和离站定位拆开。该改进直接针对官方日志中的主要开销,在保持几何定位方法不变时,已经得到12个自建场景的配对支持。推荐先落地A2,再独立验证存在数量上界、残余覆盖和时间型测点/清除点优化。
初稿形成时,七点与三种调度变体存在于离线消融脚本,官方仅验证A0;随后A2已通过下述一次官方演练。生产 `src/mcm26b` 默认策略仍未修改,A2由独立运行脚本调用。3B给出了可实现的进一步规划,但没有将其预期收益写成已测结果。固定覆盖、观测集合和清除证书负责可靠性;候选评分、任务排序和半径调参负责效率,二者的保证范围分别陈述。
## 15. 补充:A2官方演练已通过
在方案研究之后,用户启动新的问题3演练,于2026-09-11通过2026端口实际执行A2。案例 `J4ER-Y9EP-Q379-UPFA` 的官方源数为12,12个全部清除,109次检测、12次清除无失败,现实耗时3.406秒,总虚拟耗时5232.132109秒(1小时27分12秒),移动22645.661米。其余8个频道各有完整七点无信号记录,最终正常退出。
123个请求响应已严格离线回放,清除证书和官方微秒计时全部通过复核。原始数据、官方产物、运行代码哈希及复现入口见[本局验证报告](C:/Users/HelixCopex/code/MATH/output/q3/practice/20260911-seven-batch-01/report.md)。因此A2现已有自建配对实验及一个官方案例的有效性证据。
相较之前A0官方10源案例的16217.454814秒,本局虚拟时间少67.74%,但案例和源数不同,不能把该差异称为严格算法提速率;第12节的58.55%仍仅指12个自建场景的配对平均结果。3B的进一步改进尚未启用。
延伸阅读:`docs/algo-3-bayes.md`(早期贝叶斯闭环设计与消融细节)、
`docs/第三四问架构优化与运行提速方案.md`(运行历史与瓶颈)、
`docs/第三四问图论与动态规划优化方案.md`(图论/DP 轮实测与负面结论)。
## 参考文献
1. 全国大学生数学建模竞赛组委会. 2026年高教社杯全国大学生数学建模竞赛B题:无线电干扰源的快速自动定位与清除[Z]. 2026. [题面](C:/Users/HelixCopex/code/MATH/issue/B题.pdf);模拟器配套材料《附件2:模拟器通信接口说明及编程指南》[本地文件](C:/Users/HelixCopex/code/MATH/issue/附件/附件2.docx)。
2. 本项目. 问题一:有界测向误差下定位区域的直径与圆覆盖;问题二:具有接收保证的第二检测点选择[Z]. 2026. [algo-1](C:/Users/HelixCopex/code/MATH/docs/algo-1.md)、[algo-2](C:/Users/HelixCopex/code/MATH/docs/algo-2.md)。
3. BAYRAM H, VANDER HOOK J, ISLER V. Gathering Bearing Data for Target Localization[J]. IEEE Robotics and Automation Letters, 2016, 1(1): 369–374. DOI: 10.1109/LRA.2016.2521387. [作者所在大学的研究记录](https://experts.umn.edu/en/publications/gathering-bearing-data-for-target-localization-6/)。核对题目、作者、页码及移动与测量联合代价;未套用其GDOP近似比。
4. OLOFSSON J, HENDEBY G, LAUKNES T R, JOHANSEN T A. Multi-Agent Informed Path Planning Using the Probability Hypothesis Density[J]. Autonomous Robots, 2020. [作者公开稿](https://torarnj.folk.ntnu.no/AURO2020a.pdf),第1—2节。用于未观测区域与预算路径的建模对照。
5. PERERA A, TRAN V P, ANAVATTI S, KASMARIK K, GARRATT M. Radio Source Localization using Sparse Signal Measurements from Uncrewed Ground Vehicles[EB/OL]. arXiv:2312.03493, 2023. [原文入口](https://arxiv.org/abs/2312.03493)。用于稀疏覆盖与实验设计的对照,RSSI估计器未迁移。
6. ATANASOV N A, LE NY J, PAPPAS G J. Distributed Algorithms for Stochastic Source Seeking with Mobile Robot Networks: Technical Report[EB/OL]. arXiv:1402.0051v2, 2014. [原文入口](https://arxiv.org/abs/1402.0051)。用于说明场强梯度和测量模型假设的适用边界,不引用其结论证明本算法收敛。
在线来源核对日期:2026-09-11。本文的七点构造、覆盖界和具体调度规划来自对题设参数的推导与本项目实验,不宣称一般几何和路径规划思想在文献中首次出现。
1. 全国大学生数学建模竞赛组委会. 2026 年高教社杯全国大学生数学建模竞赛 B 题[Z]. 2026. 本地题面 `issue/B题.pdf`。
2. 模拟器配套材料. 附件 1《模拟器使用说明》、附件 2《通信接口说明及编程指南》[Z]. 2026. 本地 `issue/附件/`。
3. 本项目. `docs/algo-1.md`、`docs/algo-2.md`、`docs/algo-4.md`。
4. 本项目. `docs/算法审核与优化-20260911.md`、`docs/第三四问架构优化与运行提速方案.md`、`docs/第三四问图论与动态规划优化方案.md`。
+485
View File
@@ -0,0 +1,485 @@
# 问题四算法说明:混合全向/定向源搜索与清除闭环(当前实现)
> 本文汇总当前仓库中问题四的全部实际算法。生产策略是
> `src/mcm26b/planner/__init__.py::DirectionalExtension`,CLI 策略名
> `directional`,入口为 `mcm26b run --problem 4`。
> 与问题三不同,问题四的源可能包含定向源;`no_signal` 不再等价于
> “距离超过接收半径”,因此问题三的七站全向缺席证明**不能直接搬用**。
> 当前仓库尚无官方问题四演练记录;本文性能数字均来自自建
> `LocalSimulator` 冻结基准集,明确标注为测试假设。
## 1. 问题定位与核心难点
问题四每局有 $10\sim16$ 个源,其中一部分为定向源,其余为全向源;
位置在 $\Omega=B(0,1800)$ 内,频道互异。定向源有一个朝向
$h$,只有当接收点位于其**前向半平面**内、且距离不超过 $r_{\rm eff}$
时才可能返回有效读数:
$$
r=\lVert q-P\rVert\le r_{\rm eff}\quad\text{且}\quad
\operatorname{angular\_gap}\big(\operatorname{bearing}(P\to q),h\big)
\le90^\circ .
$$
其中 $r_{\rm eff}$ 对每个源未知,满足 $1000\le r_{\rm eff}\le1500$ m。
若 $r>r_{\rm eff}$ 或朝向不覆盖接收点,结果为 `no_signal`;若可见且
$r\le5$ m,结果为 `near`;若可见且 $r>5$ m,结果为 `direction`,
数值为接收点到源的方位加有界误差。
因此问题四的困难不是一般的“覆盖搜索”,而是两个额外的证明/决策问题:
1. **发现**:如何用有限的访问点证明“某个频道没有源”,即使该源是
朝外发射的定向源;
2. **定位与清除**:定向源的 `no_signal` 可能只是朝向遮挡,不能像全向源
那样删除位置候选;需要推理“源可能朝哪边”,并在定位停滞时仍能可靠
清除。
当前实现的办法是:
- 发现层用 `forward_half_disk` 语义的 31 点最小命中集覆盖计划
(`q4_mincover_v2`);
- 感知层在原有位置网格上叠加 24 档朝向掩码,得到(位置 × 朝向)联合
可行集 `JointBelief`;
- 决策层用联合信念的可见性概率筛选探点,失败时按预算进入 ≤20 m 的
有限格后备清除;
- 调度层用“本站批量扫频 + 按候选 MEC 圆心最近服务队列”的滚动顺序,
避免发现后立即远行、再返回同站扫描的往返。
| 层次 | 文件/类 | 作用 |
| --- | --- | --- |
| 覆盖计划 | `src/mcm26b/guarantee/cover.py`、`guarantee/plans/q4_mincover_v2.json` | `forward_half_disk` 最小命中集与运行期校核 |
| 位置网格 | `src/mcm26b/particles.py::ChannelParticles` | 位置幸存集与 Voronoi 保守裕量 |
| 朝向联合信念 | `src/mcm26b/belief/joint.py::JointBelief` | 每格 24 档朝向掩码、可见性/期望后验半径 |
| 决策闭环 | `src/mcm26b/planner/__init__.py::DirectionalExtension` | 批量扫频、可见性探点、后备清除、收尾 |
| 对比框架 | `project/q4/{optimal,baseline,compare}.py` | `directional` vs `bayes`/`grid` 直接搬用 |
| 回归 | `tests/test_loop_q4.py`、`tests/test_joint_belief.py`、`tests/test_coverage_plan.py` | 真源保留、朝外边界源、后备纪律、证书校核 |
| 结果 | `project/results/q4.{md,json}` | 11 个 core+boundary 场景配对结果 |
## 2. 发现覆盖:`forward_half_disk` 与最小命中集
### 2.1 覆盖语义
设访问点集合为 $S$。对全向源,`no_signal` 在 $s$ 处排除 $B(s,1000)$,
因此完整覆盖只需
$$
\Omega\subseteq\bigcup_{s\in S}B(s,1000).
$$
对定向源,还需要朝向条件。严格的缺席证明要求:
$$
\forall P\in\Omega,\ \forall h\in\mathbb S^1,\quad
\exists s\in S:\quad
\lVert s-P\rVert\le1000
\ \wedge\ (s-P)\cdot u(h)\ge0 .
$$
也就是说,对任意位置和任意朝向,至少有一个被访问点同时落在该源的
1000 m 距离内和 90° 前向半平面内。这个语义称为 `forward_half_disk`。
问题三的七站环不满足该语义:`tests/test_coverage_plan.py` 中有专门用例
验证“七站点集在 `forward_half_disk` 下有缺口”。
### 2.2 49 点 legacy 充分条件
旧实现使用 $S=\{(700i,700j):i,j\in[-3,3]\}$ 的 49 个点:
- 任意 $P\in[-2100,2100]^2$ 到某个网格点的欧氏距离不超过
$700\sqrt2\approx989.95\le1000$;
- 因此对该网格点,无论源朝向如何(前向半平面总是 $180^\circ$),
距离条件都成立。
这是 49 点充分条件,保证发现但代价很高:最近邻开放巡回约 36.4 km;
对无源频道还要在 49 个点各测一次。它现在保留为 legacy 对照与回退计划
`square49`。
### 2.3 31 点最小命中集 `q4_mincover_v2`
当前默认计划由离线贪心集合覆盖搜索得到,并带有可运行期校验证书。
生成参数:搜索分辨率 50 m / 48 档,设计距离裕量
$r_{\rm design}=965$ m,前向角裕量 $5^\circ$;随后用证书分辨率
15 m / 72 档($3\,256\,200$ 个 $(P,h)$ 采样)做精细剪枝,每删一个点都
用同一证书口径复核。
`q4_mincover_v2` 的证书摘要:
| 字段 | 值 |
| --- | ---: |
| 点数 | 31 |
| 覆盖语义 | `forward_half_disk` |
| 校核分辨率 | 15 m / 72 朝向档 |
| 采样目标数 | 3 256 200 |
| 缺口数 | 0 |
| 最坏命中距离 | 990.051 m |
| 最近邻开放巡回 | 23 883.8 m(约 4776.8 s 虚拟移动) |
| 生成器 SHA-256 | `adf4fe6e…434c0e1d`(完整值见 JSON) |
旧 `q4_mincover_v1`(31 点)在粗采样 75 m/24 档下看似零缺口,但在
25 m/48 档有 125 个缺口、15 m/72 档有 566 个缺口,属于采样过拟合;
`q4_mincover_v2` 修正了这一点,点数不变而细网格缺口归零。
**严格连续空间证书的已知残余风险.** 15 m/72 采样格上的零缺口加上设计
裕量可以覆盖相邻未采样 $(P,h)$,但默认 v2 的最坏命中距离 990.051 m
略高于严格连续界要求的约 989.4 m(需满足
$r_{\rm verify}+15\sqrt2/2\le1000$,即 $r_{\rm verify}\le989.4$ m)。
仓库另有 36 点备选计划(最坏命中 973.7 m、巡回约 25.4 km,见
`output/q4/cover-certificate-v3.json`)可关闭该连续性缺口;当前默认的
v2 在 15 m/72 离散证书上零缺口,连续空间残余约 0.65 m,已作为已知
风险登记。若论文要求严格连续证明,应改用 36 点方案并重新验收性能。
### 2.4 运行期校验
`load_plan(name, verify=True)` 会读取计划 JSON 中的证书字段,并用
**证书自带的采样分辨率**重新校核;缺口不为 0 直接拒绝启动。默认
`search.verify_coverage_plan=True`。校核成本在进程内按计划名缓存一次,
15 m/72 档约数秒(见 `scripts/run_suite.py` 的 `plan_verify_wall_s`)。
运行期不会用比证书更粗的采样去“自证”。
## 3. (位置 × 朝向)联合信念 `JointBelief`
### 3.1 网格与朝向档
位置维度复用 `ChannelParticles`:间距 $h=14.65$ m、Voronoi 裕量
$m=\sqrt2/2\,h\approx10.359$ m;朝向维度把整周分为
24 档(每档 $15^\circ$,半档 $7.5^\circ$)。每个位置格附带一个 24 位
掩码,表示该格仍可能具有的朝向;缺省掩码为全档。
联合集合的保守性目标是:**真源 (位置, 朝向) 永不被删除**(在该离散
表示意义下,即真源所在格的朝向至少保留一档,且位置格不被删)。因此
所有判定都向“保留更多”的一侧取整,并计入格内角裕量
$$
\alpha_{\rm cell}=\arcsin\!\left(\frac{m}{\max(d-m,1)}\right),
$$
即格内任一点相对格心到测点方位的最大偏差上界。
### 3.2 观测更新规则
| 观测 | 位置维度 | 朝向维度 |
| --- | --- | --- |
| `direction` @ $s$,读数 $\beta$ | 删除距 $s>1500+m$ 的格;删除角向偏离读数超过 $\delta_{\rm eff}+\alpha_{\rm cell}$ 的格 | 朝向必须**可能覆盖** $s$:保留与方位 $\operatorname{bearing}(g\to s)$ 夹角不超过 $90^\circ+7.5^\circ+1.5^\circ+\alpha_{\rm cell}$ 的档 |
| `near` @ $s$ | 删除距 $s>5+m$ 的格 | 同 `direction`:朝向必须可能覆盖 $s$ |
| `no_signal` @ $s$ | **位置不删**(可能是距离不足或朝向遮挡) | 仅对“整格必在 $r_{\rm eff,min}=1000$ 圆盘内”的格,保留与方位夹角大于 $90^\circ-7.5^\circ-1.5^\circ-\alpha_{\rm cell}$ 的档,即只保留**确定看不见** $s$ 的朝向档;掩码变空则删除该位置格 |
其中 `1.5°` 是朝向查表分辨率带来的保守余量,$7.5^\circ$ 是半档。
`no_signal` 的距离阈值使用 $1000-m$(保守侧):只有在确信整格都在
1000 m 内时,才把静默解释为朝向遮挡;否则保留全部朝向档,避免删掉
真源。
> 2026-09-12 修复记录:早期实现把 `no_signal` 分支的朝向掩码方向写反,
> 会删除真源朝向档;现已改为“只保留确定看不见的档”,并由
> `tests/test_joint_belief.py::test_true_source_survives_consistent_observations`
> 以随机观测序列固化。
联合集一旦为空(所有位置格都被删除),就给出该频道不存在的严格缺席
证明,`absence_evidence` 记为 `joint_empty`。这与覆盖证明是两类独立证据。
### 3.3 可见性与值函数
`JointBelief` 提供两个只用于选点排序的启发式量:
1. `prob_detect(q)`:在测点 $q$ 能看见该频道任一可行
(位置, 朝向) 的概率质量。对抽样格心 $P$:
- 距离概率:$d\le1000$ 时为 1;$d\ge1500$ 时为 0;中间线性插值
(对应 $r_{\rm eff}\sim U[1000,1500]$);
- 朝向覆盖比例:该格掩码中与“$P\to q$ 方位”夹角不超过
$90^\circ$ 的档位占比;
- 两者相乘后对格取平均。
2. `expected_posterior_radius(q)`:一次测量后的期望后验 MEC 半径(D1
值函数)。对每个代表格:
$$
p_{\rm vis}=(1-p_{\rm silent\_range})\cdot\text{cover\_ratio},
\quad
p_{\rm ns}=1-p_{\rm vis},
$$
- `direction` 分支:后验半径用“以 $P\to q$ 方位为读数、$\pm\delta_{\rm eff}$
角域裁剪后的子采样质心最大距离”近似;
- `no_signal` 分支:位置候选**不缩小**,半径保持当前 PF MEC 半径;
- `near` 分支:后验为 5 m 盘。
最后对代表假设取平均。
这两个量的先验(均匀格点、$r_{\rm eff}$ 均匀分布)是工程假设,不承担
任何安全责任;安全责任由覆盖证书、清除证书和联合真源保留定理承担。
## 4. 决策闭环 `DirectionalExtension`
### 4.1 覆盖阶段:本站批量扫频 + 最近队列服务
```text
while 未达到数量上界且未停止:
index = 尚有 UNKNOWN 待测的最近覆盖点(31 点计划)
if 不存在: break
pending = 该点尚未测过的 UNKNOWN 频道
pending 按“当前测向频道优先”排序
for channel in pending:
outcome = /measure(point, channel)
observe(channel, point, outcome) # 更新凸信念 + JointBelief
if outcome == near 且候选集有清除证书:
就地 /clear
queue = 所有 DETECTED 且无证书的频道
while queue:
channel = 距其候选集 MEC 圆心最近的频道
从 queue 移除并调用 _localize_and_clear(channel)
```
与问题三 `SevenBatch` 的结构类似,但覆盖点集、缺席语义和定位逻辑完全不同。
`observe` 对 `direction`/`near` 更新凸候选集和联合信念;对 `no_signal`
只更新联合信念的朝向维度,绝不用于删除凸候选集的位置。
覆盖阶段结束后(所有计划点上的 `UNKNOWN` 频道都测过):
`_mark_absent_after_coverage` 把覆盖账本完整的 `UNKNOWN` 频道标为
`ABSENT`;然后 `_resolve_detected` 再对剩余 `DETECTED` 频道做第二轮
定位。
### 4.2 定位子循环
`DirectionalExtension._localize_and_clear(channel)`:
```text
步数 steps = 0,被遮挡探点表 blocked = []
while steps < max_localize_steps=8:
if 凸/PF 清除证书已成立: 尝试 /clear;成功则返回
if len(blocked) >= max_blocked_probes=4: break # 定位停滞 -> 后备
q = _next_probe(region, channel)
within_range = (|q - region.MEC 圆心| <= safe_disk_radius(region))
outcome = /measure(q, channel)
observe(...)
if outcome == no_signal:
if within_range: 标记 directional_observed
blocked.append(q); continue # 不消耗 steps
else: # direction 或 near
blocked.clear(); steps += 1
循环结束后再检查证书;若仍不可清除 -> _fallback_clear(channel)
```
要点:
- 只有**在保证接收盘内**出现 `no_signal` 才标记“观测到定向”,避免把
距离不足误诊为朝向遮挡;
- 被遮挡探点不重复选取;最多 4 次,随后转入后备清除;
- `direction`/`near` 读数才计入定位步数;
- 每一步后都重新评估证书,滚动推进。
### 4.3 `_next_probe`:联合信念选点与后备梯子
候选点族 `_probe_candidates` 包含:
1. `select_measurement_point` 给出的保证接收盘内最坏后验最优候选
(复用问题二/问题三的选点器);
2. 若已有被遮挡点,取关于 MEC 圆心的对跖方向点,并裁进保证接收盘;
3. 抵近点序列 `center + α*(current-center)`(代码保留,默认
`approach_fractions=()` 未启用);
4. 以 MEC 圆心为心、半径 $0.5\rho,\ 1.0\rho,\ 1.5\rho$ 的 8 方向环探。
候选去重到 0.5 m,并可排除已测过且被遮挡的点。
若联合信念可用,优先调用 `_visibility_probe`(默认口径
`probe_score_mode=nearest_visible`):
1. 对每个候选计算 `prob_detect(q)`;
2. 只保留概率不低于最大值 0.7 倍的候选
(`probe_visibility_ratio=0.7`),避免选中“期望上有点信息、实际必被
朝向遮挡”的点;
3. 在保留候选中选择
$\text{move}(p\to q)+\text{move}(q\to m_{\rm MEC})+6$ 秒最小者
(6 = 检测 5 s + 换频 1 s)。
若联合信念不可用/为空或候选为空,则退回确定性梯子:
未被遮挡过用最坏后验选点器;第一次被遮挡用对跖点;之后绕 MEC 圆心
半径 $\rho$ 的环上每次 +45° 试探。几何边界必须如实说明:环上可见弧
没有正的下界(源可在环上且朝向沿外切线,可见集退化为切点),因此
梯子只是提高命中概率,**完备性由后备清除兜底**。
### 4.4 后备清除:有限格盲清
定位停滞时,`_fallback_clear` 对凸候选多边形生成 20 m 格心的有限覆盖:
1. 用全局 20 m 半开网格与候选多边形求交(带正容差,宁可多保留格);
2. 格内任一点到格心不超过 $10\sqrt2\approx14.14\le20$ m,因此若真源
仍在候选多边形内,逐格 `/clear` 至少命中一次;
3. 格数上界
$(\lceil w/20\rceil+2)(\lceil h/20\rceil+2)$;
4. 若格数超过 `fallback_max_cells=400`,记录
`fallback_cell_cap_exceeded` 并跳过,不硬扫;
5. 若现实剩余预算不足以覆盖
`格数 × real_rtt_p95_s + reserve_exit_s`,记录 `skipped_budget`
并跳过;
6. 通过检查时,按最近邻开放路径逐格 `/clear`;命中成功即标记清除;
全部失败则记录 `fallback_exhausted_without_success`,**不删除候选集**。
后备清除只依赖“清除与朝向无关”这一题面事实,是定向源定位失败时唯一
不依赖可见性的完备性底线;但它受格数上限和现实预算约束,预算不足时
会诚实地保持未完成。`fallback_optimize_tour=False` 为默认:实测把
格间路径排得更短反而会让“命中即停”的真源顺序变差,故不启用。
## 5. 调度、完成条件与预算
### 5.1 与问题三调度层的关系
`DirectionalExtension` 继承 `OmnidirectionalLoop` 的会话、预算、异常
和 summary 骨架,但不使用 `BayesLoop` 的统一任务表/信息增益调度;
它采用“每站批量扫频 + 本站服务队列”的滚动策略(类似 A2 的推广)。
因此:
- 检测/换频/清除的计时口径与问题三完全一致;
- 覆盖点、缺席证据、定位方法、清除证书不同;
- 默认不启用 Held-Karp/2-opt 任务表;后备清除走最近邻。
### 5.2 完成条件
- 清除数达到 16:直接停止并按 `count_cap` 完成;
- 否则要求每个频道 `CLEARED` 或 `ABSENT`,按 `per_channel_proof` 完成;
- 缺席证据来源:
- `coverage`:该频道在 31 点计划上全部测得 `no_signal`;
- `joint_empty`:联合可行集为空;
- 定位/清除尚未完成或预算耗尽:`completed=False`,
`stop_reason=unresolved_channels` / `real_budget_exhausted` /
`virtual_time_cap` 等,不把未完成说成成功。
## 6. 关键参数
| 参数 | 默认值 | 说明 |
| --- | ---: | --- |
| `q4_coverage_plan` | `q4_mincover_v2` | 31 点定向最小命中集 |
| `verify_coverage_plan` | `True` | 运行期按证书分辨率校核 |
| `directional_joint_belief` | `True` | 启用(位置 × 朝向)联合信念 |
| `probe_score_mode` | `nearest_visible` | 可见性过滤 + 移动最省 |
| `probe_visibility_ratio` | 0.7 | 可见概率保留比例 |
| `probe_exclude_blocked` | `True` | 不重复测已遮挡点 |
| `approach_fractions` | `()` | 抵近点默认关闭 |
| `max_localize_steps` | 8 | 每轮定位成功读数上限 |
| `max_blocked_probes` | 4 | 被遮挡探点上限,超限转后备 |
| `fallback_clear_grid_m` | 20 m | 后备清除格边长;$10\sqrt2<20$ |
| `fallback_max_cells` | 400 | 后备格数硬顶 |
| `fallback_optimize_tour` | `False` | 后备走格 NP+2-opt 默认关闭 |
| `persistent_search` | `False` | 找全证明后立即退出 |
## 7. 已验证结果与失效机理
### 7.1 冻结基准集
`project/q4` 在 11 个冻结 core+boundary 场景上的配对结果:
| 方法 | 有效局 | 全清率 | 缺席误判 | 虚拟时间均值 | 中位 | 最大 | 后备清除均值 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| `directional` | 11/11 | **100%** | **0** | 9069.9 s | 8803.3 s | 12081.1 s | 24.8 |
| `bayes` 直接搬用 | 0/11 | 77% | **24** | 3890.8 s | 3646.2 s | 5054.4 s | 0 |
| `grid` 直接搬用 | 0/11 | 67% | 0 | 18179.2 s | 18345.2 s | 20457.9 s | 0 |
两条搬用基线的失效机理不同:
- `bayes` 使用七站**全向**缺席证明;在朝外发射、$r_{\rm eff}=1000$ m 的
边界定向源场景中会把真源直接判成 `ABSENT`。它“快而错”,累计 24 次
缺席误判,虚拟时间不能作为有效优势;
- `grid` 的 49 点覆盖对定向源发现是完备的,但没有朝向推理与后备清除,
定位停滞时只能停在 `DETECTED`,属于“稳而不全”。
`directional` 在 11/11 场景全清、零缺席误判;代价是时间更长,平均
24.8 次后备清除。纯 core 9 场景(不含朝外边界压力)的均值约 8602.0 s、
最大 9630.4 s、后备 4.3 次/局;boundary 场景(朝外发射源)会把后备
推到数十至上百次,单局最大 12081.1 s(16 源 8 定向边界场景)。
因此第四问的时间对“源是否背离圆心发射”非常敏感,不存在对所有合法
场景的均匀性能保证。
### 7.2 覆盖计划消融
| 计划 | 点数 | 15 m/72 缺口 | 最坏命中 | NN 巡回 |
| --- | ---: | ---: | ---: | ---: |
| `square49` | 49 | 0 | ≤1000 m(构造) | 36.4 km |
| `q4_mincover_v1` | 31 | 566 | 1000.0 m | 22.9 km |
| `q4_mincover_v2`(默认) | 31 | **0** | 990.051 m | 23.9 km |
| 36 点严格连续备选 | 36 | 0 | 973.7 m | 25.4 km |
改用最小命中集后,覆盖点减少了 37%,巡回长度从 36.4 km 降到 23.9 km;
但第四问时间的大头仍是 23.9 km 巡回(约 4776.8 s)和逐频道缺席检测。
把七站式的“有源提前停止”规则用于 31 点计划可在一定程度上减少检测,
但最小命中集的巡回与检测开销仍是该问题的成本地板(详见
`docs/第三四问图论与动态规划优化方案.md` §2、§8)。
### 7.3 回归测试
问题四相关测试覆盖:
- 联合信念真源 (位置, 朝向) 在随机观测序列后不丢;
- 朝外发射的边界定向源不漏、不被误判缺席;
- 保证接收盘内 `no_signal` 不删空间候选、判向不越界;
- 后备清除格覆盖候选多边形每个见证点;格数上限/预算检查跳过而非硬扫;
- 全清、零异常、逐微秒计时复算一致。
当前全仓 `pytest` **268 项通过**(2026-09-12 本轮复核)。
## 8. 与问题一、二、三当前实现的复用关系和差异(核对结果)
| 对比 | 复用 | 差异 |
| --- | --- | --- |
| 问题一 | 角域半平面语义、Welzl 最小包围圆 `smallest_enclosing_circle`、MEC 清除证书思路 | 问题四不计算直径/直径圆;`no_signal` 不能解释为距离排除;覆盖语义是 `forward_half_disk` 而非纯角度交集 |
| 问题二 | `select_measurement_point`、`safe_disk_radius` 作为基础候选与“是否在保证接收盘内”的判据;清除点可向当前位置平移 | 定向源在安全盘内仍可能因朝向 `no_signal`,因此问题二的“盘内必收到信号”保证不成立;新增联合信念和可见性筛选 |
| 问题三 | PF 网格位置维度、覆盖账本、会话/预算/异常 summary、清除动作 | 问题三的负观测可删位置候选(`full_disk` 七点缺席证明);问题四的负观测只约束朝向,覆盖计划改用 31 点 `forward_half_disk`,不使用七站全向缺席证明;问题四也不使用 `BayesLoop` 的信息增益任务表 |
| 问题四独有 | — | 24 档朝向掩码、可见性概率选点、对跖/环探后备梯子、20 m 格后备清除及其格数/预算纪律 |
关键结论:**问题四不是“问题三加一点朝向”,而是发现证明、负观测语义和
清除兜底三处都必须重做**。直接套用问题三的 `bayes`(七站缺席证明)会在
朝外定向源上产生缺席误判;直接套用 `grid`(49 点全向)可以发现但无法
可靠定位清除。当前 `directional` 的路线是:最小命中集保证发现、
联合信念推理可见性、预算化后备清除保证清除底线。
## 9. 适用边界与风险声明
- **覆盖证书**:默认 v2 是 15 m/72 档离散证书加设计裕量,零缺口;
严格连续空间证书还存在约 0.65 m 的已知残余,正式论文若要求严格连续
证明应改用 36 点备选计划;
- **联合信念**:真源保留证明依赖评测机观测语义与题面误差界一致;
先验分布、朝向均匀抽样和可见性概率都只是决策启发式;
- **后备清除**:完备性只在格数不超过 400、现实预算足够且候选集确实
包含真源时成立;任一条件不满足就诚实地保持未完成;
- **性能**:11/11 全清来自自建模拟器与冻结场景,不是官方成绩;
当前仓库尚无官方问题四演练。第四问对定向源朝向分布敏感,不能把
core 均值 8602 s 或边界均值 9069.9 s 外推为官方期望;
- **调度**:站点批量与最近队列是贪心,不是全局最优;图论/DP 方案
中的插入、Or-opt、精确任务序等在本场景实测为负收益或未推广到问题四,
默认关闭。
## 10. 复现
```bash
# 冻结基准集:directional vs 问题三策略直接搬用
uv run python scripts/run_suite.py --problem 4 --suite all --jobs 6 \
--variants directional --label q4-current
# 项目对比框架(生成 project/results/q4.{md,json})
uv run python -m project.run --question 4
# 覆盖证书生成与细网格校核(默认计划的来源)
uv run python scripts/verify_q4_cover.py --spacing 100 --radius 2850 \
--target-step 50 --headings 48 --design-radius 965 --heading-margin 5 \
--verify-step 15 --verify-headings 72 --fine-prune \
--write-plan q4_mincover_v2 --out output/q4/cover-certificate-v2.json
# 回归
uv run pytest tests/test_joint_belief.py tests/test_loop_q4.py \
tests/test_coverage_plan.py tests/test_particles.py -q
```
主要文件:
- `src/mcm26b/planner/__init__.py::DirectionalExtension`、`fallback_clear_cells`、
`fallback_cell_bound`:闭环、探点与后备清除;
- `src/mcm26b/belief/joint.py`:联合信念;
- `src/mcm26b/particles.py`:位置幸存集;
- `src/mcm26b/guarantee/cover.py`、`guarantee/plans/q4_mincover_v2.json`:
覆盖计划与证书;
- `src/mcm26b/routing.py`:后备/离线巡回度量。
延伸阅读:`docs/第三四问架构优化与运行提速方案.md`(第四问失败机理与
P0-2/P0-3 实测)、`docs/第三四问图论与动态规划优化方案.md`(联合信念
修复记录与 D1 探点口径消融)、`docs/algo-3.md`(问题三全向闭环)。
## 参考文献
1. 全国大学生数学建模竞赛组委会. 2026 年高教社杯全国大学生数学建模竞赛 B 题[Z]. 2026. 本地题面 `issue/B题.pdf`。
2. 模拟器配套材料. 附件 2《通信接口说明及编程指南》[Z]. 2026. 本地附件 `issue/附件/附件2.docx`。
3. 本项目. `docs/algo-1.md`、`docs/algo-2.md`、`docs/algo-3.md`。
4. 本项目. `docs/第三四问架构优化与运行提速方案.md`、`docs/第三四问图论与动态规划优化方案.md`、`docs/算法审核与优化-20260911.md`。
-167
View File
@@ -1,167 +0,0 @@
# 问题3/4 强化学习选点(PPO + CUDA)
## 0. 摘要
**2026-09-11审核更新:**本文件下方的训练成绩与BC准确率是第一版历史记录。
复核发现训练/部署特征错位、BC激活函数不一致以及评测只检查completed等问题。
当前修复、Maskable PPO新模型和独立配对验证见
[强化学习适用性审核与改进](强化学习适用性审核与改进-20260911.md)。
新模型未替换原默认检查点;通过`--rl-model`显式加载。
本项目在保持 P0–P5 保守性与可解释证明不变的前提下,为问题3(全向源)与
问题4(定向源)增加了一个可选的**强化学习测量点选择策略**:
- 把“下一检测点去哪”建模为离散动作的局部决策问题;401维特征是压缩观测,
不能认定为完整马尔可夫状态,尤其第四问仍有未知朝向和被省略的历史约束;
- 状态由逐频道信念的几何特征 + 60 个候选检测点的几何特征组成(401 维);
- 动作为 60 选 1(保证接收盘环候选、对称交会候选、定向遮挡环探候选);
- 使用 Stable-Baselines3 的 PPO 训练,MLP 策略与价值网络在 **CUDA GPU**
(本机 RTX 4060 Laptop, CUDA 12.8 / torch 2.11.0+cu128)上更新;
- 训练环境基于自建评测机 `referee`(内存回环,与真实 HTTP 协议同边界);
- 运行闭环仅替换既有选点排序器,覆盖证明、清除证书、定向后备清除全部保留。
历史结果(第一版自建配对消融,5 个种子):Q3 用 12 万步随机初始化 PPO(与 `bayes`
基本持平,+1.18%);Q4 用**专家行为克隆初始化 + PPO 微调**,混合源平均
虚拟时间相对 `directional` 基线降低 **7.16%**(14250.1s → 13230.2s)。
Q3 的 BC 初始化在消融中反而退化,因此保留随机初始化模型;Q4 的 BC 初始化
是当时五场比较中均值最好的版本。官方演练验证见 §5:两次 Q4 演练(3 定向混合源、10 定向全定向
场景)与一次 Q3 演练均全清,且通过离线审计。
## 1. 环境搭建(CUDA)
```powershell
# 安装可选依赖组 rl(PyTorch CUDA 12.8 + stable-baselines3 + gymnasium)
uv sync --group rl --group dev
# 验证 CUDA
uv run python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"
```
`pyproject.toml` 中 `[tool.uv.sources] torch = { index = "pytorch-cu128" }`
与 `[[tool.uv.index]]` 指向 PyTorch 官方 CUDA 12.8 轮子;下载约 2.6 GB,
首次同步建议 `$env:UV_HTTP_TIMEOUT='300'`。默认 PyPI 的 Windows torch 轮子
为 `+cpu`,可以使用CPU训练;本轮修订模型即采用CPU,CUDA并非训练前提。
## 2. 第一版局部决策环境
训练环境:`src/mcm26b/rl/env.py::LocalizationEnv`。
| 项 | 定义 |
| --- | --- |
| 初始状态 | 自建模拟器随机布设一个源(Q3 全向;Q4 定向比例可调,训练默认 1.0),机器狗完成一次保证得到 `direction` 的首测 |
| 观测 | 401 维:21 个全局特征 + 20 维频道 one-hot + 60×6 维候选点特征(见 `features.py`) |
| 动作 | `Discrete(60)`:0=候选集 MEC 圆心,1..36=保证接收盘 3 环×12 方向,37..51=对称交会 15 点,52..59=定向遮挡环探 8 点 |
| 转移 | 按动作位置调用 `/measure`,用 `BeliefState` 保守更新候选集;Q4 保证接收盘内 `no_signal` 记为朝向遮挡并进入 `blocked` 序列;证书达标后自动 `/clear`;遮挡梯子用尽后模拟 20m 网格后备清除 |
| 奖励 | `-Δvirtual_time/100`(移动+检测+换频+清除真实耗时)、候选半径收缩加成、首次遮挡证据 +2、重复测点 -0.75、清除成功 +10、失败/截断负奖励 |
约束说明:候选点全部来自既有几何生成器(`planner.candidate_points`、
`planner.safe_disk_radius`、定向环探梯子),RL 不生成新的空间候选;它只做
排序。清除仍须通过几何证书;但“保证收到方向”只适用于全向源且实际点位于
距离保证盘内。第一版的52—59号环探点可能在盘外,第四问的定向遮挡也不受
距离盘保证。v2对第三问加入盘外动作屏蔽,第四问保留探索分支。
## 3. 训练与自建模拟器逻辑利用
```powershell
# 1) 用自建模拟器上的手写专家生成 (观测, 动作) 并行为克隆
uv run python scripts/pretrain_rl_expert.py --problem 3 --episodes 3000
uv run python scripts/pretrain_rl_expert.py --problem 4 --episodes 3000
# 2) 从当前v2 BC初始化继续普通PPO(算法类型需显式匹配)
uv run python scripts/train_rl.py --problem 4 --algorithm ppo --timesteps 40000 \
--init output/rl/q4_ppo_bc_init.zip
# Q3 保留随机初始化长训练版本:
uv run python scripts/train_rl.py --problem 3 --timesteps 120000
```
专家逻辑与自建模拟器同源:Q3 用 worst-posterior 选点器,Q4 用对跖/环探
遮挡梯子;`pretrain_rl_expert.py` 在 `LocalizationEnv` 上记录每个状态的
专家动作,训练与 PPO policy_net/action_net 同构的 MLP,再把权重拷入 PPO
作为初始化。产物位于 `output/rl/bc/` 与 `output/rl/q{3,4}_ppo_bc_init.zip`。
实测:Q3 专家数据 5141 条、BC 验证准确率 38.9%,微调后自建消融退化
(保留 12 万步随机初始化模型);Q4 专家数据 14181 条、BC 验证准确率
65.3%,微调后自建消融从 −3.84% 提升到 **−7.16%**。但审核确认BC与PPO的
激活函数不一致,这些数字不能证明成功迁移了专家策略,也不足以判断全向分支已最优。
输出:`output/rl/q3_ppo.zip`、`output/rl/q4_ppo.zip` 及同名 JSON 报告;
训练脚本先打印 `train_start`(含 device/gpu 字段),再执行 PPO 并在独立
种子场景上确定性评估成功率、平均步数与平均回报。Q4 4 万步微调约 236s;
Q3 12 万步约 625s(RTX 4060 Laptop,2 个 CPU 环境)。
## 4. 运行闭环接入
- Q3:`uv run mcm26b run --robot-id 2026001 --self-test --strategy rl`
`RLBayesLoop` 继承 `BayesLoop`(七点覆盖 + 网格粒子滤波 + 滚动 2-opt),
仅 `_select_point` 改由 PPO 输出候选编号。
- Q4:`uv run mcm26b run --robot-id 2026001 --self-test --problem 4 --q4-strategy rl`
`RLDirectionalLoop` 继承 `DirectionalExtension`(49 点覆盖 + 遮挡梯子 +
20m 有限圆盘后备清除),仅 `_next_probe` 改由 PPO 输出。
- 模型加载时校验观测 401 维 / 动作 60 维,失配直接拒绝运行。
- 默认运行路径不导入 torch/referee;只有显式选择 `rl` 才惰性导入,项目
运行时依赖仍保持 `requests` 一项。
## 5. 消融基准
```powershell
uv run python scripts/benchmark_rl.py --seeds 5
```
同种子同场景配对比较,结果写入 `output/rl/benchmark.json`。以下为第一版历史结果:
| 场景 | 基线 | 平均虚拟时间(基线 / RL) | 相对差 | 全清 |
| --- | --- | --- | --- | --- |
| Q3(10 源全向 ×5 种子,scratch PPO) | `bayes` | 3088.3s / 3124.8s | +1.18% | 5/5 |
| Q4(10 源、3 定向 ×5 种子,BC+PPO) | `directional` | 14250.1s / 13230.2s | −7.16% | 5/5 |
训练局评估:Q3 单源 40 局成功率 100%、平均 3.55 步;Q4 定向单源 40 局
成功率 90%、平均 4.45 步;其余单源训练局未完成,不能由此宣称已兜底成功。随机策略对照:
Q3 平均回报 13.28 vs PPO 17.71;Q4 平均回报 8.72 vs BC+PPO 12.62。
### 5.1 官方模拟器演练验证(仅演练,未触碰正式测试)
使用目录内官方 `jammers-simulator-full` 的**演练测试**(不限次数),通过
官方 HTTP 接口运行同一闭环;官方产物按原名归档并离线审计:
| 问题 | 案例 | 场景真值(演练结束后可见) | 结果 | 虚拟时间 | 请求数 | 审计 |
| --- | --- | --- | --- | --- | --- | --- |
| Q3 | `F38Y-9Q9J-B82V-CB9Z` | 13 全向 | 13/13 全清 | 3538.8s | 124 | ✅ |
| Q4 | `X43X-VMRF-8GRZ-3SYA` | 7 全向 + 3 定向 | 10/10 全清 | 14003.1s | 619 | ✅ |
| Q4(BC) | `BXSA-TFQ3-2DJ6-DHH7` | **10 定向** | 10/10 全清 | 14562.8s | 691 | ✅ |
前两次为随机初始化模型,第三次为 BC 初始化微调模型。两个 Q4 官方案例的
源构成不同(3 定向 vs 10 定向),**虚拟时间不可直接相减比较**;可确认的
是 RL 在官方混合源与全定向源演练中都能完成全部清除,且
`all_timestamps_match_microsecond_recomputation`、官方 `.jlog` 的
SHA-256 校验全部通过。归档目录:`output/rl/official-practice/`。
### 5.2 自建 referee 演练验证
`uv run mcm26b run --local-judge` 走自建 referee 的 `q3_practice` /
`q4_practice` 模块(与官方相同的演练生命周期,真值在结束后可见):
| 问题 | 案例 | 场景 | 结果 | 虚拟时间 | 归档 |
| --- | --- | --- | --- | --- | --- |
| Q3 | `FKUY-K8KJ-RXRL-FMBM` | 10 全向 | 10/10 全清 | 3317.6s | `output/rl/local-practice/q3/20260911-rl-01` |
| Q4 | `3J8T-L9GY-HRGL-LYVZ` | 7 全向 + 3 定向 | 10/10 全清 | 11942.8s | `output/rl/local-practice/q4/20260911-rl-01` |
| Q4(BC) | `VM2G-UVC6-4N7R-TVGW` | 7 全向 + 3 定向 | 10/10 全清 | 12520.8s | `output/rl/local-practice/q4/20260911-rl-bc-01` |
不同案例仍不可直接比较;成对可比的提升证据是 §5 的 5 种子同场景消融。
## 6. 结论与边界
以下是第一版结论;BC权重拷贝缺陷使“同构初始化”的解释不成立,性能判断
应以新审核报告的同场景验证及不确定性为准,而不能由BC分类准确率推出。
- RL 已接入问题3/4 完整闭环,并在自建 referee 演练与官方模拟器演练中
全清验证;这是方法验证,不是对正式成绩的承诺。
- 第一版Q4的BC初始化后均值变化为−3.84% → −7.16%,但初始化存在激活函数
缺陷,样本数也不足以支持“明确收益”的归因;当前判断见新审核报告。
- 训练环境使用自建场景假设(源均匀分布、逐点固定误差场、定向源朝向随机);
官方隐藏分布未必相同。正式测试仍应默认使用经过演练验证的手写策略;
`--strategy rl` / `--q4-strategy rl` 适合消融、方法对比与后续调参。
- 官方演练仅使用“演练测试”按钮与开放接口,从未点击“正式测试”;官方
`.jlog/.result.json` 保持原样,未解密。
- 保守性不变式:RL 只改变选点排序,不改变覆盖账本、候选集更新、清除证书
与后备清除的数学证明;所有策略均以 `/exit` 与完整日志收尾。
+62
View File
@@ -0,0 +1,62 @@
# docs/figures —— 论文插图
每张图只输出 PNG,由 `scripts/make_figures.py` 用 matplotlib 生成。
`manifest.json` 记录每张图的数据来源(路径 + sha256 前 12 位 + 行数)与生成命令。
```bash
uv run python scripts/make_figures.py # 全部 11 张
uv run python scripts/make_figures.py --list # 图名
uv run python scripts/make_figures.py --only geo-q3-seven-point-coverage
uv run python scripts/make_figures.py --scale 1.5 # 整体放大(尺寸倍率)
```
依赖:`matplotlib`、`Pillow`、`docs/paper/fonts/` 下的字体。
`matplotlib` 缓存写入仓库内 `.mpl-cache/`,不污染用户目录。
## 约定
- 图内不放标题、图注与解释性文字,只保留坐标轴、图例与数据标注;
图的含义由文件名与下表承担,解释写在论文正文。
- 配色(`scripts/make_figures.py::C`):深蓝 `#1f4e79` 主流程与协议,
砖红 `#b03a2e` 真值源与关键结论,墨绿 `#1e7a5f` 清除与通过项,
土黄 `#b8860b` 后备与警示,灰色只用于网格与次要文字。
- 字体:中文宋体 `SongtiSC-Regular/Bold`,标题黑体 `HeitiSC-Light/Medium`,
数字与西文 Times New Roman,均取自 `docs/paper/fonts/`,与 `main.tex` 一致。
- 输出为 PNG(`savefig.dpi = 200`,另有 `--scale` 倍率),按 160 mm 宽排版时
与正文同字号。
## 图清单
| 文件 | 内容 | 数据来源 |
| --- | --- | --- |
| `flow-overall-architecture.png` | 总体思路:题面抽象、在线三层、四问主线、三条闭环 | `src/mcm26b/config.py`、`docs/B题建模分析与实施计划.md` |
| `steps-state-machine.png` | 会话状态机(IDLE / 倒计时 / OPEN / CLOSED) | `docs/协议规则表与状态机.md`、`src/mcm26b/protocol/client.py` |
| `timing-attachment-example-105-111-194-199.png` | 附件计时示例逐步推演 | `docs/协议规则表与状态机.md` |
| `timing-measured-q3-10-sources.png` | 实测一局的虚拟时间分解(累计曲线 + 构成) | `referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl` |
| `geo-q1-convex-intersection-zoom.png` | 问题一:角域交会总览 + 定位区域放大(直径圆与 MEC) | `output/q1/practice/U5ZW-P9KN-TCAG-R7ST_observations.json` |
| `geo-q1-diameter-circle-counterexample.png` | 问题一:直径圆不覆盖的反例(等边三角形布站) | `examples/q1/triangle.json` |
| `geo-q2-guaranteed-reception-disk.png` | 问题二:候选盘、截断角域外接圆、安全盘 `B(c, 1000−a)` | `src/mcm26b/config.py`、`docs/algo-2.md` |
| `geo-q3-seven-point-coverage.png` | 问题三:七点覆盖(7 个 1000 m 接收盘的并集覆盖 Ω)与三套计划对比 | `src/mcm26b/planner/seven.py`、`docs/algo-3.md` |
| `geo-q4-minimum-cover-31-points.png` | 问题四:31 点最小命中集与 `forward_half_disk` 语义 | `src/mcm26b/guarantee/plans/q4_mincover_v2.json` |
| `replay-webui-q3-omnidirectional.png` | WebUI 回放画布复现(全向局,10 源全清) | `referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl` |
| `replay-webui-q4-directional.png` | WebUI 回放画布复现(定向源局) | `referee-data/sessions/GM56-DFXZ-XKDM-XYV7/log.jsonl` |
后两张对应 WebUI 的预览功能:把回放器画布上的 Ω 与真值源、运动轨迹、
检测示向度射线、清除标记,以及右侧事件流水与底部虚拟时间轴一起导出。
## 数据来源与复现
- `timing-measured-*`、`replay-webui-*` 读评测机行为日志(JSONL,含真值)。
`referee-data/` 被 `.gitignore` 忽略,因此另归档两局到 `examples/replay/`;
没有评测机数据时脚本自动改读归档,图一致。
```bash
uv run python scripts/archive_replay_logs.py --list # 本机有哪些局
uv run python scripts/archive_replay_logs.py <案例编码> # 追加归档
```
- `geo-q1-convex-intersection-zoom.png` 读官方演练留档
`output/q1/practice/*_observations.json`(同样被忽略)。文件缺失时改读
`examples/q1/triangle.json` 反例算例,图仍可用,只是案例不同。
- 问题一的几何量由生产求解器 `mcm26b.geometry.solve` 现算;
问题三、问题四直接读覆盖计划与证书,不手抄数字。
Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

+192
View File
@@ -0,0 +1,192 @@
{
"generator": "scripts/make_figures.py",
"command": "uv run python scripts/make_figures.py",
"palette": {
"ink": "#1c2430",
"muted": "#5c6673",
"grid": "#e4e9ee",
"primary": "#1f4e79",
"primary_fill": "#dce6f1",
"accent": "#b03a2e",
"accent_fill": "#f6dcd8",
"success": "#1e7a5f",
"success_fill": "#d8ece5",
"warn": "#b8860b",
"warn_fill": "#f6ecd2",
"violet": "#5b4b8a"
},
"fonts": {
"dir": "docs/paper/fonts",
"map": {
"song": "SongtiSC-Regular.ttf",
"song_bold": "SongtiSC-Bold.ttf",
"hei": "HeitiSC-Light.ttf",
"hei_bold": "HeitiSC-Medium.ttf",
"times": "Times New Roman.ttf",
"times_bold": "Times New Roman Bold.ttf"
}
},
"figures": [
{
"stem": "flow-overall-architecture",
"png": "docs/figures/flow-overall-architecture.png",
"scale": 1.0,
"sources": [
{
"path": "src/mcm26b/config.py",
"sha256_12": "c513450dc892",
"lines": 213
},
{
"path": "docs/B题建模分析与实施计划.md",
"sha256_12": "537aaa5790f3",
"lines": 237
}
]
},
{
"stem": "steps-state-machine",
"png": "docs/figures/steps-state-machine.png",
"scale": 1.0,
"sources": [
{
"path": "docs/协议规则表与状态机.md",
"sha256_12": "27c8f7051b26",
"lines": 215
},
{
"path": "src/mcm26b/protocol/client.py",
"sha256_12": "0e9797a85cd7",
"lines": 333
}
]
},
{
"stem": "timing-attachment-example-105-111-194-199",
"png": "docs/figures/timing-attachment-example-105-111-194-199.png",
"scale": 1.0,
"sources": [
{
"path": "docs/协议规则表与状态机.md",
"sha256_12": "27c8f7051b26",
"lines": 215
}
]
},
{
"stem": "geo-q1-convex-intersection-zoom",
"png": "docs/figures/geo-q1-convex-intersection-zoom.png",
"scale": 1.0,
"sources": [
{
"path": "output/q1/practice/U5ZW-P9KN-TCAG-R7ST_observations.json",
"sha256_12": "d2cba13464fd",
"lines": 87
}
]
},
{
"stem": "geo-q1-diameter-circle-counterexample",
"png": "docs/figures/geo-q1-diameter-circle-counterexample.png",
"scale": 1.0,
"sources": [
{
"path": "examples/q1/triangle.json",
"sha256_12": "eeb0c92ae21c",
"lines": 29
}
]
},
{
"stem": "geo-q2-guaranteed-reception-disk",
"png": "docs/figures/geo-q2-guaranteed-reception-disk.png",
"scale": 1.0,
"sources": [
{
"path": "src/mcm26b/config.py",
"sha256_12": "c513450dc892",
"lines": 213
},
{
"path": "docs/algo-2.md",
"sha256_12": "24f3e844deb9",
"lines": 312
}
]
},
{
"stem": "geo-q3-seven-point-coverage",
"png": "docs/figures/geo-q3-seven-point-coverage.png",
"scale": 1.0,
"sources": [
{
"path": "src/mcm26b/planner/seven.py",
"sha256_12": "6ac65bd483f8",
"lines": 113
},
{
"path": "docs/algo-3.md",
"sha256_12": "5638192b8669",
"lines": 456
}
]
},
{
"stem": "geo-q4-minimum-cover-31-points",
"png": "docs/figures/geo-q4-minimum-cover-31-points.png",
"scale": 1.0,
"sources": [
{
"path": "src/mcm26b/guarantee/plans/q4_mincover_v2.json",
"sha256_12": "71e54616ae21",
"lines": 162
},
{
"path": "docs/algo-4.md",
"sha256_12": "1774f8bf85db",
"lines": 485
}
]
},
{
"stem": "timing-measured-q3-10-sources",
"png": "docs/figures/timing-measured-q3-10-sources.png",
"scale": 1.0,
"sources": [
{
"path": "referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl",
"sha256_12": "5a308e53ed09",
"lines": 133,
"case_code": "BBM9-HZG2-77N5-NKKC",
"module": "q3_practice"
}
]
},
{
"stem": "replay-webui-q3-omnidirectional",
"png": "docs/figures/replay-webui-q3-omnidirectional.png",
"scale": 1.0,
"sources": [
{
"path": "referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl",
"sha256_12": "5a308e53ed09",
"lines": 133,
"case_code": "BBM9-HZG2-77N5-NKKC"
}
]
},
{
"stem": "replay-webui-q4-directional",
"png": "docs/figures/replay-webui-q4-directional.png",
"scale": 1.0,
"sources": [
{
"path": "referee-data/sessions/GM56-DFXZ-XKDM-XYV7/log.jsonl",
"sha256_12": "f498b2073cdf",
"lines": 421,
"case_code": "GM56-DFXZ-XKDM-XYV7"
}
]
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

-117
View File
@@ -1,117 +0,0 @@
# HRL P0+P1 执行报告(本地自建评测机)
日期:2026-09-11(本机工作区)
范围:按用户确认,仅完成 P0 正确性回归 + P1 最小可训练/可评测闭环;
P2 的 BC、完整课程长训、Optuna、正式消融与正式测试表留待下一阶段。
## 1. 本轮代码交付
| 文件 | 内容 |
| --- | --- |
| `scripts/benchmark_hrl.py` | 同一 manifest 真值场景复用;`hrl`/`hrl_heuristic`/`bayes`/`directional` 配对评测;写 `results.json`、`aggregate.json/csv`、每局 `summary.json` 与 `session.jsonl` |
| `scripts/train_hrl_high.py` | 高层 MaskablePPO 训练;`--problem/--stage/--envs/--vec-env/--device/--config-profile/--reward-profile/--model/--resume/--init/--eval-manifest`;模型元数据固化 feature/action/reward 版本;墙钟硬上限 |
| `src/mcm26b/hrl/constants.py` | 新增 `ACTION_LAYOUT_VERSION=1`、`REWARD_VERSION=1` |
| `src/mcm26b/hrl/policy.py` | 高层模型严格校验元数据;低层模型保持独立基础校验 |
| `src/mcm26b/cli.py` | 新增 `--strategy hrl`、`--q4-strategy hrl`、`--hrl-model`、`--hrl-low-model`、`--hrl-device`、`--trace-low` |
| `src/mcm26b/hrl/hierarchical_env.py` | 新增 `HRLReward.time_only()`:P0.4 建议的纯时间目标,去掉逐源清除/发现/熵减塑形 |
| `project/` | 严格目录树薄兼容层,转发真实实现,不复制算法 |
| `tests/test_hrl_p1.py` | manifest 往返、真值隔离、纯时间奖励、project re-export 回归 |
## 2. 全量回归
```bash
.venv/bin/python -m pytest -q --tb=short
# 275 passed in 124.57s
```
## 3. P1 smoke 训练(本机 Apple MPS)
```bash
.venv/bin/python scripts/train_hrl_high.py \
--problem 3 --stage 1 --timesteps 2048 --seed 320001 \
--envs 1 --vec-env dummy --device mps \
--config-profile production --reward-profile time \
--model output/hrl/p1-smoke-time/q3.zip \
--eval-episodes 2 --rollout-steps 128 --batch-size 128 \
--n-epochs 3 --max-wall-s 800 --verbose 0
```
结果:
- `actual_timesteps=2048`,墙钟 `260.069 s`;
- 保存后确定性评估 2/2 成功,`accounted=20`,无异常;
- 模型元数据含 `feature_version=4`、`action_layout_version=1`、
`reward_version=1`、`reward_profile=time`、`model_sha256`。
模型重载已由以下两条路径验证;`--resume` 的 `--timesteps` 是增量步数
(SB3 `reset_num_timesteps=False` 语义),元数据写 `timesteps_semantics="additional"`:
```bash
.venv/bin/python -m mcm26b.cli run \
--robot-id 2026001 --self-test --strategy hrl \
--hrl-model output/hrl/p1-smoke-time/q3.zip --hrl-device mps \
--sources 3 --seed 1 --summary-steps 5
python scripts/benchmark_hrl.py --variants hrl \
--hrl-model output/hrl/p1-smoke-time/q3.zip --hrl-device mps \
--problem 3 --scenes 1 --sources 3 --output output/hrl/p1-bench-hrl
```
## 4. 多轮本地配对测试
### Q3:3 个独立场景 × 3 个变体
```bash
python scripts/benchmark_hrl.py --variants hrl,hrl_heuristic,bayes \
--hrl-model output/hrl/p1-smoke-time/q3.zip --hrl-device mps \
--problem 3 --scenes 3 --sources 3 --start-seed 91000 \
--output output/hrl/p1-multiround-q3
```
| variant | episodes | valid_rate | cleared_mean | virtual_time_mean_s | virtual_time_std_s | program_run_time_mean_s |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| bayes | 3 | 1.0 | 3.0 | 2518.371 | 74.183 | 0.748 |
| hrl_heuristic | 3 | 1.0 | 3.0 | 2518.371 | 74.183 | 0.883 |
| hrl | 3 | 1.0 | 3.0 | 3731.380 | 120.536 | 1.853 |
结论:P1 模型只在 stage 1 单源课程上训练 2048 步,可直接重载并在 3 源场景保持 3/3 有效全清;
但用时明显未优于 bayes/heuristic,符合本轮不做正式性能声明的边界。
### Q4:3 个独立混合源场景 × 2 个变体
```bash
python scripts/benchmark_hrl.py --variants hrl_heuristic,directional \
--problem 4 --scenes 3 --sources 3 --directional 1 --start-seed 92000 \
--output output/hrl/p1-multiround-q4 --force
```
| variant | episodes | valid_rate | cleared_mean | virtual_time_mean_s | virtual_time_std_s | program_run_time_mean_s |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| directional | 3 | 1.0 | 3.0 | 13442.997 | 263.902 | 1.063 |
| hrl_heuristic | 3 | 1.0 | 3.0 | 12292.198 | 344.827 | 6.284 |
说明:Q4 高层 PPO 尚未训练;本轮只验证 Q4 的 `hrl_heuristic` 与 `directional` 闭环、真值隔离与计时审计。
## 5. P0 状态
- `--resume` 重载:16 步起步模型续训 32 增量步后 `actual_timesteps=48`,
校验 `feature_version/action_layout_version/reward_version` 后保存;
- 槽位唯一性:`test_hrl.py` 覆盖 channel 17–20 与 1–4 同时 clear/locate 不丢;
- 清除事件一次且仅一次:fallback 成功写 `_step_clears` 已有回归;
- 候选快照:`test_opportunity_measure_precedes_candidate_snapshot` 已覆盖;
- 奖励对齐:新增 `HRLReward.time_only()`,训练脚本默认 `--reward-profile time`;
- 终止/安全网:现有 `HierarchicalEnv` 回合测试继续通过;
- 训练/部署配置:`--config-profile production` 使用生产配置,`coarse-pretrain`
显式映射到 fast 评分配置并写入模型元数据;
- 依赖守卫:全量测试 275 项在 dev+rl 环境通过。
## 6. 未完成 / P2 待办
- `scripts/pretrain_hrl_expert.py` 已建可 `--help` 的接口占位,专家轨迹 + BC 功能待实现;
- `scripts/ablate_hrl.py` 已建接口占位,无信息增益/无掩码/无课程/无粒子统计消融待实现;
- `scripts/tune_hrl.py` 已建接口占位,Optuna TPE 搜索待实现;
- Q3→Q4 迁移训练与配对实验;
- 完整 10–16 源课程训练、多个训练种子、冻结测试清单;
- 官方三次正式测试表:必须有真实官方案例码与导出日志后才能填写;
本地 `referee` 结果只标 `local_self_test`。
-267
View File
@@ -1,267 +0,0 @@
# HRL 续作执行说明:交给 Sol 的工程任务书
适用日期:2026-09-11。工作目录:本仓库根目录。先检查当前代码与本轮测试结果,再按 P0 → P1 → P2 → P3 顺序执行。
目标是交付可运行、可审计的整场调度学习系统;训练收益由完整场景验证决定,不把训练脚本存在或局部奖励上升视为完成。
本说明更新了原粘贴 Prompt 与 `.zcode/plans/plan-sess_cf390556-4ef3-4ce6-b91e-782aee1718f9.md` 中不符合现有协议或证据的部分。
## 1. 现在有什么,缺什么
| 组件 | 当前状态 | Sol 的操作 |
| --- | --- | --- |
| `protocol/`、`referee/`、`harness.py` | 已有客户端、独立评测机、内存回环与计时审计 | 复用,不另建模拟器客户端 |
| `belief/`、`particles.py`、`planner/` | 已有保守候选、网格幸存集、覆盖证明、证书清除与后备清除 | 保持证明前提;改调度时复用 |
| `rl/`、`train_rl.py`、现有 RL 检查点 | 已有单源选点 PPO/MaskablePPO 与完整对照 | 作为局部策略和对照,勿命名为端到端 PPO |
| `hrl/constants.py`、`scheduler.py`、`planner/hrl_loop.py` | 已有高层候选、特征、执行与闭环骨架;存在本轮需修复的 P0 项 | 先完成第 4 节门槛 |
| `hrl/hierarchical_env.py`、`curriculum.py` | 已有训练环境和课程;奖励、终止、训练配置仍需审核 | 在长训前修正,覆盖独立环境/部署一致性 |
| `hrl/low_level_env.py`、`executor.py`、`train_hrl_low.py` | 有八方向到达实验;训练入口尚有掩码等缺陷 | 作为可选离线实验,不能卡住主线 |
| `tests/test_hrl.py` | 有接口和启发式 episode 测试 | 增补行为验证,不能只检验公式与实现一致 |
| `train_hrl_high.py`、`pretrain_hrl_expert.py` | 尚未实现 | P1 编写最小可训练闭环,P2 再加入 BC |
| `benchmark_hrl.py`、`ablate_hrl.py`、`tune_hrl.py` | 尚未实现 | 先评测,再训练,再做消融,最后受限调参 |
| CLI 的 `hrl` 策略和 `--hrl-model` | 当前入口尚未接入 | P1 接入并检验 `--help` 与离线闭环 |
| `output/hrl/` 的高层模型、曲线、评测表 | 本次审阅未发现这些产物 | 不声称已有 HRL 模型或训练成绩 |
现有证据:修订单步 RL 的 Q3 独立验证均值比 `bayes` 低 0.69%,区间跨 0;Q4 比 `directional` 低 14.38%,比旧 PPO 低 2.26%,后一比较区间跨 0。
这些来自固定模型、本地 18 场/题的验证;新 Q4 的后备清除次数更多,边界压力性能有退化。详情见 `docs/强化学习适用性审核与改进-20260911.md`。
没有证据证明 HRL 已优于上述基线,没有证据支持“Q4 迁移节约 80% 训练成本”或“全部合法场景小于 4000 秒”。
## 2. 必须纠正的原 Prompt 假设
1. `/measure` 与 `/clear` 提交终点,移动按两次实际动作位置间的直线距离除以 5 计费;没有朝向、转弯或八方向移动协议。
2. 八方向策略仅在本地推演再强制补上终点,无法影响模拟器实际路径;不能把这段推演称为比赛收益来源。
3. `/clear` 不切换接收机频道,目标频道与当前接收机频道应分别记录;`near` 是测量结果,清除仍需独立请求。
4. 接收半径逐源未知,动作掩码只能使用观测与保守界,不能读真实半径、源位置、类型或朝向。
5. Q3 的 `no_signal` 只能按已证明的保守半径规则删格;Q4 的 `no_signal` 可能由方向遮挡造成,不能直接删空间候选。
6. Q4 联合位置/半径/朝向粒子是后续研究选项;普通二维粒子加“角度门控”并不会自动得到正确联合后验。
7. 固定地点误差固定;同地重测不是新独立样本。保留读数舍入裕量,不收紧真实的 ±1° 误差界来追求表面收敛。
8. 源数最多 16 不等于只有 16 个频道;所有按频道编号索引的动作必须覆盖 1–20。
9. 连续无信号次数不能作为全场结束条件;覆盖参数不能随意调到破坏已证明的发现覆盖。
10. “无信息增益”“无动作掩码”“无粒子滤波”必须精确定义;不能通过取消清除证书或真源保留约束制造消融。
11. 原 Prompt 的 6 个状态与实现里的状态枚举不一致;以 `ChannelStatus` 为准,额外 TRACKING/LOCATED 只能定义为派生特征。
12. 协议文档 §6 仍写持续搜索默认开启;当前 `config.py` 为 `persistent_search=False`,CLI 用 `--persistent` 显式开启。先同步文档,不恢复过时默认值。
## 3. 推荐架构与工程边界
采用“高层学习调度 + 低层局部选点 + 协议执行”的分层架构。高层学习先处理哪个频道、继续覆盖还是定位、何时使用后备清除。
低层默认调用成熟几何选点;可切换现有 `PointSelectionPolicy` 学习局部检测点,形成第二个学习层。直线移动与设备动作继续由协议客户端执行。
Q3 首版低层用 `bayes` 几何选点;Q4 先保留 `directional` 的遮挡处理,待接线一致性通过后对比旧/新局部 PPO。
```text
SimulatorClient.state + belief + particles + coverage ledger
↓ 同一份候选快照和动作掩码
高层 MaskablePPO:选择频道/覆盖站/清除任务
↓
局部选点:geometry | 已有 v2 PointSelectionPolicy
↓
证书/预算/覆盖约束 + 实际 measure/clear 宏动作
↓
accepted 请求与响应 → 时间、信念、清除与覆盖账本
```
八方向 PPO 保留为 `low_level_env.py` 的离线附录实验;生产默认无需加载。若论文要求字面双 PPO,用高层调度 PPO + 局部选点 PPO 对应真正可影响成绩的两个层次。
现有高层一个动作可以包含整站逐频道扫描或多次后备清除,因此是变长宏动作。记录每个宏动作的实际持续时间、请求数和中断原因。
先采用 `gamma=1` 与实际时间成本,避免把“每宏动作折扣一次”误当成“每秒折扣一次”;只有明确改变目标才引入按持续时间折扣。
第一版保留 120 槽位 MLP,不同时重写注意力网络或连续动作;需要多候选/频道时另升动作版本并独立比较。
建议新增的共享接口如下;这些是待实现契约,避免训练和 CLI 分别拼接策略。
```python
@dataclass(frozen=True)
class HRLPolicyConfig:
local_selector: str = "geometry" # geometry | rl
local_model_path: str | None = None
def make_hrl_loop(client, config, *, problem: int,
high_policy=None, policy_config=HRLPolicyConfig()) -> HRLLoop: ...
def validate_episode(summary: dict, events: list[dict],
truth_channels: set[int]) -> dict: ... # 仅评测模块
def run_episode(scene: dict, variant: dict, *, output_dir: Path) -> dict: ...
```
## 4. P0:修复正确性,未过门槛不得长训
以下表中的状态以本轮提交和测试报告为准;Sol 接手时先查看 diff,已完成的项只做回归,不重复实现。
| 项目 | 精确入口与问题 | 目标与验收 |
| --- | --- | --- |
| P0.1 槽位冲突 | `constants.py`;`scheduler.build_candidates/heuristic_action`:clear 频道 17–20 与 locate 频道 1–4 重叠 | 本轮优先修复;每类按 20 频道分配,构造同时就绪冲突场景验证任务均保留 |
| P0.2 清除事件遗漏 | `scheduler._hrl_execute_fallback` 成功未写 `_step_clears` | 本轮优先修复;证书/后备/宏动作内部清除均由相同成功事件口径计数,一次且仅一次 |
| P0.3 候选过期 | `HRLLoop._coverage_phase` 在构建候选后 `_measure_at_stop` 可改变信念 | 本轮优先修复;选动作前候选/特征/掩码属于同一个状态快照 |
| P0.4 奖励对齐 | `HierarchicalEnv.step/_reward_from/HRLReward` | 改默认奖励,成功/异常/安全网/截断均计入已经发生的真实时间 |
| P0.5 回合终止 | `HierarchicalEnv.step/reset/close` | 实际完成、失败终止与采样截断分开;收尾不丢 /exit,不把零观测用于有效截断 bootstrap |
| P0.6 训练部署配置 | `curriculum.training_config` 默认网格 29.3m,部署 14.65m | 首个可比较模型使用生产几何配置;粗网格只能显式快速预训练,后接完整保真微调与评测 |
| P0.7 无进展循环 | `scheduler` 的 locate/probe/fallback 掩码及预算检查 | 去重、已清除/无效证书、后备预算不足在动作前处理;合法动作不能无限零成本自循环 |
| P0.8 测试与依赖 | `tests/test_hrl.py` 导入守卫、`policy.py/scheduler.py` 顶层 numpy | 不安装 RL 组时基础 CLI 可导入;完整 RL 环境运行测试时不得意外全部 skip |
建议槽位布局为 clear 0–19、locate 20–39、station 40–88、fallback 89–108、保留 109–119;所有槽位互斥且小于 120。
槽位含义改变必须升 `FEATURE_VERSION`,即使仍是 1248 维/120 动作,也必须拒绝旧语义检查点。
模型元数据应要求 `level/problem/algorithm/feature_version/action_layout_version/reward_version`,并记录模型 SHA、配置、依赖版本、代码版本。
缺字段不能默认为兼容;Q3 权重初始化 Q4 必须走显式训练迁移参数,部署加载仍严格检查题号。
默认奖励先用:`r = -实际本步虚拟时间增量 / 100`;证明完成时加固定完成奖,未完成的真实终止加失败罚。
失败惩罚按冻结的 episode 最大成本界设置并记录,不随意用不足以覆盖数千秒的 `-100`。
相同全清场景里逐源常数奖可能只是常数偏移,但不同终止路径、事件漏记和失败场景会改变激励;故首版去掉新发现/熵减/每源清除附加奖。
如需塑形,另做势函数差 `gamma * Phi(next_state) - Phi(state)`,真正终止态统一势函数值,并检验总和望远镜消去。
如果优化题目平均时间,用整场时间作为训练目标时明确这是所选代理;不同源数的跨场景均值与 `T/N` 均值不等价,不能暗称完全一致。
人工步数上限若仅为采样截断,返回可用的终末观测并允许 bootstrap;若定义为任务失败期限,应作为真实终止计罚。按该语义设计测试。
P0 验收至少覆盖以下行为,不只验证 reward 按代码相加:
- 20 个频道的各类槽位唯一;频道 17–20 与 1–4 同时有 clear/locate 不丢任务。
- 同一观测轨迹分别构建独立训练环境与部署闭环,比较候选、mask、特征、下一实际请求及状态。
- 固定动作序列跨成功、失败、后备与安全网路径:reward 的时间分项总和等于 accepted 日志复算时间。
- Q4 保证盘内/盘外无信号不误删真源;正读数重置遮挡序列;无效证书不能执行清除。
- 10/16 源、频道含 20、边界源与预算中断均检查真实源集合、缺席集合、正常退出、异常与计时。
- 评测端真值仅进 `validate_episode`,策略构建、候选、mask、观测与模型选择均不得读取真值。
## 5. P1:最小完整闭环,先评测再短训
先实现 `scripts/benchmark_hrl.py` 与共享审计函数,使 `HRLLoop(high_policy=None)` 可以与原 `bayes/directional` 同场景对比。
这个启发式 HRL 骨架是重要对照:若差距来自任务候选、机会测量、Q4 保底或预算语义变化,先修或如实量化,不归因给神经网络。
每次运行将 scene、误差种子、配置、summary、完整 JSONL/accepted 事件、时间复算和模型 SHA 写入新目录;目录已存在则拒绝覆盖。
单场异常也写结果;聚合存在任一无效局时 `all_valid=false` 且脚本非零退出,不从平均值表中静默删除失败场景。
随后实现 `scripts/train_hrl_high.py`,第一版提供以下参数并通过 `--help` 验证:
```text
--problem {3,4} --stage {1,2,3,4} --timesteps INT --seed INT
--envs INT --vec-env {dummy,subproc} --device {cpu,cuda,mps,auto}
--config-profile {production,coarse-pretrain}
--model PATH --resume PATH --eval-manifest PATH --verbose INT
--local-selector {geometry,rl} --local-model PATH
```
阶段 1 即保持 20 频道与固定观测维度,只改变布景复杂度;早期课程可减少源数,但完整训练必须覆盖 10/13/16 源与实际 ±1° 固定地点误差。
Q4 完整课程同时覆盖少量/半数/大量定向源及近边界向外朝向;Q3→Q4 迁移与 Q4 随机初始化作为配对实验。
禁止让策略知道课程场景真实源数或隐藏的占用频道列表;初始位置保持官方 `(0,0)`,除非任务被明确标为局部交接课程。
先测 1/2/4 个环境的采样吞吐、内存和每次决策耗时,再选择 Dummy/Subproc;小 MLP 不假定 GPU 更快。
Subproc 环境类内部提供 `action_masks()`;Windows/macOS 使用入口守卫及可序列化工厂。
随机种子覆盖 Python/NumPy/Torch、PPO、每个环境、场景误差;每个 worker 使用独立 Monitor 文件。
保存实际 `model.num_timesteps` 与请求步数,恢复时说明增量还是累计;续训加载正确算法/特征版本且不覆盖原模型。
使用掩码评估接口,如 `MaskableEvalCallback`;同时在确定性推理中传入同源 mask。
CLI 加入 `--strategy hrl`、`--q4-strategy hrl`、`--hrl-model` 与局部策略选项,经 `make_hrl_loop` 统一构建;默认策略保持现状。
显式指定缺失模型应报可操作错误,不能把启发式降级结果记成 HRL 模型成绩;启发式骨架单独命名 `hrl_heuristic`。
P1 门槛:启发式骨架全场审计通过;512–2048 步训练冒烟可保存、重载、确定性推理;CLI 内存回环至少 Q3/Q4 各一场通过。
短训先用单个种子验证流程,不用这次模型的成功率作论文结论;完成后记录吞吐再定时间预算,不预设 1–2 小时足够。
## 6. P2:完整保真训练、独立评测与消融
实现 `pretrain_hrl_expert.py`:运行 `hrl_heuristic`,保存 `(episode_id, state, candidates, mask, action)`;按 episode 划分训练/验证。
BC 与 PPO 的网络层、激活、归一化、mask 处理保持一致;复制后在真实样本上逐位比较 logits,critic 单独初始化。
记录专家动作无法映射到候选的比率与原因;若大量回退到最近候选,先改专家映射,不用假专家标签继续训练。
至少比较 BC+PPO 与随机初始化 PPO;BC 准确率单独报告,不能代替独立闭环用时与有效全清率。
冻结数据集分工:
| 集合 | 用途与约束 |
| --- | --- |
| 已有 700–702 开发场景 | 查实现错误、探索配置与性能分解 |
| 已有 91000–91005 场景 | 历史回归;结果已经被审阅,不再宣称是本次全新盲测 |
| 新开发/选择清单 | 固定 JSON manifest,记录 seed、源数、定向组成、error_seed;用于训练选择和调参 |
| 新冻结最终测试清单 | 与训练、BC、调参及选择清单不重叠;模型冻结后运行,失败后修改则新开一轮测试 |
| 压力场景 | 圆周边界、1000m 半径、向外/切向定向、高频道、固定误差与预算边界;单独汇总 |
同场景每个变体用相同位置、频道、半径、朝向和地点误差函数。每个模型至少跑 30 个完整场景,再按预算扩大;“30”是工程起点,不是统计充分性证明。
最终用于稳定收益结论的主方法至少 5 个独立训练种子;场景种子与训练种子分开报告,不能用 5 个场景替代 5 次训练。
Q3、Q4 分开统计,并按源数/定向占比分层;所有基线与候选使用相同停止、预算和计时口径。
| 指标 | 固定定义 |
| --- | --- |
| 有效全清 | 成功清除频道集合等于评测真值;缺席集合与真值不交;completed、正常 exit、无异常、计时一致 |
| `virtual_time_s` | 实际退出前的完整虚拟时间;主竞赛口径显式 `persistent_search=False` |
| `avg_locate_clear_time_s` | 每场 `T / 实际清除数`;有效全清主表再做逐场平均,另报源数分组 |
| `accounted_virtual_time_s` | 首次完成证明的时间;与最终时间并列,不悄悄用它替换正式计分 |
| 运行时间 | 每场实际墙钟、模型推理耗时分位数;本地内存回环时间不冒充官方程序运行时间 |
| 成本分解 | 移动秒、测量秒、换频秒、成功/失败 clear 秒、后备尝试、重复测量、总请求数 |
| 尾部与失败 | 中位数/P90/P95/最大值、有效全清率、失败明细;小样本尾分位注明估计局限 |
平均 `T/N` 不等于 `平均 T / 平均 N`;若另用总体总时间/总源数,明确标为按源数加权口径。
配对效应以同场景时间差为基础,报告均值相对变化、胜出场数、95% 配对 bootstrap 区间;相同场景家族共享种子时按家族重采样。
多训练种子结果报告种子间分散程度;必要时对训练种子和场景做分层重采样,不能用单一场景区间代表训练稳定性。
最小比较矩阵:`bayes/directional`、旧局部 PPO、修订局部 MaskablePPO、`hrl_heuristic`、高层 PPO+几何、后续高层 PPO+局部 PPO。
此矩阵先回答“改调度是否有用”和“增加局部学习是否有用”;既有单步 RL 不能命名为无几何的端到端基线。
若仍要端到端 PPO,必须单独定义输入、实际动作、安全执行边界并训练,标记预算;它不是 P1 完成条件。
每项消融使用相同训练步数/场景预算/种子和评测集,单次只改变一个因素:
- 调度:学习高层 vs `hrl_heuristic`,保持候选生成和局部选点一致。
- 局部策略:同一高层与执行接口下,geometry vs 现有局部 PPO;报告是冻结替换还是联合重训。
- 塑形:纯时间目标 vs 经过恒等式核验的势函数塑形;无信息增益奖励就是系数为 0。
- 课程:相同总交互步数的课程训练 vs 从完整场景开始训练;Q4 迁移另列,不预设节约百分比。
- 掩码:只取消重复/低效候选等策略性屏蔽;协议合法性、证书和预算硬守卫始终保留,标明实际取消范围。
- 粒子特征:保留几何守恒内核,先将粒子统计输入和评分消融;若真的移除粒子模块,另实现保守几何替代并重新验证。
- 八方向:只报告离线到达率/路径效率/推演耗时,以及实际协议终点相同时成绩相同的事实。
P2 推广门槛:所有最终与压力场景有效,Q4 相对最强已冻结基线的时间差区间上界小于 0;尾部容忍度先写入 manifest。
建议初始尾部门槛为 P95 不退化超过 5%,这是可调整的工程标准,不是题设要求;任何调整都在重跑最终测试前完成。
Q3 若未显示稳定收益,保留 `bayes` 默认并交付负结果。仅比手写基线快、却未优于现有 PPO,不能宣布替换默认模型。
## 7. P3:受限调参、论文与官方验证
只有 P2 主方法具备竞争力才实现并运行 `tune_hrl.py`。先搜索学习率、熵系数、网络宽度、GAE、合法候选排序参数。
不搜索真实误差上限、光学清除半径、无信号停止次数或破坏覆盖证明的网格间距;确定性网格没有粒子重采样阈值可调。
Optuna 只用开发/选择清单,失败配置先按有效性淘汰;预算与失败/剪枝逻辑写入结果。最终模型重新用固定配置多种子训练。
文档、流程图与论文表明确:学习负责哪些决策、证明由哪些模块提供、本地生成分布未知是否对应官方分布。
训练曲线、实际步数、配置、全部对照与失败明细均归档;不要只挑最好种子或去掉不利的边界场景。
官方三次测试需要对应演练已经启动、真实案例码与官方导出日志;本地 referee 的三场不能填写成“三次正式测试”。
不覆盖旧官方归档;官方结果与本地结果分表,不对不同官方案例直接计算改进百分比。
## 8. 命令:已经存在与待实现的严格区分
以下入口当前已经存在;依赖需先安装,命令失败要修复或如实报告,不能跳过错误声称通过:
```bash
uv sync --group dev --group rl
uv run python -m pytest -q --tb=short
uv run python -m pytest -q tests/test_hrl.py --tb=short
uv run mcm26b run --help
uv run mcm26b run --robot-id 2026001 --self-test --strategy bayes
uv run mcm26b run --robot-id 2026001 --self-test --problem 4 --q4-strategy directional
uv run python scripts/train_rl.py --help
uv run python scripts/train_hrl_low.py --help
```
`train_hrl_low.py` 目前仅 `--help` 可用于检查入口,不把完整训练列为已可用:
其 `MaskablePPO.learn()` 需要环境掩码,当前 `LowLevelEnv` 没有 `action_masks()`;改普通 PPO 或提供全 True 掩码后再试。
还需修 BC 按 episode 划分、统一随机种子、每 worker 独立 Monitor 文件、评估 seed 生效、实际路径长度与成功率分开统计。
低层到达失败不能靠 executor 最后强制补终点伪装成策略到达;环境裁剪后的实际移动长度也不能简单记为 `steps*100m`。
下面是 P1/P2 实现后必须支持并实测的命令契约,当前尚不能直接运行:
```bash
# P1:先验证不加载模型的共享调度闭环
uv run python scripts/benchmark_hrl.py --variants hrl_heuristic,bayes,directional --manifest output/hrl/manifests/dev.json --output output/hrl/p1-heuristic
# P1:完整保真冒烟;模型目录必须是新目录
uv run python scripts/train_hrl_high.py --problem 3 --stage 1 --timesteps 2048 --seed 320001 --envs 1 --vec-env dummy --device cpu --config-profile production --model output/hrl/p1-smoke/q3.zip --verbose 0
# P1:CLI 明确加载高层模型
uv run mcm26b run --robot-id 2026001 --self-test --strategy hrl --hrl-model output/hrl/p1-smoke/q3.zip
# P2:正式阶段训练;步数先依据采样吞吐与学习曲线再调整
uv run python scripts/train_hrl_high.py --problem 4 --stage 4 --timesteps 60000 --seed 420001 --envs 2 --vec-env dummy --device cpu --config-profile production --model output/hrl/p2/q4-seed420001.zip --eval-manifest output/hrl/manifests/select.json --verbose 0
# P2:冻结模型完整对照;variants 的模型位置来自同目录的配置清单
uv run python scripts/benchmark_hrl.py --variants hrl,hrl_heuristic,legacy,revised,baseline --manifest output/hrl/manifests/final.json --output output/hrl/p2-final
```
命令使用的 manifests 也要由脚本生成、校验并归档;尚不存在的模型不能当作初始化输入。
添加 `--full` 一键课程入口时,它应展开并记录每阶段命令/配置/检查点链,失败即停,可继续,不是忽略错误的 shell 包装。
参考现有依赖配置:基础运行依赖仅 requests;RL 为可选组。固定环境版本并记录硬件,勿假定当前执行机就是旧报告中的 RTX 4060。
## 9. 可以直接粘贴给 Sol 的续作 Prompt
```text
继续当前仓库的 HRL 工作。先读 docs/hrl-sol-execution.md、最新测试结果与 git diff,保留现有修改。
已有客户端/referee/几何/PPO 都要复用;不要重写骨架,不把缺失脚本或 CLI 说成已完成。
先完成 P0 尚未关闭的奖励、终止、完整保真配置、掩码和依赖问题;本轮已修的槽位/清除事件/候选过期只回归。
采用高层 MaskablePPO 调度 + 几何/已有局部 PPO 选点 + 协议直线执行;八方向只作为可选离线实验。
按 P1 先实现 benchmark_hrl 与真值隔离审计,再实现 train_hrl_high、模型元数据和 CLI,跑可重载的短训冒烟。
P0/P1 没通过就修实现,不用加训练步数掩盖问题。通过后再开展 BC、完整保真课程、多训练种子、冻结场景配对评测。
保持 Q3 bayes/Q4 现有默认策略;完整实验胜出前不覆盖默认模型。主指标包含有效全清、T、逐场 T/N、请求分解和尾部。
每阶段交付具体文件、实际执行命令、测试结果、模型/日志路径与未完成项;不预设 Q4 80% 节约或 4000 秒保证。
官方测试只有真实演练开始并获得案例码/导出日志才记正式结果,本地实验单独标注。
```
接口参考:[MaskablePPO 官方文档](https://sb3-contrib.readthedocs.io/en/master/modules/ppo_mask.html),[Gymnasium 终止与时间限制](https://gymnasium.farama.org/tutorials/gymnasium_basics/handling_time_limits/)。
Binary file not shown.
+69 -9
View File
@@ -49,11 +49,10 @@
{\heiti\zihao{4} 摘\quad 要}
\end{center}
无线电干扰源的测向与规划问题在生产和军事上的应用十分广泛。
\texttt{no\_signal}、\texttt{near}、\texttt{direction} 为唯一信息来源,建立
\textbf{有界误差交会定位—主动选点—覆盖证明搜索—动作耗时调度}的统一框架:四个问题
复用同一几何内核,以覆盖证明与严格停止条件保证“清除所有干扰源”的硬约束,再优化
时间指标。
无线电干扰源的测向与路径规划问题在生产和军事上的应用十分广泛。城市的非法无线电
台清查与战场的无线特征定位等日益增长的需求,与该问题的关联十分紧密。本文建立一种
基于【此处填入方法】的无线电测向多元优化方法,以便特定用途的机器狗等设备在复杂环
境中能够以更高效率完成无线电发射源测定、清除工作。
\textbf{针对问题~1},将 $\pm 1^{\circ}$ 有界误差下的测向观测建模为以检测点为顶点的
前向角域 $W_i$,交会定位区域即诸角域的半平面交 $P=\bigcap_i W_i$,给出直径
@@ -97,12 +96,73 @@ $N\le(\lceil w/20\rceil+2)(\lceil h/20\rceil+2)$,并纳入现实时间预算
% 正文(不超过 30 页,不要目录)
% ============================================================
\section{问题重述}
\subsection{问题背景}
无线电干扰源的定位与清除是无线电频谱管理的重要任务。干扰源定位通常分为
初步监测、区域性排查和精准定位三个阶段:前两个阶段使用固定监测站、移动
监测车或无人机等设备进行大范围信号采集与分析,确定干扰源目标的分布区域;
而受限于环境遮挡、低功率干扰源等因素,精准定位最终需要技术人员在目标
分布区域内携带便携式无线电方位监测测向机(简称测向机)等手持设备徒步
排查,通过观察分析信号场强变化、方向特征并结合经验判断,逐步定位并清除
干扰源。为尽快消除干扰造成的不良影响,定位清除任务的完成时间越短越好。
为此,某公司拟研发搭载于机器狗的干扰源自动定位清除系统,在危险环境中
代替技术人员开展定位及清除工作,以提高定位及清除效率。
干扰源目标分布区域已被确定为一个半径为 $1800$ 米的圆形区域,取此圆域
中心为坐标系原点,正东方向为 $x$ 轴正向,正北方向为 $y$ 轴正向(单位:
米),目标区域中干扰源个数未知。干扰源的特征由题目附录~1 给出:每个
干扰源的频谱互不相同,分布于编号 $1$ 至 $20$ 的 $20$ 个频道;不同干扰源
的信号互不影响;按信号覆盖角度范围分为全向干扰源(有效覆盖角度
$360^{\circ}$)与定向干扰源(定向方向两侧各 $90^{\circ}$ 含边界,此角度
范围之外没有信号辐射);在有效覆盖角度范围内信号均匀辐射,场强仅随距离
衰减,与角度无关。
系统的检测原理和工作方式由题目附录~2 给出:测向机在检测点处测得干扰源
的示向度(自 $x$ 轴正向逆时针计量,范围 $[0^{\circ},360^{\circ})$),
示向度与真实方位角之间的误差在 $[-1^{\circ},1^{\circ}]$ 范围内,且同一
地点重复检测不会改变检测误差;各干扰源的有效接收半径在 $1000$ 至 $1500$
米之间;测向机不能同时检测多个频道,任意两个频道之间的切换时间为 $1$
秒;机器狗沿直线行进、移动速度为 $5$ 米/秒,移动过程中无法有效检测,
每次停机检测耗时 $5$ 秒;检测点距干扰源不超过 $20$ 米时可光学精确定位
($3$ 秒)并启动激光枪清除($2$ 秒),清除成功与否仅与距离有关;距离
不超过 $5$ 米时因信号太强无法获得示向度信息,此时可直接进行光学精确定位
并清除。利用多个检测点对同一干扰源的示向度,可以采用交会定位法确定
多边形定位区域。
问题~3、4 的算法须通过无线电干扰源环境模拟器进行测试:机器狗程序经
HTTP+JSON 接口与模拟器通信,自动完成检测与清除。正式测试中机器狗从原点
$(0,0)$ 出发、初始频道为 $1$,每次测试须按题目表~1 的格式记录测试案例
编码、清除干扰源个数、平均定位清除时间与程序运行时间。
\subsection{问题提出}
\textbf{问题~1}:已知若干个检测点坐标及某干扰源关于这些检测点的示向度,
给出采用交会定位法计算多边形定位区域直径(即区域内任意两点之间距离的
最大值)的算法,并回答以定位区域直径为直径的圆能否覆盖该定位区域。
\textbf{问题~2}:已知某全向干扰源在一个检测点处测得的示向度,给出第二
个检测点的选择策略,以获得关于该干扰源较好的定位效果,并给出第二个
检测点的候选区域。
\textbf{问题~3}:目标区域中的干扰源均为全向干扰源,总数在 $10$--$16$
个之间,但具体个数未知。现派出一只机器狗从原点出发,初始频道为 $1$,
对目标区域中的干扰源进行自动定位并清除。要求在确保所有干扰源被清除的
前提下,完成任务的时间越短越好。请制定机器狗自动搜索、定位及清除的
策略,设计相应的算法,通过模拟器进行演练测试,以被清除干扰源个数的
比例和平均定位清除时间为统计值检验策略的有效性;在充分演练测试后,
再进行三次正式测试并按题目表~1 的格式给出结果。
\textbf{问题~4}:目标区域中既有全向干扰源,又有定向干扰源,总数仍在
$10$--$16$ 个之间,但具体个数未知,定向干扰源的个数及定向方向也未知,
其他条件与问题~3 相同。请在此条件下给出检测与清除的策略及算法,通过
模拟器进行演练测试以检验其有效性,并完成三次正式测试、按题目表~1 的
格式给出结果。
\section{问题分析}
四个问题构成一条递进的主线:问题~1 的交会定位几何是全部后续问题的基础;问题~2 在
单次观测下研究“下一步去哪里测”的主动测量设计;问题~3、问题~4 则是在数量未知的
条件下,把定位几何组织成“全域覆盖发现—逐个定位—清除—证明完成”的闭环调度问题。
因此不必为每问单独建模,而是复用同一几何内核与观测更新机制。
传统的无线电定位场景一般由单个人员携带设备,通过主观的经验判断在不同的地点进行模糊测向,最终以三角定位
\textbf{问题~1 的分析}。题面附录~2 第(1)项把测向误差限定在
$[-1^{\circ},1^{\circ}]$,且同一地点重复检测不改变误差:没有误差分布可利用、
View File
-261
View File
@@ -1,261 +0,0 @@
# 训练前端 Windows 兼容性与「暂停」审计(结论 + 修复方案)
> 审计对象:`src/mcm26b/training_ui/`、`src/mcm26b/process_control.py`、
> `scripts/train_hrl_high.py`。
> 触发问题:「无法暂停」「频繁出现 os 无 killpg 等」。
> 结论一句话:**这两个现象同源——训练前端的停止/暂停路径是纯 POSIX 设计;
> Windows 上 `os.killpg` 根本不存在,异常又没被兜住,所以点了停止等于没点。**
---
## 0. 结论摘要
| # | 现象 | 根因 | 严重度 |
| --- | --- | --- | --- |
| 1 | 点「停止训练」返回 500 / 无效果,训练照跑,于是「无法暂停」 | `TrainingJob.stop()` 直接调用 `os.killpg(os.getpgid(...))`;这两个符号**只存在于 POSIX**,Windows 上抛 `AttributeError`,而旧 `except` 只接 `ProcessLookupError/PermissionError` | 阻断 |
| 2 | 控制台/日志反复出现 `module 'os' has no attribute 'killpg'` | 同上:错误最终落到 `_UIHandler.do_POST` 的兜底 `except Exception`,返回 500 并带出 `AttributeError` 文本;每点一次复现一次 | 阻断 |
| 3 | 即使把 killpg 换成 `terminate()`,停止后模型/元数据仍然丢失(Windows 上) | Windows 的 `os.kill(pid, SIGTERM)` 语义是 `TerminateProcess` **硬杀**,训练脚本里"收到信号后在 step 边界保存"的处理器不会执行 | 高 |
| 4 | 界面根本没有「暂停」能力(POSIX 也没有) | 原设计只有 start/stop;且 `SIGSTOP/SIGCONT` 在 Windows 上不存在,**原生暂停在 Windows 上无法实现**,必须改成协作式 | 高 |
| 5 | 子进程进程组隔离在 Windows 上失效 | `Popen(start_new_session=True)` 在 Windows 被**静默忽略**(CPython 的 Windows `_execute_child` 形参名就是 `unused_start_new_session`) | 中 |
| 6 | subproc worker 在 Windows 下可能抢在主进程收尾前退出 | worker 只忽略 `SIGTERM/SIGINT`,没处理 Windows 的 `SIGBREAK`(`CTRL_BREAK_EVENT` 的落点) | 中 |
**修复原则**:把"暂停/继续/停止"从**信号语义**改成**控制文件语义**。
控制文件在 POSIX 与 Windows 上都只是普通文件 IO,行为完全一致;信号与强杀退居
兜底。这样 Windows 上暂停、继续、优雅停止、落盘保证全部成立。
---
## 1. 失败链复现(旧代码)
```
用户点「停止训练」
└─ POST /api/train/stop
└─ TrainingUI.stop() → TrainingJob.stop()
└─ os.killpg(os.getpgid(process.pid), signal.SIGTERM)
├─ POSIX :成功,进程组收到 SIGTERM,脚本优雅收尾
└─ Windows:AttributeError: module 'os' has no attribute 'killpg'
↑ 只 except (ProcessLookupError, PermissionError),接不住
└─ _UIHandler.do_POST 兜底 except Exception → HTTP 500
└─ 训练子进程完全没收到任何指令,继续跑 → 「无法暂停 / 停止没反应」
```
关键代码(修复前,`src/mcm26b/training_ui/server.py`):
```python
def stop(self) -> bool:
with self._lock:
process = self.process
if process is None or process.poll() is not None:
return False
try:
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
except (ProcessLookupError, PermissionError):
process.terminate()
self.status = "stopping"
return True
```
---
## 2. 根因逐条(含证据)
### 2.1 `os.killpg` / `os.getpgid` 是 POSIX-only
CPython 只在 `posix` 构建里注册这两个函数;Windows 的 `os` 模块没有它们。
访问会得到 `AttributeError`(不是 `OSError` 子类),所以旧 `except` 接不住。
### 2.2 `start_new_session=True` 在 Windows 被静默忽略
`subprocess.Popen` 接受该参数,但 Windows 的 `_execute_child` 形参名是
`unused_start_new_session`,也就是**根本不读**。要隔离进程组,Windows 必须传
`creationflags=CREATE_NEW_PROCESS_GROUP`。
### 2.3 Windows 的 `SIGTERM` 是硬杀
`os.kill(pid, sig)` 在 Windows 上只有 `CTRL_C_EVENT` / `CTRL_BREAK_EVENT` 是
"软"信号;**任何其它值**(含 `SIGTERM`)都会走 `TerminateProcess`。因此
`scripts/train_hrl_high.py` 里的:
```python
for _signum in (signal.SIGTERM, signal.SIGINT): # 旧代码
signal.signal(_signum, _on_stop_signal)
```
在 Windows 上形同虚设——处理器注册了,但没人会用它。这也解释了为什么"停止后
模型没保存"。
### 2.4 Windows 没有 `SIGSTOP`,暂停无法用信号实现
暂停(挂起/继续)在 POSIX 上可以用 `SIGSTOP/SIGCONT`,但 Windows 既无这两个
信号,也无等价的"无侵入挂起"用户态 API(真正的挂起要 `SuspendThread`/调试 API)。
所以**任何跨平台暂停都必须是协作式的**:由训练进程自己在 step 边界检查标志并
让出执行。本项目原先没有这条通道,界面也没有暂停按钮。
### 2.5 `SIGBREAK` 未处理
Windows 的 `CTRL_BREAK_EVENT`(发给进程组的软信号)在 Python 里落到
`signal.SIGBREAK`。旧的 handler 安装与 worker 屏蔽列表都只含
`SIGTERM/SIGINT`,Windows 下等于裸奔。
### 2.6 异常类型没兜住
`except (ProcessLookupError, PermissionError)` 漏掉 `AttributeError`、以及
更一般的 `OSError`;`_hard_kill` 里 `signal.SIGKILL` 在 Windows 上也不存在
(`getattr(signal, "SIGKILL", None) is None`),同样会 `AttributeError`。
---
## 3. 修复方案(已实施)
### 3.1 新增 `src/mcm26b/process_control.py`(零第三方依赖)
| 能力 | 实现 | 作用 |
| --- | --- | --- |
| 子进程隔离 | `spawn_kwargs()`:POSIX `start_new_session=True`;Windows `creationflags=CREATE_NEW_PROCESS_GROUP` | 前端 Ctrl+C 不误伤训练;Windows 也能组杀进程树 |
| 控制协议读写 | `write_control()` / `read_control()`:JSON + 同目录临时文件 + `os.replace` 原子替换;损坏/缺失一律视为"无指令" | 两端统一的暂停/停止通道 |
| 强杀兜底 | `terminate_process_tree(process, grace_s)`:先等宽限期;超时后 POSIX 走 `killpg(SIGKILL)`、Windows 走 `taskkill /F /T /PID`;所有 POSIX 符号用 `getattr` 探测 | 彻底移除 `os.killpg` 无条件调用;返回"是否动用了强杀" |
`IS_WINDOWS` 是运行期常量而非导入期分支,便于测试直接 monkeypatch 模拟 Windows。
### 3.2 控制文件协议
路径由前端生成并随命令下发:`--control-file <abs>`(默认落在
`output/hrl/ui/control/<job_id>.control.json`,`output/` 已 gitignore)。
```json
{"paused": false, "stop": false, "seq": 1712345678901234567, "ts": 1712345678.9}
```
- 前端**只写**:`pause()` → `paused=true`;`resume()` → `paused=false`;
`stop()` → `stop=true`(同时清零 paused,保证阻塞中的暂停循环能被唤醒)。
- 训练脚本**只读**:`_ControlPoll` 每 32 个 step 抽样读一次盘(避免每 step 一次
文件 IO);暂停时在 `_on_step` 内阻塞轮询(`poll_s=0.2`),进程存活、显存仍占用,
但不消耗算力。
- 墙钟上限 `--max-wall-s` **扣除累计暂停时长**,避免"挂起一小时回来直接判超时"。
### 3.3 训练脚本 `scripts/train_hrl_high.py`
- 新增 `--control-file`;`_ControlPoll`(纯标准库、可单测)+ 薄薄的
`_ControlChannel(BaseCallback)` 接到 SB3 回调链**最前面**。
- 收尾信号集合扩为 `_stop_signals()`:POSIX `SIGTERM/SIGINT`;Windows 追加
`SIGBREAK`。worker 屏蔽同一集合,保证主进程 `vec_env.close()` 之前 worker 不先退。
- 落盘保证不变:停止后仍写最终模型 + 元数据,`stopped_by_signal=true`,
`stop_signal` 记 `control_file` 或信号名;异常仍落 `*_emergency.zip`。
### 3.4 训练前端 `server.py` / `static/`
- 新增 `POST /api/train/pause`、`POST /api/train/resume`;`stop` 语义改为
"写控制文件 → 宽限期内自行退出;超时强杀",强杀在**独立看门狗线程**里做,
HTTP 请求不会被 15s 等待卡住。
- 状态机新增 `paused`;`_sync_control_events()` 用训练脚本回显的
`paused/resumed/stop_requested` 事件校正状态。
- 快照新增 `forced_kill`,前端横幅区分"优雅停止"与"超时强杀"。
- 前端新增「暂停训练 / 继续训练」按钮、暂停横幅;停止确认文案更新。
### 3.5 停止/暂停时序
```
pause: UI 写 {paused:true} ──► 脚本 _on_step 读到 ──► 回显 paused,阻塞轮询
resume: UI 写 {paused:false} ─► 暂停循环退出 ────────► 回显 resumed,继续训练
stop: UI 写 {stop:true} ────► 脚本 step 边界收尾落盘 ──► 退出码 0
│
└─(宽限 15s 未退)─► terminate_process_tree 强杀;forced_kill=true
```
### 3.6 急停(强杀)也必须可恢复
宽限期一到就强杀,训练脚本**没有任何 Python 收尾机会**——不写最终模型、不写
元数据、不写 `training_failure.json`。如果磁盘上只有 `--checkpoint-every` 的稀疏
历史 checkpoint,急停就可能丢掉上万步,或者在"保存途中被杀"时留下一个打不开的
半截 zip。为此加了四条保证:
| 保证 | 实现 | 效果 |
| --- | --- | --- |
| 起步基线 | `recovery_every > 0` 时,`learn()` 之前先写一份 `<stem>_latest.zip` | 训练刚起就急停,也有可加载、可 `--resume` 的产物 |
| 滚动恢复点 | 每 `--recovery-every`(默认 2000)环境步覆盖写同一份 `<stem>_latest.zip` | 急停最多丢 `recovery_every` 步,而不是 `checkpoint-every` 步 |
| 原子落盘 | 模型 zip / 旁挂 json / `resume.json` 一律「同目录 `.tmp-` + `os.replace`」 | 保存途中被强杀,目标路径仍是上一份**完整**快照;不会出现半截文件 |
| 权威恢复指针 | 每次落盘刷新 `<run_dir>/resume.json`(model / timesteps / 增量语义 / 生效 PPO 超参);前端 `/api/train/state` 暴露为 `recovery` | 无论怎么停,都有一份明确的"从哪继续";界面一键「用最近检查点续训」 |
前端在强杀后还会补写 `<run_dir>/forced_stop.json`(`job_id`、`pid`、`reason`、
`recovery.model`),因为此时训练脚本已经无法记录任何事情。
---
## 4. 平台兼容性矩阵(修复后)
| 能力 | POSIX | Windows |
| --- | --- | --- |
| 启动子进程并隔离 | `start_new_session=True`(setsid) | `CREATE_NEW_PROCESS_GROUP` |
| 暂停 / 继续 | 控制文件(协作式) | 控制文件(协作式) |
| 优雅停止 + 落盘 | 控制文件;`SIGTERM` 亦可 | 控制文件;`CTRL_BREAK_EVENT`→`SIGBREAK` 亦可 |
| 超时强杀进程树 | `killpg(SIGKILL)` | `taskkill /F /T /PID` |
| `os.killpg` 依赖 | 有 | **无(不再调用)** |
| 暂停期间是否算墙钟 | 否(扣除) | 否(扣除) |
---
## 5. 验证
- 新增/更新回归测试:
- `tests/test_training_ui.py`:控制文件协议往返与损坏容错、`spawn_kwargs`
平台分支、Windows 强杀走 `taskkill`、**无 `killpg` 环境下强杀不抛异常**
(直接复现旧 bug)、暂停/继续/停止全链路、控制文件被忽略时强杀并写
`forced_stop.json` 恢复指引、`discover_recovery` 的
`resume.json`/扫描/悬空指针三分支、HTTP `pause/resume` 端到端。
- `tests/test_hrl_checkpoint.py`:控制文件状态机单测;原子保存失败不破坏上一份
快照;JSON 原子替换;历史清理不误删滚动恢复点;起步基线可加载;
**强杀急停后 `resume.json` + 滚动恢复点仍可 `--resume`**;控制文件停止后
模型/元数据落盘(`stop_signal=control_file`)与暂停→继续;POSIX 信号路径
单列并加平台跳过。以上集成用例都用**真实训练脚本**跑 subproc。
- 手工验证:`--recovery-every 32` 短程实跑后强杀,`resume.json` 指向
`q3_ckpt_latest.zip`;以它为 `--resume` 目标再跑 32 步,元数据
`actual_timesteps` 从 64 变 96、`timesteps_semantics=additional`。
- 全量测试:`pytest tests referee/tests` 全绿。
- 全仓库 `pylint src scripts project tests referee main.py` 达到 10.00/10
(口径见 §7)。
---
## 6. 残余风险与后续建议
1. **暂停粒度** = `poll_every` 个 env step(默认 32,约 0.1–3s 量级),不是即时;
若要更快可调小 `_ControlChannel(poll_every=...)`,代价是更频繁的文件 stat。
2. **宽限期固定 15s**(`server.STOP_GRACE_S`)。大模型保存可能更久;但因为落盘是
原子的,即使宽限期到点被强杀,也只是"新的最终模型没写成",**上一份滚动恢复点
与历史 checkpoint 完好**,不会出现半截文件。需要更长可调大该常量。
3. **急停的损失上界 = `--recovery-every`**(默认 2000 环境步)。要更小就调小它;
调到 0 表示放弃滚动恢复点(此时只剩 `--checkpoint-every` 的稀疏历史
checkpoint 与起步基线)。
4. **Windows 强杀依赖 `taskkill`**(系统自带)。若被安全策略禁用,会退回
`Popen.kill()`(只杀主进程,spawn 的 worker 可能残留)。
5. 更严格的 Windows 方案是 **Job Object**(子进程随 job 句柄一起销毁),但需要
`ctypes`/`pywin32`,本仓库基础依赖刻意保持轻量,未引入。
6. **前端进程重启后**,内存中的任务对象没了,「用最近检查点续训」按钮不会自动
出现;但恢复信息都落在磁盘上(`<run_dir>/resume.json`、`forced_stop.json`、
`checkpoints/<stem>_latest.zip`),在表单里填同一个模型输出路径并勾选
`--resume` 即可继续。
7. 界面 `--device mps` 选项在 Windows 上无意义;`auto` 会回退 cuda/cpu,属既有
行为,未改。
8. `_ControlPoll` 的暂停循环会占用一个 Python 线程的调度(每 0.2s 一次读盘),
长暂停期间 CPU 占用可忽略。
---
## 7. pylint 口径说明
配置写在 `pyproject.toml` 的 `[tool.pylint.*]`,目标是
`pylint src scripts project tests referee main.py` = 10.00/10。
**改代码修掉的真实问题**(不是 disable):未使用的 import/变量/参数、重复字典键
(`reward_version`)、`value != value` 判 NaN、`__dataclass_fields__` 私有访问、
`raise` 非异常类型、`pytest.importorskip` 之外的赋值不确定、过长行、无谓括号、
`len(x)` 判空、循环闭包变量、`subprocess.run` 未显式 `check`、`os.path` 循环导入等。
**有意 disable 的类别**(每条在 pyproject 里写了理由):项目刻意的懒加载
(`import-outside-toplevel`)、防御式宽异常(`broad-exception-caught`)、测试访问
内部状态(`protected-access`)、pytest fixture 同名(`redefined-outer-name`)、
无头环境不实现 `gym.Env.render`(`abstract-method`)、以及静态分析的已知误报
(`possibly-used-before-assignment`)。
**注意**:`good-names` 不覆盖 `redefined-builtin`,stdlib 回调签名里的
`log_message(self, format, ...)` 只能在对应 `def` 上行内 disable。
-160
View File
@@ -1,160 +0,0 @@
# 模型训练前端(training-ui)
本地回环 Web UI,用于**实时观察一次 HRL 高层 PPO 训练**:子进程状态、步进进度、
参数收敛曲线、逐回合记录与完整 stdout 日志。设计与评测前端(`referee/` WebUI)
同构——同一套暗色面板语言、同一个「只监听 127.0.0.1 + 静态白名单 + JSON 轮询
API」模式——差别在于本页托管的是一个**训练子进程**而不是评测会话。
## 启动
```bash
uv run python -m mcm26b.training_ui --ui-port 8036 # 打开 http://127.0.0.1:8036
uv run python scripts/train_hrl_ui.py --ui-port 8036 # 等价薄入口(支撑材料命令)
uv run python -m mcm26b.training_ui --print-schema # 只看配置契约,不起服务
uv run python -m mcm26b.training_ui --print-preview # 只看离线示例快照
```
`--no-browser` 阻止自动打开浏览器;Ctrl+C 退出时会先停止训练子进程。
无训练进程时,界面顶栏「离线预览」可渲染三组合成快照(上升 / 平台期 / KL 过猛),
用于检查曲线、指标卡、时间线与日志着色——预览不启动任何进程、不写任何文件。
## 界面结构
| 区块 | 内容 |
| --- | --- |
| 顶栏 | 任务摘要、进程/进度/墙钟/设备/连接五个状态 chip、刷新·预览·暂停/继续·停止 |
| 执行进度与进程 | 步进进度条、剩余时间与预计结束、PID/吞吐/退出码、PPO 阶段时间线、完整命令行 |
| 训练配置 | 由 `/api/train/schema` 生成的五组表单 + 四个预设,运行中锁定 |
| 参数收敛状态 | 判读 chip + 判据说明,每个指标一张卡片(最新值、增量、迷你趋势线、异常高亮) |
| 曲线 | 主指标(平均回合奖励)+ 可切换诊断量,悬停十字线读数、KL=0.05 等参考线 |
| 实时运行日志 | 关键字过滤、错误/进度 JSON 开关、自动跟随、最近 4000 行 |
| 逐回合记录 | Monitor CSV 的每回合奖励/长度/时刻 |
## 数据来源与契约
三个端点都在 `src/mcm26b/training_ui/server.py`:
| 端点 | 说明 |
| --- | --- |
| `GET /api/train/schema` | 字段/分组/预设/指标字典,**与 `TrainConfig` 同源**(`schema.py`) |
| `GET /api/train/state` | 快照;支持 `log_tail`、`metric_limit`、`after_metric` 游标与 `preview=1` |
| `POST /api/train/start` | 允许只提交部分字段(其余取默认值),校验失败返回 409 |
| `POST /api/train/pause` | 写控制文件请求在 step 边界挂起(跨平台) |
| `POST /api/train/resume` | 解除挂起,从暂停处继续 |
| `POST /api/train/stop` | 请求优雅停止;宽限期(`STOP_GRACE_S`,默认 15s)后强杀进程树 |
暂停/停止走**控制文件**而不是信号,原因与平台差异见
[`training-ui-windows-audit.md`](training-ui-windows-audit.md):Windows 没有
`SIGSTOP`,且 `os.kill(pid, SIGTERM)` 会退化成 `TerminateProcess` 硬杀,训练脚本
"保存模型再退出"的收尾分支不会执行。控制文件在 POSIX 与 Windows 上都只是普通
文件 IO,语义完全一致;信号(POSIX `SIGTERM/SIGINT`、Windows `SIGBREAK`)只作兜底。
进度数据的两个来源,服务端都已解析:
1. **progress JSON**(主来源):`train_hrl_high.py --progress-json` 每若干环境步打印
一行 `{"event": "progress", "timesteps": ..., "ep_rew_mean": ...}`,字段最全;
热身阶段间隔会自动缩小,短程 smoke 也能看到完整曲线。
2. **SB3 verbose 表格**(补充来源):解析 `| key | value |` 表格,用于补
`clip_fraction`/`learning_rate` 等诊断量。表格按段分组缓存、等本表的
`total_timesteps` 到位后统一打横轴刻度;与 JSON 同一步数的表格版本会被跳过,
避免重复点。
`timesteps` 是整个前端的横轴:服务端不伪造刻度(缺刻度的表宁可丢弃,截断的表
按末尾已知刻度兜底并在收尾提交),前端不再自行编号。
## 收敛判读口径
`summarize_convergence()` 只做**可解释的启发式判读**,不替代正式学习曲线分析:
| 状态 | 触发条件 |
| --- | --- |
| 等待首个 rollout | 尚无任何指标 |
| 预热阶段 | 进度点 < 3,无法判断趋势 |
| KL 偏大,策略更新可能过猛 | 最近 `approx_kl` > 0.05(判定优先级最高) |
| 价值函数尚未拟合 | 最近 `explained_variance` < 0 |
| 奖励未形成上升趋势 | 最近窗口奖励斜率为负 |
| 已趋于平稳(疑似收敛) | 窗口对半位移 ≤ 逐点噪声、变异系数 ≤ 0.15、极差 ≤ 15% 量级 |
| 收敛趋势良好 | 其余(斜率正向) |
平台判据特意用「对半窗口位移 / 逐点噪声」而不是单看斜率绝对值:慢速但持续的
提升(斜率很小)不会被误判成收敛。所有判据数字都会写进 `notes`,便于人工复核。
## 安全边界
- 只监听 `127.0.0.1`;静态资源是固定白名单,不提供目录遍历。
- 命令由服务端以**参数列表**构造,不经过 shell;字符串参数只拒绝控制字符。
- 同一时刻只允许一个训练任务;暂停中的任务仍算「在跑」,必须先停止才能开新一局。
- 暂停/停止走控制文件(`--control-file`,默认 `output/hrl/ui/control/<job_id>.control.json`),
进程组隔离按平台选择(POSIX `setsid` / Windows `CREATE_NEW_PROCESS_GROUP`),
超时强杀按平台选择(POSIX `killpg(SIGKILL)` / Windows `taskkill /F /T`)。
- 产物路径限定在仓库根下解析,模型输出沿用训练脚本自身的 `--force`/`--resume`
语义(两者互斥,由后端校验)。
## 暂停、停止与落盘保证
「暂停」是**协作式**的:前端原子写控制文件,`train_hrl_high.py` 的
`_ControlPoll` 每 32 个环境步抽样读一次;暂停时训练阻塞在 `_on_step` 的轮询里,
进程与显存保留、不消耗算力,点「继续」从同一个 step 边界恢复。暂停时长不计入
`--max-wall-s`(否则"挂起一小时回来直接判超时")。
「停止」同样是控制文件请求(**跨平台**)。`train_hrl_high.py` 有多层兜底,
点一下「停止」不再等于这一局白跑;而**急停**(强杀,例如 `SIGKILL` /
`taskkill /F`,进程没有任何收尾机会)也保证可恢复:
| 机制 | 行为 |
| --- | --- |
| 滚动恢复点 | `--recovery-every`(默认 2000 环境步)把 `<checkpoints>/<stem>_latest.zip` **原子覆盖写**一次;训练开始前先写一份**起步基线**。因此急停后最多只丢 `--recovery-every` 个环境步,且磁盘上始终有一份完整、可加载、可 `--resume` 的产物 |
| 原子落盘 | 模型 zip、旁挂 json、`resume.json` 都是「同目录临时文件 + `os.replace`」:保存途中被强杀不会留下半截文件,也不会破坏上一份完整快照 |
| 恢复指针 | `<run_dir>/resume.json` 记录当前最佳恢复目标 + 步数(增量语义)+ 生效过的 PPO 超参;前端顶部的「用最近检查点续训」按钮直接读它 |
| 定期 checkpoint | `--checkpoint-every`(默认 20000 环境步)另留 `<stem>_<步数>.zip`,`--checkpoint-keep` 只保留最近 K 个(默认 3),供返祖对比与多档恢复;滚动恢复点与起步基线不受清理影响 |
| 优雅停止 | 控制文件 `stop=true`(或 POSIX 信号 / Windows `SIGBREAK`)后,主进程在 step 边界收尾,保存最终模型与元数据(`stopped_by_signal=true`、`stop_signal`、`checkpoint_files`、`recovery_model`)并正常关闭环境 |
| 超时强杀 | 宽限期(`STOP_GRACE_S`,默认 15s)内没退出则强杀整棵进程树,快照 `forced_kill=true`,并在 `<run_dir>/forced_stop.json` 写明 `recovery.model`(可直接续训的目标) |
| 异常兜底 | `learn()` 抛出任何异常时先落 `*_emergency.zip` + 元数据 + `resume.json`,再写 `training_failure.json` 并抛出 |
急停后恢复的操作方式:界面点「用最近检查点续训」;命令行则
`--resume --model <resume.json 里的 model>`,`--timesteps` 按**追加**步数理解。
checkpoint 与最终模型共用同一份 json 契约,因此 `--resume <checkpoint.zip>` 直接
续训(`--timesteps` 为增量步数)。注意 `--resume`/`--init` 会沿用 checkpoint 内的
PPO 超参(`n_steps`/`batch_size`/`n_epochs`):命令行这三项被忽略,脚本会打一条
`hyperparams_from_checkpoint` 事件说明差异,元数据 `ppo_hyperparams` 记录**实际生效**值。
回归测试见 `tests/test_hrl_checkpoint.py`,其中端到端用例真起 subproc 子进程,覆盖
控制文件停止、POSIX 信号停止、**强杀后仍可续训**与暂停→继续(信号路径在 Windows
上自动跳过)。
## 测试
```bash
.venv/bin/python -m pytest tests/test_training_ui.py tests/test_training_ui_js.py tests/test_hrl_checkpoint.py -q
```
- `tests/test_training_ui.py`:配置契约同源、预设可直接提交、参数校验、SB3 表格
刻度打点、游标分页、`describe_process` 进度/ETA、示例快照与真实快照同键;
用**桩训练脚本真起子进程**覆盖启动/轮询/暂停/继续/停止/退出码全链路;并覆盖
跨平台进程控制——控制文件往返与损坏容错、`spawn_kwargs` 平台分支、Windows 走
`taskkill`、**无 `killpg` 环境下强杀不抛异常**(旧 bug 的直接回归)、控制文件被
忽略时强杀并写 `forced_stop.json` 恢复指引、`discover_recovery` 的
`resume.json`/扫描/悬空指针三分支、HTTP `pause/resume`。
- `tests/js/training_ui_harness.cjs`(经 `tests/test_training_ui_js.py` 调起):
DOM 桩加载发布的 `charts.js`/`app.js` 原文,用服务端生成的真实快照驱动渲染,
断言表单/指标卡/曲线/日志/逐回合表都拿到数据,覆盖增量游标三条分支与
`classList`、HTML 转义、极端数值等边界。
- `tests/test_hrl_checkpoint.py`:落盘与恢复的端到端回归——原子保存失败不破坏
上一份快照、JSON 原子替换、历史清理不误删滚动恢复点、起步基线可加载、
**强杀急停后 `resume.json` 与滚动恢复点仍可继续训练**、控制文件停止落盘、
暂停→继续、POSIX 信号停止。
## 已知取舍
- 进度点保留上限 5000(服务端 deque 与前端本地缓存同值),超长训练只保留最近一段。
- 表格解析依赖 SB3 的段名(`rollout/`/`time/`/`train/`/`system/`);SB3 若改表格
格式,退化路径是「只显示 progress JSON」,不会导致界面崩溃。
- 收敛判读是启发式;正式结论仍需用 `scripts/benchmark_hrl.py` 的配对评测与
学习曲线人工复核。
- 暂停粒度是 `poll_every` 个环境步(默认 32),不是即时挂起;停止宽限期默认 15s。
- Windows 强杀依赖系统自带的 `taskkill`;若被策略禁用会退回 `Popen.kill()`
(只杀主进程)。更严格的 Job Object 方案需要额外依赖,未引入。
Windows 兼容性问题的完整根因与修复记录见
[`training-ui-windows-audit.md`](training-ui-windows-audit.md)。
+208
View File
@@ -0,0 +1,208 @@
# 几何计算示意图册
> 本册逐图给出坐标口径、关键量与图中各元素的含义。插图位于 [`figures/`](figures/),复现命令:
>
> ```bash
> uv run python scripts/make_figures.py --only geo-q1-convex-intersection-zoom,\
> geo-q1-diameter-circle-counterexample,geo-q2-guaranteed-reception-disk,\
> geo-q3-seven-point-coverage,geo-q4-minimum-cover-31-points
> ```
>
> 图中的数字由脚本现算:问题一调用生产求解器,问题三、四直接读覆盖计划与证书;
> 来源与 sha256 记在 [`figures/manifest.json`](figures/manifest.json)。
统一的坐标与符号约定:
- 世界坐标以 Ω 圆心为原点,$x$ 轴向右、$y$ 轴向上,单位**米**;
- Ω 是半径 $R=1800$ m 的圆盘;源的有效接收半径 $r_{\rm eff}\in[1000,1500]$ m;
- 示向度 $\theta$ 以 $+x$ 轴为 $0°$ 逆时针为正,误差半角 $\delta=1°$;
- 清除半径 $r_{\rm clear}=20$ m;
- "可保证清除" ⟺ 存在一点使整个候选区域落在该点 20 m 内 ⟺ $\rho\le 20$ m(充分)。
---
## 图 1 问题一:角域交会与定位区域
![问题一角域交会](figures/geo-q1-convex-intersection-zoom.png)
**左(总览)**:三个检测点(官方演练案例 `U5ZW-P9KN-TCAG-R7ST`,频道 9)
各自的**前向角域** $W_i=\{p:\angle(p-s_i)-\theta_i\in[-1°,+1°]\}$ 画成窄扇形
(2° 宽,图中放大成可见宽度);三者交集就是定位区域 $P$。检测点相距 600~900 m,
而 $P$ 的直径只有 24 m,所以左图里 $P$ 缩成一个点——这是**必须做局部放大**的原因。
**右(放大,视野 ±31.4 m)**:以最小包围圆圆心为中心:
- 浅蓝扇形 = 三个角域在放大框内的可见部分;三者**重叠成白色区域**= $P$;
- 红色实线多边形 = $P$ 的顶点边界(与左图同一个集合);
- 蓝色虚线圆 = **直径圆**,半径 $D/2=11.9984$ m,圆心是中点 $(-450.634,\ 508.944)$;
- 绿色实线圆 = **最小包围圆(MEC)**,$\rho=12.0686$ m,圆心 $(-449.977,\ 507.953)$。
**关键量(图 (c) 栏)**
| 量 | 值 | 判定 |
| --- | ---: | --- |
| 直径 $D(P)$ | 23.9967 m | 顶点对枚举(凸集上最远点必为顶点) |
| MEC 半径 $\rho$ | 12.0686 m | Welzl 算法 + 支撑点枚举对照 |
| 直径圆最大超出 $E$ | +0.6040 m | $E>0$ ⇒ **直径圆不覆盖** $P$ |
| $\rho\le20$ m | 成立 | ⇒ **存在可保证清除的点**(取 MEC 圆心) |
> 这两个结论不矛盾:题目问"直径圆能否覆盖"(答案:不能,$E>0$)
> 与"能否保证清除"(答案:能,$\rho\le20$ m)是**两个不同的问题**。
> $E$ 的定义:$E=\max_i\lVert v_i-o\rVert-D/2$,$o$ 为直径中点;
> 精确算术下最远顶点对就在圆周上,故 $E\ge0$,$E>0$ 即覆盖失败,
> 达到最大值的顶点就是可独立复核的失败证据。
---
## 图 2 问题一:直径圆不覆盖的反例
![直径圆反例](figures/geo-q1-diameter-circle-counterexample.png)
等边三角形布站($S_1(-1000,0)$、$S_2(540,-866)$、$S_3(520,901)$,示向度
$1°,121°,241°$,误差半角 $1°$)。三条 2° 宽的角域交出一个**等边三角形**
$P$:顶点 $(0,0)$、$(40,0)$、$(20,34.641)$。
- 直径 $D=40.0000$ m,最远点对是底边两端 ⇒ 直径圆圆心 $(20,0)$、半径 20 m;
- 到第三个顶点 $(20,34.641)$ 的距离是 $20\sqrt3\approx34.6410$ m > 20 m,
故**直径圆不覆盖**:$E=+14.6410$ m(图中箭头所指);
- 该反例的最小包围圆半径 $\rho=40/\sqrt3\approx23.0940$ m **> 20 m**,
属于"覆盖失败且无法保证清除"的更坏情形。
> 反例是**符合题设测向条件**的:把真实源放在三角形中心 $(20,20\sqrt3/3)$,
> 三个检测点的真实方位与读数偏差均小于 $1°$,且三个检测距离都小于 1500 m,
> 所以它不是"脱离测向模型的任意图形"。构造与证明见
> [`问题一解答.md`](问题一解答.md) 第六节。
---
## 图 3 问题二:保证接收的候选盘与安全盘
![问题二保证接收盘](figures/geo-q2-guaranteed-reception-disk.png)
**候选集**(首次观测之后可能的位置集合):
$$
K_1=\Omega\ \cap\ W(s_1,\theta_1\pm\delta)\ \cap\ B(s_1,\ 1500),
$$
即"Omega 内、首次角域内、且距离不超过最大接收半径"的三者之交。
**解析安全盘**:截断角域(扇形,半径 $R_{\max}=1500$ m、半角 $\delta=1°$)
的最小包围圆恰为 $B(c,a)$,其中 $c=s_1+a\boldsymbol u$($\boldsymbol u$ 为示向度单位向量),
$$
a=\frac{R_{\max}}{2\cos\delta}=\frac{1500}{2\cos1°}=750.1142\ \text{m}.
$$
于是对安全盘内任一点 $q$、扇形内任一点 $p$:
$$
\lVert q-p\rVert\le a+(1000-a)=1000\ \text{m}
\ \Longrightarrow\ q\ \text{必然收到源的信号},
$$
$$
\boxed{\ \text{安全盘半径}=1000-a=249.8858\ \text{m}\ }
$$
(严格非空;图中绿色实心圆,圆心 $c=(649.62,\ 375.06)$)。
第二检测点就在该盘内选,目标是**最小化最坏保守后验包围半径**,
移动与检测成本作次目标;交会角只用于同分筛选与可解释性说明。
> 图中 $a$ 与 1000 m 两个圆几乎重合是可预期的:$\delta$ 只有 $1°$,
> $a=R_{\max}/(2\cos\delta)$ 与 $R_{\max}/2$ 相差 0.0114%,
> 因此**安全盘的"安全"主要来自角域约束,而不是圆心位置**。
---
## 图 4 问题三:七点解析覆盖
![问题三七点覆盖](figures/geo-q3-seven-point-coverage.png)
**站点集**:原点 + 半径 $a$ 的六等分环,
$S(a)=\{(0,0)\}\cup\{a(\cos k\pi/3,\ \sin k\pi/3):k=0,\dots,5\}$。
**定理(`algo-3.md` §4.2)** 当 $0<a/\sqrt3\le R$ 时
$$
\max_{g\in\Omega}\min_{s\in S(a)}\lVert g-s\rVert
\le D(a):=\max\Bigl\{\frac{a}{\sqrt3},\ \sqrt{R^2+a^2-\sqrt3Ra}\Bigr\}.
$$
代入默认 $a=1159.7$ m、$R=1800$ m:
$$
D(a)=984.5391\ \text{m}<1000\ \text{m}
\quad(\text{几何余量 }15.46\ \text{m}).
$$
**图上看到的就是这个证明**:7 个半径 1000 m 的接收盘(浅绿,裁剪在 Ω 内)的
并集**完全覆盖** Ω,最坏点出现在 $(0,-1800)$(Ω 正下方边界,图中圈出),
到最近站点 $1159.7$ m(正下方环站)的距离恰为 984.54 m。
数值复核(脚本内 20 m 网格):Ω 内 25445 个采样点全部被覆盖,**缺口 0**——
解析上界与数值结果一致到小数点后 3 位。
**代价对比**:七点每轮 7 次检测即可证明"无源",49 点网格要 49 次;
巡回长度 $6a\approx6.96$ km(对照 49 点的 NN 巡回约 36.4 km)。
$a$ 的可行下界 $a_{\min}\approx1122.9558$ m(零余量),默认配置留 15 m 以上余量。
**为什么能"发现即证明"**:某频道若在**全部**站点都测得 `no_signal`,
由覆盖定理知该频道必无源(负观测只能排除该站点 1000 m 圆盘,而 $r_{\rm eff}\ge1000$ m),
于是可以安全销账;所有频道销账 ⇒ 完成证明成立 ⇒ 立即 `/exit`。
---
## 图 5 问题四:定向源的 31 点最小命中集与联合信念
![问题四最小命中集](figures/geo-q4-minimum-cover-31-points.png)
**覆盖语义变了**:定向源只向**朝向 $\pm90°$ 的前向半球**辐射,
所以"某站点附近一定收到"这件事必须同时考虑**源的位置与朝向**:
$$
\text{站点 }s\text{ 能发现源}\iff
\lVert s-\text{pos}\rVert\le r_{\rm eff}\ \wedge\
\angle\bigl(\text{heading},\ s-\text{pos}\bigr)\le90°.
$$
这个语义记作 `forward_half_disk`(图中右侧示意)。
**31 点最小命中集**(`q4_mincover_v2`,图中红点):
| 项 | 值 |
| --- | --- |
| 点数 | 31(离线贪心最小命中集,取代 49 点网格) |
| 设计参数 | $r_{\rm design}=965$ m + 前向角裕量 $5°$ |
| 运行期证书 | 15 m / 72 朝向档,325.62 万个 (位置, 朝向) 采样格,**缺口 0** |
| 最坏命中距离 | 990.051 m |
| 最近邻巡回 | 23.9 km ≈ 4776.8 s 虚拟时间 |
| 旧计划对照 | `q4_mincover_v1` 在 15 m/72 档下有 **566** 个缺口(粗采样过拟合) |
**位置 × 朝向联合信念**:负观测(`no_signal`)在问题四里**只约束朝向**——
它只能排除"朝向正对本站点"的那些朝向档,位置信息几乎不更新。
因此证据层维护网格 × 朝向档的联合分布,可见性判据必须与引擎一致
(距离 $\le r_{\rm eff}$ 且夹角 $\le90°$),并按格内角裕量保守裁剪。
当信念坍缩到有限格时启用**后备盲清**:就近到可疑格 `/clear`,
把盲清次数从 125.7 次/局压到 **4.3 次/局**。
> **本轮修复的正确性缺陷**:旧版 `no_signal` 的朝向裁剪规则反向、且漏计格内角裕量,
> 会删掉真源所在的朝向档。已修复,并由
> `tests/test_joint_belief.py` 的随机观测序列保留性测试固化。
---
## 附:把图接进论文
`docs/paper/main.tex` 目前用表格承载结论,插图按下例插入即可:
```latex
\begin{figure}[htbp]
\centering
\includegraphics[width=0.95\textwidth]{figures/geo-q1-convex-intersection-zoom.png}
\caption{问题一:角域交会得到的定位区域,以及直径圆与最小包围圆的关系。}
\label{fig:geo-q1}
\end{figure}
```
图片按 160 mm 宽排版。图内不含标题与图注,说明写在 `\caption` 与正文。
@@ -1,165 +0,0 @@
# 第三、四问强化学习适用性审核与改进
本轮审核第一版强化学习代码、专家数据、模型及官方演练归档,修复训练与部署不一致的问题,训练两个新的 Maskable PPO 模型,并用独立实现的本地 `referee` 完成同场景对照。所有新性能数字均为本地结果,没有启动新的官方演练。
结论:强化学习适合在现有几何算法内尝试“下一检测点”的排序,第四问比第三问更有收益空间。当前证据支持第四问的混合方案优于手写 `directional` 基线;尚不能证明新模型稳定优于旧 PPO。第三问没有稳定增益,应保留 `bayes` 默认策略。新模型作为实验版本显式加载,没有覆盖旧默认模型。
## 1. 题设和方法适用范围
附录2(3)的交会必须使用带误差的角域,不能把两条示向线的交点当作真值;同地重测不会提供新的独立误差样本。附录2(4)的单接收机逐频道检测,结合动作规则,须计入移动、5秒检测及实际1秒换频。第三问的全向假设允许用无信号排除接收圆盘;第四问的无信号还可能来自方向遮挡,不能沿用这一排除结论。题设及几何算法的完整审核见[算法审核与优化](算法审核与优化-20260911.md)。
当前 RL 实际只替换 `RLBayesLoop._select_point` 和 `RLDirectionalLoop._next_probe`。七站/49站覆盖、频道发现、全局任务调度、保守候选集、清除证书和第四问后备清除仍由原算法负责。因此,完整场景全清验证的是混合系统,不是神经网络独立获得了完备性证明。
401维输入概括几何、历史读数和60个候选点,但省略完整历史、候选多边形细节及位置—朝向联合约束,不能直接称为完整马尔可夫状态。局部单源训练也没有学习全场覆盖路线与多源调度。PPO可以作为这种压缩观测下的近似策略尝试,但其目标并不自动等于全场最短时间;评估必须使用独立完整场景。[SB3官方训练与评估建议](https://stable-baselines3.readthedocs.io/en/master/guide/rl_tips.html)也强调独立评估、多随机种子和状态信息完整性。
## 2. 确认的实现缺陷及修复
| 缺陷 | 证据和影响 | 已实施修复 |
| --- | --- | --- |
| 训练传入整个 `BeliefState`,部署传入 `ChannelBelief` | 同一状态的特征索引7、14、15、17、18不同;训练丢失测量次数、末次结果和方位信息 | `env._observe` 使用目标频道信念;测试逐位比较部署输入,并覆盖跨频道交接 |
| BC使用ReLU,接收权重的PPO使用Tanh | 仅复制线性权重无法保留函数。原始专家输入探针中,Q3的90.96%、Q4的67.42%出现不同argmax | BC改为Tanh;复制时检查完整前向输出,重新初始化critic;旧ReLU/旧特征检查点拒绝直接迁移 |
| BC按观测行随机拆分 | 同一episode的相关状态可能同时出现在训练和验证中,分类准确率不足以说明独立场景泛化 | 保存episode编号,按episode划分训练/验证 |
| 第四问训练遮挡状态与运行时不一致 | 训练只记录距离保证盘内的无信号,且获得新方向后未正确重置连续遮挡;后备清除触发轨迹偏离部署 | 所有连续无信号记录为探测序列,仅盘内无信号用于确认定向;正观测清空序列,统一4次遮挡/8次定位阈值 |
| 奖励鼓励首次遮挡等中间事件 | “获得遮挡证据”额外+2、半径收缩等奖励会改变实际时间目标;较高回报不一定更快 | 主要奖励改为实际虚拟耗时的负值,成功清除统一+20,失败/截断重罚;取消这些中间奖励,采用gamma=1 |
| 未屏蔽同地重测、重合候选和第三问盘外梯子点 | 浪费固定误差条件下的检测时间;旧文档“所有候选保证接收”不成立 | 训练/推理共用动作屏蔽,排除已测0.5m格位置、重复候选、越界点;第三问存在距离保证盘时排除盘外点 |
| 保证盘半径恰为0时动作数量可能改变 | 依赖去重后的候选生成器会破坏固定60动作接口 | 即使位置重合也保留编号,交由动作屏蔽处理 |
| 只校验401/60维度不能识别语义变化 | 接收机频道被目标频道替代;旧模型与新模型同形但输入含义不同 | 加入特征版本与算法元数据,v2使用实际接收机频道,旧版保留原输入语义;拒绝问题编号或屏蔽模型元数据不匹配 |
| 基准将 `completed` 当作全清 | 内部状态自洽不代表全部真实源已清除 | 用评测端真实频道集合对照成功清除集合,并检查真实频道没有被误判缺席、正常退出、异常及逐步计时;旧基准新增 `all_valid` 和失败退出码 |
| 官方审计没有严格对应问题与策略名称 | 第三问/第四问摘要可能交叉通过名称检查 | `verify_rl_practice.py` 分别要求 `rl` / `rl_q4` |
BC探针是对旧网络和“拷贝后换激活”的网络进行比较,并不是新模型错误率,也不是重新测得的BC验证准确率。旧报告38.9%/65.3%的分类准确率不能直接解释为已迁移PPO的模仿准确率。本轮训练的新模型均从随机初始化开始,未使用BC;BC修复通过前向一致性测试,未据此声称重新训练BC已经带来收益。
动作屏蔽采用官方 `MaskablePPO` 的 `action_masks` 接口,训练和确定性推理都传入相同规则。[SB3-Contrib官方文档](https://sb3-contrib.readthedocs.io/en/master/modules/ppo_mask.html)说明了这两处的用法。第四问仍允许探索盘外候选,距离保证不等于方向可见。退化到所有动作均被屏蔽时保留中心动作,由步数/预算边界处理,因此不能把本次零重复观测扩展为所有可能状态的严格保证。
正常成功episode的累计奖励为 `20 - 局部实际虚拟时间/100`;环境仍保留异常与失败处理,包括证书清除失败的额外惩罚。局部时间从首测与可选交接完成后开始,不能用训练报告中的局部均值替代整场成绩。第三问训练自动清除仍使用证书圆心,而完整 `BayesLoop` 可在证书范围内平移清除点;全局调度、预算与局部环境也有差异,完整闭环验证因此不可省略。
## 3. 训练和数据
第一版Q3为120000步随机初始化PPO;第一版Q4为BC初始化后40000步PPO。原专家数据分别为5141、14181条,原5场完整测试均值分别是Q3:3088.33/3124.76秒、Q4:14250.15/13230.20秒(手写/RL)。这些历史数字受旧环境和特征影响,不与本轮新课程的单源成功率直接比较。
修订课程保留首次有效测向,并加入35%的跨频道、跨位置交接,20%的区域边缘且最小接收半径场景。定向首测覆盖朝向±89.9°,更接近半平面边界。源位置、朝向、半径和逐点误差的抽样仍是自建分布,不是已知的官方生成分布;真值仅用于布设和评测,不进入策略观测或动作屏蔽。
两模型使用 `[128,128]` Tanh MLP、2个内存环境、`n_steps=512`、`batch_size=128`、6轮更新、学习率0.0003。实际均完成60416步,来自完整rollout批次向上取整;元数据中的60000是请求步数。安装版本为SB3 2.9.0、SB3-Contrib 2.9.0、Torch 2.11.0+cu128。本次选择CPU、单Torch线程,机器CUDA可用。
| 项目 | Q3新模型 | Q4新模型 |
| --- | ---: | ---: |
| 训练种子 | 310001 | 410001 |
| 定向概率 | 0 | 0.75 |
| 训练墙钟时间 | 276.6s | 250.6s |
| 独立单源评估成功 | 59/60 | 60/60 |
| 单源平均局部时间 | 270.04s | 349.51s |
| 平均动作步数 | 2.42 | 3.13 |
Q3有一次局部训练任务未完成,不能声称单源成功率100%。完整闭环仍有自身调度与后备路径。两问题各只有一个新模型训练种子,未覆盖训练随机性。
## 4. 完整场景同条件对照
比较三种固定策略:当前手写基线(Q3 `bayes`、Q4 `directional`)、旧默认PPO、新Maskable PPO。相同场景使用相同源位置、频道、半径、朝向及逐点固定误差种子。`referee` 为单独实现,策略不读取模拟器真值。每场保存场景、完整请求/响应、summary、模型哈希和计时核验。
开发集为种子700—702、10/16源,各问题6场。随后固定新模型,不再据验证成绩调参;验证集为种子91000—91005、10/13/16源,各问题18场。第四问定向数覆盖1、约半数、仅一个全向三种组成。另加两种圆周边界压力场景。开发、验证、压力共52个不同场景,三策略共156次完整运行,全部满足真实源全清、缺席无误判、正常exit、零异常、逐步耗时复算一致。
### 开发集平均整场时间
| 问题 | 手写基线 | 旧PPO | 新模型 |
| --- | ---: | ---: | ---: |
| Q3,6场 | 3294.62s | 3206.20s | 3264.62s |
| Q4,6场 | 14289.76s | 12443.43s | 11758.72s |
### 独立验证集
| 问题/指标 | 手写基线 | 旧PPO | 新模型 |
| --- | ---: | ---: | ---: |
| Q3有效全清 | 18/18 | 18/18 | 18/18 |
| Q3平均时间 | 3330.72s | 3254.61s | 3307.65s |
| Q3中位时间 | 3309.16s | 3262.64s | 3222.50s |
| Q3最大时间 | 3690.11s | 3786.98s | 3776.55s |
| Q4有效全清 | 18/18 | 18/18 | 18/18 |
| Q4平均时间 | 13778.82s | 12070.53s | 11797.57s |
| Q4中位时间 | 14587.80s | 12891.83s | 12488.23s |
| Q4最大时间 | 17273.98s | 15365.76s | 15894.44s |
| Q4累计未成功clear尝试 | 616 | 719 | 1380 |
| Q4累计同频道同点重测 | 12 | 28 | 0 |
Q3三组都没有失败clear或同点重测。Q4新模型减少了重测,但更多使用后备光学清除尝试,平均耗时降低的同时尾部表现有所退化。失败clear本身可来自允许的后备搜索,不能仅凭该计数认定证书错误;其移动和3秒动作耗时全部纳入结果。
对独立验证场景做10000次配对bootstrap,负值表示新模型更快:
| 对比 | 均值相对变化 | 95%场景重采样区间 | 新模型更快场数 |
| --- | ---: | ---: | ---: |
| Q3新模型对手写 | -0.69% | [-4.50%, +2.95%] | 9/18 |
| Q3新模型对旧PPO | +1.63% | [-1.64%, +5.19%] | 8/18 |
| Q4新模型对手写 | -14.38% | [-17.93%, -11.48%] | 18/18 |
| Q4新模型对旧PPO | -2.26% | [-6.08%, +1.71%] | 13/18 |
新旧PPO的区间均跨0,不能据小幅平均变化宣称稳定改进。区间只反映固定模型在这些场景上的差异,不覆盖训练种子、未知官方分布或所有合法边界。此外本轮同时修改多项训练因素,这不是能归因到单个修复的消融实验。
### 边界压力与4000秒目标
源全部放在半径1800m圆周、接收半径1000m;第四问隔一个源采用向外发射方向。10/16源各一场,各策略都完成全清。
| 问题 | 手写平均 | 旧PPO平均 | 新模型平均 |
| --- | ---: | ---: | ---: |
| Q3 | 4472.58s | 4429.04s | 4648.26s |
| Q4 | 18248.87s | 14404.01s | 15210.08s |
新Q3的两场分别为4659.06s、4637.46s,仍超过4000s;新Q4为14573.62s、15846.54s,且比旧PPO退化。此前几何优化在另一独立Q3验证组达到平均3315.89s、最大3981.74s,本轮新Q3验证组最大3776.55s;二者只能说明各自验证组达标,不能承诺全部题设场景小于4000s。第四问尚未达到4000s。
## 5. 官方证据与测试
重新审计已有官方归档,三次均通过题号/策略、官方包SHA、源数、完整清除、正常退出、请求时窗及逐步计时检查,未改写原归档:
| 问题 | 既有官方案例 | 全清 | 整场时间 |
| --- | --- | ---: | ---: |
| Q3 | F38Y-9Q9J-B82V-CB9Z | 13/13 | 3538.81s |
| Q4,3个定向源 | X43X-VMRF-8GRZ-3SYA | 10/10 | 14003.09s |
| Q4,10个定向源 | BXSA-TFQ3-2DJ6-DHH7 | 10/10 | 14562.82s |
这些是旧模型的官方可运行证据,不是新模型成绩;不同案例也不能直接计算优化百分比。新模型目前通过本地验证,未在官方新演练中运行。
全量回归:`python -m pytest -q --tb=short`,243项通过。初次沙箱运行有24个临时目录权限导致的fixture错误,获得权限后重跑全部通过。新增5项测试覆盖训练/部署观测、动作屏蔽、方向读数重置遮挡、实际成本奖励和BC完整前向一致性。之后对基准/官方审计入口的小修补分别用4次完整场景冒烟运行及三份官方归档复核通过。
## 6. 产物与复现
主目录为 `output/rl/review-20260911/`:
- `q3_masked.zip` / `.json`、`q4_masked.zip` / `.json`:新模型与训练元数据,必须成对保存。
- `evaluation/development/{controls,revised}/results.json`:开发对照。
- `evaluation/validation/final/results.json`:独立验证与每场完整日志。
- `evaluation/stress/final/results.json`:边界压力结果与日志。
- `review_evidence.json`:配对区间、BC/特征错位探针、旧官方重审结果和代码哈希。
- `benchmark-smoke.json`:旧基准有效性口径修复后的冒烟结果。
新Q3模型SHA-256:`b8b3a2bb103588348d8d7791bde9a2b0635c04778f0ac64f91c6f5c7cf87ca6e`。
新Q4模型SHA-256:`6865d541ff9bdee81886d327345f2660d5f7d72f4b39810a58ae4b867ab37e42`。
从项目根目录复现训练时,使用新目录保留本轮检查点:
```powershell
.venv/Scripts/python.exe scripts/train_rl.py --problem 3 --algorithm maskable_ppo --timesteps 60000 --seed 310001 --device cpu --model output/rl/reproduction/q3_masked.zip --eval-episodes 60 --verbose 0
.venv/Scripts/python.exe scripts/train_rl.py --problem 4 --algorithm maskable_ppo --timesteps 60000 --seed 410001 --directional-probability 0.75 --device cpu --model output/rl/reproduction/q4_masked.zip --eval-episodes 60 --verbose 0
```
复核本轮冻结模型的完整对照(label须使用尚不存在的名称):
```powershell
.venv/Scripts/python.exe scripts/evaluate_rl_revision.py --split validation --label rerun-validation
.venv/Scripts/python.exe scripts/evaluate_rl_revision.py --split stress --label rerun-stress
.venv/Scripts/python.exe scripts/summarize_rl_revision.py
```
本地内存自检可显式加载对应检查点;`--self-test`不会连接官方模拟器:
```powershell
.venv/Scripts/mcm26b.exe run --robot-id 2026001 --self-test --strategy rl --rl-model output/rl/review-20260911/q3_masked.zip
.venv/Scripts/mcm26b.exe run --robot-id 2026001 --self-test --problem 4 --q4-strategy rl --rl-model output/rl/review-20260911/q4_masked.zip
```
在用户另行启动相应问题的官方演练后,使用实际登录队号和`--base-url`连接。例如第三问(路径使用本轮尚未创建的官方演练目录):
```powershell
.venv/Scripts/mcm26b.exe run --robot-id 2026001 --base-url http://127.0.0.1:2026 --problem 3 --strategy rl --rl-model output/rl/review-20260911/q3_masked.zip --log output/rl/review-20260911/practice-q3/session.jsonl
```
该命令保存请求/响应日志,汇总输出到终端;官方结果文件与汇总还需按原归档流程保存。第四问改用`--problem 4 --q4-strategy rl`及对应模型。本轮未执行上述官方连接命令。
进一步研究应先缩小单源训练与完整调度的差异,并处理Q4后备清除和边界退化,再做多个训练种子及新的冻结验证集。当前结果不足以将新模型自动替换为默认策略,也不足以把训练步数增加当作达到4000秒的依据。
+178
View File
@@ -0,0 +1,178 @@
# 总体思路与流程图
> 插图:[`figures/flow-overall-architecture.png`](figures/flow-overall-architecture.png)(总体思路与算法主线)、
> [`figures/steps-state-machine.png`](figures/steps-state-machine.png)(执行步骤)、
> [`figures/timing-attachment-example-105-111-194-199.png`](figures/timing-attachment-example-105-111-194-199.png)(附件计时示例)。
> 复现:`uv run python scripts/make_figures.py --only flow-overall-architecture,steps-state-machine,timing-attachment-example-105-111-194-199`
本文给出四问的思路、端到端流程图、执行步骤与执行时间。
算法细节指向 [`algo-1.md`](algo-1.md)~[`algo-4.md`](algo-4.md),
协议细节指向 [`协议规则表与状态机.md`](协议规则表与状态机.md)。
---
## 1. 主线
把题面约束写成可计算的几何集合和计时账本,四问共用一套「证据 — 决策 — 执行」结构,
每问都给出可验证的保证:
| 问 | 保证 |
| --- | --- |
| 1 | 直径由顶点对枚举给出;最小包围圆半径 $\rho\le20$ m 时存在可保证清除的点 |
| 2 | 第二检测点取在解析安全盘 $B(c,1000-a)$(半径 249.8858 m)内,必然收到信号 |
| 3 | 七点计划覆盖整个 Ω(解析上界 984.5391 m < 1000 m),据此可判定频道无源 |
| 4 | 31 点最小命中集在 15 m / 72 朝向档证书下缺口为 0 |
![总体思路与算法主线](figures/flow-overall-architecture.png)
---
## 2. 四层结构
| 层 | 内容 | 作用 |
| --- | --- | --- |
| L0 题面抽象 | Ω 半径 1800 m;移动 5 m/s、检测 5 s、换频 1 s、清除 5 s / 3 s;观测 `direction/no_signal/near`;源 10~16 个,频道 1~20,定向源覆盖 ±90° | 后续推导只用这些量,不引入题面之外的信息 |
| L1 在线三层 | 证据层(候选集与粒子)、决策层(选点与任务表)、执行层(串行客户端) | 依赖单向向下,几何结论与调度启发式可分别测试 |
| L2 四问 | Q1 定位解算 → Q2 第二点选择 → Q3 全向搜索 → Q4 混合定向 | 后一问复用前一问的内核 |
| L3 三条闭环 | 发现、定位、清除 | 每环有明确的进入与退出条件 |
L0 的常量集中在 `src/mcm26b/config.py`,带 `[题面]` / `[工程]` 标注。
证据层只给出「可能在哪里」,决策层只读证据并产出动作,
执行层负责发送动作并维护虚拟时钟。
---
## 3. 四问思路
### 问题一
1. 检测点 $s_i$ 与示向度 $\theta_i$ 给出前向角域
$W_i=\{p:\angle(p-s_i)-\theta_i\in[-1°,+1°]\}$,定位区域是半平面交 $P=\bigcap_i W_i$;
2. 直径 $D(P)=\max_{i,j}\lVert v_i-v_j\rVert$ 只需枚举顶点对(凸集上最远点必为顶点);
3. 直径圆能否覆盖 $P$:唯一候选圆心是最远顶点对的中点。若 $a,b$ 同在该圆内,
三角不等式两处同时取等,圆心只能是 $ab$ 中点,因此只需在该点检查全部顶点;
4. 能否保证清除:最小包围圆半径 $\rho\le20$ m 时,停在 MEC 圆心即可清除。
这是充分条件,不是必要条件。
结论:直径圆不一定覆盖定位区域,见 [`geo-q1-counterexample.png`](figures/geo-q1-diameter-circle-counterexample.png);
官方演练案例是「覆盖失败但 $\rho=12.07$ m $\le20$ m,可保证清除」。
### 问题二
候选集 $K_1=\Omega\cap W(s_1,\theta_1\pm\delta)\cap B(s_1,1500)$。
截断角域(扇形)的最小包围圆为 $B(c,a)$,$a=R_{\max}/(2\cos\delta)=750.1142$ m,
故安全盘 $B(c,1000-a)$ 的半径为 249.8858 m,盘内任一点到扇形内任一点的距离
不超过 1000 m,即必然收到信号。在该盘内以最坏保守后验包围半径为主目标选点,
移动与检测成本作次目标,交会角只用于同分筛选。详见 [`algo-2.md`](algo-2.md)。
### 问题三
发现保证用七点计划(原点 + 半径 $a=1159.7$ m 的六等分环):解析上界
$D(a)=\max\{a/\sqrt3,\ \sqrt{R^2+a^2-\sqrt3Ra}\}=984.5391$ m < 1000 m,
Ω 内任意位置的源都在某站点 1000 m 内。证据层按频道维护候选集与粒子幸存集,
负观测按 `full_disk` 语义排除 1000 m 圆盘;决策层用信息增益选点,
任务表包含检测、定位、清除三类任务,排序为开放路径问题;
所有频道销账即完成证明成立,立即 `/exit`。
### 问题四
定向源只向朝向 ±90° 的前向半球辐射,覆盖语义改为 `forward_half_disk`。
七点在该语义下有缺口,改用离线贪心得到的 31 点最小命中集(设计半径 965 m,
前向角裕量 5°),并以 15 m / 72 朝向档的运行期证书校核(325.62 万个采样格,缺口 0,
最坏命中 990.05 m)。负观测只约束朝向,因此维护位置 × 朝向联合信念,
信念坍缩到有限格时使用后备盲清。详见 [`algo-4.md`](algo-4.md)。
---
## 4. 端到端流程
```mermaid
flowchart TD
S([开始:/enter 成功<br/>现实预算 1200 s 起算]) --> P0[读配置 ProblemConfig]
P0 --> PLAN{按问题选择覆盖计划}
PLAN -->|问题 3| S7[七点全向计划<br/>解析上界 984.54 m]
PLAN -->|问题 4| S31[31 点最小命中集<br/>forward_half_disk 证书]
S7 --> LOOP
S31 --> LOOP
subgraph LOOP[主循环:动作回合]
direction TB
NEXT[选下一个任务<br/>信息增益 / 最坏后验半径<br/>滚动 2-opt 排序] --> SEND[/发送动作/]
SEND --> RESP{accepted?}
RESP -->|false| FIX[不更新状态<br/>记录并重排任务]
RESP -->|true| CLK[更新虚拟时钟、位置、频道]
FIX --> NEXT
CLK --> OBS{观测类型}
OBS -->|direction| HIT[登记新源<br/>同频道安排第二点交会]
OBS -->|no_signal| NEG[负观测裁剪<br/>位置候选或朝向档]
OBS -->|near| SKIP[距离过近,换点重测]
HIT --> DONE{该频道 ρ ≤ 20 m?}
NEG --> DONE
SKIP --> DONE
DONE -->|是| CLR[/清除动作/]
DONE -->|否| NEXT
CLR --> LEDGER[覆盖账本销账]
LEDGER --> FIN{全部频道销账?}
FIN -->|否| NEXT
end
FIN -->|是| EXITQ[完成证明成立,立即 /exit]
EXITQ --> REP[日志复算与统计]
REP --> END([结束:虚拟时间即成绩])
classDef main fill:#dce6f1,stroke:#1f4e79,color:#1c2430
classDef acc fill:#f6dcd8,stroke:#b03a2e,color:#1c2430
classDef ok fill:#d8ece5,stroke:#1e7a5f,color:#1c2430
class NEXT,SEND,RESP,CLK,OBS main
class CLR,FIN,EXITQ acc
class LEDGER,REP ok
```
会话状态机与单次动作回合见 [`figures/steps-state-machine.png`](figures/steps-state-machine.png),
逐步计时示例见 [`figures/timing-attachment-example-105-111-194-199.png`](figures/timing-attachment-example-105-111-194-199.png)。
---
## 5. 执行步骤与执行时间
一次动作回合:本地预校验 → 发送 → 等响应计时 → 按响应更新状态。
异常时同 `request_id` 同内容重发,400 与 409 立即失败。
| 动作 | 虚拟耗时 | 说明 |
| --- | --- | --- |
| `/enter`、`/exit` | 0 s | 不改变虚拟时刻,`/exit` 不切频道 |
| 移动 | 直线距离 / 5 m·s⁻¹ | 同点不动为 0 s |
| 换测向频道 | 1 s | 仅 `/measure` 触发,`/clear` 不切换 |
| 检测 `/measure` | 5 s | 与返回结果无关 |
| 清除 `/clear` | 5 s / 3 s | 成功 5 s,未发现 3 s |
实测样例(评测机日志 `BBM9-HZG2-77N5-NKKC`,问题三演练,10 源全清):
| 项 | 数值 |
| --- | --- |
| 总虚拟时间 | 3134.643 s |
| 移动(里程 11.9 km) | 2379.6 s |
| 检测与清除动作(119 + 10 次) | 645.0 s |
| 换频(110 次) | 110.0 s |
| 现实耗时 | 1.889 s |
三项之和等于响应中的 `virtual_time_s`,与 `evaluation.recompute_virtual_time` 口径一致。
分解图见 [`figures/timing-measured-q3-10-sources.png`](figures/timing-measured-q3-10-sources.png),
定向局(`GM56-…`,虚拟 8703.766 s,现实 3.397 s)与复现命令见
[`执行时间与执行步骤.md`](执行时间与执行步骤.md)。
---
## 6. 交付物与验收锚点
| 问 | 算法文档 | 主要实现 | 锚点 |
| --- | --- | --- | --- |
| 1 | [`algo-1.md`](algo-1.md)、[`问题一解答.md`](问题一解答.md) | `src/mcm26b/geometry/` | 演练复算 $D=23.9967$ m、$\rho=12.0686$ m、$E=+0.6040$ m |
| 2 | [`algo-2.md`](algo-2.md) | `geometry/`、`belief/`、`planner/` | 安全盘半径 249.8858 m |
| 3 | [`algo-3.md`](algo-3.md)、[`algo-3-bayes.md`](algo-3-bayes.md) | `planner/bayes_loop.py`、`planner/seven.py` | 七点上界 984.5391 m < 1000 m |
| 4 | [`algo-4.md`](algo-4.md) | `planner/directional.py`、`belief/joint.py` | 证书缺口 0,最坏命中 990.05 m |
| 1–4 | [`最优与基线实现对比.md`](最优与基线实现对比.md) | `project/` | `uv run python -m project.run` |
优化过程与未采用的改动见
[`第三四问架构优化与运行提速方案.md`](第三四问架构优化与运行提速方案.md)、
[`第三四问图论与动态规划优化方案.md`](第三四问图论与动态规划优化方案.md)。
+178
View File
@@ -0,0 +1,178 @@
# 执行时间与执行步骤
> 配套插图:[`figures/steps-state-machine.png`](figures/steps-state-machine.png)(状态机与动作回合)、
> [`figures/timing-attachment-example-105-111-194-199.png`](figures/timing-attachment-example-105-111-194-199.png)(附件示例逐步推演)、
> [`figures/timing-measured-q3-10-sources.png`](figures/timing-measured-q3-10-sources.png)(实测一局的时序分解)。
> 复现:`uv run python scripts/make_figures.py --only steps-state-machine,timing-attachment-example-105-111-194-199,timing-measured-q3-10-sources`
本文说明每一步做什么、每步花多少虚拟时间、这些数字如何验证。
规则原文见 `issue/` 下附件1 表1、表2 与附件2 第 4、10 节;
可执行表格在 `src/mcm26b/protocol/rules.py` 与 `src/mcm26b/config.py` 的 `CostConfig`。
---
## 1. 计时模型
忽略微秒量化时,一次会话的总虚拟时间为
$$
T=\underbrace{\frac{L}{5}}_{\text{移动}}+\underbrace{5N_m}_{\text{检测}}
+\underbrace{N_s}_{\text{换频}}+\underbrace{5N_c^{+}}_{\text{清除成功}}
+\underbrace{3N_c^{-}}_{\text{清除未发现}},
\qquad L=\text{路径长度(米)},\ 5\ \text{m/s}.
$$
规则:
- 移动按两点间直线距离计,不计加减速;
- 换频只在 `/measure` 触发,任意两频道间固定 1 s,`/clear` 不切换频道;
- 检测固定 5 s,与结果无关,`direction` 与 `no_signal` 同价;
- 清除成功 5 s(光学定位 3 s + 激光清除 2 s),未发现目标 3 s(仅光学定位);
- `/enter`、`/exit` 不产生虚拟时间;
- 访问顺序是开放路径问题,起点固定、终点自由,不必回到起点。
![执行步骤:状态机与动作回合](figures/steps-state-machine.png)
---
## 2. 执行步骤
### 2.1 会话级状态机
| 状态 | 进入条件 | 允许的动作 | 退出条件 |
| --- | --- | --- | --- |
| `IDLE` | 界面待机(演练不限次 / 正式各 3 次) | — | 点击"开始测试" |
| `COUNTDOWN` | 数据准备完成 | —(接口未开放) | 5 s 倒计时结束 |
| `OPEN` | 倒计时结束,接口在 `:2026` 开放 | `/enter` → `/measure` `/clear` → `/exit` | 25 分钟窗口到期 / 源全清后主动 `/exit` / 中止 |
| `CLOSED` | 窗口到期或进程退出 | —(连接关闭,已登记动作可完成) | — |
现实预算与现实窗口是两条独立时钟:`/enter` 成功后 `max_real_duration_s = 1200 s`
起算(程序侧),测试窗口 `test_window_s = 1500 s`(服务端侧)。
客户端维护本地截止时钟,剩余不足 60 s(`reserve_exit_s`,工程参数)时不再发起新动作,
只保证 `/exit` 能发出去。
### 2.2 单次动作回合(严格串行)
![动作回合](figures/steps-state-machine.png)
1. 本地预校验:`channel ∈ [1,20]`、坐标有限且 $\lvert x\rvert,\lvert y\rvert\le 2\times10^6$、
`request_id` 长度与字符集,与服务器 400 语义一致,省一次往返;
2. 串行发送:同一时刻只有一个未决请求,不并发(并发会得到 409);
3. 等服务端计时:`accepted=true` 才更新状态,虚拟时刻取响应中的 `virtual_time_s`,
不做本地累加;`accepted=false` 抛 `ActionRejected`,状态不更新,
`virtual_time_s=0` 不计入时钟;
4. 更新本地状态:位置、当前频道、剩余现实预算,追加 JSONL 会话日志;
5. 异常处理:网络错误、429、500 时同 `request_id` 同内容重发
(请求体一次性序列化,最多 `max_attempts` 次,指数退避);
400、404、405、409、413、415 立即失败。
重发不会重复计时,服务端按 `request_id` 幂等。
### 2.3 任务类型
| 任务 | 触发 | 动作序列 | 虚拟成本 |
| --- | --- | --- | --- |
| 覆盖扫描 | 某频道尚未被任何站点覆盖 | 移动到覆盖点 → `/measure` | 距离/5 + 5 s(+ 换频 1 s) |
| 定位交会 | 某频道收到 `direction` | 移动到第二检测点 → `/measure` | 距离/5 + 5 s(+ 1 s) |
| 清除 | 同频道候选区域 ρ ≤ 20 m | 移动到 MEC 圆心附近 → `/clear` | 距离/5 + 5 s 或 3 s |
| 后备盲清(问题四) | 联合信念坍缩到有限格 | 依次到可疑格 `/clear` | 距离/5 + 3 s 或 5 s |
| 机会测量 | 已停靠且该频道待测 | 原地 `/measure` | 5 s |
任务表排序是开放路径问题,默认用滚动 2-opt 与 Or-opt;
精确 Held-Karp 与路线感知探点在本模拟器上为负收益,默认关闭,见
[`第三四问图论与动态规划优化方案.md`](第三四问图论与动态规划优化方案.md) §8.6。
---
## 3. 附件计时示例逐步推演(105 / 111 / 194 / 199)
| 步 | 指令 | 移动 | 换频 | 动作 | 本步 | 累计 |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | `/enter` | 0 | 0 | 0 | 0 | 0 |
| 2 | `/measure (300,400) ch1` | 500 m → 100 s | 0(初始即 1) | 5 | 105 | 105 |
| 3 | `/measure (300,400) ch2` | 0 | 1 | 5 | 6 | 111 |
| 4 | `/clear (300,0) ch3` | 400 m → 80 s | 0 | 3(未发现) | 83 | 194 |
| 5 | `/measure (300,0) ch2` | 0 | 0(第 3 步后已是 2) | 5 | 5 | 199 |
| 6 | `/exit` | 0 | 0 | 0 | 0 | 199 |
![附件计时示例逐步推演](figures/timing-attachment-example-105-111-194-199.png)
验证方式:
```bash
uv run mcm26b sim-check # 客户端 → 本地模拟器链路,输出 [105, 111, 194, 199]
uv run pytest tests/test_protocol_timing.py -q # 逐步断言移动、换频、动作三个分项
```
---
## 4. 实测时序分解
对评测机留档的每一局,`scripts/make_figures.py` 按与 `referee.simulator`
同源的规则逐动作复算,并检查分项之和是否等于响应中的 `virtual_time_s`。
### 4.1 问题三演练局 `BBM9-HZG2-77N5-NKKC`(10 源全清)
| 项 | 数值 | 占比 |
| --- | ---: | ---: |
| 总虚拟时间 | 3134.643 s | 100% |
| 移动(里程 11.9 km) | 2379.6 s | 75.9% |
| 检测与清除动作(119 + 10 次) | 645.0 s | 20.6% |
| 换频(110 次) | 110.0 s | 3.5% |
| 现实耗时 | 1.889 s | — |
### 4.2 问题四演练局 `GM56-DFXZ-XKDM-XYV7`(12 源,含 3 个定向源)
| 项 | 数值 | 占比 |
| --- | ---: | ---: |
| 总虚拟时间 | 8703.766 s | 100% |
| 移动(里程 32.4 km) | 6489.8 s | 74.6% |
| 检测与清除动作(338 + 79 次) | 1951.0 s | 22.4% |
| 换频(263 次) | 263.0 s | 3.0% |
| 现实耗时 | 3.397 s | — |
![实测执行时序分解](figures/timing-measured-q3-10-sources.png)
### 4.3 结论
1. 移动占约 75%,优化重点是路径长度,这解释了七点计划(7 点、6.96 km 巡回)
优于 49 点网格的原因;
2. 动作占约 21%,检测 5 s 是下限,因此找全后立即退出比复扫更省时间;
3. 现实耗时与成绩无关,本地回环为毫秒级,官方口径取虚拟时间,
程序预算(1200 s)只用于限制计算耗时。
### 4.4 复现命令
```bash
# 用评测机留档重画(含真值)
uv run python scripts/make_figures.py --only timing-measured-q3-10-sources,\
replay-webui-q3-omnidirectional,replay-webui-q4-directional
# 归档新日志,评测机数据被清理后仍可复现插图
uv run python scripts/archive_replay_logs.py --list
uv run python scripts/archive_replay_logs.py BBM9-HZG2-77N5-NKKC
# 按官方口径逐微秒复算(接受客户端 JSONL 或评测机 log.jsonl)
uv run python scripts/analyze_run_timing.py referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl
uv run python scripts/analyze_run_timing.py examples/replay/*.jsonl --json /tmp/timing.json
uv run python scripts/verify_q3_practice.py output/q3/practice/<本局目录>
```
---
## 5. 时间预算与安全阀
| 约束 | 值 | 来源 | 客户端行为 |
| --- | --- | --- | --- |
| 移动速度 | 5 m/s | 题面 | 路径长度决定虚拟时间 |
| 检测 / 换频 | 5 s / 1 s | 题面 | 避免高频扫频 |
| 清除成功 / 未发现 | 5 s / 3 s | 题面 | 盲清代价可控 |
| 测试窗口 | 1500 s(现实) | 题面 | 窗口到期接口关闭 |
| 程序预算 | 1200 s(现实) | 题面 | `/enter` 后本地时钟起算 |
| 退出预留 | 60 s | 工程 | 剩余不足时只允许 `/exit` |
| 虚拟世界限时 | 360000 s | 题面 | 实测最坏为 1e4 量级,未触及 |
| 行为日志上限 | 2 MB | 题面 | 控制请求数 |
安全阀见 [`algo-3.md`](algo-3.md) §7.2 与 [`algo-4.md`](algo-4.md) §5.2:
预算将尽、连续无新发现或联合信念长时间不收敛时,转入最低成本收尾,
先清除并登记已有发现,再 `/exit`,并写入 `stop_reason`。
+131
View File
@@ -0,0 +1,131 @@
# 问题一至四:最优实现与基线实现对比
本文件是四问"最优实现 / 基线实现"对比的**论文口径说明**。代码与可复现
产物在仓库根目录 `project/`,运行 `uv run python -m project.run` 一次生成
`project/results/summary.md` 与逐问 `q1.md … q4.md`。本文件只摘录设计与结论,
数字以后者为唯一来源。
## 1. 交付物与目录
```text
project/
├── README.md 设计原则、各问对比设计、口径与边界
├── common.py 方法描述 / 指标聚合 / 落盘 / 闭环装配
├── run.py 统一入口(--question/--quick)
├── results/ 自动生成:q1.md/json … q4.md/json + summary.md
├── q1/ optimal.py baseline.py reference.py cases.py compare.py
├── q2/ optimal.py baseline.py reference.py region.py cases.py compare.py
├── q3/ optimal.py baseline.py compare.py
└── q4/ optimal.py baseline.py compare.py
```
角色边界:
- **最优实现**:直接适配 `src/mcm26b` 中已由 pytest 固化的生产实现,
不重写算法;
- **基线实现**:同题下更朴素、但能独立跑通的对照,不共享最优实现的关键步骤;
- **独立参考**:与分析算法正交的数值/枚举标准,用于判定谁对谁错。
第三、四问统一走 `LocalSimulator` 内存回环(与官方 HTTP 协议同一边界),
真值只在评测机侧;有效性判定沿用项目口径:
**全清 ∧ 无缺席误判 ∧ 正常 `/exit` ∧ 零异常 ∧ 逐微秒计时复算一致**。
## 2. 四问方法设计对照
| 问 | 最优实现 | 基线实现 | 独立参考 | 主要指标 |
| --- | --- | --- | --- | --- |
| 1 | 半平面交 + 顶点对精确直径 + Welzl MEC + 覆盖反例 | 网格采样 + **包围盒对角线**代理直径/覆盖 | 大框半平面裁剪 + 暴力直径/MEC | 状态、直径误差、覆盖准确率、耗时 |
| 2 | 保证接收盘内最小最坏后验半径(生产选点器) | ① 垂直 1000 m 最大交会角;② 候选集 MEC 圆心 | 保证接收盘内 9×9 网格枚举 | 保证接收率、最坏后验半径、移动时间 |
| 3 | `bayes`:粒子滤波 + 信息增益 + 滚动 2-opt | `grid`:49 点网格 + 就近服务;`seven`:七点批量 | 冻结基准集 + 真值全清校验 | 全清率、虚拟时间及其分布 |
| 4 | `directional`:31 点定向覆盖 + 联合信念 + 后备清除 | 问题三策略直接搬用(`bayes` / `grid`) | 冻结基准集(core+boundary) | 全清率、**缺席误判**、虚拟时间 |
## 3. 对比结果
### 3.1 问题一(40 个随机交会算例)
| 指标 | 最优 | 基线 |
| --- | --- | --- |
| 状态判定准确率 | 100% | 100% |
| 直径平均绝对误差 | **0.000 m** | 4.583 m(最大 14.60 m) |
| 直径圆覆盖判定准确率 | **100%** | 52.5% |
| 平均耗时 | **0.11 ms** | 22.35 ms |
固定示例进一步给出结构性反例(`examples/q1`,解析期望由
`tests/test_geometry*.py` 固化):
- `normal`:直径 26.99 m,**直径圆不覆盖**定位区域(最优判否、基线判是);
- `triangle`:直径 40.00 m 的等边三角形反例,最小包围圆半径 23.09 m > 20 m,
直径圆不覆盖;基线因"包围盒中心 + 对角线"恒判覆盖;
- `poor`:近共线检测点 → 无界,最优/基线/参考一致判无界;
- `segment`:零误差退化线段,最优判线段 D=100 m 且覆盖成立,基线退化为点;
- `empty`:观测不相容 → 空集。
> 基线的两处结构性缺陷:直径用包围盒对角线在斜/细长区域系统性高估;
> 覆盖用包围盒中心圆则恒判"能覆盖",恰好丢掉问题一要考的反例。
### 3.2 问题二(30 个随机首次示向度,初始 ρ 均值 681.5 m)
| 方法 | 保证接收率 | 最坏后验均值 | 终值比 ρ'/ρ | 移动均值 |
| --- | --- | --- | --- | --- |
| 最优(保证盘内最小最坏后验) | 100% | **73.89 m** | 0.104 | 170.4 s |
| 基线① 垂直 1000 m 最大交会角 | **0%** | 80.11 m | 0.116 | 200.0 s |
| 基线② MEC 圆心 | 100% | 340.75 m | 0.500 | 136.3 s |
| 参考(保证盘内网格枚举) | 100% | 75.63 m | 0.106 | 170.3 s |
> 基线①说明"只追交会角"会在本题失败:首次角域可延伸到 1500 m,
> 真源在远端时第二点距离超过 1000 m,测量直接 `no_signal`。
> 基线②保证接收但后验几乎不收缩(≈0.5ρ)。最优在同等保证下把后验压到 0.10ρ,
> 且与网格参考几乎重合(生产采样质量足够)。
### 3.3 问题三(18 个冻结 core 场景,全向 10/13/16 源)
| 方法 | 有效局 | 全清率 | 虚拟时间均值 | 中位 | 检测均值 | 请求均值 | 位移均值 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 最优 `bayes` | 18/18 | 100% | **3188.7 s** | 3111.3 s | 111.1 | 124.1 | 12338 m |
| 中间 `seven` | 18/18 | 100% | 5361.7 s | 5367.5 s | 100.8 | 113.8 | 23508 m |
| 基线 `grid` | 18/18 | 100% | 14935.7 s | 15275.1 s | 430.6 | 443.6 | 61550 m |
配对变化:`bayes` 相对 `grid` 虚拟时间 **−78.4%**(18/18 场景更快),
`seven` 相对 `grid` −63.7%。全部 54 局零异常、计时复算一致。
### 3.4 问题四(11 个冻结 core+boundary 场景,含朝外发射的边界定向源)
| 方法 | 有效局 | 全清率 | 缺席误判 | 虚拟时间均值 | 后备清除均值 |
| --- | --- | --- | --- | --- | --- |
| 最优 `directional` | 11/11 | **100%** | **0** | 9069.9 s | 24.8 |
| 基线 `grid`(49 点全向) | 0/11 | 67% | 0 | 18179.2 s | 0 |
| 基线 `bayes`(七站全向缺席证明) | 0/11 | 77% | **24** | 3890.8 s | 0 |
> 两条搬用基线的失效机理不同:
> `bayes` 用七站环的**全向**缺席证明,遇到背离圆心发射的边界定向源时
> 会把真源直接判成 ABSENT(累计 24 次 **缺席误判**,属"快而错",其虚拟时间
> 不可与最优直接比较);`grid` 的 49 点覆盖对定向源发现是完备的,但缺少
> 定向观测推理与 ≤20 m 后备清除,定位停滞只能停在 DETECTED("稳而不全")。
> 最优 `directional` 两种工况都是 11/11 全清、零误判,代价是多花时间与
> 平均 24.8 次后备清除。
## 4. 结论
1. 问题一:生产几何内核对状态、直径、覆盖三项与独立参考**逐案一致**;
朴素包围盒基线在覆盖判定上只有约 52% 准确率,且对固定反例全错。
2. 问题二:只有在"保证接收"约束内优化后验才既安全又有效;最优相对保守
基线把最坏后验半径从 0.5ρ 降到 0.10ρ,且与网格参考几乎重合。
3. 问题三:`bayes` 在相同全清率下把虚拟时间降到 `grid` 的约 1/5,
且逐场景配对 18/18 更快,说明"负观测感知 + 信息增益选点 + 全局排序"
三步都产生净收益。
4. 问题四:定向源的难点不是"发现"而是"证明缺席"与"失去信号后的清除";
直接搬用第三问策略会得到 24 次缺席误判,不可接受。`directional` 的
联合信念 + 后备清除是 11/11 全清的关键。
写论文时建议按"基线为什么错 → 最优补了哪一步 → 独立参考如何判定"的三段式
展开,并声明:随机分布是测试假设;基线时间快于最优的场景(如问题四 `bayes`)
不构成有效性优势,因为该局基线未完成全清任务。
## 5. 复现
```bash
uv run python -m project.run # 四问全部(约 3–4 分钟)
uv run python -m project.run --question 1 # 只跑问题一
uv run python -m project.run --quick # 缩小算例/基准集规模
uv run pytest tests/test_geometry.py tests/test_geometry_certificates.py -q # 几何回归
```
@@ -0,0 +1,516 @@
# 第三、四问:图论与动态规划算法引入方案
- 版本:2026-09-12
- 前置文档:[第三四问架构优化与运行提速方案](第三四问架构优化与运行提速方案.md)(架构与 P0–P2 项)、
[algo-3-bayes.md](algo-3-bayes.md)(现役第三问策略)、[algo-3.md](algo-3.md)(问题三当前算法说明)
- 范围:只讨论"用图论 / 动态规划类算法进一步压低**虚拟耗时**"这一件事;
题面约束、协议语义、保守性不变量全部不动
- 本文所有数字均为**本轮新增实测**(自建内存回环、冻结场景、现役代码),
复现命令见 §7
---
## 0. 结论先行
**可以,而且第四问的空间远大于第三问;但真正的收益不在"把巡回排得更短",而在
"把不必要的往返与盲清从决策层消掉"。**
| 判断 | 证据 | 可回收 |
| --- | --- | --- |
| 第三问**路由**已接近最优,纯图论排线几乎无空间 | 对**同一批实际作业点**求离线最优开放回路:2308 s vs 实测移动 2458 s,只剩 **6.1%(151 s)** | ≤ 150 s |
| 第三问仍有空间,但在**探测次数**(序贯决策),不在排线 | 30.8 次探测 / 13 源,且 0 次 `no_signal`——每次都在有效收缩,但次数仍偏多 | −150 ~ −250 s |
| 第四问**路由**有 20% 空间,但那是被定位/清除绕行"拖"出来的 | 离线最优 4998 s vs 实测移动 6257 s(**20.1%**);而覆盖点巡回的投影顺序 4365 s 已接近离线 31 点最优 4181 s(+4.4%) | −400 ~ −700 s |
| 第四问最大单点是**定向源定位失败导致的后备盲清** | 平均每局 **131 次清除只有 13 次成功**,`fallback_clear_attempts=125.7`,清除动作 419 s + 清除段移动 798 s ≈ **1220 s/局(14% T)** | **−800 ~ −1100 s** |
| 第四问第二点是**探测本身** | 平均 69 次探测 ≈ **2224 s/局(26% T)**,其中 32 s/次的移动占 1880 s | −400 ~ −800 s |
| 覆盖点集**已经最小**,不要再压 | 27 点方案在 75 m/24 档"通过",但在 25 m/48 档有 **298 个 (p,h) 缺口** → 是采样过拟合的假解;在细网格上直接搜索的最小命中集仍是 **31 点** | 0(见 §5.1 的正确性风险) |
**一句话:第三问的目标是"把 30.8 次探测压到 ~26 次并把序排到最优",第四问的目标是
"把 125 次盲清变成 3 次有保证的探测"。** 两者都是 DP / 序贯决策问题,
不是经典的 TSP 排线问题。
---
## 1. 目标函数的图论化
题面计时模型(`config.CostConfig`,已由 `evaluation.recompute_virtual_time` 逐微秒复算验证):
```
T = L/5 + 5·N_measure + 1·N_switch + 5·N_clear⁺ + 3·N_clear⁻
```
把它写成图上的路径代价,后面所有算法都在这张图上做:
- **节点** = 一次"停靠"(覆盖站点、定位测点、清除点);
- **边权** `w(a,b)` = `dist(a,b)/5`(移动秒);
- **节点服务费** = `5·(该点要测的频道数) + 1·(换频次数)` 或 `5/3`(清除)。
- 于是整局 = 一条**开放路径**(起点原点、终点自由),目标是最小化
`Σ边权 + Σ服务费 + Σ动作惩罚`。
四类图问题分别对应四个子决策:
| 子决策 | 图问题 | 现役做法 | 目标做法 |
| --- | --- | --- | --- |
| 站点/任务排序 | **开放 TSP(小 n 精确)** | NN + 2-opt(滚动) | Held-Karp 精确 DP(n ≤ 14,含换频状态)|
| 定位测点选择 | **带邻域的 TSP / 定向问题(TSPN/OP)** | 每任务独立选点 + 全表重排 | 覆盖骨架 + 最便宜插入;测点作为"邻域"参与联合优化 |
| 定向源定位 | **POMDP / 随机最短路** | 一步贪心 `prob_detect/时间` | 2–3 步 rollout,值函数 = 期望后验 MEC 半径 |
| 后备清除 | **区域覆盖路径(Covering Path)** | 格心最近邻 | 割草机 + 转向点 DP / 格心集 Or-opt |
---
## 2. 本轮实测基线(现役代码,冻结场景)
场景集:`harness/suites.py`,第三问 core 的 seed 100–105 × 13 源;
第四问 core 全部 9 场(10/13/16 源 × 3 定向占比)。配置为现役默认。
### 2.1 第三问(`bayes`,13 源,6 场)
| 指标 | 数值 |
| --- | ---: |
| 平均虚拟时间 | **3197 s** |
| 移动 | 12292 m = **2458 s(77%)** |
| 覆盖点检测 | 83.5 次 = 501 s(其中 69.8 次 `no_signal`,属缺席证明) |
| 定位探测 | **30.8 次 = 185 s**(0 次 `no_signal`) |
| 清除动作 | 65 s |
| **离线最优开放回路(同一批作业点)** | **2308 s** |
| 路由可回收 | **151 s(移动的 6.1%,T 的 4.7%)** |
| 作业点数(去重) | 35–50 |
### 2.2 第四问(`directional` + `q4_mincover_v1`,9 场)
| 指标 | 数值 |
| --- | ---: |
| 平均虚拟时间 | **8676 s** |
| 移动合计 | 6257 s(72%) |
| ├ 覆盖段移动 | 3579 s |
| ├ **探测移动** | **1880 s** |
| └ **清除移动** | **798 s** |
| 动作耗时 | 2149 s(覆盖 1386 / 探测 344 / 清除 419) |
| 探测次数 | 69.0 次(`no_signal` 4–12 次) |
| **清除次数 / 成功** | **131.1 / 13.0 → 118 次失败** |
| `fallback_clear_attempts` | **125.7 次/局** |
| 后备盲清格数(单次) | 3 ~ 210 格,全部以 `cleared` 结束 |
| **离线最优开放回路(同一批作业点)** | **4998 s** |
| 路由可回收 | 1259 s(移动的 20.1%,T 的 14.5%) |
| 覆盖投影顺序 vs 离线 31 点 2-opt | 4365 s vs 4181 s(+4.4%) |
### 2.3 成本地板估计
| 问题 | 不可压缩部分 | 现状 | 真实可压缩 |
| --- | --- | ---: | ---: |
| 第三问 | 七点环 1392 s + 覆盖检测 501 s + 清除动作 65 s + 每源必经的接近/清除移动 + 每源 ≥2 次探测 | 3197 s | **~300–450 s(10–14%)** |
| 第四问 | 31 点巡回 ~4180 s + 缺席检测 ~1386 s + 每源 ≥3 次探测与一次清除 | 8676 s | **~2000–2800 s(23–32%)** |
> 第四问的 4000 s 验收线**依然不可达**(单是 31 点巡回 + 缺席检测就 ≈5566 s),
> 这与前置文档 §6.2 的结论一致;本方案只承诺把 8676 s 压向 6500 s 量级。
---
## 3. 算法设计
### 3.1 D1(第四问最高优先):定向源的"抵近 + 交会"滚动时域 DP
**问题本质**:±1° 示向度误差在距离 d 处给出的横向不确定度约 `d·tan(1°) ≈ 0.0175 d`。
d = 1000 m 时单条方位线的横向约束只有 ±17.5 m;两条方位线的交会角 θ 决定最终尺度
`≈ 0.0175 d / sin θ`。要压到 20 m 清除证书,必须**同时**满足:交会角大、距离近。
现役 `_visibility_probe` 只最大化 `prob_detect(q)/(移动+6)`,天然偏好"近且可见",
与"交会角大"无关;远距离又永远收敛不到 20 m,于是退化到 20 m 网格盲清。
**形式化**(这就是一个 POMDP):
- 状态 `b` = `JointBelief`(位置 × 24 档朝向的可行集,见 `belief/joint.py`),
再叠加 `r_eff ~ U[1000,1500]` 的不确定度;
- 动作 `q` ∈ 候选测点(保证接收点 ∪ 对跖点 ∪ 三圈环探 ∪ **朝 MEC 圆心的抵近点**);
- 观测 `o ∈ {direction, near, no_signal}`,由每条粒子 `(p, h, r_eff)` 解析预测;
- 代价 `c(q) = 6 s + dist(pos,q)/5`;
- 终止:`MEC(b).radius ≤ 20 − margin`(可一次清除);
- 值函数:`V(b) = min_q E_o[ c(q) + V(b') ]`。
**实现选择(按代价递增)**:
1. **一步期望后验半径**(最小改动,复用 Q3 已有内核的二维推广):
对候选 `q`,按粒子权重模拟三分支结果,用幸存子集的 MEC 半径近似 `V(b')`,
取 `E[radius] + λ·c(q)` 最小者。把 `particles.py::expected_posterior_radius`
的向量化实现在 `JointBelief` 上重写一份(numpy 可用时广播)。
2. **2–3 步 rollout**:对前 K=8 个候选各展开一层,深度 2;墙钟预算 ≤ 0.3 s/决策。
3. **交会角代理(解析、零墙钟)**:若一步法来不及落地,先用
`score(q) = −E[radius] · sin(Δbearing(q, 既有方位线)) / dist(q, center)`
的确定性代理,实验证明有效后再换 rollout。
**关键结构性改动**:把候选点集从"绕 MEC 的固定环"扩展为**含抵近点**,
即允许 `q` 落在 `center + α·(pos − center)` 上、`α` 从 0.6 到 1.0 采样。
这样当远距离无法收敛时,策略会**主动抵近**并以一次正常角域证书收尾,
而不是把 200 格盲清当作唯一出路。后备清除**保留为安全网**,但目标是触发次数下降 ≥ 80%。
**验收**:`fallback_clear_attempts` ≤ 15/局(现 125.7);定向频道平均探测次数
≤ 全向频道的 1.5 倍;清除成功率 ≥ 90%;9 场景全清率 100%。
**预期**:−800 ~ −1100 s。
---
### 3.2 D2:覆盖骨架 + 最便宜插入(TSPN 的在线近似)
**问题本质**:31 个覆盖点是**必须在场**的(缺席证明),但探测点与清除点是
**临时产生**的。现役做法把两类点混在一张任务表里,每次从零做 NN + 2-opt
(`bayes_loop._order_tasks`),等于让临时任务把骨架顺序"打散"。
实测投影顺序 4365 s vs 离线最优 4181 s,说明骨架顺序本身没坏,
坏在**绕行开销**——而绕行开销正是插入位置没优化。
**形式化**:这是 **TSP with Neighborhoods / Generalized TSP**:
- 骨架:离线求覆盖点集的近优开放回路 `S`(`7` 点用解析证明;`31` 点用 Or-opt/3-opt,
`n ≤ 16` 时可直接 Held-Karp 精确);
- 在线:给定当前任务 `q` 与其**邻域**(`clear` 任务的邻域是 `C₂₀(K)`,`locate`
任务的邻域是候选测点集),求
`Δ(i,j) = dist(a_i, q) + dist(q, a_{j}) − dist(a_i, a_j)`
最小的插入位置 `(i,j)`;这正是"图上的最便宜插入",`O(|S|²)` 每任务。
**实施**:
1. `guarantee/cover.py` 增加 `optimize_tour(points, seed_tour, passes)`(Or-opt + 2-opt),
把 `nn_tour_m` 从"上界"变成"已优化值",并写入证书 `tour_virtual_s`。
2. `planner/bayes_loop.py` 新增 `_skeleton`(覆盖点顺序)与 `_insert_task(task, neighborhood)`;
`_order_tasks` 退化为"骨架遍历 + 已插入任务",保留现有 2-opt 作为兜底开关。
3. `clear` 任务的邻域用 **`C₂₀(K)` 内离插入点最近的点**(见 3.4),使插入代价与
清除目标联合最小。
**验收**:第四问移动 ≤ 5000 s(现 6257 s);路由相对离线最优的 gap
(新增回归指标 `route_gap_vs_offline`)从 20.1% 降到 ≤ 10%。
**预期**:−400 ~ −700 s。
---
### 3.3 D3:后备清除的覆盖路径(若 D1 后仍触发)
后备清除是"用 20 m 圆盘覆盖残差区域 `R` 直到命中真源"——即 **Covering Path Problem**。
- 当前 `_fallback_clear` 对格心做 nearest-first 扫描,等价于格心集上的 NN 开放路径,
典型约为最优的 1.2–1.3 倍;
- 改进:对格心集做 **Or-opt + 2-opt**(`k ≤ 400`,`O(k²)` 一次约 0.1 s,且只在
极少数局触发);
- 上界更优解:凸区域上的**割草机(boustrophedon)扫描**,用 DP 在扫描线方向选择
转向点可精确最优;对一般多边形用梯形分解 + DP。
**验收**:后备触发时移动 ≤ 现值的 80%(单次);触发次数本身由 D1 压到 ≤ 15/局。
**预期**:−100 ~ −200 s(D1 未完全消除时的兜底)。
---
### 3.4 T1/T3:第三问的精确排线、换频 DP 与清除点选择
**(a) Held-Karp 精确任务序(含换频状态)**
现役 `_two_opt` 是启发式且被 4 轮上限截断。任务表典型只有 6–12 项,
可以**精确求解**:
```
dp[S][j][c] = 已访问任务集 S、停在任务 j、测向频道为 c 的最小代价
转移:dp[S∪{k}][k][c'] = dp[S][j][c] + dist(pos_j, pos_k)/5 + service(k, c, c')
```
- 规模:`|T| ≤ 12` 时 `2^12 × 12 × 20 ≈ 1.0M` 状态,纯 Python 约 0.1–0.3 s/次;
滚动重排每步一次会吃掉预算,因此**只在任务表新增/删除任务时重解**,
或在 `|T| ≤ 9` 时默认启用、否则回退 2-opt + Or-opt。
- 换频代价精确化:`service` 依赖进入/离开频道,把 `c` 并入状态即可精确;
现役 `_path_cost` 用"按频道排序"的贪心近似,会低估/高估 1–3 s/站。
- 附图论下界:对当前点集算 **MST 权重**(`O(n²)` Prim),
得到开放路径最优值的下界,写入 `summary.route_lower_bound_s`,
用于**在线后悔值审计**与回归("本步排序距最优 ≤ x%")。
**验收**:`route_gap_vs_offline` ≤ 3%;单局墙钟增量 ≤ 0.2 s。
**预期**:−120 ~ −200 s。
**(b) 探测的 2 步 rollout(T2)**
现役 `_select_point` 是一步贪心(期望 log 幸存占比 + λ·移动)。
把它扩成深度 2 的 rollout:对前 `K=8` 个候选,各展开一次测量的三分支
(direction / near / no_signal),取 `E[V]` 最小者。
`V` 沿用现有 `expected_survival`。这属于**滚动时域 DP**,不改任何安全性判定。
**验收**:探测次数 30.8 → ≤ 26;墙钟 ≤ 0.3 s/决策。
**预期**:−150 ~ −250 s。
**(c) 清除点选在 `C₂₀(K)` 内离当前位置最近处(T3)**
`C₂₀(K) = ∩_{g∈K} B(g, 20)` 是凸集(圆盘之交)。求其内离当前点最近点是一个
**凸可行性/投影问题**(对小规模可枚举多边形顶点 + 圆盘投影,或直接迭代投影)。
现役 `_near_clear_target` 只沿一维方向平移,与最优之差 ≤ 0.74 m(前置文档 P1-1 已复核),
收益主要来自**与 3.2 插入代价的耦合**:先定插入位置、再选清除点,比反过来省更多。
**验收**:清除段移动下降 ≥ 5%。
**预期**:−50 ~ −150 s。
**(d) 七点环半径(T4)**:`1159.7 → 1122.9`(可证明下界),−44 s。
仅作为"证明性"改动落地,不作为收益项。
---
## 4. 实施路线
| 阶段 | 内容 | 交付物 | 验收门槛 | 依赖 |
| --- | --- | --- | --- | --- |
| **S0 基线冻结**(0.5 天) | 把近期 sweep 的最优参数(`route_aware_probe=false`、`lambda_move_s≈0.06`、`opportunistic_radius_ratio≈0.4–0.5`)回填为基准,跑满 core+boundary 并归档 | `output/suite/q3-baseline`、`q4-baseline` | 现有 `valid` 口径 100% | 无 |
| **S1 度量补全**(0.5 天) | 在 `scripts/run_suite.py` 增加 `route_gap_vs_offline`、`route_lower_bound_s`、`distinct_service_points`、`coverage_actual_visited` 四列 | runner 改动 + 回归 | 与本文 §2 实测复现一致 | S0 |
| **S2 覆盖证书硬化**(1 天,**正确性优先**) | 证书分辨率 75 m/24 → 20 m/72;设计裕量 `r_design ≤ 960 m` 或细网格直接搜索;保留 10% 保险点预算 | `guarantee/cover.py`、`plans/*.json`、正/负例测试 | 细网格(15 m/72)缺口 = 0;故意删点必须被检出 | S1 |
| **S3 第四问 D1**(2–3 天) | `belief/joint.py` 增加期望后验半径 / rollout 选点;`planner/__init__.py::_probe_candidates` 增加抵近点;后备降级为安全网 | `belief/joint.py`、`planner/__init__.py`、测试 | `fallback_clear_attempts ≤ 15`;全清 100%;墙钟 ≤ 1.0 s/局 | S2 |
| **S4 第四问 D2/D3**(2 天) | 覆盖骨架 + 最便宜插入;`C₂₀` 邻域;后备 Or-opt | `planner/*`、`guarantee/cover.py` | 移动 ≤ 5000 s;`route_gap ≤ 10%` | S3 |
| **S5 第三问 T1/T2/T3**(2 天) | Held-Karp(含换频)+ MST 下界;探测 2 步 rollout;`C₂₀` 最近点 | `planner/bayes_loop.py`、`plan/*` | 探测 ≤ 26;`route_gap ≤ 3%`;T ≤ 2900 s | S1 |
| **S6 收口**(1 天) | 全量配对、论文数据表、消融图 | 报告 + `docs/paper` 数据 | 与 S0 配对全部 `valid`,无退化场景 | S4/S5 |
**顺序约束**:S1(度量)先于任何算法改动,否则"更快"不可证;S2(证书)先于
第四问算法改动,否则可能在错误的安全基线上做优化。
---
## 5. 风险与明确不做的部分
### 5.1 本轮发现的正确性风险(必须先处置)
现役 `q4_mincover_v1`(31 点)与 `square49`(49 点)在**粗采样**下缺口为 0,
但把校核分辨率从 75 m/24 档提到 25 m/48 档:
| 点集 | 点数 | 75 m/24 缺口 | 25 m/48 缺口 | 15 m/72 缺口 | 最坏命中@75 m | 最坏命中@25 m |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `square49` | 49 | 0 | 0 | 0 | 760.3 m | 760.3 m |
| `q4_mincover_v1`(现役) | 31 | 0 | **125** | **566** | 999.1 m | 1000.0 m |
| 细网格重搜最小集 | 31 | 0 | 0 | 35 | 983.0 m | 996.2 m |
| 贪心 27 点(75 m 档最优) | 27 | 0 | **298** | 1117 | 986.5 m | 1000.0 m |
结论:
1. **31 点很可能就是实际下界附近**:多起点随机贪心 + 冗余剪枝在 25 m/48 细网格上
直接搜索的最小解仍是 31 点(尚未做 LP 松弛下界,但连贪心都下不去);
之前看到的 27 点是**采样过拟合的假解**,不可采纳;
2. `q4_mincover_v1` 的安全裕量几乎为 0(999.1 m),存在"真源恰落在细缝 + `r_eff` 取下界"
的漏检窗口,现役测试没暴露是因为随机场景未命中细缝且 `r_eff` 通常 > 1000;
3. `square49` 裕量充足但巡回 36.4 km,不可回退;
4. 正确做法是**细网格重搜 + 设计裕量**(S2),代价约 0–150 s,**先保安全再谈提速**。
### 5.2 其他风险
| 风险 | 影响 | 缓解 |
| --- | --- | --- |
| POMDP rollout 墙钟超预算 | 单局计算 > 1 s | 深度 2、候选截断 K=8、`--profile` 纳入基准必报列;超预算自动退回一步法 |
| Held-Karp 状态爆炸(任务表变长) | 单步计算抖动 | 仅在 `|T| ≤ 9` 默认启用,`> 9` 回退 2-opt + Or-opt |
| 抵近点破坏可见性保证 | 探测反而 `no_signal` 变多 | 抵近点仍以 `prob_detect > 0` 过滤;`no_signal` 是合法负观测,不破坏守恒性 |
| 骨架插入与"找全即停"冲突 | 为走骨架而多绕行 | 骨架只提供顺序,不新增必须访问的点;任务表为空即停 |
| 细网格证书重搜耗时 | 离线 3–5 min | 一次性离线搜索 + 运行期按计划名缓存校验(沿用 `load_plan` lru_cache) |
### 5.3 明确不做
- **不重引入 PPO/HRL**(前置文档已用 109 776 步的负面结果排除);
- **不引入新的运行时依赖**(仍只有 `requests`;`numpy` 仅作可选加速后端,
`networkx`/`scipy` 不进入运行时路径);
- **不改变停止条件**(`unresolved_channels` 的口径取舍属于评分方式问题,
须先与题面评分方式核对,本轮不作为默认行为);
- **不承诺第四问 4000 s**(成本地板 ≈5566 s,见 §2.3)。
---
## 6. 验收与度量
### 6.1 有效性定义(沿用,不得放宽)
```
valid := 全部真源被清除 ∧ 缺席频道与真值一致 ∧ 正常 /exit
∧ 零算法异常 ∧ 逐微秒计时复算一致
```
### 6.2 新增必报列(写入 `scripts/run_suite.py` 逐局行与 aggregate)
| 列 | 定义 | 用途 |
| --- | --- | --- |
| `route_gap_vs_offline` | `实测移动 − 离线最优开放回路(同作业点集)` / 实测移动 | 区分"排线不够好"与"点选得不对" |
| `route_lower_bound_s` | 当前任务集 MST 权重 / 速度 | 在线后悔值审计 |
| `distinct_service_points` | 去重作业点数 | 探测是否真的在减少 |
| `coverage_actual_visited` | 实际测过的覆盖点数 | 缺席证明是否提前结束 |
| `probe_no_signal_ratio` | 探测中 `no_signal` 占比 | D1 的效果指标 |
| `fallback_clear_attempts` | 已有 | D1 的主验收指标 |
### 6.3 目标(vs §2 基线)
| 指标 | Q3 现 | Q3 目标 | Q4 现 | Q4 目标 |
| --- | ---: | ---: | ---: | ---: |
| core 平均虚拟时间 | 3197 s | **≤ 2900 s** | 8676 s | **≤ 6500 s** |
| 移动 | 2458 s | ≤ 2250 s | 6257 s | ≤ 5000 s |
| 探测次数 | 30.8 | ≤ 26 | 69.0 | ≤ 45 |
| 后备盲清次数 | 0 | 0 | 125.7 | **≤ 15** |
| `route_gap_vs_offline` | 6.1% | ≤ 3% | 20.1% | ≤ 10% |
| `fallback` 清除成功率 | — | — | 10% | ≥ 90% |
| 单局计算墙钟 | 1.0 s | ≤ 1.2 s | 1.0 s | ≤ 1.5 s |
| 细网格证书缺口(15 m/72) | — | 0(Q3 解析) | 566 | **0** |
### 6.4 回归
`uv run pytest`(当前 232 项)必须全过;新增:
- `CoveragePlan` 细网格正/负例(删掉任一点必须被检出);
- `JointBelief` 的期望后验半径与真源保留性质对拍(随机 `(p,h)` × 随机观测序列);
- `Held-Karp` 与 `2-opt` 在同一小任务集上的最优性对拍(DP 结果必须 ≤ 2-opt);
- `C₂₀` 投影的三角不等式性质(投影点距候选集任一点仍 ≤ 20);
- 逐位一致性:numpy 与纯 Python 两条路径在同一动作序列下 `actions_sha256` 相同。
---
## 7. 复现命令(本轮实测)
```bash
# 度量基线(§2.1/§2.2/§2.3):作业点分解 + 离线最优回归 + 成本地板
uv run python /tmp/analyze_headroom.py # 路由 gap:Q3 6.1%,Q4 20.1%
uv run python /tmp/decompose.py # Q4 三段移动 + 动作 + 清除成功率
uv run python /tmp/q3stats.py # Q3 探测/覆盖检测/跳测统计
# 覆盖证书分辨率(§5.1)
uv run python /tmp/verify_margin.py # 现役 31 点在 25 m/48 档缺口 125
uv run python /tmp/hitset_fine.py # 细网格最小解仍是 31 点
# 既有常驻工具
uv run python scripts/run_suite.py --problem 4 --suite all --jobs 6 \
--variants directional@q4_mincover_v1 --label q4-baseline
uv run python scripts/verify_q4_cover.py --out output/q4/cover-certificate.json
uv run python scripts/analyze_run_timing.py <log.jsonl>
```
> 上述 `/tmp/*.py` 为一次性分析脚本,S1 阶段应把其中的
> `route_gap_vs_offline`、`offline_opt_open_path`、`mst_lower_bound`
> 三个函数并入 `scripts/run_suite.py`(或新建 `scripts/analyze_routing.py`)常驻入库,
> 使"虚拟时间花在哪"与"覆盖集是否合法"一样成为可随时重跑的回归项。
---
## 8. 本轮实测回填(2026-09-12 实施结果)
本节记录 S1–S5 全部落地后的**实测**结果与**负面结论**。所有数字均为冻结基准集
(`harness/suites.py`)配对复跑,口径与 §6.1 完全一致;复现命令见 §8.6。
### 8.1 交付物清单
| 项 | 位置 | 状态 |
| --- | --- | --- |
| 图论/DP 工具箱(精确开放路径、2-opt/Or-opt、MST 下界、路由度量) | `src/mcm26b/routing.py` | ✅ 新增 |
| S1 必报列(`route_gap_vs_offline`、`route_lower_bound_s`、`distinct_service_points`、`coverage_actual_visited`、`probe_no_signal_ratio`、`plan_verify_wall_s`) | `scripts/run_suite.py` | ✅ 新增 |
| S2 设计裕量覆盖计划 + 细网格证书 + 精细剪枝 | `guarantee/cover.py`、`scripts/verify_q4_cover.py`、`plans/q4_mincover_v2.json` | ✅ 新增并设为默认 |
| S3/D1 期望后验半径值函数 + 可见性过滤 + 抵近点 | `belief/joint.py`、`planner/__init__.py` | ✅ 新增(默认口径见 §8.3) |
| S4/D3 后备清除路径改进 | `planner/__init__.py::_fallback_order` | ⚠️ 已实现,实测负收益,默认关闭 |
| S5/T1 Held-Karp 精确任务序(含换频状态) | `planner/bayes_loop.py::_exact_order` | ⚠️ 已实现,实测负收益,默认关闭 |
| 回归测试 | `tests/test_routing.py`、`tests/test_joint_belief.py`、`tests/test_coverage_plan.py` | ✅ 新增,`uv run pytest` 268 项全过 |
### 8.2 最终成绩(vs S0 基线)
| 指标 | Q3 基线 | Q3 现 | Q4 基线 | Q4 现 | 目标 |
| --- | ---: | ---: | ---: | ---: | ---: |
| core 平均虚拟时间 | 3210.3 s | **3188.7 s(−0.7%)** | 8676.1 s | **8602.0 s(−0.9%)** | 2900 / 6500 ✗ |
| core 最大虚拟时间 | 3798.5 s | **3663.7 s(−3.5%)** | 10890.8 s | **9630.4 s(−11.6%)** | — |
| 移动 | 12446.8 m | **12338.1 m(−0.9%)** | 31286.4 m | 32891.1 m(+5.1%) | 2250 / 5000 ✗ |
| 检测次数 | 111.0 | 111.1 | 346.0 | **333.7** | — |
| 后备盲清次数 | 0 | 0 | **125.7** | **4.3(−96.6%)** | ≤15 ✅ |
| `route_gap_vs_offline` | 8.67% | **8.07%** | 18.9% | 24.3% | ≤3% / ≤10% ✗ |
| 单局计算墙钟 | 1.29 s | **1.04 s** | 5.29 s | **4.09 s** | ≤1.2 / ≤1.5 ⚠️ Q4 超标 |
| 覆盖计划运行期校验 | — | 0.42 s | — | 4.80 s(15 m/72 一次性) | — |
| 细网格证书缺口(15 m/72) | — | 0(解析) | 566 | **0** | 0 ✅ |
| 有效局 | 18/18 | 20/20(含边界) | 9/9 | 11/11(含边界) | 100% ✅ |
**结论**:本轮的硬收益是**第四问后备盲清被消除**(125.7 → 4.3 次/局,最坏局
10890.8 → 9630.4 s)与**覆盖证书的正确性**(细网格缺口 566 → 0);虚拟时间只有
0.7–0.9% 的均值改善(中位 −2.0%),**远未达到方案 §6.3 的目标**。
第三问的改善落在噪声内(中位相对变化 0.0005)。§2 的成本地板估计(Q3 可压缩
10–14%、Q4 23–32%)**过于乐观**,实测只回收了约 1%。
### 8.3 定向源探点(D1):先负后正,最终只保留"可见 + 就近"
D1 的完整实现(期望后验 MEC 半径值函数 + 抵近点 + 遮挡点剔除)在**修正联合
信念朝向规则之前**配对为:后备 125.7 → 53.8 次,但探测移动 +5.6 km,虚拟时间
8676 → 9411 s(净负)。原因有两个:
1. 后备清除在命中真源时**立即结束**,"整条路径最短"不是它的目标函数,
§3.2/§3.3 的插入代价模型在这里并不成立;
2. 更关键的是:**联合信念的 `no_signal` 朝向规则被写反了**(§8.4),
`prob_detect` / 期望半径因此系统性地高估"被遮挡点可见",选点必然跑偏。
修正后重测(9 场景 core):
| `probe_score_mode` | λ | 后备次数 | T 均值 | 移动 | 计算墙钟 |
| --- | ---: | ---: | ---: | ---: | ---: |
| `visibility`(旧) | — | 125.6 | 9224.6 s | 33595 m | 11.6 s |
| `expected_radius` | 0.05 | 6.8 | 9740.5 s | 38824 m | 9.6 s |
| `expected_radius` | 5.0 | 4.3 | 8604.3 s | 32893 m | 3.7 s |
| `nearest_visible`(默认) | — | **4.3** | **8602.0 s** | 32891 m | 3.4 s |
λ 越大越优说明本题的探点问题里"**看得见且少走路**"比"单步信息量最大"更重要;
λ→∞ 的极限(可见候选中移动最省)就是默认口径。值函数代码与其对拍测试保留,
供后续研究(例如配合真正的多步 rollout)。
### 8.4 本轮发现的正确性缺陷(已修复)
`belief/joint.py` 的 no_signal 朝向裁剪**规则反向**:`keep=False` 分支用了
"确定覆盖"掩码做交集,等价于保留"必然看得见"的档、删掉"确定看不见"的档;
`keep=True` 分支又漏计了格内角裕量 `asin(margin/max(dist−margin,1))`。
两者都会删掉真源的朝向档(`tests/test_joint_belief.py::test_true_source_survives_consistent_observations`
在随机观测序列上直接复现)。修复后:
`keep=False` 改用 `_far_mask`(与 `_cover_mask` 互补)并把距离阈值收紧为
`r_eff_min − margin`,`keep=True/False` 都计入格内角裕量。
**修复本身是净成本**:在旧 `visibility` 探点口径下 Q4 core 由 8676 → 9225 s;
换成 §8.3 的新探点口径后回落到 8602 s,同时后备清除降 96.6%。
换言之,本轮第四问的成绩改善**主要来自"修好信念 + 换探点口径"这一组合**,
而不是 §3 预期的插入/排线优化。
### 8.5 覆盖证书硬化(S2)
现役 `q4_mincover_v1`(31 点)在粗采样(75 m/24)下缺口 0,但细网格复检:
| 点集 | 点数 | 25 m/48 缺口 | 20 m/72 缺口 | 15 m/72 缺口 | 最坏命中 | NN 巡回 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `q4_mincover_v1`(旧) | 31 | 125 | 336 | 566 | 1000.0 m | 22.9 km |
| `q4_mincover_v2`(默认) | 31 | **0** | **0** | **0** | **990.0 m** | 23.9 km |
| 严格连续空间证书备选 | 36 | 0 | 0 | 0 | 973.7 m | 25.4 km |
`q4_mincover_v2` 的生成方式:搜索分辨率 50 m/48 档、设计裕量 `r_design=965 m`、
前向角裕量 5°,再做**证书分辨率(15 m/72)精细剪枝**(每次删点都用同一证书口径
复核),因此点数与旧计划相同而缺口归零,**没有付出点数代价**。
> 严格连续空间界需要 `r_verify + 15·√2/2 ≤ 1000`(即 ≤989.4 m)且角裕量 ≥2.5°;
> 满足该条件的 36 点方案最坏命中 973.7 m,但代价 +5 点(约 +1000 s),
> 已落盘为 `output/q4/cover-certificate-v3.json` 备用。默认方案在 15 m/72
> 采样下最坏 990.0 m,与严格界的差 0.65 m 属采样边界效应,作为已知残余风险登记。
### 8.6 负面结论与复现命令
| 优化项 | 实测 | 结论 |
| --- | --- | --- |
| S4/D3 后备清除 Or-opt | 后备失败 125.7 → 161.4 次(T 8676 → 8940 s) | ❌ 目标函数错位:命中即停,路径最短反而把真源推后 |
| S5/T1 Held-Karp 精确任务序 | 3203.2 s vs 2-opt 3193.1 s(18 场景) | ❌ 滚动时域下"当前任务表逐位最优"反而略差;默认 0 |
| `route_aware_probe` | 3210.3 s vs 关闭 3193.1 s | ❌ 权重 1e-3 的路线项无净收益;默认关闭 |
| Q4 融合巡回(站点顺带定位) | 12711 s vs 10809 s | ❌ 与 P0-1 在第三问的负面结论一致 |
| `opportunistic_radius_ratio` | 0.65 → 0.5:3210.3 → 3205.4 s | ✅ 采纳(弱收益) |
```bash
# S1 度量基线(含路由 gap / MST 下界 / 作业点/静默率)
uv run python scripts/run_suite.py --problem 4 --suite core --jobs 6 \
--variants directional --label q4-baseline --out output/suite
uv run python scripts/run_suite.py --problem 3 --suite core --jobs 6 \
--variants bayes --label q3-baseline --out output/suite
# S2 覆盖证书(生成 + 细网格校核;--fine-prune 走证书分辨率剪枝)
uv run python scripts/verify_q4_cover.py --spacing 100 --radius 2850 \
--target-step 50 --headings 48 --design-radius 965 --heading-margin 5 \
--verify-step 15 --verify-headings 72 --fine-prune \
--write-plan q4_mincover_v2 --out output/q4/cover-certificate-v2.json
# S3/D1 口径配对(可见性/值函数/极限三档)
uv run python scripts/run_suite.py --problem 4 --suite core --jobs 6 \
--variants "directional#search.probe_score_mode=visibility,\
directional#search.probe_score_mode=expected_radius;search.probe_lambda_move_s=5,\
directional#search.probe_score_mode=nearest_visible" --label q4-probe-ab
# 回归
uv run pytest -q # 268 项
```
### 8.7 仍未达标项的处置建议
| 未达标 | 差距 | 建议 |
| --- | --- | --- |
| Q3 ≤2900 s | −9% | 已无低风险空间:七站巡回 1392 s + 覆盖检测 501 s + 每源 ≥2 次探测是成本地板;需要改停止条件或覆盖语义才能继续下降 |
| Q4 ≤6500 s | −24% | 31 点巡回 + 缺席检测 ≈5566 s 是地板,与 §2.3 一致;只能改"逐频道缺席证明"口径 |
| `route_gap` Q4 24.3% | — | 该指标在"作业点数随决策变化"时口径不稳(本方案把后备格换成探测点后作业点从 206 降到 110);建议改为"覆盖骨架段"与"临时任务段"分别报 gap |
| Q4 计算墙钟 4.1 s(目标 1.5 s) | 2.7 s | 热点在 `belief` 凸多边形与 `select_measurement_point`(D1 之前的基线即 5.3 s),属 P0-4b 表示层张量化,与本方案无关 |
| 严格连续空间覆盖证书 | 0.65 m | 若要正式采用 36 点严格方案:`--verify-radius 989 --verify-heading-margin 2.5`,代价约 +1000 s |
@@ -0,0 +1,595 @@
# 第三、四问系统性架构优化与运行提速方案
- 版本:2026-09-12
- 依据:本仓库运行历史(`session.jsonl`、`practice-p3-*.jlog`、`referee-data/sessions/*`、
`output/hrl/ui/q3-main/*`、`docs/` 全部性能记录)+ 本文档新增的复跑与离线校核实验
- 范围:第三问(全向源)与第四问(混合定向源)的**闭环架构、算法分解、运行治理**,
不改动题面约束、协议层语义与既有保守性不变量
- 结论先行:**虚拟时间的 75–83% 是移动**,移动里约一半不是覆盖巡回而是定位/清除往返;
**第四问的全部失败来自定向源**;旧机器学习层已被证明不如手写基线。
因此本轮优化的主线是"**把定位并入覆盖巡回 + 把发现集压到最小命中集 + 给定向源建位置×朝向联合信念**",
而不是再堆学习算法。
---
## 0. 摘要(TL;DR)
### 0.1 三个待解的结构性浪费
| 编号 | 现象 | 直接证据 | 估计可回收 |
| --- | --- | --- | --- |
| W1 | Q3 定位探点往返 5741 m / 1148 s,与覆盖巡回(6960 m / 1392 s)相当 | 本次复跑(13 源,seed 0):24 次探点,均值 442 m/次 | **−900 ~ −1100 s/局** |
| W2 | Q4 发现集是 700 m 方格 49 点,巡回 36.4 km;同一保证下贪心最小命中集只要 31 点、22.9 km | `scripts/verify_q4_cover.py`:43 032 个 (p,h) 采样,两组点集均 100% 覆盖 | **−2700 s(巡回)+ −1140 s(检测)** |
| W3 | Q4 定向源没有"位置×朝向"联合信念,只能阶梯探点,最后退化到 ≤400 格盲清 | referee 两局:全向 17/17 清除,定向仅 2/6;4/4 漏检全是定向 | **−1500 ~ −3000 s/局** |
### 0.2 预期收益(自建模拟器,同一冻结基准集,配对口径)
| 指标 | Q3 现状 | Q3 目标 | Q4 现状 | Q4 目标 |
| --- | ---: | ---: | ---: | ---: |
| 平均虚拟时间 | 3707 s(本次 6 场景)/ 3536 s(13 源单局) | **≤ 2700 s** | 13 652 s(10 源 3 定向单局)/ 13 165 s(4 场景均值) | **≤ 9000 s** |
| 最大虚拟时间 | 4628 s | **≤ 4000 s** | > 17 000 s(边界压力) | ≤ 12 000 s |
| 每局计算墙钟 | 2.9–6.5 s | **≤ 0.8 s** | 6.5 s | **≤ 1.0 s** |
| 有效局(全清+缺席无误判+零异常+正常退出+计时复算一致) | 6/6 | 基准集 100% | 4/4 | 基准集 100% |
> 4000 s 是本项目 `docs/算法审核与优化-20260911.md` 自设的验收线,不是题面评分线;
> 第四问在 10 源场景下**不承诺**达成 4000 s,理由见 §6.2。
### 0.3 明确不做的事
- 不重新引入 PPO/HRL。运行历史支持"保留手写基线":HRL 训练 4007.9 s / 109 776 步后
仍被 `bayes` 稳定压制 4.3–5.0%(17–18/20 场景,符号检验 p=0.0001),且 94% 的差距来自
多走的移动;其评估集 20 个场景**全部是单源全向**,无法支撑任何第四问结论。
- 不引入新的第三方运行时依赖(仍是 `requests`;`numpy` 仅作**可选加速后端**,缺失时回退纯 Python)。
### 0.4 实施进展与实测回填(2026-09-12)
冻结基准集 `harness/suites.py`(第三问 18 主场景 + 2 边界;第四问 9 + 2),
并行 runner `scripts/run_suite.py`,配对口径同场景同误差种子。
| 项 | 状态 | 实测 | 结论 |
| --- | --- | --- | --- |
| P1-4 安全阀 | ✅ 已实现 | `summary` 新增 `completion_basis` / `absence_evidence` / `redundant_rescan_measures` / `virtual_reserve_s`;`--persistent` 输出单轮上界告警 | 采纳(5 项测试) |
| P0-2 最小命中集 | ✅ 已实现并默认开启 | 第四问 11 场景配对:**14003.0 → 10975.5 s**(均值 −19.3%、中位 −25.4%、10/11 更快);检测 444.5→319.2;请求 569.5→395.6;位移 54.9→44.2 km;最大 17007→12919 s;11/11 valid | **采纳** |
| P0-4 感知层向量化 | ✅ 已实现 | 单局计算 **3.10 → 1.00 s(3.08×)**,最大 5.84 → 1.30 s;20 场景的虚拟时间与动作序列**逐位一致** | **采纳**(目标 ≤0.8 s 未达,余下为 belief 表示层) |
| P0-1 融合巡回 | ❌ 实测无效,已回退默认 | 仅追加站点方位线:3454.6 vs 3426.9 s(+0.8%,检测 +10.8 次、位移仅 −188 m);追加 + 抑制专用探点:**4989.0 vs 3426.9 s(+45.6%,20/20 更慢)** | 关闭(保留开关与代码) |
| P1-1 C₂₀ 最近清除点 | ⊘ 复核后降为非项 | 现有 `_near_clear_target` 已取安全球 `B(c, limit−ρ)` 内离当前位置最远点;与完整 C₂₀ 最优之差 ≤ slack+margin ≈ 0.74 m | 不改 |
| P1-3 基准集/并行 | ✅ 已实现 | 20 场景 × 3 变体 = 60 局 **26.5 s**(6 进程);20 局 **3.9 s** | 采纳 |
| P0-3 联合信念 | ✅ 已实施并于 2026-09-12 修正 | 网格粒子 × 24 档朝向 bin + 可见性选点;**发现并修复 `no_signal` 朝向规则反向缺陷**(原会删掉真源朝向档);配套 D1 探点口径使第四问后备盲清 **125.7 → 4.3 次/局** | 采纳(结论与实测见[图论与 DP 优化方案 §8](第三四问图论与动态规划优化方案.md)) |
**P0-1 为什么失败(重要负面结论)**:七站环上通常只有 2–3 个站能对同一源取得
有效方位线,且站间交会角不足以直接换到 20 m 证书,专用信息增益探点仍然必要;
"顺路测量"于是退化为平白多花检测,一旦抑制专用探点则会白等巡回、远端绕行。
**结论:第三问的定位往返不是可回收的浪费,`bayes` 的滚动时域调度已在做正确的事。**
**第四问现状与目标差距(2026-09-12 图论/DP 轮回填)**:启用硬化覆盖计划
`q4_mincover_v2` 与 D1 探点口径后,第四问 11 场景(core + boundary)均值为
**9069.9 s**、最大 12081.1 s、后备盲清 24.8 次/局(core 9 场景 8602.0 s /
4.3 次),仍远高于 4000 s 验收线。剩余成本主要是最小命中集巡回
(23.9 km ≈ 4777 s)与缺席频道检测,二者都是覆盖证明的固有代价;
本方案 §2.3 的"可压缩 23–32%"在本模拟器上只回收了约 1%(详见图论与 DP 方案 §8)。
---
## 1. 运行历史复核
### 1.1 数据资产清单(本次实际读取)
| 资产 | 内容 | 可用信息 |
| --- | --- | --- |
| `session.jsonl`(31 011 行) | 官方第三问演练 J2WH-2K7D-5ZXS-DNK6 的客户端日志 | 10 323 次 `/measure`、12 次 `/clear`、逐动作计时 |
| `practice-p3-*.jlog` | 同一局的官方行为日志封装 | 仅明文信封(题号 3、队号、案例码);载荷 AES-256-GCM + RSA-OAEP,不可解 |
| `referee-data/sessions/*`(6 局,5 局完整) | 本地评测机 q3×3、q4×2、截断×1 | 逐请求响应、真值、summary、step 事件 |
| `output/hrl/ui/q3-main/` | HRL 训练(109 776 步)+ `eval/at-40k`、`eval/at-final` | monitor CSV、模型元数据、20 场景配对评估 |
| `docs/算法审核与优化-20260911.md`、`docs/algo-3.md`、`docs/algo-3-bayes.md` | 历史 KPI 与消融 | 官方/自建成绩、验证集分档 |
| 本次新增复跑 | `scripts/benchmark_q3_bayes.py`(6 场景)、Q3/Q4 单局计时分解、`cProfile`、站点三角化可行性 | §1.3 中标注"本次复跑"的数字 |
| 本次新增工具(已入库) | `scripts/analyze_run_timing.py`(任意会话日志的计时分相复算)、`scripts/verify_q4_cover.py`(第四问覆盖证书 + 最小命中集搜索) | F4、F9 可复现 |
### 1.2 先确认度量可信(否则一切优化都是自欺)
官方计时模型:`T = L/5 + 5·N_measure + N_switch + 5·N_clear⁺ + 3·N_clear⁻`,
其中 `L` 为累计直线位移,`/clear` **不计**换频。`scripts/verify_q3_practice.py` 对 5 局完整
评测机日志逐微秒复算,与服务器返回的 `virtual_time_s` 完全一致(例:BBM9 复算 3134.642907 = 记录 3134.642907)。
结论:**后续所有"虚拟时间"结论都可用动作日志独立复算**,这是本项目最可靠的一条工程资产,必须保留。
### 1.3 关键事实(F1–F13)
| 编号 | 事实 | 出处 |
| --- | --- | --- |
| F1 | 虚拟时间构成:**移动 75–83%|检测动作 15–21%|换频 2.3–3.7%** | 官方会话 82.30/14.76/2.94;referee q3 80.50/16.78/2.71、q4 78.39/18.63/2.98;本次复跑 Q3 79.9/17.3/2.9、Q4 75.2/21.1/3.7 |
| F2 | 官方第三问演练 J2WH 总虚拟 350 227.7 s,其中 **346 169.9 s(98.84%)是空复扫**:7 个固定站点 × 8 个未清除频道 × 183 轮,0 检出,结束点正好落在 `virtual_reserve_s=10 000` 边界 | `session.jsonl` 相位切分;`planner/__init__.py:236`、`config.py:99` |
| F3 | **第四问的全部失败来自定向源**:referee 两局全向 17/17 清除,定向仅 2/6;4/4 漏检全是定向;每清除源 356.4 s(Q3 274.0 s,+30%) | `referee-data/sessions/{6X58,BAU8}`;`{BBM9,RM7Y,VQKB}` |
| F4 | 本次复跑 Q3(13 源,seed 0):3535.9 s / 109 次检测 / 13 清除;**七站巡回 6960 m(1392 s,39%)+ 探点往返 5741 m(1148 s)+ 清除移动 3668 m(734 s)** | 本次复跑(方法见附录 A) |
| F4b | 评测机 Q3 单局 BBM9:**21 次专用探点占 1138.7 s 移动,等于该局虚拟时间的 36.3%**,而站点扫频 98 次只占 991.2 s | `scripts/analyze_run_timing.py referee-data/sessions/BBM9-.../log.jsonl --plan seven` |
| F5 | 本次复跑 Q4(10 源 3 定向,seed 0):13 652.1 s / 560 次检测 / 18 次清除(8 次失败)/ 51 356 m | 本次复跑 |
| F6 | 感知层是墙钟热点:单局计算 6.04 s;`cProfile` 下 `expected_survival` 占累计时间 **72%**(2808 次调用),`apply_measure` ≈ 20%,`_kill_outside_wedge` 触发 498 万次 `angular_gap` | 本次 `cProfile`(13 源单局) |
| F7 | HRL 运行:109 776/200 000 步、4007.9 s、**27.0 steps/s(6.75/env)**、1.51 s 墙钟/局;被 SIGTERM 截断时回报仍在上升(Q1 1.05 → Q4 6.20) | `output/hrl/ui/q3-main/q3.json` + 4 份 monitor CSV |
| F8 | HRL 评估:20 场景**全部单源全向**;`bayes` 比 HRL 快 4.3–5.0%(17–18/20,p=0.0001),**94% 的差距是多走的移动**;40k→109k 步仅再改善 0.7% | `eval/at-40k|at-final/aggregate.*`、`eval/manifest.json` |
| F9 | 现役 Q4 发现集:700 m 方格 49 点、NN 巡回 **36.4 km**;满足同一"前向半盘命中"保证的贪心最小集 **31 点、22.9 km(−37%)**,覆盖校核 100% | `scripts/verify_q4_cover.py`;本文附录 A |
| F10 | Q3 七站巡回**已经最优**:6 × 1159.7 = 6958 m(观测 6960 m),无可压缩空间;把环半径降到覆盖下界 1122.9 m 仅省 222 m(44 s) | 几何计算 + 本次复跑 |
| F11 | 站点三角化可行:**99.28% 的源位置有 ≥2 个站在 1500 m 内**;最佳交会角 5 分位 58.5°、中位 122.9°;只有 0.72% 的源位置仅 1 个站在射程内 | 本次离线采样(20 000 点) |
| F12 | 墙钟量级差三个数量级:内存回放 **0.22–0.25 ms/请求**(≈0.35 s/局),官方接口 **9.42 ms 均值/请求**(104.49 s / 10 337 请求);本地评测机 24.5–97.9 ms/请求 | referee `session_end`、`runs/*/summary.json`、`session.jsonl elapsed_s` |
| F13 | 历史 KPI 参照:Q3 官方最好 4058.71 s(3BW5,13/13)、5232.13 s(J4ER,12/12);自建 `bayes` 3707.3 s(本次 6 场景)/ 3726.2 s(14 场景消融)/ 验证集 3315.89 s;Q4 自建 13 164.7 s,**无官方第四问演练记录** | `docs/算法审核与优化-20260911.md`、`docs/algo-3-bayes.md`、`README.md:135` |
### 1.4 由事实导出的六处结构性瓶颈
| 编号 | 瓶颈 | 支撑事实 | 归属层 |
| --- | --- | --- | --- |
| B1 | 定位/清除移动没有并入覆盖巡回,探点按"信息增益"选,移动权重 λ=0.0105 几乎不惩罚绕行 | F1、F4、F4b、F11 | 决策层 |
| B2 | Q4 发现集冗余 63%(49 点 vs 30 点),且每个"真缺席"频道要在全部 49 点各测一次 | F5、F9 | 保证层 |
| B3 | Q4 定向源缺少位置×朝向联合信念:`no_signal` 只记"被遮挡过几次",选点靠固定 45° 阶梯,收敛失败后退化到 ≤400 格 20 m 盲清(≤1200 s + ≤400 请求) | F3、`planner/__init__.py:691-768` | 感知层 + 决策层 |
| B4 | 感知层全 Python 容器:每局 20 个频道各建 ~6.1 万格 `set`,`_kill_outside_wedge` 每次遍历全部幸存格,评分核 `expected_survival` 为 7×800 的纯 Python 双循环 | F6 | 感知层 |
| B5 | 研发吞吐低:场景串行、单进程;一局 0.35–6.5 s;HRL 27 steps/s;14–52 场景的配对基准要跑几分钟到十几分钟 | F6、F7、F12 | 实验层 |
| B6 | 运行治理缺失:单源评估集使指标退化(`avg_locate_clear_time_s ≡ virtual_time_s`)、`eval/manifest.json` 三份重复且与 `output/hrl/ui/manifest.json` 不一致(后者缺失)、`persistent_search=True` 可造成 98.84% 的无效开销且无硬性告警 | F2、F8、F13 | 遥测/实验层 |
---
## 2. 目标架构
### 2.1 分层与依赖方向(依赖只能向下)
```
┌───────────────────────────────────────────────┐
L6 实验/遥测 │ bench/ 冻结基准集·并行 runner·配对统计 │
│ telemetry/ manifest·step log·replay·summary │
└───────────────▲───────────────────────────────┘
│ 只读观测
┌───────────────┴───────────────────────────────┐
L5 执行/安全 │ exec/ 动作账本·预算守卫·安全阀·幂等客户端 │
└───────────────▲───────────────────────────────┘
│ Action 请求
┌───────────────┴───────────────────────────────┐
L4 决策 │ plan/ 任务表·滚动时域排序·信息/时间评分 │
└───────────────▲───────────────────────────────┘
│ Task[]
┌───────────────┴───────────────────────────────┐
L3 保证 │ guarantee/ 命中集覆盖计划·清除证书·缺席证明 │
└───────────────▲───────────────────────────────┘
│ 候选集/幸存集
┌───────────────┴───────────────────────────────┐
L2 信念 │ belief/ BeliefBackend:OccupancyTensor(Q3) │
│ JointTensor(位置×朝向, Q4) │
└───────────────▲───────────────────────────────┘
│ Observation
┌───────────────┴───────────────────────────────┐
L1 观测模型 │ model/ 可见性半平面·r_eff 带·有界误差·舍入裕量 │
└───────────────▲───────────────────────────────┘
│ 原始响应
┌───────────────┴───────────────────────────────┐
L0 协议/时钟 │ protocol/ 规则表·计时模型·状态机·客户端(冻结)│
└───────────────────────────────────────────────┘
```
与现状的差别:**用组合取代继承**。现状是
`OmnidirectionalLoop → SevenBatch → BayesLoop → DirectionalExtension` 的单继承链,
调度、信念、清除、预算、报表五种职责混在同一族类里(`planner/__init__.py` 818 行 +
`planner/bayes_loop.py` 513 行),任何一处改动都会跨层影响其它三问。
目标形态是
```python
Episode(
client = SimulatorClient(...), # L0,冻结
belief = OccupancyTensor(...) | JointTensor(...), # L2
plan = CoveragePlan.points, # L3
scorer = InfoGainPerSecond(...), # L4
policy = FusedTourPolicy(...) | DirectionalPolicy(...), # L4
certifier= Certificate(...), # L3
ledger = Telemetry(...), # L6
)
```
三层保证策略矩阵只差**三个可替换部件**,其余代码共享:
| 问题 | 信念后端 | 覆盖计划 | 选点策略 |
| --- | --- | --- | --- |
| Q3 | `OccupancyTensor`(全向) | 七站环(已经最优,冻结) | 融合巡回 |
| Q4 | `JointTensor`(位置×朝向) | **最小命中集**(30 点,离线搜索 + 运行期校验证书) | 可见性约束选点 |
### 2.2 接口契约(关键签名)
```python
# L1 model/observation.py —— 只此一处定义"什么算看见"
@dataclass(frozen=True)
class ObservationModel:
r_eff_min_m: float; r_eff_max_m: float
near_radius_m: float; half_angle_deg: float
directional_half_deg: float = 90.0 # 含边界
def visible(self, src: Vec2, heading_deg: float | None, reader: Vec2) -> bool: ...
def detectable(self, src: Vec2, heading_deg: float | None, reader: Vec2) -> bool: ...
# L2 belief/base.py —— 两种后端实现同一协议
class BeliefBackend(Protocol):
def apply(self, channel: int, reader: Vec2, result: str,
svd_deg: float | None) -> None: ...
def alive(self, channel: int) -> int: ...
def is_absent(self, channel: int) -> bool: ... # 幸存集为空
def certificate(self, channel: int) -> ClearCertificate | None: ...
def guaranteed_no_signal(self, channel: int, reader: Vec2) -> bool: ...
def prob_detect(self, channel: int, reader: Vec2) -> float: ... # 决策用
def version(self, channel: int) -> int: ... # 派生量缓存键
# L3 guarantee/cover.py —— 覆盖计划是"可离线搜索、可在运行期校验"的一等对象
@dataclass(frozen=True)
class CoveragePlan:
problem: int # 3 | 4
points: tuple[Vec2, ...]
certificate: CoverCertificate # 采样分辨率、缺失数、最坏裕量、脚本哈希
version: str
def verify(self, model: ObservationModel, tol_m: float) -> CoverCertificate: ...
# L4 plan/policy.py
class Policy(Protocol):
def tasks(self, belief: BeliefBackend, state: RobotState) -> list[Task]: ...
def order(self, tasks: list[Task], state: RobotState) -> list[Task]: ...
def measured_at_point(self, point: Vec2) -> tuple[int, ...]: ... # 一停多测
```
### 2.3 四条设计原则
1. **保守性不变量不动**:真源永不被删;清除证书始终基于完整 ±1.005° 角域与题面距离带;
所有启发式(均匀先验、朝向先验、信息增益)**只用于选点,不用于安全证明**。
Q4 的朝向联合信念必须自带"朝向未观测时退化为全向"的保守分支。
2. **保证 = 离线搜索 + 运行期校验**:覆盖集、清除点、巡回顺序都可以离线用数值搜索优化,
但运行期必须用同一份 `ObservationModel` 重新校验证书(点集、分辨率、裕量),
校验失败即拒绝启动,而不是相信一个写死的点表。
3. **一个事实一个来源**:题面常量、`r_eff` 带、清除半径、动作耗时只在 `config.py`;
可见性语义只在 `model/observation.py`;训练/部署若将来共存,必须共用同一控制器模块
(这是旧 HRL 用 13 000 行换来的教训:v1 的 5 个特征索引错位、BC 激活函数不一致、
旧基准把 `completed` 当全清)。
4. **每个优化都必须可配对、可复算、可回归**:冻结基准集 + 逐局 `manifest` + 动作日志
+ 逐微秒复算;任何"更快"的声明必须给出配对分布(均值/中位/最大/更快场数),
而不是单个最优场景。
### 2.4 迁移映射(现状 → 目标)
| 现状 | 目标 | 处理 |
| --- | --- | --- |
| `protocol/*`、`evaluation/recompute_virtual_time` | 不变 | 冻结,作为度量基准 |
| `belief/__init__.py`(凸外包) | `belief/convex.py` | 原样搬迁,继续负责精确角域证书 |
| `particles.py`(网格幸存集) | `belief/occupancy.py`(numpy 张量 + 纯 Python 回退) | 重写热核,语义不变,保留 `tests/test_particles.py` 的真源保留性质测试 |
| — | `belief/joint.py`(位置×朝向) | 新增,Q4 专用 |
| `coverage/` | `guarantee/cover.py` | 49 点常量表 → 可校验的 `CoveragePlan` |
| `planner/bayes_loop.py` 的 `_build_tasks/_order_tasks` | `plan/tasks.py`、`plan/schedule.py` | 抽出,Q3/Q4 共用 |
| `planner/bayes_loop.py::_select_point` | `plan/score.py` | 抽出 + 向量化评分 |
| `planner/__init__.py::DirectionalExtension` | `plan/policy.py::DirectionalPolicy` + `belief/joint.py` | 保留后备清除作为最终兜底,但目标是不再触发 |
| `planner/seven.py` | `guarantee/plans.py::SEVEN` | 保留解析证明 |
| 4 个 benchmark 脚本 | `bench/` 统一 runner(并行 + manifest + 配对统计) | 合并,消除指标口径分叉 |
---
## 3. 优化项
### P0-1 第三问:发现—定位融合巡回(消除探点往返)
**现状**:每次收到 `direction` 后进入独立定位子循环,由信息增益选点器在同一站点之外
另选探点;13 源单局共 24 次探点、5741 m 往返、1148 s,与整个覆盖巡回(6960 m / 1392 s)同量级;
评测机单局 BBM9 更极端:**21 次探点花掉 1138.7 s 移动 = 全局限时时间的 36.3%**(F4b)。
评分函数 `score = E[log 幸存占比] + 0.0105 × 移动秒数`,移动项几乎不影响排名。
**方案**:把"已发现未定证"的频道加入**每一个覆盖站点**的批量扫频清单,
使第二/第三条方位线在巡回途中顺路取得;只有站点三角化不成立时才回退到专用探点。
- 巡回仍由 `plan/schedule.py` 滚动排序(现有最近邻 + 2-opt 已足够,`bayes` 的 −39.5% 移动
主要来自这里),新增"同点顺路测量"任务类型:`Task(kind="station", channels=(未知, 未定证))`。
- 站点任务的固有耗时按 `6 s × 频道数 + 1 s × 换频次数` 记账(现有 `_path_cost` 已支持)。
- 保底:`F11` 显示 0.72% 的源位置只有 1 个站在 1500 m 内,对这类频道保留
`_select_point` 的专用探点路径;判定用 `belief.prob_detect` 而非硬编码。
**预期收益(已被实测推翻)**:原估 F4 的 1148 s 探点移动可回收 70–80%,
即 −800 ~ −900 s。**实测结果相反**:仅追加站点方位线 +0.8%,追加并抑制专用探点
+45.6%(20/20 场景更慢),见 §0.4。原因是站间交会角不足以保证 20 m 证书,
专用信息增益探点仍然必要;抑制它只会白等巡回。**本项不采纳,默认关闭。**
**验收**:18 场景验证集平均 ≤ 2700 s、最大 ≤ 4000 s;`measures` 增幅 ≤ 20%;
`move_distance_m` 降幅 ≥ 25%;全部 `valid`。
**风险**:站点距离最远 2 × 1159.7 = 2319 m,可能出现 `no_signal` 浪费 5 s。
缓解:仅在 `prob_detect > 0` 时顺路测量;`no_signal` 同样是有效负观测(进信念,不算异常)。
---
### P0-2 第四问:用最小命中集替换 49 点发现集(离线搜索 + 运行期校验)
**现状**:`coverage_points()` 生成 700 m 方格 49 点(±2100),依据是"单元内任一点到 4 顶点
≤ 700√2 ≈ 989.95 ≤ 1000"。该条件是**充分但远非必要**:它要求单元内任意位置、任意朝向都由
**同一个**顶点命中。实际上,第四问的保证是"对 ∀(p,h) ∈ Ω×S¹,存在被访点位于其前向半盘内",
允许由**多个**顶点共同围住 p。
**方案**:把它当作一个显式的**击中集(hitting set)问题**离线求解,运行期校验:
1. 目标空间离散:`p` 取 Ω 内 75 m 网格,`h` 取 24 个方向 → 43 032 个 (p,h) 单元;
2. 候选点:半径 2850 m 圆盘内 200–300 m 网格(641/293 个候选);
3. 贪心集合覆盖 + 局部改进,**同时把巡回长度作为次级目标**(641/293 个候选中取 31/30 个,
仍有大量同覆盖度的等价解可用于缩短巡回);
4. 生成 `CoveragePlan(points, certificate)`,`certificate` 记录采样分辨率、未覆盖数、
最坏裕量、生成脚本哈希;`CoveragePlan.verify()` 在每次运行前用同一 `ObservationModel`
重新校核,未通过即拒绝启动。
**本次离线校核结果**(附录 A 可复现):
| 点集 | 点数 | (p,h) 覆盖 | NN 巡回 | 折算移动 |
| --- | ---: | ---: | ---: | ---: |
| 现役 700 m 方格 ±2100 | 49 | 100% | 36.4 km | 7280 s |
| 三角格 1000 m(半径 2800 盘) | 31 | 100% | 34.3 km | 6863 s |
| **贪心最小命中集(200 m 候选)** | **31** | **100%** | **22.9 km** | **4587 s** |
| **贪心最小命中集(300 m 候选)** | **30** | **100%** | **23.6 km** | **4719 s** |
**实测收益(2026-09-12,11 场景配对)**:均值 **14003.0 → 10975.5 s(−19.3%)**,
中位 −25.4%,10/11 场景更快;检测 444.5 → 319.2,请求 569.5 → 395.6,
位移 54.9 → 44.2 km,后备清除尝试 113.3 → 64.1,11/11 valid。
低于原估的 −26%,差额来自"缺席频道省下的检测"被定位探点部分抵消。
**验收**:`CoveragePlan.verify()` 通过;10/13/16 源 × 定向 1/半数/仅一个全向 × 边界朝外压力
场景全部全清;请求数、日志体积仍满足 1200 s / 2 MB 预算。
**风险**:数值采样证书弱于解析证明。缓解:(a) 保留解析七站证明用于 Q3;
(b) 证书采样分辨率与裕量写入 summary 并随日志归档;(c) 保留 10% 的额外"保险点"预算,
若演练观测到任何漏检立即回退到 49 点表。
---
### P0-3 第四问:位置×朝向联合信念与可见性选点
**现状**:定向源只被当作"候选空间集合",`no_signal` 只用于累计 `blocked_probes`
(`planner/__init__.py:663-677`),选点沿固定 45° 阶梯试探;梯子用尽后调用
`_fallback_clear`,对候选外包多边形做 20 m 网格覆盖逐格 `/clear`(≤400 格、≤1200 s、≤400 请求)。
运行历史显示这正是第四问的失败点:定向源 2/6 清除,4/4 漏检全是定向。
**方案**:为第四问频道维护 **(x, y, heading) 联合可行集**,把"看不看得见"变成可推理的量:
- 表示:`JointTensor` —— 复用 Q3 的占用网格,每格附加 24 个朝向 bin 的可行性位掩码
(uint8 位域,20 频道 × 6.1 万格 × 3 B ≈ 3.7 MB,可接受)。
- 更新规则(全部保守,仅删"必然看不见"的格):
- `direction`@s:位置删 `>1500`、角向删 `|gap| > δ_eff + 角裕量`;朝向删
"以该格为源、朝向不覆盖 s" 的半盘(保留 ±90° 含边界)。
- `no_signal`@s:对 `|g−s| ≤ 1000` 的格,朝向**只能**落在背向 s 的半盘;
对 `1000 < |g−s| ≤ 1500` 的格,朝向要么背向 s,要么源实际半径 < |g−s|(保持不确定);
对 `|g−s| > 1500` 的格不删。
- `near`@s:位置收缩到 5 m 盘,朝向置为全向(近场无遮挡语义)。
- 决策:`prob_detect(channel, reader)` = 该点能看到该频道任一可行 (p,h) 的概率质量;
选点直接最大化 `prob_detect / (移动秒数 + 6)`,即**保证有信号的信息增益/秒**。
- 定位收敛:位置由多条 `direction` 的角域交会收缩(与 Q3 相同);朝向在 2 次
"一次被遮挡 + 一次可见"后通常已被压到很窄的楔形,此时可**主动选择必然可见的探点**,
用一个正常角域证书结束,而不再进入 400 格盲清。
- 后备清除**保留**(`fallback_clear_cells` 已有格数与预算双硬顶),但目标变为
"只在证书无法建立时触发",并在 summary 中把触发次数作为回归指标。
**预期收益(未实测)**:定向频道的探点次数与后备清除触发次数大幅下降。参考量级:
后备清除上限 400 格 × 3 s = 1200 s + 400 请求/频道;`docs` 记录的 Q4 改进版每局后备
尝试 616/4 局 ≈ 154 次。保守估计 **−1500 ~ −3000 s/局**。
**验收**:10 源 3 定向场景全清率 100%(现状 referee 仅 2/6 定向);
`fallback_clear_attempts` 相对基线下降 ≥ 70%;定向信道平均检测次数 ≤ 全向信道的 1.5 倍。
**风险**:朝向均匀先验是工程假设,官方分布未知。缓解:先验只影响选点顺序,
不影响任何安全性判定;朝向不确定时自动退化为全向分支(`prob_detect` 取全向值)。
---
### P0-4 感知层向量化与并行(研发运行速度)
**现状**(F6):`expected_survival` 占单局 CPU 的 72%,2808 次调用 × (7 代表点 × 800 子采样)
≈ 1570 万次纯 Python 距离/角度运算;`apply_measure` 另有 20%,其中 `_kill_outside_wedge`
每次遍历全部幸存格(498 万次 `angular_gap`)。
**方案**:
1. `belief/occupancy.py` 用 `numpy` 布尔/整数张量替换 `set[int]`:
每频道 248×248 uint8(≈61 KB),20 频道 ≈ 1.2 MB;盘/楔删除用切片 + 布尔掩码,
粗格索引用 `np.add.reduceat`;`numpy` 缺失时回退现有纯 Python 实现(测试保证两条路径同结果)。
2. 采样评分向量化:把 `subsample` 与 `representatives` 预转 `(n,2)` 数组,
一次广播算完距离、角度、角向 gap,`expected_survival` 由 5600 次标量循环变成 2–3 条向量指令。
3. 站点级编译缓存:`(station, channel, version)` → 掩码结果,`version` 不变直接复用;
当前 `_skip_cache` 只缓存"必 no_signal"布尔,可扩展到整块删除掩码。
4. MEC 增量维护:当前 `mec()` 每次版本变化重算全部幸存点(最多 6 万点);改为
版本变化时只对新增删除点做包围圆增量更新,或按 1/8 子采样给出候选、证书判定用精确值。
5. 批量基准并行化:`bench/runner.py` 用 `concurrent.futures.ProcessPoolExecutor`
按场景分发(每进程独立 `LocalSimulator`,真值仍只进测试端),Mac M 系列 8 核可得 ~6–8×。
6. 观测/遥测:单局 summary 写入 `compute_wall_s`、`profile_top`(可选 `--profile`),
纳入基准表的必填列,防止"虚拟时间变快、墙钟悄悄变慢"。
**实测收益(2026-09-12)**:单局计算 **3.10 → 1.00 s(3.08×)**,最坏 5.84 → 1.30 s;
20 场景基准集 12.2 → 3.9 s。虚拟时间与动作序列**逐位一致**(纯 Python 回退路径保留,
`MCM26B_NO_NUMPY=1` 可强制)。未达 ≤0.8 s 的目标:剩余开销在
`apply_measure` 的网格删除与 `ChannelParticles.__init__`,需要 P0-4b(表示层张量化)。
**验收**:`tests/test_particles.py`、`tests/test_bayes_loop_q3.py` 全过;
纯 Python 与 numpy 两条路径在同一动作日志下产出逐位相同的 summary(`actions_sha256` 相同);
单局 `compute_wall_s` ≤ 0.8 s。
---
### P1-1 清除点选在 C₂₀(K) 内离当前位置最近处
现状 `_near_clear_target` 只沿"当前位置 → 候选圆心"方向平移,平移量受
`limit − radius` 限制,是被证明的一维特例。一般解是
`C₂₀(K) = ∩_{g∈K} B(g, 20)`,取其内离当前位置最近的点:
- 对凸多边形候选集,`C₂₀(K)` 仍是凸集(若干圆盘之交),可用"到当前点的最近点"的
简单迭代/投影求得;
- 若 `C₂₀(K)` 非空,则从该点清除的移动代价最小,且三角不等式保证仍在 20 m 内。
**预期收益**:Q3 单局清除移动 3668 m(734 s)中回收 20–35%(**−150 ~ −260 s**);
Q4 同步受益。
**风险**:`C₂₀` 空时退回现有 MEC 圆心逻辑(已实现)。
---
### P1-2 覆盖几何参数改为"离线搜索 + 运行期校验"
- Q3:`station_ring_radius_m` 由 1159.7 的可证明下界 1122.9 重算,并在 `validate_seven_coverage`
中同时校验 **PF 网格覆盖**(现行文档已记录 1159.7 与 Optuna 建议值差 3.3 m 的取舍)。
收益很小(≈44 s),但把"设计性质 vs 1.7% 均值差异"的取舍写成可复算脚本,而不是口口相传。
- Q4:见 P0-2,覆盖集与巡回联合优化(在等价覆盖解中选巡回最短者,
预期可在 23.6 km 基础上再降 5–10%)。
- 所有覆盖计划产物落 `output/<problem>/coverage/<version>.json` + 证书,纳入版本管理。
---
### P1-3 评估与遥测重构(消除 B6)
1. **冻结基准集**(`bench/suites/`,一题一份、版本化、写入 `manifest.json`):
- Q3:10/13/16 源 × 8 个种子 + 2 个圆周边界场景(`r_eff=1000`,扇区接缝);
- Q4:10 源 3 定向、13 源 6 定向、16 源 8 定向 × 每种 3 个种子 + 朝外边界压力场景;
- 场景与真值只进模拟器与校验器,策略端看不到(真值隔离不变量保持不变)。
2. **统一 runner + 逐局 artifact**:`manifest.json` / `results.json` / `aggregate.{json,csv}` /
`runs/<scene>/<variant>/summary.json` + `session.jsonl`,任何一局无效则 `all_valid=false` 且非零退出。
3. **指标口径去重**:目前 `avg_locate_clear_time_s ≡ virtual_time_s`(单源评估集下二者必然相等),
必须在多源基准集上重新定义并标注:
`T_total`(整场虚拟时间)、`T_accounted`(首次证明找全时刻)、`T_last_clear`、
`T_total / cleared`、`T_total / truth`。
4. **运行历史持久化**:`output/` 目前不纳入 git,导致 `output/rl/review-20260911/`、
`output/q3/optimization-20260911/` 等证据在 revert 后无法追溯。
本轮起把**基准集的 summary/aggregate/manifest(压缩,不含大日志)**纳入版本管理,
官方 jlog/日志仍按题面要求单独归档。
---
### P1-4 安全阀与退出可解释性
| 阀门 | 现状 | 改进 |
| --- | --- | --- |
| `persistent_search` | 默认已关闭,但没有任何"这会浪费多少"的提示;历史上已造成一次 346 170 s(98.84%)的无效演练 | 显式开启时输出预估上限(未清除频道数 × 站点数 × 6 s)并要求二次确认;`summary` 记录 `redundant_rescan_measures` |
| `virtual_reserve_s` | 10 000 s 固定 | 改为 `max(10 000, 2 × 最远单动作上界)`,并在接近时把 `stop_reason` 与剩余预算写入 summary |
| 完成判定 | `completed = 无中断 ∧ (清除数≥16 ∨ 每频道 CLEARED/ABSENT)` | 增加 `completion_basis ∈ {count_cap, per_channel_proof}` 字段,避免把"数量上界"与"逐频道证明"混为一谈 |
| 缺席证明 | 覆盖账本 + PF 双通道 | summary 增加 `absence_evidence[channel] ∈ {pf_empty, coverage, count_cap}`,供论文与审计逐条追溯 |
---
### P2-1 选点评分的解析化/查表化
`expected_survival` 的物理含义可用解析近似替代:对给定测点 q 与候选集,
`E[log 幸存占比]` 的一阶近似只依赖 (候选集到 q 的距离分布, 角向展布)。
先在离线基准上验证解析近似与采样评分选出的点一致率 ≥ 90%,再切默认实现。
预计再省 30–50% 的评分开销(P0-4 之后已不是瓶颈,列入 P2)。
---
### P2-2 是否重启学习类方法的门控条件
只有在**下列四条同时满足**时才考虑把 ML 重新引入,且只允许替换"任务排序"这一个部件:
1. P0-1/P0-2/P0-3 全部落地并通过基准集验收;
2. 手写基线仍有 ≥ 10% 的可测改进空间,且已定位到具体的排序子问题;
3. 训练与部署共用同一控制器模块,并有逐状态一致性测试(旧 HRL 的 13 000 行里最有价值的
就是这条纪律:`HRLControllerMixin` 被 env 与 runtime 逐字节共用);
4. 评估集包含多源与定向场景(现役 20 场景单源评估集不足以支撑任何结论)。
---
## 4. 实施路线图
| 阶段 | 内容 | 交付物 | 验收门槛 | 依赖 |
| --- | --- | --- | --- | --- |
| **S1(P0,2–3 天)** | P0-2 最小命中集 + P0-4 并行基准;P1-3 冻结基准集 + manifest;P1-4 安全阀 | `guarantee/cover.py`、`bench/runner.py`、`bench/suites/*`、`docs/` 更新 | Q4 巡回 ≤ 25 km;基准集并行跑完 ≤ 60 s;全部 `valid` | 无 |
| **S2(P0,2–3 天)** | P0-1 融合巡回(Q3);P1-1 清除点 | `plan/schedule.py`、`plan/score.py`、`Episode` 组合化重构 | Q3 均值 ≤ 2700 s、最大 ≤ 4000 s;移动 −25% | S1 的 runner |
| **S3(P0/P1,3–5 天)** | P0-4 信念层 numpy 化;P0-3 联合信念 + 可见性选点(Q4) | `belief/occupancy.py`、`belief/joint.py`、`plan/policy.py` | 单局计算 ≤ 0.8 s;Q4 定向全清 100%、后备触发 −70% | S2 的接口 |
| **S4(P1/P2,2–3 天)** | P1-2 覆盖参数搜索固化;P2-1 评分解析化;论文数据表 | 覆盖计划证书、`docs/paper` 数据 | 与 S3 结果配对不退化 | S3 |
| **S5(演练)** | 官方演练:Q3 用全向、Q4 用混合;先实测单请求延迟与总请求数,核对 1200 s / 2 MB | 官方日志与报告 | 全清 + 正常退出 + 计时复算一致 | 团队排期 |
**顺序约束**:S1 的基准集必须先于任何算法改动落地,否则无法配对;否则"更快"不可证。
---
## 5. 验收与度量
### 5.1 有效局定义(沿用现有基准脚本,不得放宽)
```
valid := 全部真实源被清除
∧ 被判缺席的频道都与真值一致(无误判)
∧ 正常 /exit(exit_reason == user_exit)
∧ 零算法异常(anomalies == [])
∧ 逐动作虚拟时间复算与服务器返回逐微秒一致
```
### 5.2 必报指标(每个变体、每个场景,落盘 + 汇总)
- 虚拟时间:`T_total`、`T_accounted`、`T_last_clear`、`T_total/cleared`,以及
均值/中位/最大/P90 与 **< 4000 s 场次比例**;
- 动作:`measures`、`clears`、`failed_clears`、`fallback_clear_attempts`、
`redundant_rescan_measures`、`total_requests`;
- 移动:`move_distance_m`,以及 move/action/switch 三分项占比;
- 墙钟:`compute_wall_s`、请求吞吐(ms/请求)、批量基准总时长、训练 steps/s(若涉及);
- 配对比较:同场景同误差种子下 `1 − T_variant / T_baseline` 的均值、
更快场数、以及对场景做 10 000 次 bootstrap 的 95% 区间(参照 `summarize_rl_revision.py` 的做法)。
### 5.3 回归
`uv run pytest`(当前 232 项)必须全过;新增:
- `CoveragePlan.verify()` 的正/负例(故意删一个点必须被检出);
- 联合信念的真源保留性质测试(随机 (p,h) × 随机观测序列,真源 (p,h) 永不被删);
- 融合巡回的"每源至少一条站点方位线"性质测试;
- 逐位一致性测试:numpy 后端与纯 Python 后端在同一动作序列下 summary 完全相同。
---
## 6. 风险与明确不承诺的部分
### 6.1 风险登记
| 风险 | 影响 | 缓解 |
| --- | --- | --- |
| 最小命中集证书依赖数值采样,官方分布未知 | 极端 (p,h) 漏检 → 漏源 | 保留解析七站证明(Q3);Q4 证书采样分辨率/裕量写入 summary;保留 10% 保险点预算与 49 点回退开关 |
| 站点三角化在 0.72% 源位置上只有 1 站在射程内 | 这些场景仍需专用探点 | `prob_detect` 触发回退路径,保留现有 `_select_point` |
| 朝向先验为工程假设 | 选点次优 | 先验只影响顺序;不确定时退化为全向;安全性由 20 m 证书 + 覆盖证明负责 |
| numpy 化引入浮点路径差异 | 真源保留性质被破坏 | 两条后端同时保留并对拍;保持整数微秒复算计时 |
| 并行基准引入进程/端口/临时目录问题 | 基准不稳定 | 每进程独立内存回环;不共用端口;`manifest` 记录随机种子 |
### 6.2 不承诺的部分
- **第四问 4000 s**:10 源场景下,仅"发现 + 缺席证明"就约需
最小命中集巡回 4719 s + 缺席检测 ≈1900 s ≈ 6600 s,加之定位清除,4000 s 不可达。
若必须逼近该线,需要改变停止条件(例如接受 `unresolved_channels` 而非逐频道缺席证明),
那是**成绩口径的取舍**,必须先与题面评分方式核对,本轮不作为代码默认行为。
- 本文所有收益数字都是**自建模拟器上的估计或本次复跑观测**,不是官方成绩;
官方分布、r_eff 分布、误差场分布仍是测试假设。
- 不声称 P0-1/P0-3 已在官方演练验证——需新的演练记录。
---
## 附录 A 复现命令与本次新增实验
```bash
# 1) 基线配对(本次复跑:bayes 3707.3 s vs seven_batch 5581.8 s,局部 −32.1%)
uv run python scripts/benchmark_q3_bayes.py --seeds 0,1 --out /tmp/mcmopt/q3
# 2) 运行历史计时分解(已入库):任意会话日志 → 移动/检测/换频分相 + 重复复扫检测
uv run python scripts/analyze_run_timing.py session.jsonl --plan seven
uv run python scripts/analyze_run_timing.py referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl --plan seven
uv run python scripts/analyze_run_timing.py referee-data/sessions/6X58-XQ7U-CJ24-JQQR/log.jsonl --plan 49
# 实测输出(与服务器记录最大偏差 0.000000 s,证明复算口径正确):
# session.jsonl 350227.692 s,移动 82.3%,检测 10323 次,重复率 96.4,
# 末次清除后仍花 346169.9 s / 10225 次空复扫
# BBM9 (Q3) 3134.643 s,移动 75.9%,探点 21 次 / 1138.7 s
# 6X58 (Q4) 3251.021 s,移动 78.3%,检测 112 次
# 3) 第四问覆盖证书与最小命中集(已入库)
uv run python scripts/verify_q4_cover.py --out output/q4/cover-certificate.json
# 实测输出:目标空间 43032 个 (p,h)
# 现役 49 点方格:缺口 0,NN 巡回 36.4 km(7280 s 移动)
# 贪心最小命中集:31 点,缺口 0,NN 巡回 22.9 km(4587 s 移动)
# 4) 感知层剖面(单局 6.04 s 计算中 expected_survival 占 ~72%)
python -m cProfile -s cumulative <单局驱动脚本>
```
> 第 2、3 项已作为常驻工具入库,使"虚拟时间花在哪"与"覆盖集是否仍然合法"
> 成为可随时重跑的回归项;第 1、4 项仍是一次性分析,建议在 S1 阶段并入
> `bench/runner.py` 的必报指标(`compute_wall_s`、`profile_top`)。
## 附录 B 数字出处索引
| 数字 | 出处 |
| --- | --- |
| 移动 80.50% / 16.78% / 2.71%(Q3) | `referee-data/sessions/{BBM9,RM7Y,VQKB}/log.jsonl` 按 `verify_q3_practice.py` 模型复算 |
| 移动 82.30%(官方 J2WH) | `session.jsonl` 求和 |
| 346 169.9 s 空复扫 | `session.jsonl` `/exit` 时刻 350 227.691846 s 减去 12 源首轮清除的 4 057.839 s |
| Q4 定向 2/6、漏检 4/4 全为定向 | `referee-data/sessions/{6X58,BAU8}/meta.json` + `log.jsonl` |
| bayes 3707.3 / seven 5581.8 | 本次复跑 `benchmark_q3_bayes.py --seeds 0,1` |
| 3535.9 s / 109 检测 / 6960 m 巡回 / 5741 m 探点 | 本次复跑计时分解 |
| 13652.1 s / 560 检测 / 51 356 m(Q4) | 本次复跑单局 |
| `expected_survival` 72% | 本次 `cProfile` 单局 |
| HRL 27.0 steps/s、4007.9 s、109 776 步 | `output/hrl/ui/q3-main/q3.json` + `*.monitor.csv` |
| bayes 比 HRL 快 4.3–5.0%、94% 差距为移动 | `output/hrl/ui/q3-main/eval/at-final/aggregate.json` + `runs/*/summary.json` |
| 站点三角化 99.28%、交会角 5 分位 58.5° | 本次离线采样 20 000 点 |
| 49 点 vs 30 点覆盖集 | 本次贪心击中集计算(附录 A 第 5 项) |
@@ -0,0 +1,133 @@
{"event":"session_start","case_code":"BBM9-HZG2-77N5-NKKC","module":"q3_practice","robot_id":"1","seed":214175614,"countdown_s":5.0,"window_s":1500.0,"max_real_duration_s":1200.0,"truth":[{"channel":13,"x":-667.5434273375823,"y":1201.9279733147766,"r_eff_m":1068.7667479727882,"directional":false,"heading_deg":0.0},{"channel":18,"x":936.4803225514449,"y":-449.0798658945765,"r_eff_m":1100.2220789348723,"directional":false,"heading_deg":0.0},{"channel":7,"x":1168.5586737701378,"y":-665.9024303254582,"r_eff_m":1380.180019258212,"directional":false,"heading_deg":0.0},{"channel":16,"x":-704.338944452677,"y":-1500.6801256821625,"r_eff_m":1260.765213581664,"directional":false,"heading_deg":0.0},{"channel":9,"x":301.3279949940345,"y":-1195.568730289507,"r_eff_m":1268.9333402487596,"directional":false,"heading_deg":0.0},{"channel":19,"x":-1016.5047516327342,"y":-1362.2054377699205,"r_eff_m":1029.8927902123228,"directional":false,"heading_deg":0.0},{"channel":17,"x":-1128.3611120627002,"y":-751.6668239293164,"r_eff_m":1073.440585013539,"directional":false,"heading_deg":0.0},{"channel":2,"x":1267.339479448259,"y":687.5619158006604,"r_eff_m":1380.3211633911274,"directional":false,"heading_deg":0.0},{"channel":14,"x":-431.7778870393432,"y":921.0181764839424,"r_eff_m":1418.973099517202,"directional":false,"heading_deg":0.0},{"channel":11,"x":437.0112473060851,"y":-112.52557536387796,"r_eff_m":1181.7035745633132,"directional":false,"heading_deg":0.0}]}
{"event":"action","seq":1,"wall_ts_ms":1789097576646,"method":"POST","path":"/enter","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0001"},"response":{"accepted":true,"real_timestamp_ms":1789097576646,"virtual_time_s":0.0,"max_virtual_duration_s":360000.0,"max_real_duration_s":1200,"remaining_real_duration_s":1200}}
{"event":"action","seq":2,"wall_ts_ms":1789097576662,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0002","position":{"x":0.0,"y":0.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097576662,"virtual_time_s":5.0,"measure_result":"no_signal"}}
{"event":"action","seq":3,"wall_ts_ms":1789097576667,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0003","position":{"x":0.0,"y":0.0},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097576667,"virtual_time_s":11.0,"measure_result":"no_signal"}}
{"event":"action","seq":4,"wall_ts_ms":1789097576672,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0004","position":{"x":0.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097576672,"virtual_time_s":17.0,"measure_result":"no_signal"}}
{"event":"action","seq":5,"wall_ts_ms":1789097576677,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0005","position":{"x":0.0,"y":0.0},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097576677,"virtual_time_s":23.0,"measure_result":"no_signal"}}
{"event":"action","seq":6,"wall_ts_ms":1789097576689,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0006","position":{"x":0.0,"y":0.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097576688,"virtual_time_s":29.0,"measure_result":"no_signal"}}
{"event":"action","seq":7,"wall_ts_ms":1789097576716,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0007","position":{"x":0.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097576716,"virtual_time_s":35.0,"measure_result":"no_signal"}}
{"event":"action","seq":8,"wall_ts_ms":1789097576727,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0008","position":{"x":0.0,"y":0.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097576727,"virtual_time_s":41.0,"measure_result":"direction","svd_deg":329.53}}
{"event":"action","seq":9,"wall_ts_ms":1789097576757,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0009","position":{"x":0.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097576757,"virtual_time_s":47.0,"measure_result":"no_signal"}}
{"event":"action","seq":10,"wall_ts_ms":1789097576762,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0010","position":{"x":0.0,"y":0.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789097576762,"virtual_time_s":53.0,"measure_result":"direction","svd_deg":284.61}}
{"event":"action","seq":11,"wall_ts_ms":1789097576791,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0011","position":{"x":0.0,"y":0.0},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097576791,"virtual_time_s":59.0,"measure_result":"no_signal"}}
{"event":"action","seq":12,"wall_ts_ms":1789097576796,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0012","position":{"x":0.0,"y":0.0},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789097576796,"virtual_time_s":65.0,"measure_result":"direction","svd_deg":345.95}}
{"event":"action","seq":13,"wall_ts_ms":1789097576825,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0013","position":{"x":0.0,"y":0.0},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097576825,"virtual_time_s":71.0,"measure_result":"no_signal"}}
{"event":"action","seq":14,"wall_ts_ms":1789097576830,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0014","position":{"x":0.0,"y":0.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789097576830,"virtual_time_s":77.0,"measure_result":"no_signal"}}
{"event":"action","seq":15,"wall_ts_ms":1789097576835,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0015","position":{"x":0.0,"y":0.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789097576835,"virtual_time_s":83.0,"measure_result":"direction","svd_deg":115.07}}
{"event":"action","seq":16,"wall_ts_ms":1789097576864,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0016","position":{"x":0.0,"y":0.0},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097576864,"virtual_time_s":89.0,"measure_result":"no_signal"}}
{"event":"action","seq":17,"wall_ts_ms":1789097576868,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0017","position":{"x":0.0,"y":0.0},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097576868,"virtual_time_s":95.0,"measure_result":"no_signal"}}
{"event":"action","seq":18,"wall_ts_ms":1789097576873,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0018","position":{"x":0.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097576873,"virtual_time_s":101.0,"measure_result":"no_signal"}}
{"event":"action","seq":19,"wall_ts_ms":1789097576878,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0019","position":{"x":0.0,"y":0.0},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789097576878,"virtual_time_s":107.0,"measure_result":"direction","svd_deg":334.09}}
{"event":"action","seq":20,"wall_ts_ms":1789097576907,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0020","position":{"x":0.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097576907,"virtual_time_s":113.0,"measure_result":"no_signal"}}
{"event":"action","seq":21,"wall_ts_ms":1789097576913,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0021","position":{"x":0.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097576913,"virtual_time_s":119.0,"measure_result":"no_signal"}}
{"event":"action","seq":22,"wall_ts_ms":1789097577020,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0022","position":{"x":-382.32549659893994,"y":438.1825018611922},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789097577020,"virtual_time_s":241.305923,"measure_result":"direction","svd_deg":95.7}}
{"event":"action","seq":23,"wall_ts_ms":1789097577105,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0023","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097577105,"virtual_time_s":375.155971,"measure_result":"no_signal"}}
{"event":"action","seq":24,"wall_ts_ms":1789097577108,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0024","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097577108,"virtual_time_s":381.155971,"measure_result":"no_signal"}}
{"event":"action","seq":25,"wall_ts_ms":1789097577111,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0025","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097577111,"virtual_time_s":387.155971,"measure_result":"no_signal"}}
{"event":"action","seq":26,"wall_ts_ms":1789097577114,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0026","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097577114,"virtual_time_s":393.155971,"measure_result":"no_signal"}}
{"event":"action","seq":27,"wall_ts_ms":1789097577117,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0027","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097577117,"virtual_time_s":399.155971,"measure_result":"no_signal"}}
{"event":"action","seq":28,"wall_ts_ms":1789097577121,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0028","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097577121,"virtual_time_s":405.155971,"measure_result":"no_signal"}}
{"event":"action","seq":29,"wall_ts_ms":1789097577124,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0029","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097577124,"virtual_time_s":411.155971,"measure_result":"no_signal"}}
{"event":"action","seq":30,"wall_ts_ms":1789097577128,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0030","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097577128,"virtual_time_s":417.155971,"measure_result":"no_signal"}}
{"event":"action","seq":31,"wall_ts_ms":1789097577132,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0031","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097577132,"virtual_time_s":423.155971,"measure_result":"no_signal"}}
{"event":"action","seq":32,"wall_ts_ms":1789097577137,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0032","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789097577136,"virtual_time_s":429.155971,"measure_result":"direction","svd_deg":112.67}}
{"event":"action","seq":33,"wall_ts_ms":1789097577155,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0033","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097577155,"virtual_time_s":435.155971,"measure_result":"no_signal"}}
{"event":"action","seq":34,"wall_ts_ms":1789097577158,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0034","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097577158,"virtual_time_s":441.155971,"measure_result":"no_signal"}}
{"event":"action","seq":35,"wall_ts_ms":1789097577161,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0035","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097577161,"virtual_time_s":447.155971,"measure_result":"no_signal"}}
{"event":"action","seq":36,"wall_ts_ms":1789097577165,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0036","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097577165,"virtual_time_s":453.155971,"measure_result":"no_signal"}}
{"event":"action","seq":37,"wall_ts_ms":1789097577169,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0037","position":{"x":-599.9999999999998,"y":1039.2304845413264},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097577169,"virtual_time_s":459.155971,"measure_result":"no_signal"}}
{"event":"action","seq":38,"wall_ts_ms":1789097577275,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0038","position":{"x":-432.59886137022454,"y":927.952956866304},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789097577275,"virtual_time_s":505.358374,"measure_result":"direction","svd_deg":276.22}}
{"event":"action","seq":39,"wall_ts_ms":1789097577364,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0039","position":{"x":-428.8404761449007,"y":898.3063116196065},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789097577364,"virtual_time_s":516.335159,"measure_result":"direction","svd_deg":96.95}}
{"event":"action","seq":40,"wall_ts_ms":1789097577365,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0040","position":{"x":-430.7196687575625,"y":913.129634242954},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789097577365,"virtual_time_s":524.323552,"clear_result":"success"}}
{"event":"action","seq":41,"wall_ts_ms":1789097577455,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0041","position":{"x":-441.9875302830439,"y":1247.8826866081681},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789097577455,"virtual_time_s":597.31208,"measure_result":"direction","svd_deg":191.28}}
{"event":"action","seq":42,"wall_ts_ms":1789097577456,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0042","position":{"x":-668.4093907720109,"y":1202.7926660772903},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789097577456,"virtual_time_s":648.485652,"clear_result":"success"}}
{"event":"action","seq":43,"wall_ts_ms":1789097577536,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0043","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097577536,"virtual_time_s":910.267979,"measure_result":"no_signal"}}
{"event":"action","seq":44,"wall_ts_ms":1789097577539,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0044","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097577539,"virtual_time_s":916.267979,"measure_result":"direction","svd_deg":332.39}}
{"event":"action","seq":45,"wall_ts_ms":1789097577554,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0045","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097577554,"virtual_time_s":922.267979,"measure_result":"no_signal"}}
{"event":"action","seq":46,"wall_ts_ms":1789097577557,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0046","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097577557,"virtual_time_s":928.267979,"measure_result":"no_signal"}}
{"event":"action","seq":47,"wall_ts_ms":1789097577560,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0047","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097577560,"virtual_time_s":934.267979,"measure_result":"no_signal"}}
{"event":"action","seq":48,"wall_ts_ms":1789097577564,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0048","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097577564,"virtual_time_s":940.267979,"measure_result":"no_signal"}}
{"event":"action","seq":49,"wall_ts_ms":1789097577567,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0049","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097577567,"virtual_time_s":946.267979,"measure_result":"no_signal"}}
{"event":"action","seq":50,"wall_ts_ms":1789097577571,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0050","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097577571,"virtual_time_s":952.267979,"measure_result":"no_signal"}}
{"event":"action","seq":51,"wall_ts_ms":1789097577574,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0051","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097577574,"virtual_time_s":958.267979,"measure_result":"no_signal"}}
{"event":"action","seq":52,"wall_ts_ms":1789097577577,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0052","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097577577,"virtual_time_s":964.267979,"measure_result":"no_signal"}}
{"event":"action","seq":53,"wall_ts_ms":1789097577581,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0053","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097577581,"virtual_time_s":970.267979,"measure_result":"no_signal"}}
{"event":"action","seq":54,"wall_ts_ms":1789097577583,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0054","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097577583,"virtual_time_s":976.267979,"measure_result":"no_signal"}}
{"event":"action","seq":55,"wall_ts_ms":1789097577586,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0055","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097577586,"virtual_time_s":982.267979,"measure_result":"no_signal"}}
{"event":"action","seq":56,"wall_ts_ms":1789097577588,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0056","position":{"x":600.0000000000001,"y":1039.2304845413264},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097577588,"virtual_time_s":988.267979,"measure_result":"no_signal"}}
{"event":"action","seq":57,"wall_ts_ms":1789097577687,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0057","position":{"x":994.1110687766269,"y":542.6492729278544},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097577687,"virtual_time_s":1121.061738,"measure_result":"direction","svd_deg":28.25}}
{"event":"action","seq":58,"wall_ts_ms":1789097577767,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0058","position":{"x":1268.7031752387938,"y":689.8006776789011},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097577767,"virtual_time_s":1188.368836,"measure_result":"near"}}
{"event":"action","seq":59,"wall_ts_ms":1789097577773,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0059","position":{"x":1268.7031752387938,"y":689.8006776789011},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789097577773,"virtual_time_s":1193.368836,"clear_result":"success"}}
{"event":"action","seq":60,"wall_ts_ms":1789097577859,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0060","position":{"x":1200.0,"y":0.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097577859,"virtual_time_s":1338.011557,"measure_result":"no_signal"}}
{"event":"action","seq":61,"wall_ts_ms":1789097577861,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0061","position":{"x":1200.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097577861,"virtual_time_s":1344.011557,"measure_result":"no_signal"}}
{"event":"action","seq":62,"wall_ts_ms":1789097577864,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0062","position":{"x":1200.0,"y":0.0},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097577864,"virtual_time_s":1350.011557,"measure_result":"no_signal"}}
{"event":"action","seq":63,"wall_ts_ms":1789097577866,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0063","position":{"x":1200.0,"y":0.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097577866,"virtual_time_s":1356.011557,"measure_result":"no_signal"}}
{"event":"action","seq":64,"wall_ts_ms":1789097577869,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0064","position":{"x":1200.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097577869,"virtual_time_s":1362.011557,"measure_result":"no_signal"}}
{"event":"action","seq":65,"wall_ts_ms":1789097577871,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0065","position":{"x":1200.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097577871,"virtual_time_s":1368.011557,"measure_result":"no_signal"}}
{"event":"action","seq":66,"wall_ts_ms":1789097577873,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0066","position":{"x":1200.0,"y":0.0},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097577873,"virtual_time_s":1374.011557,"measure_result":"no_signal"}}
{"event":"action","seq":67,"wall_ts_ms":1789097577876,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0067","position":{"x":1200.0,"y":0.0},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097577875,"virtual_time_s":1380.011557,"measure_result":"no_signal"}}
{"event":"action","seq":68,"wall_ts_ms":1789097577878,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0068","position":{"x":1200.0,"y":0.0},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097577878,"virtual_time_s":1386.011557,"measure_result":"no_signal"}}
{"event":"action","seq":69,"wall_ts_ms":1789097577881,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0069","position":{"x":1200.0,"y":0.0},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097577881,"virtual_time_s":1392.011557,"measure_result":"no_signal"}}
{"event":"action","seq":70,"wall_ts_ms":1789097577884,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0070","position":{"x":1200.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097577884,"virtual_time_s":1398.011557,"measure_result":"no_signal"}}
{"event":"action","seq":71,"wall_ts_ms":1789097577888,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0071","position":{"x":1200.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097577888,"virtual_time_s":1404.011557,"measure_result":"no_signal"}}
{"event":"action","seq":72,"wall_ts_ms":1789097577890,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0072","position":{"x":1200.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097577890,"virtual_time_s":1410.011557,"measure_result":"no_signal"}}
{"event":"action","seq":73,"wall_ts_ms":1789097577973,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0073","position":{"x":904.3723232997338,"y":-5.399878906793646},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789097577973,"virtual_time_s":1475.146955,"measure_result":"direction","svd_deg":193.85}}
{"event":"action","seq":74,"wall_ts_ms":1789097578037,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0074","position":{"x":732.9363400589687,"y":158.81239802766925},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789097578037,"virtual_time_s":1527.625779,"measure_result":"direction","svd_deg":223.37}}
{"event":"action","seq":75,"wall_ts_ms":1789097578039,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0075","position":{"x":446.4480711916748,"y":-111.48435372746496},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789097578039,"virtual_time_s":1611.400359,"clear_result":"success"}}
{"event":"action","seq":76,"wall_ts_ms":1789097578098,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0076","position":{"x":609.8586286156244,"y":-86.93118226598972},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789097578098,"virtual_time_s":1650.449334,"measure_result":"direction","svd_deg":312.82}}
{"event":"action","seq":77,"wall_ts_ms":1789097578145,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0077","position":{"x":711.4189708756367,"y":-138.68820908196022},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097578145,"virtual_time_s":1679.246959,"measure_result":"direction","svd_deg":311.79}}
{"event":"action","seq":78,"wall_ts_ms":1789097578171,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0078","position":{"x":968.3799882543295,"y":-471.87178417317915},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789097578171,"virtual_time_s":1769.399264,"measure_result":"direction","svd_deg":145.41}}
{"event":"action","seq":79,"wall_ts_ms":1789097578198,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0079","position":{"x":948.6903772101683,"y":-457.77800595341034},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789097578198,"virtual_time_s":1779.242054,"measure_result":"direction","svd_deg":144.5}}
{"event":"action","seq":80,"wall_ts_ms":1789097578200,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0080","position":{"x":938.8455716880909,"y":-450.7311168435281},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789097578200,"virtual_time_s":1786.663449,"clear_result":"success"}}
{"event":"action","seq":81,"wall_ts_ms":1789097578222,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0081","position":{"x":1216.8995655319154,"y":-717.7217593627017},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097578222,"virtual_time_s":1869.760278,"measure_result":"direction","svd_deg":132.81}}
{"event":"action","seq":82,"wall_ts_ms":1789097578247,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0082","position":{"x":1185.682710431516,"y":-684.9782355200915},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097578247,"virtual_time_s":1883.808218,"measure_result":"direction","svd_deg":132.18}}
{"event":"action","seq":83,"wall_ts_ms":1789097578269,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0083","position":{"x":1170.5902788598225,"y":-668.8979941203445},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097578269,"virtual_time_s":1893.218913,"measure_result":"near"}}
{"event":"action","seq":84,"wall_ts_ms":1789097578272,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0084","position":{"x":1170.6182266765854,"y":-668.8718181334558},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789097578272,"virtual_time_s":1898.226571,"clear_result":"success"}}
{"event":"action","seq":85,"wall_ts_ms":1789097578293,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0085","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097578293,"virtual_time_s":2040.281075,"measure_result":"no_signal"}}
{"event":"action","seq":86,"wall_ts_ms":1789097578296,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0086","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097578296,"virtual_time_s":2046.281075,"measure_result":"no_signal"}}
{"event":"action","seq":87,"wall_ts_ms":1789097578299,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0087","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097578299,"virtual_time_s":2052.281075,"measure_result":"no_signal"}}
{"event":"action","seq":88,"wall_ts_ms":1789097578301,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0088","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097578301,"virtual_time_s":2058.281075,"measure_result":"no_signal"}}
{"event":"action","seq":89,"wall_ts_ms":1789097578304,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0089","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097578304,"virtual_time_s":2064.281075,"measure_result":"no_signal"}}
{"event":"action","seq":90,"wall_ts_ms":1789097578307,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0090","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097578307,"virtual_time_s":2070.281075,"measure_result":"no_signal"}}
{"event":"action","seq":91,"wall_ts_ms":1789097578311,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0091","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097578311,"virtual_time_s":2076.281075,"measure_result":"no_signal"}}
{"event":"action","seq":92,"wall_ts_ms":1789097578314,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0092","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097578314,"virtual_time_s":2082.281075,"measure_result":"no_signal"}}
{"event":"action","seq":93,"wall_ts_ms":1789097578318,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0093","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097578318,"virtual_time_s":2088.281075,"measure_result":"no_signal"}}
{"event":"action","seq":94,"wall_ts_ms":1789097578322,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0094","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097578322,"virtual_time_s":2094.281075,"measure_result":"no_signal"}}
{"event":"action","seq":95,"wall_ts_ms":1789097578325,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0095","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097578325,"virtual_time_s":2100.281075,"measure_result":"no_signal"}}
{"event":"action","seq":96,"wall_ts_ms":1789097578328,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0096","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097578328,"virtual_time_s":2106.281075,"measure_result":"no_signal"}}
{"event":"action","seq":97,"wall_ts_ms":1789097578332,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0097","position":{"x":600.0000000000001,"y":-1039.2304845413264},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097578332,"virtual_time_s":2112.281075,"measure_result":"no_signal"}}
{"event":"action","seq":98,"wall_ts_ms":1789097578355,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0098","position":{"x":431.0177074456876,"y":-790.4383437162506},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789097578355,"virtual_time_s":2178.431734,"measure_result":"direction","svd_deg":252.8}}
{"event":"action","seq":99,"wall_ts_ms":1789097578358,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0099","position":{"x":308.8495661381867,"y":-1188.2218722331802},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789097578358,"virtual_time_s":2266.655959,"measure_result":"direction","svd_deg":225.19}}
{"event":"action","seq":100,"wall_ts_ms":1789097578359,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0100","position":{"x":302.26396092359636,"y":-1195.0880783213174},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789097578359,"virtual_time_s":2273.558746,"clear_result":"success"}}
{"event":"action","seq":101,"wall_ts_ms":1789097578360,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0101","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097578360,"virtual_time_s":2462.684041,"measure_result":"no_signal"}}
{"event":"action","seq":102,"wall_ts_ms":1789097578363,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0102","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097578363,"virtual_time_s":2468.684041,"measure_result":"no_signal"}}
{"event":"action","seq":103,"wall_ts_ms":1789097578366,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0103","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097578366,"virtual_time_s":2474.684041,"measure_result":"no_signal"}}
{"event":"action","seq":104,"wall_ts_ms":1789097578371,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0104","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097578371,"virtual_time_s":2480.684041,"measure_result":"no_signal"}}
{"event":"action","seq":105,"wall_ts_ms":1789097578374,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0105","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097578374,"virtual_time_s":2486.684041,"measure_result":"no_signal"}}
{"event":"action","seq":106,"wall_ts_ms":1789097578377,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0106","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097578377,"virtual_time_s":2492.684041,"measure_result":"no_signal"}}
{"event":"action","seq":107,"wall_ts_ms":1789097578380,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0107","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097578380,"virtual_time_s":2498.684041,"measure_result":"no_signal"}}
{"event":"action","seq":108,"wall_ts_ms":1789097578384,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0108","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097578383,"virtual_time_s":2504.684041,"measure_result":"no_signal"}}
{"event":"action","seq":109,"wall_ts_ms":1789097578386,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0109","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097578386,"virtual_time_s":2510.684041,"measure_result":"no_signal"}}
{"event":"action","seq":110,"wall_ts_ms":1789097578389,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0110","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097578389,"virtual_time_s":2516.684041,"measure_result":"direction","svd_deg":257.75}}
{"event":"action","seq":111,"wall_ts_ms":1789097578399,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0111","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097578399,"virtual_time_s":2522.684041,"measure_result":"direction","svd_deg":150.83}}
{"event":"action","seq":112,"wall_ts_ms":1789097578409,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0112","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097578409,"virtual_time_s":2528.684041,"measure_result":"direction","svd_deg":217.09}}
{"event":"action","seq":113,"wall_ts_ms":1789097578419,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0113","position":{"x":-600.0000000000006,"y":-1039.230484541326},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097578419,"virtual_time_s":2534.684041,"measure_result":"no_signal"}}
{"event":"action","seq":114,"wall_ts_ms":1789097578449,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0114","position":{"x":-855.523050877763,"y":-1149.4070702441772},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097578449,"virtual_time_s":2596.336861,"measure_result":"direction","svd_deg":293.06}}
{"event":"action","seq":115,"wall_ts_ms":1789097578473,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0115","position":{"x":-702.0198196486191,"y":-1511.0796905664733},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097578473,"virtual_time_s":2679.91684,"measure_result":"direction","svd_deg":101.78}}
{"event":"action","seq":116,"wall_ts_ms":1789097578475,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0116","position":{"x":-704.0596428309664,"y":-1500.3611560598777},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789097578475,"virtual_time_s":2687.099021,"clear_result":"success"}}
{"event":"action","seq":117,"wall_ts_ms":1789097578495,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0117","position":{"x":-786.4741505952657,"y":-1490.051846445478},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097578495,"virtual_time_s":2709.710382,"measure_result":"direction","svd_deg":151.04}}
{"event":"action","seq":118,"wall_ts_ms":1789097578497,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0118","position":{"x":-1023.4461023835017,"y":-1359.1588736906476},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789097578497,"virtual_time_s":2768.854145,"clear_result":"success"}}
{"event":"action","seq":119,"wall_ts_ms":1789097578511,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0119","position":{"x":-1266.2459250683066,"y":-1017.2747950835054},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097578511,"virtual_time_s":2858.719866,"measure_result":"direction","svd_deg":62.8}}
{"event":"action","seq":120,"wall_ts_ms":1789097578513,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0120","position":{"x":-1126.6121592386512,"y":-745.1634840678316},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789097578513,"virtual_time_s":2924.88919,"clear_result":"success"}}
{"event":"action","seq":121,"wall_ts_ms":1789097578515,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0121","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789097578515,"virtual_time_s":3080.642907,"measure_result":"no_signal"}}
{"event":"action","seq":122,"wall_ts_ms":1789097578518,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0122","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789097578518,"virtual_time_s":3086.642907,"measure_result":"no_signal"}}
{"event":"action","seq":123,"wall_ts_ms":1789097578520,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0123","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789097578520,"virtual_time_s":3092.642907,"measure_result":"no_signal"}}
{"event":"action","seq":124,"wall_ts_ms":1789097578522,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0124","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789097578522,"virtual_time_s":3098.642907,"measure_result":"no_signal"}}
{"event":"action","seq":125,"wall_ts_ms":1789097578524,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0125","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789097578524,"virtual_time_s":3104.642907,"measure_result":"no_signal"}}
{"event":"action","seq":126,"wall_ts_ms":1789097578526,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0126","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789097578526,"virtual_time_s":3110.642907,"measure_result":"no_signal"}}
{"event":"action","seq":127,"wall_ts_ms":1789097578527,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0127","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789097578527,"virtual_time_s":3116.642907,"measure_result":"no_signal"}}
{"event":"action","seq":128,"wall_ts_ms":1789097578529,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0128","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789097578529,"virtual_time_s":3122.642907,"measure_result":"no_signal"}}
{"event":"action","seq":129,"wall_ts_ms":1789097578531,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0129","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789097578531,"virtual_time_s":3128.642907,"measure_result":"no_signal"}}
{"event":"action","seq":130,"wall_ts_ms":1789097578533,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0130","position":{"x":-1200.0,"y":1.4695761589768238e-13},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789097578533,"virtual_time_s":3134.642907,"measure_result":"no_signal"}}
{"event":"action","seq":131,"wall_ts_ms":1789097578535,"method":"POST","path":"/exit","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"4721c649063d-0131"},"response":{"accepted":true,"real_timestamp_ms":1789097578535,"virtual_time_s":3134.642907,"exit_reason":"user_exit"}}
{"event":"session_end","reason":"user_exit","virtual_time_s":3134.642907,"real_elapsed_s":3.209263,"request_count":131,"cleared_count":10}
@@ -0,0 +1,421 @@
{"event":"session_start","case_code":"GM56-DFXZ-XKDM-XYV7","module":"q4_practice","robot_id":"1","seed":862296605,"countdown_s":5.0,"window_s":1500.0,"max_real_duration_s":1200.0,"truth":[{"channel":16,"x":-524.5206714300155,"y":1076.6097330631062,"r_eff_m":1266.1144095417988,"directional":true,"heading_deg":323.3365774469903},{"channel":10,"x":712.0048721054991,"y":-350.77945242364206,"r_eff_m":1142.2414995302777,"directional":true,"heading_deg":256.5462028174308},{"channel":7,"x":1591.9527024388633,"y":-417.6806591511811,"r_eff_m":1488.5247138130503,"directional":true,"heading_deg":145.9558235911333},{"channel":1,"x":-1088.117367198431,"y":-567.662158187589,"r_eff_m":1174.5517593406385,"directional":false,"heading_deg":0.0},{"channel":11,"x":906.4341088975847,"y":-1164.9533159379737,"r_eff_m":1205.6825113239083,"directional":false,"heading_deg":0.0},{"channel":12,"x":-440.7136903976244,"y":-1125.6333701710744,"r_eff_m":1392.7970264272578,"directional":false,"heading_deg":0.0},{"channel":15,"x":396.09072396953906,"y":-1233.8343338670759,"r_eff_m":1447.254884675842,"directional":false,"heading_deg":0.0},{"channel":18,"x":-924.1740699985598,"y":1042.867539519964,"r_eff_m":1397.743907895721,"directional":false,"heading_deg":0.0},{"channel":5,"x":404.69205111704883,"y":1512.8465933025086,"r_eff_m":1275.2012367943066,"directional":false,"heading_deg":0.0},{"channel":13,"x":346.29727268509714,"y":-1700.4782817821338,"r_eff_m":1110.0997753757654,"directional":false,"heading_deg":0.0},{"channel":2,"x":-848.0195414748022,"y":647.6935881860475,"r_eff_m":1437.3660943189293,"directional":false,"heading_deg":0.0},{"channel":4,"x":1284.0330369450317,"y":1006.2534742058411,"r_eff_m":1292.0520810945493,"directional":false,"heading_deg":0.0}]}
{"event":"action","seq":1,"wall_ts_ms":1789176627501,"method":"POST","path":"/enter","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0001"},"response":{"accepted":true,"real_timestamp_ms":1789176627501,"virtual_time_s":0.0,"max_virtual_duration_s":360000.0,"max_real_duration_s":1200,"remaining_real_duration_s":1200}}
{"event":"action","seq":2,"wall_ts_ms":1789176627503,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0002","position":{"x":0.0,"y":0.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176627503,"virtual_time_s":5.0,"measure_result":"no_signal"}}
{"event":"action","seq":3,"wall_ts_ms":1789176627504,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0003","position":{"x":0.0,"y":0.0},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789176627504,"virtual_time_s":11.0,"measure_result":"direction","svd_deg":142.87}}
{"event":"action","seq":4,"wall_ts_ms":1789176627538,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0004","position":{"x":0.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176627538,"virtual_time_s":17.0,"measure_result":"no_signal"}}
{"event":"action","seq":5,"wall_ts_ms":1789176627539,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0005","position":{"x":0.0,"y":0.0},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176627539,"virtual_time_s":23.0,"measure_result":"no_signal"}}
{"event":"action","seq":6,"wall_ts_ms":1789176627539,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0006","position":{"x":0.0,"y":0.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176627539,"virtual_time_s":29.0,"measure_result":"no_signal"}}
{"event":"action","seq":7,"wall_ts_ms":1789176627540,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0007","position":{"x":0.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176627540,"virtual_time_s":35.0,"measure_result":"no_signal"}}
{"event":"action","seq":8,"wall_ts_ms":1789176627540,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0008","position":{"x":0.0,"y":0.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176627540,"virtual_time_s":41.0,"measure_result":"no_signal"}}
{"event":"action","seq":9,"wall_ts_ms":1789176627541,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0009","position":{"x":0.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176627541,"virtual_time_s":47.0,"measure_result":"no_signal"}}
{"event":"action","seq":10,"wall_ts_ms":1789176627542,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0010","position":{"x":0.0,"y":0.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176627542,"virtual_time_s":53.0,"measure_result":"no_signal"}}
{"event":"action","seq":11,"wall_ts_ms":1789176627543,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0011","position":{"x":0.0,"y":0.0},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176627543,"virtual_time_s":59.0,"measure_result":"no_signal"}}
{"event":"action","seq":12,"wall_ts_ms":1789176627543,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0012","position":{"x":0.0,"y":0.0},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176627543,"virtual_time_s":65.0,"measure_result":"no_signal"}}
{"event":"action","seq":13,"wall_ts_ms":1789176627544,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0013","position":{"x":0.0,"y":0.0},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789176627544,"virtual_time_s":71.0,"measure_result":"direction","svd_deg":249.23000000000002}}
{"event":"action","seq":14,"wall_ts_ms":1789176627578,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0014","position":{"x":0.0,"y":0.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176627578,"virtual_time_s":77.0,"measure_result":"no_signal"}}
{"event":"action","seq":15,"wall_ts_ms":1789176627579,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0015","position":{"x":0.0,"y":0.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176627579,"virtual_time_s":83.0,"measure_result":"no_signal"}}
{"event":"action","seq":16,"wall_ts_ms":1789176627579,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0016","position":{"x":0.0,"y":0.0},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789176627579,"virtual_time_s":89.0,"measure_result":"direction","svd_deg":287.02}}
{"event":"action","seq":17,"wall_ts_ms":1789176627614,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0017","position":{"x":0.0,"y":0.0},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627614,"virtual_time_s":95.0,"measure_result":"direction","svd_deg":115.81}}
{"event":"action","seq":18,"wall_ts_ms":1789176627648,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0018","position":{"x":0.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176627648,"virtual_time_s":101.0,"measure_result":"no_signal"}}
{"event":"action","seq":19,"wall_ts_ms":1789176627649,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0019","position":{"x":0.0,"y":0.0},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789176627649,"virtual_time_s":107.0,"measure_result":"direction","svd_deg":131.59}}
{"event":"action","seq":20,"wall_ts_ms":1789176627683,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0020","position":{"x":0.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176627683,"virtual_time_s":113.0,"measure_result":"no_signal"}}
{"event":"action","seq":21,"wall_ts_ms":1789176627684,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0021","position":{"x":0.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176627684,"virtual_time_s":119.0,"measure_result":"no_signal"}}
{"event":"action","seq":22,"wall_ts_ms":1789176627792,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0022","position":{"x":203.4343811666737,"y":144.6893122685409},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627792,"virtual_time_s":174.928166,"measure_result":"direction","svd_deg":128.82}}
{"event":"action","seq":23,"wall_ts_ms":1789176627826,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0023","position":{"x":-311.2425550798696,"y":834.1583620758665},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627826,"virtual_time_s":352.004884,"measure_result":"direction","svd_deg":131.54}}
{"event":"action","seq":24,"wall_ts_ms":1789176627848,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0024","position":{"x":-417.950364283015,"y":970.4361579464362},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627848,"virtual_time_s":391.621755,"measure_result":"direction","svd_deg":134.21}}
{"event":"action","seq":25,"wall_ts_ms":1789176627864,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0025","position":{"x":-480.46143877622444,"y":1037.7141305929167},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627864,"virtual_time_s":414.989074,"measure_result":"direction","svd_deg":137.8}}
{"event":"action","seq":26,"wall_ts_ms":1789176627879,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0026","position":{"x":-495.83724096621324,"y":1048.755585943092},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627879,"virtual_time_s":423.77499,"measure_result":"direction","svd_deg":135.92}}
{"event":"action","seq":27,"wall_ts_ms":1789176627891,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0027","position":{"x":-502.6708670887933,"y":1055.235185439503},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627891,"virtual_time_s":430.65843,"measure_result":"direction","svd_deg":135.46}}
{"event":"action","seq":28,"wall_ts_ms":1789176627907,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0028","position":{"x":-504.15939756610106,"y":1056.6465909981732},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627907,"virtual_time_s":436.068688,"measure_result":"direction","svd_deg":136.32}}
{"event":"action","seq":29,"wall_ts_ms":1789176627919,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0029","position":{"x":-509.2545636173579,"y":1061.3274324862907},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627919,"virtual_time_s":442.452465,"measure_result":"direction","svd_deg":134.7}}
{"event":"action","seq":30,"wall_ts_ms":1789176627921,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0030","position":{"x":-530.0,"y":1070.0},"channel":16},"response":{"accepted":true,"real_timestamp_ms":1789176627921,"virtual_time_s":451.949515,"clear_result":"success"}}
{"event":"action","seq":31,"wall_ts_ms":1789176628039,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0031","position":{"x":-497.5578416531835,"y":936.4798565361209},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789176628039,"virtual_time_s":485.430507,"measure_result":"direction","svd_deg":165.91}}
{"event":"action","seq":32,"wall_ts_ms":1789176628056,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0032","position":{"x":-870.5044046825748,"y":986.9651951603664},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789176628056,"virtual_time_s":565.700131,"measure_result":"direction","svd_deg":134.69}}
{"event":"action","seq":33,"wall_ts_ms":1789176628058,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0033","position":{"x":-928.1968994917735,"y":1044.8514975713322},"channel":18},"response":{"accepted":true,"real_timestamp_ms":1789176628058,"virtual_time_s":587.045464,"clear_result":"success"}}
{"event":"action","seq":34,"wall_ts_ms":1789176628166,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0034","position":{"x":-862.9906179313325,"y":718.4282467255796},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789176628166,"virtual_time_s":659.619933,"measure_result":"direction","svd_deg":282.52}}
{"event":"action","seq":35,"wall_ts_ms":1789176628176,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0035","position":{"x":-845.1130456790994,"y":686.001392824461},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789176628176,"virtual_time_s":672.025629,"measure_result":"direction","svd_deg":265.87}}
{"event":"action","seq":36,"wall_ts_ms":1789176628177,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0036","position":{"x":-847.6746007769079,"y":648.9342354479113},"channel":2},"response":{"accepted":true,"real_timestamp_ms":1789176628177,"virtual_time_s":684.456741,"clear_result":"success"}}
{"event":"action","seq":37,"wall_ts_ms":1789176628291,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0037","position":{"x":-265.37802696051864,"y":48.506777636046536},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789176628291,"virtual_time_s":857.73883,"measure_result":"direction","svd_deg":260.6}}
{"event":"action","seq":38,"wall_ts_ms":1789176628326,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0038","position":{"x":-469.75721825078074,"y":-993.1945205185655},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789176628326,"virtual_time_s":1075.051095,"measure_result":"direction","svd_deg":282.38}}
{"event":"action","seq":39,"wall_ts_ms":1789176628327,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0039","position":{"x":-441.5215936013995,"y":-1123.0747819124222},"channel":12},"response":{"accepted":true,"real_timestamp_ms":1789176628327,"virtual_time_s":1106.633896,"clear_result":"success"}}
{"event":"action","seq":40,"wall_ts_ms":1789176628449,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0040","position":{"x":-311.5453347487594,"y":-1247.9984385205082},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789176628448,"virtual_time_s":1148.689269,"measure_result":"direction","svd_deg":2.01}}
{"event":"action","seq":41,"wall_ts_ms":1789176628465,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0041","position":{"x":344.2647005168924,"y":-1193.49630528446},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789176628465,"virtual_time_s":1285.303445,"measure_result":"direction","svd_deg":322.55}}
{"event":"action","seq":42,"wall_ts_ms":1789176628474,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0042","position":{"x":362.93782740943095,"y":-1202.306532513895},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789176628474,"virtual_time_s":1294.43288,"measure_result":"direction","svd_deg":315.62}}
{"event":"action","seq":43,"wall_ts_ms":1789176628475,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0043","position":{"x":389.58153144171735,"y":-1228.1021047955844},"channel":15},"response":{"accepted":true,"real_timestamp_ms":1789176628475,"virtual_time_s":1306.849883,"clear_result":"success"}}
{"event":"action","seq":44,"wall_ts_ms":1789176628476,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0044","position":{"x":600.0,"y":-1400.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176628476,"virtual_time_s":1367.191329,"measure_result":"no_signal"}}
{"event":"action","seq":45,"wall_ts_ms":1789176628476,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0045","position":{"x":600.0,"y":-1400.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176628476,"virtual_time_s":1373.191329,"measure_result":"no_signal"}}
{"event":"action","seq":46,"wall_ts_ms":1789176628477,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0046","position":{"x":600.0,"y":-1400.0},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176628477,"virtual_time_s":1379.191329,"measure_result":"no_signal"}}
{"event":"action","seq":47,"wall_ts_ms":1789176628477,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0047","position":{"x":600.0,"y":-1400.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176628477,"virtual_time_s":1385.191329,"measure_result":"no_signal"}}
{"event":"action","seq":48,"wall_ts_ms":1789176628478,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0048","position":{"x":600.0,"y":-1400.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176628478,"virtual_time_s":1391.191329,"measure_result":"no_signal"}}
{"event":"action","seq":49,"wall_ts_ms":1789176628479,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0049","position":{"x":600.0,"y":-1400.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176628479,"virtual_time_s":1397.191329,"measure_result":"direction","svd_deg":44.78}}
{"event":"action","seq":50,"wall_ts_ms":1789176628507,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0050","position":{"x":600.0,"y":-1400.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176628507,"virtual_time_s":1403.191329,"measure_result":"no_signal"}}
{"event":"action","seq":51,"wall_ts_ms":1789176628508,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0051","position":{"x":600.0,"y":-1400.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176628508,"virtual_time_s":1409.191329,"measure_result":"no_signal"}}
{"event":"action","seq":52,"wall_ts_ms":1789176628508,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0052","position":{"x":600.0,"y":-1400.0},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176628508,"virtual_time_s":1415.191329,"measure_result":"direction","svd_deg":83.87}}
{"event":"action","seq":53,"wall_ts_ms":1789176628537,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0053","position":{"x":600.0,"y":-1400.0},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628537,"virtual_time_s":1421.191329,"measure_result":"direction","svd_deg":36.51}}
{"event":"action","seq":54,"wall_ts_ms":1789176628566,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0054","position":{"x":600.0,"y":-1400.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628566,"virtual_time_s":1427.191329,"measure_result":"direction","svd_deg":229.98}}
{"event":"action","seq":55,"wall_ts_ms":1789176628595,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0055","position":{"x":600.0,"y":-1400.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176628595,"virtual_time_s":1433.191329,"measure_result":"no_signal"}}
{"event":"action","seq":56,"wall_ts_ms":1789176628596,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0056","position":{"x":600.0,"y":-1400.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176628596,"virtual_time_s":1439.191329,"measure_result":"no_signal"}}
{"event":"action","seq":57,"wall_ts_ms":1789176628597,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0057","position":{"x":600.0,"y":-1400.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176628597,"virtual_time_s":1445.191329,"measure_result":"no_signal"}}
{"event":"action","seq":58,"wall_ts_ms":1789176628598,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0058","position":{"x":600.0,"y":-1400.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176628598,"virtual_time_s":1451.191329,"measure_result":"no_signal"}}
{"event":"action","seq":59,"wall_ts_ms":1789176628635,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0059","position":{"x":612.769143781833,"y":-1411.9126285523905},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628635,"virtual_time_s":1460.68396,"measure_result":"direction","svd_deg":228.03}}
{"event":"action","seq":60,"wall_ts_ms":1789176628656,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0060","position":{"x":488.28892399223247,"y":-1555.258637843486},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628656,"virtual_time_s":1503.654161,"measure_result":"direction","svd_deg":225.09}}
{"event":"action","seq":61,"wall_ts_ms":1789176628680,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0061","position":{"x":464.24008775648366,"y":-1581.4091281036367},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628680,"virtual_time_s":1515.759637,"measure_result":"direction","svd_deg":225.74}}
{"event":"action","seq":62,"wall_ts_ms":1789176628702,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0062","position":{"x":443.4541092572734,"y":-1604.012442774533},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628701,"virtual_time_s":1526.90119,"measure_result":"direction","svd_deg":225.37}}
{"event":"action","seq":63,"wall_ts_ms":1789176628723,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0063","position":{"x":435.3536321162203,"y":-1612.8214287026208},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628723,"virtual_time_s":1534.294647,"measure_result":"direction","svd_deg":224.12}}
{"event":"action","seq":64,"wall_ts_ms":1789176628741,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0064","position":{"x":431.6884641242621,"y":-1616.0029103437198},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628741,"virtual_time_s":1540.265323,"measure_result":"direction","svd_deg":225.56}}
{"event":"action","seq":65,"wall_ts_ms":1789176628755,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0065","position":{"x":424.90388434893435,"y":-1623.0873437184766},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628755,"virtual_time_s":1547.227156,"measure_result":"direction","svd_deg":224.55}}
{"event":"action","seq":66,"wall_ts_ms":1789176628769,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0066","position":{"x":424.90388434893435,"y":-1623.0873437184766},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628769,"virtual_time_s":1552.227156,"measure_result":"direction","svd_deg":224.55}}
{"event":"action","seq":67,"wall_ts_ms":1789176628770,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0067","position":{"x":390.0,"y":-1650.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628770,"virtual_time_s":1564.04208,"clear_result":"no_target_in_range"}}
{"event":"action","seq":68,"wall_ts_ms":1789176628771,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0068","position":{"x":390.0,"y":-1670.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628771,"virtual_time_s":1571.04208,"clear_result":"no_target_in_range"}}
{"event":"action","seq":69,"wall_ts_ms":1789176628771,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0069","position":{"x":370.0,"y":-1670.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628771,"virtual_time_s":1578.04208,"clear_result":"no_target_in_range"}}
{"event":"action","seq":70,"wall_ts_ms":1789176628772,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0070","position":{"x":370.0,"y":-1690.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628772,"virtual_time_s":1585.04208,"clear_result":"no_target_in_range"}}
{"event":"action","seq":71,"wall_ts_ms":1789176628772,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0071","position":{"x":350.0,"y":-1690.0},"channel":13},"response":{"accepted":true,"real_timestamp_ms":1789176628772,"virtual_time_s":1594.04208,"clear_result":"success"}}
{"event":"action","seq":72,"wall_ts_ms":1789176628874,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0072","position":{"x":411.79373555366476,"y":-1717.838581828962},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628874,"virtual_time_s":1613.597083,"measure_result":"direction","svd_deg":49.15}}
{"event":"action","seq":73,"wall_ts_ms":1789176628892,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0073","position":{"x":766.8838287107096,"y":-1296.2930792223774},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628892,"virtual_time_s":1728.831304,"measure_result":"direction","svd_deg":44.09}}
{"event":"action","seq":74,"wall_ts_ms":1789176628909,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0074","position":{"x":800.7301756620684,"y":-1266.6704889596645},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628909,"virtual_time_s":1742.827021,"measure_result":"direction","svd_deg":43.75}}
{"event":"action","seq":75,"wall_ts_ms":1789176628923,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0075","position":{"x":820.3781924062749,"y":-1249.3764003674905},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628923,"virtual_time_s":1753.062019,"measure_result":"direction","svd_deg":44.6}}
{"event":"action","seq":76,"wall_ts_ms":1789176628935,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0076","position":{"x":844.4958977984477,"y":-1225.8950853428623},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628935,"virtual_time_s":1764.794139,"measure_result":"direction","svd_deg":45.05}}
{"event":"action","seq":77,"wall_ts_ms":1789176628945,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0077","position":{"x":855.9562038575117,"y":-1214.7371822060427},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628945,"virtual_time_s":1772.993123,"measure_result":"direction","svd_deg":44.9}}
{"event":"action","seq":78,"wall_ts_ms":1789176628955,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0078","position":{"x":865.9179588599695,"y":-1205.038289492462},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628955,"virtual_time_s":1780.773807,"measure_result":"direction","svd_deg":43.98}}
{"event":"action","seq":79,"wall_ts_ms":1789176628956,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0079","position":{"x":898.21078066507,"y":-1173.1730975244195},"channel":11},"response":{"accepted":true,"real_timestamp_ms":1789176628955,"virtual_time_s":1794.847322,"clear_result":"success"}}
{"event":"action","seq":80,"wall_ts_ms":1789176629078,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0080","position":{"x":866.8151916328336,"y":-1136.3661336833432},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629078,"virtual_time_s":1810.522932,"measure_result":"direction","svd_deg":44.48}}
{"event":"action","seq":81,"wall_ts_ms":1789176629176,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0081","position":{"x":871.4749861156209,"y":-1141.0811615347607},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629176,"virtual_time_s":1816.848755,"measure_result":"direction","svd_deg":44.56}}
{"event":"action","seq":82,"wall_ts_ms":1789176629261,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0082","position":{"x":835.0610147818679,"y":-1181.2600790843733},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629261,"virtual_time_s":1832.693704,"measure_result":"direction","svd_deg":45.09}}
{"event":"action","seq":83,"wall_ts_ms":1789176629343,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0083","position":{"x":834.9071059567416,"y":-1181.1002911848286},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629343,"virtual_time_s":1837.738075,"measure_result":"direction","svd_deg":45.24}}
{"event":"action","seq":84,"wall_ts_ms":1789176629428,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0084","position":{"x":834.8004921492156,"y":-1180.9897369495718},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629428,"virtual_time_s":1842.768792,"measure_result":"direction","svd_deg":44.67}}
{"event":"action","seq":85,"wall_ts_ms":1789176629512,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0085","position":{"x":864.7230500744597,"y":-1151.0671790243275},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629512,"virtual_time_s":1856.232169,"measure_result":"direction","svd_deg":45.95}}
{"event":"action","seq":86,"wall_ts_ms":1789176629589,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0086","position":{"x":860.4040223975106,"y":-1146.6963845782388},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629589,"virtual_time_s":1862.461117,"measure_result":"direction","svd_deg":45.79}}
{"event":"action","seq":87,"wall_ts_ms":1789176629648,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0087","position":{"x":979.6223276288076,"y":-1025.3778081444027},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629648,"virtual_time_s":1901.479466,"measure_result":"direction","svd_deg":45.37}}
{"event":"action","seq":88,"wall_ts_ms":1789176629652,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0088","position":{"x":1130.0,"y":-870.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629652,"virtual_time_s":1947.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":89,"wall_ts_ms":1789176629653,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0089","position":{"x":1150.0,"y":-870.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629653,"virtual_time_s":1954.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":90,"wall_ts_ms":1789176629653,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0090","position":{"x":1150.0,"y":-850.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629653,"virtual_time_s":1961.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":91,"wall_ts_ms":1789176629654,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0091","position":{"x":1170.0,"y":-850.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629654,"virtual_time_s":1968.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":92,"wall_ts_ms":1789176629654,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0092","position":{"x":1170.0,"y":-830.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629654,"virtual_time_s":1975.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":93,"wall_ts_ms":1789176629655,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0093","position":{"x":1190.0,"y":-830.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629655,"virtual_time_s":1982.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":94,"wall_ts_ms":1789176629656,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0094","position":{"x":1190.0,"y":-810.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629656,"virtual_time_s":1989.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":95,"wall_ts_ms":1789176629656,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0095","position":{"x":1210.0,"y":-810.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629656,"virtual_time_s":1996.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":96,"wall_ts_ms":1789176629657,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0096","position":{"x":1210.0,"y":-790.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629657,"virtual_time_s":2003.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":97,"wall_ts_ms":1789176629658,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0097","position":{"x":1230.0,"y":-790.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629658,"virtual_time_s":2010.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":98,"wall_ts_ms":1789176629658,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0098","position":{"x":1230.0,"y":-770.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629658,"virtual_time_s":2017.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":99,"wall_ts_ms":1789176629659,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0099","position":{"x":1250.0,"y":-770.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629659,"virtual_time_s":2024.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":100,"wall_ts_ms":1789176629660,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0100","position":{"x":1250.0,"y":-750.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629660,"virtual_time_s":2031.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":101,"wall_ts_ms":1789176629660,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0101","position":{"x":1270.0,"y":-750.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629660,"virtual_time_s":2038.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":102,"wall_ts_ms":1789176629661,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0102","position":{"x":1270.0,"y":-730.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629661,"virtual_time_s":2045.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":103,"wall_ts_ms":1789176629661,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0103","position":{"x":1290.0,"y":-730.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629661,"virtual_time_s":2052.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":104,"wall_ts_ms":1789176629662,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0104","position":{"x":1290.0,"y":-710.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629662,"virtual_time_s":2059.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":105,"wall_ts_ms":1789176629662,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0105","position":{"x":1310.0,"y":-710.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629662,"virtual_time_s":2066.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":106,"wall_ts_ms":1789176629663,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0106","position":{"x":1310.0,"y":-690.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629663,"virtual_time_s":2073.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":107,"wall_ts_ms":1789176629664,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0107","position":{"x":1330.0,"y":-690.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629664,"virtual_time_s":2080.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":108,"wall_ts_ms":1789176629664,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0108","position":{"x":1330.0,"y":-670.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629664,"virtual_time_s":2087.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":109,"wall_ts_ms":1789176629665,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0109","position":{"x":1350.0,"y":-670.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629665,"virtual_time_s":2094.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":110,"wall_ts_ms":1789176629666,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0110","position":{"x":1350.0,"y":-650.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629666,"virtual_time_s":2101.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":111,"wall_ts_ms":1789176629666,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0111","position":{"x":1370.0,"y":-650.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629666,"virtual_time_s":2108.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":112,"wall_ts_ms":1789176629667,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0112","position":{"x":1370.0,"y":-630.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629667,"virtual_time_s":2115.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":113,"wall_ts_ms":1789176629667,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0113","position":{"x":1390.0,"y":-630.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629667,"virtual_time_s":2122.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":114,"wall_ts_ms":1789176629668,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0114","position":{"x":1390.0,"y":-610.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629668,"virtual_time_s":2129.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":115,"wall_ts_ms":1789176629669,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0115","position":{"x":1410.0,"y":-610.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629669,"virtual_time_s":2136.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":116,"wall_ts_ms":1789176629669,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0116","position":{"x":1410.0,"y":-590.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629669,"virtual_time_s":2143.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":117,"wall_ts_ms":1789176629670,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0117","position":{"x":1430.0,"y":-590.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629670,"virtual_time_s":2150.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":118,"wall_ts_ms":1789176629670,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0118","position":{"x":1430.0,"y":-570.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629670,"virtual_time_s":2157.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":119,"wall_ts_ms":1789176629671,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0119","position":{"x":1450.0,"y":-570.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629671,"virtual_time_s":2164.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":120,"wall_ts_ms":1789176629672,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0120","position":{"x":1450.0,"y":-550.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629671,"virtual_time_s":2171.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":121,"wall_ts_ms":1789176629672,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0121","position":{"x":1470.0,"y":-550.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629672,"virtual_time_s":2178.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":122,"wall_ts_ms":1789176629673,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0122","position":{"x":1470.0,"y":-530.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629673,"virtual_time_s":2185.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":123,"wall_ts_ms":1789176629673,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0123","position":{"x":1490.0,"y":-530.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629673,"virtual_time_s":2192.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":124,"wall_ts_ms":1789176629674,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0124","position":{"x":1490.0,"y":-510.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629674,"virtual_time_s":2199.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":125,"wall_ts_ms":1789176629674,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0125","position":{"x":1510.0,"y":-510.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629674,"virtual_time_s":2206.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":126,"wall_ts_ms":1789176629675,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0126","position":{"x":1510.0,"y":-490.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629675,"virtual_time_s":2213.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":127,"wall_ts_ms":1789176629675,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0127","position":{"x":1510.0,"y":-470.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629675,"virtual_time_s":2220.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":128,"wall_ts_ms":1789176629676,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0128","position":{"x":1530.0,"y":-470.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629676,"virtual_time_s":2227.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":129,"wall_ts_ms":1789176629676,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0129","position":{"x":1530.0,"y":-490.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629676,"virtual_time_s":2234.725602,"clear_result":"no_target_in_range"}}
{"event":"action","seq":130,"wall_ts_ms":1789176629677,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0130","position":{"x":1550.0,"y":-470.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629677,"virtual_time_s":2243.382456,"clear_result":"no_target_in_range"}}
{"event":"action","seq":131,"wall_ts_ms":1789176629677,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0131","position":{"x":1550.0,"y":-450.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629677,"virtual_time_s":2250.382456,"clear_result":"no_target_in_range"}}
{"event":"action","seq":132,"wall_ts_ms":1789176629678,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0132","position":{"x":1530.0,"y":-450.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629678,"virtual_time_s":2257.382456,"clear_result":"no_target_in_range"}}
{"event":"action","seq":133,"wall_ts_ms":1789176629678,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0133","position":{"x":1550.0,"y":-430.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629678,"virtual_time_s":2266.03931,"clear_result":"no_target_in_range"}}
{"event":"action","seq":134,"wall_ts_ms":1789176629679,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0134","position":{"x":1570.0,"y":-430.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629679,"virtual_time_s":2273.03931,"clear_result":"no_target_in_range"}}
{"event":"action","seq":135,"wall_ts_ms":1789176629679,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0135","position":{"x":1570.0,"y":-450.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629679,"virtual_time_s":2280.03931,"clear_result":"no_target_in_range"}}
{"event":"action","seq":136,"wall_ts_ms":1789176629680,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0136","position":{"x":1590.0,"y":-430.0},"channel":7},"response":{"accepted":true,"real_timestamp_ms":1789176629680,"virtual_time_s":2290.696164,"clear_result":"success"}}
{"event":"action","seq":137,"wall_ts_ms":1789176629790,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0137","position":{"x":1429.8624502943494,"y":-654.1112669539796},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176629790,"virtual_time_s":2351.785145,"measure_result":"direction","svd_deg":157.78}}
{"event":"action","seq":138,"wall_ts_ms":1789176629806,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0138","position":{"x":739.7053147276195,"y":-388.5273903936236},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176629806,"virtual_time_s":2504.683984,"measure_result":"direction","svd_deg":126.53}}
{"event":"action","seq":139,"wall_ts_ms":1789176629815,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0139","position":{"x":737.259244277467,"y":-379.09950798866356},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176629815,"virtual_time_s":2511.63199,"measure_result":"direction","svd_deg":131.0}}
{"event":"action","seq":140,"wall_ts_ms":1789176629816,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0140","position":{"x":710.6302761970189,"y":-349.5302324286764},"channel":10},"response":{"accepted":true,"real_timestamp_ms":1789176629816,"virtual_time_s":2524.590492,"clear_result":"success"}}
{"event":"action","seq":141,"wall_ts_ms":1789176629817,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0141","position":{"x":800.0,"y":0.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176629817,"virtual_time_s":2602.745417,"measure_result":"no_signal"}}
{"event":"action","seq":142,"wall_ts_ms":1789176629818,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0142","position":{"x":800.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176629818,"virtual_time_s":2608.745417,"measure_result":"no_signal"}}
{"event":"action","seq":143,"wall_ts_ms":1789176629818,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0143","position":{"x":800.0,"y":0.0},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176629818,"virtual_time_s":2614.745417,"measure_result":"direction","svd_deg":63.87}}
{"event":"action","seq":144,"wall_ts_ms":1789176629851,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0144","position":{"x":800.0,"y":0.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176629851,"virtual_time_s":2620.745417,"measure_result":"no_signal"}}
{"event":"action","seq":145,"wall_ts_ms":1789176629851,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0145","position":{"x":800.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176629851,"virtual_time_s":2626.745417,"measure_result":"no_signal"}}
{"event":"action","seq":146,"wall_ts_ms":1789176629852,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0146","position":{"x":800.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176629852,"virtual_time_s":2632.745417,"measure_result":"no_signal"}}
{"event":"action","seq":147,"wall_ts_ms":1789176629852,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0147","position":{"x":800.0,"y":0.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176629852,"virtual_time_s":2638.745417,"measure_result":"no_signal"}}
{"event":"action","seq":148,"wall_ts_ms":1789176629853,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0148","position":{"x":800.0,"y":0.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176629853,"virtual_time_s":2644.745417,"measure_result":"no_signal"}}
{"event":"action","seq":149,"wall_ts_ms":1789176629853,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0149","position":{"x":800.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176629853,"virtual_time_s":2650.745417,"measure_result":"no_signal"}}
{"event":"action","seq":150,"wall_ts_ms":1789176629854,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0150","position":{"x":800.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176629854,"virtual_time_s":2656.745417,"measure_result":"no_signal"}}
{"event":"action","seq":151,"wall_ts_ms":1789176629854,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0151","position":{"x":800.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176629854,"virtual_time_s":2662.745417,"measure_result":"no_signal"}}
{"event":"action","seq":152,"wall_ts_ms":1789176629944,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0152","position":{"x":615.2131848563207,"y":129.68975025133534},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176629944,"virtual_time_s":2713.89654,"measure_result":"direction","svd_deg":53.64}}
{"event":"action","seq":153,"wall_ts_ms":1789176629973,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0153","position":{"x":1177.7314832954046,"y":943.2140959095032},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176629973,"virtual_time_s":2916.709451,"measure_result":"direction","svd_deg":31.61}}
{"event":"action","seq":154,"wall_ts_ms":1789176629974,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0154","position":{"x":1279.8090675459375,"y":1006.3704010851982},"channel":4},"response":{"accepted":true,"real_timestamp_ms":1789176629974,"virtual_time_s":2945.716577,"clear_result":"success"}}
{"event":"action","seq":155,"wall_ts_ms":1789176629974,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0155","position":{"x":1000.0,"y":1000.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176629974,"virtual_time_s":3007.692892,"measure_result":"no_signal"}}
{"event":"action","seq":156,"wall_ts_ms":1789176629975,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0156","position":{"x":1000.0,"y":1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176629975,"virtual_time_s":3013.692892,"measure_result":"no_signal"}}
{"event":"action","seq":157,"wall_ts_ms":1789176629976,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0157","position":{"x":1000.0,"y":1000.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176629975,"virtual_time_s":3019.692892,"measure_result":"direction","svd_deg":139.28}}
{"event":"action","seq":158,"wall_ts_ms":1789176630005,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0158","position":{"x":1000.0,"y":1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630005,"virtual_time_s":3025.692892,"measure_result":"no_signal"}}
{"event":"action","seq":159,"wall_ts_ms":1789176630006,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0159","position":{"x":1000.0,"y":1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630006,"virtual_time_s":3031.692892,"measure_result":"no_signal"}}
{"event":"action","seq":160,"wall_ts_ms":1789176630007,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0160","position":{"x":1000.0,"y":1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630007,"virtual_time_s":3037.692892,"measure_result":"no_signal"}}
{"event":"action","seq":161,"wall_ts_ms":1789176630008,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0161","position":{"x":1000.0,"y":1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630008,"virtual_time_s":3043.692892,"measure_result":"no_signal"}}
{"event":"action","seq":162,"wall_ts_ms":1789176630008,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0162","position":{"x":1000.0,"y":1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630008,"virtual_time_s":3049.692892,"measure_result":"no_signal"}}
{"event":"action","seq":163,"wall_ts_ms":1789176630009,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0163","position":{"x":1000.0,"y":1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630009,"virtual_time_s":3055.692892,"measure_result":"no_signal"}}
{"event":"action","seq":164,"wall_ts_ms":1789176630009,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0164","position":{"x":1000.0,"y":1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630009,"virtual_time_s":3061.692892,"measure_result":"no_signal"}}
{"event":"action","seq":165,"wall_ts_ms":1789176630102,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0165","position":{"x":961.1212618824487,"y":957.3588710610661},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630102,"virtual_time_s":3079.233814,"measure_result":"direction","svd_deg":134.72}}
{"event":"action","seq":166,"wall_ts_ms":1789176630157,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0166","position":{"x":727.4962312194393,"y":1188.2072757884716},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630156,"virtual_time_s":3149.921451,"measure_result":"direction","svd_deg":134.94}}
{"event":"action","seq":167,"wall_ts_ms":1789176630212,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0167","position":{"x":644.8369478160281,"y":1264.9765735176386},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630212,"virtual_time_s":3177.483439,"measure_result":"direction","svd_deg":133.41}}
{"event":"action","seq":168,"wall_ts_ms":1789176630247,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0168","position":{"x":602.1706583987492,"y":1317.180739025646},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630247,"virtual_time_s":3195.967781,"measure_result":"direction","svd_deg":136.01}}
{"event":"action","seq":169,"wall_ts_ms":1789176630277,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0169","position":{"x":593.2790406267442,"y":1325.43794313003},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630277,"virtual_time_s":3203.39465,"measure_result":"direction","svd_deg":135.64}}
{"event":"action","seq":170,"wall_ts_ms":1789176630306,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0170","position":{"x":593.2790406267442,"y":1325.43794313003},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630306,"virtual_time_s":3208.39465,"measure_result":"direction","svd_deg":135.64}}
{"event":"action","seq":171,"wall_ts_ms":1789176630337,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0171","position":{"x":593.2790406267442,"y":1325.43794313003},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630337,"virtual_time_s":3213.39465,"measure_result":"direction","svd_deg":135.64}}
{"event":"action","seq":172,"wall_ts_ms":1789176630367,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0172","position":{"x":593.2790406267442,"y":1325.43794313003},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630367,"virtual_time_s":3218.39465,"measure_result":"direction","svd_deg":135.64}}
{"event":"action","seq":173,"wall_ts_ms":1789176630369,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0173","position":{"x":530.0,"y":1390.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630369,"virtual_time_s":3239.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":174,"wall_ts_ms":1789176630369,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0174","position":{"x":510.0,"y":1390.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630369,"virtual_time_s":3246.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":175,"wall_ts_ms":1789176630370,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0175","position":{"x":510.0,"y":1410.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630370,"virtual_time_s":3253.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":176,"wall_ts_ms":1789176630370,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0176","position":{"x":490.0,"y":1410.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630370,"virtual_time_s":3260.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":177,"wall_ts_ms":1789176630371,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0177","position":{"x":490.0,"y":1430.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630371,"virtual_time_s":3267.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":178,"wall_ts_ms":1789176630372,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0178","position":{"x":470.0,"y":1430.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630372,"virtual_time_s":3274.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":179,"wall_ts_ms":1789176630372,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0179","position":{"x":470.0,"y":1450.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630372,"virtual_time_s":3281.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":180,"wall_ts_ms":1789176630373,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0180","position":{"x":450.0,"y":1450.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630373,"virtual_time_s":3288.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":181,"wall_ts_ms":1789176630373,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0181","position":{"x":450.0,"y":1470.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630373,"virtual_time_s":3295.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":182,"wall_ts_ms":1789176630374,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0182","position":{"x":430.0,"y":1470.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630374,"virtual_time_s":3302.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":183,"wall_ts_ms":1789176630375,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0183","position":{"x":430.0,"y":1490.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630375,"virtual_time_s":3309.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":184,"wall_ts_ms":1789176630375,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0184","position":{"x":410.0,"y":1490.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630375,"virtual_time_s":3316.475022,"clear_result":"no_target_in_range"}}
{"event":"action","seq":185,"wall_ts_ms":1789176630376,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0185","position":{"x":410.0,"y":1510.0},"channel":5},"response":{"accepted":true,"real_timestamp_ms":1789176630376,"virtual_time_s":3325.475022,"clear_result":"success"}}
{"event":"action","seq":186,"wall_ts_ms":1789176630376,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0186","position":{"x":400.0,"y":1800.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630376,"virtual_time_s":3389.509495,"measure_result":"no_signal"}}
{"event":"action","seq":187,"wall_ts_ms":1789176630377,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0187","position":{"x":400.0,"y":1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630377,"virtual_time_s":3395.509495,"measure_result":"no_signal"}}
{"event":"action","seq":188,"wall_ts_ms":1789176630562,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0188","position":{"x":400.0,"y":1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630559,"virtual_time_s":3401.509495,"measure_result":"no_signal"}}
{"event":"action","seq":189,"wall_ts_ms":1789176630564,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0189","position":{"x":400.0,"y":1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630564,"virtual_time_s":3407.509495,"measure_result":"no_signal"}}
{"event":"action","seq":190,"wall_ts_ms":1789176630565,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0190","position":{"x":400.0,"y":1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630565,"virtual_time_s":3413.509495,"measure_result":"no_signal"}}
{"event":"action","seq":191,"wall_ts_ms":1789176630565,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0191","position":{"x":400.0,"y":1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630565,"virtual_time_s":3419.509495,"measure_result":"no_signal"}}
{"event":"action","seq":192,"wall_ts_ms":1789176630566,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0192","position":{"x":400.0,"y":1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630566,"virtual_time_s":3425.509495,"measure_result":"no_signal"}}
{"event":"action","seq":193,"wall_ts_ms":1789176630568,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0193","position":{"x":400.0,"y":1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630568,"virtual_time_s":3431.509495,"measure_result":"no_signal"}}
{"event":"action","seq":194,"wall_ts_ms":1789176630569,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0194","position":{"x":400.0,"y":1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630569,"virtual_time_s":3437.509495,"measure_result":"no_signal"}}
{"event":"action","seq":195,"wall_ts_ms":1789176630570,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0195","position":{"x":-200.0,"y":1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630570,"virtual_time_s":3562.509495,"measure_result":"no_signal"}}
{"event":"action","seq":196,"wall_ts_ms":1789176630571,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0196","position":{"x":-200.0,"y":1800.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630571,"virtual_time_s":3568.509495,"measure_result":"no_signal"}}
{"event":"action","seq":197,"wall_ts_ms":1789176630572,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0197","position":{"x":-200.0,"y":1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630572,"virtual_time_s":3574.509495,"measure_result":"no_signal"}}
{"event":"action","seq":198,"wall_ts_ms":1789176630572,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0198","position":{"x":-200.0,"y":1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630572,"virtual_time_s":3580.509495,"measure_result":"no_signal"}}
{"event":"action","seq":199,"wall_ts_ms":1789176630573,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0199","position":{"x":-200.0,"y":1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630573,"virtual_time_s":3586.509495,"measure_result":"no_signal"}}
{"event":"action","seq":200,"wall_ts_ms":1789176630574,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0200","position":{"x":-200.0,"y":1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630574,"virtual_time_s":3592.509495,"measure_result":"no_signal"}}
{"event":"action","seq":201,"wall_ts_ms":1789176630575,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0201","position":{"x":-200.0,"y":1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630575,"virtual_time_s":3598.509495,"measure_result":"no_signal"}}
{"event":"action","seq":202,"wall_ts_ms":1789176630575,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0202","position":{"x":-200.0,"y":1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630575,"virtual_time_s":3604.509495,"measure_result":"no_signal"}}
{"event":"action","seq":203,"wall_ts_ms":1789176630576,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0203","position":{"x":-200.0,"y":1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630576,"virtual_time_s":3610.509495,"measure_result":"no_signal"}}
{"event":"action","seq":204,"wall_ts_ms":1789176630577,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0204","position":{"x":0.0,"y":1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630577,"virtual_time_s":3780.43372,"measure_result":"no_signal"}}
{"event":"action","seq":205,"wall_ts_ms":1789176630577,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0205","position":{"x":0.0,"y":1000.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630577,"virtual_time_s":3786.43372,"measure_result":"no_signal"}}
{"event":"action","seq":206,"wall_ts_ms":1789176630578,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0206","position":{"x":0.0,"y":1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630578,"virtual_time_s":3792.43372,"measure_result":"no_signal"}}
{"event":"action","seq":207,"wall_ts_ms":1789176630578,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0207","position":{"x":0.0,"y":1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630578,"virtual_time_s":3798.43372,"measure_result":"no_signal"}}
{"event":"action","seq":208,"wall_ts_ms":1789176630579,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0208","position":{"x":0.0,"y":1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630579,"virtual_time_s":3804.43372,"measure_result":"no_signal"}}
{"event":"action","seq":209,"wall_ts_ms":1789176630579,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0209","position":{"x":0.0,"y":1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630579,"virtual_time_s":3810.43372,"measure_result":"no_signal"}}
{"event":"action","seq":210,"wall_ts_ms":1789176630580,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0210","position":{"x":0.0,"y":1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630580,"virtual_time_s":3816.43372,"measure_result":"no_signal"}}
{"event":"action","seq":211,"wall_ts_ms":1789176630580,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0211","position":{"x":0.0,"y":1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630580,"virtual_time_s":3822.43372,"measure_result":"no_signal"}}
{"event":"action","seq":212,"wall_ts_ms":1789176630581,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0212","position":{"x":0.0,"y":1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630581,"virtual_time_s":3828.43372,"measure_result":"no_signal"}}
{"event":"action","seq":213,"wall_ts_ms":1789176630581,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0213","position":{"x":-200.0,"y":400.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630581,"virtual_time_s":3959.924826,"measure_result":"no_signal"}}
{"event":"action","seq":214,"wall_ts_ms":1789176630582,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0214","position":{"x":-200.0,"y":400.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630582,"virtual_time_s":3965.924826,"measure_result":"no_signal"}}
{"event":"action","seq":215,"wall_ts_ms":1789176630582,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0215","position":{"x":-200.0,"y":400.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630582,"virtual_time_s":3971.924826,"measure_result":"no_signal"}}
{"event":"action","seq":216,"wall_ts_ms":1789176630583,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0216","position":{"x":-200.0,"y":400.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630583,"virtual_time_s":3977.924826,"measure_result":"no_signal"}}
{"event":"action","seq":217,"wall_ts_ms":1789176630584,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0217","position":{"x":-200.0,"y":400.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630583,"virtual_time_s":3983.924826,"measure_result":"no_signal"}}
{"event":"action","seq":218,"wall_ts_ms":1789176630584,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0218","position":{"x":-200.0,"y":400.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630584,"virtual_time_s":3989.924826,"measure_result":"no_signal"}}
{"event":"action","seq":219,"wall_ts_ms":1789176630585,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0219","position":{"x":-200.0,"y":400.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630585,"virtual_time_s":3995.924826,"measure_result":"no_signal"}}
{"event":"action","seq":220,"wall_ts_ms":1789176630585,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0220","position":{"x":-200.0,"y":400.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630585,"virtual_time_s":4001.924826,"measure_result":"no_signal"}}
{"event":"action","seq":221,"wall_ts_ms":1789176630586,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0221","position":{"x":-200.0,"y":400.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630586,"virtual_time_s":4007.924826,"measure_result":"no_signal"}}
{"event":"action","seq":222,"wall_ts_ms":1789176630586,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0222","position":{"x":-800.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630586,"virtual_time_s":4157.146877,"measure_result":"no_signal"}}
{"event":"action","seq":223,"wall_ts_ms":1789176630587,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0223","position":{"x":-800.0,"y":0.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630587,"virtual_time_s":4163.146877,"measure_result":"direction","svd_deg":244.07999999999998}}
{"event":"action","seq":224,"wall_ts_ms":1789176630618,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0224","position":{"x":-800.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630618,"virtual_time_s":4169.146877,"measure_result":"no_signal"}}
{"event":"action","seq":225,"wall_ts_ms":1789176630619,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0225","position":{"x":-800.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630619,"virtual_time_s":4175.146877,"measure_result":"no_signal"}}
{"event":"action","seq":226,"wall_ts_ms":1789176630619,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0226","position":{"x":-800.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630619,"virtual_time_s":4181.146877,"measure_result":"no_signal"}}
{"event":"action","seq":227,"wall_ts_ms":1789176630620,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0227","position":{"x":-800.0,"y":0.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630620,"virtual_time_s":4187.146877,"measure_result":"no_signal"}}
{"event":"action","seq":228,"wall_ts_ms":1789176630620,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0228","position":{"x":-800.0,"y":0.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630620,"virtual_time_s":4193.146877,"measure_result":"no_signal"}}
{"event":"action","seq":229,"wall_ts_ms":1789176630621,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0229","position":{"x":-800.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630621,"virtual_time_s":4199.146877,"measure_result":"no_signal"}}
{"event":"action","seq":230,"wall_ts_ms":1789176630622,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0230","position":{"x":-800.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630622,"virtual_time_s":4205.146877,"measure_result":"no_signal"}}
{"event":"action","seq":231,"wall_ts_ms":1789176630712,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0231","position":{"x":-612.7393373735924,"y":-130.91442858438631},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630712,"virtual_time_s":4256.843767,"measure_result":"direction","svd_deg":222.42}}
{"event":"action","seq":232,"wall_ts_ms":1789176630729,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0232","position":{"x":-1006.5000668981338,"y":-486.82119505919434},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630729,"virtual_time_s":4367.997832,"measure_result":"direction","svd_deg":224.01}}
{"event":"action","seq":233,"wall_ts_ms":1789176630741,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0233","position":{"x":-1028.1817467480657,"y":-507.3587406401402},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630741,"virtual_time_s":4378.970724,"measure_result":"direction","svd_deg":224.99}}
{"event":"action","seq":234,"wall_ts_ms":1789176630755,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0234","position":{"x":-1029.2304268190826,"y":-508.76489554880675},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630755,"virtual_time_s":4384.321552,"measure_result":"direction","svd_deg":224.82}}
{"event":"action","seq":235,"wall_ts_ms":1789176630769,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0235","position":{"x":-1029.6867212721636,"y":-509.3769214602712},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630769,"virtual_time_s":4389.474232,"measure_result":"direction","svd_deg":225.27}}
{"event":"action","seq":236,"wall_ts_ms":1789176630782,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0236","position":{"x":-1030.2048717132175,"y":-510.072059916583},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630782,"virtual_time_s":4394.647633,"measure_result":"direction","svd_deg":224.0}}
{"event":"action","seq":237,"wall_ts_ms":1789176630795,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0237","position":{"x":-1030.5146387597,"y":-510.13828087271185},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630795,"virtual_time_s":4399.710986,"measure_result":"direction","svd_deg":224.73}}
{"event":"action","seq":238,"wall_ts_ms":1789176630807,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0238","position":{"x":-1030.5146387597,"y":-510.13828087271185},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630807,"virtual_time_s":4404.710986,"measure_result":"direction","svd_deg":224.73}}
{"event":"action","seq":239,"wall_ts_ms":1789176630808,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0239","position":{"x":-1050.0,"y":-530.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630808,"virtual_time_s":4413.275758,"clear_result":"no_target_in_range"}}
{"event":"action","seq":240,"wall_ts_ms":1789176630809,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0240","position":{"x":-1070.0,"y":-530.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630809,"virtual_time_s":4420.275758,"clear_result":"no_target_in_range"}}
{"event":"action","seq":241,"wall_ts_ms":1789176630810,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0241","position":{"x":-1070.0,"y":-550.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630810,"virtual_time_s":4427.275758,"clear_result":"no_target_in_range"}}
{"event":"action","seq":242,"wall_ts_ms":1789176630810,"method":"POST","path":"/clear","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0242","position":{"x":-1090.0,"y":-550.0},"channel":1},"response":{"accepted":true,"real_timestamp_ms":1789176630810,"virtual_time_s":4436.275758,"clear_result":"success"}}
{"event":"action","seq":243,"wall_ts_ms":1789176630811,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0243","position":{"x":-1200.0,"y":-1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630811,"virtual_time_s":4534.925637,"measure_result":"no_signal"}}
{"event":"action","seq":244,"wall_ts_ms":1789176630811,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0244","position":{"x":-1200.0,"y":-1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630811,"virtual_time_s":4540.925637,"measure_result":"no_signal"}}
{"event":"action","seq":245,"wall_ts_ms":1789176630812,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0245","position":{"x":-1200.0,"y":-1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630812,"virtual_time_s":4546.925637,"measure_result":"no_signal"}}
{"event":"action","seq":246,"wall_ts_ms":1789176630812,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0246","position":{"x":-1200.0,"y":-1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630812,"virtual_time_s":4552.925637,"measure_result":"no_signal"}}
{"event":"action","seq":247,"wall_ts_ms":1789176630813,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0247","position":{"x":-1200.0,"y":-1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630813,"virtual_time_s":4558.925637,"measure_result":"no_signal"}}
{"event":"action","seq":248,"wall_ts_ms":1789176630814,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0248","position":{"x":-1200.0,"y":-1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630814,"virtual_time_s":4564.925637,"measure_result":"no_signal"}}
{"event":"action","seq":249,"wall_ts_ms":1789176630814,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0249","position":{"x":-1200.0,"y":-1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630814,"virtual_time_s":4570.925637,"measure_result":"no_signal"}}
{"event":"action","seq":250,"wall_ts_ms":1789176630815,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0250","position":{"x":-1200.0,"y":-1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630815,"virtual_time_s":4576.925637,"measure_result":"no_signal"}}
{"event":"action","seq":251,"wall_ts_ms":1789176630815,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0251","position":{"x":-600.0,"y":-1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630815,"virtual_time_s":4701.925637,"measure_result":"no_signal"}}
{"event":"action","seq":252,"wall_ts_ms":1789176630816,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0252","position":{"x":-600.0,"y":-1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630816,"virtual_time_s":4707.925637,"measure_result":"no_signal"}}
{"event":"action","seq":253,"wall_ts_ms":1789176630816,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0253","position":{"x":-600.0,"y":-1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630816,"virtual_time_s":4713.925637,"measure_result":"no_signal"}}
{"event":"action","seq":254,"wall_ts_ms":1789176630817,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0254","position":{"x":-600.0,"y":-1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630817,"virtual_time_s":4719.925637,"measure_result":"no_signal"}}
{"event":"action","seq":255,"wall_ts_ms":1789176630817,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0255","position":{"x":-600.0,"y":-1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630817,"virtual_time_s":4725.925637,"measure_result":"no_signal"}}
{"event":"action","seq":256,"wall_ts_ms":1789176630818,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0256","position":{"x":-600.0,"y":-1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630818,"virtual_time_s":4731.925637,"measure_result":"no_signal"}}
{"event":"action","seq":257,"wall_ts_ms":1789176630818,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0257","position":{"x":-600.0,"y":-1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630818,"virtual_time_s":4737.925637,"measure_result":"no_signal"}}
{"event":"action","seq":258,"wall_ts_ms":1789176630819,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0258","position":{"x":-600.0,"y":-1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630819,"virtual_time_s":4743.925637,"measure_result":"no_signal"}}
{"event":"action","seq":259,"wall_ts_ms":1789176630820,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0259","position":{"x":0.0,"y":-1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630820,"virtual_time_s":4868.925637,"measure_result":"no_signal"}}
{"event":"action","seq":260,"wall_ts_ms":1789176630820,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0260","position":{"x":0.0,"y":-1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630820,"virtual_time_s":4874.925637,"measure_result":"no_signal"}}
{"event":"action","seq":261,"wall_ts_ms":1789176630821,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0261","position":{"x":0.0,"y":-1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630821,"virtual_time_s":4880.925637,"measure_result":"no_signal"}}
{"event":"action","seq":262,"wall_ts_ms":1789176630821,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0262","position":{"x":0.0,"y":-1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630821,"virtual_time_s":4886.925637,"measure_result":"no_signal"}}
{"event":"action","seq":263,"wall_ts_ms":1789176630822,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0263","position":{"x":0.0,"y":-1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630822,"virtual_time_s":4892.925637,"measure_result":"no_signal"}}
{"event":"action","seq":264,"wall_ts_ms":1789176630822,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0264","position":{"x":0.0,"y":-1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630822,"virtual_time_s":4898.925637,"measure_result":"no_signal"}}
{"event":"action","seq":265,"wall_ts_ms":1789176630823,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0265","position":{"x":0.0,"y":-1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630823,"virtual_time_s":4904.925637,"measure_result":"no_signal"}}
{"event":"action","seq":266,"wall_ts_ms":1789176630823,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0266","position":{"x":0.0,"y":-1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630823,"virtual_time_s":4910.925637,"measure_result":"no_signal"}}
{"event":"action","seq":267,"wall_ts_ms":1789176630824,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0267","position":{"x":400.0,"y":-800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630824,"virtual_time_s":5005.368356,"measure_result":"no_signal"}}
{"event":"action","seq":268,"wall_ts_ms":1789176630824,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0268","position":{"x":400.0,"y":-800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630824,"virtual_time_s":5011.368356,"measure_result":"no_signal"}}
{"event":"action","seq":269,"wall_ts_ms":1789176630825,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0269","position":{"x":400.0,"y":-800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630825,"virtual_time_s":5017.368356,"measure_result":"no_signal"}}
{"event":"action","seq":270,"wall_ts_ms":1789176630826,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0270","position":{"x":400.0,"y":-800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630826,"virtual_time_s":5023.368356,"measure_result":"no_signal"}}
{"event":"action","seq":271,"wall_ts_ms":1789176630826,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0271","position":{"x":400.0,"y":-800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630826,"virtual_time_s":5029.368356,"measure_result":"no_signal"}}
{"event":"action","seq":272,"wall_ts_ms":1789176630827,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0272","position":{"x":400.0,"y":-800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630827,"virtual_time_s":5035.368356,"measure_result":"no_signal"}}
{"event":"action","seq":273,"wall_ts_ms":1789176630827,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0273","position":{"x":400.0,"y":-800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630827,"virtual_time_s":5041.368356,"measure_result":"no_signal"}}
{"event":"action","seq":274,"wall_ts_ms":1789176630828,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0274","position":{"x":400.0,"y":-800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630828,"virtual_time_s":5047.368356,"measure_result":"no_signal"}}
{"event":"action","seq":275,"wall_ts_ms":1789176630828,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0275","position":{"x":1000.0,"y":-1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630828,"virtual_time_s":5178.859462,"measure_result":"no_signal"}}
{"event":"action","seq":276,"wall_ts_ms":1789176630829,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0276","position":{"x":1000.0,"y":-1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630829,"virtual_time_s":5184.859462,"measure_result":"no_signal"}}
{"event":"action","seq":277,"wall_ts_ms":1789176630829,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0277","position":{"x":1000.0,"y":-1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630829,"virtual_time_s":5190.859462,"measure_result":"no_signal"}}
{"event":"action","seq":278,"wall_ts_ms":1789176630830,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0278","position":{"x":1000.0,"y":-1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630830,"virtual_time_s":5196.859462,"measure_result":"no_signal"}}
{"event":"action","seq":279,"wall_ts_ms":1789176630830,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0279","position":{"x":1000.0,"y":-1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630830,"virtual_time_s":5202.859462,"measure_result":"no_signal"}}
{"event":"action","seq":280,"wall_ts_ms":1789176630831,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0280","position":{"x":1000.0,"y":-1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630831,"virtual_time_s":5208.859462,"measure_result":"no_signal"}}
{"event":"action","seq":281,"wall_ts_ms":1789176630832,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0281","position":{"x":1000.0,"y":-1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630832,"virtual_time_s":5214.859462,"measure_result":"no_signal"}}
{"event":"action","seq":282,"wall_ts_ms":1789176630832,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0282","position":{"x":1000.0,"y":-1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630832,"virtual_time_s":5220.859462,"measure_result":"no_signal"}}
{"event":"action","seq":283,"wall_ts_ms":1789176630833,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0283","position":{"x":1000.0,"y":-1600.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630833,"virtual_time_s":5345.859462,"measure_result":"no_signal"}}
{"event":"action","seq":284,"wall_ts_ms":1789176630833,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0284","position":{"x":1000.0,"y":-1600.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630833,"virtual_time_s":5351.859462,"measure_result":"no_signal"}}
{"event":"action","seq":285,"wall_ts_ms":1789176630834,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0285","position":{"x":1000.0,"y":-1600.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630834,"virtual_time_s":5357.859462,"measure_result":"no_signal"}}
{"event":"action","seq":286,"wall_ts_ms":1789176630834,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0286","position":{"x":1000.0,"y":-1600.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630834,"virtual_time_s":5363.859462,"measure_result":"no_signal"}}
{"event":"action","seq":287,"wall_ts_ms":1789176630835,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0287","position":{"x":1000.0,"y":-1600.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630835,"virtual_time_s":5369.859462,"measure_result":"no_signal"}}
{"event":"action","seq":288,"wall_ts_ms":1789176630835,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0288","position":{"x":1000.0,"y":-1600.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630835,"virtual_time_s":5375.859462,"measure_result":"no_signal"}}
{"event":"action","seq":289,"wall_ts_ms":1789176630836,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0289","position":{"x":1000.0,"y":-1600.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630836,"virtual_time_s":5381.859462,"measure_result":"no_signal"}}
{"event":"action","seq":290,"wall_ts_ms":1789176630836,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0290","position":{"x":1000.0,"y":-1600.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630836,"virtual_time_s":5387.859462,"measure_result":"no_signal"}}
{"event":"action","seq":291,"wall_ts_ms":1789176630837,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0291","position":{"x":800.0,"y":-1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630837,"virtual_time_s":5449.428004,"measure_result":"no_signal"}}
{"event":"action","seq":292,"wall_ts_ms":1789176630837,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0292","position":{"x":800.0,"y":-1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630837,"virtual_time_s":5455.428004,"measure_result":"no_signal"}}
{"event":"action","seq":293,"wall_ts_ms":1789176630838,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0293","position":{"x":800.0,"y":-1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630838,"virtual_time_s":5461.428004,"measure_result":"no_signal"}}
{"event":"action","seq":294,"wall_ts_ms":1789176630838,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0294","position":{"x":800.0,"y":-1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630838,"virtual_time_s":5467.428004,"measure_result":"no_signal"}}
{"event":"action","seq":295,"wall_ts_ms":1789176630839,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0295","position":{"x":800.0,"y":-1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630839,"virtual_time_s":5473.428004,"measure_result":"no_signal"}}
{"event":"action","seq":296,"wall_ts_ms":1789176630839,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0296","position":{"x":800.0,"y":-1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630839,"virtual_time_s":5479.428004,"measure_result":"no_signal"}}
{"event":"action","seq":297,"wall_ts_ms":1789176630840,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0297","position":{"x":800.0,"y":-1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630840,"virtual_time_s":5485.428004,"measure_result":"no_signal"}}
{"event":"action","seq":298,"wall_ts_ms":1789176630840,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0298","position":{"x":800.0,"y":-1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630840,"virtual_time_s":5491.428004,"measure_result":"no_signal"}}
{"event":"action","seq":299,"wall_ts_ms":1789176630841,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0299","position":{"x":-200.0,"y":-2200.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630841,"virtual_time_s":5711.834596,"measure_result":"no_signal"}}
{"event":"action","seq":300,"wall_ts_ms":1789176630841,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0300","position":{"x":-200.0,"y":-2200.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630841,"virtual_time_s":5717.834596,"measure_result":"no_signal"}}
{"event":"action","seq":301,"wall_ts_ms":1789176630842,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0301","position":{"x":-200.0,"y":-2200.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630842,"virtual_time_s":5723.834596,"measure_result":"no_signal"}}
{"event":"action","seq":302,"wall_ts_ms":1789176630842,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0302","position":{"x":-200.0,"y":-2200.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630842,"virtual_time_s":5729.834596,"measure_result":"no_signal"}}
{"event":"action","seq":303,"wall_ts_ms":1789176630843,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0303","position":{"x":-200.0,"y":-2200.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630843,"virtual_time_s":5735.834596,"measure_result":"no_signal"}}
{"event":"action","seq":304,"wall_ts_ms":1789176630843,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0304","position":{"x":-200.0,"y":-2200.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630843,"virtual_time_s":5741.834596,"measure_result":"no_signal"}}
{"event":"action","seq":305,"wall_ts_ms":1789176630844,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0305","position":{"x":-200.0,"y":-2200.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630844,"virtual_time_s":5747.834596,"measure_result":"no_signal"}}
{"event":"action","seq":306,"wall_ts_ms":1789176630844,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0306","position":{"x":-200.0,"y":-2200.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630844,"virtual_time_s":5753.834596,"measure_result":"no_signal"}}
{"event":"action","seq":307,"wall_ts_ms":1789176630845,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0307","position":{"x":-400.0,"y":-1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630845,"virtual_time_s":5848.277315,"measure_result":"no_signal"}}
{"event":"action","seq":308,"wall_ts_ms":1789176630845,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0308","position":{"x":-400.0,"y":-1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630845,"virtual_time_s":5854.277315,"measure_result":"no_signal"}}
{"event":"action","seq":309,"wall_ts_ms":1789176630846,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0309","position":{"x":-400.0,"y":-1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630846,"virtual_time_s":5860.277315,"measure_result":"no_signal"}}
{"event":"action","seq":310,"wall_ts_ms":1789176630846,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0310","position":{"x":-400.0,"y":-1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630846,"virtual_time_s":5866.277315,"measure_result":"no_signal"}}
{"event":"action","seq":311,"wall_ts_ms":1789176630847,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0311","position":{"x":-400.0,"y":-1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630847,"virtual_time_s":5872.277315,"measure_result":"no_signal"}}
{"event":"action","seq":312,"wall_ts_ms":1789176630847,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0312","position":{"x":-400.0,"y":-1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630847,"virtual_time_s":5878.277315,"measure_result":"no_signal"}}
{"event":"action","seq":313,"wall_ts_ms":1789176630848,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0313","position":{"x":-400.0,"y":-1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630848,"virtual_time_s":5884.277315,"measure_result":"no_signal"}}
{"event":"action","seq":314,"wall_ts_ms":1789176630848,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0314","position":{"x":-400.0,"y":-1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630848,"virtual_time_s":5890.277315,"measure_result":"no_signal"}}
{"event":"action","seq":315,"wall_ts_ms":1789176630849,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0315","position":{"x":-1400.0,"y":-1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630849,"virtual_time_s":6095.277315,"measure_result":"no_signal"}}
{"event":"action","seq":316,"wall_ts_ms":1789176630849,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0316","position":{"x":-1400.0,"y":-1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630849,"virtual_time_s":6101.277315,"measure_result":"no_signal"}}
{"event":"action","seq":317,"wall_ts_ms":1789176630850,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0317","position":{"x":-1400.0,"y":-1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630850,"virtual_time_s":6107.277315,"measure_result":"no_signal"}}
{"event":"action","seq":318,"wall_ts_ms":1789176630850,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0318","position":{"x":-1400.0,"y":-1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630850,"virtual_time_s":6113.277315,"measure_result":"no_signal"}}
{"event":"action","seq":319,"wall_ts_ms":1789176630851,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0319","position":{"x":-1400.0,"y":-1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630851,"virtual_time_s":6119.277315,"measure_result":"no_signal"}}
{"event":"action","seq":320,"wall_ts_ms":1789176630851,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0320","position":{"x":-1400.0,"y":-1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630851,"virtual_time_s":6125.277315,"measure_result":"no_signal"}}
{"event":"action","seq":321,"wall_ts_ms":1789176630852,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0321","position":{"x":-1400.0,"y":-1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630852,"virtual_time_s":6131.277315,"measure_result":"no_signal"}}
{"event":"action","seq":322,"wall_ts_ms":1789176630852,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0322","position":{"x":-1400.0,"y":-1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630852,"virtual_time_s":6137.277315,"measure_result":"no_signal"}}
{"event":"action","seq":323,"wall_ts_ms":1789176630853,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0323","position":{"x":-1800.0,"y":-800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630853,"virtual_time_s":6357.683907,"measure_result":"no_signal"}}
{"event":"action","seq":324,"wall_ts_ms":1789176630853,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0324","position":{"x":-1800.0,"y":-800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630853,"virtual_time_s":6363.683907,"measure_result":"no_signal"}}
{"event":"action","seq":325,"wall_ts_ms":1789176630854,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0325","position":{"x":-1800.0,"y":-800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630854,"virtual_time_s":6369.683907,"measure_result":"no_signal"}}
{"event":"action","seq":326,"wall_ts_ms":1789176630854,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0326","position":{"x":-1800.0,"y":-800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630854,"virtual_time_s":6375.683907,"measure_result":"no_signal"}}
{"event":"action","seq":327,"wall_ts_ms":1789176630855,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0327","position":{"x":-1800.0,"y":-800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630855,"virtual_time_s":6381.683907,"measure_result":"no_signal"}}
{"event":"action","seq":328,"wall_ts_ms":1789176630855,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0328","position":{"x":-1800.0,"y":-800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630855,"virtual_time_s":6387.683907,"measure_result":"no_signal"}}
{"event":"action","seq":329,"wall_ts_ms":1789176630856,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0329","position":{"x":-1800.0,"y":-800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630856,"virtual_time_s":6393.683907,"measure_result":"no_signal"}}
{"event":"action","seq":330,"wall_ts_ms":1789176630856,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0330","position":{"x":-1800.0,"y":-800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630856,"virtual_time_s":6399.683907,"measure_result":"no_signal"}}
{"event":"action","seq":331,"wall_ts_ms":1789176630857,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0331","position":{"x":-2000.0,"y":-400.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630857,"virtual_time_s":6494.126626,"measure_result":"no_signal"}}
{"event":"action","seq":332,"wall_ts_ms":1789176630857,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0332","position":{"x":-2000.0,"y":-400.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630857,"virtual_time_s":6500.126626,"measure_result":"no_signal"}}
{"event":"action","seq":333,"wall_ts_ms":1789176630858,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0333","position":{"x":-2000.0,"y":-400.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630858,"virtual_time_s":6506.126626,"measure_result":"no_signal"}}
{"event":"action","seq":334,"wall_ts_ms":1789176630858,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0334","position":{"x":-2000.0,"y":-400.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630858,"virtual_time_s":6512.126626,"measure_result":"no_signal"}}
{"event":"action","seq":335,"wall_ts_ms":1789176630859,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0335","position":{"x":-2000.0,"y":-400.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630859,"virtual_time_s":6518.126626,"measure_result":"no_signal"}}
{"event":"action","seq":336,"wall_ts_ms":1789176630859,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0336","position":{"x":-2000.0,"y":-400.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630859,"virtual_time_s":6524.126626,"measure_result":"no_signal"}}
{"event":"action","seq":337,"wall_ts_ms":1789176630860,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0337","position":{"x":-2000.0,"y":-400.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630860,"virtual_time_s":6530.126626,"measure_result":"no_signal"}}
{"event":"action","seq":338,"wall_ts_ms":1789176630860,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0338","position":{"x":-2000.0,"y":-400.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630860,"virtual_time_s":6536.126626,"measure_result":"no_signal"}}
{"event":"action","seq":339,"wall_ts_ms":1789176630861,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0339","position":{"x":-1800.0,"y":200.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630861,"virtual_time_s":6667.617732,"measure_result":"no_signal"}}
{"event":"action","seq":340,"wall_ts_ms":1789176630862,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0340","position":{"x":-1800.0,"y":200.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630862,"virtual_time_s":6673.617732,"measure_result":"no_signal"}}
{"event":"action","seq":341,"wall_ts_ms":1789176630862,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0341","position":{"x":-1800.0,"y":200.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630862,"virtual_time_s":6679.617732,"measure_result":"no_signal"}}
{"event":"action","seq":342,"wall_ts_ms":1789176630863,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0342","position":{"x":-1800.0,"y":200.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630863,"virtual_time_s":6685.617732,"measure_result":"no_signal"}}
{"event":"action","seq":343,"wall_ts_ms":1789176630863,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0343","position":{"x":-1800.0,"y":200.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630863,"virtual_time_s":6691.617732,"measure_result":"no_signal"}}
{"event":"action","seq":344,"wall_ts_ms":1789176630863,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0344","position":{"x":-1800.0,"y":200.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630863,"virtual_time_s":6697.617732,"measure_result":"no_signal"}}
{"event":"action","seq":345,"wall_ts_ms":1789176630864,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0345","position":{"x":-1800.0,"y":200.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630864,"virtual_time_s":6703.617732,"measure_result":"no_signal"}}
{"event":"action","seq":346,"wall_ts_ms":1789176630864,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0346","position":{"x":-1800.0,"y":200.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630864,"virtual_time_s":6709.617732,"measure_result":"no_signal"}}
{"event":"action","seq":347,"wall_ts_ms":1789176630865,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0347","position":{"x":-2200.0,"y":600.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630865,"virtual_time_s":6827.754817,"measure_result":"no_signal"}}
{"event":"action","seq":348,"wall_ts_ms":1789176630865,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0348","position":{"x":-2200.0,"y":600.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630865,"virtual_time_s":6833.754817,"measure_result":"no_signal"}}
{"event":"action","seq":349,"wall_ts_ms":1789176630866,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0349","position":{"x":-2200.0,"y":600.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630866,"virtual_time_s":6839.754817,"measure_result":"no_signal"}}
{"event":"action","seq":350,"wall_ts_ms":1789176630866,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0350","position":{"x":-2200.0,"y":600.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630866,"virtual_time_s":6845.754817,"measure_result":"no_signal"}}
{"event":"action","seq":351,"wall_ts_ms":1789176630867,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0351","position":{"x":-2200.0,"y":600.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630867,"virtual_time_s":6851.754817,"measure_result":"no_signal"}}
{"event":"action","seq":352,"wall_ts_ms":1789176630867,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0352","position":{"x":-2200.0,"y":600.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630867,"virtual_time_s":6857.754817,"measure_result":"no_signal"}}
{"event":"action","seq":353,"wall_ts_ms":1789176630868,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0353","position":{"x":-2200.0,"y":600.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630868,"virtual_time_s":6863.754817,"measure_result":"no_signal"}}
{"event":"action","seq":354,"wall_ts_ms":1789176630868,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0354","position":{"x":-2200.0,"y":600.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630868,"virtual_time_s":6869.754817,"measure_result":"no_signal"}}
{"event":"action","seq":355,"wall_ts_ms":1789176630869,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0355","position":{"x":-1200.0,"y":800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630869,"virtual_time_s":7078.715598,"measure_result":"no_signal"}}
{"event":"action","seq":356,"wall_ts_ms":1789176630869,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0356","position":{"x":-1200.0,"y":800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630869,"virtual_time_s":7084.715598,"measure_result":"no_signal"}}
{"event":"action","seq":357,"wall_ts_ms":1789176630870,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0357","position":{"x":-1200.0,"y":800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630870,"virtual_time_s":7090.715598,"measure_result":"no_signal"}}
{"event":"action","seq":358,"wall_ts_ms":1789176630870,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0358","position":{"x":-1200.0,"y":800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630870,"virtual_time_s":7096.715598,"measure_result":"no_signal"}}
{"event":"action","seq":359,"wall_ts_ms":1789176630870,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0359","position":{"x":-1200.0,"y":800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630870,"virtual_time_s":7102.715598,"measure_result":"no_signal"}}
{"event":"action","seq":360,"wall_ts_ms":1789176630871,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0360","position":{"x":-1200.0,"y":800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630871,"virtual_time_s":7108.715598,"measure_result":"no_signal"}}
{"event":"action","seq":361,"wall_ts_ms":1789176630871,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0361","position":{"x":-1200.0,"y":800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630871,"virtual_time_s":7114.715598,"measure_result":"no_signal"}}
{"event":"action","seq":362,"wall_ts_ms":1789176630872,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0362","position":{"x":-1200.0,"y":800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630872,"virtual_time_s":7120.715598,"measure_result":"no_signal"}}
{"event":"action","seq":363,"wall_ts_ms":1789176630872,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0363","position":{"x":-1000.0,"y":1000.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630872,"virtual_time_s":7182.28414,"measure_result":"no_signal"}}
{"event":"action","seq":364,"wall_ts_ms":1789176630873,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0364","position":{"x":-1000.0,"y":1000.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630873,"virtual_time_s":7188.28414,"measure_result":"no_signal"}}
{"event":"action","seq":365,"wall_ts_ms":1789176630873,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0365","position":{"x":-1000.0,"y":1000.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630873,"virtual_time_s":7194.28414,"measure_result":"no_signal"}}
{"event":"action","seq":366,"wall_ts_ms":1789176630874,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0366","position":{"x":-1000.0,"y":1000.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630874,"virtual_time_s":7200.28414,"measure_result":"no_signal"}}
{"event":"action","seq":367,"wall_ts_ms":1789176630874,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0367","position":{"x":-1000.0,"y":1000.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630874,"virtual_time_s":7206.28414,"measure_result":"no_signal"}}
{"event":"action","seq":368,"wall_ts_ms":1789176630875,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0368","position":{"x":-1000.0,"y":1000.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630875,"virtual_time_s":7212.28414,"measure_result":"no_signal"}}
{"event":"action","seq":369,"wall_ts_ms":1789176630875,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0369","position":{"x":-1000.0,"y":1000.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630875,"virtual_time_s":7218.28414,"measure_result":"no_signal"}}
{"event":"action","seq":370,"wall_ts_ms":1789176630876,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0370","position":{"x":-1000.0,"y":1000.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630876,"virtual_time_s":7224.28414,"measure_result":"no_signal"}}
{"event":"action","seq":371,"wall_ts_ms":1789176630876,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0371","position":{"x":-1400.0,"y":1400.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630876,"virtual_time_s":7342.421225,"measure_result":"no_signal"}}
{"event":"action","seq":372,"wall_ts_ms":1789176630877,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0372","position":{"x":-1400.0,"y":1400.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630877,"virtual_time_s":7348.421225,"measure_result":"no_signal"}}
{"event":"action","seq":373,"wall_ts_ms":1789176630877,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0373","position":{"x":-1400.0,"y":1400.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630877,"virtual_time_s":7354.421225,"measure_result":"no_signal"}}
{"event":"action","seq":374,"wall_ts_ms":1789176630877,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0374","position":{"x":-1400.0,"y":1400.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630877,"virtual_time_s":7360.421225,"measure_result":"no_signal"}}
{"event":"action","seq":375,"wall_ts_ms":1789176630878,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0375","position":{"x":-1400.0,"y":1400.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630878,"virtual_time_s":7366.421225,"measure_result":"no_signal"}}
{"event":"action","seq":376,"wall_ts_ms":1789176630878,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0376","position":{"x":-1400.0,"y":1400.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630878,"virtual_time_s":7372.421225,"measure_result":"no_signal"}}
{"event":"action","seq":377,"wall_ts_ms":1789176630879,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0377","position":{"x":-1400.0,"y":1400.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630879,"virtual_time_s":7378.421225,"measure_result":"no_signal"}}
{"event":"action","seq":378,"wall_ts_ms":1789176630879,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0378","position":{"x":-1400.0,"y":1400.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630879,"virtual_time_s":7384.421225,"measure_result":"no_signal"}}
{"event":"action","seq":379,"wall_ts_ms":1789176630880,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0379","position":{"x":-1200.0,"y":1800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630880,"virtual_time_s":7478.863944,"measure_result":"no_signal"}}
{"event":"action","seq":380,"wall_ts_ms":1789176630880,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0380","position":{"x":-1200.0,"y":1800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630880,"virtual_time_s":7484.863944,"measure_result":"no_signal"}}
{"event":"action","seq":381,"wall_ts_ms":1789176630880,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0381","position":{"x":-1200.0,"y":1800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630880,"virtual_time_s":7490.863944,"measure_result":"no_signal"}}
{"event":"action","seq":382,"wall_ts_ms":1789176630881,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0382","position":{"x":-1200.0,"y":1800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630881,"virtual_time_s":7496.863944,"measure_result":"no_signal"}}
{"event":"action","seq":383,"wall_ts_ms":1789176630881,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0383","position":{"x":-1200.0,"y":1800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630881,"virtual_time_s":7502.863944,"measure_result":"no_signal"}}
{"event":"action","seq":384,"wall_ts_ms":1789176630882,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0384","position":{"x":-1200.0,"y":1800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630882,"virtual_time_s":7508.863944,"measure_result":"no_signal"}}
{"event":"action","seq":385,"wall_ts_ms":1789176630882,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0385","position":{"x":-1200.0,"y":1800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630882,"virtual_time_s":7514.863944,"measure_result":"no_signal"}}
{"event":"action","seq":386,"wall_ts_ms":1789176630883,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0386","position":{"x":-1200.0,"y":1800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630883,"virtual_time_s":7520.863944,"measure_result":"no_signal"}}
{"event":"action","seq":387,"wall_ts_ms":1789176630883,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0387","position":{"x":1200.0,"y":1600.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630883,"virtual_time_s":8007.527727,"measure_result":"no_signal"}}
{"event":"action","seq":388,"wall_ts_ms":1789176630884,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0388","position":{"x":1200.0,"y":1600.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630884,"virtual_time_s":8013.527727,"measure_result":"no_signal"}}
{"event":"action","seq":389,"wall_ts_ms":1789176630884,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0389","position":{"x":1200.0,"y":1600.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630884,"virtual_time_s":8019.527727,"measure_result":"no_signal"}}
{"event":"action","seq":390,"wall_ts_ms":1789176630885,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0390","position":{"x":1200.0,"y":1600.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630885,"virtual_time_s":8025.527727,"measure_result":"no_signal"}}
{"event":"action","seq":391,"wall_ts_ms":1789176630885,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0391","position":{"x":1200.0,"y":1600.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630885,"virtual_time_s":8031.527727,"measure_result":"no_signal"}}
{"event":"action","seq":392,"wall_ts_ms":1789176630886,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0392","position":{"x":1200.0,"y":1600.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630886,"virtual_time_s":8037.527727,"measure_result":"no_signal"}}
{"event":"action","seq":393,"wall_ts_ms":1789176630886,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0393","position":{"x":1200.0,"y":1600.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630886,"virtual_time_s":8043.527727,"measure_result":"no_signal"}}
{"event":"action","seq":394,"wall_ts_ms":1789176630887,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0394","position":{"x":1200.0,"y":1600.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630887,"virtual_time_s":8049.527727,"measure_result":"no_signal"}}
{"event":"action","seq":395,"wall_ts_ms":1789176630887,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0395","position":{"x":1800.0,"y":600.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630887,"virtual_time_s":8287.765803,"measure_result":"no_signal"}}
{"event":"action","seq":396,"wall_ts_ms":1789176630888,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0396","position":{"x":1800.0,"y":600.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630888,"virtual_time_s":8293.765803,"measure_result":"no_signal"}}
{"event":"action","seq":397,"wall_ts_ms":1789176630888,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0397","position":{"x":1800.0,"y":600.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630888,"virtual_time_s":8299.765803,"measure_result":"no_signal"}}
{"event":"action","seq":398,"wall_ts_ms":1789176630889,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0398","position":{"x":1800.0,"y":600.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630888,"virtual_time_s":8305.765803,"measure_result":"no_signal"}}
{"event":"action","seq":399,"wall_ts_ms":1789176630889,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0399","position":{"x":1800.0,"y":600.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630889,"virtual_time_s":8311.765803,"measure_result":"no_signal"}}
{"event":"action","seq":400,"wall_ts_ms":1789176630889,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0400","position":{"x":1800.0,"y":600.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630889,"virtual_time_s":8317.765803,"measure_result":"no_signal"}}
{"event":"action","seq":401,"wall_ts_ms":1789176630890,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0401","position":{"x":1800.0,"y":600.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630890,"virtual_time_s":8323.765803,"measure_result":"no_signal"}}
{"event":"action","seq":402,"wall_ts_ms":1789176630890,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0402","position":{"x":1800.0,"y":600.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630890,"virtual_time_s":8329.765803,"measure_result":"no_signal"}}
{"event":"action","seq":403,"wall_ts_ms":1789176630891,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0403","position":{"x":1800.0,"y":0.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630891,"virtual_time_s":8454.765803,"measure_result":"no_signal"}}
{"event":"action","seq":404,"wall_ts_ms":1789176630891,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0404","position":{"x":1800.0,"y":0.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630891,"virtual_time_s":8460.765803,"measure_result":"no_signal"}}
{"event":"action","seq":405,"wall_ts_ms":1789176630892,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0405","position":{"x":1800.0,"y":0.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630892,"virtual_time_s":8466.765803,"measure_result":"no_signal"}}
{"event":"action","seq":406,"wall_ts_ms":1789176630892,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0406","position":{"x":1800.0,"y":0.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630892,"virtual_time_s":8472.765803,"measure_result":"no_signal"}}
{"event":"action","seq":407,"wall_ts_ms":1789176630893,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0407","position":{"x":1800.0,"y":0.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630893,"virtual_time_s":8478.765803,"measure_result":"no_signal"}}
{"event":"action","seq":408,"wall_ts_ms":1789176630893,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0408","position":{"x":1800.0,"y":0.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630893,"virtual_time_s":8484.765803,"measure_result":"no_signal"}}
{"event":"action","seq":409,"wall_ts_ms":1789176630894,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0409","position":{"x":1800.0,"y":0.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630894,"virtual_time_s":8490.765803,"measure_result":"no_signal"}}
{"event":"action","seq":410,"wall_ts_ms":1789176630894,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0410","position":{"x":1800.0,"y":0.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630894,"virtual_time_s":8496.765803,"measure_result":"no_signal"}}
{"event":"action","seq":411,"wall_ts_ms":1789176630895,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0411","position":{"x":1800.0,"y":-800.0},"channel":20},"response":{"accepted":true,"real_timestamp_ms":1789176630895,"virtual_time_s":8661.765803,"measure_result":"no_signal"}}
{"event":"action","seq":412,"wall_ts_ms":1789176630895,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0412","position":{"x":1800.0,"y":-800.0},"channel":3},"response":{"accepted":true,"real_timestamp_ms":1789176630895,"virtual_time_s":8667.765803,"measure_result":"no_signal"}}
{"event":"action","seq":413,"wall_ts_ms":1789176630896,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0413","position":{"x":1800.0,"y":-800.0},"channel":6},"response":{"accepted":true,"real_timestamp_ms":1789176630896,"virtual_time_s":8673.765803,"measure_result":"no_signal"}}
{"event":"action","seq":414,"wall_ts_ms":1789176630896,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0414","position":{"x":1800.0,"y":-800.0},"channel":8},"response":{"accepted":true,"real_timestamp_ms":1789176630896,"virtual_time_s":8679.765803,"measure_result":"no_signal"}}
{"event":"action","seq":415,"wall_ts_ms":1789176630896,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0415","position":{"x":1800.0,"y":-800.0},"channel":9},"response":{"accepted":true,"real_timestamp_ms":1789176630896,"virtual_time_s":8685.765803,"measure_result":"no_signal"}}
{"event":"action","seq":416,"wall_ts_ms":1789176630897,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0416","position":{"x":1800.0,"y":-800.0},"channel":14},"response":{"accepted":true,"real_timestamp_ms":1789176630897,"virtual_time_s":8691.765803,"measure_result":"no_signal"}}
{"event":"action","seq":417,"wall_ts_ms":1789176630897,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0417","position":{"x":1800.0,"y":-800.0},"channel":17},"response":{"accepted":true,"real_timestamp_ms":1789176630897,"virtual_time_s":8697.765803,"measure_result":"no_signal"}}
{"event":"action","seq":418,"wall_ts_ms":1789176630898,"method":"POST","path":"/measure","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0418","position":{"x":1800.0,"y":-800.0},"channel":19},"response":{"accepted":true,"real_timestamp_ms":1789176630898,"virtual_time_s":8703.765803,"measure_result":"no_signal"}}
{"event":"action","seq":419,"wall_ts_ms":1789176630898,"method":"POST","path":"/exit","status":200,"request":{"arena_id":"default","robot_id":"1","request_id":"2d8c15ad42ce-0419"},"response":{"accepted":true,"real_timestamp_ms":1789176630898,"virtual_time_s":8703.765803,"exit_reason":"user_exit"}}
{"event":"session_end","reason":"user_exit","virtual_time_s":8703.765803,"real_elapsed_s":8.459184,"request_count":419,"cleared_count":12}
-4
View File
@@ -1,4 +0,0 @@
# logs/
正式测试/演练导出的 JSONL 与汇总日志放置目录。本地 P1 训练/评测日志实际写入
`output/hrl/...`;本目录用于最终支撑材料归档,不修改文件名。
-4
View File
@@ -1,4 +0,0 @@
# models/
最终冻结模型归档目录。训练脚本默认把模型写到 `--model` 指定路径;
P1 smoke 产物见 `output/hrl/p1-smoke-time/`。正式提交前把冻结模型复制到本目录并保留同名 `.json` 元数据。
+118 -23
View File
@@ -1,29 +1,124 @@
# project/ 薄兼容层
# 1-4 问「最优实现 / 基线实现」对比框架
题目 Prompt 要求 `project/` 目录树;本仓库的真实算法保持唯一一份,
位于 `src/mcm26b`、`scripts/`。本目录只做 re-export/转发,不复制实现。
本目录**不是**比赛运行时代码,而是把四问的生产实现与独立基线放在同一口径下
配对对比、生成可写进论文的"算法对比"证据。运行时代码仍只有 `src/mcm26b`,
`project/` 只依赖它和测试侧内存回环,不反向污染求解入口。
| Prompt 路径 | 真实实现 |
|---|---|
| `env/simulator_client.py` | `src/mcm26b/protocol/client.py` |
| `env/local_env.py` | `src/mcm26b/hrl/hierarchical_env.py`, `low_level_env.py` |
| `env/particle_filter.py` | `src/mcm26b/particles.py` |
| `policies/high_level_ppo.py` | `src/mcm26b/hrl/policy.py` |
| `policies/low_level_ppo.py` | `src/mcm26b/hrl/policy.py`, `low_level_env.py` |
| `train/curriculum.py` | `src/mcm26b/hrl/curriculum.py` |
| `train/domain_randomization.py` | `src/mcm26b/hrl/curriculum.py` + 配置包装 |
| `eval/evaluate.py` | `scripts/benchmark_hrl.py` |
| `eval/ablation.py` | `scripts/ablate_hrl.py`(P2) |
| `baselines/heuristic.py` | `src/mcm26b/planner/hrl_loop.py` 启发式降级 |
| `baselines/end_to_end_ppo.py` | 显式未实现;单源局部 PPO 不冒充 E2E |
## 1. 设计原则
使用示例:
| 角色 | 含义 | 约束 |
| --- | --- | --- |
| **最优实现** | 复用 `src/mcm26b` 中已由测试固化的生产实现 | 不复制算法,只做 I/O 适配 |
| **基线实现** | 同题下更朴素、但能独立跑通的对照 | 不得共享最优实现的关键步骤 |
| **独立参考** | 与分析算法正交的数值/枚举标准 | 用于判定谁对谁错,而非自证 |
```python
from project.env.local_env import make_local_env
env = make_local_env(problem=3, stage=1, seed=7)
obs, info = env.reset(seed=7)
- 第三、四问走 `LocalSimulator` 内存回环,与官方 HTTP 协议同一边界;
真值只在评测机侧,策略端只看响应,因此"全清率/缺席误判"是可信的。
- 闭环有效性判定沿用项目口径:**全清 ∧ 无缺席误判 ∧ 正常 `/exit` ∧ 零异常
∧ 逐微秒计时复算一致**,任何一项不满足该局记为无效,失败不静默丢样本。
- 所有对比都按 `scene_id` 配对,汇总同时给均值、中位、最大与相对基线的
配对变化,避免"均值好看但逐局更差"。
## 2. 目录结构与职责
```text
project/
├── README.md 本文件
├── common.py 公共层:方法描述、指标聚合、结果落盘、闭环装配
├── run.py 统一入口:一次跑完四问并生成 results/
├── results/ 自动生成:q1.md/json … q4.md/json + summary.md
├── q1/ 问题一:交会定位区域直径与直径圆覆盖
│ ├── optimal.py 最优:半平面交 + 顶点对精确直径 + Welzl MEC + 覆盖反例
│ ├── baseline.py 基线:网格采样 + 轴对齐包围盒对角线代理
│ ├── reference.py 参考:大框 Sutherland–Hodgman 半平面裁剪 + 精确直径/MEC
│ ├── cases.py 固定示例(examples/q1)+ 随机交会算例
│ └── compare.py 同案配对:状态/直径/覆盖/耗时
├── q2/ 问题二:第二检测点选择
│ ├── optimal.py 最优:保证接收盘内最小最坏后验半径(生产选点器)
│ ├── baseline.py 基线:垂直 1000 m 最大交会角 / 候选集 MEC 圆心
│ ├── reference.py 参考:保证接收盘内稠密网格枚举
│ ├── region.py K1 = Ω ∩ 角域 ∩ B(s,1500) 统一构造
│ ├── cases.py 随机首次示向度算例
│ └── compare.py 统一评估器:保证接收、最坏后验、移动代价
├── q3/ 问题三:全向源闭环
│ ├── optimal.py 最优:bayes(粒子滤波 + 信息增益 + 滚动 2-opt)
│ ├── baseline.py 基线:grid(49 点网格)/ seven(七点批量)
│ └── compare.py 冻结基准集 core 配对对比
└── q4/ 问题四:含定向源闭环
├── optimal.py 最优:directional(联合信念 + 后备清除 + 定向覆盖计划)
├── baseline.py 基线:把问题三策略直接搬用(bayes / grid)
└── compare.py 冻结基准集 core+boundary 配对对比
```
P1 当前交付:`benchmark_hrl.py`、`train_hrl_high.py`、CLI `--strategy hrl`、
`--q4-strategy hrl`。P2 的 BC/Optuna/消融在 smoke 通过后另开。
## 3. 各问对比设计
### 问题一(`q1/`)
- **最优**:`mcm26b.geometry.localization.solve`,半平面交求凸多边形,顶点对
枚举直径,Welzl 最小包围圆,并输出直径圆覆盖判断、圆外顶点与最大超出距离。
- **基线**:固定大框网格采样,直径取**包围盒对角线**、覆盖取"包围盒中心 +
代理直径圆"。它在斜/细长区域上系统性高估直径,并对任意包围盒都几乎恒判覆盖。
- **参考**:从 ±1e7 m 大框出发逐半平面 Sutherland–Hodgman 裁剪,独立实现
直径暴力枚举与 1/2/3 点支撑圆暴力最小包围圆。与最优实现共享 0 个内部步骤。
- 指标:状态判定、直径绝对误差、直径圆覆盖准确率、运行耗时。
### 问题二(`q2/`)
- 候选集 `K1 = Ω ∩ W(s,θ±δ_eff) ∩ B(s,1500)`,三个方法共用同一次构造。
- **最优**:保证接收盘 `B(MEC 圆心, 1000−ρ)` 内环形采样,最小化"目标边界点 ×
读数区间端点"的最坏后验半径,移动时间同分决胜;保证接收严格,采样是启发式。
- **基线**:① 垂直首次示向度 1000 m 的"90° 交会点"——忽略接收保证,真源在
角域远端时必然 `no_signal`;② 候选集 MEC 圆心——保证接收但交会角可能最差。
- **参考**:保证接收盘内 9×9 网格枚举同一目标函数,检验生产采样接近网格最优。
- 指标:保证接收率、最坏后验包围半径、收缩量、移动时间。
### 问题三(`q3/`)
- **最优** `bayes`:网格粒子滤波幸存集 + 期望信息增益选点 + 滚动 2-opt 任务排序。
- **基线** `grid`:49 点(700 m 步长)网格发现 + 就近服务;`seven`:七点解析
覆盖 + 同站批量扫频,作为"覆盖证明 + 批量调度"的中间对照。
- 冻结基准集 `harness.suites`(种子/源数版本化),逐局校验全清与计时复算。
- 指标:全清率、均值/中位/最大虚拟时间、检测数、请求数、位移、墙钟。
### 问题四(`q4/`)
- **最优** `directional`:31 点定向覆盖计划 + 朝向遮挡推理 + (位置×朝向) 联合
信念 + ≤20 m 有限圆盘后备清除。
- **基线**:把问题三策略原样搬用——`bayes` 的七站全向缺席证明会把朝外定向源
误判为 ABSENT("快而错");`grid` 的 49 点覆盖对定向源发现完备,但无后备清除,
定位停滞只能停在 DETECTED("稳而不全")。
- 冻结基准集 `core+boundary`,其中 `boundary` 场景全部为背离圆心发射的边界定向
源,是最不利工况。
- 指标:全清率、缺席误判数、虚拟时间、后备清除次数、墙钟。
## 4. 运行方式
```bash
uv run python -m project.run # 四问全部,写入 project/results/
uv run python -m project.run --question 1 # 只跑问题一
uv run python -m project.run --quick # 缩小随机算例/基准集规模
```
> `project/` 用到 `numpy`(网格参考解)。它随 dev 依赖组(optuna)安装;
> 只跑正式求解入口 `mcm26b` 不需要它。
## 5. 结果文件
| 文件 | 内容 |
| --- | --- |
| `results/q1.md` / `q1.json` | 固定示例 + 随机算例的逐案明细与汇总 |
| `results/q2.md` / `q2.json` | 逐案第二点位置、保证接收、最坏后验与汇总 |
| `results/q3.md` / `q3.json` | 冻结基准集逐场景明细、逐方法汇总、配对变化 |
| `results/q4.md` / `q4.json` | core+boundary 逐场景明细与汇总 |
| `results/summary.md` | 四问核心指标总览 + 方法映射 + 目录结构 |
## 6. 口径与边界(写论文时必须一并声明)
- 问题一参考解与最优实现都是精确算法;固定示例的解析期望另有
`tests/test_geometry*.py` 固化,本框架在其上补齐"朴素基线错在哪"。
- 问题二"最坏后验半径"是**对候选集外包多边形的启发式评估**,不是连续问题
的全局最优证明;生产实现与参考网格共享该目标函数,只比较搜索质量。
- 问题三、四的随机分布(源位置均匀、误差场逐点固定等)是**测试假设**,
题面未规定;正式成绩以官方模拟器演练/正式测试为准。
- 基线不是稻草人:`q2` 的 MEC 圆心、`q3` 的 `seven`、`q4` 的 `grid` 都是
能独立跑通、在部分场景有效的真实方法;它们暴露的是"缺了哪一步"。
+16 -2
View File
@@ -1,4 +1,18 @@
"""题目 Prompt 所需目录树的薄兼容层。
"""1-4 问"最优实现 / 基线实现"统一对比框架(非运行时依赖,仅用于分析与论文)。
真实实现仍位于 ``src/mcm26b``;本包只做 re-export / CLI 转发,避免两份算法逻辑。
本包不改动正式求解入口 ``mcm26b``,只做三层组织:
- ``project.q1`` … ``project.q4``:四个问题各自的
``optimal.py``(生产最优实现,直接复用 ``mcm26b`` 内核)、
``baseline.py``(朴素基线,参照组)、``compare.py``(同题配对对比);
- ``project.common``:方法描述、指标聚合、结果落盘、离线闭环装配;
- ``project.run``:统一入口,一次跑完四问并生成 ``project/results/``。
运行方式(仓库根目录)::
uv run python -m project.run # 四问全部
uv run python -m project.run --question 3 # 只跑第三问
uv run python -m project.run --quick # 缩小随机场景数
"""
__all__ = ["common"]
-3
View File
@@ -1,3 +0,0 @@
from .heuristic import HeuristicHRL, run_heuristic
__all__ = ["HeuristicHRL", "run_heuristic"]
-16
View File
@@ -1,16 +0,0 @@
"""端到端 PPO 基线占位。
按本轮确认:当前只交付局部 PPO 基线;raw-observation/raw-action 的真正
端到端 PPO 不在 P0+P1 范围内,因此显式标记未实现,避免把单源局部选点
PPO 误称为端到端 baseline。
"""
from __future__ import annotations
def train_end_to_end_ppo(*args, **kwargs):
raise NotImplementedError(
"本轮只交付局部 PPO 基线;真正的端到端 PPO 基线标记为未实现,"
"需单独立项定义原始观测、动作与安全执行边界。")
__all__ = ["train_end_to_end_ppo"]
-16
View File
@@ -1,16 +0,0 @@
"""兼容入口:信息增益/TSP/覆盖规则 + 高层启发式调度。"""
from mcm26b.planner.bayes_loop import BayesLoop
from mcm26b.planner.hrl_loop import HRLLoop
def HeuristicHRL(*args, **kwargs): # pylint: disable=invalid-name # 兼容入口保留题面公开名
"""返回无模型的高层 HRL 闭环(heuristic_action 降级路径)。"""
kwargs.setdefault("high_policy", None)
return HRLLoop(*args, **kwargs)
def run_heuristic(*args, **kwargs):
return HeuristicHRL(*args, **kwargs).run()
__all__ = ["HeuristicHRL", "run_heuristic", "BayesLoop", "HRLLoop"]
+308
View File
@@ -0,0 +1,308 @@
"""对比框架公共层:方法描述、指标聚合、结果落盘、离线闭环装配。
设计口径
--------
- **最优实现** = 复用 ``src/mcm26b`` 中已由测试固化的生产实现;
- **基线实现** = 同题下更朴素但可独立运行的参照实现(不得共享最优实现的
关键步骤),用于量化"生产实现好在哪里、差多少";
- **参考解** = 与分析算法相互独立的数值/枚举标准,用来判定谁对谁错。
第三、四问是闭环问题,统一走 ``LocalSimulator`` 内存回环(与官方 HTTP
协议同一边界),真值只在评测机侧,策略端只看响应。
"""
from __future__ import annotations
import json
import statistics
from dataclasses import dataclass, replace
from pathlib import Path
from time import perf_counter
from mcm26b.config import ProblemConfig
from mcm26b.evaluation import recompute_virtual_time
from mcm26b.harness import LocalSimTransport, LocalSimulator
from mcm26b.protocol.client import SimulatorClient
ROOT = Path(__file__).resolve().parents[1]
RESULTS_DIR = Path(__file__).resolve().parent / "results"
@dataclass(frozen=True)
class Method:
"""一个可对比方法:key 用作图表列名,kind 用于区分最优/基线/参考。"""
key: str
name: str
kind: str # optimal | baseline | reference
note: str = ""
def problem_config(*, persistent_search: bool = False,
margin_deg: float | None = None) -> ProblemConfig:
"""对比口径配置:默认关闭"扫到限时"的持续复扫(对齐首次找全证明)。"""
base = ProblemConfig()
kwargs: dict = {"persistent_search": persistent_search}
if margin_deg is not None:
kwargs["bearing_rounding_margin_deg"] = margin_deg
return replace(base, search=replace(base.search, **kwargs))
# ---------------------------------------------------------------- 结果落盘
def write_json(path: Path, payload) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2,
allow_nan=False) + "\n", encoding="utf-8")
return path
def write_text(path: Path, text: str) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding="utf-8")
return path
# ---------------------------------------------------------------- 指标工具
def mean(values) -> float:
values = list(values)
return round(statistics.fmean(values), 4) if values else 0.0
def median(values) -> float:
values = list(values)
return round(statistics.median(values), 4) if values else 0.0
def ratio(hit: int, total: int) -> float:
return round(hit / total, 4) if total else 0.0
def relative_change(value: float, reference: float) -> float | None:
if reference == 0:
return None
return round(value / reference - 1.0, 4)
def markdown_table(headers: list[str], rows: list[list[str]]) -> str:
lines = ["| " + " | ".join(headers) + " |",
"| " + " | ".join("---" for _ in headers) + " |"]
for row in rows:
lines.append("| " + " | ".join(str(cell) for cell in row) + " |")
return "\n".join(lines)
def _num(value, digits: int = 2) -> str:
if value is None:
return "—"
if isinstance(value, bool):
return "✔" if value else "✘"
if isinstance(value, float):
return f"{value:.{digits}f}"
return str(value)
# ---------------------------------------------------------------- 第三/四问闭环
def run_loop_episode(loop_cls, scene_spec, config: ProblemConfig) -> dict:
"""在冻结场景上跑一局闭环,返回逐局指标行(与 ``scripts/run_suite.py`` 同口径)。"""
sources = scene_spec.sources(config) # 真值:仅测试端可见
simulator = LocalSimulator(sources, robot_id="COMPARE", config=config,
error_seed=scene_spec.error_seed)
client = SimulatorClient("COMPARE", config=config,
transport=LocalSimTransport(simulator))
start = perf_counter()
loop = loop_cls(client, config)
summary = loop.run()
compute_wall_s = perf_counter() - start
report = recompute_virtual_time(client.log.action_events())
truth = sorted(source.channel for source in sources)
cleared = sorted(summary["cleared_channels"])
absent = sorted(summary["absent_channels"])
misjudged = sorted(set(absent) & set(truth))
valid = (cleared == truth and not misjudged
and summary["exit_reason"] == "user_exit"
and not summary["anomalies"]
and not report["mismatches"])
return {
"scene_id": scene_spec.scene_id,
"problem": scene_spec.problem,
"kind": scene_spec.kind,
"sources": len(truth),
"directional": scene_spec.directional,
"cleared": len(cleared),
"cleared_ratio": ratio(len(cleared), len(truth)),
"cleared_matches_truth": cleared == truth,
"absent_misjudged": len(misjudged),
"virtual_time_s": round(summary["virtual_time_s"], 3),
"accounted_virtual_time_s": (
round(summary["accounted_virtual_time_s"], 3)
if summary.get("accounted_virtual_time_s") is not None else None),
"measures": summary["measures"],
"clears": summary["clears"],
"clear_success": summary["clear_success"],
"total_requests": summary["total_requests"],
"move_distance_m": round(summary["move_distance_m"], 2),
"fallback_clear_attempts": summary.get("fallback_clear_attempts", 0),
"coverage_points": summary.get("coverage_points", 0),
"stop_reason": summary["stop_reason"],
"exit_reason": summary["exit_reason"],
"anomaly_count": len(summary["anomalies"]),
"virtual_recompute_mismatches": len(report["mismatches"]),
"compute_wall_s": round(compute_wall_s, 3),
"valid": valid,
}
# 第三/四问统一汇报列(顺序即 Markdown 列序)
EPISODE_COLUMNS = (
"cleared_ratio", "cleared_matches_truth", "absent_misjudged",
"virtual_time_s", "measures", "total_requests", "move_distance_m",
"fallback_clear_attempts", "compute_wall_s", "valid",
)
def aggregate_episodes(rows: list[dict], labels: list[str],
base_label: str | None = None) -> dict:
"""逐方法汇总 + 相对基线的配对变化(按 scene_id 对齐)。"""
summary: dict[str, dict] = {}
for label in labels:
part = [row for row in rows if row["variant"] == label]
if not part:
continue
summary[label] = {
"episodes": len(part),
"valid_episodes": sum(1 for row in part if row["valid"]),
"cleared_ratio_mean": mean(row["cleared_ratio"] for row in part),
"cleared_matches_truth": sum(1 for row in part
if row["cleared_matches_truth"]),
"absent_misjudged_total": sum(row["absent_misjudged"] for row in part),
"virtual_time_mean_s": mean(row["virtual_time_s"] for row in part),
"virtual_time_median_s": median(row["virtual_time_s"] for row in part),
"virtual_time_max_s": round(max(row["virtual_time_s"] for row in part), 3),
"measures_mean": mean(row["measures"] for row in part),
"total_requests_mean": mean(row["total_requests"] for row in part),
"move_distance_mean_m": mean(row["move_distance_m"] for row in part),
"fallback_clear_attempts_mean": mean(
row["fallback_clear_attempts"] for row in part),
"compute_wall_mean_s": mean(row["compute_wall_s"] for row in part),
}
paired: dict[str, dict] = {}
if base_label and len(labels) > 1:
base_rows = {row["scene_id"]: row for row in rows
if row["variant"] == base_label}
for label in labels:
if label == base_label:
continue
deltas, faster, valid_pairs = [], 0, 0
for row in rows:
if row["variant"] != label or row["scene_id"] not in base_rows:
continue
base_row = base_rows[row["scene_id"]]
reference = base_row["virtual_time_s"]
deltas.append(relative_change(row["virtual_time_s"], reference))
if not (row["valid"] and base_row["valid"]):
continue
valid_pairs += 1
if row["virtual_time_s"] < reference:
faster += 1
paired[f"{label}_vs_{base_label}"] = {
"mean_relative_change": mean(d for d in deltas if d is not None),
"median_relative_change": median(d for d in deltas if d is not None),
"faster_scenes": faster,
"compared": len(deltas),
"both_valid_scenes": valid_pairs,
}
return {"variants": summary, "paired": paired}
def episodes_markdown(title: str, rows: list[dict], labels: list[str],
base_label: str | None = None) -> str:
"""逐场景明细 + 汇总表。"""
headers = ["scene", "sources", "variant", "cleared", "T(s)", "检测",
"请求", "位移(m)", "后备清除", "墙钟(s)", "有效"]
body = []
for row in sorted(rows, key=lambda r: (r["scene_id"], labels.index(r["variant"]))):
body.append([
row["scene_id"], row["sources"], row["variant"],
f"{row['cleared']}/{row['sources']}",
_num(row["virtual_time_s"], 1), row["measures"],
row["total_requests"], _num(row["move_distance_m"], 1),
row["fallback_clear_attempts"], _num(row["compute_wall_s"], 2),
_num(row["valid"]),
])
text = [f"# {title}", "", "## 逐场景明细", "",
markdown_table(headers, body), "", "## 逐方法汇总", ""]
agg = aggregate_episodes(rows, labels, base_label)
agg_headers = ["方法", "有效局", "全清率", "全清对数", "缺席误判",
"T 均值(s)", "T 中位(s)", "T 最大(s)", "检测均值",
"请求均值", "位移均值(m)", "后备清除均值", "墙钟均值(s)"]
agg_rows = []
for label in labels:
s = agg["variants"].get(label)
if not s:
continue
agg_rows.append([
label, f"{s['valid_episodes']}/{s['episodes']}",
_num(s["cleared_ratio_mean"]), s["cleared_matches_truth"],
s["absent_misjudged_total"], _num(s["virtual_time_mean_s"], 1),
_num(s["virtual_time_median_s"], 1), _num(s["virtual_time_max_s"], 1),
_num(s["measures_mean"], 1), _num(s["total_requests_mean"], 1),
_num(s["move_distance_mean_m"], 1),
_num(s["fallback_clear_attempts_mean"], 2),
_num(s["compute_wall_mean_s"], 2),
])
text.append(markdown_table(agg_headers, agg_rows))
if agg["paired"]:
text += ["", "## 相对基线的配对变化(虚拟时间)", ""]
pair_rows = [[name, f"{v['mean_relative_change']*100:+.1f}%",
f"{v['median_relative_change']*100:+.1f}%",
f"{v['faster_scenes']}/{v['compared']}",
v["both_valid_scenes"]]
for name, v in agg["paired"].items()]
text.append(markdown_table(
["配对", "均值变化", "中位变化", "更快场景", "双方均有效"], pair_rows))
invalid = [name for name, value in agg["paired"].items()
if value["both_valid_scenes"] < value["compared"]]
if invalid:
text += ["",
"> 注:" + "、".join(invalid)
+ " 存在未通过有效性判定的配对;其虚拟时间仅作参考,"
"基线未完成全清任务时不构成「更快」证据"
"(以「双方均有效」列为准)。"]
return "\n".join(text) + "\n"
def json_safe(payload):
"""把 numpy 标量等转成 json 可写类型(防御式,非必需)。"""
return json.loads(json.dumps(payload, ensure_ascii=False, default=float))
# ---------------------------------------------------------------- 闭环批量执行
def execute_variants(scenes, variants, config: ProblemConfig) -> list[dict]:
"""对每个场景跑遍所有变体(串行;对比规模小,进程池收益有限且便于复现)。"""
rows = []
for scene in scenes:
for label, loop_cls in variants:
row = run_loop_episode(loop_cls, scene, config)
row["variant"] = label
rows.append(row)
return rows
def closed_loop_payload(question: int, suite_name: str, scenes, variants,
rows: list[dict], labels: list[str],
base_label: str, config: ProblemConfig) -> dict:
return {
"question": question,
"suite": suite_name,
"scenes": [scene.as_dict() for scene in scenes],
"variants": [{"label": label, "class": loop_cls.__name__}
for label, loop_cls in variants],
"config": {
"persistent_search": config.search.persistent_search,
"bearing_rounding_margin_deg": config.search.bearing_rounding_margin_deg,
"q4_coverage_plan": config.search.q4_coverage_plan,
},
"rows": rows,
"aggregate": aggregate_episodes(rows, labels, base_label),
}
-6
View File
@@ -1,6 +0,0 @@
from .simulator_client import SimulatorClient
from .local_env import HierarchicalEnv, LowLevelEnv, HRLReward, make_local_env
from .particle_filter import ChannelParticles
__all__ = ["SimulatorClient", "HierarchicalEnv", "LowLevelEnv", "HRLReward",
"make_local_env", "ChannelParticles"]
-22
View File
@@ -1,22 +0,0 @@
"""兼容入口:本地简化训练环境。
HierarchicalEnv 是高层宏动作环境;LowLevelEnv 是独立八方向导航环境。
本文件不复制实现,只转发 mcm26b.hrl 下的真实类。
"""
from mcm26b.hrl.hierarchical_env import HRLReward, HierarchicalEnv
from mcm26b.hrl.low_level_env import LowLevelEnv
__all__ = ["HierarchicalEnv", "LowLevelEnv", "HRLReward", "make_local_env"]
def make_local_env(*, problem: int = 3, stage: int = 4, seed: int | None = None,
fidelity: str = "production"):
"""按题目 Prompt 的四阶段编号创建训练环境。"""
from mcm26b.hrl.curriculum import STAGES
if not 1 <= int(stage) <= len(STAGES):
raise ValueError(f"stage 必须在 1..{len(STAGES)}")
env = HierarchicalEnv(problem=problem, stage=STAGES[int(stage) - 1],
fidelity=fidelity)
if seed is not None:
env.reset(seed=seed)
return env
-4
View File
@@ -1,4 +0,0 @@
"""兼容入口:逐频道网格粒子/幸存集。"""
from mcm26b.particles import ChannelParticles, angular_gap
__all__ = ["ChannelParticles", "angular_gap"]
-8
View File
@@ -1,8 +0,0 @@
"""兼容入口:真实类见 mcm26b.protocol.client。"""
from mcm26b.protocol.client import (ActionRejected, ClearOutcome, DeadlineExceeded,
ExitInfo, MeasureOutcome, ProtocolError,
ProtocolViolation, SimulatorClient)
__all__ = ["SimulatorClient", "MeasureOutcome", "ClearOutcome", "ExitInfo",
"ProtocolError", "ActionRejected", "ProtocolViolation",
"DeadlineExceeded"]
-4
View File
@@ -1,4 +0,0 @@
from .evaluate import run_benchmark
from .ablation import run_ablation
__all__ = ["run_benchmark", "run_ablation"]
-20
View File
@@ -1,20 +0,0 @@
"""兼容入口:调用 scripts/ablate_hrl.py(P2 后启用)。"""
from __future__ import annotations
import importlib.util
from pathlib import Path
def run_ablation(argv=None) -> int:
path = Path(__file__).resolve().parents[2] / "scripts" / "ablate_hrl.py"
if not path.exists():
raise NotImplementedError(
"scripts/ablate_hrl.py 尚未实现;P1 阶段只保证 benchmark/training/CLI。")
spec = importlib.util.spec_from_file_location("ablate_hrl_compat", path)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return int(module.main(argv))
__all__ = ["run_ablation"]
-17
View File
@@ -1,17 +0,0 @@
"""兼容入口:调用 scripts/benchmark_hrl.py。"""
from __future__ import annotations
import importlib.util
from pathlib import Path
def run_benchmark(argv=None) -> int:
path = Path(__file__).resolve().parents[2] / "scripts" / "benchmark_hrl.py"
spec = importlib.util.spec_from_file_location("benchmark_hrl_compat", path)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return int(module.main(argv))
__all__ = ["run_benchmark"]
-5
View File
@@ -1,5 +0,0 @@
from .high_level_ppo import HighLevelPolicy, load_high_policy
from .low_level_ppo import LowLevelPolicy, load_low_policy
__all__ = ["HighLevelPolicy", "load_high_policy",
"LowLevelPolicy", "load_low_policy"]
-10
View File
@@ -1,10 +0,0 @@
"""兼容入口:高层 MaskablePPO 推理策略。"""
from mcm26b.hrl.policy import HighLevelPolicy
def load_high_policy(model_path: str, *, device: str = "auto",
problem: int | None = None) -> HighLevelPolicy:
return HighLevelPolicy(model_path, device=device, problem=problem)
__all__ = ["HighLevelPolicy", "load_high_policy"]
-9
View File
@@ -1,9 +0,0 @@
"""兼容入口:低层八方向到达策略(离线导航实验)。"""
from mcm26b.hrl.policy import LowLevelPolicy
def load_low_policy(model_path: str, *, device: str = "auto") -> LowLevelPolicy:
return LowLevelPolicy(model_path, device=device)
__all__ = ["LowLevelPolicy", "load_low_policy"]
+13
View File
@@ -0,0 +1,13 @@
"""问题一:交会定位多边形直径与直径圆覆盖。
- ``optimal.py`` :生产实现 ``mcm26b.geometry.localization.solve``(半平面交 +
顶点对精确直径 + Welzl 最小包围圆 + 覆盖反例见证);
- ``baseline.py`` :基线实现(网格采样 + 轴对齐包围盒代理直径/覆盖);
- ``reference.py``:独立精确参考解(大框半平面裁剪 + 暴力直径/最小包围圆);
- ``cases.py`` :固定示例(``examples/q1``)与随机算例生成;
- ``compare.py`` :同案配对对比并落盘。
"""
from . import baseline, cases, optimal, reference
__all__ = ["optimal", "baseline", "reference", "cases"]
+98
View File
@@ -0,0 +1,98 @@
"""问题一基线实现:网格采样 + 轴对齐包围盒(bbox)代理。
这是"先上手"的朴素做法,常见于直接对可行点打网格再读包围盒:
1. 在固定大框上按步长采样,保留满足全部角域约束的点;
2. 直径用包围盒对角线代理 —— 只要区域是斜的/细长的就会系统性高估;
3. 覆盖判断用"包围盒中心 + 代理直径"的圆 —— 因为包围盒自身对其中心对称,
该判据几乎恒为"能覆盖",从而丢掉问题一真正要考的反例。
本实现刻意保留这些结构性缺陷,作为``optimal.py``的对照;它不读取最优实现的
任何中间量,两条代码路径完全独立。
"""
from __future__ import annotations
import math
from time import perf_counter
import numpy as np
from mcm26b.geometry.localization import Measurement, halfplanes
from project.common import Method
METHOD = Method(
key="baseline",
name="网格采样 + bbox 对角线代理",
kind="baseline",
note="轴对齐包围盒近似直径与覆盖,O(盒面积/步长²),与参考解同分辨率",
)
BOX_M = 2600.0
STEP_M = 5.0
def solve_case(case: dict) -> dict:
start = perf_counter()
measurements = [Measurement(row["x"], row["y"], row["bearing_deg"],
row.get("half_angle_deg", 1.0))
for row in case["measurements"]]
planes = [plane for m in measurements for plane in halfplanes(m)]
xs = np.arange(-BOX_M, BOX_M + STEP_M, STEP_M)
grid_x, grid_y = np.meshgrid(xs, xs) # 行=y,列=x
mask = np.ones(grid_x.shape, dtype=bool)
for a, b, c in planes:
mask &= (a * grid_x + b * grid_y <= c)
result = _evaluate(mask, xs)
result["method"] = METHOD.key
result["runtime_ms"] = round((perf_counter() - start) * 1000.0, 4)
result["algorithm"] = METHOD.name
return result
def _evaluate(mask: np.ndarray, axis: np.ndarray) -> dict:
if not mask.any():
return _empty("empty")
# 可行点触到采样框边界 => 区域至少延伸到框外,判无界
if (mask[0, :].any() or mask[-1, :].any()
or mask[:, 0].any() or mask[:, -1].any()):
return _empty("unbounded")
rows, cols = np.nonzero(mask)
x_min, x_max = axis[cols].min(), axis[cols].max()
y_min, y_max = axis[rows].min(), axis[rows].max()
width, height = x_max - x_min, y_max - y_min
diameter = math.hypot(width, height) # 包围盒对角线代理
center = ((x_min + x_max) / 2.0, (y_min + y_max) / 2.0)
px = axis[cols]
py = axis[rows]
max_distance = float(np.max(np.hypot(px - center[0], py - center[1])))
return {
"status": "polygon" if mask.sum() >= 2 else "point",
"diameter_m": diameter,
"diameter_infinite": False,
"covers": bool(max_distance <= diameter / 2.0 + 1e-9),
"mec_radius_m": None,
"max_excess_m": round(max_distance - diameter / 2.0, 6),
"outside_vertex_count": None,
"vertex_count": int(mask.sum()),
"bbox_width_m": round(width, 3),
"bbox_height_m": round(height, 3),
"runtime_ms": None,
}
def _empty(status: str) -> dict:
return {
"status": status,
"diameter_m": None,
"diameter_infinite": status == "unbounded",
"covers": None,
"mec_radius_m": None,
"max_excess_m": None,
"outside_vertex_count": None,
"vertex_count": 0,
}
+67
View File
@@ -0,0 +1,67 @@
"""问题一算例:官方示例目录 ``examples/q1`` + 随机交会算例。"""
from __future__ import annotations
import json
import math
import random
from project.common import ROOT
EXAMPLE_DIR = ROOT / "examples" / "q1"
EXAMPLE_IDS = ("normal", "triangle", "poor", "segment", "empty")
def load_examples() -> list[dict]:
"""读取固定算例;缺文件时跳过,保证离线可跑。"""
cases = []
for key in EXAMPLE_IDS:
path = EXAMPLE_DIR / f"{key}.json"
if not path.exists():
continue
raw = json.loads(path.read_text(encoding="utf-8-sig"))
cases.append({
"id": raw.get("id", key),
"name": raw.get("name", key),
"source": "examples/q1",
"measurements": [
{"x": float(row["x"]), "y": float(row["y"]),
"bearing_deg": float(row["bearing_deg"]),
"half_angle_deg": float(row.get("half_angle_deg", 1.0))}
for row in raw["measurements"]
],
})
return cases
def random_case(seed: int) -> dict:
"""随机三点/四点交会:目标在 Ω 内,测站分布在不同象限。
仅生成"区域有界且非退化"的良态算例,避免参考网格因细长区域失效;
生成后由 ``compare`` 再用最优实现复核状态。
"""
rng = random.Random(seed)
target = (rng.uniform(-900, 900), rng.uniform(-900, 900))
count = rng.choice((3, 3, 4, 5))
stations = []
base_angle = rng.uniform(0, 360)
for index in range(count):
angle = base_angle + 360 * index / count + rng.uniform(-25, 25)
radius = rng.uniform(500, 1100)
stations.append((target[0] + radius * math.cos(math.radians(angle)),
target[1] + radius * math.sin(math.radians(angle))))
measurements = []
for (sx, sy) in stations:
true_bearing = math.degrees(math.atan2(target[1] - sy, target[0] - sx)) % 360.0
# 观测误差固定在同一地点、落在 ±1° 内;读数保留两位小数
error = rng.uniform(-0.9, 0.9)
measurements.append({"x": round(sx, 2), "y": round(sy, 2),
"bearing_deg": round((true_bearing + error) % 360.0, 2),
"half_angle_deg": 1.0})
return {"id": f"rand-{seed}", "name": "随机交会", "source": "synthetic",
"target": [round(target[0], 2), round(target[1], 2)],
"measurements": measurements}
def random_cases(count: int, base_seed: int = 7000) -> list[dict]:
return [random_case(base_seed + index) for index in range(count)]
+150
View File
@@ -0,0 +1,150 @@
"""问题一同案配对对比:最优 vs 基线 vs 独立参考解。"""
from __future__ import annotations
from project.common import (Method, RESULTS_DIR, markdown_table, mean,
ratio, write_json, write_text)
from project.q1 import baseline, cases, optimal, reference
METHODS: tuple[Method, ...] = (optimal.METHOD, baseline.METHOD, reference.METHOD)
FINITE = ("point", "segment", "polygon")
def _run(case: dict) -> dict:
opt = optimal.solve_case(case)
base = baseline.solve_case(case)
ref = reference.solve_case(case)
finite = ref["status"] in FINITE and ref["diameter_m"] is not None
return {
"id": case["id"],
"name": case.get("name", case["id"]),
"source": case.get("source", "synthetic"),
"measurements": len(case["measurements"]),
"status_ref": ref["status"],
"status_opt": opt["status"],
"status_base": base["status"],
"status_opt_ok": opt["status"] == ref["status"],
"status_base_ok": base["status"] == ref["status"],
"diameter_ref_m": ref["diameter_m"],
"diameter_opt_m": opt["diameter_m"],
"diameter_base_m": base["diameter_m"],
"abs_err_opt_m": (round(abs(opt["diameter_m"] - ref["diameter_m"]), 4)
if finite and opt["diameter_m"] is not None else None),
"abs_err_base_m": (round(abs(base["diameter_m"] - ref["diameter_m"]), 4)
if finite and base["diameter_m"] is not None else None),
"covers_ref": ref["covers"],
"covers_opt": opt["covers"],
"covers_base": base["covers"],
"covers_opt_ok": (opt["covers"] == ref["covers"]
if ref["covers"] is not None and opt["covers"] is not None
else None),
"covers_base_ok": (base["covers"] == ref["covers"]
if ref["covers"] is not None and base["covers"] is not None
else None),
"mec_radius_opt_m": opt["mec_radius_m"],
"mec_radius_ref_m": ref["mec_radius_m"],
"outside_vertices_opt": opt["outside_vertex_count"],
"runtime_opt_ms": opt["runtime_ms"],
"runtime_base_ms": base["runtime_ms"],
"runtime_ref_ms": ref["runtime_ms"],
"reference_resolution_m": ref["resolution_m"],
}
def _aggregate(rows: list[dict]) -> dict:
polygon_rows = [r for r in rows if r["status_ref"] == "polygon"]
opt_errs = [r["abs_err_opt_m"] for r in polygon_rows
if r["abs_err_opt_m"] is not None]
base_errs = [r["abs_err_base_m"] for r in polygon_rows
if r["abs_err_base_m"] is not None]
cov_opt = [r["covers_opt_ok"] for r in rows if r["covers_opt_ok"] is not None]
cov_base = [r["covers_base_ok"] for r in rows if r["covers_base_ok"] is not None]
return {
"cases": len(rows),
"diameter_compared": len(opt_errs),
"status_accuracy_optimal": ratio(sum(r["status_opt_ok"] for r in rows), len(rows)),
"status_accuracy_baseline": ratio(sum(r["status_base_ok"] for r in rows), len(rows)),
"diameter_mae_optimal_m": mean(opt_errs),
"diameter_mae_baseline_m": mean(base_errs),
"diameter_max_err_optimal_m": round(max(opt_errs), 4) if opt_errs else 0.0,
"diameter_max_err_baseline_m": round(max(base_errs), 4) if base_errs else 0.0,
"coverage_compared": len(cov_opt),
"coverage_accuracy_optimal": ratio(sum(cov_opt), len(cov_opt)),
"coverage_accuracy_baseline": ratio(sum(cov_base), len(cov_base)),
"runtime_optimal_mean_ms": mean(r["runtime_opt_ms"] for r in rows),
"runtime_baseline_mean_ms": mean(r["runtime_base_ms"] for r in rows),
"runtime_reference_mean_ms": mean(r["runtime_ref_ms"] for r in rows),
}
def _render(rows: list[dict], aggregate: dict, title: str) -> str:
headers = ["算例", "来源", "参考状态", "最优状态", "基线状态",
"D参考(m)", "D最优(m)", "D基线(m)", "|ΔD|最优", "|ΔD|基线",
"覆盖参考", "覆盖最优", "覆盖基线"]
body = []
for r in rows:
body.append([
r["name"], r["source"], r["status_ref"], r["status_opt"], r["status_base"],
_fmt(r["diameter_ref_m"]), _fmt(r["diameter_opt_m"]),
_fmt(r["diameter_base_m"]),
_fmt(r["abs_err_opt_m"]), _fmt(r["abs_err_base_m"]),
_bool(r["covers_ref"]), _bool(r["covers_opt"]), _bool(r["covers_base"]),
])
text = [f"# {title}", "",
"参考解为独立的大框半平面裁剪 + 精确直径/MEC;",
"固定示例见 `examples/q1`,解析期望由 `tests/test_geometry*.py` 固化。",
"", markdown_table(headers, body), "",
"## 汇总", ""]
summary_rows = [
["状态判定准确率", _pct(aggregate["status_accuracy_optimal"]),
_pct(aggregate["status_accuracy_baseline"])],
["直径平均绝对误差 (m)", _fmt(aggregate["diameter_mae_optimal_m"], 3),
_fmt(aggregate["diameter_mae_baseline_m"], 3)],
["直径最大误差 (m)", _fmt(aggregate["diameter_max_err_optimal_m"], 3),
_fmt(aggregate["diameter_max_err_baseline_m"], 3)],
["覆盖判定准确率", _pct(aggregate["coverage_accuracy_optimal"]),
_pct(aggregate["coverage_accuracy_baseline"])],
["平均耗时 (ms)", _fmt(aggregate["runtime_optimal_mean_ms"], 3),
_fmt(aggregate["runtime_baseline_mean_ms"], 3)],
]
text.append(markdown_table(["指标", "最优", "基线"], summary_rows))
return "\n".join(text) + "\n"
def _fmt(value, digits: int = 2) -> str:
if value is None:
return "—"
if isinstance(value, bool):
return "是" if value else "否"
if isinstance(value, float):
return f"{value:.{digits}f}"
return str(value)
def _bool(value) -> str:
return "—" if value is None else ("是" if value else "否")
def _pct(value: float) -> str:
return f"{value*100:.1f}%"
def run(quick: bool = False) -> dict:
example_rows = [_run(case) for case in cases.load_examples()]
random_rows = [_run(case) for case in
cases.random_cases(12 if quick else 40)]
payload = {
"question": 1,
"methods": [m.__dict__ for m in METHODS],
"examples": example_rows,
"random": random_rows,
"aggregate_examples": _aggregate(example_rows),
"aggregate_random": _aggregate(random_rows),
}
write_json(RESULTS_DIR / "q1.json", payload)
text = _render(example_rows, payload["aggregate_examples"],
"问题一:固定示例对比")
text += "\n" + _render(random_rows, payload["aggregate_random"],
"问题一:随机交会算例对比")
write_text(RESULTS_DIR / "q1.md", text)
return payload
+59
View File
@@ -0,0 +1,59 @@
"""问题一最优实现:复用生产几何内核 ``mcm26b.geometry.localization.solve``。
算法(已由 ``tests/test_geometry.py`` / ``tests/test_geometry_certificates.py``
固化,本模块只做输入输出适配,不重写):
1. 每条带 ±δ 误差的示向度写成前向角域的三条半平面约束(含 0°/360° 跨界);
2. 枚举全部边界直线交点,保留满足全部约束者,单调链求凸包;
3. 检查是否存在非零衰退方向判定无界;否则枚举凸包顶点对取精确直径;
4. 用直径两端点中点圆检验覆盖,并给出圆外顶点、最大超出距离等反例见证;
5. Welzl 增量法求最小包围圆,给出 20 m 清除余量证书。
"""
from __future__ import annotations
from time import perf_counter
from mcm26b.geometry.localization import Measurement, solve
from project.common import Method
METHOD = Method(
key="optimal",
name="精确半平面交 + 顶点对直径 + MEC",
kind="optimal",
note="生产内核 mcm26b.geometry.localization.solve",
)
def solve_case(case: dict) -> dict:
"""输入 case["measurements"],输出归一化结果。"""
measurements = [Measurement(row["x"], row["y"], row["bearing_deg"],
row.get("half_angle_deg", 1.0))
for row in case["measurements"]]
start = perf_counter()
result = solve(measurements)
elapsed_ms = (perf_counter() - start) * 1000.0
return normalize(result, elapsed_ms)
def normalize(result: dict, elapsed_ms: float) -> dict:
status = result["status"]
diameter = result.get("diameter_m")
circle = result.get("diameter_circle") or {}
mec = result.get("minimum_enclosing_circle") or {}
covers = circle.get("covers") if status in ("point", "segment", "polygon") else None
return {
"method": METHOD.key,
"status": status,
"diameter_m": diameter,
"diameter_infinite": result.get("diameter_infinite"),
"covers": covers,
"mec_radius_m": mec.get("radius_m"),
"max_excess_m": circle.get("max_excess_m"),
"outside_vertex_count": len(circle.get("outside_vertex_indices", []))
if circle else None,
"vertex_count": len(result.get("vertices", [])),
"runtime_ms": round(elapsed_ms, 4),
"algorithm": METHOD.name,
}
+178
View File
@@ -0,0 +1,178 @@
"""问题一独立参考解:大框 Sutherland–Hodgman 半平面裁剪 + 精确直径/MEC。
与生产实现 ``mcm26b.geometry.localization.solve`` 的独立性:
- 生产实现枚举"半平面边界直线两两交点"再筛可行点;
- 本参考解从一个大方框出发,逐条半平面做 Sutherland–Hodgman 裁剪,
是另一条构造路径,且这里的半平面系数、直径、最小包围圆都在本文件内
独立编码(不复用生产实现的 ``halfplanes`` / ``diameter`` / ``mec``)。
只要区域有界,大框(±1e7 m)裁剪得到的顶点即精确多边形;顶点触到大框
边界则判无界。最小包围圆用"枚举所有 1/2/3 点支撑圆"的暴力算法,直径用
顶点对暴力枚举,二者都是 O(m²)/O(m³) 的朴素精确算法,m 为多边形顶点数。
"""
from __future__ import annotations
import math
from time import perf_counter
from project.common import Method
METHOD = Method(
key="reference",
name="大框半平面裁剪 + 精确直径/MEC",
kind="reference",
note="独立于生产顶点枚举的精确参考解",
)
BOX_M = 1.0e7
_PARALLEL_EPS = 1e-12
def _planes(case: dict) -> list[tuple[float, float, float]]:
"""独立重写 a*x+b*y<=c 的半平面构造(与题面角域定义一致)。"""
planes = []
for row in case["measurements"]:
half = math.radians(row.get("half_angle_deg", 1.0))
theta = math.radians(row["bearing_deg"] % 360.0)
sx, sy = row["x"], row["y"]
for angle, sign in ((theta - half, 1.0), (theta + half, -1.0)):
a = sign * math.sin(angle)
b = -sign * math.cos(angle)
planes.append((a, b, a * sx + b * sy))
# 前向约束:不允许把角域取成反向无限双楔
a, b = -math.cos(theta), -math.sin(theta)
planes.append((a, b, a * sx + b * sy))
return planes
def _clip(polygon, a, b, c, tol=1e-7):
"""Sutherland–Hodgman:保留 a*x+b*y<=c 的一侧。"""
if not polygon:
return []
output = []
count = len(polygon)
for index in range(count):
p, q = polygon[index], polygon[(index + 1) % count]
fp = a * p[0] + b * p[1] - c
fq = a * q[0] + b * q[1] - c
p_in, q_in = fp <= tol, fq <= tol
if p_in:
output.append(p)
if p_in != q_in:
ratio = fp / (fp - fq)
output.append((p[0] + ratio * (q[0] - p[0]),
p[1] + ratio * (q[1] - p[1])))
deduped = []
for point in output:
if not deduped or math.dist(point, deduped[-1]) > 1e-9:
deduped.append(point)
if len(deduped) > 1 and math.dist(deduped[0], deduped[-1]) <= 1e-9:
deduped.pop()
return deduped
def _brute_force_diameter(points):
best = 0.0
pair = (points[0], points[0])
for i, pi in enumerate(points):
for pj in points[i + 1:]:
value = math.dist(pi, pj)
if value > best:
best, pair = value, (pi, pj)
return best, pair
def _circumcircle(a, b, c):
ux, uy = b[0] - a[0], b[1] - a[1]
vx, vy = c[0] - a[0], c[1] - a[1]
det = 2.0 * (ux * vy - uy * vx)
if abs(det) <= _PARALLEL_EPS * max(
math.hypot(ux, uy) * math.hypot(vx, vy), 1e-300):
return None
uu, vv = ux * ux + uy * uy, vx * vx + vy * vy
center = (a[0] + (uu * vy - vv * uy) / det,
a[1] + (ux * vv - vx * uu) / det)
return center, math.dist(center, a)
def _brute_force_mec(points):
"""枚举 1/2/3 点支撑圆的精确最小包围圆(朴素但无迭代)。"""
xs = [p[0] for p in points]
ys = [p[1] for p in points]
best_c = ((min(xs) + max(xs)) / 2.0, (min(ys) + max(ys)) / 2.0)
best_r = max(math.dist(best_c, p) for p in points)
candidates: list[tuple[tuple[float, float], float]] = []
for i, p in enumerate(points):
for q in points[i + 1:]:
candidates.append((((p[0] + q[0]) / 2.0, (p[1] + q[1]) / 2.0),
math.dist(p, q) / 2.0))
for i, p in enumerate(points):
for j in range(i + 1, len(points)):
for k in range(j + 1, len(points)):
circle = _circumcircle(p, points[j], points[k])
if circle is not None:
candidates.append(circle)
for center, radius in candidates:
if radius >= best_r:
continue
if all(math.dist(center, p) <= radius + 1e-7 for p in points):
best_c, best_r = center, radius
return best_c, best_r
def solve_case(case: dict) -> dict:
start = perf_counter()
planes = _planes(case)
polygon = [(-BOX_M, -BOX_M), (BOX_M, -BOX_M), (BOX_M, BOX_M), (-BOX_M, BOX_M)]
for a, b, c in planes:
polygon = _clip(polygon, a, b, c)
if not polygon:
return _finish(_degenerate("empty"), start)
boundary_tol = 1e-6 * BOX_M
if any(abs(point[0]) >= BOX_M - boundary_tol
or abs(point[1]) >= BOX_M - boundary_tol for point in polygon):
return _finish(_degenerate("unbounded"), start)
if len(polygon) == 1:
summary = {"status": "point", "diameter_m": 0.0, "covers": True,
"mec_radius_m": 0.0, "max_excess_m": 0.0,
"vertex_count": 1}
else:
value, (a, b) = _brute_force_diameter(polygon)
if len(polygon) == 2:
summary = {"status": "segment", "diameter_m": value, "covers": True,
"mec_radius_m": value / 2.0, "max_excess_m": 0.0,
"vertex_count": 2}
else:
_mec_center, radius = _brute_force_mec(polygon)
diameter_center = ((a[0] + b[0]) / 2.0, (a[1] + b[1]) / 2.0)
max_distance = max(math.dist(diameter_center, p) for p in polygon)
summary = {
"status": "polygon",
"diameter_m": value,
"covers": bool(radius <= value / 2.0 + 1e-7),
"mec_radius_m": radius,
"max_excess_m": round(max_distance - value / 2.0, 9),
"vertex_count": len(polygon),
}
return _finish(summary, start)
def _degenerate(status: str) -> dict:
return {"status": status, "diameter_m": None, "covers": None,
"mec_radius_m": None, "max_excess_m": None, "vertex_count": 0}
def _finish(summary: dict, start: float) -> dict:
result = {
"method": METHOD.key,
"algorithm": METHOD.name,
"resolution_m": 0.0,
"diameter_infinite": summary["status"] == "unbounded",
"outside_vertex_count": None,
"runtime_ms": round((perf_counter() - start) * 1000.0, 4),
}
result.update(summary)
return result
+14
View File
@@ -0,0 +1,14 @@
"""问题二:第二检测点选择策略。
- ``optimal.py`` :生产选点器 ``mcm26b.planner.select_measurement_point``
(保证接收盘内最坏后验半径最小化,采样启发式);
- ``baseline.py`` :"垂直 1000 m 最大交会角"朴素启发式(忽略接收保证),
以及"退到候选集 MEC 圆心"的保守基线;
- ``reference.py``:在保证接收盘内稠密网格枚举的近似最优参考;
- ``cases.py`` :随机首次示向度算例;
- ``compare.py`` :同案配对对比并落盘。
"""
from . import baseline, cases, optimal, reference
__all__ = ["optimal", "baseline", "reference", "cases"]
+71
View File
@@ -0,0 +1,71 @@
"""问题二基线实现:两个朴素但常见的对照。
- ``candidate_perp``:沿首次示向度垂直方向、距检测点约 1000 m 取点。
这是"尽量把交会角做成 90°"的教科书启发式,**但它忽略接收距离保证**:
真源可能落在首次角域的远端(≤1500 m),此时第二点距离可超过 1000 m,
第二次测量直接 ``no_signal``,几何收益落空。
- ``candidate_mec``:退到候选集最小包围圆圆心。它确实落在保证接收盘内
(ρ≤1000 时),但交会角可能接近 0°、后验几乎不收缩,代表"最保守"一端。
"""
from __future__ import annotations
import math
from mcm26b.config import ProblemConfig
from mcm26b.planner import safe_disk_radius
from project.common import Method, problem_config
from project.q2.region import first_bearing_region
PERP = Method(
key="baseline_perp",
name="垂直 1000 m 最大交会角",
kind="baseline",
note="忽略接收保证的几何启发式",
)
MEC = Method(
key="baseline_mec",
name="候选集 MEC 圆心",
kind="baseline",
note="保证接收但交会角最差的保守基线",
)
METHODS = (PERP, MEC)
def _region(case: dict, config: ProblemConfig):
return first_bearing_region(case, config)
def candidate_perp(case: dict, config: ProblemConfig | None = None) -> dict:
config = config or problem_config()
region = _region(case, config)
station = (case["station"][0], case["station"][1])
theta = math.radians(case["bearing_deg"] + 90.0)
distance = config.field.r_eff_min_m
position = (station[0] + distance * math.cos(theta),
station[1] + distance * math.sin(theta))
return {
"method": PERP.key,
"position": [round(position[0], 4), round(position[1], 4)],
"worst_posterior_radius_m": None, # 由 compare 统一评估
"move_cost_s": None,
"safe_disk_radius_m": safe_disk_radius(region, config),
"initial_radius_m": region.mec()[1],
"reason": "沿首次示向度法向 1000 m 取 90° 交会点",
}
def candidate_mec(case: dict, config: ProblemConfig | None = None) -> dict:
config = config or problem_config()
region = _region(case, config)
center, radius = region.mec()
return {
"method": MEC.key,
"position": [round(center[0], 4), round(center[1], 4)],
"worst_posterior_radius_m": None,
"move_cost_s": None,
"safe_disk_radius_m": safe_disk_radius(region, config),
"initial_radius_m": radius,
"reason": "取候选集最小包围圆圆心,保证接收但交会角可能最差",
}
+37
View File
@@ -0,0 +1,37 @@
"""问题二算例:随机首次示向度(全向源)。"""
from __future__ import annotations
import math
import random
from mcm26b.config import ProblemConfig
def random_case(seed: int, config: ProblemConfig | None = None) -> dict:
"""随机检测点 s 与示向度 θ:默认让真源与读数一致(误差 ±1° 内)。"""
config = config or ProblemConfig()
rng = random.Random(seed)
radius = config.field.omega_radius_m
# 检测点可在目标域内或域外;这里取域内,符合题目常规场景
angle_s = rng.uniform(0, 2 * math.pi)
distance_s = radius * math.sqrt(rng.random()) * 0.9
station = (distance_s * math.cos(angle_s), distance_s * math.sin(angle_s))
# 真源与检测点距离落在 [60, 1500) 且仍在 Ω 内
while True:
bearing_true = rng.uniform(0, 2 * math.pi)
source_distance = rng.uniform(60, config.field.r_eff_max_m - 1)
target = (station[0] + source_distance * math.cos(bearing_true),
station[1] + source_distance * math.sin(bearing_true))
if math.hypot(*target) <= radius:
break
error = math.radians(rng.uniform(-0.95, 0.95))
bearing_deg = math.degrees(bearing_true + error) % 360.0
return {"id": f"q2-{seed}", "station": [round(station[0], 2), round(station[1], 2)],
"bearing_deg": round(bearing_deg, 2), "half_angle_deg": 1.0,
"true_source": [round(target[0], 2), round(target[1], 2)]}
def random_cases(count: int, base_seed: int = 4200,
config: ProblemConfig | None = None) -> list[dict]:
return [random_case(base_seed + index, config) for index in range(count)]
+136
View File
@@ -0,0 +1,136 @@
"""问题二同案配对对比:最优 / 两个基线 / 网格参考,用同一评估器打分。"""
from __future__ import annotations
import math
from mcm26b.config import ProblemConfig
from mcm26b.planner import _worst_posterior_radius
from project.common import (Method, RESULTS_DIR, markdown_table, mean, ratio,
write_json, write_text)
from project.q2 import baseline, cases, optimal, reference
from project.q2.region import first_bearing_region
METHODS: tuple[Method, ...] = (optimal.METHOD, baseline.PERP, baseline.MEC,
reference.METHOD)
EVAL_WITNESS_SPACING_M = 60.0
def _evaluate(case: dict, config: ProblemConfig) -> list[dict]:
region = first_bearing_region(case, config)
station = (case["station"][0], case["station"][1])
initial_radius = region.mec()[1]
half_angle = (config.field.bearing_error_half_deg
+ config.search.bearing_rounding_margin_deg)
witnesses = region.witnesses(EVAL_WITNESS_SPACING_M)
plans = [optimal.candidate(case, config),
baseline.candidate_perp(case, config),
baseline.candidate_mec(case, config),
reference.candidate(case, config)]
rows = []
for plan in plans:
q = (plan["position"][0], plan["position"][1])
guarantee_distance = max(math.dist(q, vertex) for vertex in region.polygon)
worst = _worst_posterior_radius(
region, q, witnesses, half_angle,
config.field.near_radius_m, config.search.polygon_sides)
move_cost = math.dist(station, q) / config.cost.speed_mps
rows.append({
"case_id": case["id"],
"method": plan["method"],
"initial_radius_m": round(initial_radius, 4),
"q": [round(q[0], 2), round(q[1], 2)],
"guaranteed_reception": bool(guarantee_distance
<= config.field.r_eff_min_m + 1e-6),
"guarantee_distance_m": round(guarantee_distance, 3),
"worst_posterior_radius_m": round(worst, 4),
"improvement_m": round(initial_radius - worst, 4),
"final_ratio": round(worst / initial_radius, 4) if initial_radius > 0 else None,
"move_cost_s": round(move_cost, 4),
"reason": plan["reason"],
})
return rows
def _aggregate(rows: list[dict], labels: list[str]) -> dict:
summary: dict[str, dict] = {}
initial = mean(r["initial_radius_m"] for r in rows) if rows else 0.0
for label in labels:
part = [r for r in rows if r["method"] == label]
if not part:
continue
summary[label] = {
"cases": len(part),
"guaranteed_rate": ratio(sum(r["guaranteed_reception"] for r in part),
len(part)),
"worst_posterior_mean_m": mean(r["worst_posterior_radius_m"] for r in part),
"worst_posterior_median_m": sorted(
r["worst_posterior_radius_m"] for r in part)[len(part) // 2],
"improvement_mean_m": mean(r["improvement_m"] for r in part),
"final_ratio_mean": mean(r["final_ratio"] for r in part
if r["final_ratio"] is not None),
"move_cost_mean_s": mean(r["move_cost_s"] for r in part),
}
summary["_initial_radius_mean_m"] = initial
return summary
def _render(rows: list[dict], aggregate: dict, labels: list[str]) -> str:
headers = ["算例", "方法", "初始 ρ(m)", "第二点 q", "保证接收",
"q 到 K₁ 最远(m)", "最坏后验 ρ'(m)", "收缩(m)", "移动(s)"]
body = []
order = {label: index for index, label in enumerate(labels)}
for row in sorted(rows, key=lambda r: (r["case_id"], order.get(r["method"], 99))):
body.append([
row["case_id"], row["method"], _f(row["initial_radius_m"]),
f"({row['q'][0]:.0f},{row['q'][1]:.0f})",
"是" if row["guaranteed_reception"] else "否",
_f(row["guarantee_distance_m"]), _f(row["worst_posterior_radius_m"]),
_f(row["improvement_m"]), _f(row["move_cost_s"]),
])
text = ["# 问题二:第二检测点选择对比", "",
"初始 ρ 为首次示向度候选集 K₁ 的最小包围半径;最坏后验按"
"目标边界采样 × 读数区间端点统一评估。", "",
markdown_table(headers, body), "", "## 逐方法汇总", ""]
agg_headers = ["方法", "保证接收率", "最坏后验均值(m)", "中位(m)",
"平均收缩(m)", "终值比 ρ'/ρ", "移动均值(s)"]
agg_rows = []
for label in labels:
s = aggregate.get(label)
if not s:
continue
agg_rows.append([label, f"{s['guaranteed_rate']*100:.1f}%",
_f(s["worst_posterior_mean_m"]),
_f(s["worst_posterior_median_m"]),
_f(s["improvement_mean_m"]),
_f(s["final_ratio_mean"], 3),
_f(s["move_cost_mean_s"])])
text.append(markdown_table(agg_headers, agg_rows))
text.append("")
text.append(f"初始 ρ 均值:{aggregate['_initial_radius_mean_m']:.2f} m")
return "\n".join(text) + "\n"
def _f(value, digits: int = 2) -> str:
if value is None:
return "—"
if isinstance(value, bool):
return "是" if value else "否"
if isinstance(value, float):
return f"{value:.{digits}f}"
return str(value)
def run(quick: bool = False) -> dict:
config = ProblemConfig()
case_list = cases.random_cases(8 if quick else 30, config=config)
rows = [row for case in case_list for row in _evaluate(case, config)]
labels = [m.key for m in METHODS]
aggregate = _aggregate(rows, labels)
payload = {"question": 2, "methods": [m.__dict__ for m in METHODS],
"cases": case_list, "rows": rows, "aggregate": aggregate}
write_json(RESULTS_DIR / "q2.json", payload)
write_text(RESULTS_DIR / "q2.md", _render(rows, aggregate, labels))
return payload
+42
View File
@@ -0,0 +1,42 @@
"""问题二最优实现:保证接收盘内的最坏后验半径最小化选点(生产实现)。
复用 ``mcm26b.planner.select_measurement_point``:
1. 在"保证接收盘" B(mec_center, 1000-ρ) 内环形采样候选点;
2. 对每个候选,用"目标边界点 × 读数区间端点(+near 分支)"估计
最坏后验最小包围半径,并以移动时间同分决胜;
3. 选定后按 1/4 间距加密复核,返回位置、后验半径与理由。
采样是启发式(不是连续问题全局最优证明),但保证接收是严格的。
"""
from __future__ import annotations
from mcm26b.config import ProblemConfig
from mcm26b.planner import safe_disk_radius, select_measurement_point
from project.common import Method, problem_config
from project.q2.region import first_bearing_region
METHOD = Method(
key="optimal",
name="保证接收盘内最小最坏后验半径",
kind="optimal",
note="生产实现 mcm26b.planner.select_measurement_point",
)
def candidate(case: dict, config: ProblemConfig | None = None) -> dict:
config = config or problem_config()
region = first_bearing_region(case, config)
station = (case["station"][0], case["station"][1])
plan = select_measurement_point(region, station, config)
return {
"method": METHOD.key,
"position": [round(plan.position[0], 4), round(plan.position[1], 4)],
"worst_posterior_radius_m": plan.worst_posterior_radius_m,
"move_cost_s": plan.move_cost_s,
"safe_disk_radius_m": safe_disk_radius(region, config),
"initial_radius_m": region.mec()[1],
"reason": plan.reason,
}
+67
View File
@@ -0,0 +1,67 @@
"""问题二近似最优参考:在保证接收盘内做稠密网格枚举。
目标函数与生产实现一致(最坏后验包围半径 + 移动时间同分决胜),但候选点
取自**均匀网格**而非环形采样族,因此可用来检验生产采样是否接近该目标下的
网格最优。注意这是"同一目标下的网格参考",不是连续问题的严格全局最优。
"""
from __future__ import annotations
import math
from mcm26b.config import ProblemConfig
from mcm26b.planner import (_worst_posterior_radius, safe_disk_radius)
from project.common import Method, problem_config
from project.q2.region import first_bearing_region
METHOD = Method(
key="reference",
name="保证接收盘内网格枚举",
kind="reference",
note="同一目标下的稠密网格参考,非连续全局最优",
)
GRID_SIDES = 9
WITNESS_SPACING_M = 150.0
def candidate(case: dict, config: ProblemConfig | None = None) -> dict:
config = config or problem_config()
region = first_bearing_region(case, config)
station = (case["station"][0], case["station"][1])
center = region.mec()[0]
safe = safe_disk_radius(region, config)
if safe < 0:
return _payload(center, region, config, station, "无保证接收盘:退回 MEC 圆心")
field, search = config.field, config.search
half_angle = field.bearing_error_half_deg + search.bearing_rounding_margin_deg
witnesses = region.witnesses(WITNESS_SPACING_M)
step = 2.0 * safe / (GRID_SIDES - 1)
best_key, best_point, best_worst = None, center, None
for i in range(GRID_SIDES):
for j in range(GRID_SIDES):
point = (center[0] - safe + i * step, center[1] - safe + j * step)
if math.dist(point, center) > safe + 1e-9:
continue
worst = _worst_posterior_radius(region, point, witnesses, half_angle,
field.near_radius_m, search.polygon_sides)
move = math.dist(station, point) / config.cost.speed_mps
key = (round(worst, 6), round(move, 6))
if best_key is None or key < best_key:
best_key, best_point, best_worst = key, point, worst
return _payload(best_point, region, config, station,
f"安全盘网格 {GRID_SIDES}×{GRID_SIDES} 取最坏后验最小",
worst_value=best_worst)
def _payload(point, region, config, station, reason, worst_value=None) -> dict:
return {
"method": METHOD.key,
"position": [round(point[0], 4), round(point[1], 4)],
"worst_posterior_radius_m": worst_value,
"move_cost_s": math.dist(station, point) / config.cost.speed_mps,
"safe_disk_radius_m": safe_disk_radius(region, config),
"initial_radius_m": region.mec()[1],
"reason": reason,
}
+24
View File
@@ -0,0 +1,24 @@
"""问题二候选集 K1 的统一构造(三个方法共用同一输入,保证配对公平)。
K1 = Ω ∩ W(s, θ ± δ_eff) ∩ B(s, 1500),δ_eff = 题设 1° + 示向度舍入裕量。
生产实现用"圆盘外切多边形 ∩ 半平面"的保守外包(``CandidateRegion``),
圆盘用外切多边形严格外包,保证真源不丢。
"""
from __future__ import annotations
from mcm26b.belief import CandidateRegion
from mcm26b.config import ProblemConfig, Vec2
from project.common import problem_config
def first_bearing_region(case: dict,
config: ProblemConfig | None = None) -> CandidateRegion:
config = config or problem_config()
field, search = config.field, config.search
half_angle = field.bearing_error_half_deg + search.bearing_rounding_margin_deg
station: Vec2 = (case["station"][0], case["station"][1])
region = CandidateRegion.initial(station, config)
region.clip_wedge(station, case["bearing_deg"], half_angle)
return region
+11
View File
@@ -0,0 +1,11 @@
"""问题三:全向源搜索—定位—清除闭环。
- ``optimal.py`` :贝叶斯网格粒子滤波 + 信息增益选点 + 滚动 2-opt(``bayes``);
- ``baseline.py``:49 点网格发现 + 就近服务(``grid``,历史基线),
以及七点解析覆盖批量扫频(``seven``,中间对照);
- ``compare.py`` :冻结基准集配对对比并落盘。
"""
from . import baseline, optimal
__all__ = ["optimal", "baseline"]
+28
View File
@@ -0,0 +1,28 @@
"""问题三基线实现:两条不共享贝叶斯决策的对照策略。
- ``OmnidirectionalLoop``(grid):49 点(700 m 步长)网格保证发现,
发现后就近进入定位子循环;策略简单、无信息增益选点、无任务排序优化。
- ``SevenBatch``(seven):七点解析覆盖 + 同站批量扫频 + 最近候选服务队列,
是"覆盖证明 + 批量调度"的中间对照(官方演练 12/12 全清)。
"""
from __future__ import annotations
from mcm26b.planner import OmnidirectionalLoop
from mcm26b.planner.seven import SevenBatch
from project.common import Method
GRID = Method(key="baseline", name="49 点网格 + 就近服务 (grid)",
kind="baseline", note="历史基线,无信息增益与滚动排序")
SEVEN = Method(key="seven", name="七点解析覆盖 + 批量扫频 (seven)",
kind="baseline", note="覆盖证明与批量调度的中间对照")
def build_grid(client, config):
"""工厂:49 点网格基线闭环。"""
return OmnidirectionalLoop(client, config)
def build_seven(client, config):
"""工厂:七点批量扫频中间对照。"""
return SevenBatch(client, config)
+32
View File
@@ -0,0 +1,32 @@
"""问题三冻结基准集配对对比:bayes(最优) vs grid(基线) vs seven(中间)。"""
from __future__ import annotations
from project.common import (RESULTS_DIR, closed_loop_payload, episodes_markdown,
execute_variants, problem_config, write_json,
write_text)
from project.q3 import baseline, optimal
VARIANTS = (
("optimal", optimal.build_loop),
("seven", baseline.build_seven),
("baseline", baseline.build_grid),
)
LABELS = [label for label, _ in VARIANTS]
BASE_LABEL = "baseline"
def run(quick: bool = False) -> dict:
from mcm26b.harness.suites import suite
scenes = suite("core", 3)
if quick:
scenes = scenes[:6]
config = problem_config()
rows = execute_variants(scenes, VARIANTS, config)
payload = closed_loop_payload(3, "core", scenes, VARIANTS, rows,
LABELS, BASE_LABEL, config)
write_json(RESULTS_DIR / "q3.json", payload)
write_text(RESULTS_DIR / "q3.md",
episodes_markdown("问题三:全向闭环配对对比(core 基准集)",
rows, LABELS, BASE_LABEL))
return payload
+19
View File
@@ -0,0 +1,19 @@
"""问题三最优实现:``mcm26b.planner.bayes_loop.BayesLoop``(bayes 策略)。
要点:逐频道网格粒子滤波维护幸存集;以期望信息增益选探点、
滚动时域 2-opt 排序任务;证书(凸证书或 PF 幸存集 MEC)达到 20 m 即清除;
全频道"已清除或证明不存在"后立即 /exit(虚拟时间即成绩口径)。
自建消融相对 SevenBatch 再降约 30%(docs/algo-3-bayes.md)。
"""
from __future__ import annotations
from mcm26b.planner.bayes_loop import BayesLoop
from project.common import Method
METHOD = Method(key="optimal", name="贝叶斯粒子滤波闭环 (bayes)",
kind="optimal", note="生产默认策略,虚拟时间口径")
def build_loop(client, config):
"""工厂:返回生产 bayes 闭环实例。"""
return BayesLoop(client, config)
+12
View File
@@ -0,0 +1,12 @@
"""问题四:含定向干扰源的检测与清除。
- ``optimal.py`` :``DirectionalExtension``(保证覆盖 + 定向观测推理 +
(位置×朝向) 联合信念 + ≤20 m 有限圆盘后备清除);
- ``baseline.py``:把问题三最优策略**直接搬用**的两条基线——
``bayes``(七站全向缺席证明)与 ``grid``(49 点全向覆盖,无后备清除);
- ``compare.py`` :core + boundary 基准集配对对比并落盘。
"""
from . import baseline, optimal
__all__ = ["optimal", "baseline"]
+29
View File
@@ -0,0 +1,29 @@
"""问题四基线实现:把问题三策略原样搬用的两条对照。
- ``bayes``:问题三最优策略直接用于混合源。它用七站环的**全向**缺席证明,
对"定向源朝外发射"场景会错误地把真源判为 ABSENT,属于"快而错"的典型;
- ``grid``:49 点全向网格(对定向源发现是完备的),但缺少定向观测推理与
≤20 m 后备清除,定位停滞时只能停在 DETECTED,属于"稳而不全"。
两条基线都不共享最优实现的联合信念与后备清除逻辑。
"""
from __future__ import annotations
from mcm26b.planner import OmnidirectionalLoop
from mcm26b.planner.bayes_loop import BayesLoop
from project.common import Method
BAYES = Method(key="baseline", name="问题三最优策略直接搬用 (bayes)",
kind="baseline", note="七站全向缺席证明在定向源上失效")
GRID = Method(key="baseline_grid", name="49 点网格全向策略 (grid)",
kind="baseline", note="覆盖完备但无定向推理与后备清除")
def build_bayes(client, config):
"""工厂:问题三 bayes 策略直接搬用。"""
return BayesLoop(client, config)
def build_grid(client, config):
"""工厂:49 点网格全向策略直接搬用。"""
return OmnidirectionalLoop(client, config)
+32
View File
@@ -0,0 +1,32 @@
"""问题四 core+boundary 基准集配对对比:directional(最优) vs 两条搬用基线。"""
from __future__ import annotations
from project.common import (RESULTS_DIR, closed_loop_payload, episodes_markdown,
execute_variants, problem_config, write_json,
write_text)
from project.q4 import baseline, optimal
VARIANTS = (
("optimal", optimal.build_loop),
("baseline_grid", baseline.build_grid),
("baseline", baseline.build_bayes),
)
LABELS = [label for label, _ in VARIANTS]
BASE_LABEL = "baseline"
def run(quick: bool = False) -> dict:
from mcm26b.harness.suites import suite
scenes = suite("core", 4) + suite("boundary", 4)
if quick:
scenes = scenes[:4]
config = problem_config()
rows = execute_variants(scenes, VARIANTS, config)
payload = closed_loop_payload(4, "core+boundary", scenes, VARIANTS, rows,
LABELS, BASE_LABEL, config)
write_json(RESULTS_DIR / "q4.json", payload)
write_text(RESULTS_DIR / "q4.md",
episodes_markdown("问题四:混合源闭环配对对比(core+boundary 基准集)",
rows, LABELS, BASE_LABEL))
return payload
+22
View File
@@ -0,0 +1,22 @@
"""问题四最优实现:``mcm26b.planner.DirectionalExtension``(directional 策略)。
三点相对全向闭环的加装:
1. 发现覆盖改用经全向/定向双口径证伪的 31 点最小命中集
(``q4_mincover_v2``,15 m/72 档验证零缺口);
2. 保证接收盘内 ``no_signal`` 只可能由朝向遮挡解释:记为"观测到定向",
对 MEC 圆心取对跖点复核,并用 (位置×朝向) 联合可行集选可见性探点;
3. 定位停滞时对有界候选集构造 ≤20 m 网格圆盘覆盖,预算核对后逐格 /clear
(清除与朝向无关),是定向源不依赖可见性的完备后备。
"""
from __future__ import annotations
from mcm26b.planner import DirectionalExtension
from project.common import Method
METHOD = Method(key="optimal", name="定向扩展闭环 (directional)",
kind="optimal", note="联合信念 + 后备清除 + 定向覆盖计划")
def build_loop(client, config):
"""工厂:返回定向扩展闭环实例。"""
return DirectionalExtension(client, config)
File diff suppressed because it is too large Load Diff
+80
View File
@@ -0,0 +1,80 @@
# 问题一:固定示例对比
参考解为独立的大框半平面裁剪 + 精确直径/MEC;
固定示例见 `examples/q1`,解析期望由 `tests/test_geometry*.py` 固化。
| 算例 | 来源 | 参考状态 | 最优状态 | 基线状态 | D参考(m) | D最优(m) | D基线(m) | |ΔD|最优 | |ΔD|基线 | 覆盖参考 | 覆盖最优 | 覆盖基线 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 三点交会 | examples/q1 | polygon | polygon | polygon | 26.99 | 26.99 | 21.21 | 0.00 | 5.77 | 否 | 否 | 是 |
| 直径圆反例 | examples/q1 | polygon | polygon | polygon | 40.00 | 40.00 | 50.00 | 0.00 | 10.00 | 否 | 否 | 是 |
| 近共线检测点 | examples/q1 | unbounded | unbounded | unbounded | — | — | — | — | — | — | — | — |
| 零误差退化线段 | examples/q1 | segment | segment | point | 100.00 | 100.00 | 0.00 | 0.00 | 100.00 | 是 | 是 | 是 |
| 不相容观测 | examples/q1 | empty | empty | empty | — | — | — | — | — | — | — | — |
## 汇总
| 指标 | 最优 | 基线 |
| --- | --- | --- |
| 状态判定准确率 | 100.0% | 80.0% |
| 直径平均绝对误差 (m) | 0.000 | 7.886 |
| 直径最大误差 (m) | 0.000 | 10.000 |
| 覆盖判定准确率 | 100.0% | 33.3% |
| 平均耗时 (ms) | 0.064 | 14.202 |
# 问题一:随机交会算例对比
参考解为独立的大框半平面裁剪 + 精确直径/MEC;
固定示例见 `examples/q1`,解析期望由 `tests/test_geometry*.py` 固化。
| 算例 | 来源 | 参考状态 | 最优状态 | 基线状态 | D参考(m) | D最优(m) | D基线(m) | |ΔD|最优 | |ΔD|基线 | 覆盖参考 | 覆盖最优 | 覆盖基线 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 随机交会 | synthetic | polygon | polygon | polygon | 40.32 | 40.32 | 29.15 | 0.00 | 11.16 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 33.36 | 33.36 | 35.36 | 0.00 | 2.00 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 39.78 | 39.78 | 40.31 | 0.00 | 0.53 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 37.50 | 37.50 | 36.06 | 0.00 | 1.44 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 48.24 | 48.24 | 47.43 | 0.00 | 0.81 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 27.97 | 27.97 | 25.00 | 0.00 | 2.97 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 31.84 | 31.84 | 32.02 | 0.00 | 0.17 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 39.13 | 39.13 | 31.62 | 0.00 | 7.51 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 31.60 | 31.60 | 32.02 | 0.00 | 0.42 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 34.49 | 34.49 | 32.02 | 0.00 | 2.48 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 32.61 | 32.61 | 26.93 | 0.00 | 5.68 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 37.41 | 37.41 | 35.36 | 0.00 | 2.05 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 35.15 | 35.15 | 36.06 | 0.00 | 0.90 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 20.56 | 20.56 | 18.03 | 0.00 | 2.53 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 25.23 | 25.23 | 18.03 | 0.00 | 7.20 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 31.61 | 31.61 | 32.02 | 0.00 | 0.41 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 22.19 | 22.19 | 14.14 | 0.00 | 8.05 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 26.31 | 26.31 | 18.03 | 0.00 | 8.28 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 37.85 | 37.85 | 28.28 | 0.00 | 9.56 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 25.78 | 25.78 | 11.18 | 0.00 | 14.60 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 22.53 | 22.53 | 18.03 | 0.00 | 4.51 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 36.84 | 36.84 | 26.93 | 0.00 | 9.91 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 51.21 | 51.21 | 47.17 | 0.00 | 4.04 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 32.88 | 32.88 | 29.15 | 0.00 | 3.73 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 29.99 | 29.99 | 32.02 | 0.00 | 2.02 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 36.50 | 36.50 | 28.28 | 0.00 | 8.21 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 26.38 | 26.38 | 18.03 | 0.00 | 8.35 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 50.11 | 50.11 | 49.24 | 0.00 | 0.86 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 23.29 | 23.29 | 22.36 | 0.00 | 0.93 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 40.73 | 40.73 | 42.43 | 0.00 | 1.70 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 34.09 | 34.09 | 25.00 | 0.00 | 9.09 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 23.35 | 23.35 | 18.03 | 0.00 | 5.32 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 14.89 | 14.89 | 11.18 | 0.00 | 3.71 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 38.12 | 38.12 | 33.54 | 0.00 | 4.58 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 13.68 | 13.68 | 5.00 | 0.00 | 8.68 | 是 | 是 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 41.44 | 41.44 | 43.01 | 0.00 | 1.57 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 22.99 | 22.99 | 18.03 | 0.00 | 4.97 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 34.00 | 34.00 | 35.36 | 0.00 | 1.35 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 16.20 | 16.20 | 7.07 | 0.00 | 9.13 | 否 | 否 | 是 |
| 随机交会 | synthetic | polygon | polygon | polygon | 26.90 | 26.90 | 25.00 | 0.00 | 1.90 | 否 | 否 | 是 |
## 汇总
| 指标 | 最优 | 基线 |
| --- | --- | --- |
| 状态判定准确率 | 100.0% | 100.0% |
| 直径平均绝对误差 (m) | 0.000 | 4.583 |
| 直径最大误差 (m) | 0.000 | 14.599 |
| 覆盖判定准确率 | 100.0% | 52.5% |
| 平均耗时 (ms) | 0.086 | 15.932 |
File diff suppressed because it is too large Load Diff
+137
View File
@@ -0,0 +1,137 @@
# 问题二:第二检测点选择对比
初始 ρ 为首次示向度候选集 K₁ 的最小包围半径;最坏后验按目标边界采样 × 读数区间端点统一评估。
| 算例 | 方法 | 初始 ρ(m) | 第二点 q | 保证接收 | q 到 K₁ 最远(m) | 最坏后验 ρ'(m) | 收缩(m) | 移动(s) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| q2-4200 | optimal | 674.59 | (1257,89) | 是 | 907.09 | 54.45 | 620.13 | 181.42 |
| q2-4200 | baseline_perp | 674.59 | (194,462) | 否 | 1679.16 | 76.22 | 598.36 | 200.00 |
| q2-4200 | baseline_mec | 674.59 | (1173,-226) | 是 | 674.59 | 337.29 | 337.29 | 134.92 |
| q2-4200 | reference | 674.59 | (1173,100) | 是 | 850.11 | 57.70 | 616.89 | 170.02 |
| q2-4201 | optimal | 261.33 | (-1501,-348) | 是 | 461.91 | 13.55 | 247.78 | 92.38 |
| q2-4201 | baseline_perp | 261.33 | (-782,-715) | 否 | 1131.68 | 27.22 | 234.11 | 200.00 |
| q2-4201 | baseline_mec | 261.33 | (-1578,-63) | 是 | 261.33 | 130.67 | 130.67 | 52.27 |
| q2-4201 | reference | 261.33 | (-1393,-432) | 是 | 527.03 | 14.98 | 246.36 | 105.41 |
| q2-4202 | optimal | 591.09 | (-1126,-861) | 是 | 869.01 | 37.92 | 553.17 | 173.80 |
| q2-4202 | baseline_perp | 591.09 | (408,-1235) | 否 | 1561.73 | 64.57 | 526.52 | 200.00 |
| q2-4202 | baseline_mec | 591.09 | (-731,-967) | 是 | 591.09 | 295.54 | 295.54 | 118.22 |
| q2-4202 | reference | 591.09 | (-1038,-865) | 是 | 788.83 | 46.22 | 544.86 | 157.77 |
| q2-4203 | optimal | 326.92 | (1145,-1745) | 是 | 683.58 | 17.13 | 309.79 | 136.72 |
| q2-4203 | baseline_perp | 326.92 | (1837,-1523) | 否 | 1204.35 | 32.99 | 293.93 | 200.00 |
| q2-4203 | baseline_mec | 326.92 | (788,-1388) | 是 | 326.92 | 163.46 | 163.46 | 65.38 |
| q2-4203 | reference | 326.92 | (1125,-1725) | 是 | 657.98 | 16.90 | 310.02 | 131.60 |
| q2-4204 | optimal | 750.20 | (-401,208) | 是 | 876.74 | 91.60 | 658.60 | 175.35 |
| q2-4204 | baseline_perp | 750.20 | (-1541,302) | 否 | 1817.48 | 90.79 | 659.41 | 200.00 |
| q2-4204 | baseline_mec | 750.20 | (-336,-34) | 是 | 750.20 | 375.10 | 375.10 | 150.04 |
| q2-4204 | reference | 750.20 | (-336,216) | 是 | 923.80 | 92.25 | 657.95 | 184.76 |
| q2-4205 | optimal | 750.14 | (-503,21) | 是 | 881.59 | 91.10 | 659.04 | 176.32 |
| q2-4205 | baseline_perp | 750.14 | (-612,-1470) | 否 | 1817.36 | 90.78 | 659.36 | 200.00 |
| q2-4205 | baseline_mec | 750.14 | (-568,-220) | 是 | 750.14 | 375.08 | 375.06 | 150.03 |
| q2-4205 | reference | 750.14 | (-568,30) | 是 | 927.74 | 92.25 | 657.89 | 185.55 |
| q2-4206 | optimal | 750.12 | (216,677) | 是 | 892.00 | 90.96 | 659.16 | 178.40 |
| q2-4206 | baseline_perp | 750.12 | (1592,1266) | 否 | 1817.31 | 90.77 | 659.34 | 200.00 |
| q2-4206 | baseline_mec | 750.12 | (457,742) | 是 | 750.12 | 375.10 | 375.02 | 150.02 |
| q2-4206 | reference | 750.12 | (207,742) | 是 | 838.72 | 94.21 | 655.91 | 167.74 |
| q2-4207 | optimal | 750.12 | (1205,476) | 是 | 899.09 | 90.85 | 659.27 | 179.82 |
| q2-4207 | baseline_perp | 750.12 | (578,1465) | 否 | 1817.31 | 90.78 | 659.34 | 200.00 |
| q2-4207 | baseline_mec | 750.12 | (1028,299) | 是 | 750.12 | 375.09 | 375.03 | 150.02 |
| q2-4207 | reference | 750.12 | (1028,49) | 是 | 852.52 | 92.97 | 657.15 | 170.50 |
| q2-4208 | optimal | 750.19 | (-1409,-294) | 是 | 901.20 | 90.75 | 659.44 | 180.24 |
| q2-4208 | baseline_perp | 750.19 | (-8,239) | 否 | 1817.46 | 90.79 | 659.40 | 200.00 |
| q2-4208 | baseline_mec | 750.19 | (-1167,-229) | 是 | 750.19 | 375.10 | 375.09 | 150.04 |
| q2-4208 | reference | 750.19 | (-1417,-229) | 是 | 849.54 | 93.05 | 657.14 | 169.91 |
| q2-4209 | optimal | 750.20 | (463,849) | 是 | 849.70 | 93.03 | 657.17 | 169.94 |
| q2-4209 | baseline_perp | 750.20 | (-621,1100) | 否 | 1817.43 | 90.79 | 659.41 | 200.00 |
| q2-4209 | baseline_mec | 750.20 | (527,607) | 是 | 750.20 | 375.10 | 375.10 | 150.04 |
| q2-4209 | reference | 750.20 | (527,857) | 是 | 901.34 | 90.74 | 659.46 | 180.27 |
| q2-4210 | optimal | 706.03 | (-429,1151) | 是 | 915.53 | 63.69 | 642.34 | 183.11 |
| q2-4210 | baseline_perp | 706.03 | (-206,15) | 否 | 1722.00 | 80.64 | 625.39 | 200.00 |
| q2-4210 | baseline_mec | 706.03 | (-145,1227) | 是 | 706.03 | 353.02 | 353.02 | 141.21 |
| q2-4210 | reference | 706.03 | (-366,1080) | 是 | 830.65 | 72.40 | 633.63 | 166.13 |
| q2-4211 | optimal | 750.20 | (-619,-443) | 是 | 901.34 | 90.74 | 659.46 | 180.27 |
| q2-4211 | baseline_perp | 750.20 | (-379,1037) | 否 | 1817.47 | 90.79 | 659.41 | 200.00 |
| q2-4211 | baseline_mec | 750.20 | (-554,-202) | 是 | 750.20 | 375.10 | 375.10 | 150.04 |
| q2-4211 | reference | 750.20 | (-554,-451) | 是 | 943.43 | 94.71 | 655.49 | 188.69 |
| q2-4212 | optimal | 750.13 | (343,-10) | 是 | 905.38 | 90.90 | 659.23 | 181.08 |
| q2-4212 | baseline_perp | 750.13 | (1486,-980) | 否 | 1817.34 | 90.78 | 659.35 | 200.00 |
| q2-4212 | baseline_mec | 750.13 | (520,-187) | 是 | 750.13 | 375.09 | 375.04 | 150.03 |
| q2-4212 | reference | 750.13 | (520,-437) | 是 | 845.04 | 93.65 | 656.48 | 169.01 |
| q2-4213 | optimal | 750.12 | (-347,-795) | 是 | 859.45 | 92.44 | 657.68 | 171.89 |
| q2-4213 | baseline_perp | 750.12 | (-1650,-75) | 否 | 1817.31 | 90.77 | 659.34 | 200.00 |
| q2-4213 | baseline_mec | 750.12 | (-524,-618) | 是 | 750.12 | 375.09 | 375.03 | 150.02 |
| q2-4213 | reference | 750.12 | (-524,-368) | 是 | 893.01 | 90.88 | 659.24 | 178.60 |
| q2-4214 | optimal | 750.16 | (623,-1142) | 是 | 906.31 | 90.87 | 659.29 | 181.26 |
| q2-4214 | baseline_perp | 750.16 | (-445,-639) | 否 | 1817.36 | 90.78 | 659.38 | 200.00 |
| q2-4214 | baseline_mec | 750.16 | (559,-1383) | 是 | 750.16 | 375.09 | 375.07 | 150.03 |
| q2-4214 | reference | 750.16 | (559,-1134) | 是 | 855.60 | 92.58 | 657.58 | 171.12 |
| q2-4215 | optimal | 559.27 | (-1338,120) | 是 | 820.56 | 35.56 | 523.71 | 164.11 |
| q2-4215 | baseline_perp | 559.27 | (-731,-1350) | 否 | 1513.40 | 59.96 | 499.32 | 200.00 |
| q2-4215 | baseline_mec | 559.27 | (-1224,-306) | 是 | 559.27 | 279.64 | 279.64 | 111.85 |
| q2-4215 | reference | 559.27 | (-1444,-636) | 是 | 828.17 | 35.86 | 523.42 | 165.63 |
| q2-4216 | optimal | 725.32 | (-758,-1062) | 是 | 869.88 | 65.59 | 659.73 | 173.97 |
| q2-4216 | baseline_perp | 725.32 | (-669,40) | 否 | 1747.41 | 79.80 | 645.52 | 200.00 |
| q2-4216 | baseline_mec | 725.32 | (-1023,-1133) | 是 | 725.32 | 362.66 | 362.66 | 145.06 |
| q2-4216 | reference | 725.32 | (-749,-1133) | 是 | 919.99 | 63.67 | 661.65 | 184.00 |
| q2-4217 | optimal | 750.16 | (-1472,727) | 是 | 848.85 | 93.13 | 657.03 | 169.77 |
| q2-4217 | baseline_perp | 750.16 | (10,819) | 否 | 1817.41 | 90.78 | 659.38 | 200.00 |
| q2-4217 | baseline_mec | 750.16 | (-1231,663) | 是 | 750.16 | 375.09 | 375.07 | 150.03 |
| q2-4217 | reference | 750.16 | (-1481,663) | 是 | 900.62 | 90.77 | 659.39 | 180.12 |
| q2-4218 | optimal | 750.18 | (-332,-300) | 是 | 864.09 | 92.27 | 657.91 | 172.82 |
| q2-4218 | baseline_perp | 750.18 | (-1821,-299) | 否 | 1817.39 | 90.78 | 659.39 | 200.00 |
| q2-4218 | baseline_mec | 750.18 | (-573,-235) | 是 | 750.18 | 375.09 | 375.08 | 150.04 |
| q2-4218 | reference | 750.18 | (-323,-235) | 是 | 913.40 | 91.48 | 658.69 | 182.68 |
| q2-4219 | optimal | 750.13 | (-75,786) | 是 | 868.14 | 91.76 | 658.37 | 173.63 |
| q2-4219 | baseline_perp | 750.13 | (-100,-705) | 否 | 1817.34 | 90.78 | 659.35 | 200.00 |
| q2-4219 | baseline_mec | 750.13 | (-140,544) | 是 | 750.13 | 375.09 | 375.04 | 150.03 |
| q2-4219 | reference | 750.13 | (-140,794) | 是 | 916.75 | 91.35 | 658.78 | 183.35 |
| q2-4220 | optimal | 750.13 | (-142,237) | 是 | 865.60 | 92.06 | 658.07 | 173.12 |
| q2-4220 | baseline_perp | 750.13 | (-1191,-184) | 否 | 1817.34 | 90.78 | 659.35 | 200.00 |
| q2-4220 | baseline_mec | 750.13 | (35,60) | 是 | 750.13 | 375.09 | 375.04 | 150.03 |
| q2-4220 | reference | 750.13 | (285,60) | 是 | 887.39 | 90.95 | 659.18 | 177.48 |
| q2-4221 | optimal | 750.12 | (537,-636) | 是 | 859.18 | 92.47 | 657.65 | 171.84 |
| q2-4221 | baseline_perp | 750.12 | (-232,638) | 否 | 1817.32 | 90.78 | 659.35 | 200.00 |
| q2-4221 | baseline_mec | 750.12 | (472,-395) | 是 | 750.12 | 375.09 | 375.03 | 150.02 |
| q2-4221 | reference | 750.12 | (472,-644) | 是 | 801.14 | 98.78 | 651.34 | 160.23 |
| q2-4222 | optimal | 672.85 | (1340,149) | 是 | 896.12 | 46.69 | 626.15 | 179.22 |
| q2-4222 | baseline_perp | 672.85 | (461,-526) | 否 | 1662.43 | 70.95 | 601.90 | 200.00 |
| q2-4222 | baseline_mec | 672.85 | (1571,-82) | 是 | 672.85 | 336.42 | 336.42 | 134.57 |
| q2-4222 | reference | 672.85 | (1326,82) | 是 | 830.57 | 53.42 | 619.43 | 166.11 |
| q2-4223 | optimal | 395.70 | (-1736,-787) | 是 | 696.84 | 21.22 | 374.48 | 139.37 |
| q2-4223 | baseline_perp | 395.70 | (-1461,-1548) | 否 | 1286.11 | 39.72 | 355.98 | 200.00 |
| q2-4223 | baseline_mec | 395.70 | (-1416,-467) | 是 | 395.70 | 197.85 | 197.85 | 79.14 |
| q2-4223 | reference | 395.70 | (-1416,-14) | 是 | 716.03 | 20.83 | 374.87 | 143.21 |
| q2-4224 | optimal | 750.16 | (-899,669) | 是 | 888.47 | 90.87 | 659.29 | 177.69 |
| q2-4224 | baseline_perp | 750.16 | (467,1281) | 否 | 1817.40 | 90.78 | 659.38 | 200.00 |
| q2-4224 | baseline_mec | 750.16 | (-657,734) | 是 | 750.16 | 375.09 | 375.07 | 150.03 |
| q2-4224 | reference | 750.16 | (-907,734) | 是 | 834.61 | 94.50 | 655.66 | 166.92 |
| q2-4225 | optimal | 750.12 | (-305,-294) | 是 | 866.51 | 91.95 | 658.17 | 173.30 |
| q2-4225 | baseline_perp | 750.12 | (-1064,-1577) | 否 | 1817.31 | 90.77 | 659.34 | 200.00 |
| q2-4225 | baseline_mec | 750.12 | (-482,-470) | 是 | 750.12 | 375.10 | 375.02 | 150.02 |
| q2-4225 | reference | 750.12 | (-732,-470) | 是 | 886.54 | 91.02 | 659.10 | 177.31 |
| q2-4226 | optimal | 750.12 | (587,389) | 是 | 898.38 | 90.90 | 659.22 | 179.68 |
| q2-4226 | baseline_perp | 750.12 | (1757,433) | 否 | 1817.31 | 90.77 | 659.34 | 200.00 |
| q2-4226 | baseline_mec | 750.12 | (523,630) | 是 | 750.12 | 375.11 | 375.01 | 150.02 |
| q2-4226 | reference | 750.12 | (523,380) | 是 | 941.12 | 94.47 | 655.65 | 188.22 |
| q2-4227 | optimal | 527.91 | (711,-1627) | 是 | 843.99 | 29.98 | 497.92 | 168.80 |
| q2-4227 | baseline_perp | 527.91 | (1503,-1122) | 否 | 1466.90 | 55.63 | 472.28 | 200.00 |
| q2-4227 | baseline_mec | 527.91 | (377,-1293) | 是 | 527.91 | 263.95 | 263.95 | 105.58 |
| q2-4227 | reference | 527.91 | (-95,-1293) | 是 | 819.70 | 30.74 | 497.17 | 163.94 |
| q2-4228 | optimal | 750.12 | (-160,534) | 是 | 892.39 | 90.93 | 659.19 | 178.48 |
| q2-4228 | baseline_perp | 750.12 | (20,2020) | 否 | 1817.31 | 90.77 | 659.34 | 200.00 |
| q2-4228 | baseline_mec | 750.12 | (-96,775) | 是 | 750.12 | 375.11 | 375.01 | 150.02 |
| q2-4228 | reference | 750.12 | (-96,525) | 是 | 936.39 | 93.58 | 656.54 | 187.28 |
| q2-4229 | optimal | 750.20 | (455,-883) | 是 | 876.70 | 91.34 | 658.86 | 175.34 |
| q2-4229 | baseline_perp | 750.20 | (-684,-787) | 否 | 1817.44 | 90.79 | 659.41 | 200.00 |
| q2-4229 | baseline_mec | 750.20 | (519,-1124) | 是 | 750.20 | 375.10 | 375.10 | 150.04 |
| q2-4229 | reference | 750.20 | (519,-874) | 是 | 923.76 | 91.91 | 658.30 | 184.75 |
## 逐方法汇总
| 方法 | 保证接收率 | 最坏后验均值(m) | 中位(m) | 平均收缩(m) | 终值比 ρ'/ρ | 移动均值(s) |
| --- | --- | --- | --- | --- | --- | --- |
| optimal | 100.0% | 73.89 | 90.90 | 607.58 | 0.104 | 170.44 |
| baseline_perp | 0.0% | 80.11 | 90.78 | 601.36 | 0.116 | 200.00 |
| baseline_mec | 100.0% | 340.75 | 375.09 | 340.72 | 0.500 | 136.29 |
| reference | 100.0% | 75.63 | 91.35 | 605.84 | 0.106 | 170.28 |
初始 ρ 均值:681.47 m
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
# 问题三:全向闭环配对对比(core 基准集)
## 逐场景明细
| scene | sources | variant | cleared | T(s) | 检测 | 请求 | 位移(m) | 后备清除 | 墙钟(s) | 有效 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| q3-core-s100-n10 | 10 | optimal | 10/10 | 2563.0 | 109 | 119 | 9330.1 | 0 | 0.70 | ✔ |
| q3-core-s100-n10 | 10 | seven | 10/10 | 4465.5 | 102 | 112 | 19057.6 | 0 | 1.18 | ✔ |
| q3-core-s100-n10 | 10 | baseline | 10/10 | 15309.6 | 564 | 574 | 59457.9 | 0 | 1.16 | ✔ |
| q3-core-s100-n13 | 13 | optimal | 13/13 | 3120.8 | 114 | 127 | 11914.1 | 0 | 0.73 | ✔ |
| q3-core-s100-n13 | 13 | seven | 13/13 | 5216.0 | 96 | 109 | 22919.8 | 0 | 1.40 | ✔ |
| q3-core-s100-n13 | 13 | baseline | 13/13 | 16205.3 | 450 | 463 | 67311.6 | 0 | 1.46 | ✔ |
| q3-core-s100-n16 | 16 | optimal | 16/16 | 3618.1 | 113 | 129 | 14355.4 | 0 | 0.89 | ✔ |
| q3-core-s100-n16 | 16 | seven | 16/16 | 5978.8 | 96 | 112 | 26653.8 | 0 | 1.66 | ✔ |
| q3-core-s100-n16 | 16 | baseline | 16/16 | 13180.4 | 254 | 270 | 58011.9 | 0 | 1.85 | ✔ |
| q3-core-s101-n10 | 10 | optimal | 10/10 | 3101.7 | 119 | 129 | 11723.5 | 0 | 0.69 | ✔ |
| q3-core-s101-n10 | 10 | seven | 10/10 | 4498.1 | 107 | 117 | 19065.6 | 0 | 1.11 | ✔ |
| q3-core-s101-n10 | 10 | baseline | 10/10 | 15552.8 | 545 | 555 | 61248.9 | 0 | 1.15 | ✔ |
| q3-core-s101-n13 | 13 | optimal | 13/13 | 2943.3 | 112 | 125 | 11106.4 | 0 | 0.85 | ✔ |
| q3-core-s101-n13 | 13 | seven | 13/13 | 5390.3 | 101 | 114 | 23656.4 | 0 | 1.43 | ✔ |
| q3-core-s101-n13 | 13 | baseline | 13/13 | 16620.6 | 452 | 465 | 69338.1 | 0 | 1.60 | ✔ |
| q3-core-s101-n16 | 16 | optimal | 16/16 | 3560.0 | 99 | 115 | 14469.9 | 0 | 0.81 | ✔ |
| q3-core-s101-n16 | 16 | seven | 16/16 | 6462.4 | 92 | 108 | 29211.8 | 0 | 1.76 | ✔ |
| q3-core-s101-n16 | 16 | baseline | 16/16 | 13434.4 | 260 | 276 | 59121.8 | 0 | 1.96 | ✔ |
| q3-core-s102-n10 | 10 | optimal | 10/10 | 2916.0 | 125 | 135 | 10634.8 | 0 | 0.58 | ✔ |
| q3-core-s102-n10 | 10 | seven | 10/10 | 5411.3 | 118 | 128 | 23326.6 | 0 | 1.28 | ✔ |
| q3-core-s102-n10 | 10 | baseline | 10/10 | 15015.5 | 613 | 623 | 56517.5 | 0 | 1.28 | ✔ |
| q3-core-s102-n13 | 13 | optimal | 13/13 | 3039.5 | 122 | 135 | 11242.3 | 0 | 0.84 | ✔ |
| q3-core-s102-n13 | 13 | seven | 13/13 | 5209.5 | 112 | 125 | 22407.3 | 0 | 1.52 | ✔ |
| q3-core-s102-n13 | 13 | baseline | 13/13 | 16062.8 | 450 | 463 | 66603.8 | 0 | 1.54 | ✔ |
| q3-core-s102-n16 | 16 | optimal | 16/16 | 3266.2 | 119 | 135 | 12441.1 | 0 | 0.74 | ✔ |
| q3-core-s102-n16 | 16 | seven | 16/16 | 5549.9 | 97 | 113 | 24489.6 | 0 | 1.65 | ✔ |
| q3-core-s102-n16 | 16 | baseline | 16/16 | 13146.4 | 282 | 298 | 57012.1 | 0 | 1.71 | ✔ |
| q3-core-s103-n10 | 10 | optimal | 10/10 | 2847.8 | 112 | 122 | 10684.1 | 0 | 0.68 | ✔ |
| q3-core-s103-n10 | 10 | seven | 10/10 | 4877.3 | 110 | 120 | 20886.4 | 0 | 1.22 | ✔ |
| q3-core-s103-n10 | 10 | baseline | 10/10 | 14895.2 | 550 | 560 | 57815.9 | 0 | 1.27 | ✔ |
| q3-core-s103-n13 | 13 | optimal | 13/13 | 3339.9 | 114 | 127 | 13024.4 | 0 | 0.71 | ✔ |
| q3-core-s103-n13 | 13 | seven | 13/13 | 5344.6 | 102 | 115 | 23373.1 | 0 | 1.26 | ✔ |
| q3-core-s103-n13 | 13 | baseline | 13/13 | 16691.4 | 501 | 514 | 68212.0 | 0 | 1.56 | ✔ |
| q3-core-s103-n16 | 16 | optimal | 16/16 | 3378.8 | 99 | 115 | 13559.2 | 0 | 0.89 | ✔ |
| q3-core-s103-n16 | 16 | seven | 16/16 | 5526.4 | 87 | 103 | 24681.8 | 0 | 1.77 | ✔ |
| q3-core-s103-n16 | 16 | baseline | 16/16 | 12627.8 | 256 | 272 | 55189.0 | 0 | 1.83 | ✔ |
| q3-core-s104-n10 | 10 | optimal | 10/10 | 3317.0 | 115 | 125 | 12950.2 | 0 | 0.66 | ✔ |
| q3-core-s104-n10 | 10 | seven | 10/10 | 4915.9 | 105 | 115 | 21219.3 | 0 | 1.06 | ✔ |
| q3-core-s104-n10 | 10 | baseline | 10/10 | 15302.4 | 549 | 559 | 59887.2 | 0 | 1.19 | ✔ |
| q3-core-s104-n13 | 13 | optimal | 13/13 | 3085.2 | 99 | 112 | 12176.2 | 0 | 0.75 | ✔ |
| q3-core-s104-n13 | 13 | seven | 13/13 | 5437.5 | 97 | 110 | 24012.7 | 0 | 1.48 | ✔ |
| q3-core-s104-n13 | 13 | baseline | 13/13 | 16278.7 | 444 | 457 | 67868.5 | 0 | 1.56 | ✔ |
| q3-core-s104-n16 | 16 | optimal | 16/16 | 3057.8 | 85 | 101 | 12379.1 | 0 | 0.77 | ✔ |
| q3-core-s104-n16 | 16 | seven | 16/16 | 5340.9 | 85 | 101 | 23799.8 | 0 | 1.68 | ✔ |
| q3-core-s104-n16 | 16 | baseline | 16/16 | 12872.6 | 224 | 240 | 57378.0 | 0 | 2.00 | ✔ |
| q3-core-s105-n10 | 10 | optimal | 10/10 | 2933.1 | 108 | 118 | 11220.4 | 0 | 0.72 | ✔ |
| q3-core-s105-n10 | 10 | seven | 10/10 | 4370.8 | 107 | 117 | 18433.9 | 0 | 1.08 | ✔ |
| q3-core-s105-n10 | 10 | baseline | 10/10 | 15247.7 | 579 | 589 | 58688.4 | 0 | 1.17 | ✔ |
| q3-core-s105-n13 | 13 | optimal | 13/13 | 3645.3 | 122 | 135 | 14331.4 | 0 | 0.96 | ✔ |
| q3-core-s105-n13 | 13 | seven | 13/13 | 6311.3 | 104 | 117 | 28171.5 | 0 | 1.66 | ✔ |
| q3-core-s105-n13 | 13 | baseline | 13/13 | 16509.4 | 485 | 498 | 67791.8 | 0 | 1.52 | ✔ |
| q3-core-s105-n16 | 16 | optimal | 16/16 | 3663.7 | 114 | 130 | 14543.5 | 0 | 0.81 | ✔ |
| q3-core-s105-n16 | 16 | seven | 16/16 | 6204.3 | 97 | 113 | 27776.7 | 0 | 1.55 | ✔ |
| q3-core-s105-n16 | 16 | baseline | 16/16 | 13889.0 | 292 | 308 | 60450.1 | 0 | 1.94 | ✔ |
## 逐方法汇总
| 方法 | 有效局 | 全清率 | 全清对数 | 缺席误判 | T 均值(s) | T 中位(s) | T 最大(s) | 检测均值 | 请求均值 | 位移均值(m) | 后备清除均值 | 墙钟均值(s) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| optimal | 18/18 | 1.00 | 18 | 0 | 3188.7 | 3111.3 | 3663.7 | 111.1 | 124.1 | 12338.1 | 0.00 | 0.77 |
| seven | 18/18 | 1.00 | 18 | 0 | 5361.7 | 5367.5 | 6462.4 | 100.8 | 113.8 | 23508.0 | 0.00 | 1.43 |
| baseline | 18/18 | 1.00 | 18 | 0 | 14935.7 | 15275.1 | 16691.4 | 430.6 | 443.6 | 61550.2 | 0.00 | 1.54 |
## 相对基线的配对变化(虚拟时间)
| 配对 | 均值变化 | 中位变化 | 更快场景 | 双方均有效 |
| --- | --- | --- | --- | --- |
| optimal_vs_baseline | -78.4% | -80.0% | 18/18 | 18 |
| seven_vs_baseline | -63.7% | -66.9% | 18/18 | 18 |
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
# 问题四:混合源闭环配对对比(core+boundary 基准集)
## 逐场景明细
| scene | sources | variant | cleared | T(s) | 检测 | 请求 | 位移(m) | 后备清除 | 墙钟(s) | 有效 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| q4-boundary-n10-d5 | 10 | optimal | 10/10 | 10269.5 | 488 | 540 | 36107.7 | 44 | 2.63 | ✔ |
| q4-boundary-n10-d5 | 10 | baseline_grid | 6/10 | 17632.7 | 735 | 741 | 66308.6 | 0 | 5.08 | ✘ |
| q4-boundary-n10-d5 | 10 | baseline | 5/10 | 3128.1 | 135 | 140 | 11530.4 | 0 | 0.53 | ✘ |
| q4-boundary-n16-d8 | 16 | optimal | 16/16 | 12081.1 | 421 | 626 | 44820.7 | 190 | 3.58 | ✔ |
| q4-boundary-n16-d8 | 16 | baseline_grid | 9/16 | 20457.9 | 623 | 632 | 83969.3 | 0 | 8.86 | ✘ |
| q4-boundary-n16-d8 | 16 | baseline | 8/16 | 3558.7 | 149 | 157 | 13173.5 | 0 | 0.52 | ✘ |
| q4-core-s200-n10-d3 | 10 | optimal | 10/10 | 8718.7 | 402 | 412 | 31508.6 | 0 | 8.30 | ✔ |
| q4-core-s200-n10-d3 | 10 | baseline_grid | 9/10 | 16546.8 | 576 | 585 | 65379.2 | 0 | 2.81 | ✘ |
| q4-core-s200-n10-d3 | 10 | baseline | 10/10 | 3354.1 | 116 | 126 | 13100.5 | 0 | 0.67 | ✘ |
| q4-core-s200-n13-d6 | 13 | optimal | 13/13 | 8808.4 | 332 | 347 | 33967.1 | 3 | 2.82 | ✔ |
| q4-core-s200-n13-d6 | 13 | baseline_grid | 7/13 | 18438.3 | 529 | 536 | 76651.4 | 0 | 8.21 | ✘ |
| q4-core-s200-n13-d6 | 13 | baseline | 11/13 | 3264.4 | 111 | 122 | 12761.9 | 0 | 0.80 | ✘ |
| q4-core-s200-n16-d8 | 16 | optimal | 16/16 | 7629.2 | 267 | 283 | 29970.8 | 0 | 3.27 | ✔ |
| q4-core-s200-n16-d8 | 16 | baseline_grid | 10/16 | 18871.3 | 526 | 536 | 78861.6 | 0 | 9.06 | ✘ |
| q4-core-s200-n16-d8 | 16 | baseline | 12/16 | 4026.1 | 143 | 155 | 15645.6 | 0 | 1.86 | ✘ |
| q4-core-s201-n10-d3 | 10 | optimal | 10/10 | 8514.0 | 380 | 391 | 31129.9 | 2 | 2.07 | ✔ |
| q4-core-s201-n10-d3 | 10 | baseline_grid | 7/10 | 16779.7 | 624 | 631 | 65293.4 | 0 | 5.71 | ✘ |
| q4-core-s201-n10-d3 | 10 | baseline | 7/10 | 2823.3 | 120 | 127 | 10391.4 | 0 | 0.71 | ✘ |
| q4-core-s201-n13-d6 | 13 | optimal | 13/13 | 9183.0 | 325 | 338 | 36095.1 | 0 | 2.50 | ✔ |
| q4-core-s201-n13-d6 | 13 | baseline_grid | 8/13 | 19390.8 | 584 | 592 | 79678.9 | 0 | 4.40 | ✘ |
| q4-core-s201-n13-d6 | 13 | baseline | 11/13 | 4965.2 | 143 | 165 | 20260.8 | 0 | 1.11 | ✘ |
| q4-core-s201-n16-d8 | 16 | optimal | 16/16 | 8129.4 | 263 | 279 | 32667.0 | 0 | 3.50 | ✔ |
| q4-core-s201-n16-d8 | 16 | baseline_grid | 9/16 | 19845.0 | 495 | 504 | 84765.2 | 0 | 10.22 | ✘ |
| q4-core-s201-n16-d8 | 16 | baseline | 13/16 | 4759.1 | 125 | 138 | 19835.5 | 0 | 2.12 | ✘ |
| q4-core-s202-n10-d3 | 10 | optimal | 10/10 | 8803.3 | 420 | 430 | 31426.3 | 0 | 2.36 | ✔ |
| q4-core-s202-n10-d3 | 10 | baseline_grid | 7/10 | 17220.0 | 669 | 676 | 66144.9 | 0 | 5.13 | ✘ |
| q4-core-s202-n10-d3 | 10 | baseline | 7/10 | 3646.2 | 135 | 142 | 14105.9 | 0 | 0.68 | ✘ |
| q4-core-s202-n13-d6 | 13 | optimal | 13/13 | 9630.4 | 347 | 367 | 37652.0 | 10 | 3.11 | ✔ |
| q4-core-s202-n13-d6 | 13 | baseline_grid | 10/13 | 16443.2 | 498 | 508 | 67316.3 | 0 | 1.84 | ✘ |
| q4-core-s202-n13-d6 | 13 | baseline | 13/13 | 4219.3 | 123 | 137 | 17136.7 | 0 | 0.81 | ✘ |
| q4-core-s202-n16-d8 | 16 | optimal | 16/16 | 8001.5 | 267 | 305 | 31602.7 | 24 | 3.95 | ✔ |
| q4-core-s202-n16-d8 | 16 | baseline_grid | 12/16 | 18345.2 | 452 | 464 | 78265.8 | 0 | 8.90 | ✘ |
| q4-core-s202-n16-d8 | 16 | baseline | 13/16 | 5054.4 | 152 | 165 | 20561.9 | 0 | 2.05 | ✘ |
## 逐方法汇总
| 方法 | 有效局 | 全清率 | 全清对数 | 缺席误判 | T 均值(s) | T 中位(s) | T 最大(s) | 检测均值 | 请求均值 | 位移均值(m) | 后备清除均值 | 墙钟均值(s) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| optimal | 11/11 | 1.00 | 11 | 0 | 9069.9 | 8803.3 | 12081.1 | 355.6 | 392.5 | 34268.0 | 24.82 | 3.46 |
| baseline_grid | 0/11 | 0.67 | 0 | 0 | 18179.2 | 18345.2 | 20457.9 | 573.7 | 582.3 | 73875.9 | 0.00 | 6.38 |
| baseline | 0/11 | 0.77 | 2 | 24 | 3890.8 | 3646.2 | 5054.4 | 132.0 | 143.1 | 15318.6 | 0.00 | 1.08 |
## 相对基线的配对变化(虚拟时间)
| 配对 | 均值变化 | 中位变化 | 更快场景 | 双方均有效 |
| --- | --- | --- | --- | --- |
| optimal_vs_baseline | +142.9% | +141.4% | 0/11 | 0 |
| baseline_grid_vs_baseline | +381.1% | +372.3% | 0/11 | 0 |
> 注:optimal_vs_baseline、baseline_grid_vs_baseline 存在未通过有效性判定的配对;其虚拟时间仅作参考,基线未完成全清任务时不构成「更快」证据(以「双方均有效」列为准)。
+50
View File
@@ -0,0 +1,50 @@
# 1-4 问最优 vs 基线:对比总览
本节所有数字由 `uv run python -m project.run` 在同机同口径下生成,
逐问明细见 `q1.md` … `q4.md`。
| 问 | 核心指标 | 最优实现 | 基线实现 |
| --- | --- | --- | --- |
| 1 | 直径平均误差 / 覆盖准确率 | 0.00 m / 100% | 4.58 m / 52% |
| 2 | 保证接收率 / 最坏后验均值 | 100% / 73.9 m | 100% / 340.7 m |
| 3 | 全清率 / T 均值(相对基线) | 100% / 3189 s (-78%) | 100% / 14936 s |
| 4 | 全清率 / 缺席误判(问题三策略搬用) | 100% / 0 | 77% / 24 |
## 方法映射
| 问 | 最优实现 | 基线实现 | 独立参考 |
| --- | --- | --- | --- |
| 1 | 半平面交 + 顶点对直径 + MEC | 网格采样 + bbox 对角线代理 | 大框半平面裁剪 + 精确直径/MEC |
| 2 | 保证接收盘内最小最坏后验半径 | 垂直 1000 m / MEC 圆心 | 保证接收盘内网格枚举 |
| 3 | bayes(粒子滤波 + 信息增益 + 滚动调度) | grid(49 点网格)/ seven(七点批量) | 冻结基准集 + 逐微秒计时复算 |
| 4 | directional(联合信念 + 后备清除) | bayes / grid 直接搬用 | 冻结基准集 + 真值全清校验 |
## 目录结构
```text
project/
├── common.py 公共层:方法描述/指标聚合/结果落盘/闭环装配
├── q1/ 问题一:直径与直径圆覆盖
│ ├── optimal.py 生产实现:半平面交 + 顶点对直径 + MEC
│ ├── baseline.py 基线:网格采样 + bbox 对角线代理
│ ├── reference.py 参考:大框半平面裁剪 + 精确直径/MEC
│ ├── cases.py 固定示例(examples/q1)+ 随机交会算例
│ └── compare.py 同案配对对比
├── q2/ 问题二:第二检测点选择
│ ├── optimal.py 生产实现:保证接收盘内最小最坏后验半径
│ ├── baseline.py 基线:垂直 1000 m / MEC 圆心
│ ├── reference.py 参考:保证接收盘内网格枚举
│ ├── region.py K1 统一构造
│ ├── cases.py 随机首次示向度算例
│ └── compare.py
├── q3/ 问题三:全向闭环
│ ├── optimal.py bayes(生产默认策略)
│ ├── baseline.py grid(49 点网格)/ seven(七点批量)
│ └── compare.py
├── q4/ 问题四:混合源闭环
│ ├── optimal.py directional(定向扩展)
│ ├── baseline.py bayes / grid 直接搬用
│ └── compare.py
├── run.py 统一入口(本文件)
└── results/ 自动生成:q1.md/json … q4.md/json + summary.md
```
+148
View File
@@ -0,0 +1,148 @@
"""统一入口:一次跑完 1-4 问的"最优 vs 基线"对比并生成 results/。
用法(仓库根目录)::
uv run python -m project.run # 四问全部
uv run python -m project.run --question 3 # 只跑第三问
uv run python -m project.run --quick # 缩小算例/基准集规模
"""
from __future__ import annotations
import argparse
import time
from project.common import RESULTS_DIR, markdown_table, write_text
from project.q1 import compare as q1_compare
from project.q2 import compare as q2_compare
from project.q3 import compare as q3_compare
from project.q4 import compare as q4_compare
RUNNERS = {
1: q1_compare.run,
2: q2_compare.run,
3: q3_compare.run,
4: q4_compare.run,
}
STRUCTURE = """\
project/
├── common.py 公共层:方法描述/指标聚合/结果落盘/闭环装配
├── q1/ 问题一:直径与直径圆覆盖
│ ├── optimal.py 生产实现:半平面交 + 顶点对直径 + MEC
│ ├── baseline.py 基线:网格采样 + bbox 对角线代理
│ ├── reference.py 参考:大框半平面裁剪 + 精确直径/MEC
│ ├── cases.py 固定示例(examples/q1)+ 随机交会算例
│ └── compare.py 同案配对对比
├── q2/ 问题二:第二检测点选择
│ ├── optimal.py 生产实现:保证接收盘内最小最坏后验半径
│ ├── baseline.py 基线:垂直 1000 m / MEC 圆心
│ ├── reference.py 参考:保证接收盘内网格枚举
│ ├── region.py K1 统一构造
│ ├── cases.py 随机首次示向度算例
│ └── compare.py
├── q3/ 问题三:全向闭环
│ ├── optimal.py bayes(生产默认策略)
│ ├── baseline.py grid(49 点网格)/ seven(七点批量)
│ └── compare.py
├── q4/ 问题四:混合源闭环
│ ├── optimal.py directional(定向扩展)
│ ├── baseline.py bayes / grid 直接搬用
│ └── compare.py
├── run.py 统一入口(本文件)
└── results/ 自动生成:q1.md/json … q4.md/json + summary.md
"""
def _q1_headline(payload: dict) -> list[str]:
agg = payload["aggregate_random"]
return ["1", "直径平均误差 / 覆盖准确率",
f"{agg['diameter_mae_optimal_m']:.2f} m / "
f"{agg['coverage_accuracy_optimal']*100:.0f}%",
f"{agg['diameter_mae_baseline_m']:.2f} m / "
f"{agg['coverage_accuracy_baseline']*100:.0f}%"]
def _q2_headline(payload: dict) -> list[str]:
agg = payload["aggregate"]
opt = agg["optimal"]
base = agg["baseline_mec"]
return ["2", "保证接收率 / 最坏后验均值",
f"{opt['guaranteed_rate']*100:.0f}% / "
f"{opt['worst_posterior_mean_m']:.1f} m",
f"{base['guaranteed_rate']*100:.0f}% / "
f"{base['worst_posterior_mean_m']:.1f} m"]
def _q3_headline(payload: dict) -> list[str]:
agg = payload["aggregate"]["variants"]
opt, base = agg["optimal"], agg["baseline"]
paired = payload["aggregate"]["paired"].get("optimal_vs_baseline", {})
return ["3", "全清率 / T 均值(相对基线)",
f"{opt['cleared_ratio_mean']*100:.0f}% / "
f"{opt['virtual_time_mean_s']:.0f} s "
f"({paired.get('mean_relative_change', 0)*100:+.0f}%)",
f"{base['cleared_ratio_mean']*100:.0f}% / "
f"{base['virtual_time_mean_s']:.0f} s"]
def _q4_headline(payload: dict) -> list[str]:
agg = payload["aggregate"]["variants"]
opt, base = agg["optimal"], agg["baseline"]
return ["4", "全清率 / 缺席误判(问题三策略搬用)",
f"{opt['cleared_ratio_mean']*100:.0f}% / "
f"{opt['absent_misjudged_total']}",
f"{base['cleared_ratio_mean']*100:.0f}% / "
f"{base['absent_misjudged_total']}"]
def _write_summary(payloads: dict[int, dict]) -> None:
lines = ["# 1-4 问最优 vs 基线:对比总览", "",
"本节所有数字由 `uv run python -m project.run` 在同机同口径下生成,",
"逐问明细见 `q1.md` … `q4.md`。", ""]
rows = []
if 1 in payloads:
rows.append(_q1_headline(payloads[1]))
if 2 in payloads:
rows.append(_q2_headline(payloads[2]))
if 3 in payloads:
rows.append(_q3_headline(payloads[3]))
if 4 in payloads:
rows.append(_q4_headline(payloads[4]))
lines.append(markdown_table(["问", "核心指标", "最优实现", "基线实现"], rows))
lines += ["", "## 方法映射", "",
"| 问 | 最优实现 | 基线实现 | 独立参考 |",
"| --- | --- | --- | --- |",
"| 1 | 半平面交 + 顶点对直径 + MEC | 网格采样 + bbox 对角线代理 | 大框半平面裁剪 + 精确直径/MEC |",
"| 2 | 保证接收盘内最小最坏后验半径 | 垂直 1000 m / MEC 圆心 | 保证接收盘内网格枚举 |",
"| 3 | bayes(粒子滤波 + 信息增益 + 滚动调度) | grid(49 点网格)/ seven(七点批量) | 冻结基准集 + 逐微秒计时复算 |",
"| 4 | directional(联合信念 + 后备清除) | bayes / grid 直接搬用 | 冻结基准集 + 真值全清校验 |",
"", "## 目录结构", "", "```text", STRUCTURE.rstrip(), "```", ""]
write_text(RESULTS_DIR / "summary.md", "\n".join(lines))
def main(argv=None) -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("--question", choices=("1", "2", "3", "4", "all"),
default="all")
parser.add_argument("--quick", action="store_true",
help="缩小随机算例数/冻结基准集规模")
args = parser.parse_args(argv)
selected = [1, 2, 3, 4] if args.question == "all" else [int(args.question)]
payloads: dict[int, dict] = {}
for question in selected:
start = time.perf_counter()
print(f"[Q{question}] 运行对比 …", flush=True)
payloads[question] = RUNNERS[question](quick=args.quick)
print(f"[Q{question}] 完成,用时 {time.perf_counter() - start:.1f}s",
flush=True)
if selected == [1, 2, 3, 4]:
_write_summary(payloads)
print(f"总览已写入 {RESULTS_DIR / 'summary.md'}")
print(f"结果目录:{RESULTS_DIR}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
-5
View File
@@ -1,5 +0,0 @@
from .curriculum import STAGES, Stage, make_scene, training_config
from .domain_randomization import randomize_problem_config
__all__ = ["STAGES", "Stage", "make_scene", "training_config",
"randomize_problem_config"]
-6
View File
@@ -1,6 +0,0 @@
"""兼容入口:课程学习与域随机化。"""
from mcm26b.hrl.curriculum import (STAGES, Stage, make_scene, stage_with_noise,
training_config, training_spec)
__all__ = ["STAGES", "Stage", "make_scene", "stage_with_noise",
"training_config", "training_spec"]
-31
View File
@@ -1,31 +0,0 @@
"""兼容入口:本地域随机化参数包装。
当前真实随机化在 mcm26b.hrl.curriculum.make_scene 内完成;这里只暴露
ProblemConfig 的显式替换助手,便于 Optuna/消融在实验配置中记录随机化范围。
"""
from __future__ import annotations
import dataclasses
from random import Random
from mcm26b.config import ProblemConfig
def randomize_problem_config(base: ProblemConfig, *, seed: int,
bearing_error_half_deg: float | None = None,
r_eff_range: tuple[float, float] | None = None
) -> ProblemConfig:
"""返回带域随机化标量的新配置;不修改全局默认配置。"""
_rng = Random(seed) # 固定种子留作兼容:真实随机化在 make_scene 内完成
field = base.field
if bearing_error_half_deg is None:
bearing_error_half_deg = field.bearing_error_half_deg
if r_eff_range is not None:
lo, hi = r_eff_range
if not 0 <= lo <= hi:
raise ValueError("r_eff_range 必须为递增非负区间")
return dataclasses.replace(base, field=dataclasses.replace(
field, bearing_error_half_deg=float(bearing_error_half_deg)))
__all__ = ["randomize_problem_config"]
-20
View File
@@ -1,20 +0,0 @@
"""兼容入口:调用 scripts/tune_hrl.py(P2 后启用)。"""
from __future__ import annotations
import importlib.util
from pathlib import Path
def run_tuning(argv=None) -> int:
path = Path(__file__).resolve().parents[2] / "scripts" / "tune_hrl.py"
if not path.exists():
raise NotImplementedError(
"scripts/tune_hrl.py 尚未实现;P1 阶段先冻结超参并留待 P2。")
spec = importlib.util.spec_from_file_location("tune_hrl_compat", path)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return int(module.main(argv))
__all__ = ["run_tuning"]
+1 -18
View File
@@ -15,30 +15,13 @@ dev = [
# 独立评测机(自建模拟器):仅测试侧依赖,运行时代码零导入(懒加载 + 守卫测试)
"mcm26b-referee",
]
rl = [
"gymnasium>=1.1",
"sb3-contrib==2.9.0",
"stable-baselines3>=2.6",
"torch==2.11.0",
]
# uv 工作区:referee/ 是独立包(零第三方依赖、不依赖 mcm26b),双方仅通过 HTTP 协议耦合
[tool.uv.workspace]
members = ["referee"]
# RL 训练使用 CUDA 12.8 版 PyTorch(本机 RTX 4060;运行时依赖保持轻量)。
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
[tool.uv.sources]
mcm26b-referee = { workspace = true }
# CUDA 12.8 版 PyTorch 仅限 Windows/Linux(RTX 4060 训练机);
# macOS (Apple Silicon, MPS) 回落到 PyPI 官方轮子。
torch = [
{ index = "pytorch-cu128", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
[build-system]
requires = ["hatchling"]
@@ -102,7 +85,7 @@ disable = [
"missing-module-docstring", # 内部小模块与 __main__ 不强制
"missing-class-docstring",
"missing-function-docstring",
"import-outside-toplevel", # torch/SB3/referee 等重依赖与可选依赖懒加载
"import-outside-toplevel", # referee 等重依赖与可选依赖懒加载
"wrong-import-position", # 同上:importorskip 守卫后的延迟导入
"ungrouped-imports", # 同上:延迟导入无法与顶部导入分组
"broad-exception-caught", # 子进程 / IO / HTTP 边界防御式兜底,逐处注释
@@ -0,0 +1,122 @@
{"event": "session_start", "case_code": "53FK-LELA-M62B-J74U", "module": "q3_practice", "robot_id": "1", "seed": 1364411664, "countdown_s": 5.0, "window_s": 1500.0, "max_real_duration_s": 1200.0, "truth": [{"channel": 18, "x": 1296.7141429697774, "y": -444.4430546050354, "r_eff_m": 1239.1782567152018, "directional": false, "heading_deg": 0.0}, {"channel": 17, "x": 1020.5918585779062, "y": 852.2515595937525, "r_eff_m": 1026.5206174583245, "directional": false, "heading_deg": 0.0}, {"channel": 1, "x": 580.5002167548972, "y": -991.4701530799936, "r_eff_m": 1237.8121709043808, "directional": false, "heading_deg": 0.0}, {"channel": 2, "x": -16.348424904475735, "y": -478.6435890197983, "r_eff_m": 1099.9814484291328, "directional": false, "heading_deg": 0.0}, {"channel": 3, "x": -677.9492703745801, "y": 1597.8849010804165, "r_eff_m": 1497.7568411784152, "directional": false, "heading_deg": 0.0}, {"channel": 16, "x": 941.6921106181675, "y": 1045.53299027287, "r_eff_m": 1391.826351188507, "directional": false, "heading_deg": 0.0}, {"channel": 15, "x": 261.02174414951065, "y": -1297.210479453902, "r_eff_m": 1464.8227234548847, "directional": false, "heading_deg": 0.0}, {"channel": 12, "x": 889.7578735792483, "y": 1513.108837479721, "r_eff_m": 1223.8000521319436, "directional": false, "heading_deg": 0.0}, {"channel": 7, "x": 716.9679630720734, "y": -1036.910162951016, "r_eff_m": 1445.0475739763483, "directional": false, "heading_deg": 0.0}, {"channel": 4, "x": 100.68070249674014, "y": 108.02794787019978, "r_eff_m": 1176.2905736642158, "directional": false, "heading_deg": 0.0}, {"channel": 13, "x": -291.4835840002278, "y": -1010.1772742830697, "r_eff_m": 1200.9184419942253, "directional": false, "heading_deg": 0.0}, {"channel": 9, "x": 282.13965648638487, "y": 40.4254513417698, "r_eff_m": 1456.4760272053131, "directional": false, "heading_deg": 0.0}, {"channel": 10, "x": 684.7259065078848, "y": -430.9034644685128, "r_eff_m": 1479.4906472616449, "directional": false, "heading_deg": 0.0}]}
{"event": "action", "seq": 1, "wall_ts_ms": 1789180957555, "method": "POST", "path": "/enter", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0001"}, "response": {"accepted": true, "real_timestamp_ms": 1789180957555, "virtual_time_s": 0.0, "max_virtual_duration_s": 360000.0, "max_real_duration_s": 1200, "remaining_real_duration_s": 1200}}
{"event": "action", "seq": 2, "wall_ts_ms": 1789180957560, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0002", "position": {"x": 0.0, "y": 0.0}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789180957560, "virtual_time_s": 5.0, "measure_result": "direction", "svd_deg": 300.65999999999997}}
{"event": "action", "seq": 3, "wall_ts_ms": 1789180957586, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0003", "position": {"x": 0.0, "y": 0.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789180957586, "virtual_time_s": 11.0, "measure_result": "direction", "svd_deg": 268.69}}
{"event": "action", "seq": 4, "wall_ts_ms": 1789180957612, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0004", "position": {"x": 0.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180957612, "virtual_time_s": 17.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 5, "wall_ts_ms": 1789180957616, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0005", "position": {"x": 0.0, "y": 0.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789180957616, "virtual_time_s": 23.0, "measure_result": "direction", "svd_deg": 47.32}}
{"event": "action", "seq": 6, "wall_ts_ms": 1789180957643, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0006", "position": {"x": 0.0, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180957642, "virtual_time_s": 29.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 7, "wall_ts_ms": 1789180957651, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0007", "position": {"x": 0.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180957651, "virtual_time_s": 35.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 8, "wall_ts_ms": 1789180957662, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0008", "position": {"x": 0.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789180957662, "virtual_time_s": 41.0, "measure_result": "direction", "svd_deg": 305.65999999999997}}
{"event": "action", "seq": 9, "wall_ts_ms": 1789180957692, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0009", "position": {"x": 0.0, "y": 0.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180957692, "virtual_time_s": 47.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 10, "wall_ts_ms": 1789180957696, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0010", "position": {"x": 0.0, "y": 0.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789180957696, "virtual_time_s": 53.0, "measure_result": "direction", "svd_deg": 8.9}}
{"event": "action", "seq": 11, "wall_ts_ms": 1789180957722, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0011", "position": {"x": 0.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789180957722, "virtual_time_s": 59.0, "measure_result": "direction", "svd_deg": 327.54}}
{"event": "action", "seq": 12, "wall_ts_ms": 1789180957748, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0012", "position": {"x": 0.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180957748, "virtual_time_s": 65.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 13, "wall_ts_ms": 1789180957751, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0013", "position": {"x": 0.0, "y": 0.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180957751, "virtual_time_s": 71.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 14, "wall_ts_ms": 1789180957755, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0014", "position": {"x": 0.0, "y": 0.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789180957755, "virtual_time_s": 77.0, "measure_result": "direction", "svd_deg": 253.92000000000002}}
{"event": "action", "seq": 15, "wall_ts_ms": 1789180957781, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0015", "position": {"x": 0.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180957781, "virtual_time_s": 83.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 16, "wall_ts_ms": 1789180957785, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0016", "position": {"x": 0.0, "y": 0.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180957785, "virtual_time_s": 89.0, "measure_result": "direction", "svd_deg": 280.39}}
{"event": "action", "seq": 17, "wall_ts_ms": 1789180957813, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0017", "position": {"x": 0.0, "y": 0.0}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789180957813, "virtual_time_s": 95.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 18, "wall_ts_ms": 1789180957817, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0018", "position": {"x": 0.0, "y": 0.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789180957817, "virtual_time_s": 101.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 19, "wall_ts_ms": 1789180957821, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0019", "position": {"x": 0.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789180957821, "virtual_time_s": 107.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 20, "wall_ts_ms": 1789180957825, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0020", "position": {"x": 0.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180957825, "virtual_time_s": 113.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 21, "wall_ts_ms": 1789180957829, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0021", "position": {"x": 0.0, "y": 0.0}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180957829, "virtual_time_s": 119.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 22, "wall_ts_ms": 1789180957872, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0022", "position": {"x": 329.91632625184695, "y": 495.49080587993234}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789180957872, "virtual_time_s": 244.055604, "measure_result": "direction", "svd_deg": 238.82999999999998}}
{"event": "action", "seq": 23, "wall_ts_ms": 1789180957904, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0023", "position": {"x": 87.06059978275506, "y": 95.76533567044315}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789180957904, "virtual_time_s": 342.599039, "measure_result": "direction", "svd_deg": 41.36}}
{"event": "action", "seq": 24, "wall_ts_ms": 1789180957905, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0024", "position": {"x": 95.69696236243729, "y": 103.64174930725308}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789180957905, "virtual_time_s": 349.93677, "clear_result": "success"}}
{"event": "action", "seq": 25, "wall_ts_ms": 1789180957934, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0025", "position": {"x": 499.70083077051663, "y": 181.12441837044364}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789180957934, "virtual_time_s": 438.210141, "measure_result": "direction", "svd_deg": 212.08}}
{"event": "action", "seq": 26, "wall_ts_ms": 1789180957961, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0026", "position": {"x": 280.7729594067307, "y": 44.37891807732431}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789180957961, "virtual_time_s": 494.83523, "measure_result": "near"}}
{"event": "action", "seq": 27, "wall_ts_ms": 1789180957964, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0027", "position": {"x": 280.77295940673065, "y": 44.37891807732432}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789180957964, "virtual_time_s": 499.83523, "clear_result": "success"}}
{"event": "action", "seq": 28, "wall_ts_ms": 1789180957988, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0028", "position": {"x": 568.4300753615959, "y": -160.98657280949487}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789180957988, "virtual_time_s": 576.52373, "measure_result": "direction", "svd_deg": 294.24}}
{"event": "action", "seq": 29, "wall_ts_ms": 1789180958011, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0029", "position": {"x": 1159.7, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958011, "virtual_time_s": 705.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 30, "wall_ts_ms": 1789180958014, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0030", "position": {"x": 1159.7, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958014, "virtual_time_s": 711.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 31, "wall_ts_ms": 1789180958016, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0031", "position": {"x": 1159.7, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958016, "virtual_time_s": 717.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 32, "wall_ts_ms": 1789180958019, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0032", "position": {"x": 1159.7, "y": 0.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958018, "virtual_time_s": 723.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 33, "wall_ts_ms": 1789180958021, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0033", "position": {"x": 1159.7, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958021, "virtual_time_s": 729.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 34, "wall_ts_ms": 1789180958023, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0034", "position": {"x": 1159.7, "y": 0.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958023, "virtual_time_s": 735.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 35, "wall_ts_ms": 1789180958026, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0035", "position": {"x": 1159.7, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958026, "virtual_time_s": 741.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 36, "wall_ts_ms": 1789180958029, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0036", "position": {"x": 1159.7, "y": 0.0}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789180958029, "virtual_time_s": 747.082581, "measure_result": "direction", "svd_deg": 102.56}}
{"event": "action", "seq": 37, "wall_ts_ms": 1789180958046, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0037", "position": {"x": 1159.7, "y": 0.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789180958046, "virtual_time_s": 753.082581, "measure_result": "direction", "svd_deg": 100.09}}
{"event": "action", "seq": 38, "wall_ts_ms": 1789180958063, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0038", "position": {"x": 1159.7, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789180958063, "virtual_time_s": 759.082581, "measure_result": "direction", "svd_deg": 286.95}}
{"event": "action", "seq": 39, "wall_ts_ms": 1789180958080, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0039", "position": {"x": 1159.7, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958080, "virtual_time_s": 765.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 40, "wall_ts_ms": 1789180958082, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0040", "position": {"x": 1159.7, "y": 0.0}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958082, "virtual_time_s": 771.082581, "measure_result": "no_signal"}}
{"event": "action", "seq": 41, "wall_ts_ms": 1789180958085, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0041", "position": {"x": 1159.7, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789180958085, "virtual_time_s": 777.082581, "measure_result": "direction", "svd_deg": 222.4}}
{"event": "action", "seq": 42, "wall_ts_ms": 1789180958120, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0042", "position": {"x": 1181.9612781825824, "y": -398.09481493713434}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789180958120, "virtual_time_s": 862.825931, "measure_result": "direction", "svd_deg": 337.05}}
{"event": "action", "seq": 43, "wall_ts_ms": 1789180958122, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0043", "position": {"x": 1290.31584970396, "y": -444.20323002077396}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789180958122, "virtual_time_s": 891.377321, "clear_result": "success"}}
{"event": "action", "seq": 44, "wall_ts_ms": 1789180958153, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0044", "position": {"x": 692.9641961524196, "y": -431.62214158320916}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789180958153, "virtual_time_s": 1015.874146, "clear_result": "success"}}
{"event": "action", "seq": 45, "wall_ts_ms": 1789180958154, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0045", "position": {"x": 692.9641961524196, "y": -431.62214158320916}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789180958154, "virtual_time_s": 1021.874146, "measure_result": "direction", "svd_deg": 259.12}}
{"event": "action", "seq": 46, "wall_ts_ms": 1789180958155, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0046", "position": {"x": 692.9641961524196, "y": -431.62214158320916}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789180958155, "virtual_time_s": 1027.874146, "measure_result": "direction", "svd_deg": 273.15999999999997}}
{"event": "action", "seq": 47, "wall_ts_ms": 1789180958180, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0047", "position": {"x": 726.0889668955143, "y": -1013.5555150727951}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789180958180, "virtual_time_s": 1149.449221, "measure_result": "direction", "svd_deg": 249.26999999999998}}
{"event": "action", "seq": 48, "wall_ts_ms": 1789180958181, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0048", "position": {"x": 723.6947977883272, "y": -1020.2329880529497}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789180958181, "virtual_time_s": 1155.867963, "clear_result": "success"}}
{"event": "action", "seq": 49, "wall_ts_ms": 1789180958182, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0049", "position": {"x": 723.6947977883272, "y": -1020.2329880529497}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789180958182, "virtual_time_s": 1161.867963, "measure_result": "direction", "svd_deg": 169.37}}
{"event": "action", "seq": 50, "wall_ts_ms": 1789180958201, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0050", "position": {"x": 592.913377101037, "y": -995.8561016498235}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789180958201, "virtual_time_s": 1193.474739, "clear_result": "success"}}
{"event": "action", "seq": 51, "wall_ts_ms": 1789180958220, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0051", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958220, "virtual_time_s": 1202.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 52, "wall_ts_ms": 1789180958223, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0052", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958223, "virtual_time_s": 1208.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 53, "wall_ts_ms": 1789180958225, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0053", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958225, "virtual_time_s": 1214.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 54, "wall_ts_ms": 1789180958227, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0054", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958227, "virtual_time_s": 1220.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 55, "wall_ts_ms": 1789180958229, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0055", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958229, "virtual_time_s": 1226.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 56, "wall_ts_ms": 1789180958231, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0056", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958231, "virtual_time_s": 1232.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 57, "wall_ts_ms": 1789180958233, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0057", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958233, "virtual_time_s": 1238.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 58, "wall_ts_ms": 1789180958235, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0058", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958235, "virtual_time_s": 1244.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 59, "wall_ts_ms": 1789180958237, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0059", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958237, "virtual_time_s": 1250.58892, "measure_result": "no_signal"}}
{"event": "action", "seq": 60, "wall_ts_ms": 1789180958259, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0060", "position": {"x": 349.6584245894246, "y": -866.3057372173914}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180958259, "virtual_time_s": 1310.268996, "measure_result": "direction", "svd_deg": 258.57}}
{"event": "action", "seq": 61, "wall_ts_ms": 1789180958260, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0061", "position": {"x": 349.6584245894246, "y": -866.3057372173914}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789180958260, "virtual_time_s": 1316.268996, "measure_result": "direction", "svd_deg": 134.25}}
{"event": "action", "seq": 62, "wall_ts_ms": 1789180958261, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0062", "position": {"x": 349.6584245894246, "y": -866.3057372173914}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789180958261, "virtual_time_s": 1322.268996, "measure_result": "direction", "svd_deg": 192.73}}
{"event": "action", "seq": 63, "wall_ts_ms": 1789180958276, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0063", "position": {"x": 249.54413666891318, "y": -1369.282979063259}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180958276, "virtual_time_s": 1430.837798, "measure_result": "direction", "svd_deg": 80.3}}
{"event": "action", "seq": 64, "wall_ts_ms": 1789180958278, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0064", "position": {"x": 249.54413666891318, "y": -1369.282979063259}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789180958278, "virtual_time_s": 1436.837798, "measure_result": "direction", "svd_deg": 146.74}}
{"event": "action", "seq": 65, "wall_ts_ms": 1789180958292, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0065", "position": {"x": 255.2449327883272, "y": -1332.006353661351}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180958292, "virtual_time_s": 1450.379803, "measure_result": "direction", "svd_deg": 79.93}}
{"event": "action", "seq": 66, "wall_ts_ms": 1789180958307, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0066", "position": {"x": 258.1641507938497, "y": -1313.70950364736}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180958307, "virtual_time_s": 1459.085456, "measure_result": "direction", "svd_deg": 79.52}}
{"event": "action", "seq": 67, "wall_ts_ms": 1789180958308, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0067", "position": {"x": 258.1641507938497, "y": -1313.70950364736}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789180958308, "virtual_time_s": 1464.085456, "clear_result": "success"}}
{"event": "action", "seq": 68, "wall_ts_ms": 1789180958320, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0068", "position": {"x": -292.4448586303565, "y": -1014.136994071251}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789180958320, "virtual_time_s": 1595.451156, "measure_result": "near"}}
{"event": "action", "seq": 69, "wall_ts_ms": 1789180958323, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0069", "position": {"x": -292.4448586303565, "y": -1014.136994071251}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789180958323, "virtual_time_s": 1600.451156, "clear_result": "success"}}
{"event": "action", "seq": 70, "wall_ts_ms": 1789180958324, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0070", "position": {"x": -292.4448586303565, "y": -1014.136994071251}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789180958324, "virtual_time_s": 1606.451156, "measure_result": "direction", "svd_deg": 62.63}}
{"event": "action", "seq": 71, "wall_ts_ms": 1789180958332, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0071", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958332, "virtual_time_s": 1669.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 72, "wall_ts_ms": 1789180958335, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0072", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958335, "virtual_time_s": 1675.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 73, "wall_ts_ms": 1789180958337, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0073", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958337, "virtual_time_s": 1681.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 74, "wall_ts_ms": 1789180958339, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0074", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958339, "virtual_time_s": 1687.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 75, "wall_ts_ms": 1789180958341, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0075", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958341, "virtual_time_s": 1693.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 76, "wall_ts_ms": 1789180958343, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0076", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958343, "virtual_time_s": 1699.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 77, "wall_ts_ms": 1789180958345, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0077", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958345, "virtual_time_s": 1705.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 78, "wall_ts_ms": 1789180958347, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0078", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958347, "virtual_time_s": 1711.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 79, "wall_ts_ms": 1789180958349, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0079", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958349, "virtual_time_s": 1717.965641, "measure_result": "no_signal"}}
{"event": "action", "seq": 80, "wall_ts_ms": 1789180958359, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0080", "position": {"x": -20.81115691966234, "y": -491.4622015627573}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789180958359, "virtual_time_s": 1874.696648, "clear_result": "success"}}
{"event": "action", "seq": 81, "wall_ts_ms": 1789180958367, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0081", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958367, "virtual_time_s": 2127.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 82, "wall_ts_ms": 1789180958369, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0082", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958369, "virtual_time_s": 2133.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 83, "wall_ts_ms": 1789180958371, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0083", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958371, "virtual_time_s": 2139.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 84, "wall_ts_ms": 1789180958373, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0084", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958373, "virtual_time_s": 2145.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 85, "wall_ts_ms": 1789180958375, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0085", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958375, "virtual_time_s": 2151.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 86, "wall_ts_ms": 1789180958377, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0086", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958377, "virtual_time_s": 2157.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 87, "wall_ts_ms": 1789180958378, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0087", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958378, "virtual_time_s": 2163.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 88, "wall_ts_ms": 1789180958381, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0088", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958381, "virtual_time_s": 2169.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 89, "wall_ts_ms": 1789180958382, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0089", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958382, "virtual_time_s": 2175.777513, "measure_result": "no_signal"}}
{"event": "action", "seq": 90, "wall_ts_ms": 1789180958392, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0090", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958392, "virtual_time_s": 2412.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 91, "wall_ts_ms": 1789180958394, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0091", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958394, "virtual_time_s": 2418.717513, "measure_result": "direction", "svd_deg": 99.09}}
{"event": "action", "seq": 92, "wall_ts_ms": 1789180958403, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0092", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958403, "virtual_time_s": 2424.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 93, "wall_ts_ms": 1789180958406, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0093", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958406, "virtual_time_s": 2430.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 94, "wall_ts_ms": 1789180958408, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0094", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958408, "virtual_time_s": 2436.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 95, "wall_ts_ms": 1789180958410, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0095", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958410, "virtual_time_s": 2442.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 96, "wall_ts_ms": 1789180958412, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0096", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958412, "virtual_time_s": 2448.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 97, "wall_ts_ms": 1789180958415, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0097", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958414, "virtual_time_s": 2454.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 98, "wall_ts_ms": 1789180958417, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0098", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958417, "virtual_time_s": 2460.717513, "measure_result": "no_signal"}}
{"event": "action", "seq": 99, "wall_ts_ms": 1789180958430, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0099", "position": {"x": -695.8360286345146, "y": 1079.9979863420326}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958430, "virtual_time_s": 2494.414772, "measure_result": "direction", "svd_deg": 88.79}}
{"event": "action", "seq": 100, "wall_ts_ms": 1789180958440, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0100", "position": {"x": -773.4269950394429, "y": 1247.0684941553409}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958440, "virtual_time_s": 2536.256549, "measure_result": "direction", "svd_deg": 74.59}}
{"event": "action", "seq": 101, "wall_ts_ms": 1789180958451, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0101", "position": {"x": -677.0891554842904, "y": 1598.764673122199}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958451, "virtual_time_s": 2614.186977, "measure_result": "near"}}
{"event": "action", "seq": 102, "wall_ts_ms": 1789180958453, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0102", "position": {"x": -677.0891554842905, "y": 1598.764673122199}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789180958453, "virtual_time_s": 2619.186977, "clear_result": "success"}}
{"event": "action", "seq": 103, "wall_ts_ms": 1789180958461, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0103", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789180958461, "virtual_time_s": 2903.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 104, "wall_ts_ms": 1789180958463, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0104", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789180958463, "virtual_time_s": 2909.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 105, "wall_ts_ms": 1789180958465, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0105", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789180958465, "virtual_time_s": 2915.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 106, "wall_ts_ms": 1789180958467, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0106", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789180958467, "virtual_time_s": 2921.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 107, "wall_ts_ms": 1789180958468, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0107", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958468, "virtual_time_s": 2927.269628, "measure_result": "direction", "svd_deg": 59.3}}
{"event": "action", "seq": 108, "wall_ts_ms": 1789180958476, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0108", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789180958476, "virtual_time_s": 2933.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 109, "wall_ts_ms": 1789180958478, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0109", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789180958478, "virtual_time_s": 2939.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 110, "wall_ts_ms": 1789180958479, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0110", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789180958479, "virtual_time_s": 2945.269628, "measure_result": "no_signal"}}
{"event": "action", "seq": 111, "wall_ts_ms": 1789180958492, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0111", "position": {"x": 787.1138417099093, "y": 868.8330538767141}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789180958492, "virtual_time_s": 3000.794422, "measure_result": "direction", "svd_deg": 48.92}}
{"event": "action", "seq": 112, "wall_ts_ms": 1789180958495, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0112", "position": {"x": 787.1138417099093, "y": 868.8330538767141}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958495, "virtual_time_s": 3006.794422, "measure_result": "direction", "svd_deg": 81.72}}
{"event": "action", "seq": 113, "wall_ts_ms": 1789180958497, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0113", "position": {"x": 787.1138417099093, "y": 868.8330538767141}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789180958497, "virtual_time_s": 3012.794422, "measure_result": "direction", "svd_deg": 355.02}}
{"event": "action", "seq": 114, "wall_ts_ms": 1789180958505, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0114", "position": {"x": 1006.7514888052996, "y": 849.402305610616}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789180958504, "virtual_time_s": 3061.893515, "clear_result": "success"}}
{"event": "action", "seq": 115, "wall_ts_ms": 1789180958506, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0115", "position": {"x": 1006.7514888052996, "y": 849.402305610616}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958506, "virtual_time_s": 3067.893515, "measure_result": "direction", "svd_deg": 99.43}}
{"event": "action", "seq": 116, "wall_ts_ms": 1789180958507, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0116", "position": {"x": 1006.7514888052996, "y": 849.402305610616}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789180958507, "virtual_time_s": 3073.893515, "measure_result": "direction", "svd_deg": 108.49}}
{"event": "action", "seq": 117, "wall_ts_ms": 1789180958510, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0117", "position": {"x": 944.6465433737715, "y": 1035.4841640936}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789180958510, "virtual_time_s": 3118.12793, "clear_result": "success"}}
{"event": "action", "seq": 118, "wall_ts_ms": 1789180958513, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0118", "position": {"x": 891.8884900605264, "y": 1530.8309263018434}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958513, "virtual_time_s": 3223.75761, "measure_result": "direction", "svd_deg": 262.24}}
{"event": "action", "seq": 119, "wall_ts_ms": 1789180958514, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0119", "position": {"x": 890.3107496582719, "y": 1520.5980009322138}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789180958514, "virtual_time_s": 3230.828378, "clear_result": "success"}}
{"event": "action", "seq": 120, "wall_ts_ms": 1789180958515, "method": "POST", "path": "/exit", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "234dfa75ad6f-0120"}, "response": {"accepted": true, "real_timestamp_ms": 1789180958515, "virtual_time_s": 3230.828378, "exit_reason": "user_exit"}}
{"event": "session_end", "reason": "user_exit", "virtual_time_s": 3230.828378, "real_elapsed_s": 1.527473, "request_count": 120, "cleared_count": 13}
@@ -0,0 +1,112 @@
{
"case_code": "53FK-LELA-M62B-J74U",
"module": "q3_practice",
"robot_id": "1",
"seed": 1364411664,
"truth": [
{
"channel": 18,
"x": 1296.7141429697774,
"y": -444.4430546050354,
"r_eff_m": 1239.1782567152018,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 17,
"x": 1020.5918585779062,
"y": 852.2515595937525,
"r_eff_m": 1026.5206174583245,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 1,
"x": 580.5002167548972,
"y": -991.4701530799936,
"r_eff_m": 1237.8121709043808,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 2,
"x": -16.348424904475735,
"y": -478.6435890197983,
"r_eff_m": 1099.9814484291328,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 3,
"x": -677.9492703745801,
"y": 1597.8849010804165,
"r_eff_m": 1497.7568411784152,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 16,
"x": 941.6921106181675,
"y": 1045.53299027287,
"r_eff_m": 1391.826351188507,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 15,
"x": 261.02174414951065,
"y": -1297.210479453902,
"r_eff_m": 1464.8227234548847,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 12,
"x": 889.7578735792483,
"y": 1513.108837479721,
"r_eff_m": 1223.8000521319436,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 7,
"x": 716.9679630720734,
"y": -1036.910162951016,
"r_eff_m": 1445.0475739763483,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 4,
"x": 100.68070249674014,
"y": 108.02794787019978,
"r_eff_m": 1176.2905736642158,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 13,
"x": -291.4835840002278,
"y": -1010.1772742830697,
"r_eff_m": 1200.9184419942253,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 9,
"x": 282.13965648638487,
"y": 40.4254513417698,
"r_eff_m": 1456.4760272053131,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 10,
"x": 684.7259065078848,
"y": -430.9034644685128,
"r_eff_m": 1479.4906472616449,
"directional": false,
"heading_deg": 0.0
}
]
}
@@ -0,0 +1,532 @@
{"event": "session_start", "case_code": "5TQF-A8K9-QW89-V2ET", "module": "q4_practice", "robot_id": "1", "seed": 1415283134, "countdown_s": 5.0, "window_s": 1500.0, "max_real_duration_s": 1200.0, "truth": [{"channel": 17, "x": 201.83789549004942, "y": 411.9733699427643, "r_eff_m": 1221.4478310143415, "directional": true, "heading_deg": 315.48877042891024}, {"channel": 4, "x": -1105.4390726028914, "y": -836.873727576673, "r_eff_m": 1449.9048730606553, "directional": true, "heading_deg": 189.031114716249}, {"channel": 2, "x": -502.2367519508228, "y": 921.7249012630463, "r_eff_m": 1222.172364639404, "directional": true, "heading_deg": 170.22567245589232}, {"channel": 15, "x": 1338.5109618239856, "y": 1114.8362795676107, "r_eff_m": 1125.022131637457, "directional": false, "heading_deg": 0.0}, {"channel": 9, "x": -916.8137760578517, "y": -848.3836360990396, "r_eff_m": 1463.9469990173247, "directional": false, "heading_deg": 0.0}, {"channel": 16, "x": -962.2248701879902, "y": -861.6772389852658, "r_eff_m": 1057.5023609780635, "directional": false, "heading_deg": 0.0}, {"channel": 8, "x": 426.0100239176212, "y": -1395.433153095009, "r_eff_m": 1316.6412496443302, "directional": false, "heading_deg": 0.0}, {"channel": 5, "x": 1565.3993113628057, "y": 276.7308299465653, "r_eff_m": 1300.3648907717125, "directional": false, "heading_deg": 0.0}, {"channel": 12, "x": 1358.7991804165615, "y": 756.6431101382647, "r_eff_m": 1268.3365819478918, "directional": false, "heading_deg": 0.0}, {"channel": 20, "x": -1025.1717086952801, "y": -1138.8576473722178, "r_eff_m": 1274.8459885352177, "directional": false, "heading_deg": 0.0}, {"channel": 13, "x": -973.4448466468912, "y": 950.3687397692318, "r_eff_m": 1358.1824021574332, "directional": false, "heading_deg": 0.0}, {"channel": 1, "x": -679.5564210766588, "y": -113.09168897579823, "r_eff_m": 1357.5098916694712, "directional": false, "heading_deg": 0.0}]}
{"event": "action", "seq": 1, "wall_ts_ms": 1789176743503, "method": "POST", "path": "/enter", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0001"}, "response": {"accepted": true, "real_timestamp_ms": 1789176743503, "virtual_time_s": 0.0, "max_virtual_duration_s": 360000.0, "max_real_duration_s": 1200, "remaining_real_duration_s": 1200}}
{"event": "action", "seq": 2, "wall_ts_ms": 1789176743505, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0002", "position": {"x": 0.0, "y": 0.0}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789176743505, "virtual_time_s": 5.0, "measure_result": "direction", "svd_deg": 189.35}}
{"event": "action", "seq": 3, "wall_ts_ms": 1789176743540, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0003", "position": {"x": 0.0, "y": 0.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176743540, "virtual_time_s": 11.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 4, "wall_ts_ms": 1789176743541, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0004", "position": {"x": 0.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176743541, "virtual_time_s": 17.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 5, "wall_ts_ms": 1789176743541, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0005", "position": {"x": 0.0, "y": 0.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176743541, "virtual_time_s": 23.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 6, "wall_ts_ms": 1789176743542, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0006", "position": {"x": 0.0, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176743542, "virtual_time_s": 29.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 7, "wall_ts_ms": 1789176743543, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0007", "position": {"x": 0.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176743543, "virtual_time_s": 35.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 8, "wall_ts_ms": 1789176743543, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0008", "position": {"x": 0.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176743543, "virtual_time_s": 41.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 9, "wall_ts_ms": 1789176743544, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0009", "position": {"x": 0.0, "y": 0.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176743544, "virtual_time_s": 47.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 10, "wall_ts_ms": 1789176743544, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0010", "position": {"x": 0.0, "y": 0.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176743544, "virtual_time_s": 53.0, "measure_result": "direction", "svd_deg": 222.14}}
{"event": "action", "seq": 11, "wall_ts_ms": 1789176743578, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0011", "position": {"x": 0.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176743578, "virtual_time_s": 59.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 12, "wall_ts_ms": 1789176743579, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0012", "position": {"x": 0.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176743579, "virtual_time_s": 65.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 13, "wall_ts_ms": 1789176743580, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0013", "position": {"x": 0.0, "y": 0.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176743580, "virtual_time_s": 71.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 14, "wall_ts_ms": 1789176743580, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0014", "position": {"x": 0.0, "y": 0.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176743580, "virtual_time_s": 77.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 15, "wall_ts_ms": 1789176743581, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0015", "position": {"x": 0.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176743581, "virtual_time_s": 83.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 16, "wall_ts_ms": 1789176743581, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0016", "position": {"x": 0.0, "y": 0.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176743581, "virtual_time_s": 89.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 17, "wall_ts_ms": 1789176743582, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0017", "position": {"x": 0.0, "y": 0.0}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789176743582, "virtual_time_s": 95.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 18, "wall_ts_ms": 1789176743583, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0018", "position": {"x": 0.0, "y": 0.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176743583, "virtual_time_s": 101.0, "measure_result": "direction", "svd_deg": 64.7}}
{"event": "action", "seq": 19, "wall_ts_ms": 1789176743618, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0019", "position": {"x": 0.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176743618, "virtual_time_s": 107.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 20, "wall_ts_ms": 1789176743619, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0020", "position": {"x": 0.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176743619, "virtual_time_s": 113.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 21, "wall_ts_ms": 1789176743619, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0021", "position": {"x": 0.0, "y": 0.0}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789176743619, "virtual_time_s": 119.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 22, "wall_ts_ms": 1789176743727, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0022", "position": {"x": -209.85405579849834, "y": 147.75935846577704}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176743727, "virtual_time_s": 176.330908, "measure_result": "no_signal"}}
{"event": "action", "seq": 23, "wall_ts_ms": 1789176743836, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0023", "position": {"x": -209.85405579849834, "y": 147.75935846577704}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176743836, "virtual_time_s": 181.330908, "measure_result": "no_signal"}}
{"event": "action", "seq": 24, "wall_ts_ms": 1789176743951, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0024", "position": {"x": -209.85405579849834, "y": 147.75935846577704}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176743951, "virtual_time_s": 186.330908, "measure_result": "no_signal"}}
{"event": "action", "seq": 25, "wall_ts_ms": 1789176744066, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0025", "position": {"x": -209.85405579849834, "y": 147.75935846577704}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744066, "virtual_time_s": 191.330908, "measure_result": "no_signal"}}
{"event": "action", "seq": 26, "wall_ts_ms": 1789176744075, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0026", "position": {"x": 10.0, "y": 50.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744074, "virtual_time_s": 242.452711, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 27, "wall_ts_ms": 1789176744076, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0027", "position": {"x": 10.0, "y": 30.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744076, "virtual_time_s": 249.452711, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 28, "wall_ts_ms": 1789176744077, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0028", "position": {"x": 10.0, "y": 10.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744076, "virtual_time_s": 256.452711, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 29, "wall_ts_ms": 1789176744077, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0029", "position": {"x": 30.0, "y": 50.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744077, "virtual_time_s": 268.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 30, "wall_ts_ms": 1789176744078, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0030", "position": {"x": 30.0, "y": 70.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744078, "virtual_time_s": 275.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 31, "wall_ts_ms": 1789176744079, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0031", "position": {"x": 30.0, "y": 90.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744079, "virtual_time_s": 282.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 32, "wall_ts_ms": 1789176744080, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0032", "position": {"x": 50.0, "y": 90.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744080, "virtual_time_s": 289.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 33, "wall_ts_ms": 1789176744080, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0033", "position": {"x": 50.0, "y": 110.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744080, "virtual_time_s": 296.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 34, "wall_ts_ms": 1789176744081, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0034", "position": {"x": 50.0, "y": 130.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744081, "virtual_time_s": 303.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 35, "wall_ts_ms": 1789176744082, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0035", "position": {"x": 70.0, "y": 130.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744082, "virtual_time_s": 310.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 36, "wall_ts_ms": 1789176744082, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0036", "position": {"x": 70.0, "y": 150.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744082, "virtual_time_s": 317.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 37, "wall_ts_ms": 1789176744083, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0037", "position": {"x": 70.0, "y": 170.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744083, "virtual_time_s": 324.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 38, "wall_ts_ms": 1789176744084, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0038", "position": {"x": 90.0, "y": 170.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744084, "virtual_time_s": 331.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 39, "wall_ts_ms": 1789176744085, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0039", "position": {"x": 90.0, "y": 190.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744085, "virtual_time_s": 338.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 40, "wall_ts_ms": 1789176744086, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0040", "position": {"x": 90.0, "y": 210.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744086, "virtual_time_s": 345.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 41, "wall_ts_ms": 1789176744087, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0041", "position": {"x": 90.0, "y": 230.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744087, "virtual_time_s": 352.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 42, "wall_ts_ms": 1789176744088, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0042", "position": {"x": 110.0, "y": 230.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744088, "virtual_time_s": 359.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 43, "wall_ts_ms": 1789176744089, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0043", "position": {"x": 110.0, "y": 210.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744089, "virtual_time_s": 366.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 44, "wall_ts_ms": 1789176744089, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0044", "position": {"x": 110.0, "y": 250.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744089, "virtual_time_s": 377.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 45, "wall_ts_ms": 1789176744090, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0045", "position": {"x": 110.0, "y": 270.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744090, "virtual_time_s": 384.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 46, "wall_ts_ms": 1789176744091, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0046", "position": {"x": 130.0, "y": 270.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744091, "virtual_time_s": 391.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 47, "wall_ts_ms": 1789176744092, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0047", "position": {"x": 130.0, "y": 250.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744091, "virtual_time_s": 398.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 48, "wall_ts_ms": 1789176744092, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0048", "position": {"x": 130.0, "y": 290.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744092, "virtual_time_s": 409.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 49, "wall_ts_ms": 1789176744093, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0049", "position": {"x": 130.0, "y": 310.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744093, "virtual_time_s": 416.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 50, "wall_ts_ms": 1789176744094, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0050", "position": {"x": 150.0, "y": 310.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744094, "virtual_time_s": 423.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 51, "wall_ts_ms": 1789176744094, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0051", "position": {"x": 150.0, "y": 290.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744094, "virtual_time_s": 430.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 52, "wall_ts_ms": 1789176744095, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0052", "position": {"x": 150.0, "y": 330.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744095, "virtual_time_s": 441.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 53, "wall_ts_ms": 1789176744096, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0053", "position": {"x": 150.0, "y": 350.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744096, "virtual_time_s": 448.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 54, "wall_ts_ms": 1789176744096, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0054", "position": {"x": 170.0, "y": 350.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744096, "virtual_time_s": 455.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 55, "wall_ts_ms": 1789176744097, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0055", "position": {"x": 170.0, "y": 330.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744097, "virtual_time_s": 462.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 56, "wall_ts_ms": 1789176744098, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0056", "position": {"x": 170.0, "y": 370.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744098, "virtual_time_s": 473.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 57, "wall_ts_ms": 1789176744098, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0057", "position": {"x": 170.0, "y": 390.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744098, "virtual_time_s": 480.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 58, "wall_ts_ms": 1789176744099, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0058", "position": {"x": 190.0, "y": 390.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744099, "virtual_time_s": 487.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 59, "wall_ts_ms": 1789176744100, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0059", "position": {"x": 190.0, "y": 370.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744100, "virtual_time_s": 494.396983, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 60, "wall_ts_ms": 1789176744101, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0060", "position": {"x": 190.0, "y": 410.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789176744101, "virtual_time_s": 507.396983, "clear_result": "success"}}
{"event": "action", "seq": 61, "wall_ts_ms": 1789176744248, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0061", "position": {"x": -209.71604207390737, "y": 408.31180226407764}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789176744248, "virtual_time_s": 593.340904, "measure_result": "direction", "svd_deg": 228.61}}
{"event": "action", "seq": 62, "wall_ts_ms": 1789176744264, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0062", "position": {"x": -629.8687381345811, "y": -72.63944843455852}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789176744264, "virtual_time_s": 726.065983, "measure_result": "direction", "svd_deg": 219.19}}
{"event": "action", "seq": 63, "wall_ts_ms": 1789176744278, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0063", "position": {"x": -651.3328725627388, "y": -84.8382530829925}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789176744278, "virtual_time_s": 736.003674, "measure_result": "direction", "svd_deg": 224.16}}
{"event": "action", "seq": 64, "wall_ts_ms": 1789176744280, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0064", "position": {"x": -684.6469952147388, "y": -116.80120530424186}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789176744280, "virtual_time_s": 750.237224, "clear_result": "success"}}
{"event": "action", "seq": 65, "wall_ts_ms": 1789176744412, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0065", "position": {"x": -556.2448721339551, "y": -128.19722962602532}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744412, "virtual_time_s": 782.018593, "measure_result": "direction", "svd_deg": 243.95999999999998}}
{"event": "action", "seq": 66, "wall_ts_ms": 1789176744436, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0066", "position": {"x": -793.4137491491886, "y": -710.8346157336247}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744436, "virtual_time_s": 912.830421, "measure_result": "direction", "svd_deg": 228.89}}
{"event": "action", "seq": 67, "wall_ts_ms": 1789176744454, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0067", "position": {"x": -840.6507108907208, "y": -773.6752375134632}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744454, "virtual_time_s": 933.553365, "measure_result": "direction", "svd_deg": 224.88}}
{"event": "action", "seq": 68, "wall_ts_ms": 1789176744472, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0068", "position": {"x": -853.9521308716392, "y": -787.8752977423674}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744472, "virtual_time_s": 942.444737, "measure_result": "direction", "svd_deg": 224.3}}
{"event": "action", "seq": 69, "wall_ts_ms": 1789176744487, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0069", "position": {"x": -859.3063790868281, "y": -793.0528623864075}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744487, "virtual_time_s": 948.93437, "measure_result": "direction", "svd_deg": 224.2}}
{"event": "action", "seq": 70, "wall_ts_ms": 1789176744505, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0070", "position": {"x": -860.0609236842562, "y": -793.5864307088535}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744505, "virtual_time_s": 954.119198, "measure_result": "direction", "svd_deg": 223.12}}
{"event": "action", "seq": 71, "wall_ts_ms": 1789176744520, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0071", "position": {"x": -863.0416400882648, "y": -795.1906929028166}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744520, "virtual_time_s": 959.796201, "measure_result": "direction", "svd_deg": 224.99}}
{"event": "action", "seq": 72, "wall_ts_ms": 1789176744535, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0072", "position": {"x": -865.3759614633741, "y": -797.4669070200721}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744535, "virtual_time_s": 965.448281, "measure_result": "direction", "svd_deg": 224.57}}
{"event": "action", "seq": 73, "wall_ts_ms": 1789176744537, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0073", "position": {"x": -890.0, "y": -810.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744537, "virtual_time_s": 973.974298, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 74, "wall_ts_ms": 1789176744538, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0074", "position": {"x": -890.0, "y": -830.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744538, "virtual_time_s": 980.974298, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 75, "wall_ts_ms": 1789176744539, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0075", "position": {"x": -910.0, "y": -830.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789176744539, "virtual_time_s": 989.974298, "clear_result": "success"}}
{"event": "action", "seq": 76, "wall_ts_ms": 1789176744540, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0076", "position": {"x": -1200.0, "y": -1000.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176744540, "virtual_time_s": 1063.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 77, "wall_ts_ms": 1789176744540, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0077", "position": {"x": -1200.0, "y": -1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176744540, "virtual_time_s": 1069.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 78, "wall_ts_ms": 1789176744541, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0078", "position": {"x": -1200.0, "y": -1000.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176744541, "virtual_time_s": 1075.205243, "measure_result": "direction", "svd_deg": 59.37}}
{"event": "action", "seq": 79, "wall_ts_ms": 1789176744571, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0079", "position": {"x": -1200.0, "y": -1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176744571, "virtual_time_s": 1081.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 80, "wall_ts_ms": 1789176744572, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0080", "position": {"x": -1200.0, "y": -1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176744572, "virtual_time_s": 1087.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 81, "wall_ts_ms": 1789176744573, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0081", "position": {"x": -1200.0, "y": -1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176744573, "virtual_time_s": 1093.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 82, "wall_ts_ms": 1789176744574, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0082", "position": {"x": -1200.0, "y": -1000.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176744574, "virtual_time_s": 1099.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 83, "wall_ts_ms": 1789176744575, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0083", "position": {"x": -1200.0, "y": -1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176744575, "virtual_time_s": 1105.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 84, "wall_ts_ms": 1789176744575, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0084", "position": {"x": -1200.0, "y": -1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176744575, "virtual_time_s": 1111.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 85, "wall_ts_ms": 1789176744576, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0085", "position": {"x": -1200.0, "y": -1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176744576, "virtual_time_s": 1117.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 86, "wall_ts_ms": 1789176744576, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0086", "position": {"x": -1200.0, "y": -1000.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176744576, "virtual_time_s": 1123.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 87, "wall_ts_ms": 1789176744577, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0087", "position": {"x": -1200.0, "y": -1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176744577, "virtual_time_s": 1129.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 88, "wall_ts_ms": 1789176744578, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0088", "position": {"x": -1200.0, "y": -1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176744578, "virtual_time_s": 1135.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 89, "wall_ts_ms": 1789176744578, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0089", "position": {"x": -1200.0, "y": -1000.0}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789176744578, "virtual_time_s": 1141.205243, "measure_result": "direction", "svd_deg": 29.98}}
{"event": "action", "seq": 90, "wall_ts_ms": 1789176744608, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0090", "position": {"x": -1200.0, "y": -1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176744608, "virtual_time_s": 1147.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 91, "wall_ts_ms": 1789176744611, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0091", "position": {"x": -1200.0, "y": -1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176744611, "virtual_time_s": 1153.205243, "measure_result": "no_signal"}}
{"event": "action", "seq": 92, "wall_ts_ms": 1789176744613, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0092", "position": {"x": -1200.0, "y": -1000.0}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789176744613, "virtual_time_s": 1159.205243, "measure_result": "direction", "svd_deg": 320.74}}
{"event": "action", "seq": 93, "wall_ts_ms": 1789176744774, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0093", "position": {"x": -1150.1972412326336, "y": -943.9600015212543}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789176744774, "virtual_time_s": 1179.199637, "measure_result": "direction", "svd_deg": 302.88}}
{"event": "action", "seq": 94, "wall_ts_ms": 1789176744788, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0094", "position": {"x": -1044.6779392613898, "y": -1122.2439504091915}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789176744788, "virtual_time_s": 1225.633676, "measure_result": "direction", "svd_deg": 319.3}}
{"event": "action", "seq": 95, "wall_ts_ms": 1789176744790, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0095", "position": {"x": -1021.4536512199851, "y": -1142.6024379440794}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789176744790, "virtual_time_s": 1236.810522, "clear_result": "success"}}
{"event": "action", "seq": 96, "wall_ts_ms": 1789176744916, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0096", "position": {"x": -1080.7613481787325, "y": -1155.4023813693607}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789176744916, "virtual_time_s": 1254.945169, "measure_result": "direction", "svd_deg": 67.99}}
{"event": "action", "seq": 97, "wall_ts_ms": 1789176744917, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0097", "position": {"x": -962.0474755608315, "y": -862.4214540022658}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789176744917, "virtual_time_s": 1323.168838, "clear_result": "success"}}
{"event": "action", "seq": 98, "wall_ts_ms": 1789176745035, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0098", "position": {"x": -818.0490622286305, "y": -729.4600648451033}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745035, "virtual_time_s": 1368.367957, "measure_result": "no_signal"}}
{"event": "action", "seq": 99, "wall_ts_ms": 1789176745155, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0099", "position": {"x": -818.0490622286305, "y": -729.4600648451033}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745155, "virtual_time_s": 1373.367957, "measure_result": "no_signal"}}
{"event": "action", "seq": 100, "wall_ts_ms": 1789176745279, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0100", "position": {"x": -818.0490622286305, "y": -729.4600648451033}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745279, "virtual_time_s": 1378.367957, "measure_result": "no_signal"}}
{"event": "action", "seq": 101, "wall_ts_ms": 1789176745393, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0101", "position": {"x": -818.0490622286305, "y": -729.4600648451033}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745393, "virtual_time_s": 1383.367957, "measure_result": "no_signal"}}
{"event": "action", "seq": 102, "wall_ts_ms": 1789176745403, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0102", "position": {"x": -970.0, "y": -650.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745403, "virtual_time_s": 1420.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 103, "wall_ts_ms": 1789176745404, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0103", "position": {"x": -990.0, "y": -650.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745404, "virtual_time_s": 1427.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 104, "wall_ts_ms": 1789176745405, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0104", "position": {"x": -1010.0, "y": -650.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745405, "virtual_time_s": 1434.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 105, "wall_ts_ms": 1789176745406, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0105", "position": {"x": -1010.0, "y": -670.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745406, "virtual_time_s": 1441.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 106, "wall_ts_ms": 1789176745407, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0106", "position": {"x": -1010.0, "y": -690.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745407, "virtual_time_s": 1448.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 107, "wall_ts_ms": 1789176745407, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0107", "position": {"x": -1030.0, "y": -690.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745407, "virtual_time_s": 1455.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 108, "wall_ts_ms": 1789176745408, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0108", "position": {"x": -1030.0, "y": -710.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745408, "virtual_time_s": 1462.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 109, "wall_ts_ms": 1789176745409, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0109", "position": {"x": -1050.0, "y": -710.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745409, "virtual_time_s": 1469.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 110, "wall_ts_ms": 1789176745410, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0110", "position": {"x": -1050.0, "y": -730.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745410, "virtual_time_s": 1476.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 111, "wall_ts_ms": 1789176745410, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0111", "position": {"x": -1050.0, "y": -750.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745410, "virtual_time_s": 1483.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 112, "wall_ts_ms": 1789176745411, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0112", "position": {"x": -1070.0, "y": -750.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745411, "virtual_time_s": 1490.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 113, "wall_ts_ms": 1789176745412, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0113", "position": {"x": -1070.0, "y": -770.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745412, "virtual_time_s": 1497.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 114, "wall_ts_ms": 1789176745412, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0114", "position": {"x": -1070.0, "y": -790.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745412, "virtual_time_s": 1504.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 115, "wall_ts_ms": 1789176745413, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0115", "position": {"x": -1090.0, "y": -790.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745413, "virtual_time_s": 1511.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 116, "wall_ts_ms": 1789176745413, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0116", "position": {"x": -1090.0, "y": -810.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745413, "virtual_time_s": 1518.662557, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 117, "wall_ts_ms": 1789176745414, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0117", "position": {"x": -1090.0, "y": -830.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789176745414, "virtual_time_s": 1527.662557, "clear_result": "success"}}
{"event": "action", "seq": 118, "wall_ts_ms": 1789176745415, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0118", "position": {"x": -600.0, "y": -1000.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745415, "virtual_time_s": 1637.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 119, "wall_ts_ms": 1789176745416, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0119", "position": {"x": -600.0, "y": -1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745416, "virtual_time_s": 1643.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 120, "wall_ts_ms": 1789176745416, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0120", "position": {"x": -600.0, "y": -1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745416, "virtual_time_s": 1649.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 121, "wall_ts_ms": 1789176745417, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0121", "position": {"x": -600.0, "y": -1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745417, "virtual_time_s": 1655.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 122, "wall_ts_ms": 1789176745418, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0122", "position": {"x": -600.0, "y": -1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745418, "virtual_time_s": 1661.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 123, "wall_ts_ms": 1789176745418, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0123", "position": {"x": -600.0, "y": -1000.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745418, "virtual_time_s": 1667.392977, "measure_result": "direction", "svd_deg": 338.88}}
{"event": "action", "seq": 124, "wall_ts_ms": 1789176745451, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0124", "position": {"x": -600.0, "y": -1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745451, "virtual_time_s": 1673.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 125, "wall_ts_ms": 1789176745452, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0125", "position": {"x": -600.0, "y": -1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745452, "virtual_time_s": 1679.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 126, "wall_ts_ms": 1789176745452, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0126", "position": {"x": -600.0, "y": -1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745452, "virtual_time_s": 1685.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 127, "wall_ts_ms": 1789176745453, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0127", "position": {"x": -600.0, "y": -1000.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745453, "virtual_time_s": 1691.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 128, "wall_ts_ms": 1789176745454, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0128", "position": {"x": -600.0, "y": -1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745454, "virtual_time_s": 1697.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 129, "wall_ts_ms": 1789176745455, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0129", "position": {"x": -600.0, "y": -1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745455, "virtual_time_s": 1703.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 130, "wall_ts_ms": 1789176745455, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0130", "position": {"x": -600.0, "y": -1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745455, "virtual_time_s": 1709.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 131, "wall_ts_ms": 1789176745456, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0131", "position": {"x": -600.0, "y": -1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745456, "virtual_time_s": 1715.392977, "measure_result": "no_signal"}}
{"event": "action", "seq": 132, "wall_ts_ms": 1789176745575, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0132", "position": {"x": -650.2483354825911, "y": -1269.9287223757206}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745575, "virtual_time_s": 1776.306149, "measure_result": "direction", "svd_deg": 354.02}}
{"event": "action", "seq": 133, "wall_ts_ms": 1789176745605, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0133", "position": {"x": 184.07892973050934, "y": -1381.9520416188143}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745605, "virtual_time_s": 1949.668996, "measure_result": "direction", "svd_deg": 356.5}}
{"event": "action", "seq": 134, "wall_ts_ms": 1789176745627, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0134", "position": {"x": 318.3690827645098, "y": -1398.733855708937}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745627, "virtual_time_s": 1981.735931, "measure_result": "direction", "svd_deg": 1.74}}
{"event": "action", "seq": 135, "wall_ts_ms": 1789176745645, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0135", "position": {"x": 351.5150275325047, "y": -1396.2534123602163}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745645, "virtual_time_s": 1993.383656, "measure_result": "direction", "svd_deg": 359.83}}
{"event": "action", "seq": 136, "wall_ts_ms": 1789176745668, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0136", "position": {"x": 351.5150275325047, "y": -1396.2534123602163}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745668, "virtual_time_s": 1998.383656, "measure_result": "direction", "svd_deg": 359.83}}
{"event": "action", "seq": 137, "wall_ts_ms": 1789176745691, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0137", "position": {"x": 351.5150275325047, "y": -1396.2534123602163}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745691, "virtual_time_s": 2003.383656, "measure_result": "direction", "svd_deg": 359.83}}
{"event": "action", "seq": 138, "wall_ts_ms": 1789176745714, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0138", "position": {"x": 351.5150275325047, "y": -1396.2534123602163}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745714, "virtual_time_s": 2008.383656, "measure_result": "direction", "svd_deg": 359.83}}
{"event": "action", "seq": 139, "wall_ts_ms": 1789176745737, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0139", "position": {"x": 351.5150275325047, "y": -1396.2534123602163}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745737, "virtual_time_s": 2013.383656, "measure_result": "direction", "svd_deg": 359.83}}
{"event": "action", "seq": 140, "wall_ts_ms": 1789176745739, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0140", "position": {"x": 370.0, "y": -1390.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745739, "virtual_time_s": 2020.286472, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 141, "wall_ts_ms": 1789176745740, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0141", "position": {"x": 390.0, "y": -1390.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745740, "virtual_time_s": 2027.286472, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 142, "wall_ts_ms": 1789176745741, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0142", "position": {"x": 410.0, "y": -1390.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789176745741, "virtual_time_s": 2036.286472, "clear_result": "success"}}
{"event": "action", "seq": 143, "wall_ts_ms": 1789176745741, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0143", "position": {"x": 600.0, "y": -1400.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745741, "virtual_time_s": 2080.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 144, "wall_ts_ms": 1789176745742, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0144", "position": {"x": 600.0, "y": -1400.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745742, "virtual_time_s": 2086.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 145, "wall_ts_ms": 1789176745743, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0145", "position": {"x": 600.0, "y": -1400.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745743, "virtual_time_s": 2092.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 146, "wall_ts_ms": 1789176745743, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0146", "position": {"x": 600.0, "y": -1400.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745743, "virtual_time_s": 2098.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 147, "wall_ts_ms": 1789176745744, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0147", "position": {"x": 600.0, "y": -1400.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745744, "virtual_time_s": 2104.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 148, "wall_ts_ms": 1789176745744, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0148", "position": {"x": 600.0, "y": -1400.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745744, "virtual_time_s": 2110.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 149, "wall_ts_ms": 1789176745745, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0149", "position": {"x": 600.0, "y": -1400.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745745, "virtual_time_s": 2116.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 150, "wall_ts_ms": 1789176745745, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0150", "position": {"x": 600.0, "y": -1400.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745745, "virtual_time_s": 2122.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 151, "wall_ts_ms": 1789176745746, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0151", "position": {"x": 600.0, "y": -1400.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745746, "virtual_time_s": 2128.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 152, "wall_ts_ms": 1789176745747, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0152", "position": {"x": 600.0, "y": -1400.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745747, "virtual_time_s": 2134.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 153, "wall_ts_ms": 1789176745747, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0153", "position": {"x": 600.0, "y": -1400.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745747, "virtual_time_s": 2140.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 154, "wall_ts_ms": 1789176745748, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0154", "position": {"x": 600.0, "y": -1400.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745748, "virtual_time_s": 2146.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 155, "wall_ts_ms": 1789176745748, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0155", "position": {"x": 600.0, "y": -1400.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745748, "virtual_time_s": 2152.339067, "measure_result": "no_signal"}}
{"event": "action", "seq": 156, "wall_ts_ms": 1789176745749, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0156", "position": {"x": 800.0, "y": -1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745749, "virtual_time_s": 2246.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 157, "wall_ts_ms": 1789176745750, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0157", "position": {"x": 800.0, "y": -1800.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745750, "virtual_time_s": 2252.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 158, "wall_ts_ms": 1789176745750, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0158", "position": {"x": 800.0, "y": -1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745750, "virtual_time_s": 2258.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 159, "wall_ts_ms": 1789176745751, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0159", "position": {"x": 800.0, "y": -1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745751, "virtual_time_s": 2264.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 160, "wall_ts_ms": 1789176745751, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0160", "position": {"x": 800.0, "y": -1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745751, "virtual_time_s": 2270.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 161, "wall_ts_ms": 1789176745752, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0161", "position": {"x": 800.0, "y": -1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745752, "virtual_time_s": 2276.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 162, "wall_ts_ms": 1789176745752, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0162", "position": {"x": 800.0, "y": -1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745752, "virtual_time_s": 2282.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 163, "wall_ts_ms": 1789176745753, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0163", "position": {"x": 800.0, "y": -1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745753, "virtual_time_s": 2288.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 164, "wall_ts_ms": 1789176745753, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0164", "position": {"x": 800.0, "y": -1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745753, "virtual_time_s": 2294.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 165, "wall_ts_ms": 1789176745754, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0165", "position": {"x": 800.0, "y": -1800.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745754, "virtual_time_s": 2300.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 166, "wall_ts_ms": 1789176745754, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0166", "position": {"x": 800.0, "y": -1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745754, "virtual_time_s": 2306.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 167, "wall_ts_ms": 1789176745755, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0167", "position": {"x": 800.0, "y": -1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745755, "virtual_time_s": 2312.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 168, "wall_ts_ms": 1789176745756, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0168", "position": {"x": 800.0, "y": -1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745756, "virtual_time_s": 2318.781786, "measure_result": "no_signal"}}
{"event": "action", "seq": 169, "wall_ts_ms": 1789176745756, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0169", "position": {"x": 1000.0, "y": -1600.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745756, "virtual_time_s": 2380.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 170, "wall_ts_ms": 1789176745757, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0170", "position": {"x": 1000.0, "y": -1600.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745757, "virtual_time_s": 2386.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 171, "wall_ts_ms": 1789176745757, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0171", "position": {"x": 1000.0, "y": -1600.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745757, "virtual_time_s": 2392.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 172, "wall_ts_ms": 1789176745758, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0172", "position": {"x": 1000.0, "y": -1600.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745758, "virtual_time_s": 2398.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 173, "wall_ts_ms": 1789176745758, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0173", "position": {"x": 1000.0, "y": -1600.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745758, "virtual_time_s": 2404.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 174, "wall_ts_ms": 1789176745759, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0174", "position": {"x": 1000.0, "y": -1600.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745759, "virtual_time_s": 2410.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 175, "wall_ts_ms": 1789176745759, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0175", "position": {"x": 1000.0, "y": -1600.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745759, "virtual_time_s": 2416.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 176, "wall_ts_ms": 1789176745760, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0176", "position": {"x": 1000.0, "y": -1600.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745760, "virtual_time_s": 2422.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 177, "wall_ts_ms": 1789176745761, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0177", "position": {"x": 1000.0, "y": -1600.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745760, "virtual_time_s": 2428.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 178, "wall_ts_ms": 1789176745761, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0178", "position": {"x": 1000.0, "y": -1600.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745761, "virtual_time_s": 2434.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 179, "wall_ts_ms": 1789176745762, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0179", "position": {"x": 1000.0, "y": -1600.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745762, "virtual_time_s": 2440.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 180, "wall_ts_ms": 1789176745762, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0180", "position": {"x": 1000.0, "y": -1600.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745762, "virtual_time_s": 2446.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 181, "wall_ts_ms": 1789176745763, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0181", "position": {"x": 1000.0, "y": -1600.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745763, "virtual_time_s": 2452.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 182, "wall_ts_ms": 1789176745763, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0182", "position": {"x": 1000.0, "y": -1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745763, "virtual_time_s": 2577.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 183, "wall_ts_ms": 1789176745764, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0183", "position": {"x": 1000.0, "y": -1000.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745764, "virtual_time_s": 2583.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 184, "wall_ts_ms": 1789176745884, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0184", "position": {"x": 1000.0, "y": -1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745884, "virtual_time_s": 2589.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 185, "wall_ts_ms": 1789176745885, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0185", "position": {"x": 1000.0, "y": -1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745885, "virtual_time_s": 2595.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 186, "wall_ts_ms": 1789176745886, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0186", "position": {"x": 1000.0, "y": -1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745886, "virtual_time_s": 2601.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 187, "wall_ts_ms": 1789176745887, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0187", "position": {"x": 1000.0, "y": -1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745887, "virtual_time_s": 2607.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 188, "wall_ts_ms": 1789176745888, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0188", "position": {"x": 1000.0, "y": -1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745888, "virtual_time_s": 2613.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 189, "wall_ts_ms": 1789176745889, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0189", "position": {"x": 1000.0, "y": -1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745889, "virtual_time_s": 2619.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 190, "wall_ts_ms": 1789176745889, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0190", "position": {"x": 1000.0, "y": -1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745889, "virtual_time_s": 2625.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 191, "wall_ts_ms": 1789176745890, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0191", "position": {"x": 1000.0, "y": -1000.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745890, "virtual_time_s": 2631.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 192, "wall_ts_ms": 1789176745891, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0192", "position": {"x": 1000.0, "y": -1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745891, "virtual_time_s": 2637.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 193, "wall_ts_ms": 1789176745892, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0193", "position": {"x": 1000.0, "y": -1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745892, "virtual_time_s": 2643.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 194, "wall_ts_ms": 1789176745893, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0194", "position": {"x": 1000.0, "y": -1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745893, "virtual_time_s": 2649.350328, "measure_result": "no_signal"}}
{"event": "action", "seq": 195, "wall_ts_ms": 1789176745894, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0195", "position": {"x": 400.0, "y": -800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745894, "virtual_time_s": 2780.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 196, "wall_ts_ms": 1789176745895, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0196", "position": {"x": 400.0, "y": -800.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745895, "virtual_time_s": 2786.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 197, "wall_ts_ms": 1789176745895, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0197", "position": {"x": 400.0, "y": -800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745895, "virtual_time_s": 2792.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 198, "wall_ts_ms": 1789176745896, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0198", "position": {"x": 400.0, "y": -800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745896, "virtual_time_s": 2798.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 199, "wall_ts_ms": 1789176745897, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0199", "position": {"x": 400.0, "y": -800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745897, "virtual_time_s": 2804.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 200, "wall_ts_ms": 1789176745897, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0200", "position": {"x": 400.0, "y": -800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745897, "virtual_time_s": 2810.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 201, "wall_ts_ms": 1789176745898, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0201", "position": {"x": 400.0, "y": -800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745898, "virtual_time_s": 2816.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 202, "wall_ts_ms": 1789176745899, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0202", "position": {"x": 400.0, "y": -800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745899, "virtual_time_s": 2822.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 203, "wall_ts_ms": 1789176745900, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0203", "position": {"x": 400.0, "y": -800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745900, "virtual_time_s": 2828.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 204, "wall_ts_ms": 1789176745900, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0204", "position": {"x": 400.0, "y": -800.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745900, "virtual_time_s": 2834.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 205, "wall_ts_ms": 1789176745901, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0205", "position": {"x": 400.0, "y": -800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745901, "virtual_time_s": 2840.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 206, "wall_ts_ms": 1789176745901, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0206", "position": {"x": 400.0, "y": -800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745901, "virtual_time_s": 2846.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 207, "wall_ts_ms": 1789176745902, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0207", "position": {"x": 400.0, "y": -800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745902, "virtual_time_s": 2852.841434, "measure_result": "no_signal"}}
{"event": "action", "seq": 208, "wall_ts_ms": 1789176745903, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0208", "position": {"x": 0.0, "y": -1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745903, "virtual_time_s": 2947.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 209, "wall_ts_ms": 1789176745903, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0209", "position": {"x": 0.0, "y": -1000.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745903, "virtual_time_s": 2953.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 210, "wall_ts_ms": 1789176745904, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0210", "position": {"x": 0.0, "y": -1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745904, "virtual_time_s": 2959.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 211, "wall_ts_ms": 1789176745904, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0211", "position": {"x": 0.0, "y": -1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745904, "virtual_time_s": 2965.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 212, "wall_ts_ms": 1789176745905, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0212", "position": {"x": 0.0, "y": -1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745905, "virtual_time_s": 2971.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 213, "wall_ts_ms": 1789176745906, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0213", "position": {"x": 0.0, "y": -1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745905, "virtual_time_s": 2977.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 214, "wall_ts_ms": 1789176745906, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0214", "position": {"x": 0.0, "y": -1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745906, "virtual_time_s": 2983.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 215, "wall_ts_ms": 1789176745907, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0215", "position": {"x": 0.0, "y": -1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745907, "virtual_time_s": 2989.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 216, "wall_ts_ms": 1789176745907, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0216", "position": {"x": 0.0, "y": -1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745907, "virtual_time_s": 2995.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 217, "wall_ts_ms": 1789176745908, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0217", "position": {"x": 0.0, "y": -1000.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745908, "virtual_time_s": 3001.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 218, "wall_ts_ms": 1789176745909, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0218", "position": {"x": 0.0, "y": -1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745908, "virtual_time_s": 3007.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 219, "wall_ts_ms": 1789176745909, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0219", "position": {"x": 0.0, "y": -1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745909, "virtual_time_s": 3013.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 220, "wall_ts_ms": 1789176745910, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0220", "position": {"x": 0.0, "y": -1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745910, "virtual_time_s": 3019.284153, "measure_result": "no_signal"}}
{"event": "action", "seq": 221, "wall_ts_ms": 1789176745911, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0221", "position": {"x": -400.0, "y": -1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745911, "virtual_time_s": 3203.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 222, "wall_ts_ms": 1789176745911, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0222", "position": {"x": -400.0, "y": -1800.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745911, "virtual_time_s": 3209.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 223, "wall_ts_ms": 1789176745912, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0223", "position": {"x": -400.0, "y": -1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745912, "virtual_time_s": 3215.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 224, "wall_ts_ms": 1789176745913, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0224", "position": {"x": -400.0, "y": -1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745913, "virtual_time_s": 3221.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 225, "wall_ts_ms": 1789176745913, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0225", "position": {"x": -400.0, "y": -1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745913, "virtual_time_s": 3227.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 226, "wall_ts_ms": 1789176745914, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0226", "position": {"x": -400.0, "y": -1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745914, "virtual_time_s": 3233.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 227, "wall_ts_ms": 1789176745914, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0227", "position": {"x": -400.0, "y": -1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745914, "virtual_time_s": 3239.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 228, "wall_ts_ms": 1789176745915, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0228", "position": {"x": -400.0, "y": -1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745915, "virtual_time_s": 3245.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 229, "wall_ts_ms": 1789176745916, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0229", "position": {"x": -400.0, "y": -1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745916, "virtual_time_s": 3251.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 230, "wall_ts_ms": 1789176745917, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0230", "position": {"x": -400.0, "y": -1800.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745916, "virtual_time_s": 3257.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 231, "wall_ts_ms": 1789176745917, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0231", "position": {"x": -400.0, "y": -1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745917, "virtual_time_s": 3263.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 232, "wall_ts_ms": 1789176745918, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0232", "position": {"x": -400.0, "y": -1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745918, "virtual_time_s": 3269.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 233, "wall_ts_ms": 1789176745918, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0233", "position": {"x": -400.0, "y": -1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745918, "virtual_time_s": 3275.169591, "measure_result": "no_signal"}}
{"event": "action", "seq": 234, "wall_ts_ms": 1789176745919, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0234", "position": {"x": -200.0, "y": -2200.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745919, "virtual_time_s": 3369.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 235, "wall_ts_ms": 1789176745919, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0235", "position": {"x": -200.0, "y": -2200.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745919, "virtual_time_s": 3375.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 236, "wall_ts_ms": 1789176745920, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0236", "position": {"x": -200.0, "y": -2200.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745920, "virtual_time_s": 3381.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 237, "wall_ts_ms": 1789176745921, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0237", "position": {"x": -200.0, "y": -2200.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745921, "virtual_time_s": 3387.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 238, "wall_ts_ms": 1789176745921, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0238", "position": {"x": -200.0, "y": -2200.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745921, "virtual_time_s": 3393.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 239, "wall_ts_ms": 1789176745922, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0239", "position": {"x": -200.0, "y": -2200.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745922, "virtual_time_s": 3399.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 240, "wall_ts_ms": 1789176745922, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0240", "position": {"x": -200.0, "y": -2200.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745922, "virtual_time_s": 3405.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 241, "wall_ts_ms": 1789176745923, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0241", "position": {"x": -200.0, "y": -2200.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745923, "virtual_time_s": 3411.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 242, "wall_ts_ms": 1789176745924, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0242", "position": {"x": -200.0, "y": -2200.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745924, "virtual_time_s": 3417.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 243, "wall_ts_ms": 1789176745925, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0243", "position": {"x": -200.0, "y": -2200.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745925, "virtual_time_s": 3423.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 244, "wall_ts_ms": 1789176745925, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0244", "position": {"x": -200.0, "y": -2200.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745925, "virtual_time_s": 3429.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 245, "wall_ts_ms": 1789176745926, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0245", "position": {"x": -200.0, "y": -2200.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745926, "virtual_time_s": 3435.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 246, "wall_ts_ms": 1789176745926, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0246", "position": {"x": -200.0, "y": -2200.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745926, "virtual_time_s": 3441.61231, "measure_result": "no_signal"}}
{"event": "action", "seq": 247, "wall_ts_ms": 1789176745927, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0247", "position": {"x": -1400.0, "y": -1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745927, "virtual_time_s": 3699.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 248, "wall_ts_ms": 1789176745927, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0248", "position": {"x": -1400.0, "y": -1800.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745927, "virtual_time_s": 3705.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 249, "wall_ts_ms": 1789176745928, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0249", "position": {"x": -1400.0, "y": -1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745928, "virtual_time_s": 3711.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 250, "wall_ts_ms": 1789176745929, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0250", "position": {"x": -1400.0, "y": -1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745929, "virtual_time_s": 3717.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 251, "wall_ts_ms": 1789176745929, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0251", "position": {"x": -1400.0, "y": -1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745929, "virtual_time_s": 3723.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 252, "wall_ts_ms": 1789176745930, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0252", "position": {"x": -1400.0, "y": -1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745930, "virtual_time_s": 3729.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 253, "wall_ts_ms": 1789176745930, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0253", "position": {"x": -1400.0, "y": -1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745930, "virtual_time_s": 3735.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 254, "wall_ts_ms": 1789176745931, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0254", "position": {"x": -1400.0, "y": -1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745931, "virtual_time_s": 3741.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 255, "wall_ts_ms": 1789176745932, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0255", "position": {"x": -1400.0, "y": -1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745932, "virtual_time_s": 3747.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 256, "wall_ts_ms": 1789176745933, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0256", "position": {"x": -1400.0, "y": -1800.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745933, "virtual_time_s": 3753.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 257, "wall_ts_ms": 1789176745933, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0257", "position": {"x": -1400.0, "y": -1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745933, "virtual_time_s": 3759.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 258, "wall_ts_ms": 1789176745934, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0258", "position": {"x": -1400.0, "y": -1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745934, "virtual_time_s": 3765.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 259, "wall_ts_ms": 1789176745934, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0259", "position": {"x": -1400.0, "y": -1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745934, "virtual_time_s": 3771.594523, "measure_result": "no_signal"}}
{"event": "action", "seq": 260, "wall_ts_ms": 1789176745935, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0260", "position": {"x": -1800.0, "y": -800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745935, "virtual_time_s": 3992.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 261, "wall_ts_ms": 1789176745936, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0261", "position": {"x": -1800.0, "y": -800.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745936, "virtual_time_s": 3998.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 262, "wall_ts_ms": 1789176745936, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0262", "position": {"x": -1800.0, "y": -800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745936, "virtual_time_s": 4004.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 263, "wall_ts_ms": 1789176745937, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0263", "position": {"x": -1800.0, "y": -800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745937, "virtual_time_s": 4010.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 264, "wall_ts_ms": 1789176745938, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0264", "position": {"x": -1800.0, "y": -800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745938, "virtual_time_s": 4016.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 265, "wall_ts_ms": 1789176745938, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0265", "position": {"x": -1800.0, "y": -800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745938, "virtual_time_s": 4022.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 266, "wall_ts_ms": 1789176745939, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0266", "position": {"x": -1800.0, "y": -800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745939, "virtual_time_s": 4028.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 267, "wall_ts_ms": 1789176745940, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0267", "position": {"x": -1800.0, "y": -800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745939, "virtual_time_s": 4034.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 268, "wall_ts_ms": 1789176745941, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0268", "position": {"x": -1800.0, "y": -800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745941, "virtual_time_s": 4040.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 269, "wall_ts_ms": 1789176745941, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0269", "position": {"x": -1800.0, "y": -800.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745941, "virtual_time_s": 4046.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 270, "wall_ts_ms": 1789176745942, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0270", "position": {"x": -1800.0, "y": -800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745942, "virtual_time_s": 4052.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 271, "wall_ts_ms": 1789176745943, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0271", "position": {"x": -1800.0, "y": -800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745943, "virtual_time_s": 4058.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 272, "wall_ts_ms": 1789176745943, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0272", "position": {"x": -1800.0, "y": -800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745943, "virtual_time_s": 4064.001115, "measure_result": "no_signal"}}
{"event": "action", "seq": 273, "wall_ts_ms": 1789176745944, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0273", "position": {"x": -2000.0, "y": -400.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745944, "virtual_time_s": 4158.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 274, "wall_ts_ms": 1789176745945, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0274", "position": {"x": -2000.0, "y": -400.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745945, "virtual_time_s": 4164.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 275, "wall_ts_ms": 1789176745945, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0275", "position": {"x": -2000.0, "y": -400.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745945, "virtual_time_s": 4170.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 276, "wall_ts_ms": 1789176745946, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0276", "position": {"x": -2000.0, "y": -400.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745946, "virtual_time_s": 4176.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 277, "wall_ts_ms": 1789176745947, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0277", "position": {"x": -2000.0, "y": -400.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745947, "virtual_time_s": 4182.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 278, "wall_ts_ms": 1789176745947, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0278", "position": {"x": -2000.0, "y": -400.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745947, "virtual_time_s": 4188.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 279, "wall_ts_ms": 1789176745948, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0279", "position": {"x": -2000.0, "y": -400.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745948, "virtual_time_s": 4194.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 280, "wall_ts_ms": 1789176745949, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0280", "position": {"x": -2000.0, "y": -400.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745949, "virtual_time_s": 4200.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 281, "wall_ts_ms": 1789176745950, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0281", "position": {"x": -2000.0, "y": -400.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745950, "virtual_time_s": 4206.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 282, "wall_ts_ms": 1789176745950, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0282", "position": {"x": -2000.0, "y": -400.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745950, "virtual_time_s": 4212.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 283, "wall_ts_ms": 1789176745951, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0283", "position": {"x": -2000.0, "y": -400.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745951, "virtual_time_s": 4218.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 284, "wall_ts_ms": 1789176745951, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0284", "position": {"x": -2000.0, "y": -400.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745951, "virtual_time_s": 4224.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 285, "wall_ts_ms": 1789176745952, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0285", "position": {"x": -2000.0, "y": -400.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745952, "virtual_time_s": 4230.443834, "measure_result": "no_signal"}}
{"event": "action", "seq": 286, "wall_ts_ms": 1789176745953, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0286", "position": {"x": -1800.0, "y": 200.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176745953, "virtual_time_s": 4361.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 287, "wall_ts_ms": 1789176745953, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0287", "position": {"x": -1800.0, "y": 200.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176745953, "virtual_time_s": 4367.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 288, "wall_ts_ms": 1789176745954, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0288", "position": {"x": -1800.0, "y": 200.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176745954, "virtual_time_s": 4373.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 289, "wall_ts_ms": 1789176745954, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0289", "position": {"x": -1800.0, "y": 200.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176745954, "virtual_time_s": 4379.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 290, "wall_ts_ms": 1789176745955, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0290", "position": {"x": -1800.0, "y": 200.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176745955, "virtual_time_s": 4385.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 291, "wall_ts_ms": 1789176745955, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0291", "position": {"x": -1800.0, "y": 200.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176745955, "virtual_time_s": 4391.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 292, "wall_ts_ms": 1789176745956, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0292", "position": {"x": -1800.0, "y": 200.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176745956, "virtual_time_s": 4397.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 293, "wall_ts_ms": 1789176745956, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0293", "position": {"x": -1800.0, "y": 200.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176745956, "virtual_time_s": 4403.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 294, "wall_ts_ms": 1789176745957, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0294", "position": {"x": -1800.0, "y": 200.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176745957, "virtual_time_s": 4409.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 295, "wall_ts_ms": 1789176745958, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0295", "position": {"x": -1800.0, "y": 200.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176745958, "virtual_time_s": 4415.93494, "measure_result": "direction", "svd_deg": 42.21}}
{"event": "action", "seq": 296, "wall_ts_ms": 1789176745986, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0296", "position": {"x": -1800.0, "y": 200.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176745986, "virtual_time_s": 4421.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 297, "wall_ts_ms": 1789176745987, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0297", "position": {"x": -1800.0, "y": 200.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176745987, "virtual_time_s": 4427.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 298, "wall_ts_ms": 1789176745988, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0298", "position": {"x": -1800.0, "y": 200.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176745988, "virtual_time_s": 4433.93494, "measure_result": "no_signal"}}
{"event": "action", "seq": 299, "wall_ts_ms": 1789176746116, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0299", "position": {"x": -1763.0819823064817, "y": 184.7511178772495}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746116, "virtual_time_s": 4447.923603, "measure_result": "direction", "svd_deg": 43.12}}
{"event": "action", "seq": 300, "wall_ts_ms": 1789176746192, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0300", "position": {"x": -1389.2897139679978, "y": 528.1101586693555}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746192, "virtual_time_s": 4554.435394, "measure_result": "direction", "svd_deg": 45.84}}
{"event": "action", "seq": 301, "wall_ts_ms": 1789176746255, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0301", "position": {"x": -1351.2174928311083, "y": 570.8679541030758}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746255, "virtual_time_s": 4570.885675, "measure_result": "direction", "svd_deg": 46.07}}
{"event": "action", "seq": 302, "wall_ts_ms": 1789176746289, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0302", "position": {"x": -1293.8099551051155, "y": 631.8918912080569}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746289, "virtual_time_s": 4592.642222, "measure_result": "direction", "svd_deg": 43.99}}
{"event": "action", "seq": 303, "wall_ts_ms": 1789176746320, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0303", "position": {"x": -1267.7391838416484, "y": 656.6153146769659}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746320, "virtual_time_s": 4604.828133, "measure_result": "direction", "svd_deg": 45.72}}
{"event": "action", "seq": 304, "wall_ts_ms": 1789176746353, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0304", "position": {"x": -1267.7391838416484, "y": 656.6153146769659}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746353, "virtual_time_s": 4609.828133, "measure_result": "direction", "svd_deg": 45.72}}
{"event": "action", "seq": 305, "wall_ts_ms": 1789176746386, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0305", "position": {"x": -1267.7391838416484, "y": 656.6153146769659}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746386, "virtual_time_s": 4614.828133, "measure_result": "direction", "svd_deg": 45.72}}
{"event": "action", "seq": 306, "wall_ts_ms": 1789176746419, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0306", "position": {"x": -1267.7391838416484, "y": 656.6153146769659}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746419, "virtual_time_s": 4619.828133, "measure_result": "direction", "svd_deg": 45.72}}
{"event": "action", "seq": 307, "wall_ts_ms": 1789176746421, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0307", "position": {"x": -1210.0, "y": 730.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746421, "virtual_time_s": 4641.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 308, "wall_ts_ms": 1789176746422, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0308", "position": {"x": -1190.0, "y": 730.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746422, "virtual_time_s": 4648.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 309, "wall_ts_ms": 1789176746422, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0309", "position": {"x": -1190.0, "y": 750.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746422, "virtual_time_s": 4655.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 310, "wall_ts_ms": 1789176746423, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0310", "position": {"x": -1170.0, "y": 750.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746423, "virtual_time_s": 4662.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 311, "wall_ts_ms": 1789176746424, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0311", "position": {"x": -1170.0, "y": 770.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746424, "virtual_time_s": 4669.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 312, "wall_ts_ms": 1789176746424, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0312", "position": {"x": -1150.0, "y": 770.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746424, "virtual_time_s": 4676.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 313, "wall_ts_ms": 1789176746425, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0313", "position": {"x": -1150.0, "y": 790.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746425, "virtual_time_s": 4683.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 314, "wall_ts_ms": 1789176746425, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0314", "position": {"x": -1130.0, "y": 790.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746425, "virtual_time_s": 4690.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 315, "wall_ts_ms": 1789176746426, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0315", "position": {"x": -1130.0, "y": 810.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746426, "virtual_time_s": 4697.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 316, "wall_ts_ms": 1789176746426, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0316", "position": {"x": -1110.0, "y": 810.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746426, "virtual_time_s": 4704.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 317, "wall_ts_ms": 1789176746427, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0317", "position": {"x": -1110.0, "y": 830.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746427, "virtual_time_s": 4711.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 318, "wall_ts_ms": 1789176746427, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0318", "position": {"x": -1090.0, "y": 830.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746427, "virtual_time_s": 4718.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 319, "wall_ts_ms": 1789176746428, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0319", "position": {"x": -1090.0, "y": 850.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746428, "virtual_time_s": 4725.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 320, "wall_ts_ms": 1789176746428, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0320", "position": {"x": -1070.0, "y": 850.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746428, "virtual_time_s": 4732.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 321, "wall_ts_ms": 1789176746429, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0321", "position": {"x": -1070.0, "y": 870.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746429, "virtual_time_s": 4739.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 322, "wall_ts_ms": 1789176746429, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0322", "position": {"x": -1050.0, "y": 870.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746429, "virtual_time_s": 4746.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 323, "wall_ts_ms": 1789176746430, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0323", "position": {"x": -1050.0, "y": 890.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746430, "virtual_time_s": 4753.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 324, "wall_ts_ms": 1789176746431, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0324", "position": {"x": -1030.0, "y": 890.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746431, "virtual_time_s": 4760.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 325, "wall_ts_ms": 1789176746431, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0325", "position": {"x": -1030.0, "y": 910.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746431, "virtual_time_s": 4767.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 326, "wall_ts_ms": 1789176746432, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0326", "position": {"x": -1010.0, "y": 910.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746432, "virtual_time_s": 4774.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 327, "wall_ts_ms": 1789176746433, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0327", "position": {"x": -1010.0, "y": 930.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746433, "virtual_time_s": 4781.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 328, "wall_ts_ms": 1789176746433, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0328", "position": {"x": -990.0, "y": 930.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746433, "virtual_time_s": 4788.503384, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 329, "wall_ts_ms": 1789176746434, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0329", "position": {"x": -990.0, "y": 950.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789176746434, "virtual_time_s": 4797.503384, "clear_result": "success"}}
{"event": "action", "seq": 330, "wall_ts_ms": 1789176746434, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0330", "position": {"x": -1000.0, "y": 1000.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746434, "virtual_time_s": 4813.701423, "measure_result": "direction", "svd_deg": 352.01}}
{"event": "action", "seq": 331, "wall_ts_ms": 1789176746463, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0331", "position": {"x": -1000.0, "y": 1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746463, "virtual_time_s": 4819.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 332, "wall_ts_ms": 1789176746464, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0332", "position": {"x": -1000.0, "y": 1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746464, "virtual_time_s": 4825.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 333, "wall_ts_ms": 1789176746464, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0333", "position": {"x": -1000.0, "y": 1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746464, "virtual_time_s": 4831.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 334, "wall_ts_ms": 1789176746465, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0334", "position": {"x": -1000.0, "y": 1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746465, "virtual_time_s": 4837.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 335, "wall_ts_ms": 1789176746465, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0335", "position": {"x": -1000.0, "y": 1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746465, "virtual_time_s": 4843.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 336, "wall_ts_ms": 1789176746466, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0336", "position": {"x": -1000.0, "y": 1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746466, "virtual_time_s": 4849.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 337, "wall_ts_ms": 1789176746466, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0337", "position": {"x": -1000.0, "y": 1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746466, "virtual_time_s": 4855.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 338, "wall_ts_ms": 1789176746467, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0338", "position": {"x": -1000.0, "y": 1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746467, "virtual_time_s": 4861.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 339, "wall_ts_ms": 1789176746467, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0339", "position": {"x": -1000.0, "y": 1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746467, "virtual_time_s": 4867.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 340, "wall_ts_ms": 1789176746468, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0340", "position": {"x": -1000.0, "y": 1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746468, "virtual_time_s": 4873.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 341, "wall_ts_ms": 1789176746468, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0341", "position": {"x": -1000.0, "y": 1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746468, "virtual_time_s": 4879.701423, "measure_result": "no_signal"}}
{"event": "action", "seq": 342, "wall_ts_ms": 1789176746580, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0342", "position": {"x": -1007.2274998149326, "y": 896.1201622259241}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746580, "virtual_time_s": 4906.527616, "measure_result": "direction", "svd_deg": 2.83}}
{"event": "action", "seq": 343, "wall_ts_ms": 1789176746605, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0343", "position": {"x": -594.4281117361534, "y": 922.5533845877621}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746605, "virtual_time_s": 4994.256583, "measure_result": "direction", "svd_deg": 359.76}}
{"event": "action", "seq": 344, "wall_ts_ms": 1789176746633, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0344", "position": {"x": -564.4823014109752, "y": 920.6633195049048}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746633, "virtual_time_s": 5005.257663, "measure_result": "direction", "svd_deg": 0.06}}
{"event": "action", "seq": 345, "wall_ts_ms": 1789176746654, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0345", "position": {"x": -550.014263279546, "y": 919.749366674575}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746654, "virtual_time_s": 5013.157038, "measure_result": "direction", "svd_deg": 3.33}}
{"event": "action", "seq": 346, "wall_ts_ms": 1789176746656, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0346", "position": {"x": -500.9902007989175, "y": 921.8436311504328}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789176746656, "virtual_time_s": 5027.970793, "clear_result": "success"}}
{"event": "action", "seq": 347, "wall_ts_ms": 1789176746656, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0347", "position": {"x": 0.0, "y": 1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746656, "virtual_time_s": 5135.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 348, "wall_ts_ms": 1789176746657, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0348", "position": {"x": 0.0, "y": 1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746657, "virtual_time_s": 5141.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 349, "wall_ts_ms": 1789176746658, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0349", "position": {"x": 0.0, "y": 1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746658, "virtual_time_s": 5147.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 350, "wall_ts_ms": 1789176746658, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0350", "position": {"x": 0.0, "y": 1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746658, "virtual_time_s": 5153.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 351, "wall_ts_ms": 1789176746659, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0351", "position": {"x": 0.0, "y": 1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746659, "virtual_time_s": 5159.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 352, "wall_ts_ms": 1789176746660, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0352", "position": {"x": 0.0, "y": 1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746660, "virtual_time_s": 5165.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 353, "wall_ts_ms": 1789176746661, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0353", "position": {"x": 0.0, "y": 1000.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746661, "virtual_time_s": 5171.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 354, "wall_ts_ms": 1789176746662, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0354", "position": {"x": 0.0, "y": 1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746662, "virtual_time_s": 5177.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 355, "wall_ts_ms": 1789176746663, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0355", "position": {"x": 0.0, "y": 1000.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746663, "virtual_time_s": 5183.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 356, "wall_ts_ms": 1789176746664, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0356", "position": {"x": 0.0, "y": 1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746664, "virtual_time_s": 5189.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 357, "wall_ts_ms": 1789176746667, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0357", "position": {"x": 0.0, "y": 1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746667, "virtual_time_s": 5195.380773, "measure_result": "no_signal"}}
{"event": "action", "seq": 358, "wall_ts_ms": 1789176746667, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0358", "position": {"x": -200.0, "y": 400.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746667, "virtual_time_s": 5326.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 359, "wall_ts_ms": 1789176746668, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0359", "position": {"x": -200.0, "y": 400.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746668, "virtual_time_s": 5332.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 360, "wall_ts_ms": 1789176746669, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0360", "position": {"x": -200.0, "y": 400.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746669, "virtual_time_s": 5338.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 361, "wall_ts_ms": 1789176746669, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0361", "position": {"x": -200.0, "y": 400.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746669, "virtual_time_s": 5344.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 362, "wall_ts_ms": 1789176746670, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0362", "position": {"x": -200.0, "y": 400.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746670, "virtual_time_s": 5350.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 363, "wall_ts_ms": 1789176746671, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0363", "position": {"x": -200.0, "y": 400.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746671, "virtual_time_s": 5356.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 364, "wall_ts_ms": 1789176746671, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0364", "position": {"x": -200.0, "y": 400.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746671, "virtual_time_s": 5362.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 365, "wall_ts_ms": 1789176746672, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0365", "position": {"x": -200.0, "y": 400.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746672, "virtual_time_s": 5368.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 366, "wall_ts_ms": 1789176746673, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0366", "position": {"x": -200.0, "y": 400.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746673, "virtual_time_s": 5374.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 367, "wall_ts_ms": 1789176746673, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0367", "position": {"x": -200.0, "y": 400.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746673, "virtual_time_s": 5380.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 368, "wall_ts_ms": 1789176746674, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0368", "position": {"x": -200.0, "y": 400.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746674, "virtual_time_s": 5386.871879, "measure_result": "no_signal"}}
{"event": "action", "seq": 369, "wall_ts_ms": 1789176746674, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0369", "position": {"x": -800.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746674, "virtual_time_s": 5536.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 370, "wall_ts_ms": 1789176746675, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0370", "position": {"x": -800.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746675, "virtual_time_s": 5542.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 371, "wall_ts_ms": 1789176746675, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0371", "position": {"x": -800.0, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746675, "virtual_time_s": 5548.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 372, "wall_ts_ms": 1789176746676, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0372", "position": {"x": -800.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746676, "virtual_time_s": 5554.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 373, "wall_ts_ms": 1789176746677, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0373", "position": {"x": -800.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746677, "virtual_time_s": 5560.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 374, "wall_ts_ms": 1789176746677, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0374", "position": {"x": -800.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746677, "virtual_time_s": 5566.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 375, "wall_ts_ms": 1789176746678, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0375", "position": {"x": -800.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746678, "virtual_time_s": 5572.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 376, "wall_ts_ms": 1789176746678, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0376", "position": {"x": -800.0, "y": 0.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746678, "virtual_time_s": 5578.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 377, "wall_ts_ms": 1789176746679, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0377", "position": {"x": -800.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746679, "virtual_time_s": 5584.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 378, "wall_ts_ms": 1789176746679, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0378", "position": {"x": -800.0, "y": 0.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746679, "virtual_time_s": 5590.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 379, "wall_ts_ms": 1789176746680, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0379", "position": {"x": -800.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746680, "virtual_time_s": 5596.09393, "measure_result": "no_signal"}}
{"event": "action", "seq": 380, "wall_ts_ms": 1789176746681, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0380", "position": {"x": -1200.0, "y": 800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746681, "virtual_time_s": 5779.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 381, "wall_ts_ms": 1789176746681, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0381", "position": {"x": -1200.0, "y": 800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746681, "virtual_time_s": 5785.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 382, "wall_ts_ms": 1789176746682, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0382", "position": {"x": -1200.0, "y": 800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746682, "virtual_time_s": 5791.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 383, "wall_ts_ms": 1789176746682, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0383", "position": {"x": -1200.0, "y": 800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746682, "virtual_time_s": 5797.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 384, "wall_ts_ms": 1789176746683, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0384", "position": {"x": -1200.0, "y": 800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746683, "virtual_time_s": 5803.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 385, "wall_ts_ms": 1789176746683, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0385", "position": {"x": -1200.0, "y": 800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746683, "virtual_time_s": 5809.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 386, "wall_ts_ms": 1789176746684, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0386", "position": {"x": -1200.0, "y": 800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746684, "virtual_time_s": 5815.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 387, "wall_ts_ms": 1789176746684, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0387", "position": {"x": -1200.0, "y": 800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746684, "virtual_time_s": 5821.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 388, "wall_ts_ms": 1789176746685, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0388", "position": {"x": -1200.0, "y": 800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746685, "virtual_time_s": 5827.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 389, "wall_ts_ms": 1789176746685, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0389", "position": {"x": -1200.0, "y": 800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746685, "virtual_time_s": 5833.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 390, "wall_ts_ms": 1789176746686, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0390", "position": {"x": -1200.0, "y": 800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746686, "virtual_time_s": 5839.979368, "measure_result": "no_signal"}}
{"event": "action", "seq": 391, "wall_ts_ms": 1789176746687, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0391", "position": {"x": -1400.0, "y": 1400.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746687, "virtual_time_s": 5971.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 392, "wall_ts_ms": 1789176746687, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0392", "position": {"x": -1400.0, "y": 1400.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746687, "virtual_time_s": 5977.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 393, "wall_ts_ms": 1789176746688, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0393", "position": {"x": -1400.0, "y": 1400.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746688, "virtual_time_s": 5983.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 394, "wall_ts_ms": 1789176746688, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0394", "position": {"x": -1400.0, "y": 1400.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746688, "virtual_time_s": 5989.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 395, "wall_ts_ms": 1789176746689, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0395", "position": {"x": -1400.0, "y": 1400.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746689, "virtual_time_s": 5995.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 396, "wall_ts_ms": 1789176746689, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0396", "position": {"x": -1400.0, "y": 1400.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746689, "virtual_time_s": 6001.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 397, "wall_ts_ms": 1789176746690, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0397", "position": {"x": -1400.0, "y": 1400.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746690, "virtual_time_s": 6007.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 398, "wall_ts_ms": 1789176746690, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0398", "position": {"x": -1400.0, "y": 1400.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746690, "virtual_time_s": 6013.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 399, "wall_ts_ms": 1789176746691, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0399", "position": {"x": -1400.0, "y": 1400.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746691, "virtual_time_s": 6019.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 400, "wall_ts_ms": 1789176746691, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0400", "position": {"x": -1400.0, "y": 1400.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746691, "virtual_time_s": 6025.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 401, "wall_ts_ms": 1789176746692, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0401", "position": {"x": -1400.0, "y": 1400.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746692, "virtual_time_s": 6031.470474, "measure_result": "no_signal"}}
{"event": "action", "seq": 402, "wall_ts_ms": 1789176746692, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0402", "position": {"x": -1200.0, "y": 1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746692, "virtual_time_s": 6125.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 403, "wall_ts_ms": 1789176746693, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0403", "position": {"x": -1200.0, "y": 1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746693, "virtual_time_s": 6131.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 404, "wall_ts_ms": 1789176746693, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0404", "position": {"x": -1200.0, "y": 1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746693, "virtual_time_s": 6137.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 405, "wall_ts_ms": 1789176746694, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0405", "position": {"x": -1200.0, "y": 1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746694, "virtual_time_s": 6143.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 406, "wall_ts_ms": 1789176746694, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0406", "position": {"x": -1200.0, "y": 1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746694, "virtual_time_s": 6149.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 407, "wall_ts_ms": 1789176746695, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0407", "position": {"x": -1200.0, "y": 1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746695, "virtual_time_s": 6155.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 408, "wall_ts_ms": 1789176746696, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0408", "position": {"x": -1200.0, "y": 1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746696, "virtual_time_s": 6161.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 409, "wall_ts_ms": 1789176746696, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0409", "position": {"x": -1200.0, "y": 1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746696, "virtual_time_s": 6167.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 410, "wall_ts_ms": 1789176746697, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0410", "position": {"x": -1200.0, "y": 1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746697, "virtual_time_s": 6173.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 411, "wall_ts_ms": 1789176746697, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0411", "position": {"x": -1200.0, "y": 1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746697, "virtual_time_s": 6179.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 412, "wall_ts_ms": 1789176746698, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0412", "position": {"x": -1200.0, "y": 1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746698, "virtual_time_s": 6185.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 413, "wall_ts_ms": 1789176746698, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0413", "position": {"x": -200.0, "y": 1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746698, "virtual_time_s": 6390.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 414, "wall_ts_ms": 1789176746699, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0414", "position": {"x": -200.0, "y": 1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746699, "virtual_time_s": 6396.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 415, "wall_ts_ms": 1789176746699, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0415", "position": {"x": -200.0, "y": 1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746699, "virtual_time_s": 6402.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 416, "wall_ts_ms": 1789176746700, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0416", "position": {"x": -200.0, "y": 1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746700, "virtual_time_s": 6408.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 417, "wall_ts_ms": 1789176746700, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0417", "position": {"x": -200.0, "y": 1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746700, "virtual_time_s": 6414.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 418, "wall_ts_ms": 1789176746701, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0418", "position": {"x": -200.0, "y": 1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746701, "virtual_time_s": 6420.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 419, "wall_ts_ms": 1789176746701, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0419", "position": {"x": -200.0, "y": 1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746701, "virtual_time_s": 6426.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 420, "wall_ts_ms": 1789176746702, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0420", "position": {"x": -200.0, "y": 1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746702, "virtual_time_s": 6432.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 421, "wall_ts_ms": 1789176746702, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0421", "position": {"x": -200.0, "y": 1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746702, "virtual_time_s": 6438.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 422, "wall_ts_ms": 1789176746703, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0422", "position": {"x": -200.0, "y": 1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746703, "virtual_time_s": 6444.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 423, "wall_ts_ms": 1789176746703, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0423", "position": {"x": -200.0, "y": 1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746703, "virtual_time_s": 6450.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 424, "wall_ts_ms": 1789176746704, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0424", "position": {"x": 400.0, "y": 1800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746704, "virtual_time_s": 6575.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 425, "wall_ts_ms": 1789176746704, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0425", "position": {"x": 400.0, "y": 1800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746704, "virtual_time_s": 6581.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 426, "wall_ts_ms": 1789176746705, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0426", "position": {"x": 400.0, "y": 1800.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746705, "virtual_time_s": 6587.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 427, "wall_ts_ms": 1789176746706, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0427", "position": {"x": 400.0, "y": 1800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746706, "virtual_time_s": 6593.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 428, "wall_ts_ms": 1789176746706, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0428", "position": {"x": 400.0, "y": 1800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746706, "virtual_time_s": 6599.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 429, "wall_ts_ms": 1789176746707, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0429", "position": {"x": 400.0, "y": 1800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746707, "virtual_time_s": 6605.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 430, "wall_ts_ms": 1789176746708, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0430", "position": {"x": 400.0, "y": 1800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746708, "virtual_time_s": 6611.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 431, "wall_ts_ms": 1789176746709, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0431", "position": {"x": 400.0, "y": 1800.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746709, "virtual_time_s": 6617.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 432, "wall_ts_ms": 1789176746710, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0432", "position": {"x": 400.0, "y": 1800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746710, "virtual_time_s": 6623.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 433, "wall_ts_ms": 1789176746711, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0433", "position": {"x": 400.0, "y": 1800.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746711, "virtual_time_s": 6629.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 434, "wall_ts_ms": 1789176746711, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0434", "position": {"x": 400.0, "y": 1800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746711, "virtual_time_s": 6635.913193, "measure_result": "no_signal"}}
{"event": "action", "seq": 435, "wall_ts_ms": 1789176746712, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0435", "position": {"x": 1200.0, "y": 1600.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176746712, "virtual_time_s": 6805.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 436, "wall_ts_ms": 1789176746712, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0436", "position": {"x": 1200.0, "y": 1600.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176746712, "virtual_time_s": 6811.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 437, "wall_ts_ms": 1789176746713, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0437", "position": {"x": 1200.0, "y": 1600.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176746713, "virtual_time_s": 6817.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 438, "wall_ts_ms": 1789176746713, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0438", "position": {"x": 1200.0, "y": 1600.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176746713, "virtual_time_s": 6823.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 439, "wall_ts_ms": 1789176746714, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0439", "position": {"x": 1200.0, "y": 1600.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176746714, "virtual_time_s": 6829.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 440, "wall_ts_ms": 1789176746714, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0440", "position": {"x": 1200.0, "y": 1600.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176746714, "virtual_time_s": 6835.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 441, "wall_ts_ms": 1789176746715, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0441", "position": {"x": 1200.0, "y": 1600.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176746715, "virtual_time_s": 6841.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 442, "wall_ts_ms": 1789176746716, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0442", "position": {"x": 1200.0, "y": 1600.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746716, "virtual_time_s": 6847.837418, "measure_result": "direction", "svd_deg": 281.22}}
{"event": "action", "seq": 443, "wall_ts_ms": 1789176746743, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0443", "position": {"x": 1200.0, "y": 1600.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176746743, "virtual_time_s": 6853.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 444, "wall_ts_ms": 1789176746743, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0444", "position": {"x": 1200.0, "y": 1600.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176746743, "virtual_time_s": 6859.837418, "measure_result": "direction", "svd_deg": 286.65}}
{"event": "action", "seq": 445, "wall_ts_ms": 1789176746771, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0445", "position": {"x": 1200.0, "y": 1600.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176746771, "virtual_time_s": 6865.837418, "measure_result": "no_signal"}}
{"event": "action", "seq": 446, "wall_ts_ms": 1789176746870, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0446", "position": {"x": 1376.9183394605325, "y": 1598.4618226024536}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746870, "virtual_time_s": 6907.222423, "measure_result": "direction", "svd_deg": 268.73}}
{"event": "action", "seq": 447, "wall_ts_ms": 1789176746895, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0447", "position": {"x": 1361.0274758841142, "y": 977.2163838723077}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746895, "virtual_time_s": 7036.512151, "measure_result": "direction", "svd_deg": 269.37}}
{"event": "action", "seq": 448, "wall_ts_ms": 1789176746914, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0448", "position": {"x": 1360.4285069307975, "y": 914.5146047789754}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746914, "virtual_time_s": 7054.053079, "measure_result": "direction", "svd_deg": 269.45}}
{"event": "action", "seq": 449, "wall_ts_ms": 1789176746932, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0449", "position": {"x": 1360.616258629032, "y": 907.0437018395313}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746932, "virtual_time_s": 7060.547731, "measure_result": "direction", "svd_deg": 269.56}}
{"event": "action", "seq": 450, "wall_ts_ms": 1789176746949, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0450", "position": {"x": 1360.8267706096776, "y": 904.6094986372296}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746949, "virtual_time_s": 7066.036389, "measure_result": "direction", "svd_deg": 268.57}}
{"event": "action", "seq": 451, "wall_ts_ms": 1789176746966, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0451", "position": {"x": 1359.473062458676, "y": 900.8377878197774}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746966, "virtual_time_s": 7071.837846, "measure_result": "direction", "svd_deg": 269.02}}
{"event": "action", "seq": 452, "wall_ts_ms": 1789176746982, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0452", "position": {"x": 1359.4561615203038, "y": 899.1627785108348}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746982, "virtual_time_s": 7077.172865, "measure_result": "direction", "svd_deg": 269.01}}
{"event": "action", "seq": 453, "wall_ts_ms": 1789176746999, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0453", "position": {"x": 1359.4442600587033, "y": 897.9832580766667}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176746999, "virtual_time_s": 7082.408781, "measure_result": "direction", "svd_deg": 269.95}}
{"event": "action", "seq": 454, "wall_ts_ms": 1789176747000, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0454", "position": {"x": 1350.0, "y": 870.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747000, "virtual_time_s": 7091.31558, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 455, "wall_ts_ms": 1789176747000, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0455", "position": {"x": 1350.0, "y": 850.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747000, "virtual_time_s": 7098.31558, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 456, "wall_ts_ms": 1789176747001, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0456", "position": {"x": 1350.0, "y": 830.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747001, "virtual_time_s": 7105.31558, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 457, "wall_ts_ms": 1789176747002, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0457", "position": {"x": 1350.0, "y": 810.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747002, "virtual_time_s": 7112.31558, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 458, "wall_ts_ms": 1789176747002, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0458", "position": {"x": 1350.0, "y": 790.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747002, "virtual_time_s": 7119.31558, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 459, "wall_ts_ms": 1789176747003, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0459", "position": {"x": 1350.0, "y": 770.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789176747003, "virtual_time_s": 7128.31558, "clear_result": "success"}}
{"event": "action", "seq": 460, "wall_ts_ms": 1789176747102, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0460", "position": {"x": 1267.751589068303, "y": 905.6407266151634}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176747102, "virtual_time_s": 7166.04141, "measure_result": "direction", "svd_deg": 71.8}}
{"event": "action", "seq": 461, "wall_ts_ms": 1789176747117, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0461", "position": {"x": 1317.933528813386, "y": 1105.8121429791947}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176747117, "virtual_time_s": 7212.31456, "measure_result": "direction", "svd_deg": 22.95}}
{"event": "action", "seq": 462, "wall_ts_ms": 1789176747118, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0462", "position": {"x": 1338.6900103764715, "y": 1114.6535341814697}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789176747118, "virtual_time_s": 7221.826773, "clear_result": "success"}}
{"event": "action", "seq": 463, "wall_ts_ms": 1789176747119, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0463", "position": {"x": 1000.0, "y": 1000.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747119, "virtual_time_s": 7299.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 464, "wall_ts_ms": 1789176747120, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0464", "position": {"x": 1000.0, "y": 1000.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747120, "virtual_time_s": 7305.340787, "measure_result": "direction", "svd_deg": 307.65}}
{"event": "action", "seq": 465, "wall_ts_ms": 1789176747151, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0465", "position": {"x": 1000.0, "y": 1000.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747151, "virtual_time_s": 7311.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 466, "wall_ts_ms": 1789176747152, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0466", "position": {"x": 1000.0, "y": 1000.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747152, "virtual_time_s": 7317.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 467, "wall_ts_ms": 1789176747153, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0467", "position": {"x": 1000.0, "y": 1000.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747153, "virtual_time_s": 7323.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 468, "wall_ts_ms": 1789176747153, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0468", "position": {"x": 1000.0, "y": 1000.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747153, "virtual_time_s": 7329.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 469, "wall_ts_ms": 1789176747154, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0469", "position": {"x": 1000.0, "y": 1000.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747154, "virtual_time_s": 7335.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 470, "wall_ts_ms": 1789176747154, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0470", "position": {"x": 1000.0, "y": 1000.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747154, "virtual_time_s": 7341.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 471, "wall_ts_ms": 1789176747155, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0471", "position": {"x": 1000.0, "y": 1000.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747155, "virtual_time_s": 7347.340787, "measure_result": "no_signal"}}
{"event": "action", "seq": 472, "wall_ts_ms": 1789176747255, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0472", "position": {"x": 926.2448542889847, "y": 936.2857052701793}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747255, "virtual_time_s": 7372.833691, "measure_result": "direction", "svd_deg": 313.86}}
{"event": "action", "seq": 473, "wall_ts_ms": 1789176747307, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0473", "position": {"x": 1281.7263770791885, "y": 545.6716560307773}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747307, "virtual_time_s": 7483.464453, "measure_result": "direction", "svd_deg": 316.07}}
{"event": "action", "seq": 474, "wall_ts_ms": 1789176747337, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0474", "position": {"x": 1404.2733501305574, "y": 429.96480985903656}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747337, "virtual_time_s": 7522.172514, "measure_result": "direction", "svd_deg": 316.97}}
{"event": "action", "seq": 475, "wall_ts_ms": 1789176747359, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0475", "position": {"x": 1422.849787772556, "y": 418.12719651105397}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747359, "virtual_time_s": 7531.578025, "measure_result": "direction", "svd_deg": 314.3}}
{"event": "action", "seq": 476, "wall_ts_ms": 1789176747386, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0476", "position": {"x": 1422.849787772556, "y": 418.12719651105397}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747386, "virtual_time_s": 7536.578025, "measure_result": "direction", "svd_deg": 314.3}}
{"event": "action", "seq": 477, "wall_ts_ms": 1789176747413, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0477", "position": {"x": 1422.849787772556, "y": 418.12719651105397}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747413, "virtual_time_s": 7541.578025, "measure_result": "direction", "svd_deg": 314.3}}
{"event": "action", "seq": 478, "wall_ts_ms": 1789176747440, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0478", "position": {"x": 1422.849787772556, "y": 418.12719651105397}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747440, "virtual_time_s": 7546.578025, "measure_result": "direction", "svd_deg": 314.3}}
{"event": "action", "seq": 479, "wall_ts_ms": 1789176747467, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0479", "position": {"x": 1422.849787772556, "y": 418.12719651105397}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747467, "virtual_time_s": 7551.578025, "measure_result": "direction", "svd_deg": 314.3}}
{"event": "action", "seq": 480, "wall_ts_ms": 1789176747468, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0480", "position": {"x": 1470.0, "y": 370.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747468, "virtual_time_s": 7568.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 481, "wall_ts_ms": 1789176747469, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0481", "position": {"x": 1470.0, "y": 350.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747469, "virtual_time_s": 7575.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 482, "wall_ts_ms": 1789176747469, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0482", "position": {"x": 1490.0, "y": 350.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747469, "virtual_time_s": 7582.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 483, "wall_ts_ms": 1789176747470, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0483", "position": {"x": 1490.0, "y": 330.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747470, "virtual_time_s": 7589.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 484, "wall_ts_ms": 1789176747470, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0484", "position": {"x": 1510.0, "y": 330.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747470, "virtual_time_s": 7596.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 485, "wall_ts_ms": 1789176747471, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0485", "position": {"x": 1510.0, "y": 310.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747471, "virtual_time_s": 7603.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 486, "wall_ts_ms": 1789176747471, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0486", "position": {"x": 1530.0, "y": 310.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747471, "virtual_time_s": 7610.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 487, "wall_ts_ms": 1789176747472, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0487", "position": {"x": 1530.0, "y": 290.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747472, "virtual_time_s": 7617.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 488, "wall_ts_ms": 1789176747472, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0488", "position": {"x": 1550.0, "y": 290.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747472, "virtual_time_s": 7624.052994, "clear_result": "no_target_in_range"}}
{"event": "action", "seq": 489, "wall_ts_ms": 1789176747473, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0489", "position": {"x": 1550.0, "y": 270.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789176747473, "virtual_time_s": 7633.052994, "clear_result": "success"}}
{"event": "action", "seq": 490, "wall_ts_ms": 1789176747473, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0490", "position": {"x": 1800.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747473, "virtual_time_s": 7712.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 491, "wall_ts_ms": 1789176747474, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0491", "position": {"x": 1800.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747474, "virtual_time_s": 7718.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 492, "wall_ts_ms": 1789176747474, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0492", "position": {"x": 1800.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747474, "virtual_time_s": 7724.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 493, "wall_ts_ms": 1789176747475, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0493", "position": {"x": 1800.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747475, "virtual_time_s": 7730.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 494, "wall_ts_ms": 1789176747475, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0494", "position": {"x": 1800.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747475, "virtual_time_s": 7736.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 495, "wall_ts_ms": 1789176747476, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0495", "position": {"x": 1800.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747476, "virtual_time_s": 7742.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 496, "wall_ts_ms": 1789176747477, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0496", "position": {"x": 1800.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747477, "virtual_time_s": 7748.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 497, "wall_ts_ms": 1789176747477, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0497", "position": {"x": 1800.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747477, "virtual_time_s": 7754.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 498, "wall_ts_ms": 1789176747478, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0498", "position": {"x": 1800.0, "y": 600.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747478, "virtual_time_s": 7879.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 499, "wall_ts_ms": 1789176747478, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0499", "position": {"x": 1800.0, "y": 600.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747478, "virtual_time_s": 7885.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 500, "wall_ts_ms": 1789176747479, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0500", "position": {"x": 1800.0, "y": 600.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747479, "virtual_time_s": 7891.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 501, "wall_ts_ms": 1789176747479, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0501", "position": {"x": 1800.0, "y": 600.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747479, "virtual_time_s": 7897.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 502, "wall_ts_ms": 1789176747480, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0502", "position": {"x": 1800.0, "y": 600.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747480, "virtual_time_s": 7903.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 503, "wall_ts_ms": 1789176747480, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0503", "position": {"x": 1800.0, "y": 600.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747480, "virtual_time_s": 7909.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 504, "wall_ts_ms": 1789176747481, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0504", "position": {"x": 1800.0, "y": 600.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747481, "virtual_time_s": 7915.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 505, "wall_ts_ms": 1789176747482, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0505", "position": {"x": 1800.0, "y": 600.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747482, "virtual_time_s": 7921.646472, "measure_result": "no_signal"}}
{"event": "action", "seq": 506, "wall_ts_ms": 1789176747482, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0506", "position": {"x": 800.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747482, "virtual_time_s": 8159.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 507, "wall_ts_ms": 1789176747483, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0507", "position": {"x": 800.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747483, "virtual_time_s": 8165.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 508, "wall_ts_ms": 1789176747483, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0508", "position": {"x": 800.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747483, "virtual_time_s": 8171.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 509, "wall_ts_ms": 1789176747484, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0509", "position": {"x": 800.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747484, "virtual_time_s": 8177.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 510, "wall_ts_ms": 1789176747484, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0510", "position": {"x": 800.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747484, "virtual_time_s": 8183.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 511, "wall_ts_ms": 1789176747485, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0511", "position": {"x": 800.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747485, "virtual_time_s": 8189.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 512, "wall_ts_ms": 1789176747485, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0512", "position": {"x": 800.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747485, "virtual_time_s": 8195.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 513, "wall_ts_ms": 1789176747486, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0513", "position": {"x": 800.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747486, "virtual_time_s": 8201.884548, "measure_result": "no_signal"}}
{"event": "action", "seq": 514, "wall_ts_ms": 1789176747486, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0514", "position": {"x": 1800.0, "y": -800.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747486, "virtual_time_s": 8463.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 515, "wall_ts_ms": 1789176747487, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0515", "position": {"x": 1800.0, "y": -800.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747487, "virtual_time_s": 8469.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 516, "wall_ts_ms": 1789176747487, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0516", "position": {"x": 1800.0, "y": -800.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747487, "virtual_time_s": 8475.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 517, "wall_ts_ms": 1789176747488, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0517", "position": {"x": 1800.0, "y": -800.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747488, "virtual_time_s": 8481.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 518, "wall_ts_ms": 1789176747488, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0518", "position": {"x": 1800.0, "y": -800.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747488, "virtual_time_s": 8487.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 519, "wall_ts_ms": 1789176747489, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0519", "position": {"x": 1800.0, "y": -800.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747489, "virtual_time_s": 8493.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 520, "wall_ts_ms": 1789176747489, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0520", "position": {"x": 1800.0, "y": -800.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747489, "virtual_time_s": 8499.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 521, "wall_ts_ms": 1789176747490, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0521", "position": {"x": 1800.0, "y": -800.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747490, "virtual_time_s": 8505.009517, "measure_result": "no_signal"}}
{"event": "action", "seq": 522, "wall_ts_ms": 1789176747490, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0522", "position": {"x": -2200.0, "y": 600.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789176747490, "virtual_time_s": 9357.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 523, "wall_ts_ms": 1789176747491, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0523", "position": {"x": -2200.0, "y": 600.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789176747491, "virtual_time_s": 9363.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 524, "wall_ts_ms": 1789176747491, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0524", "position": {"x": -2200.0, "y": 600.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789176747491, "virtual_time_s": 9369.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 525, "wall_ts_ms": 1789176747492, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0525", "position": {"x": -2200.0, "y": 600.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789176747492, "virtual_time_s": 9375.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 526, "wall_ts_ms": 1789176747492, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0526", "position": {"x": -2200.0, "y": 600.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789176747492, "virtual_time_s": 9381.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 527, "wall_ts_ms": 1789176747493, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0527", "position": {"x": -2200.0, "y": 600.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789176747493, "virtual_time_s": 9387.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 528, "wall_ts_ms": 1789176747493, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0528", "position": {"x": -2200.0, "y": 600.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789176747493, "virtual_time_s": 9393.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 529, "wall_ts_ms": 1789176747494, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0529", "position": {"x": -2200.0, "y": 600.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789176747494, "virtual_time_s": 9399.594321, "measure_result": "no_signal"}}
{"event": "action", "seq": 530, "wall_ts_ms": 1789176747494, "method": "POST", "path": "/exit", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "48cf97ba3914-0530"}, "response": {"accepted": true, "real_timestamp_ms": 1789176747494, "virtual_time_s": 9399.594321, "exit_reason": "user_exit"}}
{"event": "session_end", "reason": "user_exit", "virtual_time_s": 9399.594321, "real_elapsed_s": 15.429505, "request_count": 530, "cleared_count": 12}
@@ -0,0 +1,104 @@
{
"case_code": "5TQF-A8K9-QW89-V2ET",
"module": "q4_practice",
"robot_id": "1",
"seed": 1415283134,
"truth": [
{
"channel": 17,
"x": 201.83789549004942,
"y": 411.9733699427643,
"r_eff_m": 1221.4478310143415,
"directional": true,
"heading_deg": 315.48877042891024
},
{
"channel": 4,
"x": -1105.4390726028914,
"y": -836.873727576673,
"r_eff_m": 1449.9048730606553,
"directional": true,
"heading_deg": 189.031114716249
},
{
"channel": 2,
"x": -502.2367519508228,
"y": 921.7249012630463,
"r_eff_m": 1222.172364639404,
"directional": true,
"heading_deg": 170.22567245589232
},
{
"channel": 15,
"x": 1338.5109618239856,
"y": 1114.8362795676107,
"r_eff_m": 1125.022131637457,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 9,
"x": -916.8137760578517,
"y": -848.3836360990396,
"r_eff_m": 1463.9469990173247,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 16,
"x": -962.2248701879902,
"y": -861.6772389852658,
"r_eff_m": 1057.5023609780635,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 8,
"x": 426.0100239176212,
"y": -1395.433153095009,
"r_eff_m": 1316.6412496443302,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 5,
"x": 1565.3993113628057,
"y": 276.7308299465653,
"r_eff_m": 1300.3648907717125,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 12,
"x": 1358.7991804165615,
"y": 756.6431101382647,
"r_eff_m": 1268.3365819478918,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 20,
"x": -1025.1717086952801,
"y": -1138.8576473722178,
"r_eff_m": 1274.8459885352177,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 13,
"x": -973.4448466468912,
"y": 950.3687397692318,
"r_eff_m": 1358.1824021574332,
"directional": false,
"heading_deg": 0.0
},
{
"channel": 1,
"x": -679.5564210766588,
"y": -113.09168897579823,
"r_eff_m": 1357.5098916694712,
"directional": false,
"heading_deg": 0.0
}
]
}
@@ -0,0 +1,122 @@
{"event": "session_start", "case_code": "8N5E-ZWC4-WH88-PLDD", "module": "q3_practice", "robot_id": "1", "seed": 1527834650, "countdown_s": 5.0, "window_s": 1500.0, "max_real_duration_s": 1200.0, "truth": [{"channel": 16, "x": -1426.4751982022606, "y": 146.3393180231787, "r_eff_m": 1059.0849032882313, "directional": false, "heading_deg": 0.0}, {"channel": 15, "x": 290.56903183954273, "y": 787.6776134403464, "r_eff_m": 1117.8704763047594, "directional": false, "heading_deg": 0.0}, {"channel": 20, "x": -554.3720531046184, "y": -965.0426141773152, "r_eff_m": 1316.1384565200517, "directional": false, "heading_deg": 0.0}, {"channel": 9, "x": 1460.5517979776075, "y": -36.23476869190996, "r_eff_m": 1217.206292613953, "directional": false, "heading_deg": 0.0}, {"channel": 4, "x": -1526.409529554257, "y": 125.74005540490136, "r_eff_m": 1215.3478133430863, "directional": false, "heading_deg": 0.0}, {"channel": 13, "x": 395.0883005217367, "y": -3.392204073397361, "r_eff_m": 1408.4188419024495, "directional": false, "heading_deg": 0.0}, {"channel": 11, "x": -1217.7260094049198, "y": 153.8296545403218, "r_eff_m": 1215.4430480237338, "directional": false, "heading_deg": 0.0}, {"channel": 3, "x": 1564.1625306319058, "y": 361.40024430914116, "r_eff_m": 1403.217608954327, "directional": false, "heading_deg": 0.0}, {"channel": 1, "x": -766.740093640507, "y": -711.7971768719724, "r_eff_m": 1463.975512276439, "directional": false, "heading_deg": 0.0}, {"channel": 7, "x": 701.797784680196, "y": -990.3589505719676, "r_eff_m": 1438.666080940352, "directional": false, "heading_deg": 0.0}, {"channel": 12, "x": 826.2042304331064, "y": 169.49742165027592, "r_eff_m": 1189.741197001806, "directional": false, "heading_deg": 0.0}, {"channel": 2, "x": -1654.1635347253784, "y": -532.8383982214895, "r_eff_m": 1385.1047407256679, "directional": false, "heading_deg": 0.0}]}
{"event": "action", "seq": 1, "wall_ts_ms": 1789177718592, "method": "POST", "path": "/enter", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0001"}, "response": {"accepted": true, "real_timestamp_ms": 1789177718592, "virtual_time_s": 0.0, "max_virtual_duration_s": 360000.0, "max_real_duration_s": 1200, "remaining_real_duration_s": 1200}}
{"event": "action", "seq": 2, "wall_ts_ms": 1789177718602, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0002", "position": {"x": 0.0, "y": 0.0}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789177718602, "virtual_time_s": 5.0, "measure_result": "direction", "svd_deg": 223.42}}
{"event": "action", "seq": 3, "wall_ts_ms": 1789177718637, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0003", "position": {"x": 0.0, "y": 0.0}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789177718637, "virtual_time_s": 11.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 4, "wall_ts_ms": 1789177718643, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0004", "position": {"x": 0.0, "y": 0.0}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177718643, "virtual_time_s": 17.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 5, "wall_ts_ms": 1789177718648, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0005", "position": {"x": 0.0, "y": 0.0}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789177718648, "virtual_time_s": 23.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 6, "wall_ts_ms": 1789177718652, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0006", "position": {"x": 0.0, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177718652, "virtual_time_s": 29.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 7, "wall_ts_ms": 1789177718658, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0007", "position": {"x": 0.0, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177718658, "virtual_time_s": 35.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 8, "wall_ts_ms": 1789177718662, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0008", "position": {"x": 0.0, "y": 0.0}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789177718662, "virtual_time_s": 41.0, "measure_result": "direction", "svd_deg": 306.28}}
{"event": "action", "seq": 9, "wall_ts_ms": 1789177718693, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0009", "position": {"x": 0.0, "y": 0.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177718693, "virtual_time_s": 47.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 10, "wall_ts_ms": 1789177718697, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0010", "position": {"x": 0.0, "y": 0.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177718697, "virtual_time_s": 53.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 11, "wall_ts_ms": 1789177718703, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0011", "position": {"x": 0.0, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177718703, "virtual_time_s": 59.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 12, "wall_ts_ms": 1789177718707, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0012", "position": {"x": 0.0, "y": 0.0}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789177718707, "virtual_time_s": 65.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 13, "wall_ts_ms": 1789177718713, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0013", "position": {"x": 0.0, "y": 0.0}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789177718713, "virtual_time_s": 71.0, "measure_result": "direction", "svd_deg": 11.92}}
{"event": "action", "seq": 14, "wall_ts_ms": 1789177718748, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0014", "position": {"x": 0.0, "y": 0.0}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789177718748, "virtual_time_s": 77.0, "measure_result": "direction", "svd_deg": 358.77}}
{"event": "action", "seq": 15, "wall_ts_ms": 1789177718787, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0015", "position": {"x": 0.0, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177718787, "virtual_time_s": 83.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 16, "wall_ts_ms": 1789177718796, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0016", "position": {"x": 0.0, "y": 0.0}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789177718796, "virtual_time_s": 89.0, "measure_result": "direction", "svd_deg": 69.34}}
{"event": "action", "seq": 17, "wall_ts_ms": 1789177718833, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0017", "position": {"x": 0.0, "y": 0.0}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789177718833, "virtual_time_s": 95.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 18, "wall_ts_ms": 1789177718841, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0018", "position": {"x": 0.0, "y": 0.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177718841, "virtual_time_s": 101.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 19, "wall_ts_ms": 1789177718846, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0019", "position": {"x": 0.0, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177718846, "virtual_time_s": 107.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 20, "wall_ts_ms": 1789177718853, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0020", "position": {"x": 0.0, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177718853, "virtual_time_s": 113.0, "measure_result": "no_signal"}}
{"event": "action", "seq": 21, "wall_ts_ms": 1789177718861, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0021", "position": {"x": 0.0, "y": 0.0}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789177718860, "virtual_time_s": 119.0, "measure_result": "direction", "svd_deg": 239.4}}
{"event": "action", "seq": 22, "wall_ts_ms": 1789177718924, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0022", "position": {"x": -473.65244518877944, "y": -482.587298252437}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789177718924, "virtual_time_s": 259.238625, "measure_result": "direction", "svd_deg": 261.24}}
{"event": "action", "seq": 23, "wall_ts_ms": 1789177718925, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0023", "position": {"x": -473.65244518877944, "y": -482.587298252437}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789177718925, "virtual_time_s": 265.238625, "measure_result": "direction", "svd_deg": 217.7}}
{"event": "action", "seq": 24, "wall_ts_ms": 1789177718938, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0024", "position": {"x": -450.4061206175299, "y": -802.0243994224704}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789177718938, "virtual_time_s": 334.294992, "measure_result": "direction", "svd_deg": 163.81}}
{"event": "action", "seq": 25, "wall_ts_ms": 1789177718940, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0025", "position": {"x": -761.7574665299293, "y": -711.8326666959506}, "channel": 1}, "response": {"accepted": true, "real_timestamp_ms": 1789177718940, "virtual_time_s": 404.125296, "clear_result": "success"}}
{"event": "action", "seq": 26, "wall_ts_ms": 1789177718941, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0026", "position": {"x": -761.7574665299293, "y": -711.8326666959506}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789177718941, "virtual_time_s": 410.125296, "measure_result": "direction", "svd_deg": 308.77}}
{"event": "action", "seq": 27, "wall_ts_ms": 1789177718953, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0027", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789177718953, "virtual_time_s": 485.01501, "measure_result": "direction", "svd_deg": 157.12}}
{"event": "action", "seq": 28, "wall_ts_ms": 1789177718973, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0028", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177718973, "virtual_time_s": 491.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 29, "wall_ts_ms": 1789177718976, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0029", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789177718976, "virtual_time_s": 497.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 30, "wall_ts_ms": 1789177718979, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0030", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177718979, "virtual_time_s": 503.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 31, "wall_ts_ms": 1789177718981, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0031", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177718981, "virtual_time_s": 509.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 32, "wall_ts_ms": 1789177718984, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0032", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177718984, "virtual_time_s": 515.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 33, "wall_ts_ms": 1789177718986, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0033", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177718986, "virtual_time_s": 521.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 34, "wall_ts_ms": 1789177718989, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0034", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177718989, "virtual_time_s": 527.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 35, "wall_ts_ms": 1789177718992, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0035", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789177718992, "virtual_time_s": 533.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 36, "wall_ts_ms": 1789177718996, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0036", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177718996, "virtual_time_s": 539.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 37, "wall_ts_ms": 1789177718999, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0037", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789177718999, "virtual_time_s": 545.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 38, "wall_ts_ms": 1789177719003, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0038", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719003, "virtual_time_s": 551.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 39, "wall_ts_ms": 1789177719006, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0039", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719006, "virtual_time_s": 557.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 40, "wall_ts_ms": 1789177719010, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0040", "position": {"x": -579.8500000000006, "y": -1004.3296607688133}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719010, "virtual_time_s": 563.01501, "measure_result": "no_signal"}}
{"event": "action", "seq": 41, "wall_ts_ms": 1789177719042, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0041", "position": {"x": -560.8418045015728, "y": -976.4060636017127}, "channel": 20}, "response": {"accepted": true, "real_timestamp_ms": 1789177719042, "virtual_time_s": 574.770863, "clear_result": "success"}}
{"event": "action", "seq": 42, "wall_ts_ms": 1789177719055, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0042", "position": {"x": -1111.4165285548472, "y": -1023.8554907742282}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789177719055, "virtual_time_s": 691.293978, "measure_result": "direction", "svd_deg": 138.8}}
{"event": "action", "seq": 43, "wall_ts_ms": 1789177719067, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0043", "position": {"x": -1651.6401282029797, "y": -550.2251896012102}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789177719067, "virtual_time_s": 839.983532, "measure_result": "direction", "svd_deg": 98.5}}
{"event": "action", "seq": 44, "wall_ts_ms": 1789177719069, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0044", "position": {"x": -1651.777119702916, "y": -549.4069993054234}, "channel": 2}, "response": {"accepted": true, "real_timestamp_ms": 1789177719069, "virtual_time_s": 845.149448, "clear_result": "success"}}
{"event": "action", "seq": 45, "wall_ts_ms": 1789177719081, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0045", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719081, "virtual_time_s": 998.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 46, "wall_ts_ms": 1789177719085, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0046", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789177719085, "virtual_time_s": 1004.660525, "measure_result": "direction", "svd_deg": 160.71}}
{"event": "action", "seq": 47, "wall_ts_ms": 1789177719117, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0047", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177719117, "virtual_time_s": 1010.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 48, "wall_ts_ms": 1789177719125, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0048", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177719125, "virtual_time_s": 1016.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 49, "wall_ts_ms": 1789177719131, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0049", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177719131, "virtual_time_s": 1022.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 50, "wall_ts_ms": 1789177719138, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0050", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719138, "virtual_time_s": 1028.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 51, "wall_ts_ms": 1789177719145, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0051", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177719145, "virtual_time_s": 1034.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 52, "wall_ts_ms": 1789177719155, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0052", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789177719155, "virtual_time_s": 1040.660525, "measure_result": "direction", "svd_deg": 109.68}}
{"event": "action", "seq": 53, "wall_ts_ms": 1789177719188, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0053", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177719188, "virtual_time_s": 1046.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 54, "wall_ts_ms": 1789177719191, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0054", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789177719191, "virtual_time_s": 1052.660525, "measure_result": "direction", "svd_deg": 151.16}}
{"event": "action", "seq": 55, "wall_ts_ms": 1789177719222, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0055", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719222, "virtual_time_s": 1058.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 56, "wall_ts_ms": 1789177719227, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0056", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719227, "virtual_time_s": 1064.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 57, "wall_ts_ms": 1789177719233, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0057", "position": {"x": -1159.7, "y": 1.4202228929711856e-13}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719233, "virtual_time_s": 1070.660525, "measure_result": "no_signal"}}
{"event": "action", "seq": 58, "wall_ts_ms": 1789177719278, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0058", "position": {"x": -1427.4425184408788, "y": -147.1906110389915}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789177719278, "virtual_time_s": 1137.76736, "measure_result": "direction", "svd_deg": 109.35}}
{"event": "action", "seq": 59, "wall_ts_ms": 1789177719280, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0059", "position": {"x": -1522.5599206546112, "y": 123.00010618867616}, "channel": 4}, "response": {"accepted": true, "real_timestamp_ms": 1789177719280, "virtual_time_s": 1200.056222, "clear_result": "success"}}
{"event": "action", "seq": 60, "wall_ts_ms": 1789177719283, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0060", "position": {"x": -1522.5599206546112, "y": 123.00010618867616}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789177719283, "virtual_time_s": 1206.056222, "measure_result": "direction", "svd_deg": 5.25}}
{"event": "action", "seq": 61, "wall_ts_ms": 1789177719286, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0061", "position": {"x": -1522.5599206546112, "y": 123.00010618867616}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789177719286, "virtual_time_s": 1212.056222, "measure_result": "direction", "svd_deg": 13.64}}
{"event": "action", "seq": 62, "wall_ts_ms": 1789177719304, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0062", "position": {"x": -1434.3849567067336, "y": 144.23605066321733}, "channel": 16}, "response": {"accepted": true, "real_timestamp_ms": 1789177719304, "virtual_time_s": 1235.19545, "clear_result": "success"}}
{"event": "action", "seq": 63, "wall_ts_ms": 1789177719323, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0063", "position": {"x": -1225.83931600015, "y": 150.90281387284583}, "channel": 11}, "response": {"accepted": true, "real_timestamp_ms": 1789177719323, "virtual_time_s": 1281.925885, "clear_result": "success"}}
{"event": "action", "seq": 64, "wall_ts_ms": 1789177719344, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0064", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719344, "virtual_time_s": 1501.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 65, "wall_ts_ms": 1789177719351, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0065", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177719351, "virtual_time_s": 1507.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 66, "wall_ts_ms": 1789177719359, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0066", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177719359, "virtual_time_s": 1513.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 67, "wall_ts_ms": 1789177719366, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0067", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177719366, "virtual_time_s": 1519.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 68, "wall_ts_ms": 1789177719374, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0068", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719374, "virtual_time_s": 1525.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 69, "wall_ts_ms": 1789177719382, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0069", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177719382, "virtual_time_s": 1531.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 70, "wall_ts_ms": 1789177719389, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0070", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177719389, "virtual_time_s": 1537.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 71, "wall_ts_ms": 1789177719395, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0071", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719395, "virtual_time_s": 1543.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 72, "wall_ts_ms": 1789177719402, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0072", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719401, "virtual_time_s": 1549.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 73, "wall_ts_ms": 1789177719408, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0073", "position": {"x": -579.8499999999998, "y": 1004.3296607688136}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719408, "virtual_time_s": 1555.994993, "measure_result": "no_signal"}}
{"event": "action", "seq": 74, "wall_ts_ms": 1789177719426, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0074", "position": {"x": 23.031096895769764, "y": 766.7491101366052}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789177719426, "virtual_time_s": 1691.59594, "measure_result": "direction", "svd_deg": 4.82}}
{"event": "action", "seq": 75, "wall_ts_ms": 1789177719435, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0075", "position": {"x": 298.2262092381425, "y": 790.2842455537672}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789177719435, "virtual_time_s": 1751.835872, "measure_result": "direction", "svd_deg": 199.25}}
{"event": "action", "seq": 76, "wall_ts_ms": 1789177719437, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0076", "position": {"x": 297.5814284315055, "y": 790.0580836065636}, "channel": 15}, "response": {"accepted": true, "real_timestamp_ms": 1789177719437, "virtual_time_s": 1756.972531, "clear_result": "success"}}
{"event": "action", "seq": 77, "wall_ts_ms": 1789177719443, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0077", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719443, "virtual_time_s": 1833.849285, "measure_result": "direction", "svd_deg": 326.84000000000003}}
{"event": "action", "seq": 78, "wall_ts_ms": 1789177719459, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0078", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177719459, "virtual_time_s": 1839.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 79, "wall_ts_ms": 1789177719462, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0079", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177719462, "virtual_time_s": 1845.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 80, "wall_ts_ms": 1789177719465, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0080", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177719465, "virtual_time_s": 1851.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 81, "wall_ts_ms": 1789177719468, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0081", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719468, "virtual_time_s": 1857.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 82, "wall_ts_ms": 1789177719470, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0082", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177719470, "virtual_time_s": 1863.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 83, "wall_ts_ms": 1789177719473, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0083", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177719473, "virtual_time_s": 1869.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 84, "wall_ts_ms": 1789177719475, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0084", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719475, "virtual_time_s": 1875.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 85, "wall_ts_ms": 1789177719478, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0085", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719478, "virtual_time_s": 1881.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 86, "wall_ts_ms": 1789177719480, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0086", "position": {"x": 579.8500000000001, "y": 1004.3296607688135}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719480, "virtual_time_s": 1887.849285, "measure_result": "no_signal"}}
{"event": "action", "seq": 87, "wall_ts_ms": 1789177719493, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0087", "position": {"x": 1004.1938800978712, "y": 505.72856686523653}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719493, "virtual_time_s": 2024.795194, "measure_result": "direction", "svd_deg": 345.51}}
{"event": "action", "seq": 88, "wall_ts_ms": 1789177719503, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0088", "position": {"x": 1573.9827834346736, "y": 356.74521333023995}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719503, "virtual_time_s": 2147.584062, "measure_result": "direction", "svd_deg": 155.09}}
{"event": "action", "seq": 89, "wall_ts_ms": 1789177719511, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0089", "position": {"x": 1543.6377024166522, "y": 370.19547054250387}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719511, "virtual_time_s": 2159.222536, "measure_result": "direction", "svd_deg": 335.92}}
{"event": "action", "seq": 90, "wall_ts_ms": 1789177719512, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0090", "position": {"x": 1557.1100795745858, "y": 364.22392813906714}, "channel": 3}, "response": {"accepted": true, "real_timestamp_ms": 1789177719512, "virtual_time_s": 2167.169835, "clear_result": "success"}}
{"event": "action", "seq": 91, "wall_ts_ms": 1789177719520, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0091", "position": {"x": 1159.7, "y": 0.0}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177719520, "virtual_time_s": 2280.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 92, "wall_ts_ms": 1789177719523, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0092", "position": {"x": 1159.7, "y": 0.0}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177719523, "virtual_time_s": 2286.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 93, "wall_ts_ms": 1789177719525, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0093", "position": {"x": 1159.7, "y": 0.0}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177719525, "virtual_time_s": 2292.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 94, "wall_ts_ms": 1789177719529, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0094", "position": {"x": 1159.7, "y": 0.0}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719529, "virtual_time_s": 2298.983348, "measure_result": "direction", "svd_deg": 352.36}}
{"event": "action", "seq": 95, "wall_ts_ms": 1789177719543, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0095", "position": {"x": 1159.7, "y": 0.0}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177719543, "virtual_time_s": 2304.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 96, "wall_ts_ms": 1789177719546, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0096", "position": {"x": 1159.7, "y": 0.0}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177719546, "virtual_time_s": 2310.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 97, "wall_ts_ms": 1789177719548, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0097", "position": {"x": 1159.7, "y": 0.0}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719548, "virtual_time_s": 2316.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 98, "wall_ts_ms": 1789177719550, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0098", "position": {"x": 1159.7, "y": 0.0}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719550, "virtual_time_s": 2322.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 99, "wall_ts_ms": 1789177719553, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0099", "position": {"x": 1159.7, "y": 0.0}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719553, "virtual_time_s": 2328.983348, "measure_result": "no_signal"}}
{"event": "action", "seq": 100, "wall_ts_ms": 1789177719563, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0100", "position": {"x": 1216.8639337515642, "y": -118.61861494713685}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719563, "virtual_time_s": 2361.318185, "measure_result": "direction", "svd_deg": 18.67}}
{"event": "action", "seq": 101, "wall_ts_ms": 1789177719572, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0101", "position": {"x": 1453.4828563318024, "y": -39.04678975266172}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719572, "virtual_time_s": 2416.246209, "measure_result": "direction", "svd_deg": 21.54}}
{"event": "action", "seq": 102, "wall_ts_ms": 1789177719573, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0102", "position": {"x": 1453.4828563318024, "y": -39.04678975266172}, "channel": 9}, "response": {"accepted": true, "real_timestamp_ms": 1789177719573, "virtual_time_s": 2421.246209, "clear_result": "success"}}
{"event": "action", "seq": 103, "wall_ts_ms": 1789177719580, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0103", "position": {"x": 910.6859195822817, "y": -21.98341160349429}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789177719580, "virtual_time_s": 2535.859224, "measure_result": "direction", "svd_deg": 114.4}}
{"event": "action", "seq": 104, "wall_ts_ms": 1789177719581, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0104", "position": {"x": 822.8073384995189, "y": 171.07554651864916}, "channel": 12}, "response": {"accepted": true, "real_timestamp_ms": 1789177719581, "virtual_time_s": 2583.282994, "clear_result": "success"}}
{"event": "action", "seq": 105, "wall_ts_ms": 1789177719582, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0105", "position": {"x": 822.8073384995189, "y": 171.07554651864916}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789177719582, "virtual_time_s": 2589.282994, "measure_result": "direction", "svd_deg": 201.78}}
{"event": "action", "seq": 106, "wall_ts_ms": 1789177719586, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0106", "position": {"x": 374.4278917389806, "y": -7.387837427605788}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789177719586, "virtual_time_s": 2690.801035, "measure_result": "direction", "svd_deg": 10.52}}
{"event": "action", "seq": 107, "wall_ts_ms": 1789177719587, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0107", "position": {"x": 390.52420942274483, "y": -4.68990542666626}, "channel": 13}, "response": {"accepted": true, "real_timestamp_ms": 1789177719587, "virtual_time_s": 2699.065206, "clear_result": "success"}}
{"event": "action", "seq": 108, "wall_ts_ms": 1789177719591, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0108", "position": {"x": 549.0337185951404, "y": -378.2743998369704}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789177719591, "virtual_time_s": 2786.229395, "measure_result": "direction", "svd_deg": 283.94}}
{"event": "action", "seq": 109, "wall_ts_ms": 1789177719594, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0109", "position": {"x": 690.68714474162, "y": -943.2211921417838}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789177719594, "virtual_time_s": 2907.716402, "measure_result": "direction", "svd_deg": 283.65}}
{"event": "action", "seq": 110, "wall_ts_ms": 1789177719599, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0110", "position": {"x": 697.568788325503, "y": -969.5366442663299}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789177719599, "virtual_time_s": 2918.156476, "measure_result": "direction", "svd_deg": 280.68}}
{"event": "action", "seq": 111, "wall_ts_ms": 1789177719601, "method": "POST", "path": "/clear", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0111", "position": {"x": 698.6787760077287, "y": -974.9036475070525}, "channel": 7}, "response": {"accepted": true, "real_timestamp_ms": 1789177719601, "virtual_time_s": 2924.252593, "clear_result": "success"}}
{"event": "action", "seq": 112, "wall_ts_ms": 1789177719602, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0112", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 5}, "response": {"accepted": true, "real_timestamp_ms": 1789177719602, "virtual_time_s": 2954.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 113, "wall_ts_ms": 1789177719604, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0113", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 6}, "response": {"accepted": true, "real_timestamp_ms": 1789177719604, "virtual_time_s": 2960.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 114, "wall_ts_ms": 1789177719606, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0114", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 8}, "response": {"accepted": true, "real_timestamp_ms": 1789177719606, "virtual_time_s": 2966.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 115, "wall_ts_ms": 1789177719609, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0115", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 10}, "response": {"accepted": true, "real_timestamp_ms": 1789177719608, "virtual_time_s": 2972.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 116, "wall_ts_ms": 1789177719610, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0116", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 14}, "response": {"accepted": true, "real_timestamp_ms": 1789177719610, "virtual_time_s": 2978.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 117, "wall_ts_ms": 1789177719615, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0117", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 17}, "response": {"accepted": true, "real_timestamp_ms": 1789177719615, "virtual_time_s": 2984.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 118, "wall_ts_ms": 1789177719617, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0118", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 18}, "response": {"accepted": true, "real_timestamp_ms": 1789177719617, "virtual_time_s": 2990.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 119, "wall_ts_ms": 1789177719620, "method": "POST", "path": "/measure", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0119", "position": {"x": 579.8500000000001, "y": -1004.3296607688135}, "channel": 19}, "response": {"accepted": true, "real_timestamp_ms": 1789177719620, "virtual_time_s": 2996.736194, "measure_result": "no_signal"}}
{"event": "action", "seq": 120, "wall_ts_ms": 1789177719622, "method": "POST", "path": "/exit", "status": 200, "request": {"arena_id": "default", "robot_id": "1", "request_id": "44560cd3725b-0120"}, "response": {"accepted": true, "real_timestamp_ms": 1789177719622, "virtual_time_s": 2996.736194, "exit_reason": "user_exit"}}
{"event": "session_end", "reason": "user_exit", "virtual_time_s": 2996.736194, "real_elapsed_s": 3.736418, "request_count": 120, "cleared_count": 12}

Some files were not shown because too many files have changed in this diff Show More