Browse Source

Merge pull request #3744 from thinkyhead/rc_bezier_curves

Add BEZIER_CURVE_SUPPORT — G5 command
Scott Lahteine 9 years ago
parent
commit
3016dfe484

+ 6
- 0
.travis.yml View File

194
   - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY
194
   - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY
195
   - build_marlin
195
   - build_marlin
196
   #
196
   #
197
+  # Enable BEZIER_CURVE_SUPPORT
198
+  #
199
+  - restore_configs
200
+  - opt_enable_adv BEZIER_CURVE_SUPPORT
201
+  - build_marlin
202
+  #
197
   # Enable COREXY
203
   # Enable COREXY
198
   #
204
   #
199
   - restore_configs
205
   - restore_configs

+ 3
- 2
Marlin/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 0
- 1
Marlin/Marlin.h View File

250
 void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued
250
 void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued
251
 void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
251
 void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
252
 
252
 
253
-void prepare_arc_move(char isclockwise);
254
 void clamp_to_software_endstops(float target[3]);
253
 void clamp_to_software_endstops(float target[3]);
255
 
254
 
256
 extern millis_t previous_cmd_ms;
255
 extern millis_t previous_cmd_ms;

+ 71
- 1
Marlin/Marlin_main.cpp View File

45
   #include "mesh_bed_leveling.h"
45
   #include "mesh_bed_leveling.h"
46
 #endif
46
 #endif
47
 
47
 
48
+#if ENABLED(BEZIER_CURVE_SUPPORT)
49
+  #include "planner_bezier.h"
50
+#endif
51
+
48
 #include "ultralcd.h"
52
 #include "ultralcd.h"
49
 #include "planner.h"
53
 #include "planner.h"
50
 #include "stepper.h"
54
 #include "stepper.h"
102
  * G2  - CW ARC
106
  * G2  - CW ARC
103
  * G3  - CCW ARC
107
  * G3  - CCW ARC
104
  * G4  - Dwell S<seconds> or P<milliseconds>
108
  * G4  - Dwell S<seconds> or P<milliseconds>
109
+ * G5  - Cubic B-spline with
105
  * G10 - retract filament according to settings of M207
110
  * G10 - retract filament according to settings of M207
106
  * G11 - retract recover filament according to settings of M208
111
  * G11 - retract recover filament according to settings of M208
107
  * G28 - Home one or more axes
112
  * G28 - Home one or more axes
510
   void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise);
515
   void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise);
511
 #endif
516
 #endif
512
 
517
 
518
+#if ENABLED(BEZIER_CURVE_SUPPORT)
519
+  void plan_cubic_move(const float offset[4]);
520
+#endif
521
+
513
 void serial_echopair_P(const char* s_P, int v)           { serialprintPGM(s_P); SERIAL_ECHO(v); }
522
 void serial_echopair_P(const char* s_P, int v)           { serialprintPGM(s_P); SERIAL_ECHO(v); }
514
 void serial_echopair_P(const char* s_P, long v)          { serialprintPGM(s_P); SERIAL_ECHO(v); }
523
 void serial_echopair_P(const char* s_P, long v)          { serialprintPGM(s_P); SERIAL_ECHO(v); }
515
 void serial_echopair_P(const char* s_P, float v)         { serialprintPGM(s_P); SERIAL_ECHO(v); }
524
 void serial_echopair_P(const char* s_P, float v)         { serialprintPGM(s_P); SERIAL_ECHO(v); }
2510
   while (PENDING(millis(), codenum)) idle();
2519
   while (PENDING(millis(), codenum)) idle();
2511
 }
2520
 }
2512
 
2521
 
