ENH: calib support multi_extruder

1. backend support multi_extrude data structure
2. Compatible with third-party calibration
3. fix bug when get extruder in gocde export process

Change-Id: I5dac9abdd9907a521a1ba9b480f9e05640591bc1
This commit is contained in:
zhimin.zeng 2024-07-08 17:32:49 +08:00 committed by lane.wei
parent 0924fce685
commit 21e6271e59
12 changed files with 159 additions and 71 deletions

View File

@ -6,13 +6,12 @@
namespace Slic3r {
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int extruder_id, int filament_idx)
{
const double general_suggested_min_speed = 100.0;
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(filament_idx);
// todo multi_extruders:
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0/*get_extruder_index(filament_idx)*/));
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(0/*get_extruder_index(filament_idx)*/)),
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(extruder_id));
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(extruder_id)),
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
return std::floor(pa_speed);

View File

@ -35,6 +35,7 @@ enum class CalibState {
struct Calib_Params
{
Calib_Params() : mode(CalibMode::Calib_None){}
int extruder_id = 0;
double start, end, step;
bool print_numbers = false;
CalibMode mode;
@ -50,8 +51,12 @@ class X1CCalibInfos
public:
struct X1CCalibInfo
{
int extruder_id = -1;
int tray_id;
int ams_id = 0;
int slot_id = 0;
int bed_temp;
NozzleVolumeType nozzle_volume_type = NozzleVolumeType::nvtNormal;
int nozzle_temp;
float nozzle_diameter;
std::string filament_id;
@ -100,7 +105,11 @@ public:
CALI_RESULT_PROBLEM = 1,
CALI_RESULT_FAILED = 2,
};
int tray_id;
int extruder_id = -1;
NozzleVolumeType nozzle_volume_type;
int tray_id = 0;
int ams_id = 0;
int slot_id = 0;
int cali_idx = -1;
float nozzle_diameter;
std::string filament_id;
@ -113,12 +122,31 @@ public:
struct PACalibIndexInfo
{
int tray_id;
int extruder_id = -1;
NozzleVolumeType nozzle_volume_type;
int tray_id = 0;
int ams_id = 0;
int slot_id = 0;
int cali_idx;
float nozzle_diameter;
std::string filament_id;
};
struct PACalibExtruderInfo
{
int extruder_id;
NozzleVolumeType nozzle_volume_type;
float nozzle_diameter;
std::string filament_id = "";
};
struct PACalibTabInfo
{
float pa_calib_tab_nozzle_dia;
int extruder_id;
NozzleVolumeType nozzle_volume_type;
};
class FlowRatioCalibResult
{
public:
@ -144,7 +172,7 @@ struct DrawBoxOptArgs
class CalibPressureAdvance
{
public:
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx = 0);
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int extruder_id = 0, int filament_idx = 0);
protected:
CalibPressureAdvance() = default;
@ -251,9 +279,8 @@ public:
Vec3d get_start_offset();
protected:
// todo multi_extruders:
double speed_first_layer() const { return m_config.option<ConfigOptionFloatsNullable>("initial_layer_speed")->get_at(0/*get_extruder_index(m_writer.extruder()->id())*/); };
double speed_perimeter() const { return m_config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(0/*get_extruder_index(m_writer.extruder()->id())*/); };
double speed_first_layer() const { return m_config.option<ConfigOptionFloatsNullable>("initial_layer_speed")->get_at(m_params.extruder_id); };
double speed_perimeter() const { return m_config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(m_params.extruder_id); };
double line_width_first_layer() const { return m_config.get_abs_value("initial_layer_line_width"); };
double line_width() const { return m_config.get_abs_value("line_width"); };
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };

View File

@ -2591,7 +2591,7 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print, int extruder_id)
{
int matched_machine_limit_idx = extruder_id * 2;
int matched_machine_limit_idx = get_extruder_id(extruder_id) * 2;
if (print.config().gcode_flavor.value == gcfMarlinLegacy || print.config().gcode_flavor.value == gcfMarlinFirmware) {
file.write_format("M201 X%d Y%d Z%d E%d\n",
int(print.config().machine_max_acceleration_x.values[matched_machine_limit_idx] + 0.5),

View File

@ -1196,7 +1196,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
return;
size_t nozzle_nums = print_config->nozzle_diameter.values.size();
if (nozzle_nums > 1) {
if (nozzle_nums > 1 && print_config->option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode")->value == FilamentMapMode::fmmAuto) {
std::vector<int> filament_maps = m_print->get_filament_maps();
if (print_config->print_sequence != PrintSequence::ByObject) {

View File

@ -229,7 +229,9 @@ void HistoryWindow::reqeust_history_result(MachineObject* obj)
float nozzle_value = get_nozzle_value();
if (nozzle_value > 0) {
CalibUtils::emit_get_PA_calib_infos(nozzle_value);
PACalibExtruderInfo cali_info;
cali_info.nozzle_diameter = nozzle_value;
CalibUtils::emit_get_PA_calib_infos(cali_info);
m_tips->SetLabel(_L("Refreshing the historical Flow Dynamics Calibration records"));
BOOST_LOG_TRIVIAL(info) << "request calib history";
}
@ -315,7 +317,12 @@ void HistoryWindow::sync_history_data() {
gbSizer->SetEmptyCellSize({ 0,0 });
m_history_data_panel->Layout();
m_history_data_panel->Fit();
CalibUtils::delete_PA_calib_result({ result.tray_id, result.cali_idx, result.nozzle_diameter, result.filament_id });
PACalibIndexInfo cali_info;
cali_info.tray_id = result.tray_id;
cali_info.cali_idx = result.cali_idx;
cali_info.nozzle_diameter = result.nozzle_diameter;
cali_info.filament_id = result.filament_id;
CalibUtils::delete_PA_calib_result(cali_info);
});
auto edit_button = new Button(m_history_data_panel, _L("Edit"));

View File

@ -478,7 +478,9 @@ void PressureAdvanceWizard::update(MachineObject* obj)
if (!m_show_result_dialog) {
if (obj->cali_version != -1 && obj->cali_version != cali_version) {
cali_version = obj->cali_version;
CalibUtils::emit_get_PA_calib_info(obj->nozzle_diameter, "");
PACalibExtruderInfo cali_info;
cali_info.nozzle_diameter = obj->nozzle_diameter;
CalibUtils::emit_get_PA_calib_info(cali_info);
}
}
}

View File

@ -2236,6 +2236,10 @@ int MachineObject::command_start_pa_calibration(const X1CCalibInfos &pa_data, in
j["print"]["filaments"][i]["filament_id"] = pa_data.calib_datas[i].filament_id;
j["print"]["filaments"][i]["setting_id"] = pa_data.calib_datas[i].setting_id;
j["print"]["filaments"][i]["nozzle_temp"] = pa_data.calib_datas[i].nozzle_temp;
j["print"]["filaments"][i]["ams_id"] = pa_data.calib_datas[i].ams_id;
j["print"]["filaments"][i]["slot_id"] = pa_data.calib_datas[i].slot_id;
j["print"]["filaments"][i]["nozzle_volume_type"] = int(pa_data.calib_datas[i].nozzle_volume_type);
j["print"]["filaments"][i]["nozzle_diameter"] = pa_data.calib_datas[i].nozzle_diameter;
j["print"]["filaments"][i]["max_volumetric_speed"] = std::to_string(pa_data.calib_datas[i].max_volumetric_speed);
if (i > 0) filament_ids += ",";
@ -2273,6 +2277,10 @@ int MachineObject::command_set_pa_calibration(const std::vector<PACalibResult> &
if (pa_calib_values[i].cali_idx >= 0)
j["print"]["filaments"][i]["cali_idx"] = pa_calib_values[i].cali_idx;
j["print"]["filaments"][i]["tray_id"] = pa_calib_values[i].tray_id;
j["print"]["filaments"][i]["extruder_id"] = pa_calib_values[i].extruder_id;
j["print"]["filaments"][i]["nozzle_volume_type"] = int(pa_calib_values[i].nozzle_volume_type);
j["print"]["filaments"][i]["ams_id"] = pa_calib_values[i].ams_id;
j["print"]["filaments"][i]["slot_id"] = pa_calib_values[i].slot_id;
j["print"]["filaments"][i]["filament_id"] = pa_calib_values[i].filament_id;
j["print"]["filaments"][i]["setting_id"] = pa_calib_values[i].setting_id;
j["print"]["filaments"][i]["name"] = pa_calib_values[i].name;
@ -2295,6 +2303,8 @@ int MachineObject::command_delete_pa_calibration(const PACalibIndexInfo& pa_cali
json j;
j["print"]["command"] = "extrusion_cali_del";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["extruder_id"] = pa_calib.extruder_id;
j["print"]["nozzle_volume_type"] = int(pa_calib.nozzle_volume_type);
j["print"]["filament_id"] = pa_calib.filament_id;
j["print"]["cali_idx"] = pa_calib.cali_idx;
j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(pa_calib.nozzle_diameter);
@ -2303,15 +2313,17 @@ int MachineObject::command_delete_pa_calibration(const PACalibIndexInfo& pa_cali
return this->publish_json(j.dump());
}
int MachineObject::command_get_pa_calibration_tab(float nozzle_diameter, const std::string &filament_id)
int MachineObject::command_get_pa_calibration_tab(const PACalibExtruderInfo &calib_info)
{
reset_pa_cali_history_result();
json j;
j["print"]["command"] = "extrusion_cali_get";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["filament_id"] = filament_id;
j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(nozzle_diameter);
j["print"]["filament_id"] = calib_info.filament_id;
j["print"]["extruder_id"] = calib_info.extruder_id;
j["print"]["nozzle_volume_type"] = int(calib_info.nozzle_volume_type);
j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(calib_info.nozzle_diameter);
BOOST_LOG_TRIVIAL(trace) << "extrusion_cali_get: " << j.dump();
return this->publish_json(j.dump());
@ -2334,6 +2346,8 @@ int MachineObject::commnad_select_pa_calibration(const PACalibIndexInfo& pa_cali
j["print"]["command"] = "extrusion_cali_sel";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["tray_id"] = pa_calib_info.tray_id;
j["print"]["ams_id"] = pa_calib_info.ams_id;
j["print"]["slot_id"] = pa_calib_info.slot_id;
j["print"]["cali_idx"] = pa_calib_info.cali_idx;
j["print"]["filament_id"] = pa_calib_info.filament_id;
j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(pa_calib_info.nozzle_diameter);
@ -4647,10 +4661,10 @@ int MachineObject::parse_json(std::string payload, bool key_field_only)
if (jj.contains("nozzle_diameter")) {
if (jj["nozzle_diameter"].is_number_float()) {
pa_calib_tab_nozzle_dia = jj["nozzle_diameter"].get<float>();
pa_calib_tab_info.pa_calib_tab_nozzle_dia = jj["nozzle_diameter"].get<float>();
}
else if (jj["nozzle_diameter"].is_string()) {
pa_calib_tab_nozzle_dia = string_to_float(jj["nozzle_diameter"].get<std::string>());
pa_calib_tab_info.pa_calib_tab_nozzle_dia = string_to_float(jj["nozzle_diameter"].get<std::string>());
}
else {
assert(false);
@ -4660,6 +4674,14 @@ int MachineObject::parse_json(std::string payload, bool key_field_only)
assert(false);
}
if (jj.contains("extruder_id")) {
pa_calib_tab_info.extruder_id = jj["extruder_id"].get<int>();
}
if (jj.contains("nozzle_volume_type")) {
pa_calib_tab_info.nozzle_volume_type = NozzleVolumeType(jj["nozzle_volume_type"].get<int>());
}
if (jj.contains("filaments") && jj["filaments"].is_array()) {
try {
for (auto it = jj["filaments"].begin(); it != jj["filaments"].end(); it++) {
@ -4731,6 +4753,30 @@ int MachineObject::parse_json(std::string payload, bool key_field_only)
pa_calib_result.nozzle_diameter = string_to_float(jj["nozzle_diameter"].get<std::string>());
}
if (it->contains("ams_id")) {
pa_calib_result.ams_id = (*it)["ams_id"].get<int>();
} else {
pa_calib_result.ams_id = 0;
}
if (it->contains("slot_id")) {
pa_calib_result.slot_id = (*it)["slot_id"].get<int>();
} else {
pa_calib_result.slot_id = 0;
}
if (it->contains("extruder_id")) {
pa_calib_result.extruder_id = (*it)["extruder_id"].get<int>();
} else {
pa_calib_result.extruder_id = -1;
}
if (it->contains("nozzle_volume_type")) {
pa_calib_result.nozzle_volume_type = NozzleVolumeType((*it)["nozzle_volume_type"].get<int>());
} else {
pa_calib_result.nozzle_volume_type = NozzleVolumeType::nvtNormal;
}
if ((*it)["k_value"].is_number_float())
pa_calib_result.k_value = (*it)["k_value"].get<float>();
else if ((*it)["k_value"].is_string())

View File

@ -660,14 +660,16 @@ public:
ManualPaCaliMethod manual_pa_cali_method = ManualPaCaliMethod::PA_LINE;
bool has_get_pa_calib_tab{ false };
std::vector<PACalibResult> pa_calib_tab;
float pa_calib_tab_nozzle_dia;
PACalibTabInfo pa_calib_tab_info;
bool get_pa_calib_result { false };
std::vector<PACalibResult> pa_calib_results;
bool get_flow_calib_result { false };
std::vector<FlowRatioCalibResult> flow_ratio_results;
void reset_pa_cali_history_result()
{
pa_calib_tab_nozzle_dia = 0.4f;
pa_calib_tab_info.pa_calib_tab_nozzle_dia = 0.4f;
pa_calib_tab_info.extruder_id = -1;
pa_calib_tab_info.nozzle_volume_type = NozzleVolumeType::nvtNormal;
has_get_pa_calib_tab = false;
pa_calib_tab.clear();
}
@ -930,7 +932,7 @@ public:
int command_start_pa_calibration(const X1CCalibInfos& pa_data, int mode = 0); // 0: automatic mode; 1: manual mode. default: automatic mode
int command_set_pa_calibration(const std::vector<PACalibResult>& pa_calib_values, bool is_auto_cali);
int command_delete_pa_calibration(const PACalibIndexInfo& pa_calib);
int command_get_pa_calibration_tab(float nozzle_diameter, const std::string &filament_id = "");
int command_get_pa_calibration_tab(const PACalibExtruderInfo& calib_info);
int command_get_pa_calibration_result(float nozzle_diameter);
int commnad_select_pa_calibration(const PACalibIndexInfo& pa_calib_info);

View File

@ -9933,7 +9933,7 @@ void Plater::_calib_pa_pattern(const Calib_Params &params)
print_config.set_key_value("outer_wall_speed",
new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
wxGetApp().preset_bundle->full_config(), print_config.get_abs_value("line_width"),
print_config.get_abs_value("layer_height"), 0)));
print_config.get_abs_value("layer_height"), 0, 0)));
for (const auto opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
print_config.set_key_value(opt.first, new ConfigOptionFloat(nozzle_diameter * opt.second / 100));
@ -9988,7 +9988,7 @@ void Plater::_calib_pa_tower(const Calib_Params &params)
//print_config->set_key_value("inner_wall_jerk", new ConfigOptionFloat(1.0f));
auto full_config = wxGetApp().preset_bundle->full_config();
auto wall_speed = CalibPressureAdvance::find_optimal_PA_speed(full_config, full_config.get_abs_value("line_width"),
full_config.get_abs_value("layer_height"), 0);
full_config.get_abs_value("layer_height"), 0, 0);
print_config->set_key_value("outer_wall_speed", new ConfigOptionFloat(wall_speed));
print_config->set_key_value("inner_wall_speed", new ConfigOptionFloat(wall_speed));
// print_config->set_key_value("wall_generator", new ConfigOptionEnum<PerimeterGeneratorType>(PerimeterGeneratorType::Classic));

View File

@ -2575,7 +2575,9 @@ void StatusPanel::update_ams(MachineObject *obj)
if (obj && (obj->last_cali_version != obj->cali_version)) {
last_cali_version = obj->cali_version;
CalibUtils::emit_get_PA_calib_info(obj->nozzle_diameter, "");
PACalibExtruderInfo cali_info;
cali_info.nozzle_diameter = obj->nozzle_diameter;
CalibUtils::emit_get_PA_calib_info(cali_info);
}
bool is_support_virtual_tray = obj->ams_support_virtual_tray;

View File

@ -379,7 +379,7 @@ bool CalibUtils::get_PA_calib_results(std::vector<PACalibResult>& pa_calib_resul
return pa_calib_results.size() > 0;
}
void CalibUtils::emit_get_PA_calib_infos(float nozzle_diameter)
void CalibUtils::emit_get_PA_calib_infos(const PACalibExtruderInfo &cali_info)
{
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev)
@ -389,7 +389,7 @@ void CalibUtils::emit_get_PA_calib_infos(float nozzle_diameter)
if (obj_ == nullptr)
return;
obj_->command_get_pa_calibration_tab(nozzle_diameter);
obj_->command_get_pa_calibration_tab(cali_info);
}
bool CalibUtils::get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos)
@ -408,7 +408,7 @@ bool CalibUtils::get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos)
return obj_->has_get_pa_calib_tab;
}
void CalibUtils::emit_get_PA_calib_info(float nozzle_diameter, const std::string &filament_id)
void CalibUtils::emit_get_PA_calib_info(const PACalibExtruderInfo &cali_info)
{
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
@ -416,7 +416,7 @@ void CalibUtils::emit_get_PA_calib_info(float nozzle_diameter, const std::string
MachineObject *obj_ = dev->get_selected_machine();
if (obj_ == nullptr) return;
obj_->command_get_pa_calibration_tab(nozzle_diameter, filament_id);
obj_->command_get_pa_calibration_tab(cali_info);
}
bool CalibUtils::get_PA_calib_info(PACalibResult & pa_calib_info) {
@ -558,8 +558,8 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1));
// todo multi_extruders:
double internal_solid_speed = std::floor(std::min(print_config.opt_float("internal_solid_infill_speed", 0/*get_extruder_index(stoi(calib_info.filament_prest->filament_id))*/), max_infill_speed));
double top_surface_speed = std::floor(std::min(print_config.opt_float("top_surface_speed", 0/*get_extruder_index(stoi(calib_info.filament_prest->filament_id))*/), max_infill_speed));
double internal_solid_speed = std::floor(std::min(print_config.opt_float("internal_solid_infill_speed", calib_info.extruder_id), max_infill_speed));
double top_surface_speed = std::floor(std::min(print_config.opt_float("top_surface_speed", calib_info.extruder_id), max_infill_speed));
// adjust parameters
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
@ -660,7 +660,7 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
print_config.set_key_value("outer_wall_speed",
new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
full_config, print_config.get_abs_value("line_width"),
print_config.get_abs_value("layer_height"), 0)));
print_config.get_abs_value("layer_height"), calib_info.extruder_id, 0)));
for (const auto opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
print_config.set_key_value(opt.first, new ConfigOptionFloat(nozzle_diameter * opt.second / 100));

View File

@ -15,6 +15,9 @@ extern const float MAX_PA_K_VALUE;
class CalibInfo
{
public:
int extruder_id = 0;
int ams_id = 0;
int slot_id = 0;
Calib_Params params;
Preset* printer_prest;
Preset* filament_prest;
@ -38,10 +41,10 @@ public:
static void emit_get_PA_calib_results(float nozzle_diameter);
static bool get_PA_calib_results(std::vector<PACalibResult> &pa_calib_results);
static void emit_get_PA_calib_infos(float nozzle_diameter);
static void emit_get_PA_calib_infos(const PACalibExtruderInfo &cali_info);
static bool get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos);
static void emit_get_PA_calib_info(float nozzle_diameter, const std::string &filament_id);
static void emit_get_PA_calib_info(const PACalibExtruderInfo& cali_info);
static bool get_PA_calib_info(PACalibResult &pa_calib_info);
static void set_PA_calib_result(const std::vector<PACalibResult>& pa_calib_values, bool is_auto_cali);