优化部分多点标定功能

This commit is contained in:
2026-10-16 18:58:31 +08:00
parent a3aeca1d12
commit 54e0b8006a
5 changed files with 288 additions and 11 deletions
+113 -1
View File
@@ -256,13 +256,17 @@ def test_stable_means_are_the_three_components_of_the_latter_half(tmp_path):
with (repeat / "reference.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=[
"step_index", "branch", "target_load_n", "t_start_host_mono_ns",
"t_end_host_mono_ns", "hold_complete",
"t_end_host_mono_ns", "hold_complete", "reference_source",
])
writer.writeheader()
writer.writerow({
"step_index": 1, "branch": "load", "target_load_n": 5,
"t_start_host_mono_ns": start, "t_end_host_mono_ns": end, "hold_complete": 1,
"reference_source": "weight",
})
(repeat / "session.json").write_text(
json.dumps({"uv_px": {"u": 128, "v": 64}}), encoding="utf-8",
)
with (repeat / "capture" / "frames.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=["frame_id", "t_host_mono_ns", "dropped"])
writer.writeheader()
@@ -296,6 +300,9 @@ def test_stable_means_are_the_three_components_of_the_latter_half(tmp_path):
assert float(rows[0]["FN_mean"]) == pytest.approx(3.0)
assert float(rows[0]["FX_mean"]) == pytest.approx(0.6)
assert float(rows[0]["FY_mean"]) == pytest.approx(-0.4)
assert rows[0]["U"] == "128"
assert rows[0]["V"] == "64"
assert rows[0]["负载类型"] == "砝码"
assert "Fmag" not in rows[0]
@@ -338,3 +345,108 @@ def test_an_outlier_in_the_stable_half_is_left_out_of_its_own_mean(tmp_path):
assert float(row["FN_mean"]) == pytest.approx(3.0)
assert float(row["FX_mean"]) == pytest.approx(0.575)
assert float(row["FY_mean"]) == pytest.approx(-0.375)
def test_a_reconnected_camera_keeps_each_hold_on_its_own_frames(tmp_path):
"""A camera that starts again reuses frame numbers. Each hold keeps its own rows."""
from orisys_autocal.multipoint import stable_component_rows
repeat = tmp_path / "repeat-001"
(repeat / "capture").mkdir(parents=True)
first = (1_000, 1_100)
second = (5_000, 5_100)
with (repeat / "reference.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=[
"step_index", "branch", "target_load_n", "t_start_host_mono_ns",
"t_end_host_mono_ns", "hold_complete", "reference_source",
])
writer.writeheader()
writer.writerow({
"step_index": 2, "branch": "load", "target_load_n": 3,
"t_start_host_mono_ns": first[0], "t_end_host_mono_ns": first[1],
"hold_complete": 1, "reference_source": "weight",
})
writer.writerow({
"step_index": 3, "branch": "unload", "target_load_n": 2,
"t_start_host_mono_ns": second[0], "t_end_host_mono_ns": second[1],
"hold_complete": 1, "reference_source": "weight",
})
with (repeat / "capture" / "frames.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=["frame_id", "t_host_mono_ns", "dropped"])
writer.writeheader()
for frame_id, stamp in ((1, 1060), (2, 1080), (1, 5060), (2, 5080)):
writer.writerow({"frame_id": frame_id, "t_host_mono_ns": stamp, "dropped": 0})
with (repeat / "capture" / "forces.csv").open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=[
"frame_id", "valid", "FN_output_N", "FX_output_N", "FY_output_N",
])
writer.writeheader()
for frame_id, fn in ((1, 10), (2, 30), (1, 4), (2, 6)):
writer.writerow({
"frame_id": frame_id, "valid": 1,
"FN_output_N": fn, "FX_output_N": 0, "FY_output_N": 0,
})
rows = stable_component_rows(repeat, site_id="P1", repeat_index=1)
assert float(rows[0]["FN_mean"]) == pytest.approx(20.0)
assert rows[0]["branch"] == "load"
assert float(rows[1]["FN_mean"]) == pytest.approx(5.0)
assert rows[1]["branch"] == "unload"
def _hold_for(campaign: Campaign, force: float) -> None:
campaign.confirm_reference(force)
campaign.complete_hold(now_ns=campaign._hold_started_ns + int(campaign._hold_s * 1e9))
def test_a_finished_step_can_be_measured_again_without_skipping_ahead(tmp_path):
campaign = Campaign()
campaign.add_site("A", 0, 0, 1, [2, 3], 20, 1, max_force_n=10)
campaign.start(
tmp_path, sensor_model="finger", sensor_sn="SN1",
coordinate_frame="sensor", max_force_n=10, simulate=True,
)
_hold_for(campaign, 0)
_hold_for(campaign, 2)
assert campaign.progress()["target_n"] == 3
assert campaign.can_remeasure_step()
campaign.remeasure_step()
assert campaign.phase == "load"
assert campaign.progress()["branch"] == "load"
assert campaign.progress()["target_n"] == 2
assert not campaign.can_remeasure_step()
saved = list(csv.DictReader(
(campaign.directory / "sites" / "A" / "repeat-001" / "reference.csv").open(encoding="utf-8")
))
assert saved[-1]["target_load_n"] == "2.0"
assert saved[-1]["hold_complete"] == "0"
_hold_for(campaign, 2)
saved = list(csv.DictReader(
(campaign.directory / "sites" / "A" / "repeat-001" / "reference.csv").open(encoding="utf-8")
))
redone = [row for row in saved if row["target_load_n"] == "2.0"]
assert [row["hold_complete"] for row in redone] == ["0", "1"]
assert campaign.progress()["target_n"] == 3
def test_a_hold_that_drops_midway_stays_on_the_same_step(tmp_path):
campaign = Campaign()
campaign.add_site("A", 0, 0, 1, [2, 3], 20, 1, max_force_n=10)
campaign.start(
tmp_path, sensor_model="finger", sensor_sn="SN1",
coordinate_frame="sensor", max_force_n=10, simulate=True,
)
_hold_for(campaign, 0)
campaign.confirm_reference(2)
assert campaign.phase == "hold"
campaign.remeasure_step()
assert campaign.phase == "load"
assert campaign.progress()["target_n"] == 2
saved = list(csv.DictReader(
(campaign.directory / "sites" / "A" / "repeat-001" / "reference.csv").open(encoding="utf-8")
))
assert saved[-1]["hold_complete"] == "0"
assert saved[-1]["target_load_n"] == "2.0"