mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 08:41:13 -07:00
Retract the pulse-length conclusion; show the minimum in the drill table
The fifth ladder, the first with a minimum pulse, moved the floor down a full rung: only 5 percent failed to mark, and 5 percent now strikes. The trace carries eight current segments where the run before it had seven, with fire beginning at 6.2 s exactly at rung 1 and the usual flat saturated final segment anchoring the count from the other end. That retracts what the previous entry concluded. Pulse length is not irrelevant: 10 percent moved from no mark at F100, with three times the dose per millimeter, to a mark at F300 at the same density, the only change being its pulses growing from 36-71 us stubs to 106 us. The matched-pairs argument was sound but drawn entirely from comparisons at or above 20 percent density, where every pulse length in play was already long enough - it generalized from the one regime where pulse length does not bite. Above ~100 us dose governs; below it pulse length does; below ~36 us the supply does not strike. The factory's 100 us quantum sits on that boundary. dladder now reads laser_pulse_min_ticks and prints what is actually emitted. Without that its table reports the pulse density alone would give, which is wrong wherever the minimum applies - at min 6 the bottom four rungs all emit 213 us and vary their rate instead, and the operator reads that table to interpret the material.
This commit is contained in:
+20
-14
@@ -1090,22 +1090,28 @@ Open items only. Anything closed is in `CAMPAIGN-LOG.md`.
|
||||
under both models - the motion grid is identical and every density FIRE
|
||||
tick is one the analog run also fired, so the model only ever masks.
|
||||
|
||||
The base period is settled: four bench ladders (F300 at periods 20, 40
|
||||
and 10, then F100 at 20) put the same six rungs on the material every
|
||||
time, and the matched pairs across periods separate the variables - at
|
||||
**Both dose and pulse length matter, in different regimes.** Four
|
||||
ladders run with no minimum pulse (F300 at periods 20, 40 and 10, then
|
||||
F100 at 20) put the same six rungs on the material every time - 20 %
|
||||
and up - and their matched pairs looked like a clean answer: at
|
||||
identical pulse length, halving density killed the mark; at identical
|
||||
density, varying pulse length 3x changed nothing. Feed did not move it
|
||||
either: 10 % at F100 carries 44 % more energy per millimeter than 20 %
|
||||
at F300, which marks, and still left nothing. So the low-end marking
|
||||
limit is average power, not dose per length and not pulse length, and
|
||||
the period can be chosen on other grounds. It stays at 20.
|
||||
density, varying pulse length 3x changed nothing; and feed did not move
|
||||
it either, 10 % at F100 carrying 44 % more energy per millimeter than a
|
||||
marking 20 % at F300 and still leaving nothing.
|
||||
|
||||
What the ladders did expose is a floor of our own making, since fixed:
|
||||
at 5 % the model emitted 36 us stubs and the `hv_current` trace shows
|
||||
**no discharge at all** for that rung, while 10 % drew current for its
|
||||
full 15 s and simply marked nothing. The factory never emits below one
|
||||
100 us tick, and reaches low density by skipping windows instead -
|
||||
which is now what `laser_pulse_min_ticks` does.
|
||||
That reading was too broad. Every one of those comparisons sat at or
|
||||
above 20 % density, where the pulses in play were already long enough.
|
||||
A fifth ladder with a 3-tick minimum moved 10 % from nothing to a mark
|
||||
at the **same density and less dose**, purely by lengthening its pulses
|
||||
from 36-71 us to 106 us. So above ~100 us the outcome follows dose;
|
||||
below it pulse length dominates - too short and the energy does
|
||||
nothing, shorter still (36 us, one tick) and the supply does not strike
|
||||
at all, which the `hv_current` trace showed as a rung with no discharge
|
||||
for its full 15 s. That is what the factory's 100 us quantum protects,
|
||||
and what `laser_pulse_min_ticks` now protects.
|
||||
|
||||
With a minimum in place the low end is decoupled from the base period,
|
||||
so the period is free to be chosen on other grounds. It stays at 20.
|
||||
|
||||
Owed: the user-facing scale. The factory maps its whole 1-100 power
|
||||
scale onto density 18.9-79.5 % (fit from the three captures; Full Power
|
||||
|
||||
+41
-4
@@ -2949,10 +2949,47 @@ only what it must. Rule 15 in the stream harness holds both halves: no burst
|
||||
below the minimum (excepting one clipped by fire going off mid-burst), and
|
||||
the rendered density still exact.
|
||||
|
||||
Owed next: the user-facing scale. Under this model `$35` and `$36` are a
|
||||
density floor and ceiling, so mapping S onto the usable band is a settings
|
||||
choice rather than new code — but the floor's value wants a finer ladder than
|
||||
the 10 %→20 % step these four runs give.
|
||||
### The fifth ladder, and a conclusion retracted
|
||||
|
||||
Same ladder, period 20, F300, with the 3-tick minimum in place. **The floor
|
||||
moved down a full rung: only 5 % failed to mark, and 5 % now strikes.**
|
||||
|
||||
The trace carries eight current segments where the F100 run had seven.
|
||||
Segmenting by time rather than by zeros — at 5 % density the sampled current
|
||||
aliases, so isolated zeros appear mid-rung and cannot serve as boundaries —
|
||||
the rung period is 5.25 s and lines up end to end: fire begins at 6.2 s,
|
||||
exactly at rung 1's start, boundaries fall at 11.4, 16.6, 21.9, 27.3, 32.6,
|
||||
38.1 and 43.3 s, and the span is 42.0 s against 41.4 s for eight rungs. The
|
||||
final segment reads 937–981 flat and saturated, which can only be full
|
||||
density. Rung 1 shows peaks of 291, 286 and 204 where the F100 run held a
|
||||
flat zero for the rung's entire fifteen seconds.
|
||||
|
||||
**This retracts the conclusion in the entry above.** Pulse length is not
|
||||
irrelevant: 10 % moved from no mark at F100 — with three times the dose per
|
||||
millimeter — to a mark at F300, at the same density, the only change being
|
||||
its pulses growing from 36–71 µs stubs to 106 µs. The matched-pairs argument
|
||||
was sound but drawn entirely from comparisons at or above 20 % density, where
|
||||
every pulse length in play was already sufficient; it generalized from the one
|
||||
regime where pulse length does not bite. Above ~100 µs dose governs, below it
|
||||
pulse length does, and below ~36 µs the supply does not strike at all. The
|
||||
factory's 100 µs quantum sits exactly on that boundary.
|
||||
|
||||
Not read into: the low-rung current means (76 and 82 raw for 5 % and 10 %).
|
||||
At those duties a 3.3 Hz point sample of a pulsed current carries
|
||||
presence-versus-absence and nothing more. Noted as a confound, though it cuts
|
||||
against the result rather than for it — this ladder started at MPos 0,0 after
|
||||
the controller restart, so it may be on different material than the stacked
|
||||
Y=0/24/48/72 runs.
|
||||
|
||||
Owed next: whether a longer minimum reaches further down (`min_ticks = 6`,
|
||||
213 µs, is set on the bench for the next ladder), and then the user-facing
|
||||
scale. Under this model `$35` and `$36` are a density floor and ceiling, so
|
||||
mapping S onto the usable band is a settings choice rather than new code, but
|
||||
the floor's value wants a finer ladder than the 10 %→20 % step. The trick has
|
||||
a ceiling of its own: a longer minimum at fixed dose means longer gaps, and
|
||||
once gap × feed approaches the beam spot a line dots. At 5 mm/s a 4.5 ms gap
|
||||
is 22 µm against a ~200 µm spot; at 2000 mm/min it is 150 µm, where dotting
|
||||
would start to show.
|
||||
|
||||
## Superseded status notes
|
||||
|
||||
|
||||
@@ -521,6 +521,8 @@ DLADDER_PITCH = 3.0 # mm between rungs
|
||||
STREAM_RATE_HZ = 28160 # machine tick (GFSINK_RATE default)
|
||||
PWM_PERIOD = 127 # 7-bit power byte against PWMSAR
|
||||
CONF = os.environ.get('GFHOME_CONF') or '/data/forgefirm.conf'
|
||||
PULSE_MIN_KEY = 'laser_pulse_min_ticks'
|
||||
PULSE_MIN_DEFAULT = 3 # glowforge_laser.c PULSE_MIN_TICKS_DEFAULT
|
||||
|
||||
|
||||
def conf_get(key):
|
||||
@@ -621,9 +623,16 @@ def drill_dladder(g):
|
||||
|
||||
# What each rung actually emits. The on-count is dithered between
|
||||
# adjacent integers, so the burst below is the mean.
|
||||
min_ticks = int(conf_get(PULSE_MIN_KEY) or PULSE_MIN_DEFAULT)
|
||||
if min_ticks < 1:
|
||||
min_ticks = 1
|
||||
print('period %d ticks = %.0f us at %d Hz -> %.0f Hz pulse rate'
|
||||
% (period, period * 1e6 / STREAM_RATE_HZ, STREAM_RATE_HZ,
|
||||
STREAM_RATE_HZ / float(period)))
|
||||
print('minimum pulse %d ticks = %.0f us (%s): below it the model skips'
|
||||
% (min_ticks, min_ticks * 1e6 / STREAM_RATE_HZ,
|
||||
PULSE_MIN_KEY if conf_get(PULSE_MIN_KEY) else 'driver default'))
|
||||
print('periods and carries the debt, so the pulse never falls under it.')
|
||||
print('rungs (drawn in order, alternating direction, +Y between):')
|
||||
levels = []
|
||||
for pct in DLADDER_PCT:
|
||||
@@ -638,8 +647,12 @@ def drill_dladder(g):
|
||||
# skipped instead - that is the short end this drill is for.
|
||||
lo = int(on)
|
||||
tick_us = 1e6 / STREAM_RATE_HZ
|
||||
if lo == 0:
|
||||
burst = '1 tick (%.0f us) on ~%.0f%% of periods' % (tick_us, on * 100)
|
||||
if on < min_ticks:
|
||||
# Below the minimum the model skips periods and carries the
|
||||
# debt, so the pulse holds at the minimum and the rate drops.
|
||||
burst = '%d ticks (%.0f us) every %.1f periods (%.0f Hz)' % (
|
||||
min_ticks, min_ticks * tick_us, min_ticks / on,
|
||||
STREAM_RATE_HZ / float(period) * on / min_ticks)
|
||||
elif on == lo:
|
||||
burst = '%d ticks (%.0f us)' % (lo, lo * tick_us)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user