Updated wipe logic to respect retraction speed during wiping (#3094)

* Wipe retraction adjusted based on available wipe distance and retraction speed

* Wipe Improvements: Removed debug code, removed retract before wipe and made the respect retract speed an option.

* Wipe improvements: Spelling & grammar

* Revert "Wipe improvements: Spelling & grammar"

This reverts commit c8f8612b3f.

* Revert "Wipe Improvements: Removed debug code, removed retract before wipe and made the respect retract speed an option."

This reverts commit ba515ffb62.

* Wipe improvements: Using retraction before wipe parameter to judge when to do excess retraction

* Wipe Improvements: Floating point comparison check

* Wipe Improvements: Refactoring the code

* Wipe Improvements: Updated Wipe Distance tool tip

* Wipe Improvements: Removed redundant code

* Wipe Improvements: Use unscale_
This commit is contained in:
Ioannis Giannakas 2023-12-16 13:54:03 +00:00 committed by GitHub
parent 7b6dbfdbcc
commit 712c28251c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 19 deletions

View file

@ -295,7 +295,65 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
: gcodegen.config().nozzle_temperature.get_at(gcodegen.writer().extruder()->id());
}
std::string Wipe::wipe(GCode& gcodegen, bool toolchange, bool is_last)
// Ioannis Giannakas:
// Function to calculate the excess retraction length that should be retracted either before or after wiping
// in order for the wipe operation to respect the filament retraction speed
Wipe::RetractionValues Wipe::calculateWipeRetractionLengths(GCode& gcodegen, bool toolchange) {
auto& writer = gcodegen.writer();
auto& config = gcodegen.config();
auto extruder = writer.extruder();
auto extruder_id = extruder->id();
auto last_pos = gcodegen.last_pos();
// Declare & initialize retraction lengths
double retraction_length_remaining = 0,
retractionBeforeWipe = 0,
retractionDuringWipe = 0;
// initialise the remaining retraction amount with the full retraction amount.
retraction_length_remaining = toolchange ? extruder->retract_length_toolchange() : extruder->retraction_length();
// nothing to retract - return early
if(retraction_length_remaining <=EPSILON) return {0.f,0.f};
// calculate retraction before wipe distance from the user setting. Keep adding to this variable any excess retraction needed
// to be performed before the wipe.
retractionBeforeWipe = retraction_length_remaining * extruder->retract_before_wipe();
retraction_length_remaining -= retractionBeforeWipe; // subtract it from the remaining retraction length
// all of the retraction is to be done before the wipe
if(retraction_length_remaining <=EPSILON) return {retractionBeforeWipe,0.f};
// Calculate wipe speed
double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed");
wipe_speed = std::max(wipe_speed, 10.0);
// Process wipe path & calculate wipe path length
double wipe_dist = scale_(config.wipe_distance.get_at(extruder_id));
Polyline wipe_path = {last_pos};
wipe_path.append(this->path.points.begin() + 1, this->path.points.end());
double wipe_path_length = std::min(wipe_path.length(), wipe_dist);
// Calculate the maximum retraction amount during wipe
retractionDuringWipe = config.retraction_speed.get_at(extruder_id) * unscale_(wipe_path_length) / wipe_speed;
// If the maximum retraction amount during wipe is too small, return 0 and retract everything prior to the wipe.
if(retractionDuringWipe <= EPSILON) return {retractionBeforeWipe,0.f};
// If the maximum retraction amount during wipe is greater than any remaining retraction length
// return the remaining retraction length to be retracted during the wipe
if (retractionDuringWipe - retraction_length_remaining > EPSILON) return {retractionBeforeWipe,retraction_length_remaining};
// If the user has requested any retract before wipe, proceed with incrementing the retraction amount before wiping with the difference
// and return the maximum allowed wipe amount to be retracted during the wipe move
// If the user has not requested any retract before wipe, the retraction amount before wiping should not be incremented and left to the parent
// function to retract after wipe is done.
if(gcodegen.config().retract_before_wipe.get_at(gcodegen.writer().extruder()->id()) > EPSILON){
retractionBeforeWipe += retraction_length_remaining - retractionDuringWipe;
}
return {retractionBeforeWipe, retractionDuringWipe};
}
std::string Wipe::wipe(GCode& gcodegen,double length, bool toolchange, bool is_last)
{
std::string gcode;
@ -307,12 +365,6 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
if(_wipe_speed < 10)
_wipe_speed = 10;
// get the retraction length
double length = toolchange
? gcodegen.writer().extruder()->retract_length_toolchange()
: gcodegen.writer().extruder()->retraction_length();
// Shorten the retraction length by the amount already retracted before wipe.
length *= (1. - gcodegen.writer().extruder()->retract_before_wipe());
//SoftFever: allow 100% retract before wipe
if (length >= 0)
@ -322,7 +374,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
for the time needed to consume retraction_length at retraction_speed? */
// BBS
double wipe_dist = scale_(gcodegen.config().wipe_distance.get_at(gcodegen.writer().extruder()->id()));
/* Take the stored wipe path and replace first point with the current actual position
(they might be different, for example, in case of loop clipping). */
Polyline wipe_path;
@ -346,7 +398,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
// add tag for processor
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Start) + "\n";
//BBS: don't need to enable cooling makers when this is the last wipe. Because no more cooling layer will clean this "_WIPE"
//Softfever:
//Softfever:
std::string cooling_mark = "";
if (gcodegen.enable_cooling_markers() && !is_last)
cooling_mark = /*gcodegen.config().role_based_wipe_speed ? ";_EXTERNAL_PERIMETER" : */";_WIPE";
@ -5463,8 +5515,9 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
// wipe (if it's enabled for this extruder and we have a stored wipe path and no-zero wipe distance)
if (EXTRUDER_CONFIG(wipe) && m_wipe.has_path() && scale_(EXTRUDER_CONFIG(wipe_distance)) > SCALED_EPSILON) {
gcode += toolchange ? m_writer.retract_for_toolchange(true) : m_writer.retract(true);
gcode += m_wipe.wipe(*this, toolchange, is_last_retraction);
Wipe::RetractionValues wipeRetractions = m_wipe.calculateWipeRetractionLengths(*this, toolchange);
gcode += toolchange ? m_writer.retract_for_toolchange(true,wipeRetractions.retractLengthBeforeWipe) : m_writer.retract(true, wipeRetractions.retractLengthBeforeWipe);
gcode += m_wipe.wipe(*this,wipeRetractions.retractLengthDuringWipe, toolchange, is_last_retraction);
}
/* The parent class will decide whether we need to perform an actual retraction

View file

@ -55,11 +55,16 @@ class Wipe {
public:
bool enable;
Polyline path;
struct RetractionValues{
double retractLengthBeforeWipe;
double retractLengthDuringWipe;
};
Wipe() : enable(false) {}
bool has_path() const { return !this->path.points.empty(); }
void reset_path() { this->path = Polyline(); }
std::string wipe(GCode &gcodegen, bool toolchange = false, bool is_last = false);
std::string wipe(GCode &gcodegen, double length, bool toolchange = false, bool is_last = false);
RetractionValues calculateWipeRetractionLengths(GCode& gcodegen, bool toolchange);
};
class WipeTowerIntegration {

View file

@ -682,23 +682,23 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std
return w.string();
}
std::string GCodeWriter::retract(bool before_wipe)
std::string GCodeWriter::retract(bool before_wipe, double retract_length)
{
double factor = before_wipe ? m_extruder->retract_before_wipe() : 1.;
assert(factor >= 0. && factor <= 1. + EPSILON);
return this->_retract(
factor * m_extruder->retraction_length(),
retract_length > EPSILON ? retract_length : factor * m_extruder->retraction_length(),
factor * m_extruder->retract_restart_extra(),
"retract"
);
}
std::string GCodeWriter::retract_for_toolchange(bool before_wipe)
std::string GCodeWriter::retract_for_toolchange(bool before_wipe, double retract_length)
{
double factor = before_wipe ? m_extruder->retract_before_wipe() : 1.;
assert(factor >= 0. && factor <= 1. + EPSILON);
return this->_retract(
factor * m_extruder->retract_length_toolchange(),
retract_length > EPSILON ? retract_length : factor * m_extruder->retract_length_toolchange(),
factor * m_extruder->retract_restart_extra_toolchange(),
"retract for toolchange"
);

View file

@ -74,8 +74,8 @@ public:
//BBS: generate G2 or G3 extrude which moves by arc
std::string extrude_arc_to_xy(const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment = std::string(), bool force_no_extrusion = false);
std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false);
std::string retract(bool before_wipe = false);
std::string retract_for_toolchange(bool before_wipe = false);
std::string retract(bool before_wipe = false, double retract_length = 0);
std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0);
std::string unretract();
std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
std::string unlift();

View file

@ -4183,7 +4183,7 @@ def = this->add("filament_loading_speed", coFloats);
def = this->add("wipe_distance", coFloats);
def->label = L("Wipe Distance");
def->tooltip = L("Discribe how long the nozzle will move along the last path when retracting");
def->tooltip = L("Discribe how long the nozzle will move along the last path when retracting. \n\nDepending on how long the wipe operation lasts, how fast and long the extruder/filament retraction settings are, a retraction move may be needed to retract the remaining filament. \n\nSetting a value in the retract amount before wipe setting below will perform any excess retraction before the wipe, else it will be performed after.");
def->sidetext = L("mm");
def->min = 0;
def->mode = comAdvanced;