mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-21 12:52:16 -05:00
EXCLUDE_OBJECT installs the ExcludeObject move transform, and inside a cancelled object _ignore_move updates Python state without ever calling next_transform.move(). Nothing reaches the toolhead, so the lookahead buffer that normally blocks gcode.run_script never fills, and virtual_sdcard.work_handler runs on its own yields alone -- one reactor.pause per 8192-byte read, about 330 lines apart. The eboard's soft-PWM refresh misses its deadline and the MCU shuts down with "Timer too close". Measured on a Creator 5 Pro: 37 s from "Excluding object" to the shutdown, with 1 Hz status queries answered in 1.30-1.78 s throughout while the main MCU sat at mcu_awake=0.000 and gcodein=0. EXCLUDE_OBJECT_DEFINE is not the cost. The line costs 115 ms through the live klippy and nothing thereafter; three prints of the same file without a cancel complete with bytes_retransmit=0. Removing it removes the object there is to cancel, not the work. tools/gcode-bench holds the harnesses, including the shlex fast path that takes that DEFINE from 91.6 ms to 5.9 ms on the printer -- worth having for large plates, but not this bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AVUMfbNuKUWWV32PBcydwb
25 lines
985 B
Python
Executable File
25 lines
985 B
Python
Executable File
#!/usr/bin/env python3
|
|
# Generate a synthetic EXCLUDE_OBJECT_DEFINE block of the shape a slicer emits.
|
|
import argparse, json, math, sys
|
|
|
|
def polygon(cx, cy, r, n):
|
|
return [[round(cx + r * math.cos(2*math.pi*i/n), 3),
|
|
round(cy + r * math.sin(2*math.pi*i/n), 3)] for i in range(n)]
|
|
|
|
def block(nobj, npoints, name_len=24):
|
|
out = []
|
|
for i in range(nobj):
|
|
cx, cy = 20.0 + (i % 10) * 20.0, 20.0 + (i // 10) * 20.0
|
|
name = ("PART_%d_" % i).ljust(name_len, 'X')[:max(name_len, 8)]
|
|
poly = json.dumps(polygon(cx, cy, 8.0, npoints), separators=(',', ' '))
|
|
out.append('EXCLUDE_OBJECT_DEFINE NAME=%s CENTER=%g,%g POLYGON=%s'
|
|
% (name, cx, cy, poly))
|
|
return out
|
|
|
|
if __name__ == '__main__':
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument('--objects', type=int, default=25)
|
|
p.add_argument('--points', type=int, default=64)
|
|
a = p.parse_args()
|
|
sys.stdout.write('\n'.join(block(a.objects, a.points)) + '\n')
|