добавлена щетка, смещение тача, переписан авд, праймлайн на тпу

This commit is contained in:
2025-04-01 02:11:44 +03:00
parent 228d45b7bf
commit 25091da86b
9 changed files with 1212 additions and 2 deletions

111
Scripts/TEST_SPEED.cfg Normal file
View File

@@ -0,0 +1,111 @@
# Home, get position, throw around toolhead, home again.
# If MCU stepper positions (first line in GET_POSITION) are greater than a full step different (your number of microsteps), then skipping occured.
# We only measure to a full step to accomodate for endstop variance.
# Example: TEST_SPEED SPEED=300 ACCEL=5000 ITERATIONS=10
[gcode_macro TEST_SPEED]
gcode:
# Speed
{% set speed = params.SPEED|default(printer.configfile.settings.printer.max_velocity)|int %}
# Iterations
{% set iterations = params.ITERATIONS|default(5)|int %}
# Acceleration
{% set accel = params.ACCEL|default(printer.configfile.settings.printer.max_accel)|int %}
# Bounding inset for large pattern (helps prevent slamming the toolhead into the sides after small skips, and helps to account for machines with imperfectly set dimensions)
{% set bound = params.BOUND|default(20)|int %}
# Size for small pattern box
{% set smallpatternsize = SMALLPATTERNSIZE|default(20)|int %}
# Large pattern
# Max positions, inset by BOUND
{% set x_min = printer.toolhead.axis_minimum.x + bound %}
{% set x_max = printer.toolhead.axis_maximum.x - bound %}
{% set y_min = printer.toolhead.axis_minimum.y + bound %}
{% set y_max = printer.toolhead.axis_maximum.y - bound %}
# Small pattern at center
# Find X/Y center point
{% set x_center = (printer.toolhead.axis_minimum.x|float + printer.toolhead.axis_maximum.x|float ) / 2 %}
{% set y_center = (printer.toolhead.axis_minimum.y|float + printer.toolhead.axis_maximum.y|float ) / 2 %}
# Set small pattern box around center point
{% set x_center_min = x_center - (smallpatternsize/2) %}
{% set x_center_max = x_center + (smallpatternsize/2) %}
{% set y_center_min = y_center - (smallpatternsize/2) %}
{% set y_center_max = y_center + (smallpatternsize/2) %}
# Save current gcode state (absolute/relative, etc)
SAVE_GCODE_STATE NAME=TEST_SPEED
# Output parameters to g-code terminal
{ action_respond_info("TEST_SPEED: starting %d iterations at speed %d, accel %d" % (iterations, speed, accel)) }
# Home and get position for comparison later:
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28 X Y
# QGL if not already QGLd (only if QGL section exists in config)
{% if printer.configfile.settings.quad_gantry_level %}
{% if printer.quad_gantry_level.applied == False %}
QUAD_GANTRY_LEVEL
G28 Z
{% endif %}
{% endif %}
# Move 50mm away from max position and home again (to help with hall effect endstop accuracy - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/24)
G90
G1 X{printer.toolhead.axis_maximum.x-50} Y{printer.toolhead.axis_maximum.y-50} F{30*60}
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28 X Y
G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
G4 P1000
GET_POSITION
# Go to starting position
G0 X{x_min} Y{y_min} F{speed*60}
# Set new limits
SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2}
{% for i in range(iterations) %}
# Large pattern diagonals
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_max} Y{y_max} F{speed*60}
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
G0 X{x_min} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
# Large pattern box
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_min} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
# Small pattern diagonals
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_max} Y{y_center_max} F{speed*60}
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
G0 X{x_center_min} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
# Small patternbox
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_min} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
{% endfor %}
# Restore max speed/accel/accel_to_decel to their configured values
SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel}
# Re-home and get position again for comparison:
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28 X Y# This is a full G28 to fix an issue with CoreXZ - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/12
# Go to XY home positions (in case your homing override leaves it elsewhere)
G90
G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
G4 P1000
GET_POSITION
# Restore previous gcode state (absolute/relative, etc)
RESTORE_GCODE_STATE NAME=TEST_SPEED

