Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBL print area #4183

Merged
merged 34 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
11e1806
Gcode documentation
leptun May 1, 2023
7b9f208
MBL print area initial implementation
leptun May 1, 2023
a4ef72b
Use mesh from eeprom during print area MBL
leptun May 1, 2023
8edfff3
MBL code cleanup
leptun May 2, 2023
fbfc6bf
MBL remove MBL_BILINEAR
leptun May 2, 2023
07b9447
Fix correction nMeasPoints
leptun May 5, 2023
46710c4
G80 code cleanup
leptun May 5, 2023
83879fd
Cleanup magnet compensation code
leptun May 5, 2023
6af5f5e
Some code cleanup around homing_feedrate
leptun May 5, 2023
6c97907
A bit more cleanup
leptun May 5, 2023
90c2142
Optimize is_bed_z_jitter_data_valid()
leptun May 5, 2023
f94bc72
Optimize G80 bed correction argument parsing
leptun May 5, 2023
b234560
MBL print function optimization
leptun May 5, 2023
36d8de0
G80 general fixes
leptun May 5, 2023
a7d3dd7
Fix eeprom mesh interpolation
leptun May 5, 2023
40db9c9
Fix eeprom mesh offset
leptun May 5, 2023
de98551
Extract hardcoded value
leptun May 5, 2023
a5c20a1
Do not plan a Z move if no move is actually performed
leptun May 5, 2023
6794557
G80 minor optimization
leptun May 5, 2023
5b8c65e
Minor magnet elimination optimization
leptun May 5, 2023
2d0b96f
Bed correction code optimization
leptun May 6, 2023
be3465c
optimize lambda expression capture
leptun May 6, 2023
3ccf2d6
Make bed correction matrix const
leptun May 6, 2023
6b12be4
optimisation: Make BED_X and BED_Y into functions
gudnimg May 6, 2023
a9d0cc5
optimisation: Move divison into constexpr
gudnimg May 6, 2023
42c27ca
Remove unused code
leptun May 6, 2023
dd1bde7
Fix Z calibration points
leptun May 7, 2023
aba0450
mbl.get_z() optimizations
leptun May 6, 2023
a15f536
Combine BED_X/Y() and mbl::get_x/y()
leptun May 7, 2023
a984b2e
G80 `O` parameter
leptun May 8, 2023
7740a81
Do not store a global mbl_z_probe_nr
leptun May 11, 2023
f5f09f1
Add a limit to how many times G80 can fail
leptun May 13, 2023
45823e7
Make the G80 Z threshold tighter
leptun May 13, 2023
ede4cc5
Update error messages
leptun May 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Firmware/Marlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "pins.h"
#include "Timer.h"
#include "mmu2.h"
extern uint8_t mbl_z_probe_nr;

#ifndef AT90USB
#define HardwareSerial_h // trick to disable the standard HWserial
Expand Down Expand Up @@ -236,7 +235,7 @@ enum class HeatingStatus : uint8_t
extern HeatingStatus heating_status;

extern bool fans_check_enabled;
extern float homing_feedrate[];
constexpr float homing_feedrate[] = HOMING_FEEDRATE;
extern uint8_t axis_relative_modes;
extern float feedrate;
extern int feedmultiply;
Expand Down
431 changes: 158 additions & 273 deletions Firmware/Marlin_main.cpp

Large diffs are not rendered by default.

91 changes: 46 additions & 45 deletions Firmware/mesh_bed_calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,11 +685,11 @@ bool is_bed_z_jitter_data_valid()
// offsets of the Z heiths of the calibration points from the first point are saved as 16bit signed int, scaled to tenths of microns
// if at least one 16bit integer has different value then -1 (0x0FFFF), data are considered valid and function returns true, otherwise it returns false
{
bool data_valid = false;
for (int8_t i = 0; i < 8; ++i) {
if (eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + i * 2)) != 0x0FFFF) data_valid = true;
if (eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + i * 2)) != 0x0FFFF)
return true;
}
return data_valid;
return false;
}

