Merge pull request #593 from Dietz0r/master

Jerk Acceleration Settings and HAAS G187 Acceleration Profiles
This commit is contained in:
Terje Io
2024-12-30 20:35:58 +01:00
committed by GitHub
8 changed files with 241 additions and 5 deletions
+34
View File
@@ -189,7 +189,10 @@ or EMI triggering the related interrupt falsely or too many times.
// ---------------------------------------------------------------------------------------
// ADVANCED CONFIGURATION OPTIONS:
// EXPERIMENTAL OPTIONS
#define ENABLE_PATH_BLENDING Off // Do NOT enable unless working on adding this feature!
#define ENABLE_ACCELERATION_PROFILES Off // Enable to allow G-Code changeable acceleration profiles.
#define ENABLE_JERK_ACCELERATION Off // Enable to use 3rd order Acceleration calculations. May need more processing power, tiny chips beware.
// Enables code for debugging purposes. Not for general use and always in constant flux.
//#define DEBUG // Uncomment to enable. Default disabled.
@@ -2016,6 +2019,37 @@ G90
#endif
///@}
/*! @name 22x - Setting_AxisJerk
*/
///@{
#if ENABLE_JERK_ACCELERATION
#if !defined DEFAULT_X_JERK|| defined __DOXYGEN__
#define DEFAULT_X_JERK 100.0f // mm/sec^3
#endif
#if !defined DEFAULT_Y_JERK|| defined __DOXYGEN__
#define DEFAULT_Y_JERK 100.0f // mm/sec^3
#endif
#if !defined DEFAULT_Z_JERK || defined __DOXYGEN__
#define DEFAULT_Z_JERK 100.0f // mm/sec^3
#endif
#if (defined A_AXIS && !defined DEFAULT_A_JERK) || defined __DOXYGEN__
#define DEFAULT_A_JERK 100.0f // mm/sec^3
#endif
#if (defined B_AXIS && !defined DEFAULT_B_JERK) || defined __DOXYGEN__
#define DEFAULT_B_JERK 100.0f // mm/sec^3
#endif
#if (defined C_AXIS && !defined DEFAULT_C_JERK) || defined __DOXYGEN__
#define DEFAULT_C_JERK 100.0f // mm/sec^3
#endif
#if (defined U_AXIS && !defined DEFAULT_U_JERK) || defined __DOXYGEN__
#define DEFAULT_U_JERK 100.0f // mm/sec^3
#endif
#if (defined V_AXIS && !defined DEFAULT_V_JERK) || defined __DOXYGEN__
#define DEFAULT_V_JERK 100.0f // mm/sec^3
#endif
#endif
///@}
/*! @name 13x - Setting_AxisMaxTravel
__NOTE:__ Must be a positive values.
*/
+30
View File
@@ -361,6 +361,9 @@ void gc_init (bool stop)
#if NGC_PARAMETERS_ENABLE
ngc_modal_state_invalidate();
#endif
#if ENABLE_ACCELERATION_PROFILES
gc_state.modal.acceleration_factor = 1.0f; // Initialize machine with 100% Profile
#endif
// if(settings.flags.lathe_mode)
// gc_state.modal.plane_select = PlaneSelect_ZX;
@@ -1194,6 +1197,15 @@ status_code_t gc_execute_block (char *block)
gc_block.modal.scaling_active = int_value == 51;
break;
#if ENABLE_ACCELERATION_PROFILES
case 187:
word_bit.modal_group.G0 = On;
gc_block.non_modal_command = (non_modal_t)int_value;
if(mantissa != 0)
FAIL(Status_GcodeUnsupportedCommand);
break;
#endif
default: FAIL(Status_GcodeUnsupportedCommand); // [Unsupported G command]
} // end G-value switch
@@ -2358,7 +2370,19 @@ status_code_t gc_execute_block (char *block)
gc_block.values.xyz[idx] = gc_state.g92_coord_offset[idx];
} while(idx);
break;
#if ENABLE_ACCELERATION_PROFILES
case NonModal_SetAccelerationProfile:
if(gc_block.words.e)
FAIL(Status_GcodeUnsupportedCommand);
if(gc_block.words.p && (gc_block.values.p < 1.0f || gc_block.values.p > 5.0f))
FAIL(Status_GcodeValueOutOfRange);
gc_state.modal.acceleration_factor = lookupfactor(gc_block.words.p ? (uint8_t)gc_block.values.p - 1 : 0);
gc_block.words.p = Off;
break;
#endif
default:
// At this point, the rest of the explicit axis commands treat the axis values as the traditional
@@ -3030,6 +3054,9 @@ status_code_t gc_execute_block (char *block)
memset(&plan_data, 0, sizeof(plan_line_data_t)); // Zero plan_data struct
plan_data.offset_id = gc_state.offset_id;
plan_data.condition.target_validated = plan_data.condition.target_valid = sys.soft_limits.mask == 0;
#if ENABLE_ACCELERATION_PROFILES
plan_data.acceleration_factor = gc_state.modal.acceleration_factor;
#endif
// Intercept jog commands and complete error checking for valid jog commands and execute.
// NOTE: G-code parser state is not updated, except the position to ensure sequential jog
@@ -3819,6 +3846,9 @@ status_code_t gc_execute_block (char *block)
gc_state.modal.coolant = (coolant_state_t){0};
gc_state.modal.override_ctrl.feed_rate_disable = Off;
gc_state.modal.override_ctrl.spindle_rpm_disable = Off;
#if ENABLE_ACCELERATION_PROFILES
gc_state.modal.acceleration_factor = 1.0f;
#endif
#if N_SYS_SPINDLE > 1
+9 -1
View File
@@ -59,7 +59,12 @@ typedef enum {
NonModal_SetCoordinateOffset = 92, //!< 92 - G92
NonModal_ResetCoordinateOffset = 102, //!< 102 - G92.1
NonModal_ClearCoordinateOffset = 112, //!< 112 - G92.2
NonModal_RestoreCoordinateOffset = 122 //!< 122 - G92.3
#if ENABLE_ACCELERATION_PROFILES
NonModal_RestoreCoordinateOffset = 122, //!< 122 - G92.3
NonModal_SetAccelerationProfile = 187 //!< 187 - G187
#else
NonModal_RestoreCoordinateOffset = 122 //!< 122 - G92.3
#endif
} non_modal_t;
@@ -541,6 +546,9 @@ typedef struct {
bool auto_restore;
float feed_rate; //!< {F} NOTE: only set when saving modal state
#endif
#if ENABLE_ACCELERATION_PROFILES
float acceleration_factor; //!< {G187} currently active factor of acceleration profile
#endif
} gc_modal_t;
//! Data for canned cycles.
+38 -1
View File
@@ -348,10 +348,23 @@ static inline float limit_acceleration_by_axis_maximum (float *unit_vec)
if (unit_vec[--idx] != 0.0f) // Avoid divide by zero.
limit_value = min(limit_value, fabsf(settings.axis[idx].acceleration / unit_vec[idx]));
} while(idx);
return limit_value;
}
#if ENABLE_JERK_ACCELERATION
static inline float limit_jerk_by_axis_maximum (float *unit_vec)
{
uint_fast8_t idx = N_AXIS;
float limit_value = SOME_LARGE_VALUE;
do {
if (unit_vec[--idx] != 0.0f) // Avoid divide by zero.
limit_value = min(limit_value, fabsf(settings.axis[idx].jerk / unit_vec[idx]));
} while(idx);
return limit_value;
}
#endif
static inline float limit_max_rate_by_axis_maximum (float *unit_vec)
{
uint_fast8_t idx = N_AXIS;
@@ -502,10 +515,24 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
#endif
block->millimeters = convert_delta_vector_to_unit_vector(unit_vec);
#if ENABLE_JERK_ACCELERATION
block->max_acceleration = limit_acceleration_by_axis_maximum(unit_vec);
block->jerk = limit_jerk_by_axis_maximum(unit_vec);
#else
block->acceleration = limit_acceleration_by_axis_maximum(unit_vec);
#endif
block->rapid_rate = limit_max_rate_by_axis_maximum(unit_vec);
#ifdef KINEMATICS_API
block->rate_multiplier = pl_data->rate_multiplier;
#endif
#if ENABLE_ACCELERATION_PROFILES // recalculate the acceleration limits when enabled.
block->acceleration_factor = pl_data->acceleration_factor;
#if ENABLE_JERK_ACCELERATION
block->max_acceleration *= block->acceleration_factor;
block->jerk *= block->acceleration_factor;
#else
block->acceleration *= block->acceleration_factor;
#endif
#endif
// Store programmed rate.
@@ -516,6 +543,13 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
if (block->condition.inverse_time)
block->programmed_rate *= block->millimeters;
}
#if ENABLE_JERK_ACCELERATION
// Calculate effective acceleration over block. Since jerk acceleration takes longer to execute due to ramp up and
// ramp down of the acceleration at the start and end of a ramp we need to adjust the acceleration value the planner
// uses so it still calculates reasonable entry and exit speeds. We do this by adding 2x the time it takes to reach
// full acceleration to the trapezoidal acceleration time and dividing the programmed rate by the value obtained.
block->acceleration = block->programmed_rate / ((block->programmed_rate / block->max_acceleration) + 2.0f * (block->max_acceleration / block->jerk));
#endif
// TODO: Need to check this method handling zero junction speeds when starting from rest.
if ((block_buffer_head == block_buffer_tail) || (block->condition.system_motion)) {
@@ -704,4 +738,7 @@ void plan_data_init (plan_line_data_t *plan_data)
#ifdef KINEMATICS_API
plan_data->rate_multiplier = 1.0f;
#endif
#ifdef ENABLE_ACCELERATION_PROFILES
plan_data->acceleration_factor = 1.0f;
#endif
}
+11 -1
View File
@@ -63,7 +63,11 @@ typedef struct plan_block {
float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2
float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
// neighboring nominal speeds with overrides in (mm/min)^2
float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
float acceleration; // Effective acceleration over plannerblock calculated from trapezoidal movement plan. Does not change in trapezoidal mode.
#if ENABLE_JERK_ACCELERATION
float max_acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
float jerk; // Axis-limit adjusted jerk value in (mm/min^3). Does not change.
#endif
float millimeters; // The remaining distance for this block to be executed in (mm).
// NOTE: This value may be altered by stepper algorithm during execution.
@@ -73,6 +77,9 @@ typedef struct plan_block {
float programmed_rate; // Programmed rate of this block (mm/min).
#ifdef KINEMATICS_API
float rate_multiplier; // Rate multiplier of this block.
#endif
#ifdef ENABLE_ACCELERATION_PROFILES
float acceleration_factor; // Stores the currently used acceleration factor.
#endif
// Stored spindle speed data used by spindle overrides and resuming methods.
spindle_t spindle; // Block spindle parameters. Copied from pl_line_data.
@@ -89,6 +96,9 @@ typedef struct {
#ifdef KINEMATICS_API
float rate_multiplier; // Feed rate multiplier.
#endif
#ifdef ENABLE_ACCELERATION_PROFILES
float acceleration_factor; // Stores the currently used acceleration factor.
#endif
#if ENABLE_PATH_BLENDING
float path_tolerance; //!< Path blending tolerance.
float cam_tolerance; //!< Naive CAM tolerance.
+83 -2
View File
@@ -210,6 +210,9 @@ PROGMEM const settings_t defaults = {
.axis[X_AXIS].steps_per_mm = DEFAULT_X_STEPS_PER_MM,
.axis[X_AXIS].max_rate = DEFAULT_X_MAX_RATE,
.axis[X_AXIS].acceleration = (DEFAULT_X_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[X_AXIS].jerk = (DEFAULT_X_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[X_AXIS].max_travel = (-DEFAULT_X_MAX_TRAVEL),
.axis[X_AXIS].dual_axis_offset = 0.0f,
.axis[X_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
@@ -222,6 +225,9 @@ PROGMEM const settings_t defaults = {
.axis[Y_AXIS].max_rate = DEFAULT_Y_MAX_RATE,
.axis[Y_AXIS].max_travel = (-DEFAULT_Y_MAX_TRAVEL),
.axis[Y_AXIS].acceleration = (DEFAULT_Y_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[Y_AXIS].jerk = (DEFAULT_Y_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[Y_AXIS].dual_axis_offset = 0.0f,
.axis[Y_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
.axis[Y_AXIS].homing_seek_rate = DEFAULT_HOMING_SEEK_RATE,
@@ -232,6 +238,9 @@ PROGMEM const settings_t defaults = {
.axis[Z_AXIS].steps_per_mm = DEFAULT_Z_STEPS_PER_MM,
.axis[Z_AXIS].max_rate = DEFAULT_Z_MAX_RATE,
.axis[Z_AXIS].acceleration = (DEFAULT_Z_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[Z_AXIS].jerk = (DEFAULT_Z_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[Z_AXIS].max_travel = (-DEFAULT_Z_MAX_TRAVEL),
.axis[Z_AXIS].dual_axis_offset = 0.0f,
.axis[Z_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
@@ -244,6 +253,9 @@ PROGMEM const settings_t defaults = {
.axis[A_AXIS].steps_per_mm = DEFAULT_A_STEPS_PER_MM,
.axis[A_AXIS].max_rate = DEFAULT_A_MAX_RATE,
.axis[A_AXIS].acceleration =(DEFAULT_A_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[A_AXIS].jerk = (DEFAULT_A_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[A_AXIS].max_travel = (-DEFAULT_A_MAX_TRAVEL),
.axis[A_AXIS].dual_axis_offset = 0.0f,
.axis[A_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
@@ -258,6 +270,9 @@ PROGMEM const settings_t defaults = {
.axis[B_AXIS].steps_per_mm = DEFAULT_B_STEPS_PER_MM,
.axis[B_AXIS].max_rate = DEFAULT_B_MAX_RATE,
.axis[B_AXIS].acceleration = (DEFAULT_B_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[B_AXIS].jerk = (DEFAULT_B_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[B_AXIS].max_travel = (-DEFAULT_B_MAX_TRAVEL),
.axis[B_AXIS].dual_axis_offset = 0.0f,
.axis[B_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
@@ -271,6 +286,9 @@ PROGMEM const settings_t defaults = {
#ifdef C_AXIS
.axis[C_AXIS].steps_per_mm = DEFAULT_C_STEPS_PER_MM,
.axis[C_AXIS].acceleration = (DEFAULT_C_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[C_AXIS].jerk = (DEFAULT_C_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[C_AXIS].max_rate = DEFAULT_C_MAX_RATE,
.axis[C_AXIS].max_travel = (-DEFAULT_C_MAX_TRAVEL),
.axis[C_AXIS].dual_axis_offset = 0.0f,
@@ -285,6 +303,9 @@ PROGMEM const settings_t defaults = {
#ifdef U_AXIS
.axis[U_AXIS].steps_per_mm = DEFAULT_U_STEPS_PER_MM,
.axis[U_AXIS].acceleration = (DEFAULT_U_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[U_AXIS].jerk = (DEFAULT_U_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[U_AXIS].max_rate = DEFAULT_U_MAX_RATE,
.axis[U_AXIS].max_travel = (-DEFAULT_U_MAX_TRAVEL),
.axis[U_AXIS].dual_axis_offset = 0.0f,
@@ -298,6 +319,9 @@ PROGMEM const settings_t defaults = {
#ifdef V_AXIS
.axis[V_AXIS].steps_per_mm = DEFAULT_V_STEPS_PER_MM,
.axis[V_AXIS].acceleration = (DEFAULT_V_ACCELERATION * 60.0f * 60.0f),
#if ENABLE_JERK_ACCELERATION
.axis[V_AXIS].jerk = (DEFAULT_V_JERK * 60.0f * 60.0f * 60.0f),
#endif
.axis[V_AXIS].max_rate = DEFAULT_V_MAX_RATE,
.axis[V_AXIS].max_travel = (-DEFAULT_V_MAX_TRAVEL),
.axis[V_AXIS].dual_axis_offset = 0.0f,
@@ -421,6 +445,9 @@ static char spindle_types[100] = "";
static char axis_dist[4] = "mm";
static char axis_rate[8] = "mm/min";
static char axis_accel[10] = "mm/sec^2";
#if ENABLE_JERK_ACCELERATION
static char axis_jerk[15] = "mm/sec^3";
#endif
#if DELTA_ROBOT
static char axis_steps[9] = "step/rev";
#else
@@ -472,12 +499,29 @@ bool settings_override_acceleration (uint8_t axis, float acceleration)
} else {
if(!override_backup.valid)
save_override_backup();
settings.axis[axis].acceleration = acceleration * 60.0f * 60.0f; // Limit max to setting value?
settings.axis[axis].acceleration = (override_backup.acceleration[axis] >= (acceleration * 60.0f * 60.0f)) ? (acceleration * 60.0f * 60.0f) : override_backup.acceleration[axis]; // Limited to max setting value
}
return true;
}
#if ENABLE_ACCELERATION_PROFILES
//Acceleration Profiles for G187 P[x] in percent of maximum machine acceleration.
float lookupfactor(uint8_t profile) {
static const float lookup[5] = {
1.0f, // 100% - Roughing - Max Acceleration Default
0.8f, // 80% - Semi Roughing
0.6f, // 60% - Semi Finish
0.4f, // 40% - Finish
0.2f, // 20% - Slow AF Mode
};
if (profile >= sizeof(lookup) / sizeof(lookup[0])) {
profile = 0;
}
return lookup[profile];
}
#endif
// ---
static void homing_pulloff_init (float pulloff)
@@ -1031,6 +1075,12 @@ static const char *set_axis_setting_unit (setting_id_t setting_id, uint_fast8_t
unit = is_rotary ? "deg/sec^2" : "mm/sec^2";
break;
#if ENABLE_JERK_ACCELERATION
case Setting_AxisJerk:
unit = is_rotary ? "deg/sec^3" : "mm/sec^3";
break;
#endif
case Setting_AxisMaxTravel:
case Setting_AxisBacklash:
unit = is_rotary ? "deg" : "mm";
@@ -1147,6 +1197,12 @@ static status_code_t set_axis_setting (setting_id_t setting, float value)
settings.axis[idx].acceleration = override_backup.acceleration[idx] = value * 60.0f * 60.0f; // Convert to mm/min^2 for grbl internal use.
break;
#if ENABLE_JERK_ACCELERATION
case Setting_AxisJerk:
settings.axis[idx].jerk = value * 60.0f * 60.0f * 60.0f; // Convert to mm/min^3 for grbl internal use.
break;
#endif
case Setting_AxisMaxTravel:
if(settings.axis[idx].max_travel != -value) {
bit_false(sys.homed.mask, bit(idx));
@@ -1249,7 +1305,22 @@ static float get_float (setting_id_t setting)
default:
break;
}
} else switch(setting) {
} else if(setting >= Setting_AxisSettingsBase1 && setting <= Setting_AxisSettingsMax1) {
uint_fast8_t idx;
switch(settings_get_axis_base(setting, &idx)) {
#if ENABLE_JERK_ACCELERATION
case Setting_AxisJerk:
value = settings.axis[idx].jerk / (60.0f * 60.0f * 60.0f); // Convert from mm/min^3 to mm/sec^3.
break;
#endif
default:
break;
}
} else switch(setting) {
case Setting_HomingFeedRate:
value = settings.axis[0].homing_feed_rate;
@@ -1951,6 +2022,9 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_AxisMaxTravel, Group_Axis0, "-axis maximum travel", axis_dist, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL, AXIS_OPTS },
#if ENABLE_BACKLASH_COMPENSATION
{ Setting_AxisBacklash, Group_Axis0, "-axis backlash compensation", axis_dist, Format_Decimal, "#####0.000##", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL, AXIS_OPTS },
#endif
#if ENABLE_JERK_ACCELERATION
{ Setting_AxisJerk, Group_Axis0, "-axis jerk", axis_jerk, Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL, AXIS_OPTS },
#endif
{ Setting_AxisAutoSquareOffset, Group_Axis0, "-axis dual axis offset", "mm", Format_Decimal, "-0.000", "-10", "10", Setting_IsExtendedFn, set_axis_setting, get_float, is_setting_available, AXIS_OPTS },
{ Setting_AxisHomingFeedRate, Group_Axis0, "-axis homing locate feed rate", axis_rate, Format_Decimal, "###0", NULL, NULL, Setting_NonCoreFn, set_axis_setting, get_float, is_setting_available, AXIS_OPTS },
@@ -2122,6 +2196,13 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ (setting_id_t)(Setting_AxisStepsPerMM + 1), "Travel resolution in steps per degree." }, // "Hack" to get correct description for rotary axes
{ Setting_AxisMaxRate, "Maximum rate. Used as G0 rapid rate." },
{ Setting_AxisAcceleration, "Acceleration. Used for motion planning to not exceed motor torque and lose steps." },
#if ENABLE_JERK_ACCELERATION
{ Setting_AxisJerk, "Maximum rate of acceleration change - smoothes out acceleration profile up to max axis acceleration.\\n\\n"
"Minimum value of x10 Acceleration setting to ensure decent acceleration times.\\n"
"Maximum is calculated by current acceleration and stepper segment time.\\n"
"At Maximum value motion is effectively trapezoidal instead of constant jerk.\\n\\n"
"Can be increased by adjusting ACCELERATION_TICKS_PER_SECOND to a larger value before compiling."},
#endif
{ Setting_AxisMaxTravel, "Maximum axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances." },
#if ENABLE_BACKLASH_COMPENSATION
{ Setting_AxisBacklash, "Backlash distance to compensate for." },
+4
View File
@@ -1081,6 +1081,10 @@ bool settings_read_coord_data(coord_system_id_t id, float (*coord_data)[N_AXIS])
// Temporarily override acceleration, if 0 restore to configured setting value
bool settings_override_acceleration (uint8_t axis, float acceleration);
#if ENABLE_ACCELERATION_PROFILES
float lookupfactor (uint8_t profile);
#endif
void settings_register (setting_details_t *details);
setting_details_t *settings_get_details (void);
bool settings_is_group_available (setting_group_t group);
+32
View File
@@ -866,6 +866,9 @@ 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.
@@ -894,7 +897,20 @@ 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)
// 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 {
last_segment_accel = min(last_segment_accel + pl_block->jerk * time_var, pl_block->max_acceleration);
}
speed_var = last_segment_accel * time_var;
#else
speed_var = pl_block->acceleration * time_var;
#endif
mm_remaining -= time_var * (prep.current_speed + 0.5f * speed_var);
if (mm_remaining < prep.accelerate_until) { // End of acceleration ramp.
// Acceleration-cruise, acceleration-deceleration ramp junction, or end of block.
@@ -902,6 +918,9 @@ void st_prep_buffer (void)
time_var = 2.0f * (pl_block->millimeters - mm_remaining) / (prep.current_speed + prep.maximum_speed);
prep.ramp_type = mm_remaining == prep.decelerate_after ? Ramp_Decel : Ramp_Cruise;
prep.current_speed = prep.maximum_speed;
#if ENABLE_JERK_ACCELERATION
last_segment_accel = 0.0f; // reset acceleration variable to 0 for next accel ramp
#endif
} else // Acceleration only.
prep.current_speed += speed_var;
break;
@@ -922,7 +941,20 @@ 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.
// 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);
}
speed_var = last_segment_accel * time_var; // Used as delta speed (mm/min)
#else
speed_var = pl_block->acceleration * time_var; // Used as delta speed (mm/min)
#endif
if (prep.current_speed > speed_var) { // Check if at or below zero speed.
// Compute distance from end of segment to end of block.
mm_var = mm_remaining - time_var * (prep.current_speed - 0.5f * speed_var); // (mm)