mirror of
https://github.com/grblHAL/core.git
synced 2026-08-18 00:47:25 +08:00
Merge pull request #593 from Dietz0r/master
Jerk Acceleration Settings and HAAS G187 Acceleration Profiles
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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." },
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user