mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-12-28 10:20:36 -07:00
parent
05a64e2013
commit
40beddeaa3
2 changed files with 251 additions and 317 deletions
|
|
@ -46,8 +46,10 @@ void say_shaper_type(const AxisEnum a, bool &sep, const char axis_name) {
|
|||
}
|
||||
|
||||
void say_shaping() {
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
|
||||
// FT Enabled
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.active, "Fixed-Time Motion ", "en", "dis", "abled");
|
||||
SERIAL_ECHO_TERNARY(c.active, "Fixed-Time Motion ", "en", "dis", "abled");
|
||||
|
||||
// FT Shaping
|
||||
const bool is_shaping = AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y) || AXIS_IS_SHAPING(Z) || AXIS_IS_SHAPING(E);
|
||||
|
|
@ -61,15 +63,15 @@ void say_shaping() {
|
|||
}
|
||||
SERIAL_EOL();
|
||||
|
||||
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, ftMotion.cfg.dynFreqMode == dynFreqMode_Z_BASED),
|
||||
g_based = TERN0(HAS_DYNAMIC_FREQ_G, ftMotion.cfg.dynFreqMode == dynFreqMode_MASS_BASED),
|
||||
const bool z_based = TERN0(HAS_DYNAMIC_FREQ_MM, c.dynFreqMode == dynFreqMode_Z_BASED),
|
||||
g_based = TERN0(HAS_DYNAMIC_FREQ_G, c.dynFreqMode == dynFreqMode_MASS_BASED),
|
||||
dynamic = z_based || g_based;
|
||||
|
||||
// FT Dynamic Frequency Mode
|
||||
if (is_shaping) {
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SERIAL_ECHOPGM("Dynamic Frequency Mode ");
|
||||
switch (ftMotion.cfg.dynFreqMode) {
|
||||
switch (c.dynFreqMode) {
|
||||
default:
|
||||
case dynFreqMode_DISABLED: SERIAL_ECHOPGM("disabled"); break;
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
|
|
@ -85,9 +87,9 @@ void say_shaping() {
|
|||
#if HAS_X_AXIS
|
||||
SERIAL_CHAR(STEPPER_A_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.x, 2), F("Hz"));
|
||||
SERIAL_ECHO(p_float_t(c.baseFreq.x, 2), F("Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.x, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
|
@ -95,9 +97,9 @@ void say_shaping() {
|
|||
#if HAS_Y_AXIS
|
||||
SERIAL_CHAR(STEPPER_B_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.y, 2), F(" Hz"));
|
||||
SERIAL_ECHO(p_float_t(c.baseFreq.y, 2), F(" Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.y, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
|
@ -105,18 +107,18 @@ void say_shaping() {
|
|||
#if ENABLED(FTM_SHAPER_Z)
|
||||
SERIAL_CHAR(STEPPER_C_NAME);
|
||||
SERIAL_ECHO_TERNARY(dynamic, " ", "base dynamic", "static", " shaper frequency: ");
|
||||
SERIAL_ECHO(p_float_t(ftMotion.cfg.baseFreq.z, 2), F(" Hz"));
|
||||
SERIAL_ECHO(p_float_t(c.baseFreq.z, 2), F(" Hz"));
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(ftMotion.cfg.dynFreqK.z, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
if (dynamic) SERIAL_ECHO(F(" scaling: "), p_float_t(c.dynFreqK.z, 2), F("Hz/"), z_based ? F("mm") : F("g"));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
if (ftMotion.cfg.active) {
|
||||
SERIAL_ECHO_TERNARY(ftMotion.cfg.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
SERIAL_ECHOLNPGM(". Gain: ", ftMotion.cfg.linearAdvK);
|
||||
if (c.active) {
|
||||
SERIAL_ECHO_TERNARY(c.linearAdvEna, "Linear Advance ", "en", "dis", "abled");
|
||||
SERIAL_ECHOLNPGM(". Gain: ", c.linearAdvK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -126,90 +128,34 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
|
||||
report_heading_etc(forReplay, F(STR_FT_MOTION));
|
||||
const ft_config_t &c = ftMotion.cfg;
|
||||
|
||||
SERIAL_ECHOLNPGM(
|
||||
" M493 S", c.active
|
||||
|
||||
// Shaper type for each axis
|
||||
#if HAS_X_AXIS
|
||||
, " X", c.shaper.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " Y", c.shaper.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " Z", c.shaper.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " E", c.shaper.e
|
||||
#endif
|
||||
|
||||
// Base Frequency for axis shapers
|
||||
#if HAS_X_AXIS
|
||||
, " A", c.baseFreq.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " B", c.baseFreq.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " C", c.baseFreq.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " W", c.baseFreq.e
|
||||
#endif
|
||||
|
||||
// Dynamic Frequency Mode and Axis K Factors
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
, " D", c.dynFreqMode
|
||||
#if HAS_X_AXIS
|
||||
, " F", c.dynFreqK.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " H", c.dynFreqK.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " L", c.dynFreqK.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " N", c.dynFreqK.e
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Zeta Value
|
||||
#if HAS_X_AXIS
|
||||
, " I", c.zeta.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " J", c.zeta.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " O", c.zeta.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " U", c.zeta.e
|
||||
#endif
|
||||
|
||||
// Vibration Tolerance
|
||||
#if HAS_X_AXIS
|
||||
, " Q", c.vtol.x
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, " R", c.vtol.y
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
, " T", c.vtol.z
|
||||
#endif
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
, " V", c.vtol.e
|
||||
#endif
|
||||
|
||||
// Axis Synchronization
|
||||
, " G", c.axis_sync_enabled
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
, " P", c.linearAdvEna, " K", c.linearAdvK
|
||||
#endif
|
||||
|
||||
// Axis Synchronization
|
||||
, " H", c.axis_sync_enabled
|
||||
);
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
#define F_REPORT(A) , F(" F"), c.dynFreqK.A
|
||||
#else
|
||||
#define F_REPORT(A)
|
||||
#endif
|
||||
#define _REPORT_M493_AXIS(A) \
|
||||
SERIAL_ECHOLN(F(" M493 "), C(AXIS_CHAR(_AXIS(A))) \
|
||||
, F(" C"), c.shaper.A \
|
||||
, F(" A"), c.baseFreq.A \
|
||||
F_REPORT(A) \
|
||||
, F(" I"), c.zeta.A \
|
||||
, F(" Q"), c.vtol.A \
|
||||
);
|
||||
// Shaper type for each axis
|
||||
SHAPED_MAP(_REPORT_M493_AXIS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -219,7 +165,23 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
* 0: Fixed-Time Motion OFF (Standard Motion)
|
||||
* 1: Fixed-Time Motion ON
|
||||
*
|
||||
* X/Y/Z/E<mode> Set the vibration compensator [input shaper] mode for an axis.
|
||||
* V Flag to request version (Version 2+). (No reply = Version < 2)
|
||||
*
|
||||
* H<bool> Enable (1) or Disable (0) Axis Synchronization.
|
||||
*
|
||||
* Linear / Pressure Advance:
|
||||
*
|
||||
* P<bool> Enable (1) or Disable (0) Linear Advance pressure control
|
||||
* K<gain> Set Linear Advance gain
|
||||
*
|
||||
* Specifying Axes (for A,C,F,I,Q):
|
||||
*
|
||||
* X/Y/Z/E : Flag the axes (or core steppers) on which to apply the given parameters
|
||||
* If none are given then XY is assumed.
|
||||
*
|
||||
* Compensator / Input Shaper:
|
||||
*
|
||||
* C<mode> Set Compensator Mode (Input Shaper) for the specified axes
|
||||
* Users / slicers must remember to set the mode for all relevant axes!
|
||||
* 0: NONE : No input shaper
|
||||
* 1: ZV : Zero Vibration
|
||||
|
|
@ -231,41 +193,27 @@ void GcodeSuite::M493_report(const bool forReplay/*=true*/) {
|
|||
* 7: 3HEI : 3-Hump Extra-Intensive
|
||||
* 8: MZV : Mass-based Zero Vibration
|
||||
*
|
||||
* P<bool> Enable (1) or Disable (0) Linear Advance pressure control
|
||||
* A<Hz> Set static/base frequency for the specified axes
|
||||
* I<flt> Set damping ratio for the specified axes
|
||||
* Q<flt> Set vibration tolerance (vtol) for the specified axes
|
||||
*
|
||||
* K<gain> Set Linear Advance gain
|
||||
* Dynamic Frequency Mode:
|
||||
*
|
||||
* G<bool> Enable (1) or Disable (0) axis synchronization.
|
||||
*
|
||||
* D<mode> Set Dynamic Frequency mode
|
||||
* D<mode> Set Dynamic Frequency mode (for all axis compensators)
|
||||
* 0: DISABLED
|
||||
* 1: Z-based (Requires a Z axis)
|
||||
* 2: Mass-based (Requires X and E axes)
|
||||
*
|
||||
* A<Hz> Set X static/base frequency
|
||||
* F<Hz> Set X frequency scaling
|
||||
* I<flt> Set X damping ratio
|
||||
* Q<flt> Set X vibration tolerance (vtol)
|
||||
*
|
||||
* B<Hz> Set Y static/base frequency
|
||||
* H<Hz> Set Y frequency scaling
|
||||
* J<flt> Set Y damping ratio
|
||||
* R<flt> Set Y vibration tolerance
|
||||
*
|
||||
* With FTM_SHAPER_Z:
|
||||
* C<Hz> Set Z static/base frequency
|
||||
* L<Hz> Set Z frequency scaling
|
||||
* O<flt> Set Z damping ratio
|
||||
* T<flt> Set Z vibration tolerance
|
||||
*
|
||||
* With FTM_SHAPER_E:
|
||||
* W<Hz> Set E static/base frequency
|
||||
* N<Hz> Set E frequency scaling
|
||||
* U<flt> Set E damping ratio
|
||||
* V<flt> Set E vibration tolerance
|
||||
* F<Hz> Set frequency scaling for the specified axes
|
||||
*
|
||||
*/
|
||||
void GcodeSuite::M493() {
|
||||
// Request version of FTM. (No response = Version < 2)
|
||||
if (parser.seen('V') && !parser.has_value()) {
|
||||
SERIAL_ECHOLNPGM("FTM V" STRINGIFY(FTM_VERSION));
|
||||
return;
|
||||
}
|
||||
|
||||
struct { bool update:1, report:1; } flag = { false };
|
||||
|
||||
if (!parser.seen_any())
|
||||
|
|
@ -283,30 +231,23 @@ void GcodeSuite::M493() {
|
|||
|
||||
#if NUM_AXES_SHAPED > 0
|
||||
|
||||
auto set_shaper = [&](const AxisEnum axis, const char c) {
|
||||
const ftMotionShaper_t newsh = (ftMotionShaper_t)parser.value_byte();
|
||||
const bool seenC = parser.seenval('C');
|
||||
const ftMotionShaper_t shaperVal = seenC ? (ftMotionShaper_t)parser.value_byte() : ftMotionShaper_NONE;
|
||||
const bool goodShaper = WITHIN(shaperVal, ftMotionShaper_NONE, ftMotionShaper_MZV);
|
||||
if (seenC && !goodShaper) {
|
||||
SERIAL_ECHOLNPGM("?Invalid (C)ompensator value. (0-", int(ftMotionShaper_MZV));
|
||||
return;
|
||||
}
|
||||
auto set_shaper = [&](const AxisEnum axis, ftMotionShaper_t newsh) {
|
||||
if (newsh != ftMotion.cfg.shaper[axis]) {
|
||||
switch (newsh) {
|
||||
default: SERIAL_ECHOLNPGM("?Invalid [", C(c), "] shaper."); return true;
|
||||
case ftMotionShaper_NONE:
|
||||
case ftMotionShaper_ZV:
|
||||
case ftMotionShaper_ZVD:
|
||||
case ftMotionShaper_ZVDD:
|
||||
case ftMotionShaper_ZVDDD:
|
||||
case ftMotionShaper_EI:
|
||||
case ftMotionShaper_2HEI:
|
||||
case ftMotionShaper_3HEI:
|
||||
case ftMotionShaper_MZV:
|
||||
ftMotion.cfg.shaper[axis] = newsh;
|
||||
flag.update = flag.report = true;
|
||||
break;
|
||||
}
|
||||
ftMotion.cfg.shaper[axis] = newsh;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
#define _SET_SHAPER(A) if (parser.seenval(CHARIFY(A)) && set_shaper(_AXIS(A), CHARIFY(A))) return;
|
||||
SHAPED_MAP(_SET_SHAPER);
|
||||
if (seenC) {
|
||||
#define _SET_SHAPER(A) set_shaper(_AXIS(A), shaperVal);
|
||||
SHAPED_MAP(_SET_SHAPER);
|
||||
}
|
||||
|
||||
#endif // NUM_AXES_SHAPED > 0
|
||||
|
||||
|
|
@ -332,8 +273,8 @@ void GcodeSuite::M493() {
|
|||
|
||||
#endif // HAS_EXTRUDERS
|
||||
|
||||
// Parse 'G' axis synchronization parameter.
|
||||
if (parser.seenval('G')) {
|
||||
// Parse 'H' Axis Synchronization parameter.
|
||||
if (parser.seenval('H')) {
|
||||
const bool enabled = parser.value_bool();
|
||||
if (enabled != ftMotion.cfg.axis_sync_enabled) {
|
||||
ftMotion.cfg.axis_sync_enabled = enabled;
|
||||
|
|
@ -359,12 +300,12 @@ void GcodeSuite::M493() {
|
|||
flag.report = true;
|
||||
break;
|
||||
default:
|
||||
SERIAL_ECHOLNPGM("?Invalid Dynamic Frequency Mode [D] value.");
|
||||
SERIAL_ECHOLNPGM("?Invalid (D)ynamic Frequency Mode value.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SERIAL_ECHOLNPGM("?Wrong shaper for [D] Dynamic Frequency mode.");
|
||||
SERIAL_ECHOLNPGM("?Wrong shaper for (D)ynamic Frequency mode ", ftMotion.cfg.dynFreqMode, ".");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -375,247 +316,238 @@ void GcodeSuite::M493() {
|
|||
|
||||
#endif // HAS_DYNAMIC_FREQ
|
||||
|
||||
// Frequency parameter
|
||||
const bool seenA = parser.seenval('A');
|
||||
const float baseFreqVal = seenA ? parser.value_float() : 0.0f;
|
||||
const bool goodBaseFreq = seenA && WITHIN(baseFreqVal, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2);
|
||||
if (seenA && !goodBaseFreq)
|
||||
SERIAL_ECHOLN(F("?Invalid (A) Base Frequency value. ("), int(FTM_MIN_SHAPE_FREQ), C('-'), int((FTM_FS) / 2), C(')'));
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Dynamic Frequency parameter
|
||||
const bool seenF = parser.seenval('F');
|
||||
const float baseDynFreqVal = seenF ? parser.value_float() : 0.0f;
|
||||
if (seenF && !modeUsesDynFreq)
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for (F)requency scaling.");
|
||||
#endif
|
||||
|
||||
// Zeta parameter
|
||||
const bool seenI = parser.seenval('I');
|
||||
const float zetaVal = seenI ? parser.value_float() : 0.0f;
|
||||
const bool goodZeta = seenI && WITHIN(zetaVal, 0.01f, 1.0f);
|
||||
if (seenI && !goodZeta)
|
||||
SERIAL_ECHOLNPGM("?Invalid (I) Zeta value. (0.01-1.0)"); // Zeta out of range
|
||||
|
||||
// Vibration Tolerance parameter
|
||||
const bool seenQ = parser.seenval('Q');
|
||||
const float vtolVal = seenQ ? parser.value_float() : 0.0f;
|
||||
const bool goodVtol = seenQ && WITHIN(vtolVal, 0.00f, 1.0f);
|
||||
if (seenQ && !goodVtol)
|
||||
SERIAL_ECHOLNPGM("?Invalid (Q) Vibration Tolerance value. (0.0-1.0)"); // VTol out of range
|
||||
|
||||
const bool apply_xy = !parser.seen("XYZE");
|
||||
|
||||
#if HAS_X_AXIS
|
||||
|
||||
// Parse X frequency parameter
|
||||
if (parser.seenval('A')) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
const float val = parser.value_float();
|
||||
// TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct.
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.x = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " [", C('A'), "] frequency value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('A'), "] frequency.");
|
||||
}
|
||||
if (apply_xy || parser.seen_test('X')) {
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse X frequency scaling parameter
|
||||
if (parser.seenval('F')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.x = parser.value_float();
|
||||
// Parse X frequency parameter
|
||||
if (seenA) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
// TODO: Frequency minimum is dependent on the shaper used; the above check isn't always correct.
|
||||
if (goodBaseFreq) {
|
||||
ftMotion.cfg.baseFreq.x = baseFreqVal;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [A] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse X frequency scaling parameter
|
||||
if (seenF && modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.x = baseDynFreqVal;
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " [", C('F'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Parse X zeta parameter
|
||||
if (parser.seenval('I')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.x = val;
|
||||
flag.update = true;
|
||||
// Parse X zeta parameter
|
||||
if (seenI) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
if (goodZeta) {
|
||||
ftMotion.cfg.zeta.x = zetaVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " zeta [", C('I'), "] value."); // Zeta out of range
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse X vtol parameter
|
||||
if (parser.seenval('Q')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(X)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.x = val;
|
||||
flag.update = true;
|
||||
// Parse X vtol parameter
|
||||
if (seenQ) {
|
||||
if (AXIS_IS_EISHAPING(X)) {
|
||||
if (goodVtol) {
|
||||
ftMotion.cfg.vtol.x = vtolVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_A_NAME), " vtol [", C('Q'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_A_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // HAS_X_AXIS
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
|
||||
// Parse Y frequency parameter
|
||||
if (parser.seenval('B')) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.y = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " frequency [", C('B'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('B'), "] frequency.");
|
||||
}
|
||||
if (apply_xy || parser.seen_test('Y')) {
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse Y frequency scaling parameter
|
||||
if (parser.seenval('H')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.y = parser.value_float();
|
||||
// Parse Y frequency parameter
|
||||
if (seenA) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
if (goodBaseFreq) {
|
||||
ftMotion.cfg.baseFreq.y = baseFreqVal;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [A] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse Y frequency scaling parameter
|
||||
if (seenF && modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.y = baseDynFreqVal;
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " [", C('H'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Parse Y zeta parameter
|
||||
if (parser.seenval('J')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.y = val;
|
||||
flag.update = true;
|
||||
// Parse Y zeta parameter
|
||||
if (seenI) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
if (goodZeta) {
|
||||
ftMotion.cfg.zeta.y = zetaVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " zeta [", C('J'), "] value."); // Zeta out of range
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse Y vtol parameter
|
||||
if (parser.seenval('R')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(Y)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.y = val;
|
||||
flag.update = true;
|
||||
// Parse Y vtol parameter
|
||||
if (seenQ) {
|
||||
if (AXIS_IS_EISHAPING(Y)) {
|
||||
if (goodVtol) {
|
||||
ftMotion.cfg.vtol.y = vtolVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_B_NAME), " vtol [", C('R'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " vtol parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_B_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // HAS_Y_AXIS
|
||||
|
||||
#if ENABLED(FTM_SHAPER_Z)
|
||||
|
||||
// Parse Z frequency parameter
|
||||
if (parser.seenval('C')) {
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.z = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " frequency [", C('C'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('C'), "] frequency.");
|
||||
}
|
||||
if (parser.seen_test('Z')) {
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse Z frequency scaling parameter
|
||||
if (parser.seenval('L')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.z = parser.value_float();
|
||||
// Parse Z frequency parameter
|
||||
if (seenA) {
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
if (goodBaseFreq) {
|
||||
ftMotion.cfg.baseFreq.z = baseFreqVal;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [A] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse Z frequency scaling parameter
|
||||
if (seenF && modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.z = baseDynFreqVal;
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " [", C('L'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Parse Z zeta parameter
|
||||
if (parser.seenval('O')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.z = val;
|
||||
flag.update = true;
|
||||
// Parse Z zeta parameter
|
||||
if (seenI) {
|
||||
if (AXIS_IS_SHAPING(Z)) {
|
||||
if (goodZeta) {
|
||||
ftMotion.cfg.zeta.z = zetaVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " zeta [", C('O'), "] value."); // Zeta out of range
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " zeta parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse Z vtol parameter
|
||||
if (parser.seenval('T')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(Z)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.z = val;
|
||||
flag.update = true;
|
||||
// Parse Z vtol parameter
|
||||
if (seenQ) {
|
||||
if (AXIS_IS_EISHAPING(Z)) {
|
||||
if (goodVtol) {
|
||||
ftMotion.cfg.vtol.z = vtolVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C(STEPPER_C_NAME), " vtol [", C('T'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " vtol parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C(STEPPER_C_NAME), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // FTM_SHAPER_Z
|
||||
|
||||
#if ENABLED(FTM_SHAPER_E)
|
||||
|
||||
// Parse E frequency parameter
|
||||
if (parser.seenval('W')) {
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
const float val = parser.value_float();
|
||||
if (WITHIN(val, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2)) {
|
||||
ftMotion.cfg.baseFreq.e = val;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
else // Frequency out of range.
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " frequency [", C('W'), "] value.");
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('W'), "] frequency.");
|
||||
}
|
||||
if (parser.seen_test('E')) {
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse E frequency scaling parameter
|
||||
if (parser.seenval('N')) {
|
||||
if (modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.e = parser.value_float();
|
||||
// Parse E frequency parameter
|
||||
if (seenA) {
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
if (goodBaseFreq) {
|
||||
ftMotion.cfg.baseFreq.e = baseFreqVal;
|
||||
flag.update = flag.report = true;
|
||||
}
|
||||
}
|
||||
else // Mode doesn't use frequency.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [A] frequency.");
|
||||
}
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
// Parse E frequency scaling parameter
|
||||
if (seenF && modeUsesDynFreq) {
|
||||
ftMotion.cfg.dynFreqK.e = baseDynFreqVal;
|
||||
flag.report = true;
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " [", C('N'), "] frequency scaling.");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Parse E zeta parameter
|
||||
if (parser.seenval('U')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta.e = val;
|
||||
flag.update = true;
|
||||
// Parse E zeta parameter
|
||||
if (seenI) {
|
||||
if (AXIS_IS_SHAPING(E)) {
|
||||
if (goodZeta) {
|
||||
ftMotion.cfg.zeta.e = zetaVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " zeta [", C('U'), "] value."); // Zeta out of range
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " zeta parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " zeta parameter.");
|
||||
}
|
||||
|
||||
// Parse E vtol parameter
|
||||
if (parser.seenval('V')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_IS_EISHAPING(E)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol.e = val;
|
||||
flag.update = true;
|
||||
// Parse E vtol parameter
|
||||
if (seenQ) {
|
||||
if (AXIS_IS_EISHAPING(E)) {
|
||||
if (goodVtol) {
|
||||
ftMotion.cfg.vtol.e = vtolVal;
|
||||
flag.update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Invalid ", C('E'), " vtol [", C('V'), "] value."); // VTol out of range.
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter.");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("?Wrong mode for ", C('E'), " vtol parameter.");
|
||||
}
|
||||
|
||||
#endif // FTM_SHAPER_E
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include "ft_motion/poly5_trajectory_generator.h"
|
||||
#include "ft_motion/poly6_trajectory_generator.h"
|
||||
|
||||
#define FTM_VERSION 2 // Change version when hosts need to know
|
||||
|
||||
#if HAS_X_AXIS && (HAS_Z_AXIS || HAS_EXTRUDERS)
|
||||
#define HAS_DYNAMIC_FREQ 1
|
||||
#if HAS_Z_AXIS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue