Browse Source

Enhance arc interpolation and add M214 for controlling arc interpolation settings.

FormerLurker 4 years ago
parent
commit
4aa5a75301

+ 14 - 1
Firmware/ConfigurationStore.cpp

@@ -169,6 +169,10 @@ void Config_PrintSettings(uint8_t level)
                  echomagic, echomagic, extruder_advance_K);
 #endif //LIN_ADVANCE
 	}
+    // Arc Interpolation Settings
+    printf_P(PSTR(
+        "%SArc Settings: N=Arc segment length max (mm) S=Arc segment length Min (mm), R=Min arc segments, F=Arc segments per second.\n%S  M214 N%.2f S%.2f R%d F%d\n"),
+        echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.min_arc_segments, cs.arc_segments_per_sec);
 }
 #endif
 
@@ -184,7 +188,7 @@ static_assert (false, "zprobe_zoffset was not initialized in printers in field t
         "0.0, if this is not acceptable, increment EEPROM_VERSION to force use default_conf");
 #endif
 
-static_assert (sizeof(M500_conf) == 196, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, "
+static_assert (sizeof(M500_conf) == 208, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, "
         "or if you added members in the end of struct, ensure that historically uninitialized values will be initialized."
         "If this is caused by change to more then 8bit processor, decide whether make this struct packed to save EEPROM,"
         "leave as it is to keep fast code, or reorder struct members to pack more tightly.");
@@ -233,6 +237,10 @@ static const M500_conf default_conf PROGMEM =
     {16,16,16,16},
 #endif
     DEFAULT_TRAVEL_ACCELERATION,
+    DEFAULT_MM_PER_ARC_SEGMENT,
+    DEFAULT_MIN_MM_PER_ARC_SEGMENT,
+    DEFAULT_MIN_ARC_SEGMENTS,
+    DEFAULT_ARC_SEGMENTS_PER_SEC
 };
 
 
@@ -273,6 +281,11 @@ bool Config_RetrieveSettings()
                 memcpy_P(&cs.max_acceleration_units_per_sq_second_silent[i],&default_conf.max_acceleration_units_per_sq_second_silent[i],sizeof(cs.max_acceleration_units_per_sq_second_silent[i]));
             }
         }
+        // Initialize arc interpolation settings if they are not already (Not sure about this bit, please review)
+        if (0xff == cs.mm_per_arc_segment) cs.mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT;
+        if (0xff == cs.min_mm_per_arc_segment) cs.min_mm_per_arc_segment = DEFAULT_MIN_MM_PER_ARC_SEGMENT;
+        if (0xff == cs.min_arc_segments) cs.min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS;
+        if (0xff == cs.arc_segments_per_sec) cs.arc_segments_per_sec = DEFAULT_ARC_SEGMENTS_PER_SEC;
 
 #ifdef TMC2130
 		for (uint8_t j = X_AXIS; j <= Y_AXIS; j++)

+ 5 - 0
Firmware/ConfigurationStore.h

@@ -39,6 +39,11 @@ typedef struct
     unsigned long max_acceleration_units_per_sq_second_silent[4];
     unsigned char axis_ustep_resolution[4];
     float travel_acceleration; //!< travel acceleration mm/s^2
+    // Arc Interpolation Settings, configurable via M214
+    float mm_per_arc_segment;
+    float min_mm_per_arc_segment;
+    int min_arc_segments; // If less than or equal to zero, this is disabled
+    int arc_segments_per_sec; // If less than or equal to zero, this is disabled
 } M500_conf;
 
 extern M500_conf cs;

+ 1 - 3
Firmware/Configuration_adv.h

@@ -289,9 +289,7 @@
   //#define LA_DEBUG_LOGIC     // @wavexx: setup logic channels for isr debugging
 #endif
 
-// Arc interpretation settings:
-#define MM_PER_ARC_SEGMENT 1
-#define N_ARC_CORRECTION 25
+// Arc interpretation settings : Moded to printer default settings (Configuration_prusa.h)
 
 const unsigned int dropsegments=5; //everything with less than this number of steps will be ignored as move and joined with the next movement
 

+ 89 - 13
Firmware/Marlin_main.cpp

@@ -7502,9 +7502,88 @@ Sigma_Exit:
       }
 
     }break;
