Fix calibration

Co-authored-by: zhimin.zeng <zhimin.zeng@bambulab.com>
This commit is contained in:
Noisyfox
2026-05-21 23:27:05 +08:00
parent bb9bc04996
commit 6690bdf149
3 changed files with 140 additions and 49 deletions

View File

@@ -238,6 +238,32 @@ static string get_diameter_string(float diameter)
return s;
}
template <typename T, typename OptionType>
static void set_config_values(DynamicPrintConfig *config, const std::string &key, T value)
{
auto config_opt = config->option<OptionType>(key);
if (config_opt) {
for (size_t i = 0; i < config_opt->values.size(); ++i) {
config_opt->values[i] = value;
}
}
else {
BOOST_LOG_TRIVIAL(info) << "set_config_values: the key" << key << "is empty.";
}
}
template <typename T, typename OptionType>
static void set_config_values(ModelConfig& config, const std::string &key, T value)
{
auto config_opt = config.get().option<OptionType>(key);
if (config_opt) {
config.set_key_value(key, new OptionType(config_opt->values.size(), value));
}
else {
BOOST_LOG_TRIVIAL(info) << "set_config_values: the key" << key << "is empty.";
}
}
bool Plater::has_illegal_filename_characters(const wxString& wxs_name)
{
std::string name = into_u8(wxs_name);
@@ -12672,11 +12698,11 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
double nozzle_diameter = printer_config->option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
filament_config->set_key_value("filament_retract_when_changing_layer", new ConfigOptionBoolsNullable{false});
filament_config->set_key_value("filament_wipe", new ConfigOptionBoolsNullable{false});
printer_config->set_key_value("wipe", new ConfigOptionBools{false});
printer_config->set_key_value("retract_when_changing_layer", new ConfigOptionBools{false});
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
set_config_values<bool, ConfigOptionBoolsNullable>(filament_config, "filament_retract_when_changing_layer", false);
set_config_values<bool, ConfigOptionBoolsNullable>(filament_config, "filament_wipe", false);
set_config_values<bool, ConfigOptionBools>(printer_config, "wipe", false);
set_config_values<bool, ConfigOptionBools>(printer_config, "retract_when_changing_layer", false);
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool(false));
//Orca: find acceleration to use in the test
auto accel = print_config.get_abs_value_at("outer_wall_acceleration", params.extruder_id); // get the outer wall acceleration
@@ -12695,7 +12721,7 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
// set max acceleration in case of batch mode to get correct test pattern size
accel = *std::max_element(accels.begin(), accels.end());
}
print_config.set_key_value("outer_wall_acceleration", new ConfigOptionFloatsNullable({accel}));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_acceleration", accel);
print_config.set_key_value( "print_sequence", new ConfigOptionEnum(PrintSequence::ByLayer));
//Orca: find jerk value to use in the test
@@ -12708,20 +12734,20 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
//Orca: Set jerk values. Again first layer jerk should not matter as it is reset to the travel jerk before the
// first PA pattern is printed.
print_config.set_key_value( "default_jerk", new ConfigOptionFloatsNullable({jerk}));
print_config.set_key_value( "outer_wall_jerk", new ConfigOptionFloatsNullable({jerk}));
print_config.set_key_value( "inner_wall_jerk", new ConfigOptionFloatsNullable({jerk}));
print_config.set_key_value( "top_surface_jerk", new ConfigOptionFloatsNullable({jerk}));
print_config.set_key_value( "infill_jerk", new ConfigOptionFloatsNullable({jerk}));
print_config.set_key_value( "travel_jerk", new ConfigOptionFloatsNullable({jerk}));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "default_jerk", jerk);
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_jerk", jerk);
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "inner_wall_jerk", jerk);
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "top_surface_jerk", jerk);
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "infill_jerk", jerk);
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "travel_jerk", jerk);
}
if (has_junction_deviation(printer_config)){
print_config.set_key_value("default_junction_deviation", new ConfigOptionFloatsNullable({0}));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "default_junction_deviation", 0);
}
for (const auto& opt : SuggestedConfigCalibPAPattern().floats_pairs) {
print_config.set_key_value(opt.first, new ConfigOptionFloatsNullable(opt.second));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, opt.first, opt.second[0]);
}
for (const auto& opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
@@ -12745,11 +12771,12 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
// Orca: Set the outer wall speed to the optimal speed for the test, cap it with max volumetric speed
if (speeds.empty()) {
// TODO: per-variant cap
double speed = CalibPressureAdvance::find_optimal_PA_speed(
wxGetApp().preset_bundle->full_config(),
print_config.get_abs_value("line_width", nozzle_diameter),
print_config.get_abs_value("layer_height"), 0, 0);
print_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({speed}));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_speed", speed);
speeds.assign({speed});
const auto msg{_L("INFO:") + "\n" +
@@ -12758,7 +12785,7 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
} else if (speeds.size() == 1) {
// If we have single value provided, set speed using global configuration.
// per-object config is not set in this case
print_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({speeds.front()}));
set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_speed", speeds.front());
}
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
@@ -12833,9 +12860,9 @@ void Plater::_calib_pa_pattern(const Calib_Params& params)
auto &obj_config = obj->config;
if (speeds.size() > 1)
obj_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({tspd}));
set_config_values<double, ConfigOptionFloatsNullable>(obj_config, "outer_wall_speed", tspd);
if (accels.size() > 1)
obj_config.set_key_value("outer_wall_acceleration", new ConfigOptionFloatsNullable({tacc}));
set_config_values<double, ConfigOptionFloatsNullable>(obj_config, "outer_wall_acceleration", tacc);
auto cur_plate = get_partplate_list().get_plate(plate_idx);
if (!cur_plate) {
@@ -12936,11 +12963,8 @@ void Plater::_calib_pa_tower(const Calib_Params& params) {
obj_cfg.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
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", nozzle_diameter),
full_config.get_abs_value("layer_height"), 0, 0);
obj_cfg.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({wall_speed}));
obj_cfg.set_key_value("inner_wall_speed", new ConfigOptionFloatsNullable({wall_speed}));
update_speed_parameter("outer_wall_speed");
update_speed_parameter("inner_wall_speed");
obj_cfg.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spRear));
obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(2));
obj_cfg.set_key_value("top_shell_layers", new ConfigOptionInt(0));
@@ -12993,12 +13017,15 @@ void Plater::_calib_pa_select_added_objects() {
void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, int pass, InfillPattern pattern)
{
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto printerConfig = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
/// --- scale ---
// model is created for a 0.4 nozzle, scale z with nozzle size.
const ConfigOptionFloats* nozzle_diameter_config = printerConfig->option<ConfigOptionFloats>("nozzle_diameter");
const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
std::vector<int> extruder_types = printer_config->option<ConfigOptionEnumsGeneric>("extruder_type")->values;
std::vector<int> nozzle_volume_types = wxGetApp().preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values;
assert(nozzle_diameter_config->values.size() > 0);
float nozzle_diameter = nozzle_diameter_config->values[0];
float xyScale = nozzle_diameter / 0.6;
@@ -13022,17 +13049,9 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i
}
canvas->do_scale("");
auto cur_flowrate = filament_config->option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter);
double filament_max_volumetric_speed = filament_config->option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
double max_infill_speed;
if (linear)
max_infill_speed = filament_max_volumetric_speed /
(infill_flow.mm3_per_mm() * (cur_flowrate + (pass == 2 ? 0.035 : 0.05)) / cur_flowrate);
else
max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1));
double internal_solid_speed = std::floor(std::min(print_config->opt_float_nullable("internal_solid_infill_speed", 0), max_infill_speed));
double top_surface_speed = std::floor(std::min(print_config->opt_float_nullable("top_surface_speed", 0), max_infill_speed));
auto cur_flowrate = filament_config->option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0); // TODO: per-filament param
std::vector<double> internal_solid_speeds = generate_max_speed_parameter_value("internal_solid_infill_speed", linear, pass);
std::vector<double> top_surface_speeds = generate_max_speed_parameter_value("top_surface_speed", linear, pass);
// adjust parameters
for (auto _obj : objects) {
@@ -13060,8 +13079,8 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i
_obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(135));
_obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true));
_obj->config.set_key_value("ironing_type", new ConfigOptionEnum<IroningType>(IroningType::NoIroning));
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloatsNullable({internal_solid_speed}));
_obj->config.set_key_value("top_surface_speed", new ConfigOptionFloatsNullable({top_surface_speed}));
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloatsNullable(internal_solid_speeds));
_obj->config.set_key_value("top_surface_speed", new ConfigOptionFloatsNullable(top_surface_speeds));
_obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
_obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum<GapFillTarget>(GapFillTarget::gftNowhere));
print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0));
@@ -13158,8 +13177,7 @@ void Plater::calib_temp(const Calib_Params& params) {
const auto calib_temp_name = wxString::Format(L"Nozzle temperature test");
new_project(false, false, calib_temp_name);
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
if (params.mode != CalibMode::Calib_Temp_Tower)
return;
if (params.mode != CalibMode::Calib_Temp_Tower) return;
add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.drc");
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
@@ -13205,8 +13223,8 @@ void Plater::calib_temp(const Calib_Params& params) {
model().objects[0]->ensure_on_bed();
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1,(int)start_temp));
filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1,(int)start_temp));
set_config_values<int, ConfigOptionInts>(filament_config, "nozzle_temperature_initial_layer", (int) start_temp);
set_config_values<int, ConfigOptionInts>(filament_config, "nozzle_temperature", (int) start_temp);
model().objects[0]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter/2));
model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(5.0));
@@ -13258,13 +13276,15 @@ void Plater::calib_max_vol_speed(const Calib_Params& params)
double layer_height = nozzle_diameter * 0.8;
auto max_lh = printer_config->option<ConfigOptionFloats>("max_layer_height");
if (max_lh->values[0] < layer_height)
max_lh->values[0] = { layer_height };
for (size_t i = 0; i < max_lh->values.size(); ++i) {
if (max_lh->values[i] < layer_height)
max_lh->values[i] = layer_height;
}
filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats { 200 });
set_config_values<double, ConfigOptionFloats>(filament_config, "filament_max_volumetric_speed", 200);
filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{0.0});
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
obj_cfg.set_key_value("enable_overhang_speed", new ConfigOptionBoolsNullable({false}));
set_config_values<bool, ConfigOptionBoolsNullable>(obj_cfg, "enable_overhang_speed", false);
obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(1));
obj_cfg.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
obj_cfg.set_key_value("top_shell_layers", new ConfigOptionInt(0));
@@ -13333,8 +13353,9 @@ void Plater::calib_retraction(const Calib_Params& params)
}
auto max_lh = printer_config->option<ConfigOptionFloats>("max_layer_height");
if (max_lh->values[0] < layer_height)
max_lh->values[0] = { layer_height };
for (size_t i = 0; i < max_lh->values.size(); ++i) {
if (max_lh->values[i] < layer_height) max_lh->values[i] = layer_height;
}
printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
printer_config->set_key_value("use_firmware_retraction", new ConfigOptionBool(false));
@@ -13379,7 +13400,7 @@ void Plater::calib_VFA(const Calib_Params& params)
printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{true});
printer_config->set_key_value("input_shaping_type", new ConfigOptionEnum<InputShaperType>(InputShaperType::Disable));
filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 });
print_config->set_key_value("enable_overhang_speed", new ConfigOptionBoolsNullable({false}));
set_config_values<bool, ConfigOptionBoolsNullable>(print_config, "enable_overhang_speed", false);
print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false));

