Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental feature to enable pulsatile purging in the wipe tower, aiming to improve purging efficiency #6363

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions src/libslic3r/GCode/WipeTower2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,12 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
m_perimeter_speed(default_region_config.inner_wall_speed),
m_current_tool(initial_tool),
wipe_volumes(wiping_matrix),
m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed))
m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
m_wipe_tower_pulsatile_purge(float(config.wipe_tower_pulsatile_purge)),
m_wipe_tower_pulse_low_speed(float(config.wipe_tower_pulse_low_speed)),
m_wipe_tower_pulse_high_speed(float(config.wipe_tower_pulse_high_speed)),
m_wipe_tower_retraction_distance(float(config.wipe_tower_retraction_distance)),
m_wipe_tower_retraction_speed(float(config.wipe_tower_retraction_speed))
{
// Read absolute value of first layer speed, if given as percentage,
// it is taken over following default. Speeds from config are not
Expand Down Expand Up @@ -827,7 +832,9 @@ WipeTower::ToolChangeResult WipeTower2::tool_change(size_t tool)
writer.speed_override_backup();
writer.speed_override(100);

Vec2f initial_position = cleaning_box.ld + Vec2f(0.f, m_depth_traversed);
// Orca: Pulsatile purge - toolchange slightly out from the purge tower perimeter to reduce blobbing on the purge tower
Vec2f initial_position = m_wipe_tower_pulsatile_purge ? cleaning_box.ld + Vec2f(-m_perimeter_width*2, m_depth_traversed) :
cleaning_box.ld + Vec2f(0.f, m_depth_traversed);
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);

// Increase the extruder driver current to allow fast ramming.
Expand Down Expand Up @@ -1195,10 +1202,31 @@ void WipeTower2::toolchange_Wipe(
}

float traversed_x = writer.x();
if (m_left_to_right)
writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5f*line_width), writer.y(), wipe_speed);
else
writer.extrude(xl + (i % 4 == 1 ? 0 : 1.5f*line_width), writer.y(), wipe_speed);
bool deretract = false; // Orca: Pulsatile purge deretraction flag
if(!m_wipe_tower_pulsatile_purge || is_first_layer()){ // Orca: Regular purging
if (m_left_to_right)
writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5f*line_width), writer.y(), wipe_speed);
else
writer.extrude(xl + (i % 4 == 1 ? 0 : 1.5f*line_width), writer.y(), wipe_speed);
}else{ // ORCA: Pusatile purging
if (m_left_to_right){
if(i % 3 == 0 && i != 0){ // print every third left to right extrusion slowly, followed by a retraction and de-retraction to dislodge stuck filament in the nozzle walls
writer.extrude(xr - (i % 4 == 0 ? line_width : 1.5f*line_width), writer.y(), m_wipe_tower_pulse_low_speed * 60.); // print slowly with low filament flow to allow for any "stuck" filament to the nozzle walls to move
// Check wipe tower ending before applying retraction
bool will_break_due_to_y = (writer.y() + float(EPSILON) > cleaning_box.lu.y() - 0.5f * line_width);
bool will_break_due_to_x = (x_to_wipe - std::abs(traversed_x - writer.x()) < WT_EPSILON);
if (!(will_break_due_to_y || will_break_due_to_x)) {
// Perform retraction only if wipe tower will continue to a next X line
writer.retract(m_wipe_tower_retraction_distance, m_wipe_tower_retraction_speed * 60.);
deretract = true;
}
} else {
writer.extrude(xr - (i % 4 == 0 ? 0.25*line_width : 1.5f*line_width), writer.y(), m_wipe_tower_pulse_high_speed * 60.); // change ancorning point to reduce collisions
}
} else {
writer.extrude(xl + (i % 4 == 1 ? 0.25*line_width : 1.5f*line_width), writer.y(), m_wipe_tower_pulse_high_speed * 60.); // change ancorning point to reduce collisions
}
}

if (writer.y()+float(EPSILON) > cleaning_box.lu.y()-0.5f*line_width)
break; // in case next line would not fit
Expand All @@ -1210,7 +1238,12 @@ void WipeTower2::toolchange_Wipe(
break;
}
// stepping to the next line:
writer.extrude(writer.x() + (i % 4 == 0 ? -1.f : (i % 4 == 1 ? 1.f : 0.f)) * 1.5f*line_width, writer.y() + dy);
if(deretract){ // ORCA: Pusatile flushing deretraction move
writer.travel(writer.x() + (i % 4 == 0 ? -1.f : (i % 4 == 1 ? 1.f : 0.f)) * 1.5f*line_width, writer.y() + dy);
writer.retract(-m_wipe_tower_retraction_distance,5*60.); // deretract slowly to ramp up pressure and allow the filament to flow through again without shearing off the nozzle walls
}else{ // Orca: regular purging move
writer.extrude(writer.x() + (i % 4 == 0 ? -1.f : (i % 4 == 1 ? 1.f : 0.f)) * 1.5f*line_width, writer.y() + dy);
}
m_left_to_right = !m_left_to_right;
}

