回放与实时统一为一套界面;修复 30 fps 设备被以 16.7 fps 消费的计时器缺陷 - What: 1) 删除 ui/replay_bar.py(进度条、录制目录选择、重算深度按钮、提示行)与回放条的全部接线:历史回放现在与实时监测同布局(分割比例同为 0,360,1080,0)、同一条状态轨、同一套曲线手势,唯一差别是来源槽——实时是摄像机,回放是「选择录制视频…」(toolbar.btn_replay_video,与文件菜单「打开视频…」同一条 _load_replay_video 路径:视频所在目录即录制目录,曲线自动配对同目录 forces.csv)。时间轴改为曲线游标本身:表头新增播放/暂停图标按钮(icons.play/pause,空格键同效)以 1× 推进(按墙钟计时,漏拍不变慢),到末尾自动停;拖动游标、框选、滚轮平移或拖总览条一律自动暂停(ForcePlotsPanel.pause_playback)。回放的降采样/跨版本提示移入来源摘要 tooltip,打开录制时另发一条 6 秒通知。修复视频文件名残留在实时视图的问题:_refresh_status_rail 只在 _view_preset == "replay" 时写视频名。2) 录制格式不变:raw_*.mp4 与 forces.csv/frames.csv/session.json 继续一起写。按「两者都要」新增 视图 → 由视频重算力值(act_recompute):默认曲线读录制的 CSV,打开后把录制视频重新跑一遍视觉管线(进 SessionStore、2D 面板交给管线绘制、只能顺序前进,播放按钮即开始/暂停,关闭即挂回 CSV),启动路径唯一(set_playing → _on_chart_play_toggled → _start_run),并让文件源的时间轴改为视频自身时间(mono_t = 帧号 × 1/fps),否则重算结果会落在与 CSV 不同的横轴上。回放 2D 面板不再提供深度视图(REPLAY_VIEW_MODES=("recorded",)),离线深度重算引擎保留但无界面入口。3) 采集只有 16.67 fps 的根因是上一轮引入的等待:Windows 默认计时器分辨率 15.6 ms,time.sleep(0.002) 实测睡 15.5 ms,重复帧等两拍即跨过 30 fps 的 33 ms 周期,30 fps 设备被以 ~16.7 fps 消费并隔帧丢弃(配置本身正确:mini/sensor.json 写 camera.fps=30;离线实测整套管线 15.2 ms/帧≈66 fps,余量充足)。新增 _high_resolution_timer() 在会话期间把分辨率提到 1 ms(结束还原),并把重复帧等待改为 min(距下一帧时间, 半个周期)、到期只 sleep(0)。 - Why: 用户评审 3 点——回放界面与实时不一致且拖拽条效果一般、不想为回放录制深度信息、想同时保留视频与 CSV 记录、以及采集帧率只有 16.67 fps(应为 30)。 - Verification: ui_check.py 562 项 0 失败(新增两视图同布局/无 bar、来源槽随视图切换且无残留、播放暂停与手动手势暂停、重算模式切换与视频源、回放提示在 tooltip);test_ui_smoke.py 73 项 0 失败(新增视图统一、传输控制、重算模式);drive_shared.py 150 项 0 失败(新增 shared/tests/test_worker_frame_rate.py::test_a_file_source_runs_on_the_video_s_own_timeline,并把 30 fps 用例改成必须落在 27–31.5 fps;同文件实测无 1 ms 计时器 21.6 fps、有则 30.0 fps,同一帧返回 3 次时 11317:39);locale_studio.py 266 键齐全、zh==en;reproduce.py 退出 0;ui_snapshot.py 三张复核图(统一后的回放、实时、选区中英)。 - Not in this change: 录制文件格式与 CSV 列序不变;离线深度重算引擎(ReplayController.request_depth / DepthRecomputer)保留并有独立测试,但界面已无入口,可下一步删除;重算模式用有损 mp4,数值与原 CSV 会有差异(这正是它要显式呈现的)。
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
"settings": "Settings area",
|
||||
"plot_settings": "Plot settings…",
|
||||
"rotate_arrows": "Rotate arrows 90°",
|
||||
"recompute": "Recompute forces from the video",
|
||||
"recompute_tip": "Off: the charts read the recorded forces.csv. On: re-run the vision pipeline over the recorded video (an algorithm check, forward-only).",
|
||||
"run": "Run / Stop",
|
||||
"stop": "Cancel acquisition",
|
||||
"preview": "Preview / Stop preview",
|
||||
@@ -61,7 +63,9 @@
|
||||
"search_cameras": "Search",
|
||||
"cam_id": "Camera",
|
||||
"use_camera": "Use camera",
|
||||
"use_camera_tip": "Go back to acquiring from a camera (a video file is in use)",
|
||||
"use_camera_tip": "Go back to acquiring from a camera (the data source is a video file)",
|
||||
"choose_video": "Choose a recorded video…",
|
||||
"choose_video_tip": "Open a recorded video: the 2D panel plays it and the charts read the forces.csv beside it",
|
||||
"preview": "Preview",
|
||||
"preview_stop": "Stop preview",
|
||||
"run": "Run",
|
||||
@@ -110,8 +114,8 @@
|
||||
"view_depth": "Depth map",
|
||||
"view_recorded": "Recorded image",
|
||||
"view_mode_tip": "Image display mode while running",
|
||||
"replay_pipeline": "Recorded video → depth recomputed",
|
||||
"replay_pipeline_tip": "Replay shows the recorded raw camera image; the depth map is recomputed offline from that video and the config, with no live arrow overlay",
|
||||
"replay_pipeline": "Recorded video (raw camera image)",
|
||||
"replay_pipeline_tip": "Replay shows the recorded raw camera image with no live arrow overlay; to check the algorithm, use View → Recompute forces from the video",
|
||||
"replay_empty": "No recording open\nPress “Open recording…” below",
|
||||
"arrow_empty": "No image yet\nPick a video or camera, then press Run",
|
||||
"arrow_empty_tip": "The deformation arrow image appears here while running or previewing",
|
||||
@@ -138,6 +142,10 @@
|
||||
"fx_name": "Shear X",
|
||||
"fy_name": "Shear Y",
|
||||
"window_readout": "{start} – {end} s / {total} s total",
|
||||
"play": "Play",
|
||||
"play_tip": "Play this recording from the cursor at 1× (space bar); dragging the cursor pauses",
|
||||
"pause": "Pause",
|
||||
"pause_tip": "Pause playback (dragging the cursor, box zoom or the wheel also pauses)",
|
||||
"window_tip": "Drag the highlighted region to move the window: this strip is the timeline of the whole session",
|
||||
"no_data": "—",
|
||||
"mode_follow": "Following live",
|
||||
@@ -165,22 +173,13 @@
|
||||
},
|
||||
"playback": {
|
||||
"title": "Replay recording",
|
||||
"open": "Open recording…",
|
||||
"open_tip": "Pick a recording directory under outputs/recordings (video + curves + metadata)",
|
||||
"scrub_tip": "Drag the progress bar to move the playhead: video, depth and the chart cursor follow",
|
||||
"loaded_short": "{name} · {frames} frames / {duration} s",
|
||||
"open": "Open a recorded video…",
|
||||
"video_filter": "Recorded video (*.mp4 *.avi *.mov *.mkv);;All files (*)",
|
||||
"no_video": "This recording has no usable video segment",
|
||||
"open_failed": "Could not open that recording: {error}",
|
||||
"none_found": "No recording found under outputs/recordings",
|
||||
"loaded": "{name} — {frames} frames / {duration} s",
|
||||
"empty": "Pick a recording directory to start replay",
|
||||
"position": "{position} / {duration} s",
|
||||
"show_newton": "Show newtons",
|
||||
"show_raw": "Show raw",
|
||||
"recompute_depth": "Recompute depth",
|
||||
"recompute_depth_tip": "Depth is not stored with a recording; recompute this frame offline from the video and the config",
|
||||
"frame_dropped": "This frame never reached the video (the record queue overflowed)",
|
||||
"frame_unreadable": "This frame could not be decoded from the video",
|
||||
"depth_hint": "Depth is not stored: press Recompute depth to rebuild it from the video and the config",
|
||||
"depth_running": "Recomputing depth… (on a worker thread)",
|
||||
"depth_busy": "The previous recomputation is still running",
|
||||
"depth_empty": "No depth data for this frame",
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
"settings": "设置区",
|
||||
"plot_settings": "绘图设置…",
|
||||
"rotate_arrows": "旋转箭头图 90°",
|
||||
"recompute": "由视频重算力值",
|
||||
"recompute_tip": "关闭:曲线读录制的 forces.csv(当时测得的值)。打开:把录制的视频重新跑一遍视觉管线(算法复核,只能顺序前进)。",
|
||||
"run": "运行 / 停止",
|
||||
"stop": "取消采集",
|
||||
"preview": "预览 / 停止预览",
|
||||
@@ -61,7 +63,9 @@
|
||||
"search_cameras": "搜索",
|
||||
"cam_id": "摄像机",
|
||||
"use_camera": "使用摄像机",
|
||||
"use_camera_tip": "回到摄像机采集(当前正在用视频文件采集)",
|
||||
"use_camera_tip": "回到摄像机采集(当前的数据源是视频文件)",
|
||||
"choose_video": "选择录制视频…",
|
||||
"choose_video_tip": "打开一段录制的视频:2D 面板放视频,曲线读同目录的 forces.csv(原始记录值)",
|
||||
"preview": "预览",
|
||||
"preview_stop": "停止预览",
|
||||
"run": "运行",
|
||||
@@ -110,8 +114,8 @@
|
||||
"view_depth": "深度图",
|
||||
"view_recorded": "原始图像",
|
||||
"view_mode_tip": "运行时的图像显示模式",
|
||||
"replay_pipeline": "录制视频 → 深度重算",
|
||||
"replay_pipeline_tip": "回放显示的是录制下来的原始相机图像;深度图由录制视频与配置离线重算,不含实时箭头叠加",
|
||||
"replay_pipeline": "录制视频(原始相机图像)",
|
||||
"replay_pipeline_tip": "回放显示的是录制下来的原始相机图像,不含实时箭头叠加;要复核算法请用「视图 → 由视频重算力值」",
|
||||
"replay_empty": "尚未打开录制\n点击下方「打开录制…」",
|
||||
"arrow_empty": "尚未采集图像\n请选择视频或摄像机后点击「运行」",
|
||||
"arrow_empty_tip": "运行或预览后在此显示形变箭头图",
|
||||
@@ -138,6 +142,10 @@
|
||||
"fx_name": "切向力 X",
|
||||
"fy_name": "切向力 Y",
|
||||
"window_readout": "{start} – {end} s / 全程 {total} s",
|
||||
"play": "播放",
|
||||
"play_tip": "从游标处按 1× 播放这段录制(空格键);拖动游标即暂停",
|
||||
"pause": "暂停",
|
||||
"pause_tip": "暂停播放(拖动游标、框选或滚轮也会暂停)",
|
||||
"window_tip": "拖动高亮区域即可移动视窗;这是整段会话的时间轴",
|
||||
"no_data": "—",
|
||||
"mode_follow": "跟随实时",
|
||||
@@ -165,22 +173,13 @@
|
||||
},
|
||||
"playback": {
|
||||
"title": "录制回放",
|
||||
"open": "打开录制…",
|
||||
"open_tip": "选择 outputs/recordings 下的一个录制目录(视频 + 曲线 + 元数据)",
|
||||
"scrub_tip": "拖动进度条移动回放位置:视频、深度与曲线游标同步",
|
||||
"loaded_short": "{name} · {frames} 帧 / {duration} s",
|
||||
"open": "打开录制视频…",
|
||||
"video_filter": "录制的视频 (*.mp4 *.avi *.mov *.mkv);;所有文件 (*)",
|
||||
"no_video": "这段录制没有可用的视频分段",
|
||||
"open_failed": "无法打开该录制: {error}",
|
||||
"none_found": "outputs/recordings 下没有找到录制",
|
||||
"loaded": "{name} — {frames} 帧 / {duration} s",
|
||||
"empty": "选择一个录制目录开始回放",
|
||||
"position": "{position} / {duration} s",
|
||||
"show_newton": "显示牛顿值",
|
||||
"show_raw": "显示原始值",
|
||||
"recompute_depth": "重算深度",
|
||||
"recompute_depth_tip": "深度未随录制保存,按录像与配置离线重算当前帧",
|
||||
"frame_dropped": "该帧未被写入视频(记录队列曾溢出)",
|
||||
"frame_unreadable": "该帧无法从视频中解码",
|
||||
"depth_hint": "深度未存储:点击「重算深度」按原视频与配置离线重算",
|
||||
"depth_running": "正在重算深度…(在后台线程)",
|
||||
"depth_busy": "上一次重算尚未完成",
|
||||
"depth_empty": "该帧没有深度数据",
|
||||
|
||||
Reference in New Issue
Block a user