Skip to content

Commit

Permalink
Add a speed knob to the wipe tower.
Browse files Browse the repository at this point in the history
The default for wipe_tower_speed is 80mm/s which was hardcoded before.
The perimeter and grid section of the wipe tower will also print at
wipe_tower_speed. Though before it was hardcoded independently at
60mm/s.

wipe_tower_wipe_starting_speed is set to 26mm/s by default. And uses the
same ramp up logic as before. Ramping up the speed of the wipe lines
with an aggressive curve, before moving linearly 0.8mm/s at a time.

wipe_tower_wipe_starting_speed can be turned of by setting to 0.

The wipe_tower_speed is capped by the filament_max_volumetric_speed.
If filament_max_volumetric_speed is not set (0 value), then there is no
cap.

I personally only set a filament_max_volumetric_speed on stuff like very
flexible TPU and what not. For the rest, I depend on the global
volumetric speed limit. This way, I can set the wipe tower speed to
exceed my normal printing flow rate since quality of the wipe tower
doesn't matter. But a low flow rate filament would still be capped by
filament_max_volumetric_speed, preventing a mess.
  • Loading branch information
bombela committed Dec 18, 2022
1 parent ec2f533 commit 3fbe811
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/libslic3r/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ class ConfigOptionVector : public ConfigOptionVectorBase
void set(const ConfigOption *rhs) override
{
if (rhs->type() != this->type())
throw ConfigurationError("ConfigOptionVector: Assigning an incompatible type");
throw ConfigurationError("ConfigOptionVector: Assigning an incompatible type");
assert(dynamic_cast<const ConfigOptionVector<T>*>(rhs));
this->values = static_cast<const ConfigOptionVector<T>*>(rhs)->values;
}
Expand Down
39 changes: 23 additions & 16 deletions src/libslic3r/GCode/WipeTower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class WipeTowerWriter
}

WipeTowerWriter& extrude_explicit(const Vec2f &dest, float e, float f = 0.f, bool record_length = false, bool limit_volumetric_flow = true)
{ return extrude_explicit(dest.x(), dest.y(), e, f, record_length); }
{ return extrude_explicit(dest.x(), dest.y(), e, f, record_length, limit_volumetric_flow); }

