✨ MarkForged YX kinematics (#23163)
This commit is contained in:
committed by
Scott Lahteine
parent
018c7b1cf4
commit
0e60c8b7e0
@ -617,7 +617,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 COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT))
|
||||
|
||||
#if ENABLED(G38_PROBE_TARGET) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
|
||||
#if ENABLED(G38_PROBE_TARGET) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_XY)
|
||||
#define HAS_G38_PROBE 1
|
||||
// For G38 moves check the probe's pin for ALL movement
|
||||
if (G38_move) UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN));
|
||||
@ -628,12 +628,12 @@ void Endstops::update() {
|
||||
#define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, TERN0(X_HOME_TO_MAX, stepper.last_moved_extruder == 0) || TERN0(X2_HOME_TO_MAX, stepper.last_moved_extruder != 0))
|
||||
|
||||
// Use HEAD for core axes, AXIS for others
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_XY)
|
||||
#define X_AXIS_HEAD X_HEAD
|
||||
#else
|
||||
#define X_AXIS_HEAD X_AXIS
|
||||
#endif
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY)
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX)
|
||||
#define Y_AXIS_HEAD Y_HEAD
|
||||
#else
|
||||
#define Y_AXIS_HEAD Y_AXIS
|
||||
@ -1111,7 +1111,7 @@ void Endstops::update() {
|
||||
bool hit = false;
|
||||
#if X_SPI_SENSORLESS
|
||||
if (tmc_spi_homing.x && (stepperX.test_stall_status()
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SPI_SENSORLESS
|
||||
|| stepperY.test_stall_status()
|
||||
#elif CORE_IS_XZ && Z_SPI_SENSORLESS
|
||||
|| stepperZ.test_stall_status()
|
||||
@ -1123,7 +1123,7 @@ void Endstops::update() {
|
||||
#endif
|
||||
#if Y_SPI_SENSORLESS
|
||||
if (tmc_spi_homing.y && (stepperY.test_stall_status()
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SPI_SENSORLESS
|
||||
|| stepperX.test_stall_status()
|
||||
#elif CORE_IS_YZ && Z_SPI_SENSORLESS
|
||||
|| stepperZ.test_stall_status()
|
||||
|
@ -1367,7 +1367,7 @@ void prepare_line_to_destination() {
|
||||
#if AXIS_HAS_STALLGUARD(X2)
|
||||
stealth_states.x2 = tmc_enable_stallguard(stepperX2);
|
||||
#endif
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SENSORLESS
|
||||
stealth_states.y = tmc_enable_stallguard(stepperY);
|
||||
#elif CORE_IS_XZ && Z_SENSORLESS
|
||||
stealth_states.z = tmc_enable_stallguard(stepperZ);
|
||||
@ -1380,7 +1380,7 @@ void prepare_line_to_destination() {
|
||||
#if AXIS_HAS_STALLGUARD(Y2)
|
||||
stealth_states.y2 = tmc_enable_stallguard(stepperY2);
|
||||
#endif
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS
|
||||
stealth_states.x = tmc_enable_stallguard(stepperX);
|
||||
#elif CORE_IS_YZ && Z_SENSORLESS
|
||||
stealth_states.z = tmc_enable_stallguard(stepperZ);
|
||||
@ -1444,7 +1444,7 @@ void prepare_line_to_destination() {
|
||||
#if AXIS_HAS_STALLGUARD(X2)
|
||||
tmc_disable_stallguard(stepperX2, enable_stealth.x2);
|
||||
#endif
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SENSORLESS
|
||||
tmc_disable_stallguard(stepperY, enable_stealth.y);
|
||||
#elif CORE_IS_XZ && Z_SENSORLESS
|
||||
tmc_disable_stallguard(stepperZ, enable_stealth.z);
|
||||
@ -1457,7 +1457,7 @@ void prepare_line_to_destination() {
|
||||
#if AXIS_HAS_STALLGUARD(Y2)
|
||||
tmc_disable_stallguard(stepperY2, enable_stealth.y2);
|
||||
#endif
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS
|
||||
tmc_disable_stallguard(stepperX, enable_stealth.x);
|
||||
#elif CORE_IS_YZ && Z_SENSORLESS
|
||||
tmc_disable_stallguard(stepperZ, enable_stealth.z);
|
||||
@ -2011,7 +2011,7 @@ void prepare_line_to_destination() {
|
||||
do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis));
|
||||
}
|
||||
|
||||
#else // CARTESIAN / CORE / MARKFORGED_XY
|
||||
#else // CARTESIAN / CORE / MARKFORGED_XY / MARKFORGED_YX
|
||||
|
||||
set_axis_is_at_home(axis);
|
||||
sync_plan_position();
|
||||
@ -2041,7 +2041,7 @@ void prepare_line_to_destination() {
|
||||
#if ENABLED(SENSORLESS_HOMING)
|
||||
planner.synchronize();
|
||||
if (false
|
||||
#if EITHER(IS_CORE, MARKFORGED_XY)
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
|| axis != NORMAL_AXIS
|
||||
#endif
|
||||
) safe_delay(200); // Short delay to allow belts to spring back
|
||||
|
@ -1743,7 +1743,7 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
|
||||
else
|
||||
axis_steps = stepper.position(axis);
|
||||
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
#elif EITHER(MARKFORGED_XY, MARKFORGED_YX)
|
||||
|
||||
// Requesting one of the joined axes?
|
||||
if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) {
|
||||
@ -1917,30 +1917,43 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
// Compute direction bit-mask for this block
|
||||
axis_bits_t dm = 0;
|
||||
#if CORE_IS_XY
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_HEAD); // ...and Y
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
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 (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#elif CORE_IS_XZ
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_AXIS);
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (da + dc < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (CORESIGN(da - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#elif CORE_IS_YZ
|
||||
if (da < 0) SBI(dm, X_AXIS);
|
||||
if (db < 0) SBI(dm, Y_HEAD); // Save the toolhead's true direction in Y
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#endif
|
||||
#if IS_CORE
|
||||
#if CORE_IS_XY
|
||||
if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#elif CORE_IS_XZ
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_AXIS);
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (da + dc < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (CORESIGN(da - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#elif CORE_IS_YZ
|
||||
if (da < 0) SBI(dm, X_AXIS);
|
||||
if (db < 0) SBI(dm, Y_HEAD); // Save the toolhead's true direction in Y
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#endif
|
||||
#if LINEAR_AXES >= 4
|
||||
if (di < 0) SBI(dm, I_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
if (dj < 0) SBI(dm, J_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
if (dk < 0) SBI(dm, K_AXIS);
|
||||
#endif
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
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
|
||||
if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (db < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
if (da < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (db + da < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
if (da < 0) SBI(dm, X_AXIS),
|
||||
@ -1952,21 +1965,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
);
|
||||
#endif
|
||||
|
||||
#if IS_CORE
|
||||
#if LINEAR_AXES >= 4
|
||||
if (di < 0) SBI(dm, I_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
if (dj < 0) SBI(dm, J_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
if (dk < 0) SBI(dm, K_AXIS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TERN_(HAS_EXTRUDERS, if (de < 0) SBI(dm, E_AXIS));
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
if (de < 0) SBI(dm, E_AXIS);
|
||||
const float esteps_float = de * e_factor[extruder];
|
||||
const uint32_t esteps = ABS(esteps_float) + 0.5f;
|
||||
#else
|
||||
@ -1996,6 +1996,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + dc), ABS(db - dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da + db), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + da), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif IS_SCARA
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#else
|
||||
@ -2012,15 +2014,18 @@ 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.
|
||||
*/
|
||||
struct DistanceMM : abce_float_t {
|
||||
#if EITHER(IS_CORE, MARKFORGED_XY)
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
struct { float x, y, z; } head;
|
||||
#endif
|
||||
} steps_dist_mm;
|
||||
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
steps_dist_mm.head.x = da * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.head.y = db * mm_per_step[B_AXIS];
|
||||
steps_dist_mm.z = dc * mm_per_step[Z_AXIS];
|
||||
#endif
|
||||
#if IS_CORE
|
||||
#if CORE_IS_XY
|
||||
steps_dist_mm.head.x = da * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.head.y = db * mm_per_step[B_AXIS];
|
||||
steps_dist_mm.z = dc * mm_per_step[Z_AXIS];
|
||||
steps_dist_mm.a = (da + db) * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.b = CORESIGN(da - db) * mm_per_step[B_AXIS];
|
||||
#elif CORE_IS_XZ
|
||||
@ -2046,11 +2051,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
steps_dist_mm.k = dk * mm_per_step[K_AXIS];
|
||||
#endif
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
steps_dist_mm.head.x = da * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.head.y = db * mm_per_step[B_AXIS];
|
||||
steps_dist_mm.z = dc * mm_per_step[Z_AXIS];
|
||||
steps_dist_mm.a = (da - db) * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.b = db * mm_per_step[B_AXIS];
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
steps_dist_mm.a = da * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.b = (db - da) * mm_per_step[B_AXIS];
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
steps_dist_mm.a = da * mm_per_step[A_AXIS],
|
||||
@ -2082,7 +2087,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
block->millimeters = millimeters;
|
||||
else {
|
||||
block->millimeters = SQRT(
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY)
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z),
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k)
|
||||
@ -2161,7 +2166,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#endif
|
||||
|
||||
// Enable active axes
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY)
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
if (block->steps.a || block->steps.b) {
|
||||
stepper.enable_axis(X_AXIS);
|
||||
stepper.enable_axis(Y_AXIS);
|
||||
@ -2191,7 +2196,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS)
|
||||
);
|
||||
#endif
|
||||
#if EITHER(IS_CORE, MARKFORGED_XY)
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
#if LINEAR_AXES >= 4
|
||||
if (block->steps.i) stepper.enable_axis(I_AXIS);
|
||||
#endif
|
||||
@ -2549,7 +2554,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
* => normalize the complete junction vector.
|
||||
* Elsewise, when needed JD will factor-in the E component
|
||||
*/
|
||||
if (EITHER(IS_CORE, MARKFORGED_XY) || esteps > 0)
|
||||
if (ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) || esteps > 0)
|
||||
normalize_junction_vector(unit_vec); // Normalize with XYZE components
|
||||
else
|
||||
unit_vec *= inverse_millimeters; // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2))
|
||||
|
@ -2212,6 +2212,8 @@ uint32_t Stepper::block_phase_isr() {
|
||||
#define Y_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
#define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define Y_MOVE_TEST !!current_block->steps.b
|
||||
#endif
|
||||
@ -2800,7 +2802,7 @@ void Stepper::init() {
|
||||
* derive the current XYZE position later on.
|
||||
*/
|
||||
void Stepper::_set_position(const abce_long_t &spos) {
|
||||
#if EITHER(IS_CORE, MARKFORGED_XY)
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
#if CORE_IS_XY
|
||||
// corexy positioning
|
||||
// these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html
|
||||
@ -2813,6 +2815,8 @@ void Stepper::_set_position(const abce_long_t &spos) {
|
||||
count_position.set(spos.a, spos.b + spos.c, CORESIGN(spos.b - spos.c));
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
count_position.set(spos.a - spos.b, spos.b, spos.c);
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
count_position.set(spos.a, spos.b - spos.a, spos.c);
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, count_position.e = spos.e);
|
||||
#else
|
||||
@ -2884,6 +2888,10 @@ void Stepper::endstop_triggered(const AxisEnum axis) {
|
||||
axis == CORE_AXIS_1
|
||||
? count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2]
|
||||
: count_position[CORE_AXIS_2]
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
axis == CORE_AXIS_1
|
||||
? count_position[CORE_AXIS_1]
|
||||
: count_position[CORE_AXIS_2] - count_position[CORE_AXIS_1]
|
||||
#else // !IS_CORE
|
||||
count_position[axis]
|
||||
#endif
|
||||
@ -2912,10 +2920,10 @@ int32_t Stepper::triggered_position(const AxisEnum axis) {
|
||||
return v;
|
||||
}
|
||||
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, IS_SCARA, DELTA)
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX, IS_SCARA, DELTA)
|
||||
#define SAYS_A 1
|
||||
#endif
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, IS_SCARA, DELTA)
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX, IS_SCARA, DELTA)
|
||||
#define SAYS_B 1
|
||||
#endif
|
||||
#if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA)
|
||||
|
Reference in New Issue
Block a user