Skip to content

Commit

Permalink
🐛 Prevent arc segments > configured size
Browse files Browse the repository at this point in the history
Fixing #22571
  • Loading branch information
thinkyhead committed Aug 19, 2021
1 parent 033e65e commit cb40c3e
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions Marlin/src/gcode/motion/G2_G3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ void plan_arc(

const feedRate_t scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);

// Start with a nominal segment length
float seg_length = (
// Determine the segment length based on settings
const float seg_length = (
#ifdef ARC_SEGMENTS_PER_R
constrain(MM_PER_ARC_SEGMENT * radius, MM_PER_ARC_SEGMENT, ARC_SEGMENTS_PER_R)
#elif ARC_SEGMENTS_PER_SEC
Expand All @@ -157,10 +157,14 @@ void plan_arc(
MM_PER_ARC_SEGMENT
#endif
);
// Divide total travel by nominal segment length
// Divide total travel by segment length
uint16_t segments = FLOOR(mm_of_travel / seg_length);
NOLESS(segments, min_segments); // At least some segments
seg_length = mm_of_travel / segments;

// Are the segments now too few to reach the destination?
const float segmented_length = seg_length * segments;
const bool tooshort = segmented_length < mm_of_travel - 0.1f;
const float proportion = tooshort ? segmented_length / mm_of_travel : 1.0f;

/**
* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
Expand Down Expand Up @@ -190,26 +194,29 @@ void plan_arc(
*/
// Vector rotation matrix values
xyze_pos_t raw;
const float theta_per_segment = angular_travel / segments,
const float theta_per_segment = proportion * angular_travel / segments,
sq_theta_per_segment = sq(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; // Small angle approximation

#if HAS_Z_AXIS && DISABLED(AUTO_BED_LEVELING_UBL)
const float linear_per_segment = linear_travel / segments;
const float linear_per_segment = proportion * linear_travel / segments;
#endif
#if HAS_EXTRUDERS
const float extruder_per_segment = extruder_travel / segments;
const float extruder_per_segment = proportion * extruder_travel / segments;
#endif

// For shortened segments, run all but the remainder in the loop
if (tooshort) segments++;

// Initialize the linear axis
TERN_(HAS_Z_AXIS, raw[l_axis] = current_position[l_axis]);

// Initialize the extruder axis
TERN_(HAS_EXTRUDERS, raw.e = current_position.e);

#if ENABLED(SCARA_FEEDRATE_SCALING)
const float inv_duration = scaled_fr_mm_s / seg_length;
const float inv_duration = scaled_fr_mm_s * segments / mm_of_travel;
#endif

millis_t next_idle_ms = millis() + 200UL;
Expand All @@ -221,8 +228,9 @@ void plan_arc(
for (uint16_t i = 1; i < segments; i++) { // Iterate (segments-1) times

thermalManager.manage_heater();
if (ELAPSED(millis(), next_idle_ms)) {
next_idle_ms = millis() + 200UL;
const millis_t ms = millis();
if (ELAPSED(ms, next_idle_ms)) {
next_idle_ms = ms + 200UL;
idle();
}

Expand Down

0 comments on commit cb40c3e

Please sign in to comment.