修正朝上判断、接触高度与过期姿态目标

朝上判断误用平台轴、接触高度报旋转前数值、多点对准复用缓存姿态,且多点会话被复核入口拒绝;
现按修正计划改正并接通 autocal-multipoint-1.0 只读复核,缺失帧源如实报告而不补零。

离线验证:新回归在 dc5a6f8 上失败、此处通过,panel_check 通过,两截图点接触高度复现
19.0510 / 21.5781 mm;实机项未做,详见 .scratch/autocal-motion-fix/verification.md。
This commit is contained in:
ykcheungab
2026-10-15 06:52:28 +08:00
parent 5339624ffa
commit bcc55a3b97
29 changed files with 2179 additions and 209 deletions
+61
View File
@@ -32,8 +32,10 @@ from orisys_autocal.motion.models import AxisState, AxisStatusBits, BusStatus
from orisys_autocal.motion.pose_move import (
MOVE_ORDER,
PoseMover,
PressAxis,
SETTLE_DEG,
SETTLE_MM,
press_targets,
)
from orisys_autocal.motion.transport import DemoTransport
from orisys_autocal.preferences import default_preferences
@@ -465,3 +467,62 @@ def test_the_units_round_trip_through_the_service():
from orisys_autocal.motion import user_units_to_deg
assert user_units_to_deg(axis, units) == pytest.approx(value)
# ------------------------------------------------------------------ press axis
def test_an_uncalibrated_press_axis_is_held_rather_than_commanded():
"""A geometric contact height is not a controller coordinate.
``solve`` reports where the point ends up; what the press axis *reads* there
is a separate bench measurement. Until someone has made it, commanding the
geometric number would drive the press to a height that means nothing.
"""
targets, held = press_targets({"x": 1.0, "y": 2.0, "z": 19.051}, PressAxis())
assert held == ("z",)
assert "z" not in targets
assert targets == {"x": 1.0, "y": 2.0}
def test_a_calibrated_press_axis_turns_the_contact_height_into_its_coordinate():
"""The relation has both a zero and a direction, and both come from the bench."""
rising = PressAxis(zero_mm=12.5, rising=True, calibrated=True)
falling = PressAxis(zero_mm=12.5, rising=False, calibrated=True)
assert rising.target_for(19.051) == pytest.approx(31.551)
assert falling.target_for(19.051) == pytest.approx(-6.551)
targets, held = press_targets({"x": 1.0, "z": 19.051}, rising)
assert held == ()
assert targets["z"] == pytest.approx(31.551)
def test_planning_the_press_axis_does_not_touch_the_caller_s_mapping():
"""The panel hands over its solved targets; holding z must not edit them."""
targets = {"x": 1.0, "z": 3.0}
press_targets(targets, PressAxis())
assert targets == {"x": 1.0, "z": 3.0}
def test_a_held_press_axis_still_plans_the_other_roles():
"""Held is not refused: the four axes that are justified still move."""
service = make_service()
plan = plan_pose_move(service, {"x": 1.0, "y": 2.0}, hold=("z",))
assert [step.role for step in plan.steps] == ["x", "y"]
assert plan.held == ("z",)
@pytest.mark.parametrize("settings", [
{"zero_mm": 12.5, "rising": True, "calibrated": "false"},
{"zero_mm": float("nan"), "rising": True, "calibrated": True},
{"zero_mm": 12.5, "rising": "false", "calibrated": True},
{"zero_mm": True, "rising": True, "calibrated": True},
{"calibrated": True},
])
def test_invalid_press_settings_keep_the_axis_held(settings):
press = PressAxis.from_settings(settings)
assert press.target_for(19.051) is None
def test_valid_press_settings_preserve_the_measured_direction():
press = PressAxis.from_settings({"zero_mm": 12.5, "rising": False, "calibrated": True})
assert press.target_for(19.051) == pytest.approx(-6.551)