New feature: BED_SKEW_CORRECTION
This commit is contained in:
		
							parent
							
								
									082ab8fcab
								
							
						
					
					
						commit
						0154e3480c
					
				| @ -62,7 +62,7 @@ script: | |||||||
|   - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS |   - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS | ||||||
|   - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS |   - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS | ||||||
|   - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED |   - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED | ||||||
|   - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE |   - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE | ||||||
|   - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU |   - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU | ||||||
|   - opt_set ABL_GRID_POINTS_X 16 |   - opt_set ABL_GRID_POINTS_X 16 | ||||||
|   - opt_set ABL_GRID_POINTS_Y 16 |   - opt_set ABL_GRID_POINTS_Y 16 | ||||||
|  | |||||||
| @ -832,7 +832,7 @@ | |||||||
| //===========================================================================
 | //===========================================================================
 | ||||||
| //=============================== Bed Leveling ==============================
 | //=============================== Bed Leveling ==============================
 | ||||||
| //===========================================================================
 | //===========================================================================
 | ||||||
| // @section bedlevel
 | // @section calibrate
 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Choose one of the options below to enable G29 Bed Leveling. The parameters |  * Choose one of the options below to enable G29 Bed Leveling. The parameters | ||||||
| @ -1039,6 +1039,63 @@ | |||||||
| #define HOMING_FEEDRATE_XY (50*60) | #define HOMING_FEEDRATE_XY (50*60) | ||||||
| #define HOMING_FEEDRATE_Z  (4*60) | #define HOMING_FEEDRATE_Z  (4*60) | ||||||
| 
 | 
 | ||||||
|  | // @section calibrate
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Bed Skew Compensation | ||||||
|  |  * | ||||||
|  |  * This feature corrects for misalignment in the XYZ axes. | ||||||
|  |  * | ||||||
|  |  * Take the following steps to get the bed skew in the XY plane: | ||||||
|  |  *  1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185)
 | ||||||
|  |  *  2. For XY_DIAG_AC measure the diagonal A to C | ||||||
|  |  *  3. For XY_DIAG_BD measure the diagonal B to D | ||||||
|  |  *  4. For XY_SIDE_AD measure the edge A to D | ||||||
|  |  * | ||||||
|  |  * Marlin automatically computes skew factors from these measurements. | ||||||
|  |  * Skew factors may also be computed and set manually: | ||||||
|  |  * | ||||||
|  |  *  - Compute AB     : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2 | ||||||
|  |  *  - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD))) | ||||||
|  |  * | ||||||
|  |  * If desired, follow the same procedure for XZ and YZ. | ||||||
|  |  * Use these diagrams for reference: | ||||||
|  |  * | ||||||
|  |  *    Y                     Z                     Z | ||||||
|  |  *    ^     B-------C       ^     B-------C       ^     B-------C | ||||||
|  |  *    |    /       /        |    /       /        |    /       / | ||||||
|  |  *    |   /       /         |   /       /         |   /       / | ||||||
|  |  *    |  A-------D          |  A-------D          |  A-------D | ||||||
|  |  *    +-------------->X     +-------------->X     +-------------->Y | ||||||
|  |  *     XY_SKEW_FACTOR        XZ_SKEW_FACTOR        YZ_SKEW_FACTOR | ||||||
|  |  */ | ||||||
|  | //#define SKEW_CORRECTION
 | ||||||
|  | 
 | ||||||
|  | #if ENABLED(SKEW_CORRECTION) | ||||||
|  |   // Input all length measurements here:
 | ||||||
|  |   #define XY_DIAG_AC 282.8427124746 | ||||||
|  |   #define XY_DIAG_BD 282.8427124746 | ||||||
|  |   #define XY_SIDE_AD 200 | ||||||
|  | 
 | ||||||
|  |   // Or, set the default skew factors directly here
 | ||||||
|  |   // to override the above measurements:
 | ||||||
|  |   #define XY_SKEW_FACTOR 0.0 | ||||||
|  | 
 | ||||||
|  |   //#define SKEW_CORRECTION_FOR_Z
 | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |     #define XZ_DIAG_AC 282.8427124746 | ||||||
|  |     #define XZ_DIAG_BD 282.8427124746 | ||||||
|  |     #define YZ_DIAG_AC 282.8427124746 | ||||||
|  |     #define YZ_DIAG_BD 282.8427124746 | ||||||
|  |     #define YZ_SIDE_AD 200 | ||||||
|  |     #define XZ_SKEW_FACTOR 0.0 | ||||||
|  |     #define YZ_SKEW_FACTOR 0.0 | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   // Enable this option for M852 to set skew at runtime
 | ||||||