static void world2machine_update(const float vec_x[2], const float vec_y[2], const float cntr[2])
Expand Down Expand Up @@ -776,7 +776,7 @@ void world2machine_revert_to_uncorrected()
static inline bool vec_undef(const float v[2])
{
const uint32_t *vx = (const uint32_t*)v;
return vx[0] == 0x0FFFFFFFF || vx[1] == 0x0FFFFFFFF;
return vx[0] == 0xFFFFFFFF || vx[1] == 0xFFFFFFFF;
}


Expand Down Expand Up @@ -2184,6 +2184,16 @@ inline void scan_bed_induction_sensor_point()

#define MESH_BED_CALIBRATION_SHOW_LCD

float __attribute__((noinline)) BED_X(const uint8_t col)
{
return ((float)col * x_mesh_density + BED_X0);
}

float __attribute__((noinline)) BED_Y(const uint8_t row)
{
return ((float)row * y_mesh_density + BED_Y0);
}

BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level, uint8_t &too_far_mask)
{
// Don't let the manage_inactivity() function remove power from the motors.
Expand Down Expand Up @@ -2481,8 +2491,8 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level
uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix;
current_position[X_AXIS] = BED_X(ix, MESH_MEAS_NUM_X_POINTS);
current_position[Y_AXIS] = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS);
current_position[X_AXIS] = BED_X(ix * 3);
current_position[Y_AXIS] = BED_Y(iy * 3);
go_to_current(homing_feedrate[X_AXIS] / 60);
delay_keep_alive(3000);
}
Expand Down Expand Up @@ -2814,16 +2824,16 @@ void go_home_with_z_lift()
// Go home.
// First move up to a safe height.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
go_to_current(homing_feedrate[Z_AXIS]/60);
go_to_current(homing_feedrate[Z_AXIS] / 60);
// Second move to XY [0, 0].
current_position[X_AXIS] = X_MIN_POS+0.2;
current_position[Y_AXIS] = Y_MIN_POS+0.2;
current_position[X_AXIS] = X_MIN_POS + 0.2;
current_position[Y_AXIS] = Y_MIN_POS + 0.2;
// Clamp to the physical coordinates.
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
go_to_current(homing_feedrate[X_AXIS]/20);
go_to_current((3 * homing_feedrate[X_AXIS]) / 60);
// Third move up to a safe height.
current_position[Z_AXIS] = Z_MIN_POS;
go_to_current(homing_feedrate[Z_AXIS]/60);
go_to_current(homing_feedrate[Z_AXIS] / 60);
}

// Sample the 9 points of the bed and store them into the EEPROM as a reference.
Expand Down Expand Up @@ -2884,8 +2894,8 @@ bool sample_mesh_and_store_reference()
uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS;
uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag
current_position[X_AXIS] = BED_X(ix, MESH_MEAS_NUM_X_POINTS);
current_position[Y_AXIS] = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS);
current_position[X_AXIS] = BED_X(ix * 3);
current_position[Y_AXIS] = BED_Y(iy * 3);
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
go_to_current(homing_feedrate[X_AXIS]/60);
#ifdef MESH_BED_CALIBRATION_SHOW_LCD
Expand Down Expand Up @@ -2951,8 +2961,7 @@ bool sample_mesh_and_store_reference()
}
}

mbl.upsample_3x3();
mbl.active = true;
mbl.reset();

go_home_with_z_lift();

