mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-18 18:41:41 -07:00
laser_stream_test: the rolloff reference pins the bench-default curve's rendering of S300 end to end
Rule 19 names laser_arm_test.c case P as the proof of the dose curve's mapping. Case P calls curveComputeValue directly and reads its counts; it does not reach the wiring from the S word to the stream: spindleConfig installing the curve as the PWM compute hook, and the level the hook returns riding the dither into FIRE density. A driver that left the hook uninstalled passes case P and renders every cut through the identity mapping, a different delivered dose at every S. The rolloff reference session (rule 23) already runs one M4 line at S300 under the shipped curve and reads its cruise density, to compare against the two-cut run. It now also holds that density to the curve's own point: 30 percent light through the bench-default curve lands between its (45 percent density, 21 percent light) and (60, 37) points, 53.44 percent density, level 68 of 127, density 0.535, held to 0.02. The expectation is mirrored next to the curved configuration the way the floor is, so a change to the curve changes it. The header's rule 19 names the point. No session is added, and no session's configuration changes. Proof: the host test grblHAL-glowforge CI runs (the step "Laser stream emission rules", python3 forgefirm/scripts/bench/laser_stream_test.py build/grblHAL_glowforge) against the native null-sink build of the driver at badc832 (-DGFMCODE_WAIT_S=5.0): the rolloff reference cruise renders 0.5355 against the expected 0.5354, and the whole harness passes, every session. Negative control, through a scratch copy of the harness: the same cut with laser_dose_curve = off renders 0.3625 (the identity mapping, level 46 through the 10 percent floor), 0.17 from the point, and fails the assertion. Acceptance: none; the harness is grblHAL's CI's, and src/** of grblhal-glowforge keeps its covers.
This commit is contained in:
@@ -82,9 +82,10 @@ over TCP, then checks the dumps against the kernel feeder contract:
|
|||||||
is 0 (the floor, not $31, sets the bottom of the S range) and $35
|
is 0 (the floor, not $31, sets the bottom of the S range) and $35
|
||||||
is the board's floor, landing at PWMSAR_FLOOR_MIN or above
|
is the board's floor, landing at PWMSAR_FLOOR_MIN or above
|
||||||
19. the dose curve's mapping of S onto delivered light is
|
19. the dose curve's mapping of S onto delivered light is
|
||||||
laser_arm_test.c case P's; every session here but the rolloff ones
|
laser_arm_test.c case P's, and the rolloff reference run (rule 23)
|
||||||
runs with laser_dose_curve = off so its S-to-level arithmetic stays
|
pins one point of it end to end: the S300 cruise renders the density
|
||||||
exact
|
the curve maps 30 % light onto; every other session runs with
|
||||||
|
laser_dose_curve = off so its S-to-level arithmetic stays exact
|
||||||
20. the corner rolloff starves the slow spots: under M4 with the curve
|
20. the corner rolloff starves the slow spots: under M4 with the curve
|
||||||
in force, the accelerate-in head of a line renders less density at
|
in force, the accelerate-in head of a line renders less density at
|
||||||
the default gamma of 2 than at gamma 1, and the cruise middle
|
the default gamma of 2 than at gamma 1, and the cruise middle
|
||||||
@@ -309,6 +310,13 @@ DENSITY_CONF_FLOORED = ("laser_power_model = density\n"
|
|||||||
"laser_dose_curve = off\n" + DENSITY_CONF_BASE)
|
"laser_dose_curve = off\n" + DENSITY_CONF_BASE)
|
||||||
# The shipped default: the bench curve in force (no keys at all).
|
# The shipped default: the bench curve in force (no keys at all).
|
||||||
DENSITY_CONF_CURVED = "laser_power_model = density\n" + DENSITY_CONF_BASE
|
DENSITY_CONF_CURVED = "laser_power_model = density\n" + DENSITY_CONF_BASE
|
||||||
|
# Rule 19's end-to-end point: 30 % light (S300) through the bench-default
|
||||||
|
# curve (glowforge_laser.c curve_default) lands between its (45 % density,
|
||||||
|
# 21 % light) and (60 %, 37 %) points, 45 + 9/16 x 15 = 53.44 % density,
|
||||||
|
# level 68 of 127. Mirrored here the way the floor is: changing the curve
|
||||||
|
# changes this expectation.
|
||||||
|
CURVE_S300_LEVEL = 68
|
||||||
|
CURVE_S300_DENSITY = CURVE_S300_LEVEL / float(PWM_PERIOD)
|
||||||
|
|
||||||
DENSITY_LEVEL = tuple(int(x * PWM_PERIOD / RPM_MAX) for x in LADDER_S)
|
DENSITY_LEVEL = tuple(int(x * PWM_PERIOD / RPM_MAX) for x in LADDER_S)
|
||||||
# A $35 typed ahead of the job: rule 18 says the arm overwrites it.
|
# A $35 typed ahead of the job: rule 18 says the arm overwrites it.
|
||||||
@@ -1531,6 +1539,12 @@ def main():
|
|||||||
a, b = rs[0]
|
a, b = rs[0]
|
||||||
mid = rt[(a + b) // 2 - 1000:(a + b) // 2 + 1000]
|
mid = rt[(a + b) // 2 - 1000:(a + b) // 2 + 1000]
|
||||||
dens_ref = sum(1 for t in mid if t & 0x10) / float(len(mid))
|
dens_ref = sum(1 for t in mid if t & 0x10) / float(len(mid))
|
||||||
|
# Rule 19: the reference cut is one M4 line at a known S under the
|
||||||
|
# shipped curve, so its cruise (velocity ratio 1, no rolloff) pins the
|
||||||
|
# curve's rendering end to end.
|
||||||
|
if abs(dens_ref - CURVE_S300_DENSITY) > 0.02:
|
||||||
|
fail("[rolloff-ref] the S300 cruise renders %.3f, expected %.3f through the "
|
||||||
|
"bench-default curve" % (dens_ref, CURVE_S300_DENSITY))
|
||||||
tt = tick_bytes(two)
|
tt = tick_bytes(two)
|
||||||
ts = fire_spans(tt)
|
ts = fire_spans(tt)
|
||||||
if len(ts) != 1:
|
if len(ts) != 1:
|
||||||
|
|||||||
Reference in New Issue
Block a user