Add custom types for position (#15204)

This commit is contained in:
Scott Lahteine
2019-09-29 04:25:39 -05:00
committed by GitHub
parent 43d6e9fa43
commit 50e4545255
227 changed files with 3147 additions and 3264 deletions

View File

@ -35,9 +35,9 @@
#include "../../../lcd/extensible_ui/ui_api.h"
#endif
int bilinear_grid_spacing[2], bilinear_start[2];
float bilinear_grid_factor[2],
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
xy_int_t bilinear_grid_spacing, bilinear_start;
xy_float_t bilinear_grid_factor;
bed_mesh_t z_values;
/**
* Extrapolate a single point from its neighbors
@ -153,8 +153,8 @@ void print_bilinear_leveling_grid() {
#define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2)
#define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
int bilinear_grid_spacing_virt[2] = { 0 };
float bilinear_grid_factor_virt[2] = { 0 };
xy_int_t bilinear_grid_spacing_virt;
xy_float_t bilinear_grid_factor_virt;
void print_bilinear_leveling_grid_virt() {
SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:");
@ -207,7 +207,7 @@ void print_bilinear_leveling_grid() {
+ p[i] * (2 - 5 * sq(t) + 3 * t * sq(t))
+ p[i+1] * t * (1 + 4 * t - 3 * sq(t))
- p[i+2] * sq(t) * (1 - t)
) * 0.5;
) * 0.5f;
}
static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const float &tx, const float &ty) {
@ -222,10 +222,8 @@ void print_bilinear_leveling_grid() {
}
void bed_level_virt_interpolate() {
bilinear_grid_spacing_virt[X_AXIS] = bilinear_grid_spacing[X_AXIS] / (BILINEAR_SUBDIVISIONS);
bilinear_grid_spacing_virt[Y_AXIS] = bilinear_grid_spacing[Y_AXIS] / (BILINEAR_SUBDIVISIONS);
bilinear_grid_factor_virt[X_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[X_AXIS]);
bilinear_grid_factor_virt[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[Y_AXIS]);
bilinear_grid_spacing_virt = bilinear_grid_spacing / (BILINEAR_SUBDIVISIONS);
bilinear_grid_factor_virt = bilinear_grid_spacing_virt.reciprocal();
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++)
@ -245,40 +243,38 @@ void print_bilinear_leveling_grid() {
// Refresh after other values have been updated
void refresh_bed_level() {
bilinear_grid_factor[X_AXIS] = RECIPROCAL(bilinear_grid_spacing[X_AXIS]);
bilinear_grid_factor[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing[Y_AXIS]);
bilinear_grid_factor = bilinear_grid_spacing.reciprocal();
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
bed_level_virt_interpolate();
#endif
}
#if ENABLED(ABL_BILINEAR_SUBDIVISION)
#define ABL_BG_SPACING(A) bilinear_grid_spacing_virt[A]
#define ABL_BG_FACTOR(A) bilinear_grid_factor_virt[A]
#define ABL_BG_SPACING(A) bilinear_grid_spacing_virt.A
#define ABL_BG_FACTOR(A) bilinear_grid_factor_virt.A
#define ABL_BG_POINTS_X ABL_GRID_POINTS_VIRT_X
#define ABL_BG_POINTS_Y ABL_GRID_POINTS_VIRT_Y
#define ABL_BG_GRID(X,Y) z_values_virt[X][Y]
#else
#define ABL_BG_SPACING(A) bilinear_grid_spacing[A]
#define ABL_BG_FACTOR(A) bilinear_grid_factor[A]
#define ABL_BG_SPACING(A) bilinear_grid_spacing.A
#define ABL_BG_FACTOR(A) bilinear_grid_factor.A
#define ABL_BG_POINTS_X GRID_MAX_POINTS_X
#define ABL_BG_POINTS_Y GRID_MAX_POINTS_Y
#define ABL_BG_GRID(X,Y) z_values[X][Y]
#endif
// Get the Z adjustment for non-linear bed leveling
float bilinear_z_offset(const float raw[XYZ]) {
float bilinear_z_offset(const xy_pos_t &raw) {
static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
last_x = -999.999, last_y = -999.999;
static float z1, d2, z3, d4, L, D;
static xy_pos_t prev { -999.999, -999.999 }, ratio;
// Whole units for the grid line indices. Constrained within bounds.
static int8_t gridx, gridy, nextx, nexty,
last_gridx = -99, last_gridy = -99;
static xy_int8_t thisg, nextg, lastg { -99, -99 };
// XY relative to the probed area
const float rx = raw[X_AXIS] - bilinear_start[X_AXIS],
ry = raw[Y_AXIS] - bilinear_start[Y_AXIS];
xy_pos_t rel = raw - bilinear_start.asFloat();
#if ENABLED(EXTRAPOLATE_BEYOND_GRID)
#define FAR_EDGE_OR_BOX 2 // Keep using the last grid box
@ -286,63 +282,62 @@ float bilinear_z_offset(const float raw[XYZ]) {
#define FAR_EDGE_OR_BOX 1 // Just use the grid far edge
#endif
if (last_x != rx) {
last_x = rx;
ratio_x = rx * ABL_BG_FACTOR(X_AXIS);
const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - (FAR_EDGE_OR_BOX));
ratio_x -= gx; // Subtract whole to get the ratio within the grid box
if (prev.x != rel.x) {
prev.x = rel.x;
ratio.x = rel.x * ABL_BG_FACTOR(x);
const float gx = constrain(FLOOR(ratio.x), 0, ABL_BG_POINTS_X - (FAR_EDGE_OR_BOX));
ratio.x -= gx; // Subtract whole to get the ratio within the grid box
#if DISABLED(EXTRAPOLATE_BEYOND_GRID)
// Beyond the grid maintain height at grid edges
NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.)
NOLESS(ratio.x, 0); // Never <0 (>1 is ok when nextg.x==thisg.x)
#endif
gridx = gx;
nextx = _MIN(gridx + 1, ABL_BG_POINTS_X - 1);
thisg.x = gx;
nextg.x = _MIN(thisg.x + 1, ABL_BG_POINTS_X - 1);
}
if (last_y != ry || last_gridx != gridx) {
if (prev.y != rel.y || lastg.x != thisg.x) {
if (last_y != ry) {
last_y = ry;
ratio_y = ry * ABL_BG_FACTOR(Y_AXIS);
const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - (FAR_EDGE_OR_BOX));
ratio_y -= gy;
if (prev.y != rel.y) {
prev.y = rel.y;
ratio.y = rel.y * ABL_BG_FACTOR(y);
const float gy = constrain(FLOOR(ratio.y), 0, ABL_BG_POINTS_Y - (FAR_EDGE_OR_BOX));
ratio.y -= gy;
#if DISABLED(EXTRAPOLATE_BEYOND_GRID)
// Beyond the grid maintain height at grid edges
NOLESS(ratio_y, 0); // Never < 0.0. (> 1.0 is ok when nexty==gridy.)
NOLESS(ratio.y, 0); // Never < 0.0. (> 1.0 is ok when nextg.y==thisg.y.)
#endif
gridy = gy;
nexty = _MIN(gridy + 1, ABL_BG_POINTS_Y - 1);
thisg.y = gy;
nextg.y = _MIN(thisg.y + 1, ABL_BG_POINTS_Y - 1);
}
if (last_gridx != gridx || last_gridy != gridy) {
last_gridx = gridx;
last_gridy = gridy;
if (lastg != thisg) {
lastg = thisg;
// Z at the box corners
z1 = ABL_BG_GRID(gridx, gridy); // left-front
d2 = ABL_BG_GRID(gridx, nexty) - z1; // left-back (delta)
z3 = ABL_BG_GRID(nextx, gridy); // right-front
d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta)
z1 = ABL_BG_GRID(thisg.x, thisg.y); // left-front
d2 = ABL_BG_GRID(thisg.x, nextg.y) - z1; // left-back (delta)
z3 = ABL_BG_GRID(nextg.x, thisg.y); // right-front
d4 = ABL_BG_GRID(nextg.x, nextg.y) - z3; // right-back (delta)
}
// Bilinear interpolate. Needed since ry or gridx has changed.
L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
// Bilinear interpolate. Needed since rel.y or thisg.x has changed.
L = z1 + d2 * ratio.y; // Linear interp. LF -> LB
const float R = z3 + d4 * ratio.y; // Linear interp. RF -> RB
D = R - L;
}
const float offset = L + ratio_x * D; // the offset almost always changes
const float offset = L + ratio.x * D; // the offset almost always changes
/*
static float last_offset = 0;
if (ABS(last_offset - offset) > 0.2) {
SERIAL_ECHOLNPAIR("Sudden Shift at x=", rx, " / ", bilinear_grid_spacing[X_AXIS], " -> gridx=", gridx);
SERIAL_ECHOLNPAIR(" y=", ry, " / ", bilinear_grid_spacing[Y_AXIS], " -> gridy=", gridy);
SERIAL_ECHOLNPAIR(" ratio_x=", ratio_x, " ratio_y=", ratio_y);
SERIAL_ECHOLNPAIR("Sudden Shift at x=", rel.x, " / ", bilinear_grid_spacing.x, " -> thisg.x=", thisg.x);
SERIAL_ECHOLNPAIR(" y=", rel.y, " / ", bilinear_grid_spacing.y, " -> thisg.y=", thisg.y);
SERIAL_ECHOLNPAIR(" ratio.x=", ratio.x, " ratio.y=", ratio.y);
SERIAL_ECHOLNPAIR(" z1=", z1, " z2=", z2, " z3=", z3, " z4=", z4);
SERIAL_ECHOLNPAIR(" L=", L, " R=", R, " offset=", offset);
}
@ -354,7 +349,7 @@ float bilinear_z_offset(const float raw[XYZ]) {
#if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES)
#define CELL_INDEX(A,V) ((V - bilinear_start[_AXIS(A)]) * ABL_BG_FACTOR(_AXIS(A)))
#define CELL_INDEX(A,V) ((V - bilinear_start.A) * ABL_BG_FACTOR(A))
/**
* Prepare a bilinear-leveled linear move on Cartesian,
@ -362,62 +357,61 @@ float bilinear_z_offset(const float raw[XYZ]) {
*/
void bilinear_line_to_destination(const feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) {
// Get current and destination cells for this line
int cx1 = CELL_INDEX(X, current_position[X_AXIS]),
cy1 = CELL_INDEX(Y, current_position[Y_AXIS]),
cx2 = CELL_INDEX(X, destination[X_AXIS]),
cy2 = CELL_INDEX(Y, destination[Y_AXIS]);
LIMIT(cx1, 0, ABL_BG_POINTS_X - 2);
LIMIT(cy1, 0, ABL_BG_POINTS_Y - 2);
LIMIT(cx2, 0, ABL_BG_POINTS_X - 2);
LIMIT(cy2, 0, ABL_BG_POINTS_Y - 2);
xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) },
c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) };
LIMIT(c1.x, 0, ABL_BG_POINTS_X - 2);
LIMIT(c1.y, 0, ABL_BG_POINTS_Y - 2);
LIMIT(c2.x, 0, ABL_BG_POINTS_X - 2);
LIMIT(c2.y, 0, ABL_BG_POINTS_Y - 2);
// Start and end in the same cell? No split needed.
if (cx1 == cx2 && cy1 == cy2) {
set_current_from_destination();
if (c1 == c2) {
current_position = destination;
line_to_current_position(scaled_fr_mm_s);
return;
}
#define LINE_SEGMENT_END(A) (current_position[_AXIS(A)] + (destination[_AXIS(A)] - current_position[_AXIS(A)]) * normalized_dist)
#define LINE_SEGMENT_END(A) (current_position.A + (destination.A - current_position.A) * normalized_dist)
float normalized_dist, end[XYZE];
const int8_t gcx = _MAX(cx1, cx2), gcy = _MAX(cy1, cy2);
float normalized_dist;
xyze_pos_t end;
const xy_int8_t gc { _MAX(c1.x, c2.x), _MAX(c1.y, c2.y) };
// Crosses on the X and not already split on this X?
// The x_splits flags are insurance against rounding errors.
if (cx2 != cx1 && TEST(x_splits, gcx)) {
if (c2.x != c1.x && TEST(x_splits, gc.x)) {
// Split on the X grid line
CBI(x_splits, gcx);
COPY(end, destination);
destination[X_AXIS] = bilinear_start[X_AXIS] + ABL_BG_SPACING(X_AXIS) * gcx;
normalized_dist = (destination[X_AXIS] - current_position[X_AXIS]) / (end[X_AXIS] - current_position[X_AXIS]);
destination[Y_AXIS] = LINE_SEGMENT_END(Y);
CBI(x_splits, gc.x);
end = destination;
destination.x = bilinear_start.x + ABL_BG_SPACING(x) * gc.x;
normalized_dist = (destination.x - current_position.x) / (end.x - current_position.x);
destination.y = LINE_SEGMENT_END(y);
}
// Crosses on the Y and not already split on this Y?
else if (cy2 != cy1 && TEST(y_splits, gcy)) {
else if (c2.y != c1.y && TEST(y_splits, gc.y)) {
// Split on the Y grid line
CBI(y_splits, gcy);
COPY(end, destination);
destination[Y_AXIS] = bilinear_start[Y_AXIS] + ABL_BG_SPACING(Y_AXIS) * gcy;
normalized_dist = (destination[Y_AXIS] - current_position[Y_AXIS]) / (end[Y_AXIS] - current_position[Y_AXIS]);
destination[X_AXIS] = LINE_SEGMENT_END(X);
CBI(y_splits, gc.y);
end = destination;
destination.y = bilinear_start.y + ABL_BG_SPACING(y) * gc.y;
normalized_dist = (destination.y - current_position.y) / (end.y - current_position.y);
destination.x = LINE_SEGMENT_END(x);
}
else {
// Must already have been split on these border(s)
// This should be a rare case.
set_current_from_destination();
current_position = destination;
line_to_current_position(scaled_fr_mm_s);
return;
}
destination[Z_AXIS] = LINE_SEGMENT_END(Z);
destination[E_AXIS] = LINE_SEGMENT_END(E);
destination.z = LINE_SEGMENT_END(z);
destination.e = LINE_SEGMENT_END(e);
// Do the split and look for more borders
bilinear_line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
// Restore destination from stack
COPY(destination, end);
destination = end;
bilinear_line_to_destination(scaled_fr_mm_s, x_splits, y_splits);
}

View File

@ -23,10 +23,10 @@
#include "../../../inc/MarlinConfigPre.h"
extern int bilinear_grid_spacing[2], bilinear_start[2];
extern float bilinear_grid_factor[2],
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
float bilinear_z_offset(const float raw[XYZ]);
extern xy_int_t bilinear_grid_spacing, bilinear_start;
extern xy_float_t bilinear_grid_factor;
extern bed_mesh_t z_values;
float bilinear_z_offset(const xy_pos_t &raw);
void extrapolate_unprobed_bed_level();
void print_bilinear_leveling_grid();
@ -40,6 +40,6 @@ void refresh_bed_level();
void bilinear_line_to_destination(const feedRate_t &scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF);
#endif
#define _GET_MESH_X(I) (bilinear_start[X_AXIS] + (I) * bilinear_grid_spacing[X_AXIS])
#define _GET_MESH_Y(J) (bilinear_start[Y_AXIS] + (J) * bilinear_grid_spacing[Y_AXIS])
#define _GET_MESH_X(I) float(bilinear_start.x + (I) * bilinear_grid_spacing.x)
#define _GET_MESH_Y(J) float(bilinear_start.y + (J) * bilinear_grid_spacing.y)
#define Z_VALUES_ARR z_values