1
0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2024-11-26 21:36:21 +00:00

🔧🚸 FT_MOTION adjustments (#27359)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
narno2202 2024-08-24 06:58:31 +02:00 committed by GitHub
parent 02ed020f3f
commit 3abe1fcf20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 95 additions and 65 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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();

View File

@ -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) {

View File

@ -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

View File

@ -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 {