-#endif // FWRETRACT
+    #endif // FWRETRACT
+    /*!
+    ### M214 - Set Arc configuration values (Use M500 to store in eeprom)
+
+    #### Usage
 
+        M214 [N] [S] [R] [F]
+
+    #### Parameters
+    - `N` - 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
+    - `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.
+    - 'F' - An int representing the number of segments per second, unless this results in segment lengths
+            greater than or less than the minimum and maximum segment length.  Set to 0 to disable.
+    */
+    case 214: //!@n M214 - Set Arc Parameters (Use M500 to store in eeprom) N<MM_PER_ARC_SEGMENT> S<MIN_MM_PER_ARC_SEGMENT> R<MIN_ARC_SEGMENTS> F<ARC_SEGMENTS_PER_SEC>
+    {
+        // Extract N
+        float n = cs.mm_per_arc_segment;
+        float s = cs.min_mm_per_arc_segment;
+        int r = cs.min_arc_segments;
+        int f = cs.arc_segments_per_sec;
+        // Extract N
+        if (code_seen('N'))
+        {
+            n = code_value();
+            if (n <= 0 || (s != 0 && n <= s))
+            {
+                SERIAL_ECHO_START;
+                SERIAL_ECHORPGM(MSG_UNKNOWN_COMMAND);
+                SERIAL_ECHO(CMDBUFFER_CURRENT_STRING);
+                SERIAL_ECHOLNPGM("\"(1)");
+                break;
+            }
+        }
+        // Extract S
+        if (code_seen('S'))
+        {
+            s = code_value();
+            if (s < 0 || s >= n)
+            {
+                SERIAL_ECHO_START;
+                SERIAL_ECHORPGM(MSG_UNKNOWN_COMMAND);
+                SERIAL_ECHO(CMDBUFFER_CURRENT_STRING);
+                SERIAL_ECHOLNPGM("\"(1)");
+                break;
+            }
+        }
+        // Extract R
+        if (code_seen('R'))
+        {
 
+            r = code_value();
+            if (r < 0)
+            {
+                SERIAL_ECHO_START;
+                SERIAL_ECHORPGM(MSG_UNKNOWN_COMMAND);
+                SERIAL_ECHO(CMDBUFFER_CURRENT_STRING);
+                SERIAL_ECHOLNPGM("\"(1)");
+                break;
+            }
+        }
+        // Extract F
+        if (code_seen('F'))
+        {
+            f = code_value();
+            if (f < 0)
+            {
+                SERIAL_ECHO_START;
+                SERIAL_ECHORPGM(MSG_UNKNOWN_COMMAND);
+                SERIAL_ECHO(CMDBUFFER_CURRENT_STRING);
+                SERIAL_ECHOLNPGM("\"(1)");
+                break;
+            }
+        }
+        cs.mm_per_arc_segment = n;
+        cs.min_mm_per_arc_segment = s;
+        cs.min_arc_segments = r;
+        cs.arc_segments_per_sec = f;
+    }break;
     #if EXTRUDERS > 1
 
     /*!
@@ -9641,18 +9720,15 @@ void prepare_move()
   set_current_to_destination();
 }
 
-void prepare_arc_move(bool isclockwise) {
-  float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
-
-  // Trace the arc
-  mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedmultiply/60/100.0, r, isclockwise, active_extruder);
-
-  // As far as the parser is concerned, the position is now == target. In reality the
-  // motion control system might still be processing the action and the real tool position
-  // in any intermediate location.
-  set_current_to_destination();
-
-  previous_millis_cmd.start();
+void prepare_arc_move(char isclockwise) {
+    float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
+    // Trace the arc
+    mc_arc(current_position, destination, offset, feedrate * feedmultiply / 60 / 100.0, r, isclockwise, active_extruder);
+    // As far as the parser is concerned, the position is now == target. In reality the
+    // motion control system might still be processing the action and the real tool position
+    // in any intermediate location.
+    set_current_to_destination();
+    previous_millis_cmd.start();
 }
 
 #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1

+ 134 - 114
Firmware/motion_control.cpp

@@ -4,7 +4,8 @@
 
   Copyright (c) 2009-2011 Simen Svale Skogsrud
   Copyright (c) 2011 Sungeun K. Jeon
-  
+  Copyright (c) 2020 Brad Hochgesang
+
   Grbl is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
@@ -25,121 +26,140 @@
 
 // The arc is approximated by generating a huge number of tiny, linear segments. The length of each 
 // segment is configured in settings.mm_per_arc_segment.  
-void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1, 
-  uint8_t axis_linear, float feed_rate, float radius, bool isclockwise, uint8_t extruder)
-{      
-  //   int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled();
-  //   plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc
-  float center_axis0 = position[axis_0] + offset[axis_0];
-  float center_axis1 = position[axis_1] + offset[axis_1];
-  float linear_travel = target[axis_linear] - position[axis_linear];
-  float extruder_travel = target[E_AXIS] - position[E_AXIS];
-  float r_axis0 = -offset[axis_0];  // Radius vector from center to current location
-  float r_axis1 = -offset[axis_1];
-  float rt_axis0 = target[axis_0] - center_axis0;
-  float rt_axis1 = target[axis_1] - center_axis1;
-  
-  // CCW angle between position and target from circle center. Only one atan2() trig computation required.
-  float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
-  if (angular_travel < 0) { angular_travel += 2*M_PI; }
-  if (isclockwise) { angular_travel -= 2*M_PI; }
-  
-  //20141002:full circle for G03 did not work, e.g. G03 X80 Y80 I20 J0 F2000 is giving an Angle of zero so head is not moving
-  //to compensate when start pos = target pos && angle is zero -> angle = 2Pi
-  if (position[axis_0] == target[axis_0] && position[axis_1] == target[axis_1] && angular_travel == 0)
-  {
-	  angular_travel += 2*M_PI;
-  }
-  //end fix G03
-  
-  float millimeters_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
-  if (millimeters_of_travel < 0.001) { return; }
-  uint16_t segments = floor(millimeters_of_travel/MM_PER_ARC_SEGMENT);
-  if(segments == 0) segments = 1;
-  
-  /*  
-    // Multiply inverse feed_rate to compensate for the fact that this movement is approximated
-    // by a number of discrete segments. The inverse feed_rate should be correct for the sum of 
-    // all segments.
-    if (invert_feed_rate) { feed_rate *= segments; }
-  */
-  float theta_per_segment = angular_travel/segments;
-  float linear_per_segment = linear_travel/segments;
-  float extruder_per_segment = extruder_travel/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);
-                sin(phi)  cos(phi] * r ;
-     
-     For arc generation, the center of the circle is the axis of rotation and the radius vector is 
-     defined from the circle center to the initial position. Each line segment is formed by successive
-     vector rotations. This requires only two cos() and sin() computations to form the rotation
-     matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
-     all double numbers are single precision on the Arduino. (True double precision will not have
-     round off issues for CNC applications.) Single precision error can accumulate to be greater than
-     tool precision in some cases. Therefore, arc path correction is implemented. 
-
-     Small angle approximation may be used to reduce computation overhead further. This approximation
-     holds for everything, but very small circles and large mm_per_arc_segment values. In other words,
-     theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
-     to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for 
-     numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
-     issue for CNC machines with the single precision Arduino calculations.
-     
-     This approximation also allows mc_arc to immediately insert a line segment into the planner 
-     without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
-     a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead. 
-     This is important when there are successive arc motions. 
-  */
-  // Vector rotation matrix values
-  float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
-  float sin_T = theta_per_segment;
-  
-  float arc_target[4];
-  float sin_Ti;
-  float cos_Ti;
-  float r_axisi;
-  uint16_t i;
-  int8_t count = 0;
-
-  // Initialize the linear axis
-  arc_target[axis_linear] = position[axis_linear];
-  
-  // Initialize the extruder axis
-  arc_target[E_AXIS] = position[E_AXIS];
-
-  for (i = 1; i<segments; i++) { // Increment (segments-1)
-    
-    if (count < N_ARC_CORRECTION) {
-      // Apply vector rotation matrix 
-      r_axisi = r_axis0*sin_T + r_axis1*cos_T;
-      r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
-      r_axis1 = r_axisi;
-      count++;
-    } else {
-      // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
-      // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
-      cos_Ti = cos(i*theta_per_segment);
-      sin_Ti = sin(i*theta_per_segment);
-      r_axis0 = -offset[axis_0]*cos_Ti + offset[axis_1]*sin_Ti;
-      r_axis1 = -offset[axis_0]*sin_Ti - offset[axis_1]*cos_Ti;
-      count = 0;
+void mc_arc(float* position, float* target, float* offset, float feed_rate, float radius, uint8_t isclockwise, uint8_t extruder)
+{
+    // Extract the position to reduce indexing at the cost of a few bytes of mem
+    float p_x = position[X_AXIS];
+    float p_y = position[Y_AXIS];
+    float p_z = position[Z_AXIS];
+    float p_e = position[E_AXIS];
+
+    float t_x = target[X_AXIS];
+    float t_y = target[Y_AXIS];
+    float t_z = target[Z_AXIS];
+    float t_e = target[E_AXIS];
+
+    float r_axis_x = -offset[X_AXIS];  // Radius vector from center to current location
+    float r_axis_y = -offset[Y_AXIS];
+    float center_axis_x = p_x - r_axis_x;
+    float center_axis_y = p_y - r_axis_y;
+    float travel_z = t_z - p_z;
+    float extruder_travel_total = t_e - p_e;
+
+    float rt_x = t_x - center_axis_x;
+    float rt_y = t_y - 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;
+
+    // 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;
     }
 
-    // Update arc_target location
-    arc_target[axis_0] = center_axis0 + r_axis0;
-    arc_target[axis_1] = center_axis1 + r_axis1;
-    arc_target[axis_linear] += linear_per_segment;
-    arc_target[E_AXIS] += extruder_per_segment;
+    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;
+    }
 
-    clamp_to_software_endstops(arc_target);
-    plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, extruder);
-    
-  }
-  // Ensure last segment arrives at target location.
-  plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, extruder);
+    if (cs.min_mm_per_arc_segment > 0)
+    {
+        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;
+    }
+
+    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;
 
