mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-06 01:27:40 +00:00
Wait in the wipe tower with a millisecond dwell on Klipper
The wipe tower's "Delay after unloading" never happened on Klipper. It was emitted as G4 S<seconds>, and Klipper's G4 reads only the P parameter, in milliseconds, so the pause was silently skipped. The option now produces a dwell Klipper actually performs. Also corrects the planner flush rationale, which cited an extruder position reset that Klipper resolves at parse time and does not need synchronized, and adds end-to-end coverage that slices a two-filament print and checks the emitted wipe tower G-code on both a Klipper and a non-Klipper flavor. No change to any other firmware flavor's output, and no shipped profile sets a non-zero delay, so no shipped profile's output moves either.
This commit is contained in:
@@ -622,6 +622,13 @@ const char* flush_planner_queue_command(GCodeFlavor flavor)
|
||||
return flavor == gcfKlipper ? "M400\n" : "G4 S0\n";
|
||||
}
|
||||
|
||||
std::string wait_command(GCodeFlavor flavor, float seconds)
|
||||
{
|
||||
if (flavor == gcfKlipper)
|
||||
return "G4 P" + std::to_string(std::lround(seconds * 1000.f)) + "\n";
|
||||
return "G4 S" + Slic3r::float_to_string_decimal_point(seconds, 3) + "\n";
|
||||
}
|
||||
|
||||
class WipeTowerWriter
|
||||
{
|
||||
public:
|
||||
@@ -1150,7 +1157,7 @@ public:
|
||||
{
|
||||
if (time==0.f)
|
||||
return *this;
|
||||
m_gcode += "G4 S" + Slic3r::float_to_string_decimal_point(time, 3) + "\n";
|
||||
m_gcode += wait_command(m_gcode_flavor, time);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,17 @@ enum GCodeFlavor : unsigned char;
|
||||
Polylines construct_gap_for_skip_points(
|
||||
const Polygon& polygon, const std::vector<Vec2f>& skip_points, float wt_width, float gap_length, Polygon& insert_skip_polygon);
|
||||
|
||||
// Returns the command that makes the firmware finish its queued moves, so a command or
|
||||
// custom-G-code boundary right after (resetting the extruder position, entering
|
||||
// [change_filament_gcode] / [filament_start_gcode]) is not reached early. Klipper acts on
|
||||
// such commands the moment it parses them, and its G4 reads only P, so the zero dwell the
|
||||
// other flavors use synchronizes nothing there — M400 does. Defined in WipeTower.cpp, shared
|
||||
// by WipeTower and WipeTower2.
|
||||
// Returns the command that makes the firmware finish its queued moves around an M104/M109
|
||||
// or custom-G-code boundary. Klipper acts on commands the instant it parses them, and its G4
|
||||
// reads only P, so the zero dwell other flavors use synchronizes nothing there — M400 does.
|
||||
// Defined in WipeTower.cpp, shared by WipeTower and WipeTower2.
|
||||
const char* flush_planner_queue_command(GCodeFlavor flavor);
|
||||
|
||||
// Returns the command that pauses for `seconds`. Klipper's G4 reads only P, in
|
||||
// milliseconds, and ignores S, so the seconds form the other flavors use would dwell zero
|
||||
// there. Defined in WipeTower.cpp, shared by WipeTower and WipeTower2.
|
||||
std::string wait_command(GCodeFlavor flavor, float seconds);
|
||||
|
||||
class WipeTower
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -636,7 +636,7 @@ public:
|
||||
{
|
||||
if (time==0.f)
|
||||
return *this;
|
||||
m_gcode += "G4 S" + Slic3r::float_to_string_decimal_point(time, 3) + "\n";
|
||||
m_gcode += wait_command(m_gcode_flavor, time);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user