supermerill / SuperSlicer

G-code generator for 3D printers (Prusa, Voron, Creality, etc.)
4.13k stars 519 forks source link

Input Shaper Y-Axis Interpolation for i3/Mendel/Bed Slinger #2722

Closed sihawken closed 2 years ago

sihawken commented 2 years ago

Feature Request SuperSlicer has become the slicer of choice for Klipper users. One of Klippers best features is input shaping, allowing printers to move dramatically faster.

Input shaping has a big flaw, however. Input shaping works best for CoreXY printers, and not i3/mendel/bed slingers. It does work, but as the mass on the printer increases, the set natural frequency in the Y direction is no longer valid.

This means a print could look flawless at the bottom, and have resonance appear near the top.

The solution I would like I would like to have a dynamic per-layer Y-axis input shaper frequency change calculated based on the printed mass.

This would be immensely valuable for the vast majority of 3D printers on the market: Prusa, Creality, Anycubic, ...

How it would work 2 or 3 data points could be taken with known masses printed on the bed, with their corresponding natural frequencies. This would be stored in the printer settings.

Klipper could (and may already) calculate the mass per layer, and interpolate the input shaper frequency in the Y direction.

Then, at each layer, output one of the following:

SET_INPUT_SHAPER SHAPER_FREQ_Y=xx

Alternatives I've considered Manually adding changes in input shaper frequencies at various different layer heights. This is slow and painful.

sihawken commented 2 years ago

Solved with a Klipper macro, a solution that I feel is more elegant (and specific to the printer).

[gcode_macro SET_INPUT_SHAPER_INTERPOLATED_Y_FREQ]
description: Calculates and sets the new Y axis natural frequency based on the amount of printed mass. Necessary for bed slinger printers. 
; Uses a very rudimentary linear interpolation, and likely will fail if pushed to extremes.

; gcode parameters
variable_parameter_FILAMENT_DENSITY : 0.0 ; g/mm^3
; natural frequency of y axis when nothing is printed.
variable_default_filament_density : 1.24 ; g/cm^3 PLA
; natural frequency when nothing is on the bed (or very little)
variable_natural_freq_base : 32.18 ; hz
; natural frequency of y axis when 250g is printed on the bed.
variable_natural_freq_sample1 : 27.17 ; hz
; known mass for sample 1
variable_mass_sample1 : 250.0 ; g
; filament area
variable_filament_area : 2.405 ; 1.75mm diameter filament
gcode:
    {% if params.FILAMENT_DENSITY %}
        {% if (params.FILAMENT_DENSITY|float > 0.00) %}
            {% set filament_density = params.FILAMENT_DENSITY|float * 0.001 %}
        {% else %}
            {action_respond_info("Warning: Filament density must be a positive number. Using default density of " + default_filament_density|string + ". Please specify filament material density (in g/cm^3) with SET_INPUT_SHAPER_INTERPOLATED_Y_FREQ FILAMENT_DENSITY=xx")}
            {% set filament_density = default_filament_density|float * 0.001 %}
        {% endif %}
    {% else %}
        {action_respond_info("Warning: No filament density was given. Using default density of " + default_filament_density|string + ". Please specify filament material density (in g/cm^3) with SET_INPUT_SHAPER_INTERPOLATED_Y_FREQ FILAMENT_DENSITY=xx")}
        {% set filament_density = default_filament_density|float * 0.001 %}
    {% endif %}
    {% set extruded_mm = printer.print_stats.filament_used|float %}
    {% set extruded_volume = filament_area*extruded_mm %}
    {% set extruded_mass = extruded_volume * filament_density %}
    {% set freq_mass_curve = (natural_freq_sample1 - natural_freq_base) / mass_sample1 %}
    { action_respond_info( "Extruded mass: " + extruded_mass|round(2)|string + "g")}
    {% set y_natural_freq = natural_freq_base + freq_mass_curve * extruded_mass %}
    SET_INPUT_SHAPER SHAPER_FREQ_Y={y_natural_freq|round(3)}

Only need to add this to the After Layer Change section in superslicer.

SET_INPUT_SHAPER_INTERPOLATED_Y_FREQ FILAMENT_DENSITY=[filament_density]

sihawken commented 2 years ago

This would be a cool feature to add regardless. But it may not be worth it when it can be solved by a macro. I am going to close this feature request.

supermerill commented 2 years ago

Maybe I can expose some stats (extruded weight, length, ..., rough estimation time) in the custom gcode, so you can use it in the layer change gcode.

10bn commented 1 year ago

Hi, thank you for raising this point. Wouldn't it also make sense to use different input shaper values Z-orientation and interpolate for x in relation to z as well? This would be particularly useful for printers like the Prusa Mini that have a single Z mount.