删除深度重算引擎;修好回放视频每帧重开文件导致的无法播放,运输控制改到状态轨主按钮 - What: 1) 彻底删除深度重算引擎:shared/.../record/depth.py(DepthRecomputer/DepthResult)与 depth_backends.py(BoxReplay/FingerReplay)、其专属测试 test_depth_replay.py,record/__init__ 不再导出,playback.py::replay_warnings 不再报 depth_recomputed;apps/studio/replay.py 由 515 行瘦身为只做读盘+游标+视频帧+提示,回放视图的 2D 面板只提供「原始图像」;session.json 的 depth.replay 由 recompute 改为 none;删除 31 个只剩深度使用的文案键(depth_*/warn_state_*/warn_reset_*),warn_config_changed 与 warn_sdk_changed 改为描述"由视频重算";ui_check 深度段、studio 两个深度用例、test_playback 三例、drive_shared 的 test_depth_replay 与 reproduce.py 的深度段一并清理(shared 套件 150→134 项)。2) 无法播放的根因是 RecordingReader.video_frame_at 每帧都 cv2.VideoCapture 重开并 seek:小片段已 ~10 ms/帧,1080p H.264 每次 seek 需从关键帧解码(上百 ms),而播放每 33 ms 要一帧且全在 UI 线程上,视频因此看着不动;改为按分段缓存解码器、顺序帧用 read() 步进(实测 10 ms → 0.5 ms/帧)、跳转才 seek,新增 RecordingReader.close() 释放。运输控制按用户建议上移到状态轨主按钮:toolbar.set_run_role("playback") 使回放视图的主按钮变成「▶ 回放」/「⏸ 暂停」(实时视图仍是「▶ 运行」),点按以 1× 推进游标(墙钟计时,漏拍不变慢)、到末尾自动停,拖动游标/框选/滚轮/拖总览条经 ForcePlotsPanel.timeline_taken_over 自动暂停,空格键同效;曲线表头不再放第二个播放按钮;按钮样式在回放角色下不再套用"停止"的红色语义。 - Why: 用户要求先清掉深度重算引擎、并反馈"现在无法播放视频",建议把上方播放按钮在历史回放形式下改为回放。 - Verification: ui_check.py 554 项 0 失败(新增 seek<250ms/步进<60ms 的解码预算、回放按钮文字随播放/暂停切换、手动拖游标即暂停、切回实时视图按钮恢复运行、按深度视图已移除);test_ui_smoke.py 71 项 0 失败;drive_shared.py 134 项 0 失败(深度引擎用例随代码删除);locale_studio.py 262 键齐全、zh==en;reproduce.py 退出 0;.repro/probe_play.py 实测按「回放」后 0.75 s 内游标推进 0.689 s、面板 12/12 帧都在更新;两张复核图(回放视图的「▶ 回放」、实时视图的「▶ 运行」)。 - Not in this change: 录制文件格式与 CSV 列序不变(raw_*.mp4 与 forces.csv 继续一起写);「由视频重算」复核模式保留(它复用实时管线,是有状态、只能顺序前进的一遍)。
This commit is contained in:
@@ -24,7 +24,6 @@ from orisys_app_shared.record import (
|
||||
RecordingReader,
|
||||
list_recordings,
|
||||
)
|
||||
from orisys_app_shared.record.depth import DepthRecomputer
|
||||
|
||||
SCRATCH = Path(__file__).resolve().parent / "_scratch_playback"
|
||||
|
||||
@@ -219,60 +218,12 @@ def test_depth_policy_says_recompute_and_warns_about_drift(recording):
|
||||
# The config file on disk no longer matches what was recorded.
|
||||
codes = reader.replay_warnings(sdk_version="0.5.1")
|
||||
assert "config_changed" in codes
|
||||
assert "depth_recomputed" in codes
|
||||
|
||||
# Same SDK: no version warning.
|
||||
assert "sdk_changed" not in codes
|
||||
assert "sdk_changed" in reader.replay_warnings(sdk_version="9.9.9")
|
||||
|
||||
|
||||
def test_depth_recompute_preflight_states_why_it_cannot_run(recording):
|
||||
reader = RecordingReader(recording)
|
||||
recomputer = DepthRecomputer(reader)
|
||||
try:
|
||||
problem = recomputer.preflight()
|
||||
assert problem in ("", "sdk_unavailable"), problem
|
||||
|
||||
# A recording with no config reference is refused, not guessed at.
|
||||
missing = RecordingReader(recording)
|
||||
missing._info = None # noqa: SLF001 - force a re-read below
|
||||
empty = SCRATCH / "empty"
|
||||
empty.mkdir(exist_ok=True)
|
||||
(empty / "forces.csv").write_text(
|
||||
",".join(("session_id", "frame_id", "t_rel_s", "FN_raw", "FX_raw", "FY_raw",
|
||||
"FN_N", "FX_N", "FY_N", "valid", "calibration_id")) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(empty / "session.json").write_text(json.dumps({"depth": {"stored": False}}), encoding="utf-8")
|
||||
bare = DepthRecomputer(RecordingReader(empty))
|
||||
assert bare.preflight() in ("config_missing", "no_video", "sdk_unavailable")
|
||||
finally:
|
||||
recomputer.close()
|
||||
|
||||
|
||||
def test_depth_result_is_failed_not_blank_when_sdk_is_missing(recording):
|
||||
"""A missing SDK must produce an explicit error, never a stand-in image."""
|
||||
saved = sys.modules.get("orisys")
|
||||
blocker = types.ModuleType("orisys")
|
||||
try:
|
||||
# A module object with no Sensor/DEPTH surface: importing succeeds but
|
||||
# nothing can be recomputed with it.
|
||||
sys.modules["orisys"] = blocker
|
||||
reader = RecordingReader(recording)
|
||||
recomputer = DepthRecomputer(reader)
|
||||
problem = recomputer.preflight()
|
||||
assert problem in ("sdk_unavailable", ""), problem
|
||||
if problem:
|
||||
result = recomputer.depth_at(1.0)
|
||||
assert not result.ok
|
||||
assert result.depth is None
|
||||
assert result.error
|
||||
finally:
|
||||
if saved is None:
|
||||
sys.modules.pop("orisys", None)
|
||||
else:
|
||||
sys.modules["orisys"] = saved
|
||||
|
||||
|
||||
def test_list_recordings_finds_directories_newest_first(recording):
|
||||
second = SCRATCH / "zzz_later"
|
||||
|
||||
Reference in New Issue
Block a user