Expand Down Expand Up @@ -3004,8 +3013,8 @@ bool scan_bed_induction_points(int8_t verbosity_level)
uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix;
float bedX = BED_X(ix, MESH_MEAS_NUM_X_POINTS);
float bedY = BED_Y(iy, MESH_MEAS_NUM_Y_POINTS);
float bedX = BED_X(ix * 3);
float bedY = BED_Y(iy * 3);
current_position[X_AXIS] = vec_x[0] * bedX + vec_y[0] * bedY + cntr[0];
current_position[Y_AXIS] = vec_x[1] * bedX + vec_y[1] * bedY + cntr[1];
// The calibration points are very close to the min Y.
Expand Down Expand Up @@ -3034,9 +3043,12 @@ bool scan_bed_induction_points(int8_t verbosity_level)
// To replace loading of the babystep correction.
static void shift_z(float delta)
{
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] - delta, current_position[E_AXIS], homing_feedrate[Z_AXIS]/40);
const float curpos_z = current_position[Z_AXIS];
current_position[Z_AXIS] -= delta;
plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60);
st_synchronize();
plan_set_z_position(current_position[Z_AXIS]);
current_position[Z_AXIS] = curpos_z;
plan_set_z_position(curpos_z);
}

// Number of baby steps applied
Expand Down Expand Up @@ -3112,20 +3124,19 @@ void mbl_settings_init() {
//magnet elimination: use aaproximate Z-coordinate instead of measured values for points which are near magnets
eeprom_init_default_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION, 1);
eeprom_init_default_byte((uint8_t*)EEPROM_MBL_POINTS_NR, 3);
mbl_z_probe_nr = eeprom_init_default_byte((uint8_t*)EEPROM_MBL_PROBE_NR, 3);
eeprom_init_default_byte((uint8_t*)EEPROM_MBL_PROBE_NR, 3);
}

//parameter ix: index of mesh bed leveling point in X-axis (for meas_points == 7 is valid range from 0 to 6; for meas_points == 3 is valid range from 0 to 2 )
//parameter iy: index of mesh bed leveling point in Y-axis (for meas_points == 7 is valid range from 0 to 6; for meas_points == 3 is valid range from 0 to 2 )
//parameter meas_points: number of mesh bed leveling points in one axis; currently designed and tested for values 3 and 7
//parameter zigzag: false if ix is considered 0 on left side of bed and ix rises with rising X coordinate; true if ix is considered 0 on the right side of heatbed for odd iy values (zig zag mesh bed leveling movements)
//function returns true if point is considered valid (typicaly in safe distance from magnet or another object which inflences PINDA measurements)
bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag) {
bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy) {
//"human readable" heatbed plan
//magnet proximity influence Z coordinate measurements significantly (40 - 100 um)
//0 - measurement point is above magnet and Z coordinate can be influenced negatively
//1 - we should be in safe distance from magnets, measurement should be accurate
if ((ix >= meas_points) || (iy >= meas_points)) return false;
if ((ix >= MESH_NUM_X_POINTS) || (iy >= MESH_NUM_Y_POINTS))
return false;

uint8_t valid_points_mask[7] = {
//[X_MAX,Y_MAX]
Expand All @@ -3139,36 +3150,26 @@ bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bo
0b1111111,//0
//[0,0]
};
if (meas_points == 3) {
ix *= 3;
iy *= 3;
}
if (zigzag) {
if ((iy % 2) == 0) return (valid_points_mask[6 - iy] & (1 << (6 - ix)));
else return (valid_points_mask[6 - iy] & (1 << ix));
}
else {
return (valid_points_mask[6 - iy] & (1 << (6 - ix)));
}
return (valid_points_mask[6 - iy] & (1 << (6 - ix)));
}

