明确 Autocal 录制按钮及中止结果

区分连续录制和到档标记,并验证中止重试的目录数量。相关测试与代码检查通过。
This commit is contained in:
ykcheungab
2026-10-11 16:44:43 +08:00
parent 69c1322616
commit 7828bc1fe9
4 changed files with 71 additions and 19 deletions
+14 -8
View File
@@ -271,17 +271,22 @@
"uv": "U / V (px)",
"position": "Mesh position",
"levels": "Load levels (N)",
"hold": "Suggested hold",
"reference": "Actual reference (N)",
"start": "Start trial recording",
"confirm": "Confirm current level",
"finish": "Finish and save",
"abort": "Abort and keep data",
"hold": "Planned hold",
"hold_tip": "The planned hold time is saved; levels and recording do not advance automatically.",
"reference": "Manual reference force (N)",
"start": "Record this site",
"start_tip": "Create one trial folder for this site and continuously record images and sensor output. This does not move the platform. One load-unload cycle uses this folder.",
"confirm": "Mark load reached",
"confirm_tip": "After reaching the target and entering the manual reference force, mark this level's start and begin its hold timer. Images are already recording.",
"finish": "Stop and complete",
"finish_tip": "After all levels are marked, stop recording, flush the files, and check this trial.",
"abort": "Abort this recording",
"abort_tip": "Stop recording, keep this folder, and mark it incomplete. Starting again creates a new folder; it does not resume this one.",
"load": "Load",
"unload": "Unload",
"next_step": "Next: {branch} to {load:g} N",
"before_start": "Start trial recording first",
"ready_to_finish": "All levels confirmed; finish and save",
"before_start": "Select a site and start the input, then begin recording",
"ready_to_finish": "All levels marked; recording can be stopped",
"no_step": "No step pending",
"progress": "Progress {done}/{total} · {status}",
"held": " · Current level held {seconds:.1f} s",
@@ -293,6 +298,7 @@
"complete": "Complete",
"incomplete": "Incomplete",
"result": "{status}: {path}",
"incomplete_result": "This recording is incomplete; data written so far is at: {path}",
"error": "Action failed: {detail}",
"invalid_site": "Select a valid UV site first",
"start_input": "Start camera or video input first",
+15 -9
View File
@@ -271,28 +271,34 @@
"uv": "U / V (px)",
"position": "网格坐标",
"levels": "加载档位 (N)",
"hold": "建议保持",
"reference": "实际参考力 (N)",
"start": "开始试验并录制",
"confirm": "确认当前档位",
"finish": "完成并保存",
"abort": "中止并保留",
"hold": "计划保持",
"hold_tip": "仅保存计划保持时间;不会自动切换档位或结束录制。",
"reference": "人工参考力 (N)",
"start": "开始本测点录制",
"start_tip": "为当前测点新建试验目录,持续录制图像与传感器输出;不会移动平台。一次加载—卸载循环共用此目录。",
"confirm": "标记到档时刻",
"confirm_tip": "达到目标载荷并填写人工参考力后点击;记录本档起点并开始保持计时。图像此前已开始持续录制。",
"finish": "结束录制并完成",
"finish_tip": "全部档位标记后停止录制、完成写盘并检查本次试验。",
"abort": "中止本次录制",
"abort_tip": "停止录制并保留当前目录,标记为未完成;再次开始会创建新目录,不会续录。",
"load": "加载",
"unload": "卸载",
"next_step": "下一档:{branch}至 {load:g} N",
"before_start": "请先开始试验并录制",
"ready_to_finish": "全部档位已确认,请完成并保存",
"before_start": "先选测点并启动输入,再开始录制",
"ready_to_finish": "全部档位已标记,可结束录制",
"no_step": "无待确认档位",
"progress": "进度 {done}/{total} · {status}",
"held": " · 当前档已保持 {seconds:.1f} s",
"source_state": "输入:{status} · 帧 {frame} · 采集丢帧 {dropped}",
"replay_note": "视频重放仅用于调试;本次人工参考力不能与原实验时间同步。",
"idle": "未开始",
"recording": "记录中",
"recording": "录制中",
"closing": "正在写盘",
"complete": "已完成",
"incomplete": "未完成",
"result": "{status}:{path}",
"incomplete_result": "本次录制未完成;已写入的数据在:{path}",
"error": "操作失败:{detail}",
"invalid_site": "请先选择有效的 UV 测点",
"start_input": "请先启动相机或视频输入",
@@ -267,8 +267,13 @@ class CalibrationPanel(QWidget):
previous = self.trial.status
current = self.trial.poll()
if current != previous and current in {"complete", "incomplete"}:
result_key = (
"calibration.incomplete_result"
if current == "incomplete"
else "calibration.result"
)
self.result_label.setText(
t("calibration.result").format(
t(result_key).format(
status=t(f"calibration.{current}"), path=self.trial.directory
)
+ (
@@ -355,9 +360,14 @@ class CalibrationPanel(QWidget):
self.position_label.setText(t("calibration.position"))
self.levels_label.setText(t("calibration.levels"))
self.hold_label.setText(t("calibration.hold"))
self.hold.setToolTip(t("calibration.hold_tip"))
self.reference_label.setText(t("calibration.reference"))
self.start_button.setText(t("calibration.start"))
self.start_button.setToolTip(t("calibration.start_tip"))
self.confirm_button.setText(t("calibration.confirm"))
self.confirm_button.setToolTip(t("calibration.confirm_tip"))
self.finish_button.setText(t("calibration.finish"))
self.finish_button.setToolTip(t("calibration.finish_tip"))
self.abort_button.setText(t("calibration.abort"))
self.abort_button.setToolTip(t("calibration.abort_tip"))
self._sync()
+31 -1
View File
@@ -163,6 +163,29 @@ def test_manual_trial_records_video_stamps_and_load_unload_events(tmp_dir):
assert session["sensor_model"] == "Finger D40"
assert session["reference_file"] == "reference.csv"
assert session["site"]["mesh_sha256"]
assert len(list(tmp_dir.glob("*/session.json"))) == 1
second_directory = trial.start(
root=tmp_dir,
site=site,
levels=[5, 10],
hold_s=20,
sensor_model="Finger D40",
sensor_sn="F-001",
bundle_path=str(bundle),
source={"kind": "camera", "value": 0},
config_ref=str(config),
fps=30,
)
worker.emit()
trial.confirm(5)
trial.finish(aborted=True, reason="operator aborted")
trial.recorder.stop(wait=True)
assert trial.poll() == "incomplete"
assert len(list(tmp_dir.glob("*/session.json"))) == 2
assert second_directory != directory
with (second_directory / "reference.csv").open(encoding="utf-8", newline="") as handle:
assert [row["F_ref_normal_N"] for row in csv.DictReader(handle)] == ["5.0"]
def test_calibration_page_keeps_precise_uv_site_when_switching_to_live_view(
@@ -186,7 +209,14 @@ def test_calibration_page_keeps_precise_uv_site_when_switching_to_live_view(
uv_max=(1, 1),
)
panel = window.calibration_panel
assert panel.start_button.text() == t("calibration.start")
for key, button in (
("start", panel.start_button),
("confirm", panel.confirm_button),
("finish", panel.finish_button),
("abort", panel.abort_button),
):
assert button.text() == t(f"calibration.{key}")
assert button.toolTip() == t(f"calibration.{key}_tip")
assert panel.target_label.text() == t("calibration.before_start")
panel.set_flat(flat, "bundle")
panel._picked(2, 1)