mesh_bed_leveling.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "mesh_bed_leveling.h"
  2. #include "Configuration.h"
  3. #ifdef MESH_BED_LEVELING
  4. mesh_bed_leveling mbl;
  5. mesh_bed_leveling::mesh_bed_leveling() { reset(); }
  6. void mesh_bed_leveling::reset() {
  7. active = 0;
  8. for (int y = 0; y < MESH_NUM_Y_POINTS; y++)
  9. for (int x = 0; x < MESH_NUM_X_POINTS; x++)
  10. z_values[y][x] = 0;
  11. }
  12. static inline bool vec_undef(const float v[2])
  13. {
  14. const uint32_t *vx = (const uint32_t*)v;
  15. return vx[0] == 0x0FFFFFFFF || vx[1] == 0x0FFFFFFFF;
  16. }
  17. void mesh_bed_leveling::get_meas_xy(int ix, int iy, float &x, float &y, bool use_default)
  18. {
  19. float cntr[2] = {
  20. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0)),
  21. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4))
  22. };
  23. float vec_x[2] = {
  24. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0)),
  25. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4))
  26. };
  27. float vec_y[2] = {
  28. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0)),
  29. eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4))
  30. };
  31. if (use_default || vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y)) {
  32. // Default, uncorrected positions of the calibration points. Works well for correctly built printers.
  33. x = float(MESH_MIN_X) + float(MEAS_NUM_X_DIST) * float(ix) - X_PROBE_OFFSET_FROM_EXTRUDER;
  34. //FIXME
  35. //x -= 5.f;
  36. y = float(MESH_MIN_Y) + float(MEAS_NUM_Y_DIST) * float(iy) - Y_PROBE_OFFSET_FROM_EXTRUDER;
  37. } else {
  38. #if 0
  39. SERIAL_ECHO("Running bed leveling. Calibration data: ");
  40. SERIAL_ECHO(cntr[0]);
  41. SERIAL_ECHO(",");
  42. SERIAL_ECHO(cntr[1]);
  43. SERIAL_ECHO(", x: ");
  44. SERIAL_ECHO(vec_x[0]);
  45. SERIAL_ECHO(",");
  46. SERIAL_ECHO(vec_x[1]);
  47. SERIAL_ECHO(", y: ");
  48. SERIAL_ECHO(vec_y[0]);
  49. SERIAL_ECHO(",");
  50. SERIAL_ECHO(vec_y[1]);
  51. SERIAL_ECHOLN("");
  52. #endif
  53. x = cntr[0];
  54. y = cntr[1];
  55. if (ix < 1) {
  56. x -= vec_x[0];
  57. y -= vec_x[1];
  58. } else if (ix > 1) {
  59. x += vec_x[0];
  60. y += vec_x[1];
  61. }
  62. if (iy < 1) {
  63. x -= vec_y[0];
  64. y -= vec_y[1];
  65. } else if (iy > 1) {
  66. x += vec_y[0];
  67. y += vec_y[1];
  68. }
  69. #if 0
  70. SERIAL_ECHO("Calibration point position: ");
  71. SERIAL_ECHO(x);
  72. SERIAL_ECHO(",");
  73. SERIAL_ECHO(y);
  74. SERIAL_ECHOLN("");
  75. #endif
  76. }
  77. }
  78. #if MESH_NUM_X_POINTS>=5 && MESH_NUM_Y_POINTS>=5 && (MESH_NUM_X_POINTS&1)==1 && (MESH_NUM_Y_POINTS&1)==1
  79. // Works for an odd number of MESH_NUM_X_POINTS and MESH_NUM_Y_POINTS
  80. void mesh_bed_leveling::upsample_3x3()
  81. {
  82. int idx0 = 0;
  83. int idx1 = MESH_NUM_X_POINTS / 2;
  84. int idx2 = MESH_NUM_X_POINTS - 1;
  85. {
  86. // First interpolate the points in X axis.
  87. static const float x0 = MESH_MIN_X;
  88. static const float x1 = 0.5f * float(MESH_MIN_X + MESH_MAX_X);
  89. static const float x2 = MESH_MAX_X;
  90. for (int j = 0; j < 3; ++ j) {
  91. // 1) Copy the source points to their new destination.
  92. z_values[j][idx2] = z_values[j][2];
  93. z_values[j][idx1] = z_values[j][1];
  94. // 2) Interpolate the remaining values by Largrangian polynomials.
  95. for (int i = idx0 + 1; i < idx2; ++ i) {
  96. if (i == idx1)
  97. continue;
  98. float x = get_x(i);
  99. z_values[j][i] = z_values[j][idx0] * (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2)) +
  100. z_values[j][idx1] * (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2)) +
  101. z_values[j][idx2] * (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
  102. }
  103. }
  104. }
  105. {
  106. // Second interpolate the points in Y axis.
  107. static const float y0 = MESH_MIN_Y;
  108. static const float y1 = 0.5f * float(MESH_MIN_Y + MESH_MAX_Y);
  109. static const float y2 = MESH_MAX_Y;
  110. for (int i = 0; i < MESH_NUM_X_POINTS; ++ i) {
  111. // 1) Copy the intermediate points to their new destination.
  112. z_values[idx2][i] = z_values[2][i];
  113. z_values[idx1][i] = z_values[1][i];
  114. // 2) Interpolate the remaining values by Largrangian polynomials.
  115. for (int j = 1; j + 1 < MESH_NUM_Y_POINTS; ++ j) {
  116. if (j == idx1)
  117. continue;
  118. float y = get_y(j);
  119. z_values[j][i] = z_values[idx0][i] * (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2)) +
  120. z_values[idx1][i] * (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2)) +
  121. z_values[idx2][i] * (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
  122. }
  123. }
  124. }
  125. }
  126. #endif
  127. #endif // MESH_BED_LEVELING