void mbl_single_point_interpolation(uint8_t x, uint8_t y, uint8_t meas_points) {
void mbl_single_point_interpolation(uint8_t x, uint8_t y) {
//printf_P(PSTR("x = %d; y = %d \n"), x, y);
uint8_t count = 0;
float z = 0;
if (mbl_point_measurement_valid(x, y + 1, meas_points, false)) { z += mbl.z_values[y + 1][x]; /*printf_P(PSTR("x; y+1: Z = %f \n"), mbl.z_values[y + 1][x]);*/ count++; }
if (mbl_point_measurement_valid(x, y - 1, meas_points, false)) { z += mbl.z_values[y - 1][x]; /*printf_P(PSTR("x; y-1: Z = %f \n"), mbl.z_values[y - 1][x]);*/ count++; }
if (mbl_point_measurement_valid(x + 1, y, meas_points, false)) { z += mbl.z_values[y][x + 1]; /*printf_P(PSTR("x+1; y: Z = %f \n"), mbl.z_values[y][x + 1]);*/ count++; }
if (mbl_point_measurement_valid(x - 1, y, meas_points, false)) { z += mbl.z_values[y][x - 1]; /*printf_P(PSTR("x-1; y: Z = %f \n"), mbl.z_values[y][x - 1]);*/ count++; }
if (mbl_point_measurement_valid(x, y + 1)) { z += mbl.z_values[y + 1][x]; /*printf_P(PSTR("x; y+1: Z = %f \n"), mbl.z_values[y + 1][x]);*/ count++; }
if (mbl_point_measurement_valid(x, y - 1)) { z += mbl.z_values[y - 1][x]; /*printf_P(PSTR("x; y-1: Z = %f \n"), mbl.z_values[y - 1][x]);*/ count++; }
if (mbl_point_measurement_valid(x + 1, y)) { z += mbl.z_values[y][x + 1]; /*printf_P(PSTR("x+1; y: Z = %f \n"), mbl.z_values[y][x + 1]);*/ count++; }
if (mbl_point_measurement_valid(x - 1, y)) { z += mbl.z_values[y][x - 1]; /*printf_P(PSTR("x-1; y: Z = %f \n"), mbl.z_values[y][x - 1]);*/ count++; }
if(count != 0) mbl.z_values[y][x] = z / count; //if we have at least one valid point in surrounding area use average value, otherwise use inaccurately measured Z-coordinate
//printf_P(PSTR("result: Z = %f \n\n"), mbl.z_values[y][x]);
}

void mbl_interpolation(uint8_t meas_points) {
for (uint8_t x = 0; x < meas_points; x++) {
for (uint8_t y = 0; y < meas_points; y++) {
if (!mbl_point_measurement_valid(x, y, meas_points, false)) {
mbl_single_point_interpolation(x, y, meas_points);
void mbl_magnet_elimination() {
for (uint8_t y = 0; y < MESH_NUM_Y_POINTS; y++) {
for (uint8_t x = 0; x < MESH_NUM_X_POINTS; x++) {
if (!mbl_point_measurement_valid(x, y)) {
mbl_single_point_interpolation(x, y);
}
}
}
Expand Down
20 changes: 15 additions & 5 deletions Firmware/mesh_bed_calibration.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

#endif //not HEATBED_V2

#define BED_X(i, n) ((float)i * (BED_Xn - BED_X0) / (n - 1) + BED_X0)
#define BED_Y(i, n) ((float)i * (BED_Yn - BED_Y0) / (n - 1) + BED_Y0)
constexpr float x_mesh_density = (BED_Xn - BED_X0) / (MESH_NUM_X_POINTS - 1);
constexpr float y_mesh_density = (BED_Yn - BED_Y0) / (MESH_NUM_Y_POINTS - 1);

// Exact positions of the print head above the bed reference points, in the world coordinates.
// The world coordinates match the machine coordinates only in case, when the machine
Expand Down Expand Up @@ -145,6 +145,17 @@ inline bool world2machine_clamp(float &x, float &y)
machine2world(tmpx, tmpy, x, y);
return clamped;
}

/// @brief For a given column on the mesh calculate the bed X coordinate
/// @param col column index on mesh
/// @return Bed X coordinate
float BED_X(const uint8_t col);

/// @brief For a given row on the mesh calculate the bed Y coordinate
/// @param row row index on mesh
/// @return Bed Y coordinate
float BED_Y(const uint8_t row);

/**
* @brief Bed skew and offest detection result
*
Expand Down Expand Up @@ -203,6 +214,5 @@ extern void count_xyz_details(float (&distanceMin)[2]);
extern bool sample_z();

extern void mbl_settings_init();

extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag);
extern void mbl_interpolation(uint8_t meas_points);
extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy);
extern void mbl_magnet_elimination();
Loading