mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-12-28 02:10:32 -07:00
🧑💻 Shaped axis macros, etc. (#28084)
This commit is contained in:
parent
d08a7d4fd2
commit
c6cd10a92d
24 changed files with 208 additions and 263 deletions
|
|
@ -58,6 +58,7 @@
|
|||
// Macros to make a string from a macro
|
||||
#define STRINGIFY_(M) #M
|
||||
#define STRINGIFY(M) STRINGIFY_(M)
|
||||
#define CHARIFY(M) STRINGIFY(M)[0]
|
||||
|
||||
#define A(CODE) " " CODE "\n\t"
|
||||
#define L(CODE) CODE ":\n\t"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,21 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
|||
#define GANG_ITEM_E(N)
|
||||
#endif
|
||||
|
||||
// Emitters for code that only cares about XYZE and not IJKUVW
|
||||
#define CARTES_COUNT TERN(HAS_EXTRUDERS, INCREMENT(XYZ_COUNT), XYZ_COUNT)
|
||||
#define CARTES_LIST(x,y,z,e) XYZ_LIST(x,y,z) LIST_ITEM_E(e)
|
||||
#define CARTES_PAIRED_LIST(V...) LIST_N(DOUBLE(CARTES_COUNT), V)
|
||||
#define CARTES_ARRAY(x,y,z,e) { CARTES_LIST(x,y,z,e) }
|
||||
#define CARTES_CODE(x,y,z,e) XYZ_CODE(x,y,z) CODE_ITEM_E(e)
|
||||
#define CARTES_GANG(x,y,z,e) XYZ_GANG(x,y,z) GANG_ITEM_E(e)
|
||||
#define CARTES_AXIS_NAMES CARTES_LIST(X,Y,Z,E)
|
||||
#define CARTES_MAP(F) MAP(F, CARTES_AXIS_NAMES)
|
||||
#if CARTES_COUNT
|
||||
#define CARTES_COMMA ,
|
||||
#else
|
||||
#define CARTES_COMMA
|
||||
#endif
|
||||
|
||||
#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L || AXIS7_NAME == L || AXIS8_NAME == L || AXIS9_NAME == L)
|
||||
|
||||
// Helpers
|
||||
|
|
@ -371,7 +386,7 @@ typedef IF<TERN0(ABL_USES_GRID, (GRID_MAX_POINTS > 255)), uint16_t, uint8_t>::ty
|
|||
#define MMS_TO_MMM(MM_S) (static_cast<float>(MM_S) * 60.0f)
|
||||
|
||||
// Packaged character for C macro and other usage
|
||||
typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t;
|
||||
typedef struct SerialChar { char c; SerialChar(const char n) : c(n) { } } serial_char_t;
|
||||
#define C(c) serial_char_t(c)
|
||||
|
||||
// Packaged types: float with precision and/or width; a repeated space/character
|
||||
|
|
|
|||
|
|
@ -48,31 +48,31 @@ void GcodeSuite::M210() {
|
|||
return M210_report();
|
||||
|
||||
#if HAS_X_AXIS
|
||||
if (parser.floatval('X') > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS);
|
||||
if (parser.floatval(AXIS1_PARAM) > 0) homing_feedrate_mm_m.x = parser.value_axis_units(X_AXIS);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.floatval('Y') > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS);
|
||||
if (parser.floatval(AXIS2_PARAM) > 0) homing_feedrate_mm_m.y = parser.value_axis_units(Y_AXIS);
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
if (parser.floatval('Z') > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS);
|
||||
if (parser.floatval(AXIS3_PARAM) > 0) homing_feedrate_mm_m.z = parser.value_axis_units(Z_AXIS);
|
||||
#endif
|
||||
#if HAS_I_AXIS
|
||||
if (parser.floatval(AXIS4_NAME) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS);
|
||||
if (parser.floatval(AXIS4_PARAM) > 0) homing_feedrate_mm_m.i = parser.value_axis_units(I_AXIS);
|
||||
#endif
|
||||
#if HAS_J_AXIS
|
||||
if (parser.floatval(AXIS5_NAME) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS);
|
||||
if (parser.floatval(AXIS5_PARAM) > 0) homing_feedrate_mm_m.j = parser.value_axis_units(J_AXIS);
|
||||
#endif
|
||||
#if HAS_K_AXIS
|
||||
if (parser.floatval(AXIS6_NAME) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS);
|
||||
if (parser.floatval(AXIS6_PARAM) > 0) homing_feedrate_mm_m.k = parser.value_axis_units(K_AXIS);
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
if (parser.floatval(AXIS7_NAME) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS);
|
||||
if (parser.floatval(AXIS7_PARAM) > 0) homing_feedrate_mm_m.u = parser.value_axis_units(U_AXIS);
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
if (parser.floatval(AXIS8_NAME) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS);
|
||||
if (parser.floatval(AXIS8_PARAM) > 0) homing_feedrate_mm_m.v = parser.value_axis_units(V_AXIS);
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
if (parser.floatval(AXIS9_NAME) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS);
|
||||
if (parser.floatval(AXIS9_PARAM) > 0) homing_feedrate_mm_m.w = parser.value_axis_units(W_AXIS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,19 +53,10 @@ void say_shaping() {
|
|||
const bool is_shaping = AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E);
|
||||
bool sep = false;
|
||||
if (is_shaping) {
|
||||
#define STEPPER_E_NAME 'E'
|
||||
#define _SAY_SHAPER(A) if (AXIS_IS_SHAPING(A)) say_shaper_type(_AXIS(A), sep, STEPPER_##A##_NAME);
|
||||
SERIAL_ECHOPGM(" (");
|
||||
#if HAS_X_AXIS
|
||||
if (AXIS_IS_SHAPING(X)) say_shaper_type(X_AXIS, sep, STEPPER_A_NAME);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (AXIS_IS_SHAPING(Y)) say_shaper_type(Y_AXIS, sep, STEPPER_B_NAME);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
if (AXIS_IS_SHAPING(Z)) say_shaper_type(Z_AXIS, sep, STEPPER_C_NAME);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
if (AXIS_IS_SHAPING(E)) say_shaper_type(E_AXIS, sep, 'E');
|
||||
#endif
|
||||
SHAPED_CODE(_SAY_SHAPER(A), _SAY_SHAPER(B), _SAY_SHAPER(C), _SAY_SHAPER(E));
|
||||
SERIAL_CHAR(')');
|
||||
}
|
||||
SERIAL_EOL();
|
||||
|
|
@ -244,7 +235,7 @@ void GcodeSuite::M493() {
|
|||
}
|
||||
}
|
||||
|
||||
#if ANY(HAS_X_AXIS, HAS_Y_AXIS, FTM_SHAPER_Z, FTM_SHAPER_E)
|
||||
#if NUM_AXES_SHAPED > 0
|
||||
|
||||
auto set_shaper = [&](const AxisEnum axis, const char c) {
|
||||
const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte();
|
||||
|
|
@ -268,20 +259,10 @@ void GcodeSuite::M493() {
|
|||
return false;
|
||||
};
|
||||
|
||||
#if HAS_X_AXIS
|
||||
if (parser.seenval('X') && set_shaper(X_AXIS, 'X')) return; // Parse 'X' mode parameter
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.seenval('Y') && set_shaper(Y_AXIS, 'Y')) return; // Parse 'Y' mode parameter
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
if (parser.seenval('Z') && set_shaper(Z_AXIS, 'Z')) return; // Parse 'Z' mode parameter
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
if (parser.seenval('E') && set_shaper(E_AXIS, 'E')) return; // Parse 'E' mode parameter
|
||||
#endif
|
||||
#define _SET_SHAPER(A) if (parser.seenval(CHARIFY(A)) && set_shaper(_AXIS(A), CHARIFY(A))) return;
|
||||
SHAPED_MAP(_SET_SHAPER);
|
||||
|
||||
#endif // HAS_X_AXIS || HAS_Y_AXIS || FTM_SHAPER_Z || FTM_SHAPER_E
|
||||
#endif // NUM_AXES_SHAPED > 0
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,16 @@
|
|||
|
||||
void say_smoothing() {
|
||||
#if HAS_X_AXIS
|
||||
SERIAL_ECHOLN(F(" "), C('X'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.x, 3), C('s'));
|
||||
SERIAL_ECHOLN(F(" "), C('X'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.X, 3), C('s'));
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
SERIAL_ECHOLN(F(" "), C('Y'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.y, 3), C('s'));
|
||||
SERIAL_ECHOLN(F(" "), C('Y'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.Y, 3), C('s'));
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
SERIAL_ECHOLN(F(" "), C('Z'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.z, 3), C('s'));
|
||||
SERIAL_ECHOLN(F(" "), C('Z'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.Z, 3), C('s'));
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHOLN(F(" "), C('E'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.e, 3), C('s'));
|
||||
SERIAL_ECHOLN(F(" "), C('E'), F(" smoothing time: "), p_float_t(ftMotion.cfg.smoothingTime.E, 3), C('s'));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -48,18 +48,10 @@ void GcodeSuite::M494_report(const bool forReplay/*=true*/) {
|
|||
report_heading_etc(forReplay, F("FTM Smoothing"));
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
SERIAL_ECHOLN(F(" M494")
|
||||
#if HAS_X_AXIS
|
||||
, F(" X"), c.smoothingTime.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, F(" Y"), c.smoothingTime.y
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
, F(" Z"), c.smoothingTime.z
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
, F(" E"), c.smoothingTime.e
|
||||
#endif
|
||||
CARTES_COMMA CARTES_PAIRED_LIST(
|
||||
F(" X"), c.smoothingTime.X, F(" Y"), c.smoothingTime.Y,
|
||||
F(" Z"), c.smoothingTime.Z, F(" E"), c.smoothingTime.E
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,8 +139,7 @@ void GcodeSuite::M360() {
|
|||
if (TERN0(HAS_Y_AXIS, planner.max_jerk.x == planner.max_jerk.y))
|
||||
config_line(F("XY"), planner.max_jerk.x, JERK_STR);
|
||||
else {
|
||||
TERN_(HAS_X_AXIS, _REPORT_JERK(X));
|
||||
TERN_(HAS_Y_AXIS, _REPORT_JERK(Y));
|
||||
XY_MAP(_REPORT_JERK);
|
||||
}
|
||||
TERN_(HAS_Z_AXIS, config_line(Z_STR, planner.max_jerk.z, JERK_STR));
|
||||
SECONDARY_AXIS_MAP(_REPORT_JERK);
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@
|
|||
#undef LIN_ADVANCE
|
||||
#undef SMOOTH_LIN_ADVANCE
|
||||
#undef MANUAL_E_MOVES_RELATIVE
|
||||
#undef MPCTEMP
|
||||
#undef MPC_AUTOTUNE
|
||||
#undef PID_EXTRUSION_SCALING
|
||||
#undef SHOW_TEMP_ADC_VALUES
|
||||
#undef STEALTHCHOP_E
|
||||
|
|
|
|||
|
|
@ -102,6 +102,35 @@
|
|||
#define AXIS9_NAME 'W'
|
||||
#endif
|
||||
|
||||
// G-code parameters where XYZ are invariant but IJKUVW can be renamed
|
||||
#ifndef AXIS1_PARAM
|
||||
#define AXIS1_PARAM 'X'
|
||||
#endif
|
||||
#ifndef AXIS2_PARAM
|
||||
#define AXIS2_PARAM 'Y'
|
||||
#endif
|
||||
#ifndef AXIS3_PARAM
|
||||
#define AXIS3_PARAM 'Z'
|
||||
#endif
|
||||
#ifndef AXIS4_PARAM
|
||||
#define AXIS4_PARAM AXIS4_NAME
|
||||
#endif
|
||||
#ifndef AXIS5_PARAM
|
||||
#define AXIS5_PARAM AXIS5_NAME
|
||||
#endif
|
||||
#ifndef AXIS6_PARAM
|
||||
#define AXIS6_PARAM AXIS6_NAME
|
||||
#endif
|
||||
#ifndef AXIS7_PARAM
|
||||
#define AXIS7_PARAM AXIS7_NAME
|
||||
#endif
|
||||
#ifndef AXIS8_PARAM
|
||||
#define AXIS8_PARAM AXIS8_NAME
|
||||
#endif
|
||||
#ifndef AXIS9_PARAM
|
||||
#define AXIS9_PARAM AXIS9_NAME
|
||||
#endif
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3754,33 +3754,11 @@ static_assert(COUNT(sanity_arr_3) <= DISTINCT_AXES, "DEFAULT_MAX_ACCELERATION ha
|
|||
static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive.");
|
||||
|
||||
#if MAXIMUM_STEPPER_RATE
|
||||
static_assert(TERN1(HAS_X_AXIS, sanity_arr_1[X_AXIS] * sanity_arr_2[X_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[X] * DEFAULT_AXIS_STEPS_PER_UNIT[X] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_Y_AXIS, sanity_arr_1[Y_AXIS] * sanity_arr_2[Y_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[Y] * DEFAULT_AXIS_STEPS_PER_UNIT[Y] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_Z_AXIS, sanity_arr_1[Z_AXIS] * sanity_arr_2[Z_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[Z] * DEFAULT_AXIS_STEPS_PER_UNIT[Z] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_I_AXIS, sanity_arr_1[I_AXIS] * sanity_arr_2[I_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[I] * DEFAULT_AXIS_STEPS_PER_UNIT[I] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_J_AXIS, sanity_arr_1[J_AXIS] * sanity_arr_2[J_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[J] * DEFAULT_AXIS_STEPS_PER_UNIT[J] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_K_AXIS, sanity_arr_1[K_AXIS] * sanity_arr_2[K_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[K] * DEFAULT_AXIS_STEPS_PER_UNIT[K] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_U_AXIS, sanity_arr_1[U_AXIS] * sanity_arr_2[U_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[U] * DEFAULT_AXIS_STEPS_PER_UNIT[U] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_V_AXIS, sanity_arr_1[V_AXIS] * sanity_arr_2[V_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[V] * DEFAULT_AXIS_STEPS_PER_UNIT[V] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
);
|
||||
static_assert(TERN1(HAS_W_AXIS, sanity_arr_1[W_AXIS] * sanity_arr_2[W_AXIS] <= MAXIMUM_STEPPER_RATE),
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[W] * DEFAULT_AXIS_STEPS_PER_UNIT[W] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")."
|
||||
#define _RATE_ASSERT(A) static_assert(sanity_arr_1[_AXIS(A)] * sanity_arr_2[_AXIS(A)] <= MAXIMUM_STEPPER_RATE, \
|
||||
"Slow down! DEFAULT_MAX_FEEDRATE[" STRINGIFY(A) "] * DEFAULT_AXIS_STEPS_PER_UNIT[" STRINGIFY(A) "] > MAXIMUM_STEPPER_RATE (" STRINGIFY(MAXIMUM_STEPPER_RATE) ")." \
|
||||
);
|
||||
LOGICAL_AXIS_MAP(_RATE_ASSERT)
|
||||
#undef _RATE_ASSERT
|
||||
#if ALL(HAS_EXTRUDERS, SANITY_CHECK_E_STEPPER_RATES)
|
||||
#if DISABLED(DISTINCT_E_FACTORS)
|
||||
static_assert(sanity_arr_1[E_AXIS] * sanity_arr_2[E_AXIS] <= MAXIMUM_STEPPER_RATE,
|
||||
|
|
|
|||
|
|
@ -584,8 +584,10 @@ void MarlinUI::draw_status_screen() {
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
TERN_(HAS_X_AXIS, strcpy(xstring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.x)) : ftostr4sign(lpos.x)));
|
||||
TERN_(HAS_Y_AXIS, strcpy(ystring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.y)) : ftostr4sign(lpos.y)));
|
||||
XY_CODE(
|
||||
strcpy(xstring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.x)) : ftostr4sign(lpos.x)),
|
||||
strcpy(ystring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.y)) : ftostr4sign(lpos.y))
|
||||
);
|
||||
}
|
||||
|
||||
TERN_(HAS_Z_AXIS, strcpy(zstring, is_inch ? ftostr42_52(LINEAR_UNIT(lpos.z)) : ftostr52sp(lpos.z)));
|
||||
|
|
@ -868,8 +870,10 @@ void MarlinUI::draw_status_screen() {
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
TERN_(HAS_X_AXIS, _draw_axis_value(X_AXIS, xstring, blink));
|
||||
TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ystring, blink));
|
||||
XY_CODE(
|
||||
_draw_axis_value(X_AXIS, xstring, blink),
|
||||
_draw_axis_value(Y_AXIS, ystring, blink)
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2992,9 +2992,11 @@ void hmiAxisMove() {
|
|||
hmiFlag.cold_flag = false;
|
||||
hmiValues.moveScaled.e = current_position.e * MINUNITMULT;
|
||||
drawMoveMenu();
|
||||
TERN_(HAS_X_AXIS, drawEditFloat3(1, hmiValues.moveScaled.x));
|
||||
TERN_(HAS_Y_AXIS, drawEditFloat3(2, hmiValues.moveScaled.y));
|
||||
TERN_(HAS_Z_AXIS, drawEditFloat3(3, hmiValues.moveScaled.z));
|
||||
XYZ_CODE(
|
||||
drawEditFloat3(1, hmiValues.moveScaled.x),
|
||||
drawEditFloat3(2, hmiValues.moveScaled.y),
|
||||
drawEditFloat3(3, hmiValues.moveScaled.z)
|
||||
);
|
||||
drawEditSignedFloat3(4, 0);
|
||||
dwinUpdateLCD();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,8 +315,10 @@ void MarlinUI::draw_status_screen() {
|
|||
TERN_(LCD_SHOW_E_TOTAL, _draw_e_value(e_move_accumulator, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy));
|
||||
}
|
||||
else {
|
||||
TERN_(HAS_X_AXIS, _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy));
|
||||
TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink, TERN(DWIN_MARLINUI_PORTRAIT, 95, 184), cpy));
|
||||
XY_CODE(
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy),
|
||||
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink, TERN(DWIN_MARLINUI_PORTRAIT, 95, 184), cpy)
|
||||
);
|
||||
}
|
||||
TERN_(HAS_Z_AXIS, _draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink, TERN(DWIN_MARLINUI_PORTRAIT, 165, 300), cpy));
|
||||
|
||||
|
|
|
|||
|
|
@ -534,9 +534,7 @@ void MarlinUI::init() {
|
|||
ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP;
|
||||
ui.encoderPosition = dir;
|
||||
switch (axis) {
|
||||
TERN_(HAS_X_AXIS, case X_AXIS:)
|
||||
TERN_(HAS_Y_AXIS, case Y_AXIS:)
|
||||
TERN_(HAS_Z_AXIS, case Z_AXIS:)
|
||||
XYZ_GANG(case X_AXIS:, case Y_AXIS:, case Z_AXIS:)
|
||||
lcd_move_axis(axis);
|
||||
default: break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,10 +361,7 @@ void menu_move() {
|
|||
END_MENU(); \
|
||||
}
|
||||
|
||||
MENU_FTM_SHAPER(X);
|
||||
MENU_FTM_SHAPER(Y);
|
||||
TERN_(FTM_SHAPER_Z, MENU_FTM_SHAPER(Z));
|
||||
TERN_(FTM_SHAPER_E, MENU_FTM_SHAPER(E));
|
||||
SHAPED_MAP(MENU_FTM_SHAPER);
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
|
||||
|
|
@ -448,27 +445,13 @@ void menu_move() {
|
|||
if (AXIS_IS_EISHAPING(A)) \
|
||||
EDIT_ITEM_FAST_N(float42_52, _AXIS(A), MSG_FTM_VTOL_N, &c.vtol.A, 0.0f, 1.0f, ftMotion.update_shaping_params); \
|
||||
}
|
||||
|
||||
TERN_(HAS_X_AXIS, SHAPER_MENU_ITEM(X));
|
||||
TERN_(HAS_Y_AXIS, SHAPER_MENU_ITEM(Y));
|
||||
TERN_(FTM_SHAPER_Z, SHAPER_MENU_ITEM(Z));
|
||||
TERN_(FTM_SHAPER_E, SHAPER_MENU_ITEM(E));
|
||||
SHAPED_MAP(SHAPER_MENU_ITEM);
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SUBMENU_S(_dmode(), MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
|
||||
if (c.dynFreqMode != dynFreqMode_DISABLED) {
|
||||
#if HAS_X_AXIS
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_DFREQ_K_N, &c.dynFreqK.x, 0.0f, 20.0f);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_DFREQ_K_N, &c.dynFreqK.y, 0.0f, 20.0f);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
EDIT_ITEM_FAST_N(float42_52, Z_AXIS, MSG_FTM_DFREQ_K_N, &c.dynFreqK.z, 0.0f, 20.0f);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
EDIT_ITEM_FAST_N(float42_52, E_AXIS, MSG_FTM_DFREQ_K_N, &c.dynFreqK.e, 0.0f, 20.0f);
|
||||
#endif
|
||||
#define _DYN_MENU_ITEM(A) EDIT_ITEM_FAST_N(float42_52, _AXIS(A), MSG_FTM_DFREQ_K_N, &c.dynFreqK.A, 0.0f, 20.0f);
|
||||
SHAPED_MAP(_DYN_MENU_ITEM);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -479,22 +462,21 @@ void menu_move() {
|
|||
#endif
|
||||
|
||||
EDIT_ITEM(bool, MSG_FTM_AXIS_SYNC, &c.axis_sync_enabled);
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
#if HAS_X_AXIS
|
||||
editable.decimal = c.smoothingTime.x;
|
||||
editable.decimal = c.smoothingTime.X;
|
||||
EDIT_ITEM_FAST_N(float43, X_AXIS, MSG_FTM_SMOOTH_TIME_N, &editable.decimal, 0.0f, FTM_MAX_SMOOTHING_TIME, []{ ftMotion.set_smoothing_time(X_AXIS, editable.decimal); });
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
editable.decimal = c.smoothingTime.y;
|
||||
editable.decimal = c.smoothingTime.Y;
|
||||
EDIT_ITEM_FAST_N(float43, Y_AXIS, MSG_FTM_SMOOTH_TIME_N, &editable.decimal, 0.0f, FTM_MAX_SMOOTHING_TIME, []{ ftMotion.set_smoothing_time(Y_AXIS, editable.decimal); });
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
editable.decimal = c.smoothingTime.z;
|
||||
editable.decimal = c.smoothingTime.Z;
|
||||
EDIT_ITEM_FAST_N(float43, Z_AXIS, MSG_FTM_SMOOTH_TIME_N, &editable.decimal, 0.0f, FTM_MAX_SMOOTHING_TIME, []{ ftMotion.set_smoothing_time(Z_AXIS, editable.decimal); });
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
editable.decimal = c.smoothingTime.e;
|
||||
editable.decimal = c.smoothingTime.E;
|
||||
EDIT_ITEM_FAST_N(float43, E_AXIS, MSG_FTM_SMOOTH_TIME_N, &editable.decimal, 0.0f, FTM_MAX_SMOOTHING_TIME, []{ ftMotion.set_smoothing_time(E_AXIS, editable.decimal); });
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -541,18 +523,8 @@ void menu_move() {
|
|||
START_MENU();
|
||||
BACK_ITEM(MSG_TUNE);
|
||||
|
||||
#if HAS_X_AXIS
|
||||
SUBMENU_N_S(X_AXIS, _shaper_name(X_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_X);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
SUBMENU_N_S(Y_AXIS, _shaper_name(Y_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_Y);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
SUBMENU_N_S(Z_AXIS, _shaper_name(Z_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_Z);
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
SUBMENU_N_S(E_AXIS, _shaper_name(E_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_E);
|
||||
#endif
|
||||
#define _CMPM_MENU_ITEM(A) SUBMENU_N_S(_AXIS(A), _shaper_name(_AXIS(A)), MSG_FTM_CMPN_MODE, menu_ftm_shaper_##A);
|
||||
SHAPED_MAP(_CMPM_MENU_ITEM);
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SUBMENU_S(_dmode(), MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ struct vector_3 {
|
|||
vector_3 operator-(const vector_3 &v) { return vector_3(x - v.x, y - v.y, z - v.z); }
|
||||
vector_3 operator*(const float &v) { return vector_3(x * v, y * v, z * v); }
|
||||
|
||||
operator xy_float_t() { return xy_float_t({ TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y) }); }
|
||||
operator xyz_float_t() { return xyz_float_t({ TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y) OPTARG(HAS_Z_AXIS, z) }); }
|
||||
operator xy_float_t() { return xy_float_t(XY_ARRAY(x, y)); }
|
||||
operator xyz_float_t() { return xyz_float_t(XYZ_ARRAY(x, y, z)); }
|
||||
|
||||
void debug(FSTR_P const title);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -101,16 +101,16 @@ uint32_t FTMotion::interpIdx = 0; // Index of current data point b
|
|||
FTMotion::shaping_t FTMotion::shaping = {
|
||||
zi_idx: 0
|
||||
#if HAS_X_AXIS
|
||||
, x:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
, X:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, y:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
, Y:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, z:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
, Z:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, e:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
, E:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
|
@ -118,16 +118,16 @@ uint32_t FTMotion::interpIdx = 0; // Index of current data point b
|
|||
#if ENABLED(FTM_SMOOTHING)
|
||||
FTMotion::smoothing_t FTMotion::smoothing = {
|
||||
#if HAS_X_AXIS
|
||||
x:{ { 0.0f }, 0.0f, 0 }, // smoothing_pass[], alpha, delay_samples
|
||||
X:{ { 0.0f }, 0.0f, 0 }, // smoothing_pass[], alpha, delay_samples
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
y:{ { 0.0f }, 0.0f, 0 },
|
||||
Y:{ { 0.0f }, 0.0f, 0 },
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
z:{ { 0.0f }, 0.0f, 0 },
|
||||
Z:{ { 0.0f }, 0.0f, 0 },
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
e:{ { 0.0f }, 0.0f, 0 }
|
||||
E:{ { 0.0f }, 0.0f, 0 }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
|
@ -406,10 +406,7 @@ void FTMotion::loop() {
|
|||
shaping.A.set_axis_shaping_A(cfg.shaper.A, cfg.zeta.A, cfg.vtol.A); \
|
||||
shaping.A.set_axis_shaping_N(cfg.shaper.A, cfg.baseFreq.A, cfg.zeta.A);
|
||||
|
||||
TERN_(HAS_X_AXIS, UPDATE_SHAPER(x));
|
||||
TERN_(HAS_Y_AXIS, UPDATE_SHAPER(y));
|
||||
TERN_(FTM_SHAPER_Z, UPDATE_SHAPER(z));
|
||||
TERN_(FTM_SHAPER_E, UPDATE_SHAPER(e));
|
||||
SHAPED_MAP(UPDATE_SHAPER);
|
||||
}
|
||||
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
|
@ -417,18 +414,15 @@ void FTMotion::loop() {
|
|||
#if ENABLED(FTM_SMOOTHING)
|
||||
|
||||
void FTMotion::update_smoothing_params() {
|
||||
TERN_(HAS_X_AXIS, smoothing.x.set_smoothing_time(cfg.smoothingTime.x));
|
||||
TERN_(HAS_Y_AXIS, smoothing.y.set_smoothing_time(cfg.smoothingTime.y));
|
||||
TERN_(HAS_Z_AXIS, smoothing.z.set_smoothing_time(cfg.smoothingTime.z));
|
||||
TERN_(HAS_EXTRUDERS, smoothing.e.set_smoothing_time(cfg.smoothingTime.e));
|
||||
#define _SMOOTH_PARAM(A) smoothing.A.set_smoothing_time(cfg.smoothingTime.A);
|
||||
CARTES_MAP(_SMOOTH_PARAM);
|
||||
}
|
||||
|
||||
void FTMotion::set_smoothing_time(uint8_t axis, const float s_time) {
|
||||
#define _SMOOTH_CASE(A) case _AXIS(A): cfg.smoothingTime.A = s_time; break;
|
||||
switch (axis) {
|
||||
TERN_(HAS_X_AXIS, case X_AXIS: cfg.smoothingTime.x = s_time; break;)
|
||||
TERN_(HAS_Y_AXIS, case Y_AXIS: cfg.smoothingTime.y = s_time; break;)
|
||||
TERN_(HAS_Z_AXIS, case Z_AXIS: cfg.smoothingTime.z = s_time; break;)
|
||||
TERN_(HAS_EXTRUDERS, case E_AXIS: cfg.smoothingTime.e = s_time; break;)
|
||||
default:
|
||||
CARTES_MAP(_SMOOTH_CASE);
|
||||
}
|
||||
update_smoothing_params();
|
||||
}
|
||||
|
|
@ -454,10 +448,8 @@ void FTMotion::reset() {
|
|||
interpIdx = 0;
|
||||
|
||||
#if HAS_FTM_SHAPING
|
||||
TERN_(HAS_X_AXIS, ZERO(shaping.x.d_zi));
|
||||
TERN_(HAS_Y_AXIS, ZERO(shaping.y.d_zi));
|
||||
TERN_(FTM_SHAPER_Z, ZERO(shaping.z.d_zi));
|
||||
TERN_(FTM_SHAPER_E, ZERO(shaping.e.d_zi));
|
||||
#define _RESET_ZI(A) ZERO(shaping.A.d_zi);
|
||||
SHAPED_MAP(_RESET_ZI);
|
||||
shaping.zi_idx = 0;
|
||||
#endif
|
||||
|
||||
|
|
@ -532,11 +524,11 @@ void FTMotion::loadBlockData(block_t * const current_block) {
|
|||
const xyze_pos_t& moveDist = current_block->dist_mm;
|
||||
ratio = moveDist * oneOverLength;
|
||||
|
||||
const float spm = totalLength / current_block->step_event_count; // (steps/mm) Distance for each step
|
||||
const float mmps = totalLength / current_block->step_event_count; // (mm/step) Distance for each step
|
||||
|
||||
f_s = spm * current_block->initial_rate; // (steps/s) Start feedrate
|
||||
f_s = mmps * current_block->initial_rate; // (steps/s) Start feedrate
|
||||
|
||||
const float f_e = spm * current_block->final_rate; // (steps/s) End feedrate
|
||||
const float f_e = mmps * current_block->final_rate; // (steps/s) End feedrate
|
||||
|
||||
/* Keep for comprehension
|
||||
const float a = current_block->acceleration, // (mm/s^2) Same magnitude for acceleration or deceleration
|
||||
|
|
@ -676,11 +668,11 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
oldz = z;
|
||||
#if HAS_X_AXIS
|
||||
const float xf = cfg.baseFreq.x + cfg.dynFreqK.x * z;
|
||||
shaping.x.set_axis_shaping_N(cfg.shaper.x, _MAX(xf, FTM_MIN_SHAPE_FREQ), cfg.zeta.x);
|
||||
shaping.X.set_axis_shaping_N(cfg.shaper.x, _MAX(xf, FTM_MIN_SHAPE_FREQ), cfg.zeta.x);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
const float yf = cfg.baseFreq.y + cfg.dynFreqK.y * z;
|
||||
shaping.y.set_axis_shaping_N(cfg.shaper.y, _MAX(yf, FTM_MIN_SHAPE_FREQ), cfg.zeta.y);
|
||||
shaping.Y.set_axis_shaping_N(cfg.shaper.y, _MAX(yf, FTM_MIN_SHAPE_FREQ), cfg.zeta.y);
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
|
|
@ -691,10 +683,10 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
// Update constantly. The optimization done for Z value makes
|
||||
// less sense for E, as E is expected to constantly change.
|
||||
#if HAS_X_AXIS
|
||||
shaping.x.set_axis_shaping_N(cfg.shaper.x, cfg.baseFreq.x + cfg.dynFreqK.x * traj.e[traj_idx_set], cfg.zeta.x);
|
||||
shaping.X.set_axis_shaping_N(cfg.shaper.x, cfg.baseFreq.x + cfg.dynFreqK.x * traj.e[traj_idx_set], cfg.zeta.x);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
shaping.y.set_axis_shaping_N(cfg.shaper.y, cfg.baseFreq.y + cfg.dynFreqK.y * traj.e[traj_idx_set], cfg.zeta.y);
|
||||
shaping.Y.set_axis_shaping_N(cfg.shaper.y, cfg.baseFreq.y + cfg.dynFreqK.y * traj.e[traj_idx_set], cfg.zeta.y);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -704,7 +696,7 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
uint32_t max_total_delay = 0;
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
#define SMOOTHEN(A) /* Approximate gaussian smoothing via chained EMAs */ \
|
||||
#define _SMOOTHEN(A) /* Approximate gaussian smoothing via chained EMAs */ \
|
||||
if (smoothing.A.alpha > 0.0f) { \
|
||||
float smooth_val = traj.A[traj_idx_set]; \
|
||||
for (uint8_t _i = 0; _i < FTM_SMOOTHING_ORDER; ++_i) { \
|
||||
|
|
@ -714,33 +706,25 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
traj.A[traj_idx_set] = smooth_val; \
|
||||
}
|
||||
|
||||
TERN_(HAS_X_AXIS, SMOOTHEN(x));
|
||||
TERN_(HAS_Y_AXIS, SMOOTHEN(y));
|
||||
TERN_(HAS_Z_AXIS, SMOOTHEN(z));
|
||||
TERN_(HAS_EXTRUDERS, SMOOTHEN(e));
|
||||
|
||||
max_total_delay += _MAX(
|
||||
TERN0(HAS_X_AXIS, smoothing.x.delay_samples),
|
||||
TERN0(HAS_Y_AXIS, smoothing.y.delay_samples),
|
||||
TERN0(HAS_Z_AXIS, smoothing.z.delay_samples),
|
||||
TERN0(HAS_EXTRUDERS, smoothing.e.delay_samples)
|
||||
);
|
||||
CARTES_MAP(_SMOOTHEN);
|
||||
max_total_delay += _MAX(CARTES_LIST(
|
||||
smoothing.X.delay_samples, smoothing.Y.delay_samples,
|
||||
smoothing.Z.delay_samples, smoothing.E.delay_samples
|
||||
));
|
||||
|
||||
#endif // FTM_SMOOTHING
|
||||
|
||||
#if HAS_FTM_SHAPING
|
||||
|
||||
if (ftMotion.cfg.axis_sync_enabled) {
|
||||
max_total_delay -= _MIN(
|
||||
TERN0(HAS_X_AXIS, shaping.x.Ni[0]),
|
||||
TERN0(HAS_Y_AXIS, shaping.y.Ni[0]),
|
||||
TERN0(FTM_SHAPER_Z, shaping.z.Ni[0]),
|
||||
TERN0(FTM_SHAPER_E, shaping.e.Ni[0])
|
||||
);
|
||||
max_total_delay -= _MIN(SHAPED_LIST(
|
||||
shaping.X.Ni[0], shaping.Y.Ni[0],
|
||||
shaping.Z.Ni[0], shaping.E.Ni[0]
|
||||
));
|
||||
}
|
||||
|
||||
// Apply shaping if active on each axis
|
||||
#define SHAPE(A) \
|
||||
#define _SHAPE(A) \
|
||||
do { \
|
||||
const uint32_t group_delay = ftMotion.cfg.axis_sync_enabled \
|
||||
? max_total_delay - TERN0(FTM_SMOOTHING, smoothing.A.delay_samples) \
|
||||
|
|
@ -756,12 +740,9 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
if (udiff < 0) udiff += FTM_ZMAX; \
|
||||
traj.A[traj_idx_set] += shaping.A.Ai[i] * shaping.A.d_zi[udiff]; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0);
|
||||
|
||||
TERN_(HAS_X_AXIS, SHAPE(x));
|
||||
TERN_(HAS_Y_AXIS, SHAPE(y));
|
||||
TERN_(FTM_SHAPER_Z, SHAPE(z));
|
||||
TERN_(FTM_SHAPER_E, SHAPE(e));
|
||||
SHAPED_MAP(_SHAPE);
|
||||
|
||||
if (++shaping.zi_idx == (FTM_ZMAX)) shaping.zi_idx = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfigPre.h" // Access the top level configurations.
|
||||
#include "../module/planner.h" // Access block type from planner.
|
||||
#include "../module/stepper.h" // For stepper motion and direction
|
||||
#include "planner.h" // Access block type from planner.
|
||||
#include "stepper.h" // For stepper motion and direction
|
||||
|
||||
#include "ft_types.h"
|
||||
|
||||
|
|
@ -43,13 +43,13 @@ typedef struct FTConfig {
|
|||
|
||||
#if HAS_FTM_SHAPING
|
||||
ft_shaped_shaper_t shaper = // Shaper type
|
||||
{ SHAPED_ELEM(FTM_DEFAULT_SHAPER_X, FTM_DEFAULT_SHAPER_Y, FTM_DEFAULT_SHAPER_Z, FTM_DEFAULT_SHAPER_E) };
|
||||
SHAPED_ARRAY(FTM_DEFAULT_SHAPER_X, FTM_DEFAULT_SHAPER_Y, FTM_DEFAULT_SHAPER_Z, FTM_DEFAULT_SHAPER_E);
|
||||
ft_shaped_float_t baseFreq = // Base frequency. [Hz]
|
||||
{ SHAPED_ELEM(FTM_SHAPING_DEFAULT_FREQ_X, FTM_SHAPING_DEFAULT_FREQ_Y, FTM_SHAPING_DEFAULT_FREQ_Z, FTM_SHAPING_DEFAULT_FREQ_E) };
|
||||
SHAPED_ARRAY(FTM_SHAPING_DEFAULT_FREQ_X, FTM_SHAPING_DEFAULT_FREQ_Y, FTM_SHAPING_DEFAULT_FREQ_Z, FTM_SHAPING_DEFAULT_FREQ_E);
|
||||
ft_shaped_float_t zeta = // Damping factor
|
||||
{ SHAPED_ELEM(FTM_SHAPING_ZETA_X, FTM_SHAPING_ZETA_Y, FTM_SHAPING_ZETA_Z, FTM_SHAPING_ZETA_E) };
|
||||
SHAPED_ARRAY(FTM_SHAPING_ZETA_X, FTM_SHAPING_ZETA_Y, FTM_SHAPING_ZETA_Z, FTM_SHAPING_ZETA_E);
|
||||
ft_shaped_float_t vtol = // Vibration Level
|
||||
{ SHAPED_ELEM(FTM_SHAPING_V_TOL_X, FTM_SHAPING_V_TOL_Y, FTM_SHAPING_V_TOL_Z, FTM_SHAPING_V_TOL_E) };
|
||||
SHAPED_ARRAY(FTM_SHAPING_V_TOL_X, FTM_SHAPING_V_TOL_Y, FTM_SHAPING_V_TOL_Z, FTM_SHAPING_V_TOL_E);
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
ft_smoothed_float_t smoothingTime; // Smoothing time. [s]
|
||||
|
|
@ -84,24 +84,22 @@ class FTMotion {
|
|||
|
||||
#if HAS_FTM_SHAPING
|
||||
|
||||
#define SET_CFG_DEFAULTS(A) \
|
||||
#define _SET_CFG_DEFAULTS(A) do{ \
|
||||
cfg.shaper.A = FTM_DEFAULT_SHAPER_##A; \
|
||||
cfg.baseFreq.A = FTM_SHAPING_DEFAULT_FREQ_##A; \
|
||||
cfg.zeta.A = FTM_SHAPING_ZETA_##A; \
|
||||
cfg.vtol.A = FTM_SHAPING_V_TOL_##A;
|
||||
cfg.vtol.A = FTM_SHAPING_V_TOL_##A; \
|
||||
}while(0);
|
||||
|
||||
TERN_(HAS_X_AXIS, SET_CFG_DEFAULTS(X));
|
||||
TERN_(HAS_Y_AXIS, SET_CFG_DEFAULTS(Y));
|
||||
TERN_(FTM_SHAPER_Z, SET_CFG_DEFAULTS(Z));
|
||||
TERN_(FTM_SHAPER_E, SET_CFG_DEFAULTS(E));
|
||||
SHAPED_MAP(_SET_CFG_DEFAULTS);
|
||||
#undef _SET_CFG_DEFAULTS
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
cfg.dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE;
|
||||
//ZERO(cfg.dynFreqK);
|
||||
TERN_(HAS_X_AXIS, cfg.dynFreqK.x = 0.0f);
|
||||
TERN_(HAS_Y_AXIS, cfg.dynFreqK.y = 0.0f);
|
||||
TERN_(FTM_SHAPER_Z, cfg.dynFreqK.z = 0.0f);
|
||||
TERN_(FTM_SHAPER_E, cfg.dynFreqK.e = 0.0f);
|
||||
#define _DYN_RESET(A) cfg.dynFreqK.A = 0.0f;
|
||||
SHAPED_MAP(_DYN_RESET);
|
||||
#undef _DYN_RESET
|
||||
#endif
|
||||
|
||||
update_shaping_params();
|
||||
|
|
@ -109,10 +107,9 @@ class FTMotion {
|
|||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
TERN_(HAS_X_AXIS, set_smoothing_time(X_AXIS, FTM_SMOOTHING_TIME_X));
|
||||
TERN_(HAS_Y_AXIS, set_smoothing_time(Y_AXIS, FTM_SMOOTHING_TIME_Y));
|
||||
TERN_(HAS_Z_AXIS, set_smoothing_time(Z_AXIS, FTM_SMOOTHING_TIME_Z));
|
||||
TERN_(HAS_EXTRUDERS, set_smoothing_time(E_AXIS, FTM_SMOOTHING_TIME_E));
|
||||
#define _SET_SMOOTH(A) set_smoothing_time(_AXIS(A), FTM_SMOOTHING_TIME_##A);
|
||||
CARTES_MAP(_SET_SMOOTH);
|
||||
#undef _SET_SMOOTH
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
|
|
@ -214,10 +211,7 @@ class FTMotion {
|
|||
|
||||
typedef struct Shaping {
|
||||
uint32_t zi_idx; // Index of storage in the data point delay vectors.
|
||||
OPTCODE(HAS_X_AXIS, axis_shaping_t x)
|
||||
OPTCODE(HAS_Y_AXIS, axis_shaping_t y)
|
||||
OPTCODE(FTM_SHAPER_Z, axis_shaping_t z)
|
||||
OPTCODE(FTM_SHAPER_E, axis_shaping_t e)
|
||||
axis_shaping_t SHAPED_AXIS_NAMES;
|
||||
} shaping_t;
|
||||
|
||||
static shaping_t shaping; // Shaping data
|
||||
|
|
@ -235,10 +229,7 @@ class FTMotion {
|
|||
|
||||
// Smoothing data for XYZE axes
|
||||
typedef struct Smoothing {
|
||||
OPTCODE(HAS_X_AXIS, axis_smoothing_t x)
|
||||
OPTCODE(HAS_Y_AXIS, axis_smoothing_t y)
|
||||
OPTCODE(HAS_Z_AXIS, axis_smoothing_t z)
|
||||
OPTCODE(HAS_EXTRUDERS, axis_smoothing_t e)
|
||||
axis_smoothing_t CARTES_AXIS_NAMES;
|
||||
} smoothing_t;
|
||||
static smoothing_t smoothing; // Smoothing data
|
||||
#endif
|
||||
|
|
@ -257,12 +248,9 @@ class FTMotion {
|
|||
static void generateStepsFromTrajectory(const uint32_t idx);
|
||||
|
||||
FORCE_INLINE static int32_t num_samples_shaper_settle() {
|
||||
return (
|
||||
TERN0(HAS_X_AXIS, shaping.x.ena)
|
||||
|| TERN0(HAS_Y_AXIS, shaping.y.ena)
|
||||
|| TERN0(FTM_SHAPER_Z, shaping.z.ena)
|
||||
|| TERN0(FTM_SHAPER_E, shaping.e.ena)
|
||||
) ? FTM_ZMAX : 0;
|
||||
#define _OR_ENA(A) || shaping.A.ena
|
||||
return false SHAPED_MAP(_OR_ENA) ? FTM_ZMAX : 0;
|
||||
#undef _OR_ENA
|
||||
}
|
||||
|
||||
}; // class FTMotion
|
||||
|
|
|
|||
|
|
@ -60,19 +60,30 @@ enum {
|
|||
|
||||
typedef bits_t(FT_BIT_COUNT) ft_command_t;
|
||||
|
||||
// Emitters for code that only cares about shaped XYZE
|
||||
#if HAS_FTM_SHAPING
|
||||
#define NUM_AXES_SHAPED COUNT_ENABLED(HAS_X_AXIS, HAS_Y_AXIS, FTM_SHAPER_Z, FTM_SHAPER_E)
|
||||
#define SHAPED_ELEM(A,B,C,D) A OPTARG(HAS_Y_AXIS, B) OPTARG(FTM_SHAPER_Z, C) OPTARG(FTM_SHAPER_E, D)
|
||||
#define NUM_AXES_SHAPED COUNT_ENABLED(HAS_X_AXIS, HAS_Y_AXIS, FTM_SHAPER_Z, FTM_SHAPER_E)
|
||||
#define SHAPED_AXIS_NAMES XY_LIST(X, Y) OPTARG(FTM_SHAPER_Z, Z) OPTARG(FTM_SHAPER_E, E)
|
||||
#define SHAPED_GANG(A,B,C,D) XY_GANG(A, B) TERN_(FTM_SHAPER_Z, C) TERN_(FTM_SHAPER_E, D)
|
||||
#define SHAPED_LIST(A,B,C,D) XY_LIST(A, B) OPTARG(FTM_SHAPER_Z, C) OPTARG(FTM_SHAPER_E, D)
|
||||
#define SHAPED_ARRAY(A,B,C,D) { SHAPED_LIST(A, B, C, D) }
|
||||
#define SHAPED_CODE(A,B,C,D) XY_CODE(A, B) OPTCODE(FTM_SHAPER_Z, C) OPTCODE(FTM_SHAPER_E, D)
|
||||
#define SHAPED_MAP(F) MAP(F, SHAPED_AXIS_NAMES)
|
||||
#else
|
||||
#define NUM_AXES_SHAPED 0
|
||||
#define SHAPED_ELEM(A,B,C,D)
|
||||
#define SHAPED_AXIS_NAMES
|
||||
#define SHAPED_GANG(...)
|
||||
#define SHAPED_LIST(...)
|
||||
#define SHAPED_ARRAY(...) {}
|
||||
#define SHAPED_CODE(...)
|
||||
#define SHAPED_MAP(...)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct FTShapedAxes {
|
||||
union {
|
||||
struct { T SHAPED_ELEM(X, Y, Z, E); };
|
||||
struct { T SHAPED_ELEM(x, y, z, e); };
|
||||
struct { T SHAPED_AXIS_NAMES; };
|
||||
struct { T SHAPED_LIST(x, y, z, e); };
|
||||
T val[NUM_AXES_SHAPED];
|
||||
};
|
||||
T& operator[](const int axis) {
|
||||
|
|
@ -80,24 +91,11 @@ struct FTShapedAxes {
|
|||
}
|
||||
|
||||
private:
|
||||
static constexpr int axis_to_index(int axis) {
|
||||
int idx = 0;
|
||||
#if HAS_X_AXIS
|
||||
if (axis == X_AXIS) return idx;
|
||||
idx++;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (axis == Y_AXIS) return idx;
|
||||
idx++;
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
if (axis == Z_AXIS) return idx;
|
||||
idx++;
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
if (axis == E_AXIS) return idx;
|
||||
idx++;
|
||||
#endif
|
||||
static constexpr int axis_to_index(const int axis) {
|
||||
int idx = -1;
|
||||
#define _ATOI(A) idx++; if (axis == _AXIS(A)) return idx;
|
||||
SHAPED_MAP(_ATOI);
|
||||
#undef _ATOI
|
||||
return -1; // Invalid axis
|
||||
}
|
||||
};
|
||||
|
|
@ -108,17 +106,6 @@ typedef FTShapedAxes<dynFreqMode_t> ft_shaped_dfm_t;
|
|||
|
||||
#if ENABLED(FTM_SMOOTHING)
|
||||
typedef struct FTSmoothedAxes {
|
||||
#if HAS_X_AXIS
|
||||
float x;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
float y;
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
float z;
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
float e;
|
||||
#endif
|
||||
float CARTES_AXIS_NAMES;
|
||||
} ft_smoothed_float_t;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ void report_current_position_projected() {
|
|||
#else // CARTESIAN
|
||||
|
||||
// Return true if the given position is within the machine bounds.
|
||||
bool position_is_reachable(TERN_(HAS_X_AXIS, const float rx) OPTARG(HAS_Y_AXIS, const float ry)) {
|
||||
bool position_is_reachable(XY_LIST(const float rx, const float ry)) {
|
||||
if (TERN0(HAS_Y_AXIS, !COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop))) return false;
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
if (active_extruder)
|
||||
|
|
@ -957,7 +957,7 @@ void do_blocking_move_to(NUM_AXIS_ARGS_(const float) const feedRate_t fr_mm_s/*=
|
|||
if (current_position.z < z) { current_position.z = z; line_to_current_position(z_feedrate); }
|
||||
#endif
|
||||
|
||||
current_position.set(TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y)); line_to_current_position(xy_feedrate);
|
||||
current_position.set(XY_LIST(x, y)); line_to_current_position(xy_feedrate);
|
||||
|
||||
#if SECONDARY_AXES
|
||||
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
|
||||
|
|
|
|||
|
|
@ -578,9 +578,9 @@ void home_if_needed(const bool keeplev=false);
|
|||
#else
|
||||
|
||||
// Return true if the given position is within the machine bounds.
|
||||
bool position_is_reachable(TERN_(HAS_X_AXIS, const float rx) OPTARG(HAS_Y_AXIS, const float ry));
|
||||
bool position_is_reachable(XY_LIST(const float rx, const float ry));
|
||||
inline bool position_is_reachable(const xy_pos_t &pos) {
|
||||
return position_is_reachable(TERN_(HAS_X_AXIS, pos.x) OPTARG(HAS_Y_AXIS, pos.y));
|
||||
return position_is_reachable(XY_LIST(pos.x, pos.y));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
* di -> (2 a d - s1^2 + s2^2)/(4 a)
|
||||
*
|
||||
* We note, as an optimization, that if we have already calculated an
|
||||
* acceleration distance d1 from s1 to m and a deceration distance d2
|
||||
* acceleration distance d1 from s1 to m and a deceleration distance d2
|
||||
* from m to s2 then
|
||||
*
|
||||
* d1 -> (m^2 - s1^2) / (2 a)
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public:
|
|||
|
||||
static bool set_deployed(const bool, const bool=false) { return false; }
|
||||
|
||||
static bool can_reach(const float rx, const float ry, const bool=true) { return position_is_reachable(TERN_(HAS_X_AXIS, rx) OPTARG(HAS_Y_AXIS, ry)); }
|
||||
static bool can_reach(const float rx, const float ry, const bool=true) { return position_is_reachable(XY_LIST(rx, ry)); }
|
||||
|
||||
#endif // !HAS_BED_PROBE
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,6 @@
|
|||
#endif
|
||||
|
||||
#if ENABLED(MPCTEMP)
|
||||
#include <math.h>
|
||||
#include "probe.h"
|
||||
#endif
|
||||
|
||||
|
|
|
|||
15
buildroot/share/PlatformIO/scripts/deeper.cpp
Normal file
15
buildroot/share/PlatformIO/scripts/deeper.cpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Use this file to dig deeper into compile issues.
|
||||
*
|
||||
* Usage:
|
||||
* gcc -D__MARLIN_DEPS__ -E -o - buildroot/share/PlatformIO/scripts/deeper.cpp
|
||||
*
|
||||
* For convenience redirect output to a file or pipe to your favorite editor.
|
||||
*/
|
||||
|
||||
#include "../../../../Marlin/src/inc/MarlinConfig.h"
|
||||
|
||||
int main() {
|
||||
// Insert your code here
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue