mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-22 21:32:16 -05:00
__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>