|  |   //#define SKEW_CORRECTION_GCODE
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| //=============================================================================
 | //=============================================================================
 | ||||||
| //============================= Additional Features ===========================
 | //============================= Additional Features ===========================
 | ||||||
| //=============================================================================
 | //=============================================================================
 | ||||||
|  | |||||||
| @ -130,7 +130,6 @@ | |||||||
| #define MSG_ERR_LINE_NO                     "Line Number is not Last Line Number+1, Last Line: " | #define MSG_ERR_LINE_NO                     "Line Number is not Last Line Number+1, Last Line: " | ||||||
| #define MSG_ERR_CHECKSUM_MISMATCH           "checksum mismatch, Last Line: " | #define MSG_ERR_CHECKSUM_MISMATCH           "checksum mismatch, Last Line: " | ||||||
| #define MSG_ERR_NO_CHECKSUM                 "No Checksum with line number, Last Line: " | #define MSG_ERR_NO_CHECKSUM                 "No Checksum with line number, Last Line: " | ||||||
| #define MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM "No Line Number with checksum, Last Line: " |  | ||||||
| #define MSG_FILE_PRINTED                    "Done printing file" | #define MSG_FILE_PRINTED                    "Done printing file" | ||||||
| #define MSG_BEGIN_FILE_LIST                 "Begin file list" | #define MSG_BEGIN_FILE_LIST                 "Begin file list" | ||||||
| #define MSG_END_FILE_LIST                   "End file list" | #define MSG_END_FILE_LIST                   "End file list" | ||||||
| @ -163,6 +162,9 @@ | |||||||
| #define MSG_Z2_MAX                          "z2_max: " | #define MSG_Z2_MAX                          "z2_max: " | ||||||
| #define MSG_Z_PROBE                         "z_probe: " | #define MSG_Z_PROBE                         "z_probe: " | ||||||
| #define MSG_PROBE_Z_OFFSET                  "Probe Z Offset" | #define MSG_PROBE_Z_OFFSET                  "Probe Z Offset" | ||||||
|  | #define MSG_SKEW_MIN                        "min_skew_factor: " | ||||||
|  | #define MSG_SKEW_MAX                        "max_skew_factor: " | ||||||
|  | #define MSG_SKEW_WARN                       "WARNING: Skew compensation disabled (outside MIN/MAX limits)" | ||||||
| #define MSG_FILAMENT_RUNOUT_SENSOR          "filament: " | #define MSG_FILAMENT_RUNOUT_SENSOR          "filament: " | ||||||
| #define MSG_ERR_MATERIAL_INDEX              "M145 S<index> out of range (0-1)" | #define MSG_ERR_MATERIAL_INDEX              "M145 S<index> out of range (0-1)" | ||||||
| #define MSG_ERR_M355_NONE                   "No case light" | #define MSG_ERR_M355_NONE                   "No case light" | ||||||
|  | |||||||
							
								
								
									
										89
									
								
								Marlin/src/gcode/calibrate/M852.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Marlin/src/gcode/calibrate/M852.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | |||||||
