🏗️ Support for up to 6 linear axes (#19112)

Co-authored-by: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
DerAndere
2021-06-05 09:18:47 +02:00
committed by Scott Lahteine
parent d3c56a76e7
commit c1fca91103
98 changed files with 5040 additions and 2256 deletions

View File

@ -52,7 +52,10 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
LINEAR_AXIS_GANG(
(parser.seen_test('X') ? _BV(X_AXIS) : 0),
| (parser.seen_test('Y') ? _BV(Y_AXIS) : 0),
| (parser.seen_test('Z') ? _BV(Z_AXIS) : 0))
| (parser.seen_test('Z') ? _BV(Z_AXIS) : 0),
| (parser.seen_test(AXIS4_NAME) ? _BV(I_AXIS) : 0),
| (parser.seen_test(AXIS5_NAME) ? _BV(J_AXIS) : 0),
| (parser.seen_test(AXIS6_NAME) ? _BV(K_AXIS) : 0))
)
#endif
) {
@ -85,7 +88,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves
if (fwretract.autoretract_enabled && parser.seen_test('E') && !parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z"))) {
if (fwretract.autoretract_enabled && parser.seen_test('E')
&& !parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))
) {
const float echange = destination.e - current_position.e;
// Is this a retract or recover move?
if (WITHIN(ABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) {

View File

@ -63,7 +63,7 @@ void plan_arc(
case GcodeSuite::PLANE_ZX: p_axis = Z_AXIS; q_axis = X_AXIS; l_axis = Y_AXIS; break;
}
#else
constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS, l_axis = Z_AXIS;
constexpr AxisEnum p_axis = X_AXIS, q_axis = Y_AXIS OPTARG(HAS_Z_AXIS, l_axis = Z_AXIS);
#endif
// Radius vector from center to current location
@ -73,8 +73,8 @@ void plan_arc(
center_P = current_position[p_axis] - rvec.a,
center_Q = current_position[q_axis] - rvec.b,
rt_X = cart[p_axis] - center_P,
rt_Y = cart[q_axis] - center_Q,
start_L = current_position[l_axis];
rt_Y = cart[q_axis] - center_Q
OPTARG(HAS_Z_AXIS, start_L = current_position[l_axis]);
#ifdef MIN_ARC_SEGMENTS
uint16_t min_segments = MIN_ARC_SEGMENTS;
@ -109,8 +109,9 @@ void plan_arc(
#endif
}
float linear_travel = cart[l_axis] - start_L;
#if HAS_Z_AXIS
float linear_travel = cart[l_axis] - start_L;
#endif
#if HAS_EXTRUDERS
float extruder_travel = cart.e - current_position.e;
#endif
@ -118,9 +119,11 @@ void plan_arc(
// If circling around...
if (ENABLED(ARC_P_CIRCLES) && circles) {
const float total_angular = angular_travel + circles * RADIANS(360), // Total rotation with all circles and remainder
part_per_circle = RADIANS(360) / total_angular, // Each circle's part of the total
l_per_circle = linear_travel * part_per_circle; // L movement per circle
part_per_circle = RADIANS(360) / total_angular; // Each circle's part of the total
#if HAS_Z_AXIS
const float l_per_circle = linear_travel * part_per_circle; // L movement per circle
#endif
#if HAS_EXTRUDERS
const float e_per_circle = extruder_travel * part_per_circle; // E movement per circle
#endif
@ -128,17 +131,15 @@ void plan_arc(
xyze_pos_t temp_position = current_position; // for plan_arc to compare to current_position
for (uint16_t n = circles; n--;) {
TERN_(HAS_EXTRUDERS, temp_position.e += e_per_circle); // Destination E axis
temp_position[l_axis] += l_per_circle; // Destination L axis
TERN_(HAS_Z_AXIS, temp_position[l_axis] += l_per_circle); // Destination L axis
plan_arc(temp_position, offset, clockwise, 0); // Plan a single whole circle
}
linear_travel = cart[l_axis] - current_position[l_axis];
#if HAS_EXTRUDERS
extruder_travel = cart.e - current_position.e;
#endif
TERN_(HAS_Z_AXIS, linear_travel = cart[l_axis] - current_position[l_axis]);
TERN_(HAS_EXTRUDERS, extruder_travel = cart.e - current_position.e);
}
const float flat_mm = radius * angular_travel,
mm_of_travel = linear_travel ? HYPOT(flat_mm, linear_travel) : ABS(flat_mm);
mm_of_travel = TERN_(HAS_Z_AXIS, linear_travel ? HYPOT(flat_mm, linear_travel) :) ABS(flat_mm);
if (mm_of_travel < 0.001f) return;
const feedRate_t scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);
@ -187,17 +188,19 @@ void plan_arc(
// Vector rotation matrix values
xyze_pos_t raw;
const float theta_per_segment = angular_travel / segments,
linear_per_segment = linear_travel / segments,
sq_theta_per_segment = sq(theta_per_segment),
sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
cos_T = 1 - 0.5f * sq_theta_per_segment; // Small angle approximation
#if HAS_Z_AXIS && DISABLED(AUTO_BED_LEVELING_UBL)
const float linear_per_segment = linear_travel / segments;
#endif
#if HAS_EXTRUDERS
const float extruder_per_segment = extruder_travel / segments;
#endif
// Initialize the linear axis
raw[l_axis] = current_position[l_axis];
TERN_(HAS_Z_AXIS, raw[l_axis] = current_position[l_axis]);
// Initialize the extruder axis
TERN_(HAS_EXTRUDERS, raw.e = current_position.e);
@ -246,11 +249,8 @@ void plan_arc(
// Update raw location
raw[p_axis] = center_P + rvec.a;
raw[q_axis] = center_Q + rvec.b;
#if ENABLED(AUTO_BED_LEVELING_UBL)
raw[l_axis] = start_L;
UNUSED(linear_per_segment);
#else
raw[l_axis] += linear_per_segment;
#if HAS_Z_AXIS
raw[l_axis] = TERN(AUTO_BED_LEVELING_UBL, start_L, raw[l_axis] + linear_per_segment);
#endif
TERN_(HAS_EXTRUDERS, raw.e += extruder_per_segment);
@ -268,7 +268,7 @@ void plan_arc(
// Ensure last segment arrives at target location.
raw = cart;
TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L);
TERN_(AUTO_BED_LEVELING_UBL, TERN_(HAS_Z_AXIS, raw[l_axis] = start_L));
apply_motion_limits(raw);
@ -280,7 +280,7 @@ void plan_arc(
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
);
TERN_(AUTO_BED_LEVELING_UBL, raw[l_axis] = start_L);
TERN_(AUTO_BED_LEVELING_UBL, TERN_(HAS_Z_AXIS, raw[l_axis] = start_L));
current_position = raw;
} // plan_arc

View File

@ -87,7 +87,7 @@ void GcodeSuite::M290() {
}
#endif
if (!parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z")) || parser.seen('R')) {
if (!parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR)) || parser.seen('R')) {
SERIAL_ECHO_START();
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)