Browse Source

✨ X Twist Compensation & Calibration (#23238)

Giuseppe499 3 years ago
parent
commit
a16a059312

+ 16 - 0
Marlin/Configuration_adv.h

@@ -1270,6 +1270,22 @@
       // Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
       // Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
       //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
       //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
     #endif
     #endif
+
+    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
+      // Add a calibration procedure in the Probe Offsets menu
+      // to compensate for twist in the X-axis.
+      //#define X_AXIS_TWIST_COMPENSATION
+      #if ENABLED(X_AXIS_TWIST_COMPENSATION)
+        /**
+         * Enable to init the Probe Z-Offset when starting the Wizard.
+         * Use a height slightly above the estimated nozzle-to-probe Z offset.
+         * For example, with an offset of -5, consider a starting height of -4.
+         */
+        #define XATC_START_Z 0.0
+        #define XATC_MAX_POINTS 3             // Number of points to probe in the wizard
+        #define XATC_Y_POSITION Y_CENTER      // (mm) Y position to probe
+      #endif
+    #endif
   #endif
   #endif
 
 
   // Include a page of printer information in the LCD Main Menu
   // Include a page of printer information in the LCD Main Menu

+ 59 - 0
Marlin/src/feature/bedlevel/abl/x_twist.cpp

@@ -0,0 +1,59 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(X_AXIS_TWIST_COMPENSATION)
+
+#include "../bedlevel.h"
+
+XATC xatc;
+
+float XATC::spacing, XATC::start;
+xatc_points_t XATC::z_values;
+
+void XATC::print_points() {
+  SERIAL_ECHOLNPGM(" X-Twist Correction:");
+  LOOP_L_N(x, XATC_MAX_POINTS) {
+    SERIAL_CHAR(' ');
+    if (!isnan(z_values[x])) {
+      if (z_values[x] >= 0) SERIAL_CHAR('+');
+      SERIAL_ECHO_F(z_values[x], 3);
+    }
+    else {
+      LOOP_L_N(i, 6)
+        SERIAL_CHAR(i ? '=' : ' ');
+    }
+  }
+  SERIAL_EOL();
+}
+
+float lerp(const_float_t t, const_float_t a, const_float_t b) { return a + t * (b - a); }
+
+float XATC::compensation(const xy_pos_t &raw) {
+  float t = (raw.x - start) / spacing;
+  int i = FLOOR(t);
+  LIMIT(i, 0, XATC_MAX_POINTS - 2);
+  t -= i;
+  return lerp(t, z_values[i], z_values[i + 1]);
+}
+
+#endif // X_AXIS_TWIST_COMPENSATION

+ 37 - 0
Marlin/src/feature/bedlevel/abl/x_twist.h

@@ -0,0 +1,37 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfigPre.h"
+
+typedef float xatc_points_t[XATC_MAX_POINTS];
+
+class XATC {
+public:
+  static float spacing, start;
+  static xatc_points_t z_values;
+
+  static float compensation(const xy_pos_t &raw);
+  static void print_points();
+};
+
+extern XATC xatc;

+ 3 - 0
Marlin/src/feature/bedlevel/bedlevel.h

@@ -63,6 +63,9 @@ class TemporaryBedLevelingState {
 
 
   #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
   #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
     #include "abl/abl.h"
     #include "abl/abl.h"
+    #if ENABLED(X_AXIS_TWIST_COMPENSATION)
+      #include "abl/x_twist.h"
+    #endif
   #elif ENABLED(AUTO_BED_LEVELING_UBL)
   #elif ENABLED(AUTO_BED_LEVELING_UBL)
     #include "ubl/ubl.h"
     #include "ubl/ubl.h"
   #elif ENABLED(MESH_BED_LEVELING)
   #elif ENABLED(MESH_BED_LEVELING)

+ 1 - 1
Marlin/src/gcode/bedlevel/abl/G29.cpp

@@ -662,7 +662,7 @@ G29_TYPE GcodeSuite::G29() {
           #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
           #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
 
 
             const float z = abl.measured_z + abl.Z_offset;
             const float z = abl.measured_z + abl.Z_offset;
-            z_values[abl.meshCount.x][abl.meshCount.y] = z;
+            z_values[abl.meshCount.x][abl.meshCount.y] = z PLUS_TERN0(X_AXIS_TWIST_COMPENSATION, xatc.compensation(abl.probePos));
             TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z));
             TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z));
 
 
           #endif
           #endif

+ 4 - 0
Marlin/src/inc/SanityCheck.h

@@ -3391,6 +3391,10 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
   #endif
   #endif
 #endif
 #endif
 
 
+#if BOTH(X_AXIS_TWIST_COMPENSATION, NOZZLE_AS_PROBE)
+  #error "X_AXIS_TWIST_COMPENSATION is incompatible with NOZZLE_AS_PROBE."
+#endif
+
 #if ENABLED(POWER_LOSS_RECOVERY)
 #if ENABLED(POWER_LOSS_RECOVERY)
   #if ENABLED(BACKUP_POWER_SUPPLY) && !PIN_EXISTS(POWER_LOSS)
   #if ENABLED(BACKUP_POWER_SUPPLY) && !PIN_EXISTS(POWER_LOSS)
     #error "BACKUP_POWER_SUPPLY requires a POWER_LOSS_PIN."
     #error "BACKUP_POWER_SUPPLY requires a POWER_LOSS_PIN."