View File

@@ -0,0 +1,242 @@
#########################################
########## ADAPTIVE BED MESH ############
#########################################
# Written by Frix_x#0161 #
# @version: 4.0
# CHANGELOG:
# v4.0: - patched and re-simplified the macro to work with latest Klipper changes: zero_reference_position is much more constrained and all the fancy stuff
# that was used in the past for homing over the RRI with virtual probe or Z calibration plugin is not possible anymore. Now homing must be done at
# fixed zero_reference_poisition and can't be dynamic anymore (but it's also simpler)
# - this change also allow the mesh to have even probe point now for more flexibility
# v3.0: - added the use of [exclude_object] tags to extract the first layer bounding box (many thanks to Kyleisah for the excellent idea and inspiration)
# the macro is still fully compatible with the old way using the SIZE parameter: it will use it if specified, or else
# fallback to the [exclude_object] method and if both are not available, it will do a full and normal bed mesh as usual.
# - also added a FORCE_MESH parameter to mesh even for very small parts
# - removed the RRI that was always added put in the BED_MESH_CALIBRATE call. Now it's added only when there is one defined in the [bed_mesh] section
# v2.3: moved the install notes into a proper markdown file in: docs > features > adaptive_bed_mesh.md
# v2.2: removed the requirement to set mesh_pps in the [bed_mesh] section. It's now again optional as it should be
# v2.1: fix for the nominal mesh (when no SIZE parameter is used or SIZE=0_0_0_0)
# v2.0: split in multple macros to be able to use the center point in the z calibration bed probing position before doing the mesh
# v1.1: fix for a bug when parsing string when using uppercase letters in the [bed_mesh] section
# v1.0: first adaptive bed mesh macro
# -------------------------------------------------------------------------------------------------------------------------
# If you want to use it into your own config, please install it as a standalone macro as described in the
# installation section of this file: docs > features > adaptive_bed_mesh.md
# -------------------------------------------------------------------------------------------------------------------------
### What is it ? ###
# The adaptive bed mesh is simple: it's a normal bed mesh, but only "where" and "when" it's necessary.
# Sometime I print small parts, sometime I print full plates and I like to get a precise bed_mesh (like 9x9 or more). However, it take a
# lot of time and it's useless to probe all the plate for only a 5cm² part. So this is where the adaptive bed mesh is helping:
# 1. It get the corners coordinates of the fisrt layer surface either from the slicer or the [exclude_object] tags
# 2. It compute a new set of points to probe on this new zone to get at least the same precision as your standard bed mesh. For example, if
# a normal bed mesh is set to 9x9 for 300mm², it will then compute 3x3 for a 100mm² surface. Also if for whatever reason your parts are in
# the corner of the build plate (like for a damaged PEI in the center), it will follow them to probe this exact area.
# 3. To go further, it will not do any bed_mesh if there is less than 3x3 points to probe (very small part alone) and choose/change the
# algorithm (bicubic/lagrange) depending of the size and shape of the mesh computed (like 3x3 vs 3x9)
# Feel free to ping me on Discord (Frix_x#0161) if you need help or have any comments to improve it :)
# ===========================================================================================================
# DO NOT MODIFY THOSE VARIABLES (they are used internaly by the adaptive bed mesh macro)
[gcode_macro _ADAPTIVE_MESH_VARIABLES]
variable_ready: False
variable_do_mesh: False
variable_do_nominal: False
variable_mesh_min: 0,0
variable_mesh_max: 0,0
variable_probe_count: 0,0
variable_algo: "bicubic"
gcode:
[gcode_macro COMPUTE_MESH_PARAMETERS]
description: Compute the mesh parameters and store them for later use
gcode:
# 1 ----- GET ORIGINAL BEDMESH PARAMS FROM CONFIG ----------------------
{% set xMinConf, yMinConf = printer["configfile"].config["bed_mesh"]["mesh_min"].split(',')|map('trim')|map('int') %}
{% set xMaxConf, yMaxConf = printer["configfile"].config["bed_mesh"]["mesh_max"].split(',')|map('trim')|map('int') %}
{% set xProbeCntConf, yProbeCntConf = printer["configfile"].config["bed_mesh"]["probe_count"].split(',')|map('trim')|map('int') %}
{% set algo = printer["configfile"].config["bed_mesh"]["algorithm"]|lower %}
{% set xMeshPPS, yMeshPPS = (printer["configfile"].config["bed_mesh"]["mesh_pps"]|default('2,2')).split(',')|map('trim')|map('int') %}
{% set margin = params.MARGIN|default(5)|int %} # additional margin to mesh around the first layer
{% set force_mesh = params.FORCE_MESH|default(False) %} # force the mesh even if it's a small part (ie. computed less than 3x3)
# 2 ----- GET FIRST LAYER COORDINATES and SIZE -------------------------------------
# If the SIZE parameter is defined and not a dummy placeholder, we use it to do the adaptive bed mesh logic
{% set coordinatesFound = false %}
{% if params.SIZE is defined and params.SIZE != "0_0_0_0" %}
RESPOND MSG="Got a SIZE parameter for the adaptive bed mesh"
{% set xMinSpec, yMinSpec, xMaxSpec, yMaxSpec = params.SIZE.split('_')|map('trim')|map('int') %}
{% set coordinatesFound = true %}
{% elif printer.exclude_object is defined %}
{% if printer.exclude_object.objects %}
# Else if SIZE is not defined, we fallback to use the [exclude_object] tags
# This method is derived from Kyleisah KAMP repository: https://github.com/kyleisah/Klipper-Adaptive-Meshing-Purging)
RESPOND MSG="No SIZE parameter, using the [exclude_object] tags for the adaptive bed mesh"
{% set eo_points = printer.exclude_object.objects|map(attribute='polygon')|sum(start=[]) %}
{% set xMinSpec = eo_points|map(attribute=0)|min %}
{% set yMinSpec = eo_points|map(attribute=1)|min %}
{% set xMaxSpec = eo_points|map(attribute=0)|max %}
{% set yMaxSpec = eo_points|map(attribute=1)|max %}
{% set coordinatesFound = true %}
{% endif %}
{% endif %}
{% if not coordinatesFound %}
# If no SIZE parameter and no [exclude_object] tags, then we want to do a nominal bed mesh
# so nothing to do here...
RESPOND MSG="No info about the first layer coordinates, doing a nominal bed mesh instead of adaptive"
{% endif %}
# If the first layer size was correctly retrieved, we can do the adaptive bed mesh logic, else we
# fallback to the original and nominal BED_MESH_CALIBRATE function (full bed probing)
{% if xMinSpec and yMinSpec and xMaxSpec and yMaxSpec %}
# 3 ----- APPLY MARGINS ----------------------------------------------
# We use min/max function as we want it to be constrained by the original
# bedmesh size. This will avoid going outside the machine limits
{% set xMin = [xMinConf, (xMinSpec - margin)]|max %}
{% set xMax = [xMaxConf, (xMaxSpec + margin)]|min %}
{% set yMin = [yMinConf, (yMinSpec - margin)]|max %}
{% set yMax = [yMaxConf, (yMaxSpec + margin)]|min %}
# 4 ----- COMPUTE A NEW PROBE COUNT ----------------------------------
# The goal is to have at least the same precision as from the config. So we compute an equivalent number
# of probe points on each X/Y dimensions (distance between two points should be the same as in the config)
{% set xProbeCnt = ((xMax - xMin) * xProbeCntConf / (xMaxConf - xMinConf))|round(0, 'ceil')|int %}
{% set yProbeCnt = ((yMax - yMin) * yProbeCntConf / (yMaxConf - yMinConf))|round(0, 'ceil')|int %}
# Then, three possibilities :
# a) Both dimensions have less than 3 probe points : the bed_mesh is not needed as it's a small print (if not forced).
# b) If one of the dimension is less than 3 and the other is greater. The print looks to be elongated and
# need the adaptive bed_mesh : we add probing points to the small direction to reach 3 and be able to do it.
# c) If both direction are greater than 3, we need the adaptive bed_mesh and it's ok.
# At the end we control (according to Klipper bed_mesh method: "_verify_algorithm") that the computed probe_count is
# valid according to the choosen algorithm or change it if needed.
{% if xProbeCnt < 3 and yProbeCnt < 3 %}
{% if force_mesh %}
RESPOND MSG="Bed mesh forced (small part detected): meshing 3x3..."
{% set xProbeCnt = 3 %}
{% set yProbeCnt = 3 %}
{% set algo = "lagrange" %}
{% set mesh_min = "%d,%d"|format(xMin, yMin) %}
{% set mesh_max = "%d,%d"|format(xMax, yMax) %}
{% set probe_count = "%d,%d"|format(xProbeCnt, yProbeCnt) %}
RESPOND MSG="Computed mesh parameters: MESH_MIN={mesh_min} MESH_MAX={mesh_max} PROBE_COUNT={probe_count} ALGORITHM={algo}"
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_mesh VALUE={True}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_nominal VALUE={False}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=mesh_min VALUE='"{mesh_min}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=mesh_max VALUE='"{mesh_max}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=probe_count VALUE='"{probe_count}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=algo VALUE='"{algo}"'
{% else %}
RESPOND MSG="Computed mesh parameters: none, bed mesh not needed for very small parts"
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_mesh VALUE={False}
{% endif %}
{% else %}
{% set xProbeCnt = [3, xProbeCnt]|max %}
{% set yProbeCnt = [3, yProbeCnt]|max %}
# Check of the probe points and interpolation algorithms according to Klipper code
{% if xMeshPPS != 0 or yMeshPPS != 0 %}
{% set probeCntMin = [xProbeCnt, yProbeCnt]|min %}
{% set probeCntMax = [xProbeCnt, yProbeCnt]|max %}
{% if algo == "lagrange" and probeCntMax > 6 %}
# Lagrange interpolation tends to oscillate when using more than 6 samples: swith to bicubic
{% set algo = "bicubic" %}
{% endif %}
{% if algo == "bicubic" and probeCntMin < 4 %}
{% if probeCntMax > 6 %}
# Impossible case: need to add probe point on the small axis to be >= 4 (we want 5 to keep it odd)
{% if xProbeCnt > yProbeCnt %}
{% set yProbeCnt = 5 %}
{% else %}
{% set xProbeCnt = 5 %}
{% endif %}
{% else %}
# In this case bicubic is not adapted (less than 4 points): switch to lagrange
{% set algo = "lagrange" %}
{% endif %}
{% endif %}
{% endif %}
# 5 ----- FORMAT THE PARAMETERS AND SAVE THEM ---------------------------
{% set mesh_min = "%d,%d"|format(xMin, yMin) %}
{% set mesh_max = "%d,%d"|format(xMax, yMax) %}
{% set probe_count = "%d,%d"|format(xProbeCnt, yProbeCnt) %}
RESPOND MSG="Computed mesh parameters: MESH_MIN={mesh_min} MESH_MAX={mesh_max} PROBE_COUNT={probe_count} ALGORITHM={algo}"
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_mesh VALUE={True}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_nominal VALUE={False}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=mesh_min VALUE='"{mesh_min}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=mesh_max VALUE='"{mesh_max}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=probe_count VALUE='"{probe_count}"'
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=algo VALUE='"{algo}"'
{% endif %}
{% else %}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_mesh VALUE={True}
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=do_nominal VALUE={True}
{% endif %}
# Finaly save in the variables that we already computed the values
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=ready VALUE={True}
[gcode_macro ADAPTIVE_BED_MESH]
description: Perform a bed mesh, but only where and when it's needed
gcode:
{% set ready = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].ready %}
{% if not 'xyz' in printer.toolhead.homed_axes %}
{ action_raise_error("Must Home printer first!") }
{% endif %}
# If the parameters where computed, we can do the mesh by calling the _DO_ADAPTIVE_MESH
{% if ready %}
_DO_ADAPTIVE_MESH
# If the parameters where not computed prior to the ADAPTIVE_BED_MESH call, we call the COMPUTE_MESH_PARAMETERS
# macro first and then call the _DO_ADAPTIVE_MESH macro after it
{% else %}
RESPOND MSG="Adaptive bed mesh: parameters not already computed, automatically calling the COMPUTE_MESH_PARAMETERS macro prior to the mesh"
COMPUTE_MESH_PARAMETERS {rawparams}
M400 # mandatory to flush the gcode buffer and be sure to use the last computed parameters
_DO_ADAPTIVE_MESH
{% endif %}
[gcode_macro _DO_ADAPTIVE_MESH]
gcode:
# 1 ----- POPULATE BEDMESH PARAMS FROM SAVED VARIABLES ----------------------
{% set do_mesh = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].do_mesh %}
{% set do_nominal = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].do_nominal %}
{% set mesh_min = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].mesh_min %}
{% set mesh_max = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].mesh_max %}
{% set probe_count = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].probe_count %}
{% set algo = printer["gcode_macro _ADAPTIVE_MESH_VARIABLES"].algo %}
# 2 --------- ADAPTIVE_BED_MESH LOGIC --------------------------------------
# If it's necessary to do a mesh
{% if do_mesh %}
# If it's a standard bed_mesh to be done
{% if do_nominal %}
RESPOND MSG="Adaptive bed mesh: nominal bed mesh"
BED_MESH_CALIBRATE
{% else %}
RESPOND MSG="Adaptive bed mesh: MESH_MIN={mesh_min} MESH_MAX={mesh_max} PROBE_COUNT={probe_count} ALGORITHM={algo}"
BED_MESH_CALIBRATE MESH_MIN={mesh_min} MESH_MAX={mesh_max} PROBE_COUNT={probe_count} ALGORITHM={algo}
{% endif %}
{% else %}
RESPOND MSG="Adaptive bed mesh: no mesh to be done"
{% endif %}
# Set back the 'ready' parameter to false
SET_GCODE_VARIABLE MACRO=_ADAPTIVE_MESH_VARIABLES VARIABLE=ready VALUE={False}

