@ -31,7 +31,7 @@
# ifdef ENABLE_AUTO_BED_LEVELING
# ifdef ENABLE_AUTO_BED_LEVELING
# include "vector_3.h"
# include "vector_3.h"
# ifdef A CCURATE_BED_LEVELING
# ifdef A UTO_BED_LEVELING_GRID
# include "qr_solve.h"
# include "qr_solve.h"
# endif
# endif
# endif // ENABLE_AUTO_BED_LEVELING
# endif // ENABLE_AUTO_BED_LEVELING
@ -822,7 +822,7 @@ static void axis_is_at_home(int axis) {
}
}
# ifdef ENABLE_AUTO_BED_LEVELING
# ifdef ENABLE_AUTO_BED_LEVELING
# ifdef A CCURATE_BED_LEVELING
# ifdef A UTO_BED_LEVELING_GRID
static void set_bed_level_equation_lsq ( double * plane_equation_coefficients )
static void set_bed_level_equation_lsq ( double * plane_equation_coefficients )
{
{
vector_3 planeNormal = vector_3 ( - plane_equation_coefficients [ 0 ] , - plane_equation_coefficients [ 1 ] , 1 ) ;
vector_3 planeNormal = vector_3 ( - plane_equation_coefficients [ 0 ] , - plane_equation_coefficients [ 1 ] , 1 ) ;
@ -846,42 +846,36 @@ static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
}
}
# else
# else // not AUTO_BED_LEVELING_GRID
static void set_bed_level_equation ( float z_at_xLeft_yFront , float z_at_xRight_yFront , float z_at_xLeft_yBack ) {
plan_bed_level_matrix . set_to_identity ( ) ;
vector_3 xLeftyFront = vector_3 ( LEFT_PROBE_BED_POSITION , FRONT_PROBE_BED_POSITION , z_at_xLeft_yFront ) ;
static void set_bed_level_equation_3pts ( float z_at_pt_1 , float z_at_pt_2 , float z_at_pt_3 ) {
vector_3 xLeftyBack = vector_3 ( LEFT_PROBE_BED_POSITION , BACK_PROBE_BED_POSITION , z_at_xLeft_yBack ) ;
vector_3 xRightyFront = vector_3 ( RIGHT_PROBE_BED_POSITION , FRONT_PROBE_BED_POSITION , z_at_xRight_yFront ) ;
vector_3 xPositive = ( xRightyFront - xLeftyFront ) . get_normal ( ) ;
plan_bed_level_matrix . set_to_identity ( ) ;
vector_3 yPositive = ( xLeftyBack - xLeftyFront ) . get_normal ( ) ;
vector_3 planeNormal = vector_3 : : cross ( xPositive , yPositive ) . get_normal ( ) ;
//planeNormal.debug("planeNormal");
vector_3 pt1 = vector_3 ( ABL_PROBE_PT_1_X , ABL_PROBE_PT_1_Y , z_at_pt_1 ) ;
//yPositive.debug("yPositive");
vector_3 pt2 = vector_3 ( ABL_PROBE_PT_2_X , ABL_PROBE_PT_2_Y , z_at_pt_2 ) ;
plan_bed_level_matrix = matrix_3x3 : : create_look_at ( planeNormal ) ;
vector_3 pt3 = vector_3 ( ABL_PROBE_PT_3_X , ABL_PROBE_PT_3_Y , z_at_pt_3 ) ;
//bedLevel.debug("bedLevel");
//plan_bed_level_matrix.debug("bed level before");
vector_3 from_2_to_1 = ( pt1 - pt2 ) . get_normal ( ) ;
//vector_3 uncorrected_position = plan_get_position_mm();
vector_3 from_2_to_3 = ( pt3 - pt2 ) . get_normal ( ) ;
//uncorrected_position.debug("position before");
vector_3 planeNormal = vector_3 : : cross ( from_2_to_1 , from_2_to_3 ) . get_normal ( ) ;
planeNormal = vector_3 ( planeNormal . x , planeNormal . y , abs ( planeNormal . z ) ) ;
// and set our bed level equation to do the right thing
plan_bed_level_matrix = matrix_3x3 : : create_look_at ( planeNormal ) ;
//plan_bed_level_matrix.debug("bed level after");
vector_3 corrected_position = plan_get_position ( ) ;
vector_3 corrected_position = plan_get_position ( ) ;
//corrected_position.debug("position after");
current_position [ X_AXIS ] = corrected_position . x ;
current_position [ X_AXIS ] = corrected_position . x ;
current_position [ Y_AXIS ] = corrected_position . y ;
current_position [ Y_AXIS ] = corrected_position . y ;
current_position [ Z_AXIS ] = corrected_position . z ;
current_position [ Z_AXIS ] = corrected_position . z ;
// b ut the bed at 0 so we don't go below it.
// p ut the bed at 0 so we don't go below it.
current_position [ Z_AXIS ] = zprobe_zoffset ;
current_position [ Z_AXIS ] = zprobe_zoffset ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
}
}
# endif // ACCURATE_BED_LEVELING
# endif // AUTO_BED_LEVELING_GRID
static void run_z_probe ( ) {
static void run_z_probe ( ) {
plan_bed_level_matrix . set_to_identity ( ) ;
plan_bed_level_matrix . set_to_identity ( ) ;
@ -1403,7 +1397,7 @@ void process_commands()
break ;
break ;
# ifdef ENABLE_AUTO_BED_LEVELING
# ifdef ENABLE_AUTO_BED_LEVELING
case 29 : // G29 Detailed Z-Probe, probes the bed at 3 points.
case 29 : // G29 Detailed Z-Probe, probes the bed at 3 or more points.
{
{
# if Z_MIN_PIN == -1
# if Z_MIN_PIN == -1
# error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin."
# error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin."
@ -1432,10 +1426,11 @@ void process_commands()
setup_for_endstop_move ( ) ;
setup_for_endstop_move ( ) ;
feedrate = homing_feedrate [ Z_AXIS ] ;
feedrate = homing_feedrate [ Z_AXIS ] ;
# ifdef ACCURATE_BED_LEVELING
# ifdef AUTO_BED_LEVELING_GRID
// probe at the points of a lattice grid
int xGridSpacing = ( RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION ) / ( A CCURATE_BED_LEVELING _POINTS- 1 ) ;
int xGridSpacing = ( RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION ) / ( A UTO_BED_LEVELING_GRID _POINTS- 1 ) ;
int yGridSpacing = ( BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION ) / ( A CCURATE_BED_LEVELING _POINTS- 1 ) ;
int yGridSpacing = ( BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION ) / ( A UTO_BED_LEVELING_GRID _POINTS- 1 ) ;
// solve the plane equation ax + by + d = z
// solve the plane equation ax + by + d = z
@ -1445,9 +1440,9 @@ void process_commands()
// so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
// so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
// "A" matrix of the linear system of equations
// "A" matrix of the linear system of equations
double eqnAMatrix [ A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS* 3 ] ;
double eqnAMatrix [ A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS* 3 ] ;
// "B" vector of Z points
// "B" vector of Z points
double eqnBVector [ A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS] ;
double eqnBVector [ A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS] ;
int probePointCounter = 0 ;
int probePointCounter = 0 ;
@ -1470,7 +1465,7 @@ void process_commands()
zig = true ;
zig = true ;
}
}
for ( int xCount = 0 ; xCount < A CCURATE_BED_LEVELING _POINTS; xCount + + )
for ( int xCount = 0 ; xCount < A UTO_BED_LEVELING_GRID _POINTS; xCount + + )
{
{
float z_before ;
float z_before ;
if ( probePointCounter = = 0 )
if ( probePointCounter = = 0 )
@ -1487,9 +1482,9 @@ void process_commands()
eqnBVector [ probePointCounter ] = measured_z ;
eqnBVector [ probePointCounter ] = measured_z ;
eqnAMatrix [ probePointCounter + 0 * A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS] = xProbe ;
eqnAMatrix [ probePointCounter + 0 * A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS] = xProbe ;
eqnAMatrix [ probePointCounter + 1 * A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS] = yProbe ;
eqnAMatrix [ probePointCounter + 1 * A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS] = yProbe ;
eqnAMatrix [ probePointCounter + 2 * A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS] = 1 ;
eqnAMatrix [ probePointCounter + 2 * A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS] = 1 ;
probePointCounter + + ;
probePointCounter + + ;
xProbe + = xInc ;
xProbe + = xInc ;
}
}
@ -1497,7 +1492,7 @@ void process_commands()
clean_up_after_endstop_move ( ) ;
clean_up_after_endstop_move ( ) ;
// solve lsq problem
// solve lsq problem
double * plane_equation_coefficients = qr_solve ( A CCURATE_BED_LEVELING_POINTS* ACCURATE_BED_LEVELING _POINTS, 3 , eqnAMatrix , eqnBVector ) ;
double * plane_equation_coefficients = qr_solve ( A UTO_BED_LEVELING_GRID_POINTS* AUTO_BED_LEVELING_GRID _POINTS, 3 , eqnAMatrix , eqnBVector ) ;
SERIAL_PROTOCOLPGM ( " Eqn coefficients: a: " ) ;
SERIAL_PROTOCOLPGM ( " Eqn coefficients: a: " ) ;
SERIAL_PROTOCOL ( plane_equation_coefficients [ 0 ] ) ;
SERIAL_PROTOCOL ( plane_equation_coefficients [ 0 ] ) ;
@ -1511,24 +1506,24 @@ void process_commands()
free ( plane_equation_coefficients ) ;
free ( plane_equation_coefficients ) ;
# else // ACCURATE_BED_LEVELING not defined
# else // AUTO_BED_LEVELING_GRID not defined
// prob 1
// Probe at 3 arbitrary points
float z_at_xLeft_yBack = probe_pt ( LEFT_PROBE_BED_POSITION , BACK_PROBE_BED_POSITION , Z_RAISE_BEFORE_PROBING ) ;
// probe 1
float z_at_pt_1 = probe_pt ( ABL_PROBE_PT_1_X , ABL_PROBE_PT_1_Y , Z_RAISE_BEFORE_PROBING ) ;
// prob 2
// prob e 2
float z_at_ xLeft_yFront = probe_pt ( LEFT_PROBE_BED_POSITION , FRONT_PROBE_BED_POSITION , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ;
float z_at_ pt_2 = probe_pt ( ABL_PROBE_PT_2_X , ABL_PROBE_PT_2_Y , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ;
// prob 3
// prob e 3
float z_at_ xRight_yFront = probe_pt ( RIGHT_PROBE_BED_POSITION , FRONT_PROBE_BED_POSITION , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ;
float z_at_ pt_3 = probe_pt ( ABL_PROBE_PT_3_X , ABL_PROBE_PT_3_Y , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ;
clean_up_after_endstop_move ( ) ;
clean_up_after_endstop_move ( ) ;
set_bed_level_equation ( z_at_xLeft_yFront , z_at_xRight_yFront , z_at_xLeft_yBack ) ;
set_bed_level_equation _3pts( z_at_pt_1 , z_at_pt_2 , z_at_pt_3 ) ;
# endif // A CCURATE_BED_LEVELING
# endif // A UTO_BED_LEVELING_GRID
st_synchronize ( ) ;
st_synchronize ( ) ;
// The following code correct the Z height difference from z-probe position and hotend tip position.
// The following code correct the Z height difference from z-probe position and hotend tip position.