mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -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
|
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.
|
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
|
**Both dose and pulse length matter, in different regimes.** Four
|
||||||
and 10, then F100 at 20) put the same six rungs on the material every
|
ladders run with no minimum pulse (F300 at periods 20, 40 and 10, then
|
||||||
time, and the matched pairs across periods separate the variables - at
|
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
|
identical pulse length, halving density killed the mark; at identical
|
||||||
density, varying pulse length 3x changed nothing. Feed did not move it
|
density, varying pulse length 3x changed nothing; and feed did not move
|
||||||
either: 10 % at F100 carries 44 % more energy per millimeter than 20 %
|
it either, 10 % at F100 carrying 44 % more energy per millimeter than a
|
||||||
at F300, which marks, and still left nothing. So the low-end marking
|
marking 20 % at F300 and still leaving nothing.
|
||||||
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.
|
|
||||||
|
|
||||||
What the ladders did expose is a floor of our own making, since fixed:
|
That reading was too broad. Every one of those comparisons sat at or
|
||||||
at 5 % the model emitted 36 us stubs and the `hv_current` trace shows
|
above 20 % density, where the pulses in play were already long enough.
|
||||||
**no discharge at all** for that rung, while 10 % drew current for its
|
A fifth ladder with a 3-tick minimum moved 10 % from nothing to a mark
|
||||||
full 15 s and simply marked nothing. The factory never emits below one
|
at the **same density and less dose**, purely by lengthening its pulses
|
||||||
100 us tick, and reaches low density by skipping windows instead -
|
from 36-71 us to 106 us. So above ~100 us the outcome follows dose;
|
||||||
which is now what `laser_pulse_min_ticks` does.
|
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
|
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
|
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
|
below the minimum (excepting one clipped by fire going off mid-burst), and
|
||||||
the rendered density still exact.
|
the rendered density still exact.
|
||||||
|
|
||||||
Owed next: the user-facing scale. Under this model `$35` and `$36` are a
|
### The fifth ladder, and a conclusion retracted
|
||||||
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
|
Same ladder, period 20, F300, with the 3-tick minimum in place. **The floor
|
||||||
the 10 %→20 % step these four runs give.
|
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
|
## Superseded status notes
|
||||||
|
|
||||||
|
|||||||
@@ -521,6 +521,8 @@ DLADDER_PITCH = 3.0 # mm between rungs
|
|||||||
STREAM_RATE_HZ = 28160 # machine tick (GFSINK_RATE default)
|
STREAM_RATE_HZ = 28160 # machine tick (GFSINK_RATE default)
|
||||||
PWM_PERIOD = 127 # 7-bit power byte against PWMSAR
|
PWM_PERIOD = 127 # 7-bit power byte against PWMSAR
|
||||||
CONF = os.environ.get('GFHOME_CONF') or '/data/forgefirm.conf'
|
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):
|
def conf_get(key):
|
||||||
@@ -621,9 +623,16 @@ def drill_dladder(g):
|
|||||||
|
|
||||||
# What each rung actually emits. The on-count is dithered between
|
# What each rung actually emits. The on-count is dithered between
|
||||||
# adjacent integers, so the burst below is the mean.
|
# 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'
|
print('period %d ticks = %.0f us at %d Hz -> %.0f Hz pulse rate'
|
||||||
% (period, period * 1e6 / STREAM_RATE_HZ, STREAM_RATE_HZ,
|
% (period, period * 1e6 / STREAM_RATE_HZ, STREAM_RATE_HZ,
|
||||||
STREAM_RATE_HZ / float(period)))
|
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):')
|
print('rungs (drawn in order, alternating direction, +Y between):')
|
||||||
levels = []
|
levels = []
|
||||||
for pct in DLADDER_PCT:
|
for pct in DLADDER_PCT:
|
||||||
@@ -638,8 +647,12 @@ def drill_dladder(g):
|
|||||||
# skipped instead - that is the short end this drill is for.
|
# skipped instead - that is the short end this drill is for.
|
||||||
lo = int(on)
|
lo = int(on)
|
||||||
tick_us = 1e6 / STREAM_RATE_HZ
|
tick_us = 1e6 / STREAM_RATE_HZ
|
||||||
if lo == 0:
|
if on < min_ticks:
|
||||||
burst = '1 tick (%.0f us) on ~%.0f%% of periods' % (tick_us, on * 100)
|
# 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:
|
elif on == lo:
|
||||||
burst = '%d ticks (%.0f us)' % (lo, lo * tick_us)
|
burst = '%d ticks (%.0f us)' % (lo, lo * tick_us)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user