View File

@@ -138,8 +138,13 @@ gcode:
BED_MESH_CALIBRATE PROFILE={default_profile}
BED_MESH_PROFILE LOAD={default_profile}
{% endif %}
{% if printer["gcode_macro RatOS"].nozzle_scrub_enabled|lower == 'true' %}
M190 S{TARGET_TEMP}
clean_nozzle
M140 S0
{% endif %}
{% if printer["gcode_macro RatOS"].touch_cart_enabled|lower == 'true' %}
CARTOGRAPHER_TOUCH ; Perform touch probe
CARTOGRAPHER_TOUCH FUZZY = {printer["gcode_macro RatOS"].touch_cart_fuzzy} ; Perform touch probe
{% endif %}
M190 S{TARGET_TEMP}
{% elif printer["gcode_macro RatOS"].bed_mesh_profile is defined %}
@@ -166,6 +171,13 @@ gcode:
{% if has_offset %}
ADD_PRIME_PROBE_TO_OFFSET
{% endif %}
{% if printer["gcode_macro RatOS"].nozzle_priming|lower == 'auto' %}
{% if params.MATERIAL is defined and params.MATERIAL|lower == 'tpu'%}
PRIME_LINE
{% else %}
PRIME_BLOB
{% endif %}
{% endif %}
{% if printer["gcode_macro RatOS"].nozzle_priming|lower == 'primeline' %}
PRIME_LINE
{% endif %}