Fixed-Time Motion with Input Shaping by Ulendo (#25394)

Co-authored-by: Ulendo Alex <alex@ulendo.io>
This commit is contained in:
Scott Lahteine
2023-03-31 21:18:37 -05:00
committed by GitHub
parent 8cdf43f8fd
commit c37fa3cc90
15 changed files with 1772 additions and 50 deletions

View File

@@ -69,6 +69,9 @@
#include "stepper.h"
#include "motion.h"
#include "temperature.h"
#if ENABLED(FT_MOTION)
#include "ft_motion.h"
#endif
#include "../lcd/marlinui.h"
#include "../gcode/parser.h"
@@ -112,7 +115,8 @@
// Delay for delivery of first block to the stepper ISR, if the queue contains 2 or
// fewer movements. The delay is measured in milliseconds, and must be less than 250ms
#define BLOCK_DELAY_FOR_1ST_MOVE 100
#define BLOCK_DELAY_NONE 0U
#define BLOCK_DELAY_FOR_1ST_MOVE 100U
Planner planner;
@@ -127,7 +131,7 @@ volatile uint8_t Planner::block_buffer_head, // Index of the next block to be
Planner::block_buffer_planned, // Index of the optimally planned block
Planner::block_buffer_tail; // Index of the busy block, if any
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
uint8_t Planner::delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
uint8_t Planner::delay_before_delivering; // Delay block delivery so initial blocks in an empty queue may merge
planner_settings_t Planner::settings; // Initialized by settings.load()
@@ -225,6 +229,10 @@ float Planner::previous_nominal_speed;
int32_t Planner::xy_freq_min_interval_us = LROUND(1000000.0f / (XY_FREQUENCY_LIMIT));
#endif
#if ENABLED(FT_MOTION)
bool Planner::fxdTiCtrl_busy = false;
#endif
#if ENABLED(LIN_ADVANCE)
float Planner::extruder_advance_K[DISTINCT_E]; // Initialized by settings.load()
#endif
@@ -1683,7 +1691,8 @@ void Planner::quick_stop() {
// Restart the block delay for the first movement - As the queue was
// forced to empty, there's no risk the ISR will touch this.
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg_mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
TERN_(HAS_WIRED_LCD, clear_block_buffer_runtime()); // Clear the accumulated runtime
@@ -1729,6 +1738,7 @@ bool Planner::busy() {
return (has_blocks_queued() || cleaning_buffer_counter
|| TERN0(EXTERNAL_CLOSED_LOOP_CONTROLLER, CLOSED_LOOP_WAITING())
|| TERN0(HAS_ZV_SHAPING, stepper.input_shaping_busy())
|| TERN0(FT_MOTION, fxdTiCtrl_busy)
);
}
@@ -1841,7 +1851,7 @@ bool Planner::_buffer_steps(const xyze_long_t &target
// As there are no queued movements, the Stepper ISR will not touch this
// variable, so there is no risk setting this here (but it MUST be done
// before the following line!!)
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg_mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
}
// Move buffer head
@@ -2945,7 +2955,7 @@ void Planner::buffer_sync_block(const BlockFlagBit sync_flag/*=BLOCK_BIT_SYNC_PO
// As there are no queued movements, the Stepper ISR will not touch this
// variable, so there is no risk setting this here (but it MUST be done
// before the following line!!)
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg_mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
}
block_buffer_head = next_buffer_head;
@@ -3243,7 +3253,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s
// As there are no queued movements, the Stepper ISR will not touch this
// variable, so there is no risk setting this here (but it MUST be done
// before the following line!!)
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
delay_before_delivering = TERN_(FT_MOTION, fxdTiCtrl.cfg_mode ? BLOCK_DELAY_NONE :) BLOCK_DELAY_FOR_1ST_MOVE;
}
// Move buffer head