mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-26 13:25:54 +00:00
🔧🚸 FT_MOTION adjustments (#27359)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
02ed020f3f
commit
3abe1fcf20
@ -1127,8 +1127,8 @@
|
||||
#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_X_FREQ 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#define FTM_SHAPING_DEFAULT_Y_FREQ 37.0f // (Hz) Default peak frequency used by input shapers
|
||||
#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 // Default linear advance gain, integer value. (Acceleration-based scaling factor.)
|
||||
#define FTM_SHAPING_ZETA_X 0.1f // Zeta used by input shapers for X axis
|
||||
|
@ -752,11 +752,11 @@
|
||||
#ifndef FTM_DEFAULT_SHAPER_Y
|
||||
#define FTM_DEFAULT_SHAPER_Y ftMotionShaper_NONE
|
||||
#endif
|
||||
#ifndef FTM_SHAPING_DEFAULT_X_FREQ
|
||||
#define FTM_SHAPING_DEFAULT_X_FREQ 37.0f
|
||||
#ifndef FTM_SHAPING_DEFAULT_FREQ_X
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_X 37.0f
|
||||
#endif
|
||||
#ifndef FTM_SHAPING_DEFAULT_Y_FREQ
|
||||
#define FTM_SHAPING_DEFAULT_Y_FREQ 37.0f
|
||||
#ifndef FTM_SHAPING_DEFAULT_FREQ_Y
|
||||
#define FTM_SHAPING_DEFAULT_FREQ_Y 37.0f
|
||||
#endif
|
||||
#ifndef FTM_LINEAR_ADV_DEFAULT_ENA
|
||||
#define FTM_LINEAR_ADV_DEFAULT_ENA false
|
||||
|
@ -701,6 +701,8 @@
|
||||
#error "CALIBRATION_MEASUREMENT_RESOLUTION is no longer needed and should be removed."
|
||||
#elif defined(MMU2_MENUS)
|
||||
#error "MMU2_MENUS is now MMU_MENUS."
|
||||
#elif defined(FTM_SHAPING_DEFAULT_X_FREQ) || defined(FTM_SHAPING_DEFAULT_Y_FREQ)
|
||||
#error "FTM_SHAPING_DEFAULT_[XY]_FREQ is now FTM_SHAPING_DEFAULT_FREQ_[XY]."
|
||||
#endif
|
||||
|
||||
// Changes to Probe Temp Compensation (#17392)
|
||||
|
@ -1396,9 +1396,14 @@
|
||||
#endif
|
||||
|
||||
// FT Motion unified window and batch size
|
||||
#if ALL(FT_MOTION, FTM_UNIFIED_BWS)
|
||||
#define FTM_WINDOW_SIZE FTM_BW_SIZE
|
||||
#define FTM_BATCH_SIZE FTM_BW_SIZE
|
||||
#if ENABLED(FT_MOTION)
|
||||
#if HAS_X_AXIS
|
||||
#define HAS_FTM_SHAPING 1
|
||||
#endif
|
||||
#if ENABLED(FTM_UNIFIED_BWS)
|
||||
#define FTM_WINDOW_SIZE FTM_BW_SIZE
|
||||
#define FTM_BATCH_SIZE FTM_BW_SIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Toolchange Event G-code
|
||||
|
@ -44,6 +44,9 @@
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
// Always show configurable options regardless of FT Motion active
|
||||
//#define FT_MOTION_NO_MENU_TOGGLE
|
||||
|
||||
constexpr bool has_large_area() {
|
||||
return TERN0(HAS_X_AXIS, (X_BED_SIZE) >= 1000) || TERN0(HAS_Y_AXIS, (Y_BED_SIZE) >= 1000) || TERN0(HAS_Z_AXIS, (Z_MAX_POS) >= 1000);
|
||||
}
|
||||
@ -323,7 +326,6 @@ void menu_move() {
|
||||
#if ENABLED(FT_MOTION_MENU)
|
||||
|
||||
#include "../../module/ft_motion.h"
|
||||
#include "../../gcode/gcode.h"
|
||||
|
||||
FSTR_P get_shaper_name(const AxisEnum axis=X_AXIS) {
|
||||
switch (ftMotion.cfg.shaper[axis]) {
|
||||
@ -436,7 +438,8 @@ void menu_move() {
|
||||
ftMotion.update_shaping_params();
|
||||
});
|
||||
|
||||
if (c.active) {
|
||||
// Show only when FT Motion is active (or optionally always show)
|
||||
if (c.active || ENABLED(FT_MOTION_NO_MENU_TOGGLE)) {
|
||||
#if HAS_X_AXIS
|
||||
SUBMENU_N(X_AXIS, MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
|
||||
MENU_ITEM_ADDON_START_RJ(5); lcd_put_u8str(shaper_name[X_AXIS]); MENU_ITEM_ADDON_END();
|
||||
@ -475,7 +478,8 @@ void menu_move() {
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &c.linearAdvEna);
|
||||
if (c.linearAdvEna) EDIT_ITEM(float42_52, MSG_ADVANCE_K, &c.linearAdvK, 0, 10);
|
||||
if (c.linearAdvEna || ENABLED(FT_MOTION_NO_MENU_TOGGLE))
|
||||
EDIT_ITEM(float42_52, MSG_ADVANCE_K, &c.linearAdvK, 0, 10);
|
||||
#endif
|
||||
}
|
||||
END_MENU();
|
||||
@ -492,6 +496,10 @@ void menu_move() {
|
||||
MString<20> dmode = get_dyn_freq_mode_name();
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
ft_config_t &c = ftMotion.cfg;
|
||||
#endif
|
||||
|
||||
START_MENU();
|
||||
|
||||
#if HAS_X_AXIS
|
||||
@ -502,13 +510,14 @@ void menu_move() {
|
||||
SUBMENU_N(Y_AXIS, MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
|
||||
MENU_ITEM_ADDON_START_RJ(5); lcd_put_u8str(shaper_name[Y_AXIS]); MENU_ITEM_ADDON_END();
|
||||
#endif
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
SUBMENU(MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
|
||||
MENU_ITEM_ADDON_START_RJ(dmode.length()); lcd_put_u8str(dmode); MENU_ITEM_ADDON_END();
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &ftMotion.cfg.linearAdvEna);
|
||||
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &c.linearAdvEna);
|
||||
if (c.linearAdvEna || ENABLED(FT_MOTION_NO_MENU_TOGGLE))
|
||||
EDIT_ITEM(float42_52, MSG_ADVANCE_K, &c.linearAdvK, 0, 10);
|
||||
#endif
|
||||
|
||||
END_MENU();
|
||||
|
@ -90,12 +90,14 @@ xyze_long_t FTMotion::steps = { 0 }; // Step count accumulator.
|
||||
uint32_t FTMotion::interpIdx = 0; // Index of current data point being interpolated.
|
||||
|
||||
// Shaping variables.
|
||||
#if HAS_X_AXIS
|
||||
#if HAS_FTM_SHAPING
|
||||
FTMotion::shaping_t FTMotion::shaping = {
|
||||
0,
|
||||
x:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 }, // ena, d_zi[], Ai[], Ni[], max_i
|
||||
#if HAS_X_AXIS
|
||||
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 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
y:{ false, { 0.0f }, { 0.0f }, { 0 }, 0 } // ena, d_zi[], Ai[], Ni[], max_i
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@ -210,7 +212,7 @@ void FTMotion::loop() {
|
||||
|
||||
}
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#if HAS_FTM_SHAPING
|
||||
|
||||
// Refresh the gains used by shaping functions.
|
||||
void FTMotion::AxisShaping::set_axis_shaping_A(const ftMotionShaper_t shaper, const_float_t zeta, const_float_t vtol) {
|
||||
@ -361,7 +363,7 @@ void FTMotion::loop() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_X_AXIS
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
// Reset all trajectory processing variables.
|
||||
void FTMotion::reset() {
|
||||
@ -382,8 +384,8 @@ void FTMotion::reset() {
|
||||
|
||||
stepper.axis_did_move.reset();
|
||||
|
||||
#if HAS_X_AXIS
|
||||
ZERO(shaping.x.d_zi);
|
||||
#if HAS_FTM_SHAPING
|
||||
TERN_(HAS_X_AXIS, ZERO(shaping.x.d_zi));
|
||||
TERN_(HAS_Y_AXIS, ZERO(shaping.y.d_zi));
|
||||
shaping.zi_idx = 0;
|
||||
#endif
|
||||
@ -652,15 +654,17 @@ void FTMotion::makeVector() {
|
||||
}
|
||||
|
||||
// Apply shaping if active on each axis
|
||||
#if HAS_X_AXIS
|
||||
if (shaping.x.ena) {
|
||||
shaping.x.d_zi[shaping.zi_idx] = traj.x[makeVector_batchIdx];
|
||||
traj.x[makeVector_batchIdx] *= shaping.x.Ai[0];
|
||||
for (uint32_t i = 1U; i <= shaping.x.max_i; i++) {
|
||||
const uint32_t udiffx = shaping.zi_idx - shaping.x.Ni[i];
|
||||
traj.x[makeVector_batchIdx] += shaping.x.Ai[i] * shaping.x.d_zi[shaping.x.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffx : udiffx];
|
||||
#if HAS_FTM_SHAPING
|
||||
#if HAS_X_AXIS
|
||||
if (shaping.x.ena) {
|
||||
shaping.x.d_zi[shaping.zi_idx] = traj.x[makeVector_batchIdx];
|
||||
traj.x[makeVector_batchIdx] *= shaping.x.Ai[0];
|
||||
for (uint32_t i = 1U; i <= shaping.x.max_i; i++) {
|
||||
const uint32_t udiffx = shaping.zi_idx - shaping.x.Ni[i];
|
||||
traj.x[makeVector_batchIdx] += shaping.x.Ai[i] * shaping.x.d_zi[shaping.x.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffx : udiffx];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
if (shaping.y.ena) {
|
||||
@ -673,7 +677,7 @@ void FTMotion::makeVector() {
|
||||
}
|
||||
#endif
|
||||
if (++shaping.zi_idx == (FTM_ZMAX)) shaping.zi_idx = 0;
|
||||
#endif // HAS_X_AXIS
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
// Filled up the queue with regular and shaped steps
|
||||
if (++makeVector_batchIdx == FTM_WINDOW_SIZE) {
|
||||
|
@ -40,23 +40,23 @@
|
||||
typedef struct FTConfig {
|
||||
bool active = ENABLED(FTM_IS_DEFAULT_MOTION); // Active (else standard motion)
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#if HAS_FTM_SHAPING
|
||||
ft_shaped_shaper_t shaper = // Shaper type
|
||||
{ SHAPED_ELEM(FTM_DEFAULT_SHAPER_X, FTM_DEFAULT_SHAPER_Y) };
|
||||
ft_shaped_float_t baseFreq = // Base frequency. [Hz]
|
||||
{ SHAPED_ELEM(FTM_SHAPING_DEFAULT_X_FREQ, FTM_SHAPING_DEFAULT_Y_FREQ) };
|
||||
{ SHAPED_ELEM(FTM_SHAPING_DEFAULT_FREQ_X, FTM_SHAPING_DEFAULT_FREQ_Y) };
|
||||
ft_shaped_float_t zeta = // Damping factor
|
||||
{ SHAPED_ELEM(FTM_SHAPING_ZETA_X, FTM_SHAPING_ZETA_Y) };
|
||||
ft_shaped_float_t vtol = // Vibration Level
|
||||
{ SHAPED_ELEM(FTM_SHAPING_V_TOL_X, FTM_SHAPING_V_TOL_Y) };
|
||||
#endif
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
dynFreqMode_t dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE; // Dynamic frequency mode configuration.
|
||||
ft_shaped_float_t dynFreqK = { 0.0f }; // Scaling / gain for dynamic frequency. [Hz/mm] or [Hz/g]
|
||||
#else
|
||||
static constexpr dynFreqMode_t dynFreqMode = dynFreqMode_DISABLED;
|
||||
#endif
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
dynFreqMode_t dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE; // Dynamic frequency mode configuration.
|
||||
ft_shaped_float_t dynFreqK = { 0.0f }; // Scaling / gain for dynamic frequency. [Hz/mm] or [Hz/g]
|
||||
#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.
|
||||
@ -75,33 +75,37 @@ class FTMotion {
|
||||
static void set_defaults() {
|
||||
cfg.active = ENABLED(FTM_IS_DEFAULT_MOTION);
|
||||
|
||||
#if HAS_X_AXIS
|
||||
cfg.shaper.x = FTM_DEFAULT_SHAPER_X;
|
||||
cfg.baseFreq.x = FTM_SHAPING_DEFAULT_X_FREQ;
|
||||
cfg.zeta.x = FTM_SHAPING_ZETA_X;
|
||||
cfg.vtol.x = FTM_SHAPING_V_TOL_X;
|
||||
#endif
|
||||
#if HAS_FTM_SHAPING
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
cfg.shaper.y = FTM_DEFAULT_SHAPER_Y;
|
||||
cfg.baseFreq.y = FTM_SHAPING_DEFAULT_Y_FREQ;
|
||||
cfg.zeta.y = FTM_SHAPING_ZETA_Y;
|
||||
cfg.vtol.y = FTM_SHAPING_V_TOL_Y;
|
||||
#endif
|
||||
#if HAS_X_AXIS
|
||||
cfg.shaper.x = FTM_DEFAULT_SHAPER_X;
|
||||
cfg.baseFreq.x = FTM_SHAPING_DEFAULT_FREQ_X;
|
||||
cfg.zeta.x = FTM_SHAPING_ZETA_X;
|
||||
cfg.vtol.x = FTM_SHAPING_V_TOL_X;
|
||||
#endif
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
cfg.dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE;
|
||||
TERN_(HAS_X_AXIS, cfg.dynFreqK.x = 0.0f);
|
||||
TERN_(HAS_Y_AXIS, cfg.dynFreqK.y = 0.0f);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
cfg.shaper.y = FTM_DEFAULT_SHAPER_Y;
|
||||
cfg.baseFreq.y = FTM_SHAPING_DEFAULT_FREQ_Y;
|
||||
cfg.zeta.y = FTM_SHAPING_ZETA_Y;
|
||||
cfg.vtol.y = FTM_SHAPING_V_TOL_Y;
|
||||
#endif
|
||||
|
||||
#if HAS_DYNAMIC_FREQ
|
||||
cfg.dynFreqMode = FTM_DEFAULT_DYNFREQ_MODE;
|
||||
TERN_(HAS_X_AXIS, cfg.dynFreqK.x = 0.0f);
|
||||
TERN_(HAS_Y_AXIS, cfg.dynFreqK.y = 0.0f);
|
||||
#endif
|
||||
|
||||
update_shaping_params();
|
||||
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
cfg.linearAdvEna = FTM_LINEAR_ADV_DEFAULT_ENA;
|
||||
cfg.linearAdvK = FTM_LINEAR_ADV_DEFAULT_K;
|
||||
#endif
|
||||
|
||||
TERN_(HAS_X_AXIS, update_shaping_params());
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
@ -118,7 +122,7 @@ class FTMotion {
|
||||
static void init();
|
||||
static void loop(); // Controller main, to be invoked from non-isr task.
|
||||
|
||||
#if HAS_X_AXIS
|
||||
#if HAS_FTM_SHAPING
|
||||
// Refresh gains and indices used by shaping functions.
|
||||
static void update_shaping_params(void);
|
||||
#endif
|
||||
@ -166,7 +170,7 @@ class FTMotion {
|
||||
static xyze_long_t steps;
|
||||
|
||||
// Shaping variables.
|
||||
#if HAS_X_AXIS
|
||||
#if HAS_FTM_SHAPING
|
||||
|
||||
typedef struct AxisShaping {
|
||||
bool ena = false; // Enabled indication.
|
||||
@ -182,16 +186,17 @@ class FTMotion {
|
||||
|
||||
typedef struct Shaping {
|
||||
uint32_t zi_idx; // Index of storage in the data point delay vectors.
|
||||
axis_shaping_t x;
|
||||
#if HAS_X_AXIS
|
||||
axis_shaping_t x;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
axis_shaping_t y;
|
||||
#endif
|
||||
|
||||
} shaping_t;
|
||||
|
||||
static shaping_t shaping; // Shaping data
|
||||
|
||||
#endif // HAS_X_AXIS
|
||||
#endif // HAS_FTM_SHAPING
|
||||
|
||||
// Linear advance variables.
|
||||
#if HAS_EXTRUDERS
|
||||
|
@ -58,8 +58,13 @@ enum {
|
||||
FT_BIT_COUNT
|
||||
};
|
||||
|
||||
#define NUM_AXES_SHAPED TERN(HAS_Y_AXIS, 2, 1)
|
||||
#define SHAPED_ELEM(A, B) A OPTARG(HAS_Y_AXIS, B)
|
||||
#if HAS_FTM_SHAPING
|
||||
#define NUM_AXES_SHAPED TERN(HAS_Y_AXIS, 2, 1)
|
||||
#define SHAPED_ELEM(A, B) A OPTARG(HAS_Y_AXIS, B)
|
||||
#else
|
||||
#define NUM_AXES_SHAPED 0
|
||||
#define SHAPED_ELEM(A, B)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct FTShapedAxes {
|
||||
|
Loading…
Reference in New Issue
Block a user