Browse Source

Add support for G2/G3 with R parameter

Scott Lahteine 8 years ago
parent
commit
c2744d8a8b
2 changed files with 51 additions and 9 deletions
  1. 50
    9
      Marlin/Marlin_main.cpp
  2. 1
    0
      Marlin/language.h

+ 50
- 9
Marlin/Marlin_main.cpp View File

@@ -2511,6 +2511,25 @@ inline void gcode_G0_G1() {
2511 2511
 /**
2512 2512
  * G2: Clockwise Arc
2513 2513
  * G3: Counterclockwise Arc
2514
+ *
2515
+ * This command has two forms: IJ-form and R-form.
2516
+ *
2517
+ *  - I specifies an X offset. J specifies a Y offset.
2518
+ *    At least one of the IJ parameters is required.
2519
+ *    X and Y can be omitted to do a complete circle.
2520
+ *    The given XY is not error-checked. The arc ends
2521
+ *     based on the angle of the destination.
2522
+ *    Mixing I or J with R will throw an error.
2523
+ *
2524
+ *  - R specifies the radius. X or Y is required.
2525
+ *    Omitting both X and Y will throw an error.
2526
+ *    X or Y must differ from the current XY.
2527
+ *    Mixing R with I or J will throw an error.
2528
+ *
2529
+ *  Examples:
2530
+ *
2531
+ *    G2 I10           ; CW circle centered at X+10
2532
+ *    G3 X20 Y12 R14   ; CCW circle with r=14 ending at X20 Y12
2514 2533
  */
2515 2534
 #if ENABLED(ARC_SUPPORT)
2516 2535
   inline void gcode_G2_G3(bool clockwise) {
@@ -2527,16 +2546,38 @@ inline void gcode_G0_G1() {
2527 2546
         relative_mode = relative_mode_backup;
2528 2547
       #endif
2529 2548
 
2530
-      // Center of arc as offset from current_position
2531
-      float arc_offset[2] = {
2532
-        code_seen('I') ? code_value_axis_units(X_AXIS) : 0,
2533
-        code_seen('J') ? code_value_axis_units(Y_AXIS) : 0
2534
-      };
2535
-
2536
-      // Send an arc to the planner
2537
-      plan_arc(destination, arc_offset, clockwise);
2549
+      float arc_offset[2] = { 0.0, 0.0 };
2550
+      if (code_seen('R')) {
2551
+        const float r = code_value_axis_units(X_AXIS),
2552
+                    x1 = current_position[X_AXIS], y1 = current_position[Y_AXIS],
2553
+                    x2 = destination[X_AXIS], y2 = destination[Y_AXIS];
2554
+        if (r && (x2 != x1 || y2 != y1)) {
2555
+          const float e = clockwise ? -1 : 1,                     // clockwise -1, counterclockwise 1
2556
+                      dx = x2 - x1, dy = y2 - y1,                 // X and Y differences
2557
+                      d = HYPOT(dx, dy),                          // Linear distance between the points
2558
+                      h = sqrt(sq(r) - sq(d * 0.5)),              // Distance to the arc pivot-point
2559
+                      mx = (x1 + x2) * 0.5, my = (y1 + y2) * 0.5, // Point between the two points
2560
+                      sx = -dy / d, sy = dx / d,                  // Slope of the perpendicular bisector
2561
+                      cx = mx + e * h * sx, cy = my + e * h * sy; // Pivot-point of the arc
2562
+          arc_offset[X_AXIS] = cx - x1;
2563
+          arc_offset[Y_AXIS] = cy - y1;
2564
+        }
2565
+      }
2566
+      else {
2567
+        if (code_seen('I')) arc_offset[X_AXIS] = code_value_axis_units(X_AXIS);
2568
+        if (code_seen('J')) arc_offset[Y_AXIS] = code_value_axis_units(Y_AXIS);
2569
+      }
2538 2570
 
2539
-      refresh_cmd_timeout();
2571
+      if (arc_offset[0] || arc_offset[1]) {
2572
+        // Send an arc to the planner
2573
+        plan_arc(destination, arc_offset, clockwise);
2574
+        refresh_cmd_timeout();
2575
+      }
2576
+      else {
2577
+        // Bad arguments
2578
+        SERIAL_ERROR_START;
2579
+        SERIAL_ERRORLNPGM(MSG_ERR_ARC_ARGS);
2580
+      }
2540 2581
     }
2541 2582
   }
2542 2583
 #endif

+ 1
- 0
Marlin/language.h View File

@@ -150,6 +150,7 @@
150 150
 #define MSG_ERR_MATERIAL_INDEX              "M145 S<index> out of range (0-1)"
151 151
 #define MSG_ERR_M421_PARAMETERS             "M421 requires XYZ or IJZ parameters"
152 152
 #define MSG_ERR_MESH_XY                     "Mesh XY or IJ cannot be resolved"
153
+#define MSG_ERR_ARC_ARGS                    "G2/G3 bad parameters"
153 154
 #define MSG_ERR_M428_TOO_FAR                "Too far from reference point"
154 155
 #define MSG_ERR_M303_DISABLED               "PIDTEMP disabled"
155 156
 #define MSG_M119_REPORT                     "Reporting endstop status"

Loading…
Cancel
Save