Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable s-curve #459

Merged
merged 1 commit into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions uCNC/cnc_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,14 @@ extern "C"
* Performs motions with variable acceleration (trapezoidal speed profile
* with rounded speed transition between accel/deaccel and constant speed)
* instead of constant acceleration (trapezoidal speed profile)
*
* 0 - disabled
* 1 - mild profile (smaller mid slope and higher initial and exit slopes)
* 2 - medium profile (medium mid slope and medium initial and exit slopes)
* 3 - agressive (higher mid slope and smaller initial and exit slopes - uses bezier 5th order)
*
* -1 - selectable via setting $14
* 0 - disabled
* 1 - mild profile (smaller mid slope and higher initial and exit slopes)
* 2 - medium profile (medium mid slope and medium initial and exit slopes)
* 3 - stron profile (high mid slope and medium initial and exit slopes)
* 4 - agressive (higher mid slope and smaller initial and exit slopes - uses bezier 5th order)
* 5 - agressive2 (higher mid slope and smaller initial and exit slopes - uses tanh curve)
*
* */

Expand Down
6 changes: 3 additions & 3 deletions uCNC/src/cnc_hal_config_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extern "C"
{
#endif

//undefined pin
// undefined pin
#define UNDEF_PIN 0
// assert pin (io or extended)
#define ASSERT_PIN(X) (X != 0)
Expand Down Expand Up @@ -1996,7 +1996,7 @@ typedef uint16_t step_t;
#error "DSS_CUTOFF_FREQ should not be set above 1/8th of the max step rate"
#endif

#if ((S_CURVE_ACCELERATION_LEVEL < 0) || (S_CURVE_ACCELERATION_LEVEL > 3))
#if ((S_CURVE_ACCELERATION_LEVEL < -1) || (S_CURVE_ACCELERATION_LEVEL > 5))
#error "invalid s-curve velocity profile setting"
#endif

Expand Down Expand Up @@ -2120,7 +2120,7 @@ typedef uint16_t step_t;

#ifdef ENABLE_PLASMA_THC

//forces modes
// forces modes
#ifndef ENABLE_TOOL_PID_CONTROLLER
#define ENABLE_TOOL_PID_CONTROLLER
#endif
Expand Down
74 changes: 64 additions & 10 deletions uCNC/src/core/interpolator.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,33 +219,87 @@ void itp_init(void)
// evals the point in a s-curve function
// receives a value between 0 and 1
// outputs a value along a curve according to the scale
static float s_curve_function(float pt, float scale)
static float s_curve_function(float pt)
{
#ifdef S_CURVE_TANH
return 0.5 * (tanh(6 * pt - 3) + 1) * scale;
#endif
#if S_CURVE_ACCELERATION_LEVEL == 3
#if S_CURVE_ACCELERATION_LEVEL == 5
return 0.5 * (tanh(6 * pt - 3) + 1);
#elif S_CURVE_ACCELERATION_LEVEL == 4
// from this https://forum.duet3d.com/topic/4802/6th-order-jerk-controlled-motion-planning/95
float pt_sqr = fast_flt_pow2(pt);
float k = 3.0f * (pt_sqr - 2.5f * pt) + 5.0f;
k = fast_flt_mul2(k) * pt_sqr * pt;
return k * scale;
return k;
#elif S_CURVE_ACCELERATION_LEVEL == 3
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
float k = (0.15f + ABS(pt));
int32_t *i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
k = (0.65f * pt * k + 0.5f);
return CLAMP(0, k, 1);
#elif S_CURVE_ACCELERATION_LEVEL == 2
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
float k = (0.25f + ABS(pt));
int32_t *i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
return scale * (0.75f * pt * k + 0.5f);
k = (0.75f * pt * k + 0.5f);
return CLAMP(0, k, 1);
#elif S_CURVE_ACCELERATION_LEVEL == 1
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
float k = (0.5f + ABS(pt));
int32_t *i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
return scale * (pt * k + 0.5f);
k = (pt * k + 0.5f);
return CLAMP(0, k, 1);
#elif S_CURVE_ACCELERATION_LEVEL == -1
float k, pt_sqr;
int32_t *i;
switch (g_settings.s_curve_profile)
{
case 1:
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
k = (0.5f + ABS(pt));
i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
k = (pt * k + 0.5f);
return CLAMP(0, k, 1);
case 2:
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
k = (0.25f + ABS(pt));
i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
k = (0.75f * pt * k + 0.5f);
return CLAMP(0, k, 1);
case 3:
// from this https://en.wikipedia.org/wiki/Sigmoid_function
pt -= 0.5f;
// optimized fast inverse aproximation
k = (0.15f + ABS(pt));
i = (int32_t *)&k;
*i = 0x7EEF1AA0 - *i;
k = (0.65f * pt * k + 0.5f);
return CLAMP(0, k, 1);
case 4:
// from this https://forum.duet3d.com/topic/4802/6th-order-jerk-controlled-motion-planning/95
pt_sqr = fast_flt_pow2(pt);
k = 3.0f * (pt_sqr - 2.5f * pt) + 5.0f;
k = fast_flt_mul2(k) * pt_sqr * pt;
return k;
case 5:
return 0.5 * (tanh(6 * pt - 3) + 1);
default:
// defaults to linear
return pt;
}
#endif
}
#endif
Expand Down Expand Up @@ -454,7 +508,7 @@ void itp_run(void)
float acum = acc_step_acum;
acum += acc_step;
acc_step_acum = MIN(acum, 0.999f);
float new_speed = s_curve_function(acum, acc_scale) + acc_init_speed;
float new_speed = acc_scale * s_curve_function(acum) + acc_init_speed;
new_speed = (t_acc_integrator >= 0) ? (new_speed + acc_init_speed) : (acc_init_speed - new_speed);
speed_change = new_speed - current_speed;
#else
Expand All @@ -479,7 +533,7 @@ void itp_run(void)
float acum = deac_step_acum;
acum += deac_step;
deac_step_acum = MIN(acum, 0.999f);
float new_speed = junction_speed - s_curve_function(acum, deac_scale);
float new_speed = junction_speed - deac_scale * s_curve_function(acum);
speed_change = new_speed - current_speed;
#else
speed_change = -(integrator * itp_cur_plan_block->acceleration);
Expand Down
16 changes: 4 additions & 12 deletions uCNC/src/hal/tools/tools/laser_ppi.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <float.h>
#include <math.h>

#ifndef LASER_PPI
#define LASER_PPI PWM0
#endif

// #define ENABLE_COOLANT
#ifdef ENABLE_COOLANT
#ifndef LASER_PPI_AIR_ASSIST
Expand All @@ -42,12 +46,6 @@ static void startup_code(void)
#else
io_set_output(LASER_PPI);
#endif
#elif ASSERT_PIN_EXTENDER(LASER_PPI)
#ifndef INVERT_LASER_PPI_LOGIC
io_set_output(LASER_PPI, false);
#else
io_set_output(LASER_PPI, true);
#endif
#endif
g_settings.laser_mode |= LASER_PPI_MODE;
parser_config_ppi();
Expand All @@ -61,12 +59,6 @@ static void shutdown_code(void)
#else
io_set_output(LASER_PPI);
#endif
#elif ASSERT_PIN_EXTENDER(LASER_PPI)
#ifndef INVERT_LASER_PPI_LOGIC
io_set_output(LASER_PPI, false);
#else
io_set_output(LASER_PPI, true);
#endif
#endif
// restore laser mode
g_settings.laser_mode &= ~(LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE);
Expand Down
3 changes: 3 additions & 0 deletions uCNC/src/interface/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@ void protocol_send_cnc_settings(void)
protocol_send_gcode_setting_line_flt(11, g_settings.g64_angle_factor);
protocol_send_gcode_setting_line_flt(12, g_settings.arc_tolerance);
protocol_send_gcode_setting_line_int(13, g_settings.report_inches);
#if S_CURVE_ACCELERATION_LEVEL == -1
protocol_send_gcode_setting_line_int(14, g_settings.s_curve_profile);
#endif
protocol_send_gcode_setting_line_int(20, g_settings.soft_limits_enabled);
protocol_send_gcode_setting_line_int(21, g_settings.hard_limits_enabled);
protocol_send_gcode_setting_line_int(22, g_settings.homing_enabled);
Expand Down
10 changes: 9 additions & 1 deletion uCNC/src/interface/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ const settings_t __rom__ default_settings =
.g64_angle_factor = DEFAULT_G64_FACTOR,
.arc_tolerance = DEFAULT_ARC_TOLERANCE,
.report_inches = DEFAULT_REPORT_INCHES,
#if S_CURVE_ACCELERATION_LEVEL == -1
.s_curve_profile = 0,
#endif
.soft_limits_enabled = DEFAULT_SOFT_LIMITS_ENABLED,
.hard_limits_enabled = DEFAULT_HARD_LIMITS_ENABLED,
.homing_enabled = DEFAULT_HOMING_ENABLED,
Expand Down Expand Up @@ -370,6 +373,11 @@ uint8_t settings_change(setting_offset_t id, float value)
case 13:
g_settings.report_inches = value1;
break;
#if S_CURVE_ACCELERATION_LEVEL == -1
case 14:
g_settings.s_curve_profile = CLAMP(0, value8, 5);
break;
#endif
case 20:
if (!g_settings.homing_enabled && value1)
{
Expand Down Expand Up @@ -618,7 +626,7 @@ uint16_t settings_register_external_setting(uint8_t size)
setting_offset += size + 1; // include crc
return new_offset;
#else
#warning "External/extension settings storing is disabled"
#warning "External/extension settings storing is disabled"
return UINT16_MAX;
#endif
}
3 changes: 3 additions & 0 deletions uCNC/src/interface/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ extern "C"
// juntion deviation is automatic and always on
float arc_tolerance;
bool report_inches;
#if S_CURVE_ACCELERATION_LEVEL == -1
uint8_t s_curve_profile;
#endif
bool soft_limits_enabled;
bool hard_limits_enabled;
bool homing_enabled;
Expand Down
Loading