Skip to content

Commit

Permalink
✨ X Twist Compensation & Calibration (MarlinFirmware#23238)
Browse files Browse the repository at this point in the history
  • Loading branch information
Giuseppe499 authored Dec 7, 2021
1 parent c67f7fb commit a16a059
Show file tree
Hide file tree
Showing 20 changed files with 417 additions and 23 deletions.
16 changes: 16 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,22 @@
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
#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

// Include a page of printer information in the LCD Main Menu
Expand Down
59 changes: 59 additions & 0 deletions Marlin/src/feature/bedlevel/abl/x_twist.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 37 additions & 0 deletions Marlin/src/feature/bedlevel/abl/x_twist.h
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions Marlin/src/feature/bedlevel/bedlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class TemporaryBedLevelingState {

#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
#include "abl/abl.h"
#if ENABLED(X_AXIS_TWIST_COMPENSATION)
#include "abl/x_twist.h"
#endif
#elif ENABLED(AUTO_BED_LEVELING_UBL)
#include "ubl/ubl.h"
#elif ENABLED(MESH_BED_LEVELING)
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/gcode/bedlevel/abl/G29.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ G29_TYPE GcodeSuite::G29() {
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)

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));

#endif
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -3391,6 +3391,10 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#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(BACKUP_POWER_SUPPLY) && !PIN_EXISTS(POWER_LOSS)
#error "BACKUP_POWER_SUPPLY requires a POWER_LOSS_PIN."
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/lcd/language/language_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,10 @@ namespace Language_en {
LSTR MSG_PROBE_WIZARD_PROBING = _UxGT("Probing Z Reference");
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_TOP_LEFT = _UxGT("Top Left");
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/lcd/marlinui.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ class MarlinUI {
//
// 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
static bool wait_for_move;
#else
Expand Down
12 changes: 9 additions & 3 deletions Marlin/src/lcd/menu/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,21 @@
#include "../../module/probe.h"
#endif

#if EITHER(ENABLE_LEVELING_FADE_HEIGHT, AUTO_BED_LEVELING_UBL)
#if HAS_LEVELING
#include "../../feature/bedlevel/bedlevel.h"
#endif

////////////////////////////////////////////
///////////// 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
int8_t encoderTopLine, encoderLine, screen_items;

Expand Down Expand Up @@ -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); }
#endif

Expand Down
13 changes: 13 additions & 0 deletions Marlin/src/lcd/menu/menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ void _lcd_draw_homing();
void goto_probe_offset_wizard();
#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))
void _lcd_toggle_bed_leveling();
#endif
Expand Down Expand Up @@ -249,3 +254,11 @@ extern uint8_t screen_history_depth;
inline void clear_menu_history() { screen_history_depth = 0; }

#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
4 changes: 4 additions & 0 deletions Marlin/src/lcd/menu/menu_advanced.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ void menu_backlash();
SUBMENU(MSG_PROBE_WIZARD, goto_probe_offset_wizard);
#endif

#if ENABLED(X_AXIS_TWIST_COMPENSATION)
SUBMENU(MSG_XATC, xatc_wizard_continue);
#endif

END_MENU();
}
#endif
Expand Down
4 changes: 0 additions & 4 deletions Marlin/src/lcd/menu/menu_bed_corners.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@

static_assert(LEVEL_CORNERS_Z_HOP >= 0, "LEVEL_CORNERS_Z_HOP must be >= 0. Please update your configuration.");

#if HAS_LEVELING
static bool leveling_was_active = false;
#endif

#ifndef LEVEL_CORNERS_LEVELING_ORDER
#define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, LB, RB } // Default
//#define LEVEL_CORNERS_LEVELING_ORDER { LF, LB, RF } // 3 hard-coded points
Expand Down
2 changes: 0 additions & 2 deletions Marlin/src/lcd/menu/menu_bed_leveling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@
// Motion > Level Bed handlers
//

static uint8_t manual_probe_index;

// LCD probed points are from defaults
constexpr uint8_t total_probe_points = TERN(AUTO_BED_LEVELING_3POINT, 3, GRID_MAX_POINTS);

Expand Down
9 changes: 9 additions & 0 deletions Marlin/src/lcd/menu/menu_motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ void lcd_move_x() { _lcd_move_xyz(GET_TEXT(MSG_MOVE_X), X_AXIS); }

#endif // E_MANUAL

#if EITHER(PROBE_OFFSET_WIZARD, X_AXIS_TWIST_COMPENSATION)

void _goto_manual_move_z(const_float_t scale) {
ui.manual_move.menu_scale = scale;
ui.goto_screen(lcd_move_z);
}

#endif

//
// "Motion" > "Move Xmm" > "Move XYZ" submenu
//
Expand Down
11 changes: 2 additions & 9 deletions Marlin/src/lcd/menu/menu_probe_offset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@
#include "../../feature/bedlevel/bedlevel.h"
#endif

void _goto_manual_move_z(const_float_t);

// Global storage
float z_offset_backup, calculated_z_offset, z_offset_ref;

#if HAS_LEVELING
bool leveling_was_active;
#endif

inline void z_clearance_move() {
do_z_clearance(
#ifdef Z_AFTER_HOMING
Expand All @@ -65,11 +63,6 @@ void set_offset_and_go_back(const_float_t z) {
ui.goto_previous_screen_no_defer();
}

void _goto_manual_move_z(const_float_t scale) {
ui.manual_move.menu_scale = scale;
ui.goto_screen(lcd_move_z);
}

void probe_offset_wizard_menu() {
START_MENU();
calculated_z_offset = probe.offset.z + current_position.z - z_offset_ref;
Expand Down
Loading

0 comments on commit a16a059

Please sign in to comment.