Prusa3d Marlin fork
mesh_bed_calibration.h
1 #pragma once
2 
3 #include "Marlin.h"
4 
5 #define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1
6 #define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4
7 
8 #ifdef HEATBED_V2
9 
10 #define BED_X0 (2.f - BED_ZERO_REF_X) //1
11 #define BED_Y0 (9.4f - BED_ZERO_REF_Y) //1
12 #define BED_Xn (206.f - BED_ZERO_REF_X) //205
13 #define BED_Yn (213.4f - BED_ZERO_REF_Y) //205
14 
15 #else
16 
17 #define BED_X0 (13.f - BED_ZERO_REF_X)
18 #define BED_Y0 (8.4f - BED_ZERO_REF_Y)
19 #define BED_Xn (216.f - BED_ZERO_REF_X)
20 #define BED_Yn (202.4f - BED_ZERO_REF_Y)
21 
22 #endif //not HEATBED_V2
23 
24 constexpr float x_mesh_density = (BED_Xn - BED_X0) / (MESH_NUM_X_POINTS - 1);
25 constexpr float y_mesh_density = (BED_Yn - BED_Y0) / (MESH_NUM_Y_POINTS - 1);
26 
27 // Exact positions of the print head above the bed reference points, in the world coordinates.
28 // The world coordinates match the machine coordinates only in case, when the machine
29 // is built properly, the end stops are at the correct positions and the axes are perpendicular.
30 extern const float bed_ref_points_4[] PROGMEM;
31 
32 extern const float bed_skew_angle_mild;
33 extern const float bed_skew_angle_extreme;
34 
35 // Is the world2machine correction activated?
36 enum World2MachineCorrectionMode
37 {
38  WORLD2MACHINE_CORRECTION_NONE = 0,
39  WORLD2MACHINE_CORRECTION_SHIFT = 1,
40  WORLD2MACHINE_CORRECTION_SKEW = 2,
41 };
42 extern uint8_t world2machine_correction_mode;
43 // 2x2 transformation matrix from the world coordinates to the machine coordinates.
44 // Corrects for the rotation and skew of the machine axes.
45 // Used by the planner's plan_buffer_line() and plan_set_position().
46 extern float world2machine_rotation_and_skew[2][2];
47 extern float world2machine_rotation_and_skew_inv[2][2];
48 // Shift of the machine zero point, in the machine coordinates.
49 extern float world2machine_shift[2];
50 
51 extern void world2machine_reset();
53 extern void world2machine_initialize();
54 extern void world2machine_read_valid(float vec_x[2], float vec_y[2], float cntr[2]);
55 extern void world2machine_update_current();
56 
57 inline void world2machine(float &x, float &y)
58 {
59  if (world2machine_correction_mode == WORLD2MACHINE_CORRECTION_NONE) {
60  // No correction.
61  } else {
62  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SKEW) {
63  // Firs the skew & rotation correction.
64  float out_x = world2machine_rotation_and_skew[0][0] * x + world2machine_rotation_and_skew[0][1] * y;
65  float out_y = world2machine_rotation_and_skew[1][0] * x + world2machine_rotation_and_skew[1][1] * y;
66  x = out_x;
67  y = out_y;
68  }
69  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SHIFT) {
70  // Then add the offset.
71  x += world2machine_shift[0];
72  y += world2machine_shift[1];
73  }
74  }
75 }
76 
77 inline void world2machine(const float &x, const float &y, float &out_x, float &out_y)
78 {
79  out_x = x;
80  out_y = y;
81  world2machine(out_x, out_y);
82 }
83 
84 inline void machine2world(float x, float y, float &out_x, float &out_y)
85 {
86  if (world2machine_correction_mode == WORLD2MACHINE_CORRECTION_NONE) {
87  // No correction.
88  out_x = x;
89  out_y = y;
90  } else {
91  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SHIFT) {
92  // Then add the offset.
93  x -= world2machine_shift[0];
94  y -= world2machine_shift[1];
95  }
96  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SKEW) {
97  // Firs the skew & rotation correction.
98  out_x = world2machine_rotation_and_skew_inv[0][0] * x + world2machine_rotation_and_skew_inv[0][1] * y;
99  out_y = world2machine_rotation_and_skew_inv[1][0] * x + world2machine_rotation_and_skew_inv[1][1] * y;
100  }
101  }
102 }
103 
104 inline void machine2world(float &x, float &y)
105 {
106  if (world2machine_correction_mode == WORLD2MACHINE_CORRECTION_NONE) {
107  // No correction.
108  } else {
109  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SHIFT) {
110  // Then add the offset.
111  x -= world2machine_shift[0];
112  y -= world2machine_shift[1];
113  }
114  if (world2machine_correction_mode & WORLD2MACHINE_CORRECTION_SKEW) {
115  // Firs the skew & rotation correction.
116  float out_x = world2machine_rotation_and_skew_inv[0][0] * x + world2machine_rotation_and_skew_inv[0][1] * y;
117  float out_y = world2machine_rotation_and_skew_inv[1][0] * x + world2machine_rotation_and_skew_inv[1][1] * y;
118  x = out_x;
119  y = out_y;
120  }
121  }
122 }
123 
124 inline bool world2machine_clamp(float &x, float &y)
125 {
126  bool clamped = false;
127  float tmpx, tmpy;
128  world2machine(x, y, tmpx, tmpy);
129  if (tmpx < X_MIN_POS) {
130  tmpx = X_MIN_POS;
131  clamped = true;
132  } else if (tmpx > X_MAX_POS) {
133  tmpx = X_MAX_POS;
134  clamped = true;
135  }
136 
137  if (tmpy < Y_MIN_POS) {
138  tmpy = Y_MIN_POS;
139  clamped = true;
140  } else if (tmpy > Y_MAX_POS) {
141  tmpy = Y_MAX_POS;
142  clamped = true;
143  }
144  if (clamped)
145  machine2world(tmpx, tmpy, x, y);
146  return clamped;
147 }
148 
152 float BED_X(const uint8_t col);
153 
157 float BED_Y(const uint8_t row);
158 
166 enum BedSkewOffsetDetectionResultType {
167  // Detection failed, some point was not found.
168  BED_SKEW_OFFSET_DETECTION_POINT_FOUND = 0,
169  BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND = -1,
170  BED_SKEW_OFFSET_DETECTION_FITTING_FAILED = -2,
171  BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED = -3,
172 
173  // Detection finished with success.
174  BED_SKEW_OFFSET_DETECTION_PERFECT = 0,
175  BED_SKEW_OFFSET_DETECTION_SKEW_MILD = 1,
176  BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME = 2
177 };
178 
179 bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0);
180 BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level = 0);
181 void go_home_with_z_lift();
182 
183 extern BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level, uint8_t &too_far_mask);
184 #ifndef NEW_XYZCAL
185 extern BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8_t verbosity_level, uint8_t &too_far_mask);
186 #endif //NEW_XYZCAL
187 
188 extern bool sample_mesh_and_store_reference();
189 
190 extern void reset_bed_offset_and_skew();
191 extern bool is_bed_z_jitter_data_valid();
192 
193 // Scan the mesh bed induction points one by one by a left-right zig-zag movement,
194 // write the trigger coordinates to the serial line.
195 // Useful for visualizing the behavior of the bed induction detector.
196 extern bool scan_bed_induction_points(int8_t verbosity_level);
197 
198 // Load Z babystep value from the EEPROM into babystepLoadZ,
199 // but don't apply it through the planner. This is useful on wake up
200 // after power panic, when it is expected, that the baby step has been already applied.
201 extern void babystep_load();
202 
203 // Apply Z babystep value from the EEPROM through the planner.
204 extern void babystep_apply();
205 
206 // Undo the current Z babystep value.
207 extern void babystep_undo();
208 
209 // Reset the current babystep counter without moving the axes.
210 extern void babystep_reset();
211 
212 
213 extern void count_xyz_details(float (&distanceMin)[2]);
214 extern bool sample_z();
215 
216 extern void mbl_settings_init();
217 extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy);
218 extern void mbl_magnet_elimination();
world2machine_initialize()
Read and apply validated calibration data from EEPROM.
Definition: mesh_bed_calibration.cpp:867
world2machine_revert_to_uncorrected()
Set calibration matrix to identity and update current position with absolute position.
Definition: mesh_bed_calibration.cpp:766
world2machine_update_current()
Update current position after switching to corrected coordinates.
Definition: mesh_bed_calibration.cpp:902