diff --git a/forgetest/forgetest/suite/commission_dark.py b/forgetest/forgetest/suite/commission_dark.py index ea972df..d9ed910 100644 --- a/forgetest/forgetest/suite/commission_dark.py +++ b/forgetest/forgetest/suite/commission_dark.py @@ -228,9 +228,12 @@ def check_cameras(ctx): @test("commission.check-motion", title="The motion check proves the rail, the lens reference, and the jogs", subsystem="commission", kind="auto", hardware="takeover", est_min=5, covers=DARK_COVERS + [("forgectrl", "src/super.c"), ("forgectrl", "src/liveness.c"), + ("forgectrl", "src/lenshome.c"), ("forgectrl", "src/accel.c"), ("forgectrl", "src/cool.c")], requires=["forgectrl.auth", "motion.pacing"], - description="POST /wiz/motion/start: the controller stops, the liveness probe runs, the lens " + description="POST /wiz/motion/start: the controller stops, the liveness probe runs and the " + "lens takes its hall-edge reference behind it (a lens that cannot reach its " + "edge is a motion fault, and no controller starts), the lens " "finds the hall reference in five agreeing passes, the controller comes back in " "loopback posture, and the head jogs 50 mm each way on X and Y with the " "accelerometer as the witness. The one prompt (the jogs are about to move) is " diff --git a/forgetest/forgetest/suite/forgectrl.py b/forgetest/forgetest/suite/forgectrl.py index 1d638af..970d7da 100644 --- a/forgetest/forgetest/suite/forgectrl.py +++ b/forgetest/forgetest/suite/forgectrl.py @@ -281,7 +281,9 @@ def settings_bounds(ctx): ("forgectrl", "src/curverec.*")], description="The panel page is served, /status carries the machine telemetry the panel and " "the acceptance tool read (including the sys block: CPU busy percent over the " - "interval since the previous read, memory used percent), and /cam/status " + "interval since the previous read, memory used percent; and homed_axes, " + "the axes that carry a reference, Z alone once the lens has taken its " + "own at the controller's start), and /cam/status " "answers. In GRBL mode with a live controller, /status also echoes the " "controller's published state file as the grbl block (fresh age, machine " "state, sender session, laser window and dose model, modal report), " @@ -328,6 +330,32 @@ def panel_serves(ctx): ctx.check(isinstance(sys_.get("mem_pct"), (int, float)) and 0.0 < sys_["mem_pct"] < 100.0, "/status sys.mem_pct is not a percent: %s", sys_) + # The lens takes its own reference on the hall edge at every + # controller start, so with a controller running Z is referenced on + # its own while X and Y wait for a home: homed_axes names the axes + # that carry one, and Z reads inside the lens reach rather than the + # zero an unreferenced axis would show. + axes = s.get("homed_axes") + ev["homed_axes"] = axes + ctx.check(isinstance(axes, int) and 0 <= axes <= 7, + "/status homed_axes is not an axis mask: %s", axes) + ctx.check(bool(s.get("homed")) == (axes == 7), + "/status homed (%s) disagrees with homed_axes (%s)", + s.get("homed"), axes) + st, mode0 = fc.get("/mode") + if isinstance(mode0, dict) and mode0.get("controller") == "running": + lens = s.get("lens") or {} + pos = s.get("pos") or {} + ctx.log("/status homed_axes=%s pos.z=%s reach=%s..%s", axes, + pos.get("z"), lens.get("reach_min"), lens.get("reach_max")) + ctx.check(axes is not None and axes & 4, + "Z is not referenced with a controller running: %s", axes) + ctx.check(isinstance(pos.get("z"), (int, float)) + and lens.get("reach_min") is not None + and lens["reach_min"] <= pos["z"] <= lens["reach_max"], + "Z %s is outside the lens reach %s..%s", pos.get("z"), + lens.get("reach_min"), lens.get("reach_max")) + st, cam = fc.get("/cam/status") ev["cam_status"] = st ctx.log("GET /cam/status -> %s %s", st, cam) diff --git a/scripts/bench/laser_stream_test.py b/scripts/bench/laser_stream_test.py index c696438..be23a58 100644 --- a/scripts/bench/laser_stream_test.py +++ b/scripts/bench/laser_stream_test.py @@ -146,12 +146,11 @@ JOB_M4 = [ "M5", ] -# Session Z: the lens is in the stream. The sender references the lens -# (M103, as a commissioning card does), then a 1 mm move up and back at -# the screw's 2.922 half-steps per millimeter: three Z steps with the -# direction bit set, three with it clear. +# Session Z: the lens is in the stream. The lens is referenced on its hall +# edge at the controller's start, so Z is already open here: a 1 mm move up +# and back at the screw's 2.922 half-steps per millimeter, three Z steps +# with the direction bit set, three with it clear. JOB_Z = [ - "M103 Z3 P14 Q20", "G0 Z4", "G0 Z3", ]