|  | /**
 | ||||||
|  |  * Marlin 3D Printer Firmware | ||||||
|  |  * Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "../../inc/MarlinConfig.h" | ||||||
|  | 
 | ||||||
|  | #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  | 
 | ||||||
|  | #include "../gcode.h" | ||||||
|  | #include "../../module/planner.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * M852: Get or set the machine skew factors. Reports current values with no arguments. | ||||||
|  |  * | ||||||
|  |  *  S[xy_factor] - Alias for 'I' | ||||||
|  |  *  I[xy_factor] - New XY skew factor | ||||||
|  |  *  J[xz_factor] - New XZ skew factor | ||||||
|  |  *  K[yz_factor] - New YZ skew factor | ||||||
|  |  */ | ||||||
|  | void GcodeSuite::M852() { | ||||||
|  |   const bool ijk = parser.seen('I') || parser.seen('S') | ||||||
|  |     #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |       || parser.seen('J') || parser.seen('K') | ||||||
|  |     #endif | ||||||
|  |   ; | ||||||
|  |   bool badval = false; | ||||||
|  | 
 | ||||||
|  |   if (parser.seen('I') || parser.seen('S')) { | ||||||
|  |     const float value = parser.value_linear_units(); | ||||||
|  |     if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) | ||||||
|  |       planner.xy_skew_factor = value; | ||||||
|  |     else | ||||||
|  |       badval = true; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  | 
 | ||||||
|  |     if (parser.seen('J')) { | ||||||
|  |       const float value = parser.value_linear_units(); | ||||||
|  |       if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) | ||||||
|  |         planner.xz_skew_factor = value; | ||||||
|  |       else | ||||||
|  |         badval = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (parser.seen('K')) { | ||||||
|  |       const float value = parser.value_linear_units(); | ||||||
|  |       if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) | ||||||
|  |         planner.yz_skew_factor = value; | ||||||
|  |       else | ||||||
|  |         badval = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|  |   if (badval) | ||||||
|  |     SERIAL_ECHOLNPGM(MSG_SKEW_MIN " " STRINGIFY(SKEW_FACTOR_MIN) " " MSG_SKEW_MAX " " STRINGIFY(SKEW_FACTOR_MAX)); | ||||||
|  | 
 | ||||||
|  |   if (!ijk) { | ||||||
|  |     SERIAL_ECHO_START(); | ||||||
|  |     SERIAL_ECHOPAIR(MSG_SKEW_FACTOR " XY: ", planner.xy_skew_factor); | ||||||
|  |     #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |       SERIAL_ECHOPAIR(" XZ: ", planner.xz_skew_factor); | ||||||
|  |       SERIAL_ECHOLNPAIR(" YZ: ", planner.yz_skew_factor); | ||||||
|  |     #else | ||||||
|  |       SERIAL_EOL(); | ||||||
|  |     #endif | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif // SKEW_CORRECTION_GCODE
 | ||||||
| @ -622,6 +622,12 @@ void GcodeSuite::process_parsed_command() { | |||||||
|           break; |           break; | ||||||
|       #endif // HAS_BED_PROBE
 |       #endif // HAS_BED_PROBE
 | ||||||
| 
 | 
 | ||||||
|  |       #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |         case 852: // M852: Set Skew factors
 | ||||||
|  |           M852(); | ||||||
|  |           break; | ||||||
|  |       #endif | ||||||
|  | 
 | ||||||
|       #if ENABLED(ADVANCED_PAUSE_FEATURE) |       #if ENABLED(ADVANCED_PAUSE_FEATURE) | ||||||
|         case 600: // M600: Pause for filament change
 |         case 600: // M600: Pause for filament change
 | ||||||
|           M600(); |           M600(); | ||||||
|  | |||||||
| @ -201,6 +201,7 @@ | |||||||
|  * M666 - Set delta endstop adjustment. (Requires DELTA) |  * M666 - Set delta endstop adjustment. (Requires DELTA) | ||||||
|  * M605 - Set dual x-carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE) |  * M605 - Set dual x-carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE) | ||||||
|  * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.) |  * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.) | ||||||
|  |  * M852 - Set skew factors: "M852 [I<xy>] [J<xz>] [K<yz>]". (Requires SKEW_CORRECTION_GCODE, and SKEW_CORRECTION_FOR_Z for IJ) | ||||||
|  * M860 - Report the position of position encoder modules. |  * M860 - Report the position of position encoder modules. | ||||||
|  * M861 - Report the status of position encoder modules. |  * M861 - Report the status of position encoder modules. | ||||||
|  * M862 - Perform an axis continuity test for position encoder modules. |  * M862 - Perform an axis continuity test for position encoder modules. | ||||||
| @ -705,6 +706,10 @@ private: | |||||||
|     static void M851(); |     static void M851(); | ||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |     static void M852(); | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|   #if ENABLED(I2C_POSITION_ENCODERS) |   #if ENABLED(I2C_POSITION_ENCODERS) | ||||||
|     FORCE_INLINE static void M860() { I2CPEM.M860(); } |     FORCE_INLINE static void M860() { I2CPEM.M860(); } | ||||||
|     FORCE_INLINE static void M861() { I2CPEM.M861(); } |     FORCE_INLINE static void M861() { I2CPEM.M861(); } | ||||||
|  | |||||||
| @ -888,6 +888,49 @@ | |||||||
|   #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 |   #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * XYZ Bed Skew Correction | ||||||
|  |  */ | ||||||
|  | #if ENABLED(SKEW_CORRECTION) | ||||||
|  |   #define SKEW_FACTOR_MIN -1 | ||||||
|  |   #define SKEW_FACTOR_MAX 1 | ||||||
|  | 
 | ||||||
|  |   #define _GET_SIDE(a,b,c) (SQRT(2*sq(a)+2*sq(b)-4*sq(c))*0.5) | ||||||
|  |   #define _SKEW_SIDE(a,b,c) tan(M_PI*0.5-acos((sq(a)-sq(b)-sq(c))/(2*c*b))) | ||||||
|  |   #define _SKEW_FACTOR(a,b,c) _SKEW_SIDE(a,_GET_SIDE(a,b,c),c) | ||||||
|  | 
 | ||||||