+ 4 - 0
Marlin/src/lcd/language/language_en.h

@@ -734,6 +734,10 @@ namespace Language_en {
   LSTR MSG_PROBE_WIZARD_PROBING           = _UxGT("Probing Z Reference");
   LSTR MSG_PROBE_WIZARD_PROBING           = _UxGT("Probing Z Reference");
   LSTR MSG_PROBE_WIZARD_MOVING            = _UxGT("Moving to Probing Pos");
   LSTR MSG_PROBE_WIZARD_MOVING            = _UxGT("Moving to Probing Pos");
 
 
+  LSTR MSG_XATC                           = _UxGT("X-Twist Wizard");
+  LSTR MSG_XATC_DONE                      = _UxGT("X-Twist Wizard Done!");
+  LSTR MSG_XATC_UPDATE_Z_OFFSET           = _UxGT("Update Probe Z-Offset to ");
+
   LSTR MSG_SOUND                          = _UxGT("Sound");
   LSTR MSG_SOUND                          = _UxGT("Sound");
 
 
   LSTR MSG_TOP_LEFT                       = _UxGT("Top Left");
   LSTR MSG_TOP_LEFT                       = _UxGT("Top Left");

+ 1 - 1
Marlin/src/lcd/marlinui.h

@@ -640,7 +640,7 @@ public:
   //
   //
   // Special handling if a move is underway
   // Special handling if a move is underway
   //
   //
-  #if ANY(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION, PROBE_OFFSET_WIZARD) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING))
+  #if ANY(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION, PROBE_OFFSET_WIZARD, X_AXIS_TWIST_COMPENSATION) || (ENABLED(LCD_BED_LEVELING) && EITHER(PROBE_MANUALLY, MESH_BED_LEVELING))
     #define LCD_HAS_WAIT_FOR_MOVE 1
     #define LCD_HAS_WAIT_FOR_MOVE 1
     static bool wait_for_move;
     static bool wait_for_move;
   #else
   #else

+ 9 - 3
Marlin/src/lcd/menu/menu.cpp

@@ -38,7 +38,7 @@
   #include "../../module/probe.h"
   #include "../../module/probe.h"
 #endif
 #endif
 
 
-#if EITHER(ENABLE_LEVELING_FADE_HEIGHT, AUTO_BED_LEVELING_UBL)
+#if HAS_LEVELING
   #include "../../feature/bedlevel/bedlevel.h"
   #include "../../feature/bedlevel/bedlevel.h"
 #endif
 #endif
 
 
@@ -46,6 +46,13 @@
 ///////////// Global Variables /////////////
 ///////////// Global Variables /////////////
 ////////////////////////////////////////////
 ////////////////////////////////////////////
 
 
+#if HAS_LEVELING && ANY(LEVEL_BED_CORNERS, PROBE_OFFSET_WIZARD, X_AXIS_TWIST_COMPENSATION)
+  bool leveling_was_active; // = false
+#endif
+#if ANY(PROBE_MANUALLY, MESH_BED_LEVELING, X_AXIS_TWIST_COMPENSATION)
+  uint8_t manual_probe_index; // = 0
+#endif
+
 // Menu Navigation
 // Menu Navigation
 int8_t encoderTopLine, encoderLine, screen_items;
 int8_t encoderTopLine, encoderLine, screen_items;
 
 
@@ -338,8 +345,7 @@ void _lcd_draw_homing() {
   }
   }
 }
 }
 
 
-#if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS))
-  #include "../../feature/bedlevel/bedlevel.h"
+#if HAS_LEVELING && DISABLED(SLIM_LCD_MENUS)
   void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(!planner.leveling_active); }
   void _lcd_toggle_bed_leveling() { set_bed_leveling_enabled(!planner.leveling_active); }
 #endif
 #endif
 
 

+ 13 - 0
Marlin/src/lcd/menu/menu.h

@@ -218,6 +218,11 @@ void _lcd_draw_homing();
   void goto_probe_offset_wizard();
   void goto_probe_offset_wizard();
 #endif
 #endif
 
 
+#if ENABLED(X_AXIS_TWIST_COMPENSATION)
+  void xatc_wizard_continue();
+  void menu_advanced_settings();
+#endif
+
 #if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS))
 #if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS))
   void _lcd_toggle_bed_leveling();
   void _lcd_toggle_bed_leveling();
 #endif
 #endif
@@ -249,3 +254,11 @@ extern uint8_t screen_history_depth;
 inline void clear_menu_history() { screen_history_depth = 0; }
 inline void clear_menu_history() { screen_history_depth = 0; }
 
 
 #define STICKY_SCREEN(S) []{ ui.defer_status_screen(); ui.goto_screen(S); }
 #define STICKY_SCREEN(S) []{ ui.defer_status_screen(); ui.goto_screen(S); }
+
+#if HAS_LEVELING && ANY(LEVEL_BED_CORNERS, PROBE_OFFSET_WIZARD, X_AXIS_TWIST_COMPENSATION)
+  extern bool leveling_was_active;
+#endif
+
+#if ANY(PROBE_MANUALLY, MESH_BED_LEVELING, X_AXIS_TWIST_COMPENSATION)
+  extern uint8_t manual_probe_index;
+#endif

Some files were not shown because too many files changed in this diff