|
@@ -36,12 +36,11 @@
|
36
|
36
|
|
37
|
37
|
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
38
|
38
|
#include "vector_3.h"
|
39
|
|
- #if ENABLED(AUTO_BED_LEVELING_GRID)
|
40
|
|
- #include "qr_solve.h"
|
41
|
|
- #endif
|
42
|
|
-#endif // AUTO_BED_LEVELING_FEATURE
|
|
39
|
+#endif
|
43
|
40
|
|
44
|
|
-#if ENABLED(MESH_BED_LEVELING)
|
|
41
|
+#if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
|
42
|
+ #include "qr_solve.h"
|
|
43
|
+#elif ENABLED(MESH_BED_LEVELING)
|
45
|
44
|
#include "mesh_bed_leveling.h"
|
46
|
45
|
#endif
|
47
|
46
|
|
|
@@ -497,7 +496,12 @@ static uint8_t target_extruder;
|
497
|
496
|
|
498
|
497
|
#endif
|
499
|
498
|
|
500
|
|
-#if ENABLED(SCARA)
|
|
499
|
+#if IS_SCARA
|
|
500
|
+ // Float constants for SCARA calculations
|
|
501
|
+ const float L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2,
|
|
502
|
+ L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2,
|
|
503
|
+ L2_2 = sq(float(L2));
|
|
504
|
+
|
501
|
505
|
float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND,
|
502
|
506
|
delta[ABC],
|
503
|
507
|
axis_scaling[ABC] = { 1, 1, 1 }, // Build size scaling, default to 1
|
|
@@ -651,7 +655,7 @@ inline void sync_plan_position() {
|
651
|
655
|
}
|
652
|
656
|
inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }
|
653
|
657
|
|
654
|
|
-#if ENABLED(DELTA) || ENABLED(SCARA)
|
|
658
|
+#if IS_KINEMATIC
|
655
|
659
|
inline void sync_plan_position_delta() {
|
656
|
660
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
657
|
661
|
if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_delta", current_position);
|
|
@@ -2161,7 +2165,7 @@ static void clean_up_after_endstop_or_probe_move() {
|
2161
|
2165
|
// Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding
|
2162
|
2166
|
refresh_cmd_timeout();
|
2163
|
2167
|
|
2164
|
|
- #if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
2168
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
2165
|
2169
|
planner.bed_level_matrix.set_to_identity();
|
2166
|
2170
|
#endif
|
2167
|
2171
|
|
|
@@ -2272,7 +2276,7 @@ static void clean_up_after_endstop_or_probe_move() {
|
2272
|
2276
|
|
2273
|
2277
|
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
2274
|
2278
|
|
2275
|
|
- #if DISABLED(DELTA)
|
|
2279
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
2276
|
2280
|
|
2277
|
2281
|
/**
|
2278
|
2282
|
* Get the stepper positions, apply the rotation matrix
|
|
@@ -2302,9 +2306,7 @@ static void clean_up_after_endstop_or_probe_move() {
|
2302
|
2306
|
return pos;
|
2303
|
2307
|
}
|
2304
|
2308
|
|
2305
|
|
- #endif // !DELTA
|
2306
|
|
-
|
2307
|
|
- #if ENABLED(DELTA)
|
|
2309
|
+ #elif ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
2308
|
2310
|
|
2309
|
2311
|
/**
|
2310
|
2312
|
* All DELTA leveling in the Marlin uses NONLINEAR_BED_LEVELING
|
|
@@ -2870,7 +2872,7 @@ inline void gcode_G4() {
|
2870
|
2872
|
SERIAL_ECHOPGM("Machine Type: ");
|
2871
|
2873
|
#if ENABLED(DELTA)
|
2872
|
2874
|
SERIAL_ECHOLNPGM("Delta");
|
2873
|
|
- #elif ENABLED(SCARA)
|
|
2875
|
+ #elif IS_SCARA
|
2874
|
2876
|
SERIAL_ECHOLNPGM("SCARA");
|
2875
|
2877
|
#elif ENABLED(COREXY) || ENABLED(COREXZ) || ENABLED(COREYZ)
|
2876
|
2878
|
SERIAL_ECHOLNPGM("Core");
|
|
@@ -2947,11 +2949,12 @@ inline void gcode_G28() {
|
2947
|
2949
|
stepper.synchronize();
|
2948
|
2950
|
|
2949
|
2951
|
// For auto bed leveling, clear the level matrix
|
2950
|
|
- #if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
2952
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
2951
|
2953
|
planner.bed_level_matrix.set_to_identity();
|
2952
|
|
- #if ENABLED(DELTA)
|
2953
|
|
- reset_bed_level();
|
2954
|
|
- #endif
|
|
2954
|
+ #endif
|
|
2955
|
+
|
|
2956
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
|
2957
|
+ reset_bed_level();
|
2955
|
2958
|
#endif
|
2956
|
2959
|
|
2957
|
2960
|
// Always home with tool 0 active
|
|
@@ -3533,7 +3536,7 @@ inline void gcode_G28() {
|
3533
|
3536
|
|
3534
|
3537
|
#if ENABLED(AUTO_BED_LEVELING_GRID)
|
3535
|
3538
|
|
3536
|
|
- #if DISABLED(DELTA)
|
|
3539
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
3537
|
3540
|
bool do_topography_map = verbose_level > 2 || code_seen('T');
|
3538
|
3541
|
#endif
|
3539
|
3542
|
|
|
@@ -3544,7 +3547,7 @@ inline void gcode_G28() {
|
3544
|
3547
|
|
3545
|
3548
|
int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS;
|
3546
|
3549
|
|
3547
|
|
- #if DISABLED(DELTA)
|
|
3550
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
3548
|
3551
|
if (code_seen('P')) auto_bed_leveling_grid_points = code_value_int();
|
3549
|
3552
|
if (auto_bed_leveling_grid_points < 2) {
|
3550
|
3553
|
SERIAL_PROTOCOLLNPGM("?Number of probed (P)oints is implausible (2 minimum).");
|
|
@@ -3594,17 +3597,19 @@ inline void gcode_G28() {
|
3594
|
3597
|
|
3595
|
3598
|
if (!dryrun) {
|
3596
|
3599
|
|
3597
|
|
- // Reset the bed_level_matrix because leveling
|
3598
|
|
- // needs to be done without leveling enabled.
|
3599
|
|
- planner.bed_level_matrix.set_to_identity();
|
|
3600
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
|
3601
|
+ // Reset the bed_level_matrix because leveling
|
|
3602
|
+ // needs to be done without leveling enabled.
|
|
3603
|
+ planner.bed_level_matrix.set_to_identity();
|
|
3604
|
+ #endif
|
3600
|
3605
|
|
3601
|
3606
|
//
|
3602
|
3607
|
// Re-orient the current position without leveling
|
3603
|
3608
|
// based on where the steppers are positioned.
|
3604
|
3609
|
//
|
3605
|
|
- #if ENABLED(DELTA) || ENABLED(SCARA)
|
|
3610
|
+ #if IS_KINEMATIC
|
3606
|
3611
|
|
3607
|
|
- #if ENABLED(DELTA)
|
|
3612
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
3608
|
3613
|
reset_bed_level();
|
3609
|
3614
|
#endif
|
3610
|
3615
|
|
|
@@ -3639,12 +3644,14 @@ inline void gcode_G28() {
|
3639
|
3644
|
const float xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points - 1),
|
3640
|
3645
|
yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points - 1);
|
3641
|
3646
|
|
3642
|
|
- #if ENABLED(DELTA)
|
|
3647
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
3643
|
3648
|
delta_grid_spacing[X_AXIS] = xGridSpacing;
|
3644
|
3649
|
delta_grid_spacing[Y_AXIS] = yGridSpacing;
|
3645
|
3650
|
float zoffset = zprobe_zoffset;
|
3646
|
3651
|
if (code_seen('Z')) zoffset += code_value_axis_units(Z_AXIS);
|
3647
|
|
- #else // !DELTA
|
|
3652
|
+
|
|
3653
|
+ #elif ENABLED(AUTO_BED_LEVELING_LINEAR)
|
|
3654
|
+
|
3648
|
3655
|
/**
|
3649
|
3656
|
* solve the plane equation ax + by + d = z
|
3650
|
3657
|
* A is the matrix with rows [x y 1] for all the probed points
|
|
@@ -3660,7 +3667,8 @@ inline void gcode_G28() {
|
3660
|
3667
|
eqnBVector[abl2], // "B" vector of Z points
|
3661
|
3668
|
mean = 0.0;
|
3662
|
3669
|
int8_t indexIntoAB[auto_bed_leveling_grid_points][auto_bed_leveling_grid_points];
|
3663
|
|
- #endif // !DELTA
|
|
3670
|
+
|
|
3671
|
+ #endif // AUTO_BED_LEVELING_LINEAR
|
3664
|
3672
|
|
3665
|
3673
|
int probePointCounter = 0;
|
3666
|
3674
|
bool zig = auto_bed_leveling_grid_points & 1; //always end at [RIGHT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION]
|
|
@@ -3694,16 +3702,19 @@ inline void gcode_G28() {
|
3694
|
3702
|
|
3695
|
3703
|
float measured_z = probe_pt(xProbe, yProbe, stow_probe_after_each, verbose_level);
|
3696
|
3704
|
|
3697
|
|
- #if DISABLED(DELTA)
|
3698
|
|
- mean += measured_z;
|
|
3705
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
3699
|
3706
|
|
|
3707
|
+ mean += measured_z;
|
3700
|
3708
|
eqnBVector[probePointCounter] = measured_z;
|
3701
|
3709
|
eqnAMatrix[probePointCounter + 0 * abl2] = xProbe;
|
3702
|
3710
|
eqnAMatrix[probePointCounter + 1 * abl2] = yProbe;
|
3703
|
3711
|
eqnAMatrix[probePointCounter + 2 * abl2] = 1;
|
3704
|
3712
|
indexIntoAB[xCount][yCount] = probePointCounter;
|
3705
|
|
- #else
|
|
3713
|
+
|
|
3714
|
+ #elif ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
|
3715
|
+
|
3706
|
3716
|
bed_level[xCount][yCount] = measured_z + zoffset;
|
|
3717
|
+
|
3707
|
3718
|
#endif
|
3708
|
3719
|
|
3709
|
3720
|
probePointCounter++;
|
|
@@ -3713,7 +3724,7 @@ inline void gcode_G28() {
|
3713
|
3724
|
} //xProbe
|
3714
|
3725
|
} //yProbe
|
3715
|
3726
|
|
3716
|
|
- #else // !AUTO_BED_LEVELING_GRID
|
|
3727
|
+ #elif ENABLED(AUTO_BED_LEVELING_3POINT)
|
3717
|
3728
|
|
3718
|
3729
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
3719
|
3730
|
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("> 3-point Leveling");
|
|
@@ -3759,12 +3770,12 @@ inline void gcode_G28() {
|
3759
|
3770
|
|
3760
|
3771
|
// Calculate leveling, print reports, correct the position
|
3761
|
3772
|
#if ENABLED(AUTO_BED_LEVELING_GRID)
|
3762
|
|
- #if ENABLED(DELTA)
|
|
3773
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
3763
|
3774
|
|
3764
|
3775
|
if (!dryrun) extrapolate_unprobed_bed_level();
|
3765
|
3776
|
print_bed_level();
|
3766
|
3777
|
|
3767
|
|
- #else // !DELTA
|
|
3778
|
+ #elif ENABLED(AUTO_BED_LEVELING_LINEAR)
|
3768
|
3779
|
|
3769
|
3780
|
// solve lsq problem
|
3770
|
3781
|
double plane_equation_coefficients[3];
|
|
@@ -3860,11 +3871,11 @@ inline void gcode_G28() {
|
3860
|
3871
|
}
|
3861
|
3872
|
} //do_topography_map
|
3862
|
3873
|
|
3863
|
|
- #endif //!DELTA
|
|
3874
|
+ #endif // AUTO_BED_LEVELING_LINEAR
|
3864
|
3875
|
|
3865
|
3876
|
#endif // AUTO_BED_LEVELING_GRID
|
3866
|
3877
|
|
3867
|
|
- #if DISABLED(DELTA)
|
|
3878
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
3868
|
3879
|
|
3869
|
3880
|
if (verbose_level > 0)
|
3870
|
3881
|
planner.bed_level_matrix.debug("\n\nBed Level Correction Matrix:");
|
|
@@ -4358,10 +4369,10 @@ inline void gcode_M42() {
|
4358
|
4369
|
if (verbose_level > 2)
|
4359
|
4370
|
SERIAL_PROTOCOLLNPGM("Positioning the probe...");
|
4360
|
4371
|
|
4361
|
|
- #if ENABLED(DELTA)
|
|
4372
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
4362
|
4373
|
// we don't do bed level correction in M48 because we want the raw data when we probe
|
4363
|
4374
|
reset_bed_level();
|
4364
|
|
- #elif ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
4375
|
+ #elif ENABLED(AUTO_BED_LEVELING_LINEAR)
|
4365
|
4376
|
// we don't do bed level correction in M48 because we want the raw data when we probe
|
4366
|
4377
|
planner.bed_level_matrix.set_to_identity();
|
4367
|
4378
|
#endif
|
|
@@ -6361,7 +6372,7 @@ inline void gcode_M503() {
|
6361
|
6372
|
lastpos[i] = destination[i] = current_position[i];
|
6362
|
6373
|
|
6363
|
6374
|
// Define runplan for move axes
|
6364
|
|
- #if ENABLED(DELTA)
|
|
6375
|
+ #if IS_KINEMATIC
|
6365
|
6376
|
#define RUNPLAN(RATE_MM_S) inverse_kinematics(destination); \
|
6366
|
6377
|
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], RATE_MM_S, active_extruder);
|
6367
|
6378
|
#else
|
|
@@ -6482,7 +6493,7 @@ inline void gcode_M503() {
|
6482
|
6493
|
destination[E_AXIS] = lastpos[E_AXIS];
|
6483
|
6494
|
planner.set_e_position_mm(current_position[E_AXIS]);
|
6484
|
6495
|
|
6485
|
|
- #if ENABLED(DELTA)
|
|
6496
|
+ #if IS_KINEMATIC
|
6486
|
6497
|
// Move XYZ to starting position, then E
|
6487
|
6498
|
inverse_kinematics(lastpos);
|
6488
|
6499
|
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], FILAMENT_CHANGE_XY_FEEDRATE, active_extruder);
|
|
@@ -6925,7 +6936,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
6925
|
6936
|
* Z software endstop. But this is technically correct (and
|
6926
|
6937
|
* there is no viable alternative).
|
6927
|
6938
|
*/
|
6928
|
|
- #if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
6939
|
+ #if ENABLED(AUTO_BED_LEVELING_LINEAR)
|
6929
|
6940
|
// Offset extruder, make sure to apply the bed level rotation matrix
|
6930
|
6941
|
vector_3 tmp_offset_vec = vector_3(hotend_offset[X_AXIS][tmp_extruder],
|
6931
|
6942
|
hotend_offset[Y_AXIS][tmp_extruder],
|
|
@@ -7961,7 +7972,7 @@ void ok_to_send() {
|
7961
|
7972
|
stepper.get_axis_position_mm(C_AXIS));
|
7962
|
7973
|
}
|
7963
|
7974
|
|
7964
|
|
- #if ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
7975
|
+ #if ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
7965
|
7976
|
|
7966
|
7977
|
// Adjust print surface height by linear interpolation over the bed_level array.
|
7967
|
7978
|
void adjust_delta(float cartesian[XYZ]) {
|
|
@@ -8001,7 +8012,7 @@ void ok_to_send() {
|
8001
|
8012
|
SERIAL_ECHOPGM(" offset="); SERIAL_ECHOLN(offset);
|
8002
|
8013
|
*/
|
8003
|
8014
|
}
|
8004
|
|
- #endif // AUTO_BED_LEVELING_FEATURE
|
|
8015
|
+ #endif // AUTO_BED_LEVELING_NONLINEAR
|
8005
|
8016
|
|
8006
|
8017
|
#endif // DELTA
|
8007
|
8018
|
|
|
@@ -8076,7 +8087,7 @@ void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_
|
8076
|
8087
|
}
|
8077
|
8088
|
#endif // MESH_BED_LEVELING
|
8078
|
8089
|
|
8079
|
|
-#if ENABLED(DELTA) || ENABLED(SCARA)
|
|
8090
|
+#if IS_KINEMATIC
|
8080
|
8091
|
|
8081
|
8092
|
inline bool prepare_kinematic_move_to(float target[NUM_AXIS]) {
|
8082
|
8093
|
float difference[NUM_AXIS];
|
|
@@ -8103,7 +8114,7 @@ void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_
|
8103
|
8114
|
|
8104
|
8115
|
inverse_kinematics(target);
|
8105
|
8116
|
|
8106
|
|
- #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
8117
|
+ #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
8107
|
8118
|
if (!bed_leveling_in_progress) adjust_delta(target);
|
8108
|
8119
|
#endif
|
8109
|
8120
|
|
|
@@ -8115,7 +8126,7 @@ void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_
|
8115
|
8126
|
return true;
|
8116
|
8127
|
}
|
8117
|
8128
|
|
8118
|
|
-#endif // DELTA || SCARA
|
|
8129
|
+#endif // IS_KINEMATIC
|
8119
|
8130
|
|
8120
|
8131
|
#if ENABLED(DUAL_X_CARRIAGE)
|
8121
|
8132
|
|
|
@@ -8161,7 +8172,7 @@ void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_
|
8161
|
8172
|
|
8162
|
8173
|
#endif // DUAL_X_CARRIAGE
|
8163
|
8174
|
|
8164
|
|
-#if DISABLED(DELTA) && DISABLED(SCARA)
|
|
8175
|
+#if !IS_KINEMATIC
|
8165
|
8176
|
|
8166
|
8177
|
inline bool prepare_move_to_destination_cartesian() {
|
8167
|
8178
|
// Do not use feedrate_percentage for E or Z only moves
|
|
@@ -8181,7 +8192,7 @@ void mesh_line_to_destination(float fr_mm_s, uint8_t x_splits = 0xff, uint8_t y_
|
8181
|
8192
|
return true;
|
8182
|
8193
|
}
|
8183
|
8194
|
|
8184
|
|
-#endif // !DELTA && !SCARA
|
|
8195
|
+#endif // !IS_KINEMATIC
|
8185
|
8196
|
|
8186
|
8197
|
#if ENABLED(PREVENT_COLD_EXTRUSION)
|
8187
|
8198
|
|
|
@@ -8220,7 +8231,7 @@ void prepare_move_to_destination() {
|
8220
|
8231
|
prevent_dangerous_extrude(current_position[E_AXIS], destination[E_AXIS]);
|
8221
|
8232
|
#endif
|
8222
|
8233
|
|
8223
|
|
- #if ENABLED(DELTA) || ENABLED(SCARA)
|
|
8234
|
+ #if IS_KINEMATIC
|
8224
|
8235
|
if (!prepare_kinematic_move_to(destination)) return;
|
8225
|
8236
|
#else
|
8226
|
8237
|
#if ENABLED(DUAL_X_CARRIAGE)
|
|
@@ -8356,9 +8367,9 @@ void prepare_move_to_destination() {
|
8356
|
8367
|
|
8357
|
8368
|
clamp_to_software_endstops(arc_target);
|
8358
|
8369
|
|
8359
|
|
- #if ENABLED(DELTA) || ENABLED(SCARA)
|
|
8370
|
+ #if IS_KINEMATIC
|
8360
|
8371
|
inverse_kinematics(arc_target);
|
8361
|
|
- #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
8372
|
+ #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
8362
|
8373
|
adjust_delta(arc_target);
|
8363
|
8374
|
#endif
|
8364
|
8375
|
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], arc_target[E_AXIS], fr_mm_s, active_extruder);
|
|
@@ -8368,9 +8379,9 @@ void prepare_move_to_destination() {
|
8368
|
8379
|
}
|
8369
|
8380
|
|
8370
|
8381
|
// Ensure last segment arrives at target location.
|
8371
|
|
- #if ENABLED(DELTA) || ENABLED(SCARA)
|
|
8382
|
+ #if IS_KINEMATIC
|
8372
|
8383
|
inverse_kinematics(target);
|
8373
|
|
- #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_FEATURE)
|
|
8384
|
+ #if ENABLED(DELTA) && ENABLED(AUTO_BED_LEVELING_NONLINEAR)
|
8374
|
8385
|
adjust_delta(target);
|
8375
|
8386
|
#endif
|
8376
|
8387
|
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], fr_mm_s, active_extruder);
|