diff --git a/uCNC/cnc_config.h b/uCNC/cnc_config.h index 6eb2eb9bc..aaa2ab6b5 100644 --- a/uCNC/cnc_config.h +++ b/uCNC/cnc_config.h @@ -430,6 +430,30 @@ extern "C" // #define ENABLE_BACKLASH_COMPENSATION + /** + * By enabling this option the planner will only care about the exit speed. + * This will make the planner not perform the forward pass to adjust entry speeds. + * The adjustment of the next planner block is made on the fly when the block is loaded. + * */ + // #define ENABLE_PLANNER_SPEED_OVERSHOOT + + /** + * By enabling this option the planner will junction speed based on accel only if need + * meaning that the junction speed will only be the maximum value between current and exit speed + * This will eliminate ramp up and down completly and over-simplify calculations + * */ + // #define ENABLE_PLANNER_ACCEL_NONOPTIMAL + + /** + * By enabling this option the planner will only perform acceleration if the exit speed is higher + * then the current speed and the distance travelled is lower then a give threshold (in steps) + * This will prevent sucessive ramp up and down speed profiles a produce more continuous speed motions + * */ + // #define ENABLE_PLANNER_NOACCEL_ON_SLOWER_EXIT + #ifdef ENABLE_PLANNER_NOACCEL_ON_SLOWER_EXIT + #define ENABLE_PLANNER_NOACCEL_MAX_STEP_DISTANCE 200 + #endif + /** * Uncomment these to enable step ISR calculation strategies (uses more * memory) STEP_ISR_SKIP_MAIN - carries the information about the main diff --git a/uCNC/src/core/interpolator.c b/uCNC/src/core/interpolator.c index c79a5c8c3..e8af2daa1 100644 --- a/uCNC/src/core/interpolator.c +++ b/uCNC/src/core/interpolator.c @@ -452,6 +452,9 @@ void itp_run(void) float accel_dist = ABS(junction_speed_sqr - itp_cur_plan_block->entry_feed_sqr) * accel_inv; accel_dist = fast_flt_div2(accel_dist); accel_until -= floorf(accel_dist); +#ifdef ENABLE_PLANNER_ACCEL_NONOPTIMAL + accel_until = MIN(accel_until, remaining_steps); +#endif float t = ABS(junction_speed - current_speed); #if S_CURVE_ACCELERATION_LEVEL != 0 acc_scale = t; @@ -701,6 +704,7 @@ void itp_run(void) { itp_cur_plan_block->entry_feed_sqr = fast_flt_pow2(junction_speed); } +#endif itp_cur_plan_block->steps[itp_cur_plan_block->main_stepper] = remaining_steps; diff --git a/uCNC/src/core/planner.c b/uCNC/src/core/planner.c index 28a8e1315..65a31348b 100644 --- a/uCNC/src/core/planner.c +++ b/uCNC/src/core/planner.c @@ -217,6 +217,9 @@ void planner_discard_block(void) } uint8_t index = planner_data_read; +#ifdef ENABLE_PLANNER_SPEED_OVERSHOOT + float last_speed = planner_data[index].entry_feed_sqr; +#endif if (++index == PLANNER_BUFFER_SIZE) { @@ -233,6 +236,9 @@ void planner_discard_block(void) #endif planner_data_blocks = blocks; +#ifdef ENABLE_PLANNER_SPEED_OVERSHOOT + planner_data[index].entry_feed_sqr = last_speed; +#endif planner_data_read = index; } @@ -360,9 +366,40 @@ float planner_get_block_top_speed(float exit_speed_sqr) v_max^2 = (v_exit^2 + 2 * acceleration * distance + v_entry)/2 */ + // calculates the difference between the entry speed and the exit speed uint8_t index = planner_data_read; + +#ifdef ENABLE_PLANNER_ACCEL_NONOPTIMAL + // just computes half way accel + float junction_speed_sqr = planner_data[index].acceleration * (float)(planner_data[index].total_steps); + if (planner_data[index].entry_feed_sqr > exit_speed_sqr) + { + junction_speed_sqr += exit_speed_sqr; + } + else + { + junction_speed_sqr += planner_data[index].entry_feed_sqr; + junction_speed_sqr = MAX(junction_speed_sqr, exit_speed_sqr); + } +#else + float speed_delta = exit_speed_sqr - planner_data[index].entry_feed_sqr; + +#ifdef ENABLE_PLANNER_NOACCEL_ON_SLOWER_EXIT + // exit speed is lower then entry speed + if (speed_delta < 0) + { + uint8_t i = planner_data[index].main_stepper; + // is short distance? + if (ENABLE_PLANNER_NOACCEL_MAX_STEP_DISTANCE > planner_data[index].steps[i]) + { + // keep speed (avoid accel on short motion that will have to deaccel after) + return planner_data[index].entry_feed_sqr; + } + } +#endif + // calculates the speed increase/decrease for the given distance float junction_speed_sqr = planner_data[index].acceleration * (float)(planner_data[index].steps[planner_data[index].main_stepper]); junction_speed_sqr = fast_flt_mul2(junction_speed_sqr); @@ -382,6 +419,7 @@ float planner_get_block_top_speed(float exit_speed_sqr) // will overshoot the desired exit speed even deaccelerating all the way junction_speed_sqr = planner_data[index].entry_feed_sqr; } +#endif float rapid_feed_sqr = planner_data[index].rapid_feed_sqr; float target_speed_sqr = planner_data[index].feed_sqr; @@ -453,9 +491,10 @@ static void planner_recalculate(void) while (!planner_data[block].planner_flags.bit.optimal && block != first) { - if ((planner_data[block].entry_feed_sqr >= planner_data[block].entry_max_feed_sqr) || planner_data[block].planner_flags.bit.optimal) + if ((planner_data[block].entry_feed_sqr >= planner_data[block].entry_max_feed_sqr)) { // found optimal + planner_data[block].planner_flags.bit.optimal = true; break; } speedchange = ((float)(planner_data[block].steps[planner_data[block].main_stepper] << 1)) * planner_data[block].acceleration; @@ -466,6 +505,7 @@ static void planner_recalculate(void) block = planner_buffer_prev(block); } +#ifndef ENABLE_PLANNER_SPEED_OVERSHOOT // optimizes exit speeds (forward pass) while (block != last) { @@ -493,6 +533,7 @@ static void planner_recalculate(void) block = next; next = planner_buffer_next(block); } +#endif } void planner_sync_tools(motion_data_t *block_data)