MarkForged kinematics (#19235)
This commit is contained in:
		| @@ -608,7 +608,7 @@ | |||||||
|  |  | ||||||
| // @section machine | // @section machine | ||||||
|  |  | ||||||
| // Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics | // Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, | ||||||
| // either in the usual order or reversed | // either in the usual order or reversed | ||||||
| //#define COREXY | //#define COREXY | ||||||
| //#define COREXZ | //#define COREXZ | ||||||
| @@ -616,6 +616,7 @@ | |||||||
| //#define COREYX | //#define COREYX | ||||||
| //#define COREZX | //#define COREZX | ||||||
| //#define COREZY | //#define COREZY | ||||||
|  | //#define MARKFORGED_XY  // MarkForged. See https://reprap.org/forum/read.php?152,504042 | ||||||
|  |  | ||||||
| //=========================================================================== | //=========================================================================== | ||||||
| //============================== Endstop Settings =========================== | //============================== Endstop Settings =========================== | ||||||
|   | |||||||
| @@ -57,10 +57,11 @@ void safe_delay(millis_t ms) { | |||||||
|  |  | ||||||
|   void log_machine_info() { |   void log_machine_info() { | ||||||
|     SERIAL_ECHOLNPGM("Machine Type: " |     SERIAL_ECHOLNPGM("Machine Type: " | ||||||
|       TERN_(DELTA, "Delta") |       TERN_(DELTA,         "Delta") | ||||||
|       TERN_(IS_SCARA, "SCARA") |       TERN_(IS_SCARA,      "SCARA") | ||||||
|       TERN_(IS_CORE, "Core") |       TERN_(IS_CORE,       "Core") | ||||||
|       TERN_(IS_CARTESIAN, "Cartesian") |       TERN_(MARKFORGED_XY, "MarkForged") | ||||||
|  |       TERN_(IS_CARTESIAN,  "Cartesian") | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     SERIAL_ECHOLNPGM("Probe: " |     SERIAL_ECHOLNPGM("Probe: " | ||||||
|   | |||||||
| @@ -145,10 +145,11 @@ void GcodeSuite::M360() { | |||||||
|  |  | ||||||
|   config_prefix(PSTR("PrinterType")); |   config_prefix(PSTR("PrinterType")); | ||||||
|   SERIAL_ECHOLNPGM( |   SERIAL_ECHOLNPGM( | ||||||
|     TERN_(DELTA,        "Delta") |     TERN_(DELTA,         "Delta") | ||||||
|     TERN_(IS_SCARA,     "SCARA") |     TERN_(IS_SCARA,      "SCARA") | ||||||
|     TERN_(IS_CORE,      "Core") |     TERN_(IS_CORE,       "Core") | ||||||
|     TERN_(IS_CARTESIAN, "Cartesian") |     TERN_(MARKFORGED_XY, "MarkForged") | ||||||
|  |     TERN_(IS_CARTESIAN,  "Cartesian") | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   | |||||||
| @@ -149,11 +149,16 @@ | |||||||
|     #define CORE_AXIS_2 C_AXIS |     #define CORE_AXIS_2 C_AXIS | ||||||
|   #endif |   #endif | ||||||
|   #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) |   #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) | ||||||
|  | #elif ENABLED(MARKFORGED_XY) | ||||||
|  |   // Markforged kinematics | ||||||
|  |   #define CORE_AXIS_1 A_AXIS | ||||||
|  |   #define CORE_AXIS_2 B_AXIS | ||||||
|  |   #define NORMAL_AXIS Z_AXIS | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Calibration codes only for non-core axes | // Calibration codes only for non-core axes | ||||||
| #if EITHER(BACKLASH_GCODE, CALIBRATION_GCODE) | #if EITHER(BACKLASH_GCODE, CALIBRATION_GCODE) | ||||||
|   #if IS_CORE |   #if EITHER(IS_CORE, MARKFORGED_XY) | ||||||
|     #define X_AXIS_INDEX 0 |     #define X_AXIS_INDEX 0 | ||||||
|     #define Y_AXIS_INDEX 1 |     #define Y_AXIS_INDEX 1 | ||||||
|     #define Z_AXIS_INDEX 2 |     #define Z_AXIS_INDEX 2 | ||||||
|   | |||||||
| @@ -764,6 +764,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
| #if ENABLED(BABYSTEPPING) | #if ENABLED(BABYSTEPPING) | ||||||
|   #if ENABLED(SCARA) |   #if ENABLED(SCARA) | ||||||
|     #error "BABYSTEPPING is not implemented for SCARA yet." |     #error "BABYSTEPPING is not implemented for SCARA yet." | ||||||
|  |   #elif BOTH(MARKFORGED_XY, BABYSTEP_XY) | ||||||
|  |     #error "BABYSTEPPING only implemented for Z axis on MarkForged." | ||||||
|   #elif BOTH(DELTA, BABYSTEP_XY) |   #elif BOTH(DELTA, BABYSTEP_XY) | ||||||
|     #error "BABYSTEPPING only implemented for Z axis on deltabots." |     #error "BABYSTEPPING only implemented for Z axis on deltabots." | ||||||
|   #elif BOTH(BABYSTEP_ZPROBE_OFFSET, MESH_BED_LEVELING) |   #elif BOTH(BABYSTEP_ZPROBE_OFFSET, MESH_BED_LEVELING) | ||||||
| @@ -1155,8 +1157,9 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
|   + ENABLED(COREYZ) \ |   + ENABLED(COREYZ) \ | ||||||
|   + ENABLED(COREYX) \ |   + ENABLED(COREYX) \ | ||||||
|   + ENABLED(COREZX) \ |   + ENABLED(COREZX) \ | ||||||
|   + ENABLED(COREZY) |   + ENABLED(COREZY) \ | ||||||
|   #error "Please enable only one of DELTA, MORGAN_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, or COREZY." |   + ENABLED(MARKFORGED_XY) | ||||||
|  |   #error "Please enable only one of DELTA, MORGAN_SCARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, COREZY, or MARKFORGED_XY." | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1576,8 +1579,8 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal | |||||||
| #if ENABLED(DUAL_X_CARRIAGE) | #if ENABLED(DUAL_X_CARRIAGE) | ||||||
|   #if EXTRUDERS < 2 |   #if EXTRUDERS < 2 | ||||||
|     #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." |     #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." | ||||||
|   #elif CORE_IS_XY || CORE_IS_XZ |   #elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) | ||||||
|     #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, or COREZX." |     #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, or MARKFORGED_XY." | ||||||
|   #elif !GOOD_AXIS_PINS(X2) |   #elif !GOOD_AXIS_PINS(X2) | ||||||
|     #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." |     #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." | ||||||
|   #elif !HAS_X_MAX |   #elif !HAS_X_MAX | ||||||
| @@ -2533,6 +2536,8 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal | |||||||
|   #error "CoreXZ requires both X and Z to use sensorless homing if either one does." |   #error "CoreXZ requires both X and Z to use sensorless homing if either one does." | ||||||
| #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE | #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE | ||||||
|   #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." |   #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." | ||||||
|  | #elif ENABLED(MARKFORGED_XY) && X_SENSORLESS != Y_SENSORLESS | ||||||
|  |   #error "MARKFORGED_XY requires both X and Y to use sensorless homing if either one does." | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Other TMC feature requirements | // Other TMC feature requirements | ||||||
| @@ -2848,6 +2853,10 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) | |||||||
|     #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." |     #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." | ||||||
|   #elif !defined(BACKLASH_CORRECTION) |   #elif !defined(BACKLASH_CORRECTION) | ||||||
|     #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." |     #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |     constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; | ||||||
|  |     static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], | ||||||
|  |                   "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system."); | ||||||
|   #elif IS_CORE |   #elif IS_CORE | ||||||
|     constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; |     constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; | ||||||
|     static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], |     static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], | ||||||
|   | |||||||
| @@ -498,7 +498,7 @@ void Endstops::update() { | |||||||
|   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) |   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) | ||||||
|   #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) |   #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) | ||||||
|  |  | ||||||
|   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) |   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) | ||||||
|     // If G38 command is active check Z_MIN_PROBE for ALL movement |     // If G38 command is active check Z_MIN_PROBE for ALL movement | ||||||
|     if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE); |     if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE); | ||||||
|   #endif |   #endif | ||||||
| @@ -514,12 +514,12 @@ void Endstops::update() { | |||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   // Use HEAD for core axes, AXIS for others |   // Use HEAD for core axes, AXIS for others | ||||||
|   #if CORE_IS_XY || CORE_IS_XZ |   #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) | ||||||
|     #define X_AXIS_HEAD X_HEAD |     #define X_AXIS_HEAD X_HEAD | ||||||
|   #else |   #else | ||||||
|     #define X_AXIS_HEAD X_AXIS |     #define X_AXIS_HEAD X_AXIS | ||||||
|   #endif |   #endif | ||||||
|   #if CORE_IS_XY || CORE_IS_YZ |   #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY) | ||||||
|     #define Y_AXIS_HEAD Y_HEAD |     #define Y_AXIS_HEAD Y_HEAD | ||||||
|   #else |   #else | ||||||
|     #define Y_AXIS_HEAD Y_AXIS |     #define Y_AXIS_HEAD Y_AXIS | ||||||
| @@ -736,7 +736,7 @@ void Endstops::update() { | |||||||
|     #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX) |     #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX) | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) |   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) | ||||||
|     #if ENABLED(G38_PROBE_AWAY) |     #if ENABLED(G38_PROBE_AWAY) | ||||||
|       #define _G38_OPEN_STATE (G38_move >= 4) |       #define _G38_OPEN_STATE (G38_move >= 4) | ||||||
|     #else |     #else | ||||||
| @@ -865,7 +865,7 @@ void Endstops::update() { | |||||||
|     bool hit = false; |     bool hit = false; | ||||||
|     #if X_SPI_SENSORLESS |     #if X_SPI_SENSORLESS | ||||||
|       if (tmc_spi_homing.x && (stepperX.test_stall_status() |       if (tmc_spi_homing.x && (stepperX.test_stall_status() | ||||||
|         #if CORE_IS_XY && Y_SPI_SENSORLESS |         #if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS | ||||||
|           || stepperY.test_stall_status() |           || stepperY.test_stall_status() | ||||||
|         #elif CORE_IS_XZ && Z_SPI_SENSORLESS |         #elif CORE_IS_XZ && Z_SPI_SENSORLESS | ||||||
|           || stepperZ.test_stall_status() |           || stepperZ.test_stall_status() | ||||||
| @@ -877,7 +877,7 @@ void Endstops::update() { | |||||||
|     #endif |     #endif | ||||||
|     #if Y_SPI_SENSORLESS |     #if Y_SPI_SENSORLESS | ||||||
|       if (tmc_spi_homing.y && (stepperY.test_stall_status() |       if (tmc_spi_homing.y && (stepperY.test_stall_status() | ||||||
|         #if CORE_IS_XY && X_SPI_SENSORLESS |         #if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS | ||||||
|           || stepperX.test_stall_status() |           || stepperX.test_stall_status() | ||||||
|         #elif CORE_IS_YZ && Z_SPI_SENSORLESS |         #elif CORE_IS_YZ && Z_SPI_SENSORLESS | ||||||
|           || stepperZ.test_stall_status() |           || stepperZ.test_stall_status() | ||||||
|   | |||||||
| @@ -1152,7 +1152,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { | |||||||
|           #if AXIS_HAS_STALLGUARD(X2) |           #if AXIS_HAS_STALLGUARD(X2) | ||||||
|             stealth_states.x2 = tmc_enable_stallguard(stepperX2); |             stealth_states.x2 = tmc_enable_stallguard(stepperX2); | ||||||
|           #endif |           #endif | ||||||
|           #if CORE_IS_XY && Y_SENSORLESS |           #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS | ||||||
|             stealth_states.y = tmc_enable_stallguard(stepperY); |             stealth_states.y = tmc_enable_stallguard(stepperY); | ||||||
|           #elif CORE_IS_XZ && Z_SENSORLESS |           #elif CORE_IS_XZ && Z_SENSORLESS | ||||||
|             stealth_states.z = tmc_enable_stallguard(stepperZ); |             stealth_states.z = tmc_enable_stallguard(stepperZ); | ||||||
| @@ -1165,7 +1165,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { | |||||||
|           #if AXIS_HAS_STALLGUARD(Y2) |           #if AXIS_HAS_STALLGUARD(Y2) | ||||||
|             stealth_states.y2 = tmc_enable_stallguard(stepperY2); |             stealth_states.y2 = tmc_enable_stallguard(stepperY2); | ||||||
|           #endif |           #endif | ||||||
|           #if CORE_IS_XY && X_SENSORLESS |           #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS | ||||||
|             stealth_states.x = tmc_enable_stallguard(stepperX); |             stealth_states.x = tmc_enable_stallguard(stepperX); | ||||||
|           #elif CORE_IS_YZ && Z_SENSORLESS |           #elif CORE_IS_YZ && Z_SENSORLESS | ||||||
|             stealth_states.z = tmc_enable_stallguard(stepperZ); |             stealth_states.z = tmc_enable_stallguard(stepperZ); | ||||||
| @@ -1216,7 +1216,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { | |||||||
|           #if AXIS_HAS_STALLGUARD(X2) |           #if AXIS_HAS_STALLGUARD(X2) | ||||||
|             tmc_disable_stallguard(stepperX2, enable_stealth.x2); |             tmc_disable_stallguard(stepperX2, enable_stealth.x2); | ||||||
|           #endif |           #endif | ||||||
|           #if CORE_IS_XY && Y_SENSORLESS |           #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS | ||||||
|             tmc_disable_stallguard(stepperY, enable_stealth.y); |             tmc_disable_stallguard(stepperY, enable_stealth.y); | ||||||
|           #elif CORE_IS_XZ && Z_SENSORLESS |           #elif CORE_IS_XZ && Z_SENSORLESS | ||||||
|             tmc_disable_stallguard(stepperZ, enable_stealth.z); |             tmc_disable_stallguard(stepperZ, enable_stealth.z); | ||||||
| @@ -1229,7 +1229,7 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { | |||||||
|           #if AXIS_HAS_STALLGUARD(Y2) |           #if AXIS_HAS_STALLGUARD(Y2) | ||||||
|             tmc_disable_stallguard(stepperY2, enable_stealth.y2); |             tmc_disable_stallguard(stepperY2, enable_stealth.y2); | ||||||
|           #endif |           #endif | ||||||
|           #if CORE_IS_XY && X_SENSORLESS |           #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS | ||||||
|             tmc_disable_stallguard(stepperX, enable_stealth.x); |             tmc_disable_stallguard(stepperX, enable_stealth.x); | ||||||
|           #elif CORE_IS_YZ && Z_SENSORLESS |           #elif CORE_IS_YZ && Z_SENSORLESS | ||||||
|             tmc_disable_stallguard(stepperZ, enable_stealth.z); |             tmc_disable_stallguard(stepperZ, enable_stealth.z); | ||||||
| @@ -1789,7 +1789,7 @@ void homeaxis(const AxisEnum axis) { | |||||||
|       do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); |       do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   #else // CARTESIAN / CORE |   #else // CARTESIAN / CORE / MARKFORGED_XY | ||||||
|  |  | ||||||
|     set_axis_is_at_home(axis); |     set_axis_is_at_home(axis); | ||||||
|     sync_plan_position(); |     sync_plan_position(); | ||||||
| @@ -1818,8 +1818,11 @@ void homeaxis(const AxisEnum axis) { | |||||||
|  |  | ||||||
|       #if ENABLED(SENSORLESS_HOMING) |       #if ENABLED(SENSORLESS_HOMING) | ||||||
|         planner.synchronize(); |         planner.synchronize(); | ||||||
|         if (TERN0(IS_CORE, axis != NORMAL_AXIS)) |         if (false | ||||||
|           safe_delay(200);  // Short delay to allow belts to spring back |           #if EITHER(IS_CORE, MARKFORGED_XY) | ||||||
|  |             || axis != NORMAL_AXIS | ||||||
|  |           #endif | ||||||
|  |         ) safe_delay(200);  // Short delay to allow belts to spring back | ||||||
|       #endif |       #endif | ||||||
|     } |     } | ||||||
|   #endif |   #endif | ||||||
|   | |||||||
| @@ -1614,6 +1614,7 @@ void Planner::finish_and_disable() { | |||||||
| float Planner::get_axis_position_mm(const AxisEnum axis) { | float Planner::get_axis_position_mm(const AxisEnum axis) { | ||||||
|   float axis_steps; |   float axis_steps; | ||||||
|   #if IS_CORE |   #if IS_CORE | ||||||
|  |  | ||||||
|     // Requesting one of the "core" axes? |     // Requesting one of the "core" axes? | ||||||
|     if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { |     if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { | ||||||
|  |  | ||||||
| @@ -1631,9 +1632,30 @@ float Planner::get_axis_position_mm(const AxisEnum axis) { | |||||||
|     } |     } | ||||||
|     else |     else | ||||||
|       axis_steps = stepper.position(axis); |       axis_steps = stepper.position(axis); | ||||||
|  |  | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |  | ||||||
|  |     // Requesting one of the joined axes? | ||||||
|  |     if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { | ||||||
|  |       // Protect the access to the position. | ||||||
|  |       const bool was_enabled = stepper.suspend(); | ||||||
|  |  | ||||||
|  |       const int32_t p1 = stepper.position(CORE_AXIS_1), | ||||||
|  |                     p2 = stepper.position(CORE_AXIS_2); | ||||||
|  |  | ||||||
|  |       if (was_enabled) stepper.wake_up(); | ||||||
|  |  | ||||||
|  |       axis_steps = ((axis == CORE_AXIS_1) ? p1 - p2 : p2); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |       axis_steps = stepper.position(axis); | ||||||
|  |  | ||||||
|   #else |   #else | ||||||
|  |  | ||||||
|     axis_steps = stepper.position(axis); |     axis_steps = stepper.position(axis); | ||||||
|  |  | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   return axis_steps * steps_to_mm[axis]; |   return axis_steps * steps_to_mm[axis]; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1808,6 +1830,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|     if (dc < 0) SBI(dm, Z_HEAD);                // ...and Z |     if (dc < 0) SBI(dm, Z_HEAD);                // ...and Z | ||||||
|     if (db + dc < 0) SBI(dm, B_AXIS);           // Motor B direction |     if (db + dc < 0) SBI(dm, B_AXIS);           // Motor B direction | ||||||
|     if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction |     if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |     if (da < 0) SBI(dm, X_HEAD);                // Save the real Extruder (head) direction in X Axis | ||||||
|  |     if (db < 0) SBI(dm, Y_HEAD);                // ...and Y | ||||||
|  |     if (dc < 0) SBI(dm, Z_AXIS); | ||||||
|  |     if (da + db < 0) SBI(dm, A_AXIS);           // Motor A direction | ||||||
|  |     if (db < 0) SBI(dm, B_AXIS);                // Motor B direction | ||||||
|   #else |   #else | ||||||
|     if (da < 0) SBI(dm, X_AXIS); |     if (da < 0) SBI(dm, X_AXIS); | ||||||
|     if (db < 0) SBI(dm, Y_AXIS); |     if (db < 0) SBI(dm, Y_AXIS); | ||||||
| @@ -1843,6 +1871,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|     block->steps.set(ABS(da + dc), ABS(db), ABS(da - dc)); |     block->steps.set(ABS(da + dc), ABS(db), ABS(da - dc)); | ||||||
|   #elif CORE_IS_YZ |   #elif CORE_IS_YZ | ||||||
|     block->steps.set(ABS(da), ABS(db + dc), ABS(db - dc)); |     block->steps.set(ABS(da), ABS(db + dc), ABS(db - dc)); | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |     block->steps.set(ABS(da + db), ABS(db), ABS(dc)); | ||||||
|   #elif IS_SCARA |   #elif IS_SCARA | ||||||
|     block->steps.set(ABS(da), ABS(db), ABS(dc)); |     block->steps.set(ABS(da), ABS(db), ABS(dc)); | ||||||
|   #else |   #else | ||||||
| @@ -1859,7 +1889,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|    * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed. |    * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed. | ||||||
|    */ |    */ | ||||||
|   struct DistanceMM : abce_float_t { |   struct DistanceMM : abce_float_t { | ||||||
|     TERN_(IS_CORE, xyz_pos_t head); |     #if EITHER(IS_CORE, MARKFORGED_XY) | ||||||
|  |       xyz_pos_t head; | ||||||
|  |     #endif | ||||||
|   } steps_dist_mm; |   } steps_dist_mm; | ||||||
|   #if IS_CORE |   #if IS_CORE | ||||||
|     #if CORE_IS_XY |     #if CORE_IS_XY | ||||||
| @@ -1881,6 +1913,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       steps_dist_mm.b      = (db + dc) * steps_to_mm[B_AXIS]; |       steps_dist_mm.b      = (db + dc) * steps_to_mm[B_AXIS]; | ||||||
|       steps_dist_mm.c      = CORESIGN(db - dc) * steps_to_mm[C_AXIS]; |       steps_dist_mm.c      = CORESIGN(db - dc) * steps_to_mm[C_AXIS]; | ||||||
|     #endif |     #endif | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |     steps_dist_mm.head.x = da * steps_to_mm[A_AXIS]; | ||||||
|  |     steps_dist_mm.head.y = db * steps_to_mm[B_AXIS]; | ||||||
|  |     steps_dist_mm.z      = dc * steps_to_mm[Z_AXIS]; | ||||||
|  |     steps_dist_mm.a      = (da - db) * steps_to_mm[A_AXIS]; | ||||||
|  |     steps_dist_mm.b      = db * steps_to_mm[B_AXIS]; | ||||||
|   #else |   #else | ||||||
|     steps_dist_mm.a = da * steps_to_mm[A_AXIS]; |     steps_dist_mm.a = da * steps_to_mm[A_AXIS]; | ||||||
|     steps_dist_mm.b = db * steps_to_mm[B_AXIS]; |     steps_dist_mm.b = db * steps_to_mm[B_AXIS]; | ||||||
| @@ -1907,7 +1945,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       block->millimeters = millimeters; |       block->millimeters = millimeters; | ||||||
|     else |     else | ||||||
|       block->millimeters = SQRT( |       block->millimeters = SQRT( | ||||||
|         #if CORE_IS_XY |         #if EITHER(CORE_IS_XY, MARKFORGED_XY) | ||||||
|           sq(steps_dist_mm.head.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.z) |           sq(steps_dist_mm.head.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.z) | ||||||
|         #elif CORE_IS_XZ |         #elif CORE_IS_XZ | ||||||
|           sq(steps_dist_mm.head.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.head.z) |           sq(steps_dist_mm.head.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.head.z) | ||||||
| @@ -1964,7 +2002,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   // Enable active axes |   // Enable active axes | ||||||
|   #if CORE_IS_XY |   #if EITHER(CORE_IS_XY, MARKFORGED_XY) | ||||||
|     if (block->steps.a || block->steps.b) { |     if (block->steps.a || block->steps.b) { | ||||||
|       ENABLE_AXIS_X(); |       ENABLE_AXIS_X(); | ||||||
|       ENABLE_AXIS_Y(); |       ENABLE_AXIS_Y(); | ||||||
| @@ -2325,9 +2363,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|      * On CoreXY the length of the vector [A,B] is SQRT(2) times the length of the head movement vector [X,Y]. |      * On CoreXY the length of the vector [A,B] is SQRT(2) times the length of the head movement vector [X,Y]. | ||||||
|      * So taking Z and E into account, we cannot scale to a unit vector with "inverse_millimeters". |      * So taking Z and E into account, we cannot scale to a unit vector with "inverse_millimeters". | ||||||
|      * => normalize the complete junction vector. |      * => normalize the complete junction vector. | ||||||
|      * Elsewise, when needed JD factors in the E component |      * Elsewise, when needed JD will factor-in the E component | ||||||
|      */ |      */ | ||||||
|     if (ENABLED(IS_CORE) || esteps > 0) |     if (EITHER(IS_CORE, MARKFORGED_XY) || esteps > 0) | ||||||
|       normalize_junction_vector(unit_vec);  // Normalize with XYZE components |       normalize_junction_vector(unit_vec);  // Normalize with XYZE components | ||||||
|     else |     else | ||||||
|       unit_vec *= inverse_millimeters;      // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2)) |       unit_vec *= inverse_millimeters;      // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2)) | ||||||
|   | |||||||
| @@ -2041,6 +2041,8 @@ uint32_t Stepper::block_phase_isr() { | |||||||
|           #define X_CMP(A,B) ((A)!=(B)) |           #define X_CMP(A,B) ((A)!=(B)) | ||||||
|         #endif |         #endif | ||||||
|         #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) ) |         #define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) ) | ||||||
|  |       #elif ENABLED(MARKFORGED_XY) | ||||||
|  |         #define X_MOVE_TEST (current_block->steps.a != current_block->steps.b) | ||||||
|       #else |       #else | ||||||
|         #define X_MOVE_TEST !!current_block->steps.a |         #define X_MOVE_TEST !!current_block->steps.a | ||||||
|       #endif |       #endif | ||||||
| @@ -2614,6 +2616,8 @@ void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c | |||||||
|   #elif CORE_IS_YZ |   #elif CORE_IS_YZ | ||||||
|     // coreyz planning |     // coreyz planning | ||||||
|     count_position.set(a, b + c, CORESIGN(b - c)); |     count_position.set(a, b + c, CORESIGN(b - c)); | ||||||
|  |   #elif ENABLED(MARKFORGED_XY) | ||||||
|  |     count_position.set(a - b, b, c); | ||||||
|   #else |   #else | ||||||
|     // default non-h-bot planning |     // default non-h-bot planning | ||||||
|     count_position.set(a, b, c); |     count_position.set(a, b, c); | ||||||
| @@ -2680,6 +2684,10 @@ void Stepper::endstop_triggered(const AxisEnum axis) { | |||||||
|         ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]) |         ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]) | ||||||
|         : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2] |         : count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2] | ||||||
|       ) * double(0.5) |       ) * double(0.5) | ||||||
|  |     #elif ENABLED(MARKFORGED_XY) | ||||||
|  |       axis == CORE_AXIS_1 | ||||||
|  |         ? count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2] | ||||||
|  |         : count_position[CORE_AXIS_2] | ||||||
|     #else // !IS_CORE |     #else // !IS_CORE | ||||||
|       count_position[axis] |       count_position[axis] | ||||||
|     #endif |     #endif | ||||||
| @@ -2709,12 +2717,12 @@ int32_t Stepper::triggered_position(const AxisEnum axis) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void Stepper::report_a_position(const xyz_long_t &pos) { | void Stepper::report_a_position(const xyz_long_t &pos) { | ||||||
|   #if CORE_IS_XY || CORE_IS_XZ || ENABLED(DELTA) || IS_SCARA |   #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, DELTA, IS_SCARA) | ||||||
|     SERIAL_ECHOPAIR(STR_COUNT_A, pos.x, " B:", pos.y); |     SERIAL_ECHOPAIR(STR_COUNT_A, pos.x, " B:", pos.y); | ||||||
|   #else |   #else | ||||||
|     SERIAL_ECHOPAIR_P(PSTR(STR_COUNT_X), pos.x, SP_Y_LBL, pos.y); |     SERIAL_ECHOPAIR_P(PSTR(STR_COUNT_X), pos.x, SP_Y_LBL, pos.y); | ||||||
|   #endif |   #endif | ||||||
|   #if CORE_IS_XZ || CORE_IS_YZ || ENABLED(DELTA) |   #if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA) | ||||||
|     SERIAL_ECHOLNPAIR(" C:", pos.z); |     SERIAL_ECHOLNPAIR(" C:", pos.z); | ||||||
|   #else |   #else | ||||||
|     SERIAL_ECHOLNPAIR_P(SP_Z_LBL, pos.z); |     SERIAL_ECHOLNPAIR_P(SP_Z_LBL, pos.z); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user