Machine Input Shaping (#11202)
* Base IS Machine * Toggle line * Rebase * Intento 1 * Wiki IS * Flavorized * Tooltips * Calibration using the same list * max * Reorder JD validation * Refactor set input shaping * Calibrations IS * Default values * Axis * Orca comments * Rename input_shaping_enable to input_shaping_emit Refactor all references of the input shaping configuration option from 'input_shaping_enable' to 'input_shaping_emit' across the codebase. This improves clarity by better reflecting the option's purpose of controlling whether input shaping commands are emitted in the generated G-code. Restore DONT EMIT FOR KLIPPER * Refactor input shaping option toggling logic Simplifies and consolidates the logic for toggling input shaping related options in TabPrinter::toggle_options(). Uses a loop to handle enabling/disabling lines based on GCode flavor compatibility, and refines the conditions for toggling individual options. * Improve input shaping option toggling logic in TabPrinter * GrayOut Emit to gcode limits for klipper * Typo Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Typo * Skip Y input-shaper when type is Disable If marlin2 and disabled it will be already disabled at X. * IS expert Co-Authored-By: SoftFever <softfeverever@gmail.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
#include "Widgets/TabCtrl.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "MarkdownTip.hpp"
|
||||
#include "Search.hpp"
|
||||
#include "BedShapeDialog.hpp"
|
||||
@@ -1494,6 +1495,11 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt_key == "gcode_flavor" && m_type == Preset::TYPE_PRINTER) {
|
||||
if (auto printer_tab = dynamic_cast<TabPrinter*>(this))
|
||||
printer_tab->on_gcode_flavor_changed();
|
||||
}
|
||||
|
||||
if (opt_key == "compatible_prints")
|
||||
this->compatible_widget_reload(m_compatible_prints);
|
||||
if (opt_key == "compatible_printers")
|
||||
@@ -4796,7 +4802,7 @@ PageShp TabPrinter::build_kinematics_page()
|
||||
optgroup->append_single_option_line("emit_machine_limits_to_gcode", "printer_motion_ability#emit-limits-to-g-code");
|
||||
|
||||
// resonance avoidance ported over from qidi slicer
|
||||
optgroup = page->new_optgroup(L("Resonance Avoidance"), "param_resonance_avoidance");
|
||||
optgroup = page->new_optgroup(L("Resonance Compensation"), "param_resonance_avoidance");
|
||||
optgroup->append_single_option_line("resonance_avoidance", "printer_motion_ability#resonance-avoidance");
|
||||
// Resonance‑avoidance speed inputs
|
||||
{
|
||||
@@ -4806,6 +4812,20 @@ PageShp TabPrinter::build_kinematics_page()
|
||||
resonance_line.append_option(optgroup->get_option("max_resonance_avoidance_speed"));
|
||||
optgroup->append_line(resonance_line);
|
||||
}
|
||||
optgroup->append_single_option_line("input_shaping_emit", "input-shaping-calib");
|
||||
optgroup->append_single_option_line("input_shaping_type", "input-shaping-calib");
|
||||
{
|
||||
Line freq_line = {L("Frequency"), L("The frequency of the anti-vibration signal will correspond to the natural frequency of the frame.")};
|
||||
freq_line.append_option(optgroup->get_option("input_shaping_freq_x"));
|
||||
freq_line.append_option(optgroup->get_option("input_shaping_freq_y"));
|
||||
optgroup->append_line(freq_line);
|
||||
}
|
||||
{
|
||||
Line damping_line = {L("Damping"), L("Damping ratio for the input shaping filter.")};
|
||||
damping_line.append_option(optgroup->get_option("input_shaping_damp_x"));
|
||||
damping_line.append_option(optgroup->get_option("input_shaping_damp_y"));
|
||||
optgroup->append_line(damping_line);
|
||||
}
|
||||
|
||||
const std::vector<std::string> speed_axes{
|
||||
"machine_max_speed_x",
|
||||
@@ -5248,6 +5268,115 @@ void TabPrinter::clear_pages()
|
||||
m_reset_to_filament_color = nullptr;
|
||||
}
|
||||
|
||||
std::vector<InputShaperType> input_shaper_types_for_flavor(GCodeFlavor flavor)
|
||||
{
|
||||
switch (flavor) {
|
||||
case GCodeFlavor::gcfKlipper:
|
||||
return {
|
||||
InputShaperType::Default,
|
||||
InputShaperType::ZV,
|
||||
InputShaperType::MZV,
|
||||
InputShaperType::ZVD,
|
||||
InputShaperType::EI,
|
||||
InputShaperType::TwoHumpEI,
|
||||
InputShaperType::ThreeHumpEI,
|
||||
InputShaperType::Disable
|
||||
};
|
||||
case GCodeFlavor::gcfRepRapFirmware:
|
||||
return {
|
||||
InputShaperType::Default,
|
||||
InputShaperType::MZV,
|
||||
InputShaperType::ZVD,
|
||||
InputShaperType::ZVDD,
|
||||
InputShaperType::ZVDDD,
|
||||
InputShaperType::EI2,
|
||||
InputShaperType::EI3,
|
||||
InputShaperType::DAA,
|
||||
InputShaperType::Disable
|
||||
};
|
||||
case GCodeFlavor::gcfMarlinFirmware:
|
||||
return {
|
||||
InputShaperType::ZV,
|
||||
InputShaperType::Disable
|
||||
};
|
||||
default:
|
||||
return {
|
||||
InputShaperType::Default,
|
||||
InputShaperType::Disable
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void TabPrinter::update_input_shaper_menu(GCodeFlavor flavor)
|
||||
{
|
||||
if (m_presets->get_edited_preset().printer_technology() != ptFFF)
|
||||
return;
|
||||
|
||||
const std::vector<InputShaperType> allowed = input_shaper_types_for_flavor(flavor);
|
||||
if (allowed.empty())
|
||||
return;
|
||||
|
||||
const InputShaperType current = m_config->opt_enum<InputShaperType>("input_shaping_type");
|
||||
const bool needs_reset = std::find(allowed.begin(), allowed.end(), current) == allowed.end();
|
||||
const InputShaperType desired = needs_reset ? allowed.front() : current;
|
||||
|
||||
if (needs_reset && current != desired) {
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("input_shaping_type", new ConfigOptionEnum<InputShaperType>(desired));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
}
|
||||
|
||||
Page* owning_page = nullptr;
|
||||
Field* field = get_field("input_shaping_type", &owning_page);
|
||||
if (field == nullptr)
|
||||
return;
|
||||
|
||||
auto choice_field = dynamic_cast<Choice*>(field);
|
||||
if (choice_field == nullptr)
|
||||
return;
|
||||
|
||||
auto combo = dynamic_cast<ComboBox*>(choice_field->getWindow());
|
||||
if (combo == nullptr)
|
||||
return;
|
||||
|
||||
const ConfigOptionDef* def = m_config->def()->get("input_shaping_type");
|
||||
if (def == nullptr)
|
||||
return;
|
||||
|
||||
const auto& labels = def->enum_labels;
|
||||
const auto& values = def->enum_values;
|
||||
|
||||
wxWindowUpdateLocker locker(combo);
|
||||
combo->Clear();
|
||||
|
||||
for (InputShaperType type : allowed) {
|
||||
const size_t idx = static_cast<size_t>(type);
|
||||
wxString label;
|
||||
if (idx < labels.size() && !labels[idx].empty())
|
||||
label = _(labels[idx]);
|
||||
else if (idx < values.size())
|
||||
label = wxString::FromUTF8(values[idx].c_str());
|
||||
else
|
||||
label = wxString::Format("%d", static_cast<int>(type));
|
||||
|
||||
combo->Append(label, wxNullBitmap,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(static_cast<int>(type))));
|
||||
}
|
||||
|
||||
if (combo->GetCount() == 0)
|
||||
return;
|
||||
|
||||
choice_field->set_value(static_cast<int>(desired), false);
|
||||
}
|
||||
|
||||
void TabPrinter::on_gcode_flavor_changed()
|
||||
{
|
||||
auto* flavor_option = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor");
|
||||
if (!flavor_option)
|
||||
return;
|
||||
update_input_shaper_menu(flavor_option->value);
|
||||
}
|
||||
|
||||
void TabPrinter::toggle_options()
|
||||
{
|
||||
if (!m_active_page || m_presets->get_edited_preset().printer_technology() == ptSLA)
|
||||
@@ -5400,6 +5529,7 @@ void TabPrinter::toggle_options()
|
||||
|
||||
if (m_active_page->title() == L("Motion ability")) {
|
||||
auto gcf = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value;
|
||||
update_input_shaper_menu(gcf);
|
||||
bool silent_mode = m_config->opt_bool("silent_mode");
|
||||
int max_field = silent_mode ? 2 : 1;
|
||||
for (int i = 0; i < max_field; ++i)
|
||||
@@ -5427,9 +5557,31 @@ void TabPrinter::toggle_options()
|
||||
toggle_option("machine_max_jerk_e", enable_jerk, i);
|
||||
}
|
||||
|
||||
bool emittable_limits = m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfMarlinLegacy || m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfMarlinFirmware || m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfRepRapFirmware;
|
||||
toggle_option("emit_machine_limits_to_gcode", emittable_limits);
|
||||
|
||||
bool resonance_avoidance = m_config->opt_bool("resonance_avoidance");
|
||||
toggle_option("min_resonance_avoidance_speed", resonance_avoidance);
|
||||
toggle_option("max_resonance_avoidance_speed", resonance_avoidance);
|
||||
|
||||
bool input_shaping_compatible = m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfMarlinFirmware || m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfRepRapFirmware;
|
||||
|
||||
for (auto is : {"input_shaping_emit", "input_shaping_type", "input_shaping_freq_x", "input_shaping_freq_y",
|
||||
"input_shaping_damp_x", "input_shaping_damp_y"})
|
||||
toggle_line(is, input_shaping_compatible);
|
||||
|
||||
if (input_shaping_compatible) {
|
||||
bool emit_machine_limits_to_gcode = m_config->opt_bool("emit_machine_limits_to_gcode");
|
||||
toggle_option("input_shaping_emit", emit_machine_limits_to_gcode);
|
||||
bool input_shaping_emit = emit_machine_limits_to_gcode && m_config->opt_bool("input_shaping_emit");
|
||||
bool reprap = m_config->opt_enum<GCodeFlavor>("gcode_flavor") == GCodeFlavor::gcfRepRapFirmware;
|
||||
toggle_option("input_shaping_type", input_shaping_emit);
|
||||
toggle_option("input_shaping_freq_x", input_shaping_emit);
|
||||
toggle_option("input_shaping_freq_y", input_shaping_emit && !reprap);
|
||||
toggle_option("input_shaping_damp_x", input_shaping_emit);
|
||||
toggle_option("input_shaping_damp_y", input_shaping_emit && !reprap);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user