2522
+#if ENABLED(BEZIER_CURVE_SUPPORT)
2523
+
2524
+  /**
2525
+   * Parameters interpreted according to:
2526
+   * http://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G5-Cubic-Spline
2527
+   * However I, J omission is not supported at this point; all
2528
+   * parameters can be omitted and default to zero.
2529
+   */
2530
+
2531
+  /**
2532
+   * G5: Cubic B-spline
2533
+   */
2534
+  inline void gcode_G5() {
2535
+    if (IsRunning()) {
2536
+
2537
+      #ifdef SF_ARC_FIX
2538
+        bool relative_mode_backup = relative_mode;
2539
+        relative_mode = true;
2540
+      #endif
2541
+      gcode_get_destination();
2542
+      #ifdef SF_ARC_FIX
2543
+        relative_mode = relative_mode_backup;
2544
+      #endif
2545
+
2546
+      float offset[] = {
2547
+        code_seen('I') ? code_value() : 0.0,
2548
+        code_seen('J') ? code_value() : 0.0,
2549
+        code_seen('P') ? code_value() : 0.0,
2550
+        code_seen('Q') ? code_value() : 0.0
2551
+      };
2552
+
2553
+      plan_cubic_move(offset);
2554
+    }
2555
+  }
2556
+
2557
+#endif // BEZIER_CURVE_SUPPORT
2558
+
2513
 #if ENABLED(FWRETRACT)
2559
 #if ENABLED(FWRETRACT)
2514
 
2560
 
