Skip to content

Commit ba91fa0

Browse files
authored
⚡️ Optimize FT_MOTION (MarlinFirmware#26557)
1 parent 1aeee2c commit ba91fa0

File tree

3 files changed

+46
-52
lines changed

3 files changed

+46
-52
lines changed

Marlin/src/module/ft_motion.cpp

+44-47
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ FTMotion ftMotion;
4646
static_assert(FTM_DEFAULT_DYNFREQ_MODE != dynFreqMode_MASS_BASED, "dynFreqMode_MASS_BASED requires an X axis and an extruder.");
4747
#endif
4848

49-
//-----------------------------------------------------------------//
49+
//-----------------------------------------------------------------
5050
// Variables.
51-
//-----------------------------------------------------------------//
51+
//-----------------------------------------------------------------
5252

5353
// Public variables.
5454

@@ -61,10 +61,10 @@ uint32_t FTMotion::stepperCmdBuff_produceIdx = 0, // Index of next stepper comma
6161
bool FTMotion::sts_stepperBusy = false; // The stepper buffer has items and is in use.
6262

6363
// Private variables.
64+
6465
// NOTE: These are sized for Ulendo FBS use.
65-
xyze_trajectory_t FTMotion::traj; // = {0.0f} Storage for fixed-time-based trajectory.
66-
xyze_trajectoryMod_t FTMotion::trajMod; // = {0.0f} Storage for modified fixed-time-based trajectory.
67-
xyze_trajectoryWin_t FTMotion::trajWin; // = {0.0f} Storage for fixed time trajectory window.
66+
xyze_trajectory_t FTMotion::traj; // = {0.0f} Storage for fixed-time-based trajectory.
67+
xyze_trajectoryMod_t FTMotion::trajMod; // = {0.0f} Storage for fixed time trajectory window.
6868

6969
bool FTMotion::blockProcRdy = false, // Indicates a block is ready to be processed.
7070
FTMotion::blockProcRdy_z1 = false, // Storage for the previous indicator.
@@ -96,23 +96,23 @@ uint32_t FTMotion::N1, // Number of data points in the
9696
uint32_t FTMotion::max_intervals; // Total number of data points that will be generated from block.
9797

9898
// Make vector variables.
99-
uint32_t FTMotion::makeVector_idx = 0, // Index of fixed time trajectory generation of the overall block.
100-
FTMotion::makeVector_idx_z1 = 0, // Storage for the previously calculated index above.
101-
FTMotion::makeVector_batchIdx = 0; // Index of fixed time trajectory generation within the batch.
99+
uint32_t FTMotion::makeVector_idx = 0, // Index of fixed time trajectory generation of the overall block.
100+
FTMotion::makeVector_idx_z1 = 0, // Storage for the previously calculated index above.
101+
FTMotion::makeVector_batchIdx = 0; // Index of fixed time trajectory generation within the batch.
102102

103103
// Interpolation variables.
104-
xyze_long_t FTMotion::steps = { 0 }; // Step count accumulator.
104+
xyze_long_t FTMotion::steps = { 0 }; // Step count accumulator.
105105

106-
uint32_t FTMotion::interpIdx = 0, // Index of current data point being interpolated.
107-
FTMotion::interpIdx_z1 = 0; // Storage for the previously calculated index above.
106+
uint32_t FTMotion::interpIdx = 0, // Index of current data point being interpolated.
107+
FTMotion::interpIdx_z1 = 0; // Storage for the previously calculated index above.
108108

109109
// Shaping variables.
110110
#if HAS_X_AXIS
111111
FTMotion::shaping_t FTMotion::shaping = {
112112
0, 0,
113-
x:{ { 0.0f }, { 0.0f }, { 0 } }, // d_zi, Ai, Ni
113+
x:{ { 0.0f }, { 0.0f }, { 0 } }, // d_zi, Ai, Ni
114114
#if HAS_Y_AXIS
115-
y:{ { 0.0f }, { 0.0f }, { 0 } } // d_zi, Ai, Ni
115+
y:{ { 0.0f }, { 0.0f }, { 0 } } // d_zi, Ai, Ni
116116
#endif
117117
};
118118
#endif
@@ -123,9 +123,9 @@ uint32_t FTMotion::interpIdx = 0, // Index of current data p
123123
float FTMotion::e_advanced_z1 = 0.0f; // (ms) Unit delay of advanced extruder position.
124124
#endif
125125

126-
//-----------------------------------------------------------------//
126+
//-----------------------------------------------------------------
127127
// Function definitions.
128-
//-----------------------------------------------------------------//
128+
//-----------------------------------------------------------------
129129

130130
// Public functions.
131131

@@ -186,8 +186,7 @@ void FTMotion::loop() {
186186
// Call Ulendo FBS here.
187187

188188
#if ENABLED(FTM_UNIFIED_BWS)
189-
trajMod = traj; // Copy the uncompensated vectors.
190-
traj = trajWin; // Move the window to traj
189+
trajMod = traj; // Move the window to traj
191190
#else
192191
// Copy the uncompensated vectors.
193192
#define TCOPY(A) memcpy(trajMod.A, traj.A, sizeof(trajMod.A))
@@ -199,7 +198,7 @@ void FTMotion::loop() {
199198
);
200199

201200
// Shift the time series back in the window
202-
#define TSHIFT(A) memcpy(traj.A, trajWin.A, sizeof(trajWin.A))
201+
#define TSHIFT(A) memcpy(traj.A, &traj.A[FTM_BATCH_SIZE], (FTM_WINDOW_SIZE - FTM_BATCH_SIZE) * sizeof(traj.A[0]))
203202
LOGICAL_AXIS_CODE(
204203
TSHIFT(e),
205204
TSHIFT(x), TSHIFT(y), TSHIFT(z),
@@ -215,12 +214,11 @@ void FTMotion::loop() {
215214
}
216215

217216
// Interpolation.
218-
while ( batchRdyForInterp
219-
&& ( stepperCmdBuffItems() < (FTM_STEPPERCMD_BUFF_SIZE) - (FTM_STEPS_PER_UNIT_TIME) )
220-
&& ( interpIdx - interpIdx_z1 < (FTM_STEPS_PER_LOOP) )
217+
while (batchRdyForInterp
218+
&& (stepperCmdBuffItems() < (FTM_STEPPERCMD_BUFF_SIZE) - (FTM_STEPS_PER_UNIT_TIME))
219+
&& (interpIdx - interpIdx_z1 < (FTM_STEPS_PER_LOOP))
221220
) {
222221
convertToSteps(interpIdx);
223-
224222
if (++interpIdx == TERN(FTM_UNIFIED_BWS, FTM_BW_SIZE, FTM_BATCH_SIZE)) {
225223
batchRdyForInterp = false;
226224
interpIdx = 0;
@@ -443,7 +441,6 @@ void FTMotion::reset() {
443441
stepperCmdBuff_produceIdx = stepperCmdBuff_consumeIdx = 0;
444442

445443
traj.reset();
446-
trajWin.reset();
447444

448445
blockProcRdy = blockProcRdy_z1 = blockProcDn = false;
449446
batchRdy = batchRdyForInterp = false;
@@ -611,26 +608,26 @@ void FTMotion::makeVector() {
611608
}
612609

613610
LOGICAL_AXIS_CODE(
614-
trajWin.e[makeVector_batchIdx] = startPosn.e + ratio.e * dist,
615-
trajWin.x[makeVector_batchIdx] = startPosn.x + ratio.x * dist,
616-
trajWin.y[makeVector_batchIdx] = startPosn.y + ratio.y * dist,
617-
trajWin.z[makeVector_batchIdx] = startPosn.z + ratio.z * dist,
618-
trajWin.i[makeVector_batchIdx] = startPosn.i + ratio.i * dist,
619-
trajWin.j[makeVector_batchIdx] = startPosn.j + ratio.j * dist,
620-
trajWin.k[makeVector_batchIdx] = startPosn.k + ratio.k * dist,
621-
trajWin.u[makeVector_batchIdx] = startPosn.u + ratio.u * dist,
622-
trajWin.v[makeVector_batchIdx] = startPosn.v + ratio.v * dist,
623-
trajWin.w[makeVector_batchIdx] = startPosn.w + ratio.w * dist
611+
traj.e[makeVector_batchIdx] = startPosn.e + ratio.e * dist,
612+
traj.x[makeVector_batchIdx] = startPosn.x + ratio.x * dist,
613+
traj.y[makeVector_batchIdx] = startPosn.y + ratio.y * dist,
614+
traj.z[makeVector_batchIdx] = startPosn.z + ratio.z * dist,
615+
traj.i[makeVector_batchIdx] = startPosn.i + ratio.i * dist,
616+
traj.j[makeVector_batchIdx] = startPosn.j + ratio.j * dist,
617+
traj.k[makeVector_batchIdx] = startPosn.k + ratio.k * dist,
618+
traj.u[makeVector_batchIdx] = startPosn.u + ratio.u * dist,
619+
traj.v[makeVector_batchIdx] = startPosn.v + ratio.v * dist,
620+
traj.w[makeVector_batchIdx] = startPosn.w + ratio.w * dist
624621
);
625622

626623
#if HAS_EXTRUDERS
627624
if (cfg.linearAdvEna) {
628-
float dedt_adj = (trajWin.e[makeVector_batchIdx] - e_raw_z1) * (FTM_FS);
625+
float dedt_adj = (traj.e[makeVector_batchIdx] - e_raw_z1) * (FTM_FS);
629626
if (ratio.e > 0.0f) dedt_adj += accel_k * cfg.linearAdvK;
630627

631-
e_raw_z1 = trajWin.e[makeVector_batchIdx];
628+
e_raw_z1 = traj.e[makeVector_batchIdx];
632629
e_advanced_z1 += dedt_adj * (FTM_TS);
633-
trajWin.e[makeVector_batchIdx] = e_advanced_z1;
630+
traj.e[makeVector_batchIdx] = e_advanced_z1;
634631
}
635632
#endif
636633

@@ -640,9 +637,9 @@ void FTMotion::makeVector() {
640637

641638
#if HAS_DYNAMIC_FREQ_MM
642639
case dynFreqMode_Z_BASED:
643-
if (trajWin.z[makeVector_batchIdx] != 0.0f) { // Only update if Z changed.
644-
const float xf = cfg.baseFreq[X_AXIS] + cfg.dynFreqK[X_AXIS] * trajWin.z[makeVector_batchIdx]
645-
OPTARG(HAS_Y_AXIS, yf = cfg.baseFreq[Y_AXIS] + cfg.dynFreqK[Y_AXIS] * trajWin.z[makeVector_batchIdx]);
640+
if (traj.z[makeVector_batchIdx] != 0.0f) { // Only update if Z changed.
641+
const float xf = cfg.baseFreq[X_AXIS] + cfg.dynFreqK[X_AXIS] * traj.z[makeVector_batchIdx]
642+
OPTARG(HAS_Y_AXIS, yf = cfg.baseFreq[Y_AXIS] + cfg.dynFreqK[Y_AXIS] * traj.z[makeVector_batchIdx]);
646643
updateShapingN(_MAX(xf, FTM_MIN_SHAPE_FREQ) OPTARG(HAS_Y_AXIS, _MAX(yf, FTM_MIN_SHAPE_FREQ)));
647644
}
648645
break;
@@ -652,8 +649,8 @@ void FTMotion::makeVector() {
652649
case dynFreqMode_MASS_BASED:
653650
// Update constantly. The optimization done for Z value makes
654651
// less sense for E, as E is expected to constantly change.
655-
updateShapingN( cfg.baseFreq[X_AXIS] + cfg.dynFreqK[X_AXIS] * trajWin.e[makeVector_batchIdx]
656-
OPTARG(HAS_Y_AXIS, cfg.baseFreq[Y_AXIS] + cfg.dynFreqK[Y_AXIS] * trajWin.e[makeVector_batchIdx]) );
652+
updateShapingN( cfg.baseFreq[X_AXIS] + cfg.dynFreqK[X_AXIS] * traj.e[makeVector_batchIdx]
653+
OPTARG(HAS_Y_AXIS, cfg.baseFreq[Y_AXIS] + cfg.dynFreqK[Y_AXIS] * traj.e[makeVector_batchIdx]) );
657654
break;
658655
#endif
659656

@@ -663,18 +660,18 @@ void FTMotion::makeVector() {
663660
// Apply shaping if in mode.
664661
#if HAS_X_AXIS
665662
if (cfg.modeHasShaper()) {
666-
shaping.x.d_zi[shaping.zi_idx] = trajWin.x[makeVector_batchIdx];
667-
trajWin.x[makeVector_batchIdx] *= shaping.x.Ai[0];
663+
shaping.x.d_zi[shaping.zi_idx] = traj.x[makeVector_batchIdx];
664+
traj.x[makeVector_batchIdx] *= shaping.x.Ai[0];
668665
#if HAS_Y_AXIS
669-
shaping.y.d_zi[shaping.zi_idx] = trajWin.y[makeVector_batchIdx];
670-
trajWin.y[makeVector_batchIdx] *= shaping.y.Ai[0];
666+
shaping.y.d_zi[shaping.zi_idx] = traj.y[makeVector_batchIdx];
667+
traj.y[makeVector_batchIdx] *= shaping.y.Ai[0];
671668
#endif
672669
for (uint32_t i = 1U; i <= shaping.max_i; i++) {
673670
const uint32_t udiffx = shaping.zi_idx - shaping.x.Ni[i];
674-
trajWin.x[makeVector_batchIdx] += shaping.x.Ai[i] * shaping.x.d_zi[shaping.x.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffx : udiffx];
671+
traj.x[makeVector_batchIdx] += shaping.x.Ai[i] * shaping.x.d_zi[shaping.x.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffx : udiffx];
675672
#if HAS_Y_AXIS
676673
const uint32_t udiffy = shaping.zi_idx - shaping.y.Ni[i];
677-
trajWin.y[makeVector_batchIdx] += shaping.y.Ai[i] * shaping.y.d_zi[shaping.y.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffy : udiffy];
674+
traj.y[makeVector_batchIdx] += shaping.y.Ai[i] * shaping.y.d_zi[shaping.y.Ni[i] > shaping.zi_idx ? (FTM_ZMAX) + udiffy : udiffy];
678675
#endif
679676
}
680677
if (++shaping.zi_idx == (FTM_ZMAX)) shaping.zi_idx = 0;

Marlin/src/module/ft_motion.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ class FTMotion {
134134

135135
static xyze_trajectory_t traj;
136136
static xyze_trajectoryMod_t trajMod;
137-
static xyze_trajectoryWin_t trajWin;
138137

139138
static bool blockProcRdy, blockProcRdy_z1, blockProcDn;
140139
static bool batchRdy, batchRdyForInterp;
@@ -155,8 +154,8 @@ class FTMotion {
155154
static uint32_t max_intervals;
156155

157156
static constexpr uint32_t _ftm_size = TERN(FTM_UNIFIED_BWS, FTM_BW_SIZE, FTM_BATCH_SIZE),
158-
_ftm_wind = TERN(FTM_UNIFIED_BWS, 2, ceil((FTM_WINDOW_SIZE) / _ftm_size)),
159-
shaper_intervals = _ftm_size * ceil((FTM_ZMAX) / _ftm_size),
157+
_ftm_wind = TERN(FTM_UNIFIED_BWS, 2, CEIL((FTM_WINDOW_SIZE) / _ftm_size)),
158+
shaper_intervals = _ftm_size * CEIL((FTM_ZMAX) / _ftm_size),
160159
min_max_intervals = _ftm_size * _ftm_wind;
161160

162161
// Make vector variables.

Marlin/src/module/ft_types.h

-2
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ enum dynFreqMode_t : uint8_t {
4949
#if ENABLED(FTM_UNIFIED_BWS)
5050
typedef struct XYZEarray<float, FTM_BW_SIZE> xyze_trajectory_t;
5151
typedef struct XYZEarray<float, FTM_BW_SIZE> xyze_trajectoryMod_t;
52-
typedef struct XYZEarray<float, FTM_BW_SIZE> xyze_trajectoryWin_t;
5352
#else
5453
typedef struct XYZEarray<float, FTM_WINDOW_SIZE> xyze_trajectory_t;
5554
typedef struct XYZEarray<float, FTM_BATCH_SIZE> xyze_trajectoryMod_t;
56-
typedef struct XYZEarray<float, (FTM_WINDOW_SIZE - FTM_BATCH_SIZE)> xyze_trajectoryWin_t;
5755
#endif
5856

5957
enum {

0 commit comments

Comments
 (0)