Files
firmware/docs/notes
Oleksandr ShyshatskyiandClaude Opus 5 eea7025596 The per-tool frame exists before anything asks for it
__init__ called refresh_offsets() nineteen lines before it built the
transform that refresh_offsets() reads to decide whether gcode_move's
position cache needs invalidating. The read is guarded by `changed`, and
nothing has changed only when every derived offset is zero -- so the
section parsed on a factory-fresh machine and raised AttributeError on any
printer that had ever been calibrated. Which is also why the suite missed
it: the replica boots uncalibrated, and the transform tests build the
object with __new__. Both are now pinned.

While in there: the three offset series were one list bound to three names.

The job term gets its own slot. It shared homing_origin with the operator's
babystep, and SET_GCODE_OFFSET Z=0 -- what the end/cancel block issued --
cannot tell them apart, so ending a print wiped the babystep too. It is a
term of the tool frame now, set absolutely by TOOLCHANGE_SET_PRINT_OFFSET
and dropped by its new CLEAR=1, which moves nothing and so no longer needs
END_PRINT's homed/unhomed fork. Reported as toolchanger.print_z_offset,
because a macro converting a G-code Z to a machine Z now has three layers
to subtract, not two.

And a way back from an aborted toolchange, which leaves the frame off with
a tool still on the carriage -- a bare G1 Z0 then aims 3.2 mm into the
plate. INITIALIZE_TOOLCHANGER re-applies the frame, as upstream's does,
touching no dock; TOOLCHANGE_STATUS says which frame is on; and applying an
uncalibrated tool's frame says so at the moment it goes on rather than only
at startup. _log_transform_chain now checks that bed_mesh and
skew_correction really did end up below us instead of only printing the
chain. TOOL_Z_ADJUST no longer claims "in force now": it is
SET_GCODE_OFFSET Z_ADJUST without MOVE=1, so it lands on the next Z move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 16:04:01 +03:00
..