2515
   /**
2561
   /**
6498
 
6544
 
6499
       // G2, G3
6545
       // G2, G3
6500
       #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA)
6546
       #if ENABLED(ARC_SUPPORT) && DISABLED(SCARA)
6547
+
6501
         case 2: // G2  - CW ARC
6548
         case 2: // G2  - CW ARC
6502
         case 3: // G3  - CCW ARC
6549
         case 3: // G3  - CCW ARC
6503
           gcode_G2_G3(codenum == 2);
6550
           gcode_G2_G3(codenum == 2);
6504
           break;
6551
           break;
6552
+
6505
       #endif
6553
       #endif
6506
 
6554
 
6507
       // G4 Dwell
6555
       // G4 Dwell
6509
         gcode_G4();
6557
         gcode_G4();
6510
         break;
6558
         break;
6511
 
6559
 
6560
+      #if ENABLED(BEZIER_CURVE_SUPPORT)
6561
+
6562
+        // G5
6563
+        case 5: // G5  - Cubic B_spline
6564
+          gcode_G5();
6565
+          break;
6566
+
6567
+      #endif // BEZIER_CURVE_SUPPORT
6568
+
6512
       #if ENABLED(FWRETRACT)
6569
       #if ENABLED(FWRETRACT)
6513
 
6570
 
6514
         case 10: // G10: retract
6571
         case 10: // G10: retract
6516
           gcode_G10_G11(codenum == 10);
6573
           gcode_G10_G11(codenum == 10);
6517
           break;
6574
           break;
6518
 
6575
 
6519
-      #endif //FWRETRACT
6576
+      #endif // FWRETRACT
6520
 
6577
 
6521
       case 28: // G28: Home all axes, one at a time
6578
       case 28: // G28: Home all axes, one at a time
6522
         gcode_G28();
6579
         gcode_G28();
7588
   }
7645
   }
7589
 #endif
7646
 #endif
7590
 
7647
 
7648
+#if ENABLED(BEZIER_CURVE_SUPPORT)
7649
+
7650
+  void plan_cubic_move(const float offset[4]) {
7651
+    cubic_b_spline(current_position, destination, offset, feedrate * feedrate_multiplier / 60 / 100.0, active_extruder);
7652
+
7653
+    // As far as the parser is concerned, the position is now == target. In reality the
7654
+    // motion control system might still be processing the action and the real tool position
7655
+    // in any intermediate location.
7656
+    set_current_to_destination();
7657
+  }
7658
+
7659
+#endif // BEZIER_CURVE_SUPPORT
7660
+
7591
 #if HAS_CONTROLLERFAN
7661
 #if HAS_CONTROLLERFAN
7592
 
7662
 
7593
   void controllerFan() {
7663
   void controllerFan() {

+ 3
- 2
Marlin/example_configurations/Felix/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/Hephestos/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/Hephestos_2/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/K8200/Configuration_adv.h View File

290
 
290
 
291
 #define AXIS_RELATIVE_MODES {false, false, false, false}
291
 #define AXIS_RELATIVE_MODES {false, false, false, false}
292
 
292
 
293
-// @section machine
294
-
295
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
293
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
296
 #define INVERT_X_STEP_PIN false
294
 #define INVERT_X_STEP_PIN false
297
 #define INVERT_Y_STEP_PIN false
295
 #define INVERT_Y_STEP_PIN false
465
 #define MM_PER_ARC_SEGMENT 1
463
 #define MM_PER_ARC_SEGMENT 1
466
 #define N_ARC_CORRECTION 25
464
 #define N_ARC_CORRECTION 25
467
 
465
 
466
+// Support for G5 with XYZE destination and IJPQ offsets
467
+//#define BEZIER_CURVE_SUPPORT
468
+
468
 const unsigned int dropsegments = 2; //everything with less than this number of steps will be ignored as move and joined with the next movement
469
 const unsigned int dropsegments = 2; //everything with less than this number of steps will be ignored as move and joined with the next movement
469
 
470
 
470
 // @section temperature
471
 // @section temperature

+ 3
- 2
Marlin/example_configurations/RigidBot/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/SCARA/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/TAZ4/Configuration_adv.h View File

292
 
292
 
293
 #define AXIS_RELATIVE_MODES {false, false, false, false}
293
 #define AXIS_RELATIVE_MODES {false, false, false, false}
294
 
294
 
295
-// @section machine
296
-
297
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
295
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
298
 #define INVERT_X_STEP_PIN false
296
 #define INVERT_X_STEP_PIN false
299
 #define INVERT_Y_STEP_PIN false
297
 #define INVERT_Y_STEP_PIN false
467
 #define MM_PER_ARC_SEGMENT 1
465
 #define MM_PER_ARC_SEGMENT 1
468
 #define N_ARC_CORRECTION 25
466
 #define N_ARC_CORRECTION 25
469
 
467
 
468
+// Support for G5 with XYZE destination and IJPQ offsets
469
+//#define BEZIER_CURVE_SUPPORT
470
+
470
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
471
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
471
 
472
 
472
 // @section temperature
473
 // @section temperature

+ 3
- 2
Marlin/example_configurations/WITBOX/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/delta/biv2.5/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
461
 #define MM_PER_ARC_SEGMENT 1
459
 #define MM_PER_ARC_SEGMENT 1
462
 #define N_ARC_CORRECTION 25
460
 #define N_ARC_CORRECTION 25
463
 
461
 
462
+// Support for G5 with XYZE destination and IJPQ offsets
463
+//#define BEZIER_CURVE_SUPPORT
464
+
464
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 
466
 
466
 // @section temperature
467
 // @section temperature

+ 3
- 2
Marlin/example_configurations/delta/generic/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
461
 #define MM_PER_ARC_SEGMENT 1
459
 #define MM_PER_ARC_SEGMENT 1
462
 #define N_ARC_CORRECTION 25
460
 #define N_ARC_CORRECTION 25
463
 
461
 
462
+// Support for G5 with XYZE destination and IJPQ offsets
463
+//#define BEZIER_CURVE_SUPPORT
464
+
464
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 
466
 
466
 // @section temperature
467
 // @section temperature

+ 3
- 2
Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
460
 #define MM_PER_ARC_SEGMENT 1
458
 #define MM_PER_ARC_SEGMENT 1
461
 #define N_ARC_CORRECTION 25
459
 #define N_ARC_CORRECTION 25
462
 
460
 
461
+// Support for G5 with XYZE destination and IJPQ offsets
462
+//#define BEZIER_CURVE_SUPPORT
463
+
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
464
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
464
 
465
 
465
 // @section temperature
466
 // @section temperature

+ 3
- 2
Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h View File

289
 
289
 
290
 #define AXIS_RELATIVE_MODES {false, false, false, false}
290
 #define AXIS_RELATIVE_MODES {false, false, false, false}
291
 
291
 
292
-// @section machine
293
-
294
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
292
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
295
 #define INVERT_X_STEP_PIN false
293
 #define INVERT_X_STEP_PIN false
296
 #define INVERT_Y_STEP_PIN false
294
 #define INVERT_Y_STEP_PIN false
465
 #define MM_PER_ARC_SEGMENT 1
463
 #define MM_PER_ARC_SEGMENT 1
466
 #define N_ARC_CORRECTION 25
464
 #define N_ARC_CORRECTION 25
467
 
465
 
466
+// Support for G5 with XYZE destination and IJPQ offsets
467
+//#define BEZIER_CURVE_SUPPORT
468
+
468
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
469
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
469
 
470
 
470
 // @section temperature
471
 // @section temperature

+ 3
- 2
Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
461
 #define MM_PER_ARC_SEGMENT 1
459
 #define MM_PER_ARC_SEGMENT 1
462
 #define N_ARC_CORRECTION 25
460
 #define N_ARC_CORRECTION 25
463
 
461
 
462
+// Support for G5 with XYZE destination and IJPQ offsets
463
+//#define BEZIER_CURVE_SUPPORT
464
+
464
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
465
 
466
 
466
 // @section temperature
467
 // @section temperature

+ 3
- 2
Marlin/example_configurations/makibox/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 3
- 2
Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h View File

284
 
284
 
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
285
 #define AXIS_RELATIVE_MODES {false, false, false, false}
286
 
286
 
287
-// @section machine
288
-
289
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
287
 //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
290
 #define INVERT_X_STEP_PIN false
288
 #define INVERT_X_STEP_PIN false
291
 #define INVERT_Y_STEP_PIN false
289
 #define INVERT_Y_STEP_PIN false
459
 #define MM_PER_ARC_SEGMENT 1
457
 #define MM_PER_ARC_SEGMENT 1
460
 #define N_ARC_CORRECTION 25
458
 #define N_ARC_CORRECTION 25
461
 
459
 
460
+// Support for G5 with XYZE destination and IJPQ offsets
461
+//#define BEZIER_CURVE_SUPPORT
462
+
462
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 const unsigned int dropsegments = 5; //everything with less than this number of steps will be ignored as move and joined with the next movement
463
 
464
 
464
 // @section temperature
465
 // @section temperature

+ 194
- 0
Marlin/planner_bezier.cpp View File

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * planner_bezier.cpp
25
+ *
26
+ * Compute and buffer movement commands for bezier curves
27
+ *
28
+ */
29
+
30
+#include "Marlin.h"
31
+
32
+#if ENABLED(BEZIER_CURVE_SUPPORT)
33
+
34
+#include "planner.h"
35
+#include "language.h"
36
+#include "temperature.h"
37
+
38
+// See the meaning in the documentation of cubic_b_spline().
39
+#define MIN_STEP 0.002
40
+#define MAX_STEP 0.1
41
+#define SIGMA 0.1
42
+
43
+/* Compute the linear interpolation between to real numbers.
44
+*/
45
+inline static float interp(float a, float b, float t) { return (1.0 - t) * a + t * b; }
46
+
47
+/**
48
+ * Compute a Bézier curve using the De Casteljau's algorithm (see
49
+ * https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm), which is
50
+ * easy to code and has good numerical stability (very important,
51
+ * since Arudino works with limited precision real numbers).
52
+ */
53
+inline static float eval_bezier(float a, float b, float c, float d, float t) {
54
+  float iab = interp(a, b, t);
55
+  float ibc = interp(b, c, t);
56
+  float icd = interp(c, d, t);
57
+  float iabc = interp(iab, ibc, t);
58
+  float ibcd = interp(ibc, icd, t);
59
+  float iabcd = interp(iabc, ibcd, t);
60
+  return iabcd;
61
+}
62
+
63
+/**
64
+ * We approximate Euclidean distance with the sum of the coordinates
65
+ * offset (so-called "norm 1"), which is quicker to compute.
66
+ */
67
+inline static float dist1(float x1, float y1, float x2, float y2) { return fabs(x1 - x2) + fabs(y1 - y2); }
68
+
69
+/**
70
+ * The algorithm for computing the step is loosely based on the one in Kig
71
+ * (See https://sources.debian.net/src/kig/4:15.08.3-1/misc/kigpainter.cpp/#L759)
72
+ * However, we do not use the stack.
73
+ *
74
+ * The algorithm goes as it follows: the parameters t runs from 0.0 to
75
+ * 1.0 describing the curve, which is evaluated by eval_bezier(). At
76
+ * each iteration we have to choose a step, i.e., the increment of the
77
+ * t variable. By default the step of the previous iteration is taken,
78
+ * and then it is enlarged or reduced depending on how straight the
79
+ * curve locally is. The step is always clamped between MIN_STEP/2 and
80
+ * 2*MAX_STEP. MAX_STEP is taken at the first iteration.
81
+ *
82
+ * For some t, the step value is considered acceptable if the curve in
83
+ * the interval [t, t+step] is sufficiently straight, i.e.,
84
+ * sufficiently close to linear interpolation. In practice the
85
+ * following test is performed: the distance between eval_bezier(...,
86
+ * t+step/2) is evaluated and compared with 0.5*(eval_bezier(...,
87
+ * t)+eval_bezier(..., t+step)). If it is smaller than SIGMA, then the
88
+ * step value is considered acceptable, otherwise it is not. The code
89
+ * seeks to find the larger step value which is considered acceptable.
90
+ *
91
+ * At every iteration the recorded step value is considered and then
92
+ * iteratively halved until it becomes acceptable. If it was already
93
+ * acceptable in the beginning (i.e., no halving were done), then
94
+ * maybe it was necessary to enlarge it; then it is iteratively
95
+ * doubled while it remains acceptable. The last acceptable value
96
+ * found is taken, provided that it is between MIN_STEP and MAX_STEP
97
+ * and does not bring t over 1.0.
98
+ *
99
+ * Caveat: this algorithm is not perfect, since it can happen that a
100
+ * step is considered acceptable even when the curve is not linear at
101
+ * all in the interval [t, t+step] (but its mid point coincides "by
102
+ * chance" with the midpoint according to the parametrization). This
103
+ * kind of glitches can be eliminated with proper first derivative
104
+ * estimates; however, given the improbability of such configurations,
105
+ * the mitigation offered by MIN_STEP and the small computational
106
+ * power available on Arduino, I think it is not wise to implement it.
107
+ */
108
+void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float feed_rate, uint8_t extruder) {
109
+  // Absolute first and second control points are recovered.
110
+  float first0 = position[X_AXIS] + offset[0];
111
+  float first1 = position[Y_AXIS] + offset[1];
112
+  float second0 = target[X_AXIS] + offset[2];
113
+  float second1 = target[Y_AXIS] + offset[3];
114
+  float t = 0.0;
115
+
116
+  float tmp[4];
117
+  tmp[X_AXIS] = position[X_AXIS];
118
+  tmp[Y_AXIS] = position[Y_AXIS];
119
+  float step = MAX_STEP;
120
+
121
+  uint8_t idle_counter = 0;
122
+  millis_t next_ping_ms = millis() + 200UL;
123
+
124
+  while (t < 1.0) {
125
+
126
+    millis_t now = millis();
127
+    if (ELAPSED(now, next_ping_ms)) {
128
+      next_ping_ms = now + 200UL;
129
+      (idle_counter++ & 0x03) ? thermalManager.manage_heater() : idle();
130
+    }
131
+
132
+    // First try to reduce the step in order to make it sufficiently
133
+    // close to a linear interpolation.
134
+    bool did_reduce = false;
135
+    float new_t = t + step;
136
+    NOMORE(new_t, 1.0);
137
+    float new_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], new_t);
138
+    float new_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], new_t);
139
+    for (;;) {
140
+      if (new_t - t < (MIN_STEP)) break;
141
+      float candidate_t = 0.5 * (t + new_t);
142
+      float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t);
143
+      float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t);
144
+      float interp_pos0 = 0.5 * (tmp[X_AXIS] + new_pos0);
145
+      float interp_pos1 = 0.5 * (tmp[Y_AXIS] + new_pos1);
146
+      if (dist1(candidate_pos0, candidate_pos1, interp_pos0, interp_pos1) <= (SIGMA)) break;
147
+      new_t = candidate_t;
148
+      new_pos0 = candidate_pos0;
149
+      new_pos1 = candidate_pos1;
150
+      did_reduce = true;
151
+    }
152
+
153
+    // If we did not reduce the step, maybe we should enlarge it.
154
+    if (!did_reduce) for (;;) {
155
+      if (new_t - t > MAX_STEP) break;
156
+      float candidate_t = t + 2.0 * (new_t - t);
157
+      if (candidate_t >= 1.0) break;
158
+      float candidate_pos0 = eval_bezier(position[X_AXIS], first0, second0, target[X_AXIS], candidate_t);
159
+      float candidate_pos1 = eval_bezier(position[Y_AXIS], first1, second1, target[Y_AXIS], candidate_t);
160
+      float interp_pos0 = 0.5 * (tmp[X_AXIS] + candidate_pos0);
161
+      float interp_pos1 = 0.5 * (tmp[Y_AXIS] + candidate_pos1);
162
+      if (dist1(new_pos0, new_pos1, interp_pos0, interp_pos1) > (SIGMA)) break;
163
+      new_t = candidate_t;
164
+      new_pos0 = candidate_pos0;
165
+      new_pos1 = candidate_pos1;
166
+    }
167
+
168
+    // Check some postcondition; they are disabled in the actual
169
+    // Marlin build, but if you test the same code on a computer you
170
+    // may want to check they are respect.
171
+    /*
172
+      assert(new_t <= 1.0);
173
+      if (new_t < 1.0) {
174
+        assert(new_t - t >= (MIN_STEP) / 2.0);
175
+        assert(new_t - t <= (MAX_STEP) * 2.0);
176
+      }
177
+    */
178
+
179
+    step = new_t - t;
180
+    t = new_t;
181
+
182
+    // Compute and send new position
183
+    tmp[X_AXIS] = new_pos0;
184
+    tmp[Y_AXIS] = new_pos1;
185
+    // FIXME. The following two are wrong, since the parameter t is
186
+    // not linear in the distance.
187
+    tmp[Z_AXIS] = interp(position[Z_AXIS], target[Z_AXIS], t);
188
+    tmp[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
189
+    clamp_to_software_endstops(tmp);
190
+    planner.buffer_line(tmp[X_AXIS], tmp[Y_AXIS], tmp[Z_AXIS], tmp[E_AXIS], feed_rate, extruder);
191
+  }
192
+}
193
+
194
+#endif // BEZIER_CURVE_SUPPORT

+ 43
- 0
Marlin/planner_bezier.h View File

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+/**
24
+ * planner_bezier.h
25
+ *
26
+ * Compute and buffer movement commands for bezier curves
27
+ *
28
+ */
29
+
30
+#ifndef PLANNER_BEZIER_H
31
+#define PLANNER_BEZIER_H
32
+
33
+#include "Marlin.h"
34
+
35
+void cubic_b_spline(
36
+              const float position[NUM_AXIS], // current position
37
+              const float target[NUM_AXIS],   // target position
38
+              const float offset[4],          // a pair of offsets
39
+              float feed_rate,
40
+              uint8_t extruder
41
+            );
42
+
43
+#endif // PLANNER_BEZIER_H

Loading…
Cancel
Save