// Travel to a new XY position. f=0 means use the current value.
WipeTowerWriter& travel(float x, float y, float f = 0.f)
Expand Down Expand Up @@ -510,6 +510,8 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_wipe_tower_width(float(config.wipe_tower_width)),
m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)),
m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)),
m_speed(float(config.wipe_tower_speed)),
m_wipe_starting_speed(config.wipe_tower_wipe_starting_speed),
m_y_shift(0.f),
m_z_pos(0.f),
m_bridging(float(config.wipe_tower_bridging)),
Expand All @@ -519,13 +521,16 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_current_tool(initial_tool),
wipe_volumes(wiping_matrix)
{
// Wipe starting speed defaults to wipe_tower_speed.
if (m_wipe_starting_speed == 0.f) {
m_wipe_starting_speed = m_speed;
}

// Read absolute value of first layer speed, if given as percentage,
// it is taken over following default. Speeds from config are not
// easily accessible here.
const float default_speed = 60.f;
m_first_layer_speed = config.get_abs_value("first_layer_speed", default_speed);
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
m_first_layer_speed = default_speed / 2.f;
// it is taken over wipe_tower_speed.
m_first_layer_speed = config.get_abs_value("first_layer_speed", m_speed);
if (m_first_layer_speed == 0.f)
m_first_layer_speed = m_speed;

// If this is a single extruder MM printer, we will use all the SE-specific config values.
// Otherwise, the defaults will be used to turn off the SE stuff.
Expand Down Expand Up @@ -1006,11 +1011,12 @@ void WipeTower::toolchange_Wipe(
// the ordered volume, even if it means violating the box. This can later be removed and simply
// wipe until the end of the assigned area.

float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
const float x_wipe_target = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
float x_wiped = 0.f;
float dy = m_extra_spacing*m_perimeter_width;

const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : 4800.f;
float wipe_speed = 0.33f * target_speed;
const float target_speed = (is_first_layer() ? m_first_layer_speed : m_speed) * 60.f;
float wipe_speed = (m_wipe_starting_speed < target_speed ? m_wipe_starting_speed : target_speed) * 60.f;

// if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
if ((m_left_to_right ? xr-writer.x() : writer.x()-xl) < 2.5f*m_perimeter_width) {
Expand All @@ -1020,14 +1026,15 @@ void WipeTower::toolchange_Wipe(

// now the wiping itself:
for (int i = 0; true; ++i) {
if (i!=0) {
//const float wipe_speed = starting_speed + ((target_speed - starting_speed) * x_wiped / x_wipe_target);
if (i!=0) {
if (wipe_speed < 0.34f * target_speed) wipe_speed = 0.375f * target_speed;
else if (wipe_speed < 0.377 * target_speed) wipe_speed = 0.458f * target_speed;
else if (wipe_speed < 0.46f * target_speed) wipe_speed = 0.875f * target_speed;
else wipe_speed = std::min(target_speed, wipe_speed + 50.f);
}

float traversed_x = writer.x();
const float x_start = writer.x();
if (m_left_to_right)
writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5f*m_perimeter_width), writer.y(), wipe_speed);
else
Expand All @@ -1036,9 +1043,9 @@ void WipeTower::toolchange_Wipe(
if (writer.y()+float(EPSILON) > cleaning_box.lu.y()-0.5f*m_perimeter_width)
break; // in case next line would not fit

traversed_x -= writer.x();
x_to_wipe -= std::abs(traversed_x);
if (x_to_wipe < WT_EPSILON) {
const float traversed_x = x_start - writer.x();
x_wiped += std::abs(traversed_x);
if ((x_wiped + WT_EPSILON) >= x_wipe_target) {
writer.travel(m_left_to_right ? xl + 1.5f*m_perimeter_width : xr - 1.5f*m_perimeter_width, writer.y(), 7200);
break;
}
Expand Down Expand Up @@ -1078,7 +1085,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()

// Slow down on the 1st layer.
bool first_layer = is_first_layer();
float feedrate = first_layer ? m_first_layer_speed * 60.f : 2900.f;
float feedrate = first_layer ? m_first_layer_speed * 60.f : m_speed * 60.f;
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
box_coordinates fill_box(Vec2f(m_perimeter_width, m_layer_info->depth-(current_depth-m_perimeter_width)),
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
Expand Down
4 changes: 3 additions & 1 deletion src/libslic3r/GCode/WipeTower.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,10 @@ class WipeTower
size_t m_max_color_changes = 0; // Maximum number of color changes per layer.
int m_old_temperature = -1; // To keep track of what was the last temp that we set (so we don't issue the command when not neccessary)
float m_travel_speed = 0.f;
float m_first_layer_speed = 0.f;
float m_first_layer_speed = 0.f; // First layer speed in mm/s.
size_t m_first_layer_idx = size_t(-1);
float m_speed = 0.f; // Wipe tower speed in mm/s.
float m_wipe_starting_speed = 0.f; // Starting speed during wipe, up to m_speed.

// G-code generator parameters.
float m_cooling_tube_retraction = 0.f;
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static std::vector<std::string> s_Preset_print_options {
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "wipe_tower_speed", "wipe_tower_wipe_starting_speed", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width"
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "wipe_tower_brim_width"
|| opt_key == "wipe_tower_bridging"
|| opt_key == "wipe_tower_no_sparse_layers"
|| opt_key == "wipe_tower_speed"
|| opt_key == "wipe_tower_wipe_starting_speed"
|| opt_key == "wiping_volumes_matrix"
|| opt_key == "parking_pos_retraction"
|| opt_key == "cooling_tube_retraction"
Expand Down
14 changes: 14 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3042,6 +3042,20 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(10.));

def = this->add("wipe_tower_speed", coFloat);
def->label = L("Speed");
def->tooltip = L("Printing speed of the wipe tower. Capped by filament_max_volumetric_speed (if set).");
def->sidetext = L("mm/s");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(80.));

def = this->add("wipe_tower_wipe_starting_speed", coFloat);
def->label = L("Wipe starting speed");
def->tooltip = L("Start of the wiping speed ramp up. Set to 0 to disable.");
def->sidetext = L("mm/s");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(26.));

def = this->add("xy_size_compensation", coFloat);
def->label = L("XY Size Compensation");
def->category = L("Advanced");
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, wipe_tower_rotation_angle))
((ConfigOptionFloat, wipe_tower_brim_width))
((ConfigOptionFloat, wipe_tower_bridging))
((ConfigOptionFloat, wipe_tower_speed))
((ConfigOptionFloat, wipe_tower_wipe_starting_speed))
((ConfigOptionFloats, wiping_volumes_matrix))
((ConfigOptionFloats, wiping_volumes_extruders))
((ConfigOptionFloat, z_offset))
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)

bool have_wipe_tower = config->opt_bool("wipe_tower");
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width",
"wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" })
"wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming", "wipe_tower_speed", "wipe_tower_wipe_starting_speed"})
toggle_field(el, have_wipe_tower);

bool have_avoid_crossing_perimeters = config->opt_bool("avoid_crossing_perimeters");
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/Plater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2004,7 +2004,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
"bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance",
"brim_width", "brim_separation", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material",
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width",
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_speed", "wipe_tower_wipe_starting_speed",
"extruder_colour", "filament_colour", "material_colour", "max_print_height", "printer_model", "printer_technology",
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
Expand Down
2 changes: 2 additions & 0 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,8 @@ void TabPrint::build()
optgroup->append_single_option_line("wipe_tower_bridging");
optgroup->append_single_option_line("wipe_tower_no_sparse_layers");
optgroup->append_single_option_line("single_extruder_multi_material_priming");
optgroup->append_single_option_line("wipe_tower_speed");
optgroup->append_single_option_line("wipe_tower_wipe_starting_speed");

optgroup = page->new_optgroup(L("Advanced"));
optgroup->append_single_option_line("interface_shells");
Expand Down

0 comments on commit 3fbe811

Please sign in to comment.