|  |   #ifndef XY_SKEW_FACTOR | ||||||
|  |     constexpr float XY_SKEW_FACTOR = ( | ||||||
|  |       #if defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD) | ||||||
|  |         _SKEW_FACTOR(XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD) | ||||||
|  |       #else | ||||||
|  |         0.0 | ||||||
|  |       #endif | ||||||
|  |     ); | ||||||
|  |   #endif | ||||||
|  |   #ifndef XZ_SKEW_FACTOR | ||||||
|  |     #if defined(XY_SIDE_AD) && !defined(XZ_SIDE_AD) | ||||||
|  |       #define XZ_SIDE_AD XY_SIDE_AD | ||||||
|  |     #endif | ||||||
|  |     constexpr float XZ_SKEW_FACTOR = ( | ||||||
|  |       #if defined(XZ_DIAG_AC) && defined(XZ_DIAG_BD) && defined(XZ_SIDE_AD) | ||||||
|  |         _SKEW_FACTOR(XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD) | ||||||
|  |       #else | ||||||
|  |         0.0 | ||||||
|  |       #endif | ||||||
|  |     ); | ||||||
|  |   #endif | ||||||
|  |   #ifndef YZ_SKEW_FACTOR | ||||||
|  |     constexpr float YZ_SKEW_FACTOR = ( | ||||||
|  |       #if defined(YZ_DIAG_AC) && defined(YZ_DIAG_BD) && defined(YZ_SIDE_AD) | ||||||
|  |         _SKEW_FACTOR(YZ_DIAG_AC, YZ_DIAG_BD, YZ_SIDE_AD) | ||||||
|  |       #else | ||||||
|  |         0.0 | ||||||
|  |       #endif | ||||||
|  |     ); | ||||||
|  |   #endif | ||||||
|  | #endif // SKEW_CORRECTION
 | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Heater & Fan Pausing |  * Heater & Fan Pausing | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -1483,4 +1483,18 @@ static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too m | |||||||
|   #error "LED_CONTROL_MENU requires an LCD controller." |   #error "LED_CONTROL_MENU requires an LCD controller." | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if ENABLED(SKEW_CORRECTION) | ||||||
|  |   #if !defined(XY_SKEW_FACTOR) && !(defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD)) | ||||||
|  |     #error "SKEW_CORRECTION requires XY_SKEW_FACTOR or XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD." | ||||||
|  |   #endif | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |     #if !defined(XZ_SKEW_FACTOR) && !(defined(XZ_DIAG_AC) && defined(XZ_DIAG_BD) && defined(XZ_SIDE_AD)) | ||||||
|  |       #error "SKEW_CORRECTION requires XZ_SKEW_FACTOR or XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD." | ||||||
|  |     #endif | ||||||
|  |     #if !defined(YZ_SKEW_FACTOR) && !(defined(YZ_DIAG_AC) && defined(YZ_DIAG_BD) && defined(YZ_SIDE_AD)) | ||||||
|  |       #error "SKEW_CORRECTION requires YZ_SKEW_FACTOR or YZ_DIAG_AC, YZ_DIAG_BD, YZ_SIDE_AD." | ||||||
|  |     #endif | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #endif // _SANITYCHECK_H_
 | #endif // _SANITYCHECK_H_
 | ||||||
|  | |||||||
| @ -698,6 +698,9 @@ | |||||||
| #ifndef MSG_ZPROBE_OUT | #ifndef MSG_ZPROBE_OUT | ||||||
|   #define MSG_ZPROBE_OUT                      _UxGT("Z probe out. bed") |   #define MSG_ZPROBE_OUT                      _UxGT("Z probe out. bed") | ||||||
| #endif | #endif | ||||||
|  | #ifndef MSG_SKEW_FACTOR | ||||||
|  |   #define MSG_SKEW_FACTOR                     _UxGT("Skew Factor") | ||||||
|  | #endif | ||||||
| #ifndef MSG_BLTOUCH | #ifndef MSG_BLTOUCH | ||||||
|   #define MSG_BLTOUCH                         _UxGT("BLTouch") |   #define MSG_BLTOUCH                         _UxGT("BLTouch") | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -36,13 +36,13 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #define EEPROM_VERSION "V45" | #define EEPROM_VERSION "V46" | ||||||
| 
 | 
 | ||||||
| // Change EEPROM version if these are changed:
 | // Change EEPROM version if these are changed:
 | ||||||
