2
This commit is contained in:
@@ -5,15 +5,16 @@
|
||||
|
||||
与官方实现的边界:本类只承诺"协议可观测行为一致"(响应字段、
|
||||
耗时推进、幂等与拒绝语义);示向度误差分布是测试假设,不代表官方实现。
|
||||
误差场为逐点固定:同一(源频道,位置)的示向度误差由种子确定性决定,
|
||||
重复测量读数不变 [题面/官方演练实测];不同位置误差独立(白噪声假设)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from math import atan2, degrees, hypot, isfinite
|
||||
from random import Random
|
||||
from time import time
|
||||
|
||||
from ..config import ProblemConfig
|
||||
@@ -58,7 +59,7 @@ class LocalSimulator:
|
||||
self.cost = config.cost
|
||||
self.error_half_deg = (self.field.bearing_error_half_deg
|
||||
if error_half_deg is None else error_half_deg)
|
||||
self._rng = Random(error_seed)
|
||||
self.error_seed = error_seed
|
||||
self._rtt_ms = rtt_ms
|
||||
self.entered = False
|
||||
self.exited = False
|
||||
@@ -190,10 +191,21 @@ class LocalSimulator:
|
||||
if distance <= self.field.near_radius_m:
|
||||
return NEAR, None
|
||||
true_bearing = degrees(atan2(source.y - pos[1], source.x - pos[0]))
|
||||
error = self._rng.uniform(-self.error_half_deg, self.error_half_deg)
|
||||
error = self._bearing_error(channel, pos)
|
||||
svd = round(true_bearing + error, self.field.bearing_decimals) % 360.0
|
||||
return DIRECTION, svd
|
||||
|
||||
def _bearing_error(self, channel: int, pos) -> float:
|
||||
"""逐点固定误差场:同一(频道, 位置)误差恒定 [题面:同一地点误差不变]。
|
||||
|
||||
坐标按 1e-6 m 量化后与种子、频道一起哈希,映射到
|
||||
[-error_half_deg, +error_half_deg);不同位置近似独立(白噪声假设)。
|
||||
"""
|
||||
key = f"{self.error_seed}|{channel}|{round(pos[0], 6)}|{round(pos[1], 6)}"
|
||||
digest = hashlib.sha256(key.encode("utf-8")).digest()
|
||||
unit = int.from_bytes(digest[:8], "big") / 2.0 ** 64
|
||||
return (2.0 * unit - 1.0) * self.error_half_deg
|
||||
|
||||
def _source(self, channel: int):
|
||||
for source in self.sources:
|
||||
if source.channel == channel:
|
||||
|
||||
Reference in New Issue
Block a user