62 lines
3.3 KiB
Python
62 lines
3.3 KiB
Python
from dataclasses import replace
|
|
import pytest
|
|
|
|
from linkerhand_calibration.core.domain.profile import ReferenceWaypoint
|
|
from linkerhand_calibration.profiles import load_bundled_hand_profile, dump_hand_profile, load_hand_profile
|
|
from linkerhand_calibration.runtime.execution import SessionExecution
|
|
from linkerhand_calibration.runtime.session import CalibrationPhase as Phase
|
|
from linkerhand_calibration.runtime.resume import select_installation_evidence, ResumeVerifier
|
|
from test_resume_v2 import _fingerprint
|
|
|
|
|
|
def test_reference_waypoint_cannot_drive_disabled_channel():
|
|
from linkerhand_calibration.core.domain.profile import validate_profile
|
|
profile = load_bundled_hand_profile("g20_right_19")
|
|
channel = next(iter(profile.command.disabled_indices))
|
|
pose = list(profile.command.baseline_values)
|
|
pose[channel] -= 1
|
|
view = profile.vision.views[0]
|
|
tag = next(tag for tag in view.tags if not tag.fixed_reference)
|
|
waypoint = ReferenceWaypoint("show", tuple(pose), {view.name: (tag.tag_id,)})
|
|
profile = replace(profile, motion=replace(profile.motion, resume_verification_waypoints=(waypoint,)))
|
|
with pytest.raises(ValueError, match="disabled channels"):
|
|
validate_profile(profile)
|
|
|
|
|
|
def test_reference_waypoints_share_executor_and_return_before_resume(tmp_path):
|
|
profile = load_bundled_hand_profile("l6_right_8")
|
|
# Legacy v2 sessions retain their all-at-start verification waypoint API.
|
|
profile = replace(profile, artifacts=replace(profile.artifacts, output_schema_version=2))
|
|
pose = (230., 255., 255., 255., 255., 255.)
|
|
waypoint = ReferenceWaypoint("show_tip", pose, {"front": (2,)})
|
|
profile = replace(profile, motion=replace(profile.motion, resume_verification_waypoints=(waypoint,)))
|
|
path = tmp_path/"virtual.yaml"
|
|
path.write_text(dump_hand_profile(profile))
|
|
assert load_hand_profile(path) == profile
|
|
engine = SessionExecution(profile)
|
|
engine.session.device_ready()
|
|
engine.session.start(resume_requested=True)
|
|
current = profile.command.baseline_values
|
|
while engine.session.phase == Phase.BASELINE:
|
|
motion = engine.motion(current); current = motion.target; engine.motion_complete()
|
|
engine.session.reference_locked()
|
|
assert engine.session.phase == Phase.REFERENCE_POSES
|
|
motion = engine.motion(current)
|
|
assert motion.phase == "reference_pose" and motion.target == pose
|
|
while engine.session.phase == Phase.REFERENCE_POSES:
|
|
motion = engine.motion(current); current = motion.target; engine.motion_complete()
|
|
assert current == profile.command.baseline_values
|
|
assert engine.session.phase == Phase.RESUME_VERIFY
|
|
|
|
|
|
def test_resume_never_compares_mounts_from_different_waypoint_poses():
|
|
fingerprint = _fingerprint()
|
|
pose = fingerprint.moving_tag_poses["finger"]
|
|
old = replace(fingerprint, moving_tag_poses={"show/finger": pose})
|
|
new = replace(fingerprint, moving_tag_poses={"other/finger": pose})
|
|
checker = ResumeVerifier(required_moving_poses=("finger",))
|
|
assert not checker.compare(*select_installation_evidence(old, new, {"finger"})).reuse
|
|
assert checker.compare(*select_installation_evidence(old, old, {"finger"})).reuse
|
|
missing = replace(fingerprint, moving_tag_poses={})
|
|
assert not checker.compare(*select_installation_evidence(old, missing, {"finger"})).reuse
|