Expand Down
7 changes: 7 additions & 0 deletions src/libslic3r/GCode/WipeTower2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ class WipeTower2
float m_travel_speed = 0.f;
float m_infill_speed = 0.f;
float m_wipe_tower_max_purge_speed = 90.f;
// Orca: pulsatile purging
bool m_wipe_tower_pulsatile_purge = false;
float m_wipe_tower_pulse_low_speed = 30.f;
float m_wipe_tower_pulse_high_speed = 150.f;
float m_wipe_tower_retraction_distance = 2.f;
float m_wipe_tower_retraction_speed = 30.f;
// Orca: pulsatile purging end
float m_perimeter_speed = 0.f;
float m_first_layer_speed = 0.f;
size_t m_first_layer_idx = size_t(-1);
Expand Down
4 changes: 3 additions & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,9 @@ static std::vector<std::string> s_Preset_print_options {
"initial_layer_travel_speed", "exclude_object", "slow_down_layers", "infill_anchor", "infill_anchor_max","initial_layer_min_bead_width",
"make_overhang_printable", "make_overhang_printable_angle", "make_overhang_printable_hole_size" ,"notes",
"wipe_tower_cone_angle", "wipe_tower_extra_spacing","wipe_tower_max_purge_speed", "wipe_tower_filament", "wiping_volumes_extruders","wipe_tower_bridging", "wipe_tower_extra_flow","single_extruder_multi_material_priming",
"wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic",
"wipe_tower_rotation_angle",
"wipe_tower_pulsatile_purge","wipe_tower_retraction_speed","wipe_tower_pulse_low_speed","wipe_tower_pulse_high_speed","wipe_tower_retraction_distance", // Orca: Pulsatile purging
"tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic",
"hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth",
"small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model",
"seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", "scarf_overhang_threshold",
Expand Down
5 changes: 5 additions & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "wipe_tower_cone_angle"
|| opt_key == "wipe_tower_extra_spacing"
|| opt_key == "wipe_tower_max_purge_speed"
|| opt_key == "wipe_tower_pulsatile_purge" // Orca: Pulsatile purging
|| opt_key == "wipe_tower_pulse_low_speed"
|| opt_key == "wipe_tower_pulse_high_speed"
|| opt_key == "wipe_tower_retraction_distance"
|| opt_key == "wipe_tower_retraction_speed" // Orca: Pulsatile purging
|| opt_key == "wipe_tower_filament"
|| opt_key == "wiping_volumes_extruders"
|| opt_key == "enable_filament_ramming"
Expand Down
45 changes: 45 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5171,6 +5171,51 @@ void PrintConfigDef::init_fff_params()
def->min = 0;
def->max = max_temp;
def->set_default_value(new ConfigOptionInts{0});

// Orca: Pulsatile purging
def = this->add("wipe_tower_pulsatile_purge", coBool);
def->label = L("Enable pulsatile purging");
def->tooltip = L("Use the pulsatile flushing technique when purging in the purge tower. This technique aims to reduce the purging volume needed to perform a color transition, "
"by forcing turbulent flow inside the nozzle causing the filament residue to unstick from the nozzle tube surfaces. This feature is particularly helpful "
"for CHT type nozzles as, due to their increased internal surface, more material tends to cling on, hence, need more material to be purged for a thorough "
"color change. Set the below parameters to appropriate values for your setup.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));

def = this->add("wipe_tower_pulse_low_speed", coFloat);
def->label = L("Purge speed - low");
def->tooltip = L("The minimum print speed (hence flow) when printing the wipe tower sparse layers during purging.");
def->sidetext = L("mm/s");
def->mode = comAdvanced;
def->min = 10;
def->set_default_value(new ConfigOptionFloat(50.));

def = this->add("wipe_tower_pulse_high_speed", coFloat);
def->label = L("Purge speed - high");
def->tooltip = L("The maximum print speed (hence flow) when printing the wipe tower sparse layers during purging. This speed is constrained by the maximum volumetric flow rate "
"set for the filament.");
def->sidetext = L("mm/s");
def->mode = comAdvanced;
def->min = 10;
def->set_default_value(new ConfigOptionFloat(200.));

def = this->add("wipe_tower_retraction_distance", coFloat);
def->label = L("Retraction distance");
def->tooltip = L("The retraction distance used to pulse the filament with during purging.");
def->sidetext = L("mm");
def->mode = comAdvanced;
def->min = 0.1;
def->set_default_value(new ConfigOptionFloat(4.));

def = this->add("wipe_tower_retraction_speed", coFloat);
def->label = L("Retraction speed");
def->tooltip = L("The retraction speed used to pulse the filament with during purging. This is used to create turbulance in the nozzle before slowly de-retracting at a fixed "
"5mm/sec speeed and continuing with the purge cycle.");
def->sidetext = L("mm/s");
def->mode = comAdvanced;
def->min = 10;
def->set_default_value(new ConfigOptionFloat(60.));
// Orca: Pulsatile purging

def = this->add("xy_hole_compensation", coFloat);
def->label = L("X-Y hole compensation");
Expand Down
7 changes: 7 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,13 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionInt, wipe_tower_filament))
((ConfigOptionFloats, wiping_volumes_extruders))
((ConfigOptionInts, idle_temperature))

