Code cleanup to reduce program storage

This commit is contained in:
FormerLurker 2021-01-13 18:37:15 -06:00 committed by Alex Voinea
parent acc234b0c5
commit 623c029bfa
3 changed files with 34 additions and 96 deletions

View File

@ -171,7 +171,7 @@ void Config_PrintSettings(uint8_t level)
}
// Arc Interpolation Settings
printf_P(PSTR(
"%SArc Settings: P=Arc segment length max (mm) S=Arc segment length Min (mm), N=Num Segments Per Correction, R=Min arc segments, F=Arc segments per second.\n%S M214 P%.2f S%.2f N%d R%d F%d\n"),
"%SArc Settings: P:Max length(mm) S:Min length (mm) N:Corrections R:Min segments F:Segments/sec.\n%S M214 P%.2f S%.2f N%d R%d F%d\n"),
echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.n_arc_correction, cs.min_arc_segments, cs.arc_segments_per_sec);
}
#endif

View File

@ -4901,6 +4901,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
#### Parameters
- `X` - The position to move to on the X axis
- `Y` - The position to move to on the Y axis
- 'Z' - The position to move to on the Z axis
- `I` - The point in X space from the current X position to maintain a constant distance from
- `J` - The point in Y space from the current Y position to maintain a constant distance from
- `E` - The amount to extrude between the starting point and ending point
@ -7514,7 +7515,7 @@ Sigma_Exit:
#### Parameters
- `P` - A float representing the max and default millimeters per arc segment. Must be greater than 0.
- `S` - A float representing the minimum allowable millimeters per arc segment. Set to 0 to disable
- `N` - An int representing the number of arcs to draw before correcting the small angle approximation. Set to 1 or 0 to disable.
- `N` - An int representing the number of arcs to draw before correcting the small angle approximation. Set to 0 to disable.
- `R` - An int representing the minimum number of segments per arcs of any radius,
except when the results in segment lengths greater than or less than the minimum
and maximum segment length. Set to 0 to disable.
@ -7523,60 +7524,19 @@ Sigma_Exit:
*/
case 214: //!@n M214 - Set Arc Parameters (Use M500 to store in eeprom) P<MM_PER_ARC_SEGMENT> S<MIN_MM_PER_ARC_SEGMENT> R<MIN_ARC_SEGMENTS> F<ARC_SEGMENTS_PER_SEC>
{
// Extract N
float p = cs.mm_per_arc_segment;
float s = cs.min_mm_per_arc_segment;
uint8_t n = cs.n_arc_correction;
uint16_t r = cs.min_arc_segments;
uint16_t f = cs.arc_segments_per_sec;
// Extract all possible parameters if they appear
float p = code_seen('P') ? code_value_float() : cs.mm_per_arc_segment;
float s = code_seen('S') ? code_value_float() : cs.min_mm_per_arc_segment;
uint8_t n = code_seen('N') ? code_value() : cs.n_arc_correction;
uint16_t r = code_seen('R') ? code_value() : cs.min_arc_segments;
uint16_t f = code_seen('F') ? code_value() : cs.arc_segments_per_sec;
// Extract N
if (code_seen('P'))
// Ensure mm_per_arc_segment is greater than 0, and that min_mm_per_arc_segment is sero or greater than or equal to mm_per_arc_segment
if (p <=0 || s < 0 || p < s)
{
p = code_value_float();
if (p <= 0 || (s != 0 && p <= s))
{
break;
}
break;
}
// Extract S
if (code_seen('S'))
{
s = code_value_float();
if (s < 0 || s >= p)
{
break;
}
}
// Extract N
if (code_seen('N'))
{
n = code_value();
if (n < 0)
{
break;
}
}
// Extract R
if (code_seen('R'))
{
r = code_value();
if (r < 0)
{
break;
}
}
// Extract F
if (code_seen('F'))
{
f = code_value();
if (f < 0)
{
break;
}
}
cs.mm_per_arc_segment = p;
cs.min_mm_per_arc_segment = s;
cs.n_arc_correction = n;

View File

@ -33,49 +33,43 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
float center_axis_x = position[X_AXIS] - r_axis_x;
float center_axis_y = position[Y_AXIS] - r_axis_y;
float travel_z = target[Z_AXIS] - position[Z_AXIS];
float extruder_travel_total = target[E_AXIS] - position[E_AXIS];
float rt_x = target[X_AXIS] - center_axis_x;
float rt_y = target[Y_AXIS] - center_axis_y;
// 20200419 - Add a variable that will be used to hold the arc segment length
float mm_per_arc_segment = cs.mm_per_arc_segment;
// 20210109 - Add a variable to hold the n_arc_correction value
bool correction_enabled = cs.n_arc_correction > 1;
uint8_t n_arc_correction = cs.n_arc_correction;
// CCW angle between position and target from circle center. Only one atan2() trig computation required.
float angular_travel_total = atan2(r_axis_x * rt_y - r_axis_y * rt_x, r_axis_x * rt_x + r_axis_y * rt_y);
if (angular_travel_total < 0) { angular_travel_total += 2 * M_PI; }
bool check_mm_per_arc_segment_max = false;
if (cs.min_arc_segments > 0)
{
// 20200417 - FormerLurker - Implement MIN_ARC_SEGMENTS if it is defined - from Marlin 2.0 implementation
// Do this before converting the angular travel for clockwise rotation
mm_per_arc_segment = radius * ((2.0f * M_PI) / cs.min_arc_segments);
check_mm_per_arc_segment_max = true;
}
if (cs.arc_segments_per_sec > 0)
{
// 20200417 - FormerLurker - Implement MIN_ARC_SEGMENTS if it is defined - from Marlin 2.0 implementation
float mm_per_arc_segment_sec = (feed_rate / 60.0f) * (1.0f / cs.arc_segments_per_sec);
if (mm_per_arc_segment_sec < mm_per_arc_segment)
mm_per_arc_segment = mm_per_arc_segment_sec;
check_mm_per_arc_segment_max = true;
}
if (cs.min_mm_per_arc_segment > 0)
// Note: no need to check to see if min_mm_per_arc_segment is enabled or not (i.e. = 0), since mm_per_arc_segment can never be below 0.
if (mm_per_arc_segment < cs.min_mm_per_arc_segment)
{
check_mm_per_arc_segment_max = true;
// 20200417 - FormerLurker - Implement MIN_MM_PER_ARC_SEGMENT if it is defined
// This prevents a very high number of segments from being generated for curves of a short radius
if (mm_per_arc_segment < cs.min_mm_per_arc_segment) mm_per_arc_segment = cs.min_mm_per_arc_segment;
mm_per_arc_segment = cs.min_mm_per_arc_segment;
}
else if (mm_per_arc_segment > cs.mm_per_arc_segment){
// 20210113 - This can be implemented in an else if since we can't be below the min AND above the max at the same time.
// 20200417 - FormerLurker - Implement MIN_MM_PER_ARC_SEGMENT if it is defined
mm_per_arc_segment = cs.mm_per_arc_segment;
}
if (check_mm_per_arc_segment_max && mm_per_arc_segment > cs.mm_per_arc_segment) mm_per_arc_segment = cs.mm_per_arc_segment;
// Adjust the angular travel if the direction is clockwise
if (isclockwise) { angular_travel_total -= 2 * M_PI; }
@ -90,18 +84,12 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
// 20200417 - FormerLurker - rename millimeters_of_travel to millimeters_of_travel_arc to better describe what we are
// calculating here
float millimeters_of_travel_arc = hypot(angular_travel_total * radius, fabs(travel_z));
const float millimeters_of_travel_arc = hypot(angular_travel_total * radius, fabs(travel_z));
if (millimeters_of_travel_arc < 0.001) { return; }
// Calculate the total travel per segment
// Calculate the number of arc segments
uint16_t segments = static_cast<uint16_t>(ceil(millimeters_of_travel_arc / mm_per_arc_segment));
// Calculate theta per segments and linear (z) travel per segment
float theta_per_segment = angular_travel_total / segments;
float linear_per_segment = travel_z / (segments);
// Calculate the extrusion amount per segment
float segment_extruder_travel = extruder_travel_total / (segments);
/* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
r_T = [cos(phi) -sin(phi);
@ -124,30 +112,20 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
arc when using the previous approximation, would be beneficial.
*/
// Don't bother calculating cot_T or sin_T if there is only 1 segment.
// If there is only one segment, no need to do a bunch of work since this is a straight line!
if (segments > 1)
{
// Initialize the extruder axis
float cos_T;
float sin_T;
if (correction_enabled){
float sq_theta_per_segment = theta_per_segment * theta_per_segment;
// Small angle approximation
sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
cos_T = 1 - 0.5f * sq_theta_per_segment;
}
else {
cos_T = cos(theta_per_segment);
sin_T = sin(theta_per_segment);
}
float r_axisi;
uint16_t i;
for (i = 1; i < segments; i++) { // Increment (segments-1)
if (correction_enabled && --n_arc_correction == 0) {
// Calculate theta per segments and linear (z) travel per segment
const float theta_per_segment = angular_travel_total / segments,
linear_per_segment = travel_z / (segments),
segment_extruder_travel = (target[E_AXIS] - position[E_AXIS]) / (segments),
sq_theta_per_segment = theta_per_segment * theta_per_segment,
sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
cos_T = 1 - 0.5f * sq_theta_per_segment;
for (uint16_t i = 1; i < segments; i++) { // Increment (segments-1)
if (n_arc_correction--<1) {
// Calculate the actual position for r_axis_x and r_axis_y
const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment);
r_axis_x = -offset[X_AXIS] * cos_Ti + offset[Y_AXIS] * sin_Ti;
@ -156,7 +134,7 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
n_arc_correction = cs.n_arc_correction;
}
else {
r_axisi = r_axis_x * sin_T + r_axis_y * cos_T;
const float r_axisi = r_axis_x * sin_T + r_axis_y * cos_T;
r_axis_x = r_axis_x * cos_T - r_axis_y * sin_T;
r_axis_y = r_axisi;
}