mirror of
https://github.com/grblHAL/core.git
synced 2026-09-22 03:08:33 +08:00
moved last_segment_accel to static so values dont get lost between stepper loops, adjusted jerk ramps to grblhal calculations in mm instead of time based calculations. now works with low and very low jerk values.
known issue: decel ramp does not hit 0 speed at end.
This commit is contained in:
@@ -95,6 +95,11 @@ static float cycles_per_min;
|
||||
static volatile segment_t *segment_buffer_tail;
|
||||
static segment_t *segment_buffer_head, *segment_next_head;
|
||||
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
// Static storage for acceleration value of last computed segment.
|
||||
static float last_segment_accel = 0.0f;
|
||||
#endif
|
||||
|
||||
// Pointers for the step segment being prepped from the planner buffer. Accessed only by the
|
||||
// main program. Pointers may be planning segments or planner blocks ahead of what being executed.
|
||||
static plan_block_t *pl_block; // Pointer to the planner block being prepped
|
||||
@@ -866,13 +871,14 @@ void st_prep_buffer (void)
|
||||
float dt_max = DT_SEGMENT; // Maximum segment time
|
||||
float dt = 0.0f; // Initialize segment time
|
||||
float time_var = dt_max; // Time worker variable
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
float last_segment_accel = 0.0f; // Acceleration value of last computed segment. Initialize as 0.0
|
||||
#endif
|
||||
float mm_var; // mm - Distance worker variable
|
||||
float speed_var; // Speed worker variable
|
||||
float mm_remaining = pl_block->millimeters; // New segment distance from end of block.
|
||||
float minimum_mm = mm_remaining - prep.req_mm_increment; // Guarantee at least one step.
|
||||
#if ENABLE_ACCELERATION_PROFILES
|
||||
float time_to_jerk; // time needed for jerk ramp
|
||||
float mm_to_rampend; // mm needed to complete one jerk ramp mm == V(0)*T + 1/2 A0*T^2 + 1/6 J*T^3
|
||||
#endif
|
||||
|
||||
if (minimum_mm < 0.0f)
|
||||
minimum_mm = 0.0f;
|
||||
@@ -897,15 +903,17 @@ void st_prep_buffer (void)
|
||||
|
||||
case Ramp_Accel:
|
||||
// NOTE: Acceleration ramp only computes during first do-while loop.
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
if (((mm_remaining - prep.accelerate_until) / (prep.current_speed + 0.001f)) <= (last_segment_accel / pl_block->jerk)) {
|
||||
//+0.001f to avoid divide by 0 speed, minor effect on jerk ramp (+1.0f was too large for low jerk values)
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
time_to_jerk = last_segment_accel / pl_block->jerk;
|
||||
mm_to_rampend = (prep.current_speed * time_to_jerk) + (0.5f * last_segment_accel * time_to_jerk * time_to_jerk) + (pl_block->jerk * time_to_jerk * time_to_jerk * time_to_jerk) / 6.0f;
|
||||
if ((mm_remaining - prep.accelerate_until) > mm_to_rampend) {
|
||||
//+1.0f to avoid divide by 0 speed, minor effect on jerk ramp
|
||||
// Check if we are on ramp up or ramp down. Ramp down if time to end of acceleration is less than time needed to reach 0 acceleration.
|
||||
// Then limit acceleration change by jerk up to max acceleration and update for next segment.
|
||||
// Minimum acceleration jerk per time_var to ensure acceleartion completes. Acceleration change at end of ramp is in acceptable jerk range.
|
||||
last_segment_accel = max(last_segment_accel - pl_block->jerk * time_var, pl_block->jerk * time_var);
|
||||
} else {
|
||||
// Minimum acceleration jerk per time_var to ensure acceleration completes. Acceleration change at end of ramp is in acceptable jerk range.
|
||||
last_segment_accel = min(last_segment_accel + pl_block->jerk * time_var, pl_block->max_acceleration);
|
||||
} else {
|
||||
last_segment_accel = max(last_segment_accel - pl_block->jerk * time_var, pl_block->jerk * time_var);
|
||||
}
|
||||
speed_var = last_segment_accel * time_var;
|
||||
#else
|
||||
@@ -942,14 +950,15 @@ void st_prep_buffer (void)
|
||||
default: // case Ramp_Decel:
|
||||
// NOTE: mm_var used as a misc worker variable to prevent errors when near zero speed.
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
if ((mm_remaining / (prep.current_speed + 0.001f)) <= (last_segment_accel / pl_block->jerk)) {
|
||||
//+0.001f to avoid divide by 0 speed, minor effect on jerk ramp (+1.0f was too large for low jerk values)
|
||||
// Check if we are on ramp up or ramp down. Ramp down if time to end of deceleration is less than time needed to reach 0 acceleration.
|
||||
time_to_jerk = last_segment_accel / pl_block->jerk;
|
||||
mm_to_rampend = (prep.current_speed * time_to_jerk) + (0.5f * last_segment_accel * time_to_jerk * time_to_jerk) + (pl_block->jerk * time_to_jerk * time_to_jerk * time_to_jerk) / 6.0f;
|
||||
if (mm_remaining > mm_to_rampend) {
|
||||
// Check if we are on ramp up or ramp down. Ramp down if travel distance to end of deceleration is less than distance needed to reach 0 acceleration.
|
||||
// Then limit acceleration change by jerk up to max acceleration and update for next segment.
|
||||
// Minimum acceleration of jerk per time_var to ensure acceleration completes. Acceleration change at end of ramp is in acceptable jerk range.
|
||||
last_segment_accel = max(last_segment_accel - pl_block->jerk * time_var, pl_block->jerk * time_var);
|
||||
} else {
|
||||
last_segment_accel = min(last_segment_accel + pl_block->jerk * time_var, pl_block->max_acceleration);
|
||||
} else {
|
||||
last_segment_accel = max(last_segment_accel - pl_block->jerk * time_var, pl_block->jerk * time_var);
|
||||
}
|
||||
speed_var = last_segment_accel * time_var; // Used as delta speed (mm/min)
|
||||
#else
|
||||
@@ -968,6 +977,9 @@ void st_prep_buffer (void)
|
||||
time_var = 2.0f * (mm_remaining - prep.mm_complete) / (prep.current_speed + prep.exit_speed);
|
||||
mm_remaining = prep.mm_complete;
|
||||
prep.current_speed = prep.exit_speed;
|
||||
#if ENABLE_JERK_ACCELERATION
|
||||
last_segment_accel = 0.0f; // reset acceleration variable to 0 for next accel ramp
|
||||
#endif
|
||||
}
|
||||
|
||||
dt += time_var; // Add computed ramp time to total segment time.
|
||||
|
||||
Reference in New Issue
Block a user