mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-01-01 20:33:52 -07:00
🎨 Clean up FTM, etc.
This commit is contained in:
parent
294903439a
commit
8aac26275e
8 changed files with 65 additions and 65 deletions
|
|
@ -1150,16 +1150,18 @@
|
|||
#if ENABLED(FT_MOTION)
|
||||
//#define FTM_IS_DEFAULT_MOTION // Use FT Motion as the factory default?
|
||||
#define FTM_DEFAULT_DYNFREQ_MODE dynFreqMode_DISABLED // Default mode of dynamic frequency calculation. (DISABLED, Z_BASED, MASS_BASED)
|
||||
#define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV)
|
||||
#define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
|
||||
#define FTM_LINEAR_ADV_DEFAULT_ENA false // Default linear advance enable (true) or disable (false)
|
||||
#define FTM_LINEAR_ADV_DEFAULT_K 0.0f // Default linear advance gain. (Acceleration-based scaling factor.)
|
||||
#define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis
|
||||
#define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis
|
||||
|
||||
#define FTM_DEFAULT_SHAPER_X ftMotionShaper_NONE // Default shaper mode on X axis (NONE, ZV, ZVD, ZVDD, ZVDDD, EI, 2HEI, 3HEI, MZV)
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis
|
||||
#define FTM_SHAPING_V_TOL_X 0.05f // Vibration tolerance used by EI input shapers for X axis
|
||||
|
||||
#define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE // Default shaper mode on Y axis
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_ZETA_Y 0.1f // Zeta used by input shapers for Y axis
|
||||
#define FTM_SHAPING_V_TOL_Y 0.05f // Vibration tolerance used by EI input shapers for Y axis
|
||||
|
||||
//#define FT_MOTION_MENU // Provide a MarlinUI menu to set M493 parameters
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ void say_shaping() {
|
|||
|
||||
// FT Shaping
|
||||
#if HAS_X_AXIS
|
||||
if (AXIS_HAS_SHAPER(X)) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
SERIAL_ECHOPGM(" with " AXIS_0_NAME);
|
||||
say_shaper_type(X_AXIS);
|
||||
}
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (AXIS_HAS_SHAPER(Y)) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
SERIAL_ECHOPGM(" and with " AXIS_1_NAME);
|
||||
say_shaper_type(Y_AXIS);
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ void say_shaping() {
|
|||
dynamic = z_based || g_based;
|
||||
|
||||
// FT Dynamic Frequency Mode
|
||||
if (AXIS_HAS_SHAPER(X) || AXIS_HAS_SHAPER(Y)) {
|
||||
if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) {
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SERIAL_ECHOPGM("Dynamic Frequency Mode ");
|
||||
switch (ftMotion.cfg.dynFreqMode) {
|
||||
|
|
@ -263,7 +263,7 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Dynamic frequency mode parameter.
|
||||
if (parser.seenval('D')) {
|
||||
if (AXIS_HAS_SHAPER(X) || AXIS_HAS_SHAPER(Y)) {
|
||||
if (AXIS_IS_SHAPING(X) || AXIS_IS_SHAPING(Y)) {
|
||||
const dynFreqMode_t val = dynFreqMode_t(parser.value_byte());
|
||||
switch (val) {
|
||||
#if HAS_DYNAMIC_FREQ_MM
|
||||
|
|
@ -297,7 +297,7 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Parse frequency parameter (X axis).
|
||||
if (parser.seenval('A')) {
|
||||
if (AXIS_HAS_SHAPER(X)) {
|
||||
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)) {
|
||||
|
|
@ -326,7 +326,7 @@ void GcodeSuite::M493() {
|
|||
// Parse zeta parameter (X axis).
|
||||
if (parser.seenval('I')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_HAS_SHAPER(X)) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta[0] = val;
|
||||
flag.update = true;
|
||||
|
|
@ -341,7 +341,7 @@ void GcodeSuite::M493() {
|
|||
// Parse vtol parameter (X axis).
|
||||
if (parser.seenval('Q')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_HAS_EISHAPER(X)) {
|
||||
if (AXIS_IS_EISHAPING(X)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol[0] = val;
|
||||
flag.update = true;
|
||||
|
|
@ -359,7 +359,7 @@ void GcodeSuite::M493() {
|
|||
|
||||
// Parse frequency parameter (Y axis).
|
||||
if (parser.seenval('B')) {
|
||||
if (AXIS_HAS_SHAPER(Y)) {
|
||||
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;
|
||||
|
|
@ -387,7 +387,7 @@ void GcodeSuite::M493() {
|
|||
// Parse zeta parameter (Y axis).
|
||||
if (parser.seenval('J')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_HAS_SHAPER(Y)) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
if (WITHIN(val, 0.01f, 1.0f)) {
|
||||
ftMotion.cfg.zeta[1] = val;
|
||||
flag.update = true;
|
||||
|
|
@ -402,7 +402,7 @@ void GcodeSuite::M493() {
|
|||
// Parse vtol parameter (Y axis).
|
||||
if (parser.seenval('R')) {
|
||||
const float val = parser.value_float();
|
||||
if (AXIS_HAS_EISHAPER(Y)) {
|
||||
if (AXIS_IS_EISHAPING(Y)) {
|
||||
if (WITHIN(val, 0.00f, 1.0f)) {
|
||||
ftMotion.cfg.vtol[1] = val;
|
||||
flag.update = true;
|
||||
|
|
|
|||
|
|
@ -95,15 +95,16 @@ void GcodeSuite::M920() {
|
|||
void GcodeSuite::M920_report(const bool forReplay/*=true*/) {
|
||||
TERN_(MARLIN_SMALL_BUILD, return);
|
||||
|
||||
report_heading(forReplay, F(STR_HOMING_CURRENT));
|
||||
|
||||
auto say_M920 = [](const bool forReplay, int8_t index=-1) {
|
||||
report_echo_start(forReplay);
|
||||
SERIAL_ECHOPGM(" M920");
|
||||
if (index >= 0) SERIAL_ECHOPGM(" " I_PARAM_STR, index);
|
||||
};
|
||||
|
||||
#if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS
|
||||
|
||||
report_heading(forReplay, F(STR_HOMING_CURRENT));
|
||||
|
||||
auto say_M920 = [](const bool forReplay, int8_t index=-1) {
|
||||
report_echo_start(forReplay);
|
||||
SERIAL_ECHOPGM(" M920");
|
||||
if (index >= 0) SERIAL_ECHOPGM(" " I_PARAM_STR, index);
|
||||
};
|
||||
|
||||
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS || Z3_SENSORLESS || Z4_SENSORLESS
|
||||
say_M920(forReplay, 0);
|
||||
#else
|
||||
|
|
@ -123,23 +124,26 @@ void GcodeSuite::M920_report(const bool forReplay/*=true*/) {
|
|||
TERN_(V_SENSORLESS, SERIAL_ECHOPGM_P(SP_V_STR, homing_current_mA.V));
|
||||
TERN_(W_SENSORLESS, SERIAL_ECHOPGM_P(SP_W_STR, homing_current_mA.W));
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS
|
||||
say_M920(forReplay, 1);
|
||||
TERN_(X2_SENSORLESS, SERIAL_ECHOPGM_P(SP_X_STR, homing_current_mA.X2));
|
||||
TERN_(Y2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Y_STR, homing_current_mA.Y2));
|
||||
TERN_(Z2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Z_STR, homing_current_mA.Z2));
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
#if Z3_SENSORLESS
|
||||
say_M920(forReplay, 2);
|
||||
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z3);
|
||||
#endif
|
||||
#if Z4_SENSORLESS
|
||||
say_M920(forReplay, 3);
|
||||
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z4);
|
||||
#endif
|
||||
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS
|
||||
say_M920(forReplay, 1);
|
||||
TERN_(X2_SENSORLESS, SERIAL_ECHOPGM_P(SP_X_STR, homing_current_mA.X2));
|
||||
TERN_(Y2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Y_STR, homing_current_mA.Y2));
|
||||
TERN_(Z2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Z_STR, homing_current_mA.Z2));
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if Z3_SENSORLESS
|
||||
say_M920(forReplay, 2);
|
||||
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z3);
|
||||
#endif
|
||||
|
||||
#if Z4_SENSORLESS
|
||||
say_M920(forReplay, 3);
|
||||
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z4);
|
||||
#endif
|
||||
|
||||
#endif // X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS
|
||||
}
|
||||
|
||||
#endif // EDITABLE_HOMING_CURRENT
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ void menu_move() {
|
|||
|
||||
#include "../../module/ft_motion.h"
|
||||
|
||||
FSTR_P get_shaper_name(const AxisEnum axis=X_AXIS) {
|
||||
FSTR_P get_shaper_name(const AxisEnum axis) {
|
||||
switch (ftMotion.cfg.shaper[axis]) {
|
||||
default: return nullptr;
|
||||
case ftMotionShaper_NONE: return GET_TEXT_F(MSG_LCD_OFF);
|
||||
|
|
@ -457,20 +457,20 @@ void menu_move() {
|
|||
#if HAS_X_AXIS
|
||||
SUBMENU_N_S(X_AXIS, _shaper_name(X_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
|
||||
|
||||
if (AXIS_HAS_SHAPER(X)) {
|
||||
if (AXIS_IS_SHAPING(X)) {
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq.x, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.update_shaping_params);
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_ZETA_N, &c.zeta.x, 0.0f, 1.0f, ftMotion.update_shaping_params);
|
||||
if (AXIS_HAS_EISHAPER(X))
|
||||
if (AXIS_IS_EISHAPING(X))
|
||||
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_VTOL_N, &c.vtol.x, 0.0f, 1.0f, ftMotion.update_shaping_params);
|
||||
}
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
SUBMENU_N_S(Y_AXIS, _shaper_name(Y_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
|
||||
|
||||
if (AXIS_HAS_SHAPER(Y)) {
|
||||
if (AXIS_IS_SHAPING(Y)) {
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq.y, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.update_shaping_params);
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_ZETA_N, &c.zeta.y, 0.0f, 1.0f, ftMotion.update_shaping_params);
|
||||
if (AXIS_HAS_EISHAPER(Y))
|
||||
if (AXIS_IS_EISHAPING(Y))
|
||||
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_VTOL_N, &c.vtol.y, 0.0f, 1.0f, ftMotion.update_shaping_params);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -269,11 +269,8 @@ void FTMotion::loop() {
|
|||
Ai[2] = Ai[0] * K2;
|
||||
|
||||
const float adj = 1.0f / (Ai[0] + Ai[1] + Ai[2]);
|
||||
for (uint32_t i = 0U; i < 3U; i++) {
|
||||
Ai[i] *= adj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (uint32_t i = 0; i < 3U; i++) Ai[i] *= adj;
|
||||
} break;
|
||||
|
||||
case ftMotionShaper_2HEI: {
|
||||
max_i = 3U;
|
||||
|
|
@ -285,11 +282,8 @@ void FTMotion::loop() {
|
|||
Ai[3] = Ai[0] * K3;
|
||||
|
||||
const float adj = 1.0f / (Ai[0] + Ai[1] + Ai[2] + Ai[3]);
|
||||
for (uint32_t i = 0U; i < 4U; i++) {
|
||||
Ai[i] *= adj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (uint32_t i = 0; i < 4U; i++) Ai[i] *= adj;
|
||||
} break;
|
||||
|
||||
case ftMotionShaper_3HEI: {
|
||||
max_i = 4U;
|
||||
|
|
@ -300,11 +294,8 @@ void FTMotion::loop() {
|
|||
Ai[4] = Ai[0] * K4;
|
||||
|
||||
const float adj = 1.0f / (Ai[0] + Ai[1] + Ai[2] + Ai[3] + Ai[4]);
|
||||
for (uint32_t i = 0U; i < 5U; i++) {
|
||||
Ai[i] *= adj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (uint32_t i = 0; i < 5U; i++) Ai[i] *= adj;
|
||||
} break;
|
||||
|
||||
case ftMotionShaper_MZV: {
|
||||
max_i = 2U;
|
||||
|
|
@ -358,13 +349,13 @@ void FTMotion::loop() {
|
|||
|
||||
void FTMotion::update_shaping_params() {
|
||||
#if HAS_X_AXIS
|
||||
if ((shaping.x.ena = AXIS_HAS_SHAPER(X))) {
|
||||
if ((shaping.x.ena = AXIS_IS_SHAPING(X))) {
|
||||
shaping.x.set_axis_shaping_A(cfg.shaper.x, cfg.zeta.x, cfg.vtol.x);
|
||||
shaping.x.set_axis_shaping_N(cfg.shaper.x, cfg.baseFreq.x, cfg.zeta.x);
|
||||
}
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if ((shaping.y.ena = AXIS_HAS_SHAPER(Y))) {
|
||||
if ((shaping.y.ena = AXIS_IS_SHAPING(Y))) {
|
||||
shaping.y.set_axis_shaping_A(cfg.shaper.y, cfg.zeta.y, cfg.vtol.y);
|
||||
shaping.y.set_axis_shaping_N(cfg.shaper.y, cfg.baseFreq.y, cfg.zeta.y);
|
||||
}
|
||||
|
|
@ -663,6 +654,7 @@ void FTMotion::generateTrajectoryPointsFromBlock() {
|
|||
}
|
||||
#endif
|
||||
if (++shaping.zi_idx == (FTM_ZMAX)) shaping.zi_idx = 0;
|
||||
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
// Filled up the queue with regular and shaped steps
|
||||
|
|
|
|||
|
|
@ -56,12 +56,14 @@ typedef struct FTConfig {
|
|||
#else
|
||||
static constexpr dynFreqMode_t dynFreqMode = dynFreqMode_DISABLED;
|
||||
#endif
|
||||
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
bool linearAdvEna = FTM_LINEAR_ADV_DEFAULT_ENA; // Linear advance enable configuration.
|
||||
float linearAdvK = FTM_LINEAR_ADV_DEFAULT_K; // Linear advance gain.
|
||||
#endif
|
||||
|
||||
} ft_config_t;
|
||||
|
||||
class FTMotion {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ enum dynFreqMode_t : uint8_t {
|
|||
dynFreqMode_MASS_BASED = 2
|
||||
};
|
||||
|
||||
#define AXIS_HAS_SHAPER(A) (ftMotion.cfg.shaper[_AXIS(A)] != ftMotionShaper_NONE)
|
||||
#define AXIS_HAS_EISHAPER(A) WITHIN(ftMotion.cfg.shaper[_AXIS(A)], ftMotionShaper_EI, ftMotionShaper_3HEI)
|
||||
#define AXIS_IS_SHAPING(A) (ftMotion.cfg.shaper[_AXIS(A)] != ftMotionShaper_NONE)
|
||||
#define AXIS_IS_EISHAPING(A) WITHIN(ftMotion.cfg.shaper[_AXIS(A)], ftMotionShaper_EI, ftMotionShaper_3HEI)
|
||||
|
||||
typedef struct XYZEarray<float, FTM_WINDOW_SIZE> xyze_trajectory_t;
|
||||
typedef struct XYZEarray<float, FTM_BATCH_SIZE> xyze_trajectoryMod_t;
|
||||
|
|
|
|||
|
|
@ -3007,7 +3007,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
static int32_t smoothed_vals[SMOOTH_LIN_ADV_EXP_ORDER] = {0};
|
||||
|
||||
for (uint8_t i = 0; i < SMOOTH_LIN_ADV_EXP_ORDER; i++) {
|
||||
// Approximate gaussian smoothing via higher order exponential smoothing
|
||||
// Approximate Gaussian smoothing via higher order exponential smoothing
|
||||
smoothed_vals[i] += MULT_Q(30, la_step_rate - smoothed_vals[i], extruder_advance_alpha_q30[E_INDEX_N(active_extruder)]);
|
||||
la_step_rate = smoothed_vals[i];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue