重构 Autocal 采集页:单一队列与控制器驱动的主按钮
选点、对准、加载与录像分散在两个面板,状态靠隐藏相位判断。现改由不依赖 Qt 的采集控制器驱动,并加入录像选项、汇总平铺副本、保持到时自动结束、会话结束回到空闲,以及无设备时的模拟采集。已运行 Autocal 非 Qt 测试并通过范围内门禁;界面测试待 Windows 复核,未做实机验收。
This commit is contained in:
@@ -290,6 +290,7 @@ def _write_multipoint_trial(
|
||||
raw_per_n: float,
|
||||
samples_per_hold: int,
|
||||
frame_start: int,
|
||||
capture_status: str | None = None,
|
||||
) -> list[dict]:
|
||||
write_csv(
|
||||
path / "reference.csv",
|
||||
@@ -302,14 +303,17 @@ def _write_multipoint_trial(
|
||||
["t_host_mono_ns", "t_host_utc_ns", "kind", "detail"],
|
||||
[],
|
||||
)
|
||||
write_json_file(path / "session.json", {
|
||||
manifest = {
|
||||
"trial_id": f"{site_id}-repeat-{repeat_index:03d}",
|
||||
"site_id": site_id,
|
||||
"status": "complete",
|
||||
"uv_px": {"u": 128, "v": 64},
|
||||
"images": {"captured": with_capture,
|
||||
"reason": "" if with_capture else "camera not attached yet"},
|
||||
})
|
||||
}
|
||||
if capture_status is not None:
|
||||
manifest["capture_status"] = capture_status
|
||||
write_json_file(path / "session.json", manifest)
|
||||
if not with_capture:
|
||||
return []
|
||||
frames: list[dict] = []
|
||||
@@ -324,8 +328,13 @@ def _write_multipoint_trial(
|
||||
)
|
||||
frames.extend(hold_frames)
|
||||
forces.extend(hold_forces)
|
||||
write_capture(path / "capture", frames, forces, fields=None if video else FRAMES_FIELDS,
|
||||
video_segments=1)
|
||||
if not video:
|
||||
# A data-only recording: the rows exist, no frame was written to a video.
|
||||
frames = [
|
||||
{**row, "segment": 0, "segment_frame": 0, "in_video": 0} for row in frames
|
||||
]
|
||||
write_capture(path / "capture", frames, forces, fields=FRAMES_FIELDS,
|
||||
video_segments=1 if video else 0)
|
||||
return []
|
||||
|
||||
|
||||
@@ -343,8 +352,17 @@ def multipoint_session(
|
||||
simulate: bool = False,
|
||||
trial_status: str = "complete",
|
||||
extra_holds: list[Hold] | None = None,
|
||||
recording_block: dict | None = None,
|
||||
capture_status: str | None = None,
|
||||
) -> Path:
|
||||
"""A complete multi-point session directory through the review contract."""
|
||||
"""A complete multi-point session directory through the review contract.
|
||||
|
||||
``video=False`` writes a data-only recording: frame rows exist with
|
||||
``in_video=0`` and no MP4 is created. ``recording_block`` writes the root
|
||||
manifest's ``recording`` block; ``None`` keeps the fixture shaped like a
|
||||
session recorded before that block existed. ``capture_status`` puts the
|
||||
lifecycle into the trial records, as the campaign does.
|
||||
"""
|
||||
session_id = f"finger-SN1_{root.name}_test0001"
|
||||
trials: list[dict] = []
|
||||
completion: list[dict] = []
|
||||
@@ -379,21 +397,25 @@ def multipoint_session(
|
||||
raw_per_n=raw_per_n,
|
||||
samples_per_hold=samples_per_hold,
|
||||
frame_start=1,
|
||||
capture_status=capture_status,
|
||||
)
|
||||
trials.append({
|
||||
trial_record = {
|
||||
"trial_id": f"{site_id}-repeat-{repeat:03d}",
|
||||
"site_id": site_id,
|
||||
"repeat_index": repeat,
|
||||
"directory": directory,
|
||||
"status": trial_status,
|
||||
"reason": "" if trial_status == "complete" else "stopped by the operator",
|
||||
})
|
||||
}
|
||||
if capture_status is not None:
|
||||
trial_record["capture_status"] = capture_status
|
||||
trials.append(trial_record)
|
||||
if trial_status == "complete":
|
||||
complete += 1
|
||||
completion.append({"site_id": site_id, "repeats_planned": repeats,
|
||||
"repeats_complete": complete,
|
||||
"complete": complete >= repeats})
|
||||
write_json_file(root / "session.json", {
|
||||
manifest = {
|
||||
"format_version": "autocal-multipoint-1.0",
|
||||
"session_id": session_id,
|
||||
"sensor_model": "finger",
|
||||
@@ -411,7 +433,10 @@ def multipoint_session(
|
||||
"[t_start_host_mono_ns, t_end_host_mono_ns). Rows are not paired."},
|
||||
"platform_motion": False,
|
||||
"automatic_force_control": False,
|
||||
})
|
||||
}
|
||||
if recording_block is not None:
|
||||
manifest["recording"] = recording_block
|
||||
write_json_file(root / "session.json", manifest)
|
||||
return root
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user