// ORCA: Pulsatile purging
((ConfigOptionBool, wipe_tower_pulsatile_purge))
((ConfigOptionFloat, wipe_tower_pulse_low_speed))
((ConfigOptionFloat, wipe_tower_pulse_high_speed))
((ConfigOptionFloat, wipe_tower_retraction_distance))
((ConfigOptionFloat, wipe_tower_retraction_speed))


// BBS: wipe tower is only used for priming
Expand Down
8 changes: 7 additions & 1 deletion src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,13 +676,19 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
for (auto el : {"wipe_tower_rotation_angle", "wipe_tower_cone_angle",
"wipe_tower_extra_spacing", "wipe_tower_max_purge_speed",
"wipe_tower_bridging", "wipe_tower_extra_flow",
"wipe_tower_no_sparse_layers"})
"wipe_tower_no_sparse_layers",
"wipe_tower_pulsatile_purge"}) // ORCA: Pulsatile purging

toggle_line(el, have_prime_tower && !is_BBL_Printer);

toggle_line("single_extruder_multi_material_priming", !bSEMM && have_prime_tower && !is_BBL_Printer);

toggle_line("prime_volume",have_prime_tower && (!purge_in_primetower || !bSEMM));

bool pulsatile_purge = config->opt_bool("wipe_tower_pulsatile_purge");
for (auto el : {"wipe_tower_pulse_low_speed","wipe_tower_pulse_high_speed","wipe_tower_retraction_distance","wipe_tower_retraction_speed"})
toggle_line(el, have_prime_tower && !is_BBL_Printer && pulsatile_purge);

for (auto el : {"flush_into_infill", "flush_into_support", "flush_into_objects"})
toggle_field(el, have_prime_tower);

Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/Plater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
"enable_support", "support_filament", "support_interface_filament",
"support_top_z_distance", "support_bottom_z_distance", "raft_layers",
"wipe_tower_rotation_angle", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extra_flow", "wipe_tower_max_purge_speed", "wipe_tower_filament",
"wipe_tower_pulsatile_purge","wipe_tower_pulse_low_speed","wipe_tower_pulse_high_speed","wipe_tower_retraction_distance","wipe_tower_retraction_speed",
"best_object_pos"
}))
, sidebar(new Sidebar(q))
Expand Down
9 changes: 9 additions & 0 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2284,6 +2284,15 @@ void TabPrint::build()
optgroup->append_single_option_line("wipe_tower_max_purge_speed");
optgroup->append_single_option_line("wipe_tower_no_sparse_layers");
optgroup->append_single_option_line("single_extruder_multi_material_priming");
// Orca: pulsatile purging
optgroup->append_single_option_line("wipe_tower_pulsatile_purge");

optgroup = page->new_optgroup(L("Pulsatile purging"), L"param_tower");
optgroup->append_single_option_line("wipe_tower_pulse_low_speed");
optgroup->append_single_option_line("wipe_tower_pulse_high_speed");
optgroup->append_single_option_line("wipe_tower_retraction_distance");
optgroup->append_single_option_line("wipe_tower_retraction_speed");
// Orca: pulsatile purging end

optgroup = page->new_optgroup(L("Filament for Features"));
optgroup->append_single_option_line("wall_filament");
Expand Down