From 623c029bfac88b53acb08071124602e1ed058be9 Mon Sep 17 00:00:00 2001 From: FormerLurker Date: Wed, 13 Jan 2021 18:37:15 -0600 Subject: [PATCH] Code cleanup to reduce program storage --- Firmware/ConfigurationStore.cpp | 2 +- Firmware/Marlin_main.cpp | 62 ++++++------------------------- Firmware/motion_control.cpp | 66 +++++++++++---------------------- 3 files changed, 34 insertions(+), 96 deletions(-) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index fec4a0c5..a24bae15 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -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 diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 0bc9c6bc..b600a1b2 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -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 S R F { - // 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; diff --git a/Firmware/motion_control.cpp b/Firmware/motion_control.cpp index cc2cabd5..44876f6c 100644 --- a/Firmware/motion_control.cpp +++ b/Firmware/motion_control.cpp @@ -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(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; }