View File

@@ -89,6 +89,73 @@ wxString get_nozzle_volume_type_name(NozzleVolumeType type)
return wxString();
}
void update_speed_parameter( const std::string& key)
{
auto preset_bundle = wxGetApp().preset_bundle;
auto& printer_config = preset_bundle->printers.get_edited_preset().config;
auto& filament_config = preset_bundle->filaments.get_edited_preset().config;
auto& print_config = preset_bundle->prints.get_edited_preset().config;
int extruder_nums = preset_bundle->get_printer_extruder_count();
std::vector<int> extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type")->values;
std::vector<int> nozzle_volume_types = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values;
float nozzle_diameter = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values[0];
float layer_height = print_config.option<ConfigOptionFloat>("layer_height")->value;
float line_width = print_config.get_abs_value("line_width", nozzle_diameter);
if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter);
Flow flow = Flow(line_width, layer_height, nozzle_diameter);
for (size_t i = 0; i < extruder_nums; ++i) {
int index = get_index_for_extruder_parameter(filament_config, "filament_max_volumetric_speed", i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(index);
double max_speed = filament_max_volumetric_speed / flow.mm3_per_mm();
index = get_index_for_extruder_parameter(print_config, key, i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
ConfigOptionFloatsNullable *speed_opt = print_config.option<ConfigOptionFloatsNullable>(key);
speed_opt->values[index] = max_speed;
}
}
std::vector<double> generate_max_speed_parameter_value(const std::string &key, const bool linear, const int pass)
{
auto preset_bundle = wxGetApp().preset_bundle;
auto &printer_config = preset_bundle->printers.get_edited_preset().config;
auto &filament_config = preset_bundle->filaments.get_edited_preset().config;
auto &print_config = preset_bundle->prints.get_edited_preset().config;
int extruder_nums = preset_bundle->get_printer_extruder_count();
std::vector<int> extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type")->values;
std::vector<int> nozzle_volume_types = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values;
float nozzle_diameter = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values[0];
float layer_height = print_config.option<ConfigOptionFloat>("layer_height")->value;
float line_width = print_config.get_abs_value("line_width", nozzle_diameter);
Flow flow = Flow(line_width, layer_height, nozzle_diameter);
std::vector<double> speed_values;
speed_values.resize(extruder_nums * nozzle_volume_types.size());
for (size_t i = 0; i < extruder_nums; ++i) {
int index = get_index_for_extruder_parameter(filament_config, "filament_max_volumetric_speed", i, ExtruderType(extruder_types[i]),
NozzleVolumeType(nozzle_volume_types[i]));
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(index);
double cur_flowrate = filament_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(index);
double max_speed = linear ? filament_max_volumetric_speed / (flow.mm3_per_mm() * (cur_flowrate + (pass == 2 ? 0.035 : 0.05)) / cur_flowrate) :
filament_max_volumetric_speed / (flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1));
index = get_index_for_extruder_parameter(print_config, key, i, ExtruderType(extruder_types[i]), NozzleVolumeType(nozzle_volume_types[i]));
ConfigOptionFloatsNullable *speed_opt = print_config.option<ConfigOptionFloatsNullable>(key);
double speed_value = std::floor(std::min(speed_opt->values[index], max_speed));
for (size_t v_id = 0; v_id < nozzle_volume_types.size(); ++v_id) {
speed_values.emplace_back(speed_value);
}
}
return speed_values;
}
static int get_physical_extruder_idx(std::vector<int> physical_extruder_maps, int extruder_id)
{
for (size_t index = 0; index < physical_extruder_maps.size(); ++index) {

View File

@@ -95,5 +95,8 @@ extern void get_tray_ams_and_slot_id(MachineObject* obj, int in_tray_id, int &am
extern void get_default_k_n_value(const std::string &filament_id, float &k, float &n);
extern wxString get_nozzle_volume_type_name(NozzleVolumeType type);
extern void update_speed_parameter(const std::string &key);
extern std::vector<double> generate_max_speed_parameter_value(const std::string &key, bool linear, int pass);
}
}