-  //   plan_set_acceleration_manager_enabled(acceleration_manager_was_enabled);
-}
 
+
+    // Adjust the angular travel if the direction is clockwise
+    if (isclockwise) { angular_travel_total -= 2 * M_PI; }
+
+    //20141002:full circle for G03 did not work, e.g. G03 X80 Y80 I20 J0 F2000 is giving an Angle of zero so head is not moving
+    //to compensate when start pos = target pos && angle is zero -> angle = 2Pi
+    if (p_x == t_x && p_y == t_y && angular_travel_total == 0)
+    {
+        angular_travel_total += 2 * M_PI;
+    }
+    //end fix G03
+
+    // 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));
+    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);
+                  sin(phi)  cos(phi] * r ;
+
+       For arc generation, the center of the circle is the axis of rotation and the radius vector is
+       defined from the circle center to the initial position. Each line segment is formed by successive
+       vector rotations. This requires only two cos() and sin() computations to form the rotation
+       matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
+       all double numbers are single precision on the Arduino. (True double precision will not have
+       round off issues for CNC applications.) Single precision error can accumulate to be greater than
+       tool precision in some cases. Therefore, arc path correction is implemented.
+
+       The small angle approximation was removed because of excessive errors for small circles (perhaps unique to
+       3d printing applications, causing significant path deviation and extrusion issues).
+       Now there will be no corrections applied, but an accurate initial sin and cos will be calculated.
+       This seems to work with a very high degree of accuracy and results in much simpler code.
+
+       Finding a faster way to approximate sin, knowing that there can be substantial deviations from the true
+       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 (segments > 1)
+    {
+        // Initialize the extruder axis
+
+        float cos_T = cos(theta_per_segment);
+        float sin_T = sin(theta_per_segment);
+        float r_axisi;
+        uint16_t i;
+
+        for (i = 1; i < segments; i++) { // Increment (segments-1)
+            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;
+
+            // Update arc_target location
+            p_x = center_axis_x + r_axis_x;
+            p_y = center_axis_y + r_axis_y;
+            p_z += linear_per_segment;
+            p_e += segment_extruder_travel;
+            // We can't clamp to the target because we are interpolating!  We would need to update a position, clamp to it
+            // after updating from calculated values.
+            //clamp_to_software_endstops(position);
+            plan_buffer_line(p_x, p_y, p_z, p_e, feed_rate, extruder);
+        }
+    }
+    // Ensure last segment arrives at target location.
+    // Here we could clamp, but why bother.  We would need to update our current position, clamp to it
+    //clamp_to_software_endstops(target);
+    plan_buffer_line(t_x, t_y, t_z, t_e, feed_rate, extruder);
+}

