Commit Graph
13 Commits
Author SHA1 Message Date
ScottW514 58cad9a8d8 Prove the corner rolloff; document the one-press recorder
The stream harness gains rule 20: under M4 with the curve in force, the
accelerate-in head of a line renders less density at the default gamma
of 2 than at gamma 1 (0.317 against 0.537 on the host grid) while the
cruise middle renders identically - the exponent shapes only the
velocity-scaled rolloff, never the programmed level. The panel-serves
covers widen to the whole recorder (src/curverec.*). BRINGUP describes
the rolloff and the one-press recorder; the MOTION table gains
laser_corner_gamma; the panel help explains the knob.
2026-08-30 21:48:32 -04:00
ScottW514 0b941fd743 Prove the dose curve and the recorder; document S-means-light
The stream harness gains rule 19: with the bench-default curve in force
a ladder of S rungs renders the curve's densities exactly (half light
lands near 80 percent density), monotonic, floored and ceiled by
$35/$36; every other session pins laser_dose_curve = off so its
S-to-level arithmetic stays exact, and the arm-report checks carry the
curve name. The lifecycle harness asserts the published state file
names the curve in force. The catalog's forgectrl.panel-serves asserts
the curve field in the grbl report, /curve/status and the ladder
G-code, and its covers name the recorder.