| #define EEPROM_OFFSET 100 | #define EEPROM_OFFSET 100 | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * V45 EEPROM Layout: |  * V46 EEPROM Layout: | ||||||
|  * |  * | ||||||
|  *  100  Version                                    (char x4) |  *  100  Version                                    (char x4) | ||||||
|  *  104  EEPROM CRC16                               (uint16_t) |  *  104  EEPROM CRC16                               (uint16_t) | ||||||
| @ -166,8 +166,13 @@ | |||||||
|  * CNC_COORDINATE_SYSTEMS                           108 bytes |  * CNC_COORDINATE_SYSTEMS                           108 bytes | ||||||
|  *  602  G54-G59.3 coordinate_system                (float x 27) |  *  602  G54-G59.3 coordinate_system                (float x 27) | ||||||
|  * |  * | ||||||
|  *  710                                   Minimum end-point |  * SKEW_CORRECTION:                                 12 bytes | ||||||
|  * 2239 (710 + 208 + 36 + 9 + 288 + 988)  Maximum end-point |  *  710  M852 I    planner.xy_skew_factor           (float) | ||||||
|  |  *  714  M852 J    planner.xz_skew_factor           (float) | ||||||
|  |  *  718  M852 K    planner.yz_skew_factor           (float) | ||||||
|  |  * | ||||||
|  |  *  722                                   Minimum end-point | ||||||
|  |  * 2251 (722 + 208 + 36 + 9 + 288 + 988)  Maximum end-point | ||||||
|  * |  * | ||||||
|  * ======================================================================== |  * ======================================================================== | ||||||
|  * meshes_begin (between max and min end-point, directly above) |  * meshes_begin (between max and min end-point, directly above) | ||||||
| @ -633,6 +638,10 @@ void MarlinSettings::postprocess() { | |||||||
|       for (uint8_t q = 3; q--;) EEPROM_WRITE(dummyui32); |       for (uint8_t q = 3; q--;) EEPROM_WRITE(dummyui32); | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|  |     //
 | ||||||
|  |     // CNC Coordinate Systems
 | ||||||
|  |     //
 | ||||||
|  | 
 | ||||||
|     #if ENABLED(CNC_COORDINATE_SYSTEMS) |     #if ENABLED(CNC_COORDINATE_SYSTEMS) | ||||||
|       EEPROM_WRITE(coordinate_system); // 27 floats
 |       EEPROM_WRITE(coordinate_system); // 27 floats
 | ||||||
|     #else |     #else | ||||||
| @ -640,6 +649,19 @@ void MarlinSettings::postprocess() { | |||||||
|       for (uint8_t q = 27; q--;) EEPROM_WRITE(dummy); |       for (uint8_t q = 27; q--;) EEPROM_WRITE(dummy); | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|  |     //
 | ||||||
|  |     // Skew correction factors
 | ||||||
|  |     //
 | ||||||
|  | 
 | ||||||
|  |     #if ENABLED(SKEW_CORRECTION) | ||||||
|  |       EEPROM_WRITE(planner.xy_skew_factor); | ||||||
|  |       EEPROM_WRITE(planner.xz_skew_factor); | ||||||
|  |       EEPROM_WRITE(planner.yz_skew_factor); | ||||||
|  |     #else | ||||||
|  |       dummy = 0.0f; | ||||||
|  |       for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); | ||||||
|  |     #endif | ||||||
|  | 
 | ||||||
|     if (!eeprom_error) { |     if (!eeprom_error) { | ||||||
|       #if ENABLED(EEPROM_CHITCHAT) |       #if ENABLED(EEPROM_CHITCHAT) | ||||||
|         const int eeprom_size = eeprom_index; |         const int eeprom_size = eeprom_index; | ||||||
| @ -1078,6 +1100,23 @@ void MarlinSettings::postprocess() { | |||||||
|         for (uint8_t q = 27; q--;) EEPROM_READ(dummy); |         for (uint8_t q = 27; q--;) EEPROM_READ(dummy); | ||||||
|       #endif |       #endif | ||||||
| 
 | 
 | ||||||
|  |       //
 | ||||||
|  |       // Skew correction factors
 | ||||||
|  |       //
 | ||||||
|  | 
 | ||||||
|  |       #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |         EEPROM_READ(planner.xy_skew_factor); | ||||||
|  |         #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |           EEPROM_READ(planner.xz_skew_factor); | ||||||
|  |           EEPROM_READ(planner.yz_skew_factor); | ||||||
|  |         #else | ||||||
|  |           EEPROM_READ(dummy); | ||||||
|  |           EEPROM_READ(dummy); | ||||||
|  |         #endif | ||||||
|  |       #else | ||||||
|  |         for (uint8_t q = 3; q--;) EEPROM_READ(dummy); | ||||||
|  |       #endif | ||||||
|  | 
 | ||||||
|       if (working_crc == stored_crc) { |       if (working_crc == stored_crc) { | ||||||
|         postprocess(); |         postprocess(); | ||||||
|         #if ENABLED(EEPROM_CHITCHAT) |         #if ENABLED(EEPROM_CHITCHAT) | ||||||
| @ -1463,6 +1502,14 @@ void MarlinSettings::reset() { | |||||||
|     ubl.reset(); |     ubl.reset(); | ||||||
|   #endif |   #endif | ||||||
| 
 | 
 | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |     planner.xy_skew_factor = XY_SKEW_FACTOR; | ||||||
|  |     #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |       planner.xz_skew_factor = XZ_SKEW_FACTOR; | ||||||
|  |       planner.yz_skew_factor = YZ_SKEW_FACTOR; | ||||||
|  |     #endif | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|   postprocess(); |   postprocess(); | ||||||
| 
 | 
 | ||||||
|   #if ENABLED(EEPROM_CHITCHAT) |   #if ENABLED(EEPROM_CHITCHAT) | ||||||
| @ -1887,6 +1934,24 @@ void MarlinSettings::reset() { | |||||||
|       SERIAL_ECHOLNPAIR("  M851 Z", LINEAR_UNIT(zprobe_zoffset)); |       SERIAL_ECHOLNPAIR("  M851 Z", LINEAR_UNIT(zprobe_zoffset)); | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Bed Skew Correction | ||||||
|  |      */ | ||||||
|  |     #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |       if (!forReplay) { | ||||||
|  |         CONFIG_ECHO_START; | ||||||
|  |         SERIAL_ECHOLNPGM("Skew Factor: "); | ||||||
|  |       } | ||||||
|  |       CONFIG_ECHO_START; | ||||||
|  |       #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |         SERIAL_ECHOPAIR("  M852 I", LINEAR_UNIT(planner.xy_skew_factor)); | ||||||
|  |         SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.xz_skew_factor)); | ||||||
|  |         SERIAL_ECHOLNPAIR(" K", LINEAR_UNIT(planner.yz_skew_factor)); | ||||||
|  |       #else | ||||||
|  |         SERIAL_ECHOLNPAIR("  M852 S", LINEAR_UNIT(planner.xy_skew_factor)); | ||||||
|  |       #endif | ||||||
|  |     #endif | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * TMC2130 stepper driver current |      * TMC2130 stepper driver current | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -135,6 +135,20 @@ float Planner::min_feedrate_mm_s, | |||||||
|   #endif |   #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if ENABLED(SKEW_CORRECTION) | ||||||
|  |   #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |     // Initialized by settings.load()
 | ||||||
|  |     float Planner::xy_skew_factor; | ||||||
|  |     #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |       float Planner::xz_skew_factor, Planner::yz_skew_factor; | ||||||
|  |     #else | ||||||
|  |       constexpr float Planner::xz_skew_factor, Planner::yz_skew_factor; | ||||||
|  |     #endif | ||||||
|  |   #else | ||||||
|  |     constexpr float Planner::xy_skew_factor, Planner::xz_skew_factor, Planner::yz_skew_factor; | ||||||
|  |   #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if ENABLED(AUTOTEMP) | #if ENABLED(AUTOTEMP) | ||||||
|   float Planner::autotemp_max = 250, |   float Planner::autotemp_max = 250, | ||||||
|         Planner::autotemp_min = 210, |         Planner::autotemp_min = 210, | ||||||
| @ -565,6 +579,19 @@ void Planner::calculate_volumetric_multipliers() { | |||||||
|    */ |    */ | ||||||
|   void Planner::apply_leveling(float &rx, float &ry, float &rz) { |   void Planner::apply_leveling(float &rx, float &ry, float &rz) { | ||||||
| 
 | 
 | ||||||
|  |     #if ENABLED(SKEW_CORRECTION) | ||||||
|  |       if (WITHIN(rx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(ry, Y_MIN_POS + 1, Y_MAX_POS)) { | ||||||
|  |         const float tempry = ry - (rz * planner.yz_skew_factor), | ||||||
|  |                     temprx = rx - (ry * planner.xy_skew_factor) - (rz * (planner.xz_skew_factor - (planner.xy_skew_factor * planner.yz_skew_factor))); | ||||||
|  |         if (WITHIN(temprx, X_MIN_POS, X_MAX_POS) && WITHIN(tempry, Y_MIN_POS, Y_MAX_POS)) { | ||||||
|  |           rx = temprx; | ||||||
|  |           ry = tempry; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |           SERIAL_ECHOLN(MSG_SKEW_WARN); | ||||||
|  |       } | ||||||
|  |     #endif | ||||||
|  | 
 | ||||||
|     if (!leveling_active) return; |     if (!leveling_active) return; | ||||||
| 
 | 
 | ||||||
|     #if ABL_PLANAR |     #if ABL_PLANAR | ||||||
| @ -611,45 +638,56 @@ void Planner::calculate_volumetric_multipliers() { | |||||||
| 
 | 
 | ||||||
|   void Planner::unapply_leveling(float raw[XYZ]) { |   void Planner::unapply_leveling(float raw[XYZ]) { | ||||||
| 
 | 
 | ||||||
|     if (!leveling_active) return; |     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) | ||||||
| 
 |       const float fade_scaling_factor = fade_scaling_factor_for_z(raw[Z_AXIS]); | ||||||
|     #if ABL_PLANAR |  | ||||||
| 
 |  | ||||||
|       matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); |  | ||||||
| 
 |  | ||||||
|       float dx = raw[X_AXIS] - (X_TILT_FULCRUM), |  | ||||||
|             dy = raw[Y_AXIS] - (Y_TILT_FULCRUM); |  | ||||||
| 
 |  | ||||||
|       apply_rotation_xyz(inverse, dx, dy, raw[Z_AXIS]); |  | ||||||
| 
 |  | ||||||
|       raw[X_AXIS] = dx + X_TILT_FULCRUM; |  | ||||||
|       raw[Y_AXIS] = dy + Y_TILT_FULCRUM; |  | ||||||
| 
 |  | ||||||
|     #else |     #else | ||||||
|  |       constexpr float fade_scaling_factor = 1.0; | ||||||
|  |     #endif | ||||||
| 
 | 
 | ||||||
|       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) |     if (leveling_active && fade_scaling_factor) { | ||||||
|         const float fade_scaling_factor = fade_scaling_factor_for_z(raw[Z_AXIS]); |  | ||||||
|         if (!fade_scaling_factor) return; |  | ||||||
|       #elif HAS_MESH |  | ||||||
|         constexpr float fade_scaling_factor = 1.0; |  | ||||||
|       #endif |  | ||||||
| 
 | 
 | ||||||
|       raw[Z_AXIS] -= ( |       #if ABL_PLANAR | ||||||
|         #if ENABLED(AUTO_BED_LEVELING_UBL) |  | ||||||
|           ubl.get_z_correction(raw[X_AXIS], raw[Y_AXIS]) * fade_scaling_factor |  | ||||||
|         #elif ENABLED(MESH_BED_LEVELING) |  | ||||||
|           mbl.get_z(raw[X_AXIS], raw[Y_AXIS] |  | ||||||
|             #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) |  | ||||||
|               , fade_scaling_factor |  | ||||||
|             #endif |  | ||||||
|           ) |  | ||||||
|         #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) |  | ||||||
|           bilinear_z_offset(raw) * fade_scaling_factor |  | ||||||
|         #else |  | ||||||
|           0 |  | ||||||
|         #endif |  | ||||||
|       ); |  | ||||||
| 
 | 
 | ||||||
|  |         matrix_3x3 inverse = matrix_3x3::transpose(bed_level_matrix); | ||||||
|  | 
 | ||||||
|  |         float dx = raw[X_AXIS] - (X_TILT_FULCRUM), | ||||||
|  |               dy = raw[Y_AXIS] - (Y_TILT_FULCRUM); | ||||||
|  | 
 | ||||||
|  |         apply_rotation_xyz(inverse, dx, dy, raw[Z_AXIS]); | ||||||
|  | 
 | ||||||
|  |         raw[X_AXIS] = dx + X_TILT_FULCRUM; | ||||||
|  |         raw[Y_AXIS] = dy + Y_TILT_FULCRUM; | ||||||
|  | 
 | ||||||
|  |       #else // !ABL_PLANAR
 | ||||||
|  | 
 | ||||||
|  |         raw[Z_AXIS] -= ( | ||||||
|  |           #if ENABLED(AUTO_BED_LEVELING_UBL) | ||||||
|  |             ubl.get_z_correction(raw[X_AXIS], raw[Y_AXIS]) * fade_scaling_factor | ||||||
|  |           #elif ENABLED(MESH_BED_LEVELING) | ||||||
|  |             mbl.get_z(raw[X_AXIS], raw[Y_AXIS] | ||||||
|  |               #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) | ||||||
|  |                 , fade_scaling_factor | ||||||
|  |               #endif | ||||||
|  |             ) | ||||||
|  |           #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) | ||||||
|  |             bilinear_z_offset(raw) * fade_scaling_factor | ||||||
|  |           #else | ||||||
|  |             0 | ||||||
|  |           #endif | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |       #endif // !ABL_PLANAR
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #if ENABLED(SKEW_CORRECTION) | ||||||
|  |       if (WITHIN(raw[X_AXIS], X_MIN_POS, X_MAX_POS) && WITHIN(raw[Y_AXIS], Y_MIN_POS, Y_MAX_POS)) { | ||||||
|  |         const float temprx = raw[X_AXIS] + raw[Y_AXIS] * planner.xy_skew_factor + raw[Z_AXIS] * planner.xz_skew_factor, | ||||||
|  |                     tempry = raw[Y_AXIS] + raw[Z_AXIS] * planner.yz_skew_factor; | ||||||
|  |         if (WITHIN(temprx, X_MIN_POS, X_MAX_POS) && WITHIN(tempry, Y_MIN_POS, Y_MAX_POS)) { | ||||||
|  |           raw[X_AXIS] = temprx; | ||||||
|  |           raw[Y_AXIS] = tempry; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -658,13 +696,13 @@ void Planner::calculate_volumetric_multipliers() { | |||||||
| /**
 | /**
 | ||||||
|  * Planner::_buffer_line |  * Planner::_buffer_line | ||||||
|  * |  * | ||||||
|  * Add a new linear movement to the buffer. |  * Add a new linear movement to the buffer in axis units. | ||||||
|  * |  * | ||||||
|  * Leveling and kinematics should be applied ahead of calling this. |  * Leveling and kinematics should be applied ahead of calling this. | ||||||
|  * |  * | ||||||
|  *  a,b,c,e     - target positions in mm or degrees |  *  a,b,c,e   - target positions in mm and/or degrees | ||||||
|  *  fr_mm_s     - (target) speed of the move |  *  fr_mm_s   - (target) speed of the move | ||||||
|  *  extruder    - target extruder |  *  extruder  - target extruder | ||||||
|  */ |  */ | ||||||
| void Planner::_buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder) { | void Planner::_buffer_line(const float &a, const float &b, const float &c, const float &e, float fr_mm_s, const uint8_t extruder) { | ||||||
| 
 | 
 | ||||||
| @ -713,6 +751,10 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const | |||||||
|   SERIAL_EOL(); |   SERIAL_EOL(); | ||||||
|   //*/
 |   //*/
 | ||||||
| 
 | 
 | ||||||
|  |   // DRYRUN ignores all temperature constraints and assures that the extruder is instantly satisfied
 | ||||||
|  |   if (DEBUGGING(DRYRUN)) | ||||||
|  |     position[E_AXIS] = target[E_AXIS]; | ||||||
|  | 
 | ||||||
|   int32_t de = target[E_AXIS] - position[E_AXIS]; |   int32_t de = target[E_AXIS] - position[E_AXIS]; | ||||||
| 
 | 
 | ||||||
|   #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) |   #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) | ||||||
| @ -736,6 +778,10 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const | |||||||
|     } |     } | ||||||
|   #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE
 |   #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE
 | ||||||
| 
 | 
 | ||||||
|  |   #if ENABLED(LIN_ADVANCE) | ||||||
|  |     float de_float = de * steps_to_mm[E_AXIS_N]; | ||||||
|  |   #endif | ||||||
|  | 
 | ||||||
|   // Compute direction bit-mask for this block
 |   // Compute direction bit-mask for this block
 | ||||||
|   uint8_t dm = 0; |   uint8_t dm = 0; | ||||||
|   #if CORE_IS_XY |   #if CORE_IS_XY | ||||||
| @ -1332,6 +1378,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const | |||||||
|   previous_safe_speed = safe_speed; |   previous_safe_speed = safe_speed; | ||||||
| 
 | 
 | ||||||
|   #if ENABLED(LIN_ADVANCE) |   #if ENABLED(LIN_ADVANCE) | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * |      * | ||||||
|      * Use LIN_ADVANCE for blocks if all these are true: |      * Use LIN_ADVANCE for blocks if all these are true: | ||||||
|  | |||||||
| @ -180,6 +180,23 @@ class Planner { | |||||||
|       static float extruder_advance_k, advance_ed_ratio; |       static float extruder_advance_k, advance_ed_ratio; | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|  |     #if ENABLED(SKEW_CORRECTION) | ||||||
|  |       #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |         static float xy_skew_factor; | ||||||
|  |       #else | ||||||
|  |         static constexpr float xy_skew_factor = XY_SKEW_FACTOR; | ||||||
|  |       #endif | ||||||
|  |       #if ENABLED(SKEW_CORRECTION_FOR_Z) | ||||||
|  |         #if ENABLED(SKEW_CORRECTION_GCODE) | ||||||
|  |           static float xz_skew_factor, yz_skew_factor; | ||||||
|  |         #else | ||||||
|  |           static constexpr float xz_skew_factor = XZ_SKEW_FACTOR, yz_skew_factor = YZ_SKEW_FACTOR; | ||||||
|  |         #endif | ||||||
|  |       #else | ||||||
|  |         static constexpr float xz_skew_factor = 0, yz_skew_factor = 0; | ||||||
|  |       #endif | ||||||
|  |     #endif | ||||||
|  | 
 | ||||||
|   private: |   private: | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user