+ 2 - 2
Firmware/motion_control.h

@@ -26,7 +26,7 @@
 // offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is
 // the direction of helical travel, radius == circle radius, isclockwise boolean. Used
 // for vector transformation direction.
-void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1,
-  uint8_t axis_linear, float feed_rate, float radius, bool isclockwise, uint8_t extruder);
+void mc_arc(float *position, float *target, float *offset, float feed_rate, float radius,
+  unsigned char isclockwise, uint8_t extruder);
   
 #endif

+ 8 - 0
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -525,4 +525,12 @@
 
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -529,4 +529,12 @@
 //#define HEATBED_ANALYSIS //for meash bed leveling and heatbed analysis D-codes D80 and D81
 //#define MICROMETER_LOGGING //related to D-codes D80 and D81, currently works on MK2.5 only (MK3 board pin definitions missing)
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h

@@ -532,4 +532,12 @@
 //#define MMU_ALWAYS_CUT
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h

@@ -533,4 +533,12 @@
 //#define MMU_ALWAYS_CUT
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -671,4 +671,12 @@
 #define MMU_HAS_CUTTER
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -683,4 +683,12 @@
 //#define MMU_ALWAYS_CUT
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/obsolete/1_75mm_MK2-RAMBo10a-E3Dv6full.h

@@ -449,4 +449,12 @@ THERMISTORS SETTINGS
 
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H

+ 8 - 0
Firmware/variants/obsolete/1_75mm_MK2-RAMBo13a-E3Dv6full.h

@@ -438,4 +438,12 @@ THERMISTORS SETTINGS
 
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
+// Default Arc Interpolation Settings (Now configurable via M214)
+#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
+    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
+    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+
 #endif //__CONFIGURATION_PRUSA_H