Which indeed would make kind of sense. If you switch extruder and print with T1 then you would not want to return to T0 with some unknown E step offset.
Thanks Sineos. I’m trying to figure out that line too.
It seems erroneous that the extruder base position (its frame of reference) should be overwritten and set to the last position of the same extruder. This makes “absolute” moves relative to the position before the tool-change.
What I just described would happen to T0 after switching to T1 and back, without T1 moving at all.
This behavior is certainly due to a bug, evidenced by this reduced test code:
T0 ; Change to T0, the default (optional).
M82 ; Set absolute coordinates for extrusion moves.
G0 E10 ; Move to E=10.
T1 ; Switch to T1.
T0 ; Switch back to T0.
G0 E10 ; Move to E=10.
M82 ; Set absolute coordinates for extrusion moves (optional).
; T0 should not move because it is already at E=10, but it does!
PS: For anyone else reading, the “base position” is used to calculate the final coordinate of an absolute move, by adding it to the E parameter in the GCODE command (relevant code here).
I’m not sure I understand that part. I expected base coordinates to be known, stored for each extruder, and restored on tool-change.
gcode: Reset extrude_factor and extruder position on a tool change
The extrude_factor and extruder position are specific to the current extruder, so reset them to default values on a Tn command.
It does not look like base position is reset to the default value of 0, as intended by the commit.
The present effect of that line is to instead set the base position to the last position of the activated extruder, which breaks the origin coordinate for absolute extruder moves.
The nearby call to reset_last_position is not obvious either (commit here), but it is responsible for setting last_position[3] to the position of the new extruder, which is then used to overwrite base_position[3] (but only if the printer is ready, otherwise the value from a previous extruder will be used).
I also found other “uses” of base_position[3]. The M221 command seems to rely on manipulating the extruder’s origin somehow, to implement the extrusion factor feature. Commit here.
I’m starting to understand why.
This is now too hairy, perhaps @koconnor will know how to proceed.
I’d expect to start with the stored coordinate system and last position of the tool being picked-up.
For an (M82) absolute extrusion move to work predictably across a GCODE program, the coordinate origin of the extruder axis must remain fixed; as for any stepper axis.
In the current implementation, the origin is made relative to the last move (i.e. before the T0/T1/T0 sequence). This seems contradictory, and makes absolute M82 moves work in the way that relative M83 would be expected to.
This is shown clearly by the second GCODE sample above. It achieves relative motion style using only M82 G0 E10 commands between tool-changes, and no motion with M82 G0 E10 + M82 G0 E0, which should be impossible.
I do indeed think that this line is essentially doing a G92 E0 just after switching extruders.
I’m not familiar with tool changing in klipper, so I took your liquid handler for a ride
I compared the gcode positions after each instructions in your test gocde test gcode, for these conditions:
Vanillia Klipper,
Klipper with the line commented out,
Same as above but with a G92 E0 executed after each tool change.
I wouldn’t expect this offset when switching tool. It doesn’t restore the original extruder position, but resets it to 0 and adds what was already extruded to the offset.
This is just my observation, there could be implications for relative extrusion or other configurations that I am not familiar with.
Thanks a lot Piezo I just tested your code and reproduced the same result.
Knocking-out line 73 seems like a good quick fix.
The documentation lists the commands that affect the coordinate systems. Activate extruder is not there, but M221 is. I’ve been looking at the definition of M221 (code here) but can’t figure out why it relies on changing the base position.
I can’t tell if removing L73 messes up the expected behavior of M221.
As an alternative, I hoped that using SET_GCODE_OFFSET E=0 after the tool change would remove the base_position position offset.
But it doesn’t. Instead this does something like base_position[3] += offset - self.homing_position[3] which is a no-op.
Implementing M112 seems difficult with absolute extruder positioning, the current E position can’t be simply scaled. That could explain the complexity we are seeing here.
When it comes to old G-Code commands, the goal in Klipper is to support the G-Code commands produced by common 3rd party software (eg, OctoPrint, Printrun, Slic3r, Cura, etc.) in their standard configurations (as mentioned at G-Codes - Klipper documentation ).
FWIW, the old G-Code commands are maddeningly cryptic and I try my best to avoid spending any time trying to decipher them.
To the best of my knowledge, the Klipper code works with the popular slicer programs (which to the best of my knowledge effectively issue a “g92 e0” when changing tools).
If you’re concerned about the position being reset between toolhead changes, you could manually save and restore it. The position prior to the toolhead change is in printer.gcode_move.base_position.e and it can be restored with a G92 command (something like G92 E{-old_e_base_position})