BRINGUP describes S-commands-light through the measured curve and the
owner recorder; the MOTION table gains laser_dose_curve; LIGHTBURN
tells the operator power now means light and how to record their own
tube's curve from the panel.
2026-08-30 20:19:24 -04:00
ScottW514 d612c0099a Prove the density-only model; record the rasters and the decision
The stream harness keeps the analog rendering as the host-test
conservatism reference (rule 13's mask, the duty ladders) and drops the
M101 switch sessions; rule 18 stays as the derived-floor proof, now
satisfied from boot by the precompute. The lifecycle harness's
state-files scenario asserts the derived floor is in $$ before any arm.
The catalog's laser.power-model-switch goes and laser.power-floor reads
the one floor key with no M-code needed. The mswitch drill goes; the
m4corner drill becomes a single density pass; the dpatch drill returns
to density only.

The CAMPAIGN-LOG records the first rasters (254 and 508 DPI grayscale
wedges: tonality held to ~14 pulse slots per pixel, no dither artifact,
one benign stale-verdict suppression under CPU starvation) and the
decision that ends the analog mode - the strike transient fires a spot
at every beam-on, and the finish comparison found no advantage. BRINGUP,
LIGHTBURN, MOTION and SAFETY describe the density-only present.
2026-08-30 19:41:50 -04:00
ScottW514 3025996c86 Prove the M101 dose-model switch; record the judged dose curves
The stream harness gains rules 18 to 21: the floor is derived from the
selected model's config key at the arm and a typed $35 is overwritten;
M101 switches the rendering exactly at the boundary in both directions
with no continuous FIRE at full duty across it; a refused switch (the
spindle on) leaves the stream unchanged, and the harness resyncs with
an empty line because the core skips G-code after an error until the
sender resyncs; M2 reverts a program-scoped switch and Q1 holds. The
analog sessions pin laser_floor_analog at the density floor so the
existing duty expectations stand, and the density ladder's unfloored
run moves from a chained $35 write to the laser_floor_density key.

The catalog's laser.power-floor becomes model-aware: it reads the
configured model and the floor keys from forgectrl, switches to the
configured model with M101 so the derivation runs without a fire, and
expects $35 to be that model's floor. The new laser.power-model-switch
switches to each model with the spindle off, checks the reported
message and $35 after each switch, and checks the M2 revert. The new
mswitch bench drill runs the switch on the machine in one armed run.

Docs follow: BRINGUP's Laser control section describes the switch, the
derived floors and the measured dose response of both models; the
MOTION settings table gains the five keys; LIGHTBURN gains a Power
models section and drops the stale 30 percent floor advice; SAFETY
names the switch's refusal rule; the CAMPAIGN-LOG records the judged
depth-witness runs of 2026-08-30 and the switch's host and bench proof.
2026-08-30 15:08:34 -04:00
ScottW514 fff0980079 Laser: the rapids after an M5 ship dark and the next job fires; the performance-curve drill
Stream harness rules 16 and 17 with their sessions: an M5 executed with
the planner drained and the kernel run over must darken the rapids that
follow it (m5-idle), and a job whose M3 runs at the level the previous
job ended at must still fire its first cut (next-job). The second rule
is the core's contract: set_state records the rpm and the per-segment
update is skipped while it is unchanged, so the driver's set_state is
the only thing that can light that move. Both sessions run under both
dose models; the bench build that went dark on its second job fails
next-job with one fire span.

Bench drills: pcurve (a per-level ladder of 100 mm lines read from the
HV current and the head thermopile at 25 Hz, with the instrument checks
and the JSON record) and m5dark (one line, M5, two rapids, judged on the
current trace and laser_on_sampled until the armed window closes).

Catalog: laser.m5-rapid-dark, a live test of the M5 case (46 tests; the
counts in BRINGUP follow). CAMPAIGN-LOG carries the day's record: the
two curve ladders, the defect pair, the root cause, the host and bench
proof.
2026-08-25 17:41:45 -04:00
ScottW514 0c2dd37b2f Cover both dose models explicitly now that density is the default
grblHAL-glowforge 03d70e0, pinned here, makes density the shipped model
and $35 the density floor at 10. Every analog session in the stream
harness now selects its model rather than inheriting it: without that the
flip would have quietly turned them into density runs and taken the
analog fallback's coverage with them. laser.power-floor carries the new
floor and its PWMSAR minimum, and its description no longer describes
$35 as a duty floor.

All ten stream sessions pass on the new defaults, with the analog duties
shifting exactly as the floor predicts - min_value 12, gradient 0.115 -
along with both C harnesses and the lifecycle harness.

Recorded in BRINGUP and the campaign log, including what the defaults
rest on and what they do not: the seven ladders ran at F300 and F100 at
constant power, so production feeds, M4 into corners and the raster path
remain unproven on hardware.
2026-08-17 22:03:56 -04:00
ScottW514 a3e83c4fd5 Cover the minimum pulse width; record what the density ladders measured
Rule 15 in the stream harness holds both halves of the minimum
(grblHAL-glowforge f7e8c17, pinned here): no emitted burst falls below
laser_pulse_min_ticks, excepting one clipped by fire going off mid-burst,
and the levels too faint to fill a window still render their exact
average density. Checked against a run at minimum 1 so it cannot pass
vacuously - level 2 goes from 444 bursts of one tick to 147 of three at
the same density, and levels already above the minimum are unchanged.

Four bench ladders settle the base period at 20. The same six rungs
marked in all of them, and the matched pairs across periods separate the
variables: at identical pulse length, halving the density killed the
mark; at identical density, varying the pulse 3x changed nothing. Feed
does not move it either - 10 percent at F100 carries 44 percent more
energy per mm than 20 percent at F300, which marks, and still left
nothing. The low-end marking limit is average power, not dose per length
and not pulse length.

The F100 trace separates two failures that look alike on the material:
seven current segments for eight rungs, anchored by a flat saturated
final segment that can only be full density, put 5 percent at no
discharge at all and 10 percent at a full 15 seconds of current with no
mark. Only the first is ours, and the minimum pulse is the answer to it.

Also recorded: the factory's Precision Power 1 runs a 19.53 percent FIRE
duty cycle at full PWM duty, and its 1-100 scale maps onto density
18.9-79.5 percent, so its 1 percent is the bottom of the useful band
rather than 1 percent of the range. Under the density model $35 and $36
are that same control - a density floor and ceiling - which makes the
user-facing scale a settings choice rather than new code.
2026-08-17 21:37:41 -04:00
ScottW514 c2c627d9b6 Prove the density dose model host-side; close the idle-gap level loss
Four new sessions in the stream harness cover the model (grblHAL-glowforge
2bca017, pinned here). Density renders the commanded level exactly -
levels 2, 3, 7, 15, 25 and 38 came back as 0.0158, 0.0237, 0.0551,
0.1182, 0.1969 and 0.2993 against level/127 of 0.01575, 0.02362, 0.05512,
0.11811, 0.19685 and 0.29921 - S1000 renders 1.0000 and still ends dark,
every power byte carries full duty, and a level change inside a run costs
no stream byte where analog ships one per level.

Rule 13 is the one worth having: the same job run under both models
produces an identical motion grid tick for tick, and all 20051 density
FIRE ticks fall inside the 169776 the analog run fired. The model masks
the core's fire state and never sources one, measured rather than argued.

Rule 14 covers the idle-gap fix: a standalone S between moves, from a
sender slow enough to drain the planner, now fires each move at its own
level (28338 ticks each at duties 30, 52 and 84). Before the fix duty 30
held all 85014 and the other two levels never appeared. That closes
"Next work" item 18, which this work opened earlier today.

The harness now derives its expectations from the board's floor and
chains two launches over one settings file, because the core precomputes
the S to duty mapping once when the spindle is enabled: $35 written at
runtime persists and reports immediately but only enters force at the
next controller start. That is recorded in BRINGUP beside the existing
defaults note, and laser.power-floor's failure message now says so.

Acceptance: the density path shipping off by default is inert until
laser_power_model is set, and the laser tests' covers already name
grblhal-glowforge src/**; the model's own acceptance test waits on the
bench drill that picks the base period.
2026-08-17 20:24:43 -04:00
ScottW514 cb41a6030c Commission the laser duty floor; record how the factory sets power
The pthresh ladder on scrap puts the tube's two thresholds far apart: the
discharge strikes between 2 and 3 percent duty, but nothing lases usefully
below 16 percent (PWMSAR 20), and the rungs between show only a spot at
each line start. $35 ships at 16 (grblhal-glowforge 9466f76, pinned here).

The drill said current lift-off and first mark share a rung; this run
falsifies that, so its docstring and read-the-material text now name both
thresholds and warn that a start-of-line spot is below the threshold, not
at it.

A start-of-line spot is also what a full-power leak at a kernel run start
would look like, so laser_stream_test gains a ladder session (rule 10):
every FIRE tick must ride a commanded duty, and the fire ticks must divide
evenly across rungs. Both hold exactly - six commanded duties, no others,
and 28296 fire ticks on every rung - so the spots are the tube, not the
stream. The harness now derives its expectations from the floor, which
moves the M4 session's S500 plateau from 63 to 73.

laser.power-floor is a new auto acceptance test, the suite's only
non-firing one: a machine must actually carry the commissioned floor,
since stored settings beat freshly baked defaults.

Three cloud cuts of one square at Precision Power 1, 100 and Full Power
show what the analog path is competing with: the power byte is pinned at
127 in all three, dose is FIRE-bit density on a fixed 7-tick period with
the on-count dithered between adjacent integers, and the power setting
never reaches the machine at all. Facts bank and item 17 carry the
numbers; CAMPAIGN-LOG carries both sessions.
2026-08-17 19:45:19 -04:00
ScottW514 6050c0e703 Unified logging: rsyslog as the system logger, the ForgeFIRM log tree
rsyslog replaces busybox syslogd/klogd (VIRTUAL-RUNTIME_base-utils-syslog,
trimmed PACKAGECONFIG) and becomes the only log writer: the appended
/etc/rsyslog.conf sets the inputs and the ff_line format and includes
the per-logger rules that `forgectrl --render-syslog` renders from the
machine settings at boot. forgefirm-logrotate becomes forgefirm-logging:
render before rsyslog starts (S19), sweep the pre-syslog log files into
/data/forgefirm/legacy-logs once, and rotate the tree at boot and hourly
by rename + HUP instead of copytruncate. Pins bumped to the pushed
forgectrl (syslog emitter, Logs tab, export), grblHAL-glowforge (syslog
emitter) and python3-gfhardware apps (syslog handlers, capture dir);
the CI harnesses set FFLOG_STDERR=1 so failure diagnostics keep the
controller's log lines. BRINGUP carries the bench validation checklist
(Next work item 14); this is an image change and rides the next flash.
2026-08-15 14:37:33 -04:00
ScottW514 26ed519348 bench: surface the controller stderr when the harness cannot connect
A startup failure previously reported only cannot-connect with the
process stderr discarded - undiagnosable in CI.
2026-08-14 19:10:38 -04:00
ScottW514 cc927aca5f Add laser-safety and regulatory documentation; scrub bench identity
- LIGHTBURN.md: mandatory "Before you cut" safety section; the
  walkthrough now reflects the firing machine (dry runs need the
  layer output off or M5; live first-cut instructions); the homing
  entry documents homing_mode and the gfcloud method; the machine
  address is a placeholder.
- README.md: condensed safety section linking the full text and the
  regulatory notes.
- INSTALL.md: "Regulatory and legal" section ahead of the install
  steps; routine updates route through the panel updater rather than
  the installer.
- BRINGUP.md: the release signing key is described as held offline
  (no on-disk path); bench address and credential notes removed;
  Next-work item 7 corrected (the installer embeds the production
  release key); status entry for audit remediation Phases 0-1; the
  GATE A kernel drills join the pending image-flash checklist.
- bench scripts: the target host comes from GF_HOST (or argv) instead
  of a hardcoded address.
- laser_stream_test.py: per-session controller runs with a hermetic
  cooling-verdict publisher; new assertions that every stream
  terminates with FIRE clear (including M3 held to stream end) and
  that no FIRE bit rides a zero-step gap; a cycle-churn session
  exercises the stop/start seams.

Audit findings D-1, D-2, D-3, D-5, D-10, D-12, B-10, and the harness
half of D-4/G-1.
2026-08-14 15:38:24 -04:00
ScottW514 3c095ccbd1 laser milestone: grblhal SRCREV -> 09bc882, host stream test, docs
BRINGUP item 2: grbl-mode laser software implemented + bench-verified
without fire (record in the gate list); first light pending.
LIGHTBURN.md: arming/button-press operation, S-max 1000, fire gates.
scripts/bench/laser_stream_test.py: host-side stream-dump contract
verification against the null-sink build.
2026-08-09 16:13:03 -04:00