ENH: add grab length

1.During the filament change, the extruder will extrude an extra length
of grap_length for the corresponding detection, so the purge volume can
reduce this length.

jira:NEW

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I14f55a3200c1dd48b1603e50280d0c29e1319ebe
(cherry picked from commit 16cadec565f987e6baae97428d5392c1f8e7ad39)
This commit is contained in:
xun.zhang
2025-08-24 23:18:07 +08:00
committed by Noisyfox
parent 78e7821041
commit cc4c03d76f
6 changed files with 63 additions and 95 deletions
@@ -20,6 +20,9 @@
"0x0" "0x0"
], ],
"gcode_flavor": "marlin", "gcode_flavor": "marlin",
"grab_length" : [
"0"
],
"silent_mode": "0", "silent_mode": "0",
"long_retractions_when_cut": [ "long_retractions_when_cut": [
"0" "0"
+3
View File
@@ -6480,6 +6480,8 @@ std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool b
old_retract_length = m_config.retraction_length.get_at(previous_extruder_id); old_retract_length = m_config.retraction_length.get_at(previous_extruder_id);
old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(previous_extruder_id); old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(previous_extruder_id);
old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(previous_filament_id) : m_config.nozzle_temperature.get_at(previous_filament_id); old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(previous_filament_id) : m_config.nozzle_temperature.get_at(previous_filament_id);
//During the filament change, the extruder will extrude an extra length of grab_length for the corresponding detection, so the purge can reduce this length.
float grab_purge_volume = m_config.grab_length.get_at(extruder_id) * 2.4;
if (previous_extruder_id != extruder_id) { if (previous_extruder_id != extruder_id) {
//calc flush volume between the same extruder id //calc flush volume between the same extruder id
int previous_filament_id_in_new_extruder = m_writer.filament(extruder_id) != nullptr ? m_writer.filament(extruder_id)->id() : -1; int previous_filament_id_in_new_extruder = m_writer.filament(extruder_id) != nullptr ? m_writer.filament(extruder_id)->id() : -1;
@@ -6494,6 +6496,7 @@ std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool b
wipe_volume = flush_matrix[previous_filament_id * number_of_extruders + filament_id]; wipe_volume = flush_matrix[previous_filament_id * number_of_extruders + filament_id];
wipe_volume *= m_config.flush_multiplier.get_at(extruder_id); // if is multi_extruder only use the fist extruder matrix wipe_volume *= m_config.flush_multiplier.get_at(extruder_id); // if is multi_extruder only use the fist extruder matrix
} }
wipe_volume = std::max(0.f, wipe_volume-grab_purge_volume);
old_filament_e_feedrate = (int) (60.0 * m_config.filament_max_volumetric_speed.get_at(previous_filament_id) / filament_area); old_filament_e_feedrate = (int) (60.0 * m_config.filament_max_volumetric_speed.get_at(previous_filament_id) / filament_area);
old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate; old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate;
+1
View File
@@ -909,6 +909,7 @@ static std::vector<std::string> s_Preset_printer_options {
"printhost_cafile","printhost_port","printhost_authorization_type", "printhost_cafile","printhost_port","printhost_authorization_type",
"printhost_user", "printhost_password", "printhost_ssl_ignore_revoke", "thumbnails", "thumbnails_format", "printhost_user", "printhost_password", "printhost_ssl_ignore_revoke", "thumbnails", "thumbnails_format",
"use_firmware_retraction", "use_relative_e_distances", "printer_notes", "use_firmware_retraction", "use_relative_e_distances", "printer_notes",
"grab_length",
"cooling_tube_retraction", "cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "purge_in_prime_tower", "enable_filament_ramming", "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "purge_in_prime_tower", "enable_filament_ramming",
"z_offset", "z_offset",
+6 -53
View File
@@ -206,7 +206,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"long_retractions_when_cut", "long_retractions_when_cut",
"retraction_distances_when_cut", "retraction_distances_when_cut",
"filament_long_retractions_when_cut", "filament_long_retractions_when_cut",
"filament_retraction_distances_when_cut" "filament_retraction_distances_when_cut",
"grab_length"
}; };
static std::unordered_set<std::string> steps_ignore; static std::unordered_set<std::string> steps_ignore;
@@ -2762,7 +2763,6 @@ void Print::_make_wipe_tower()
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>: // Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
bool is_mutli_extruder = m_config.nozzle_diameter.values.size() > 1; bool is_mutli_extruder = m_config.nozzle_diameter.values.size() > 1;
size_t nozzle_nums = m_config.nozzle_diameter.values.size(); size_t nozzle_nums = m_config.nozzle_diameter.values.size();
if (is_mutli_extruder) {
using FlushMatrix = std::vector<std::vector<float>>; using FlushMatrix = std::vector<std::vector<float>>;
std::vector<FlushMatrix> multi_extruder_flush; std::vector<FlushMatrix> multi_extruder_flush;
for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) { for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) {
@@ -2801,6 +2801,10 @@ void Print::_make_wipe_tower()
layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_filament_id, filament_id, volume_to_purge); layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_filament_id, filament_id, volume_to_purge);
} }
//During the filament change, the extruder will extrude an extra length of grab_length for the corresponding detection, so the purge can reduce this length.
float grab_purge_volume = m_config.grab_length.get_at(nozzle_id) * 2.4; //(diameter/2)^2*PI=2.4
volume_to_purge = std::max(0.f, volume_to_purge - grab_purge_volume);
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id, wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id,
m_config.prime_volume, volume_to_purge); m_config.prime_volume, volume_to_purge);
current_filament_id = filament_id; current_filament_id = filament_id;
@@ -2818,57 +2822,6 @@ void Print::_make_wipe_tower()
break; break;
} }
} }
else {
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(m_config.flush_volumes_matrix.values, 0, nozzle_nums)));
// Extract purging volumes for each extruder pair:
std::vector<std::vector<float>> wipe_volumes;
for (unsigned int i = 0; i < number_of_extruders; ++i)
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
// BBS: priming logic is removed, so get the initial extruder by first_extruder()
unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.first_extruder();
for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
if (!layer_tools.has_wipe_tower) continue;
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id);
for (const auto extruder_id : layer_tools.extruders) {
// BBS: priming logic is removed, so no need to do toolchange for first extruder
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {
float volume_to_purge = wipe_volumes[current_extruder_id][extruder_id];
volume_to_purge *= m_config.flush_multiplier.get_at(0);
// Not all of that can be used for infill purging:
//volume_to_purge -= (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
// try to assign some infills/objects for the wiping:
volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_purge);
// add back the minimal amount toforce on the wipe tower:
//volume_to_purge += (float)m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height,
current_extruder_id, extruder_id, m_config.prime_volume, volume_to_purge);
current_extruder_id = extruder_id;
}
}
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
// if enable timelapse, slice all layer
if (enable_timelapse_print()) {
if (layer_tools.wipe_tower_partitions == 0)
wipe_tower.set_last_layer_extruder_fill(false);
continue;
}
if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0)
break;
}
}
}
// Generate the wipe tower layers. // Generate the wipe tower layers.
m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size()); m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
+7
View File
@@ -1922,6 +1922,13 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0)); def->set_default_value(new ConfigOptionFloat(0));
def = this->add("grab_length",coFloats);
def->label = L("Grab length");
def->sidetext = L("mm");
def->min = 0;
def->mode = comDevelop;
def->set_default_value(new ConfigOptionFloats({0}));
def = this->add("extruder_colour", coStrings); def = this->add("extruder_colour", coStrings);
def->label = L("Extruder Color"); def->label = L("Extruder Color");
def->tooltip = L("Only used as a visual help on UI."); def->tooltip = L("Only used as a visual help on UI.");
+1
View File
@@ -1455,6 +1455,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionPercents, filament_shrinkage_compensation_z)) ((ConfigOptionPercents, filament_shrinkage_compensation_z))
((ConfigOptionBool, gcode_label_objects)) ((ConfigOptionBool, gcode_label_objects))
((ConfigOptionBool, exclude_object)) ((ConfigOptionBool, exclude_object))
((ConfigOptionFloats, grab_length))
((ConfigOptionBool, gcode_comments)) ((ConfigOptionBool, gcode_comments))
((ConfigOptionInt, slow_down_layers)) ((ConfigOptionInt, slow_down_layers))
((ConfigOptionInts, support_material_interface_fan_speed)) ((ConfigOptionInts, support_material_interface_fan_speed))