Переглянути джерело

Cleanup of planner code

- Use named axis indexes, `X_AXIS` etc.
- Replace `block.steps_A` with block.steps[A]`
- Replace `A_segment_time` with `segment_time[A]`
- Add `A_AXIS`, `B_AXIS` for `COREXY` axes
- Conditional compile based on `EXTRUDERS`
- Add BLOCK_MOD macro for planner block indexes
- Apply coding standards to `planner.h` and `planner.cpp`
- Small optimizations of planner code
- Update `stepper.cpp` for new `block` struct
- Replace `memcpy` with loops, let the compiler unroll them
- Make `movesplanned` into an inline function
Scott Lahteine 9 роки тому
джерело
коміт
13fbf42d95
4 змінених файлів з 616 додано та 754 видалено
  1. 2
    2
      Marlin/Marlin.h
  2. 510
    636
      Marlin/planner.cpp
  3. 51
    62
      Marlin/planner.h
  4. 53
    54
      Marlin/stepper.cpp

+ 2
- 2
Marlin/Marlin.h Переглянути файл

@@ -183,7 +183,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
183 183
   #define disable_e3() /* nothing */
184 184
 #endif
185 185
 
186
-enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5}; 
186
+enum AxisEnum {X_AXIS=0, Y_AXIS=1, A_AXIS=0, B_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
187 187
 //X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
188 188
 
189 189
 void FlushSerialRequestResend();
@@ -270,7 +270,7 @@ extern unsigned char fanSpeedSoftPwm;
270 270
   extern bool filament_sensor;  //indicates that filament sensor readings should control extrusion
271 271
   extern float filament_width_meas; //holds the filament diameter as accurately measured
272 272
   extern signed char measurement_delay[];  //ring buffer to delay measurement
273
-  extern int delay_index1, delay_index2;  //index into ring buffer
273
+  extern int delay_index1, delay_index2;  //ring buffer index. used by planner, temperature, and main code
274 274
   extern float delay_dist; //delay distance counter
275 275
   extern int meas_delay_cm; //delay distance
276 276
 #endif

+ 510
- 636
Marlin/planner.cpp
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 51
- 62
Marlin/planner.h Переглянути файл

@@ -21,20 +21,16 @@
21 21
 // This module is to be considered a sub-module of stepper.c. Please don't include 
22 22
 // this file from any other module.
23 23
 
24
-#ifndef planner_h
25
-#define planner_h
24
+#ifndef PLANNER_H
25
+#define PLANNER_H
26 26
 
27 27
 #include "Marlin.h"
28 28
 
29
-#ifdef ENABLE_AUTO_BED_LEVELING
30
-#include "vector_3.h"
31
-#endif // ENABLE_AUTO_BED_LEVELING
32
-
33 29
 // This struct is used when buffering the setup for each linear movement "nominal" values are as specified in 
34 30
 // the source g-code and may never actually be reached if acceleration management is active.
35 31
 typedef struct {
36 32
   // Fields used by the bresenham algorithm for tracing the line
37
-  long steps_x, steps_y, steps_z, steps_e;  // Step count along each axis
33
+  long steps[NUM_AXIS];                     // Step count along each axis
38 34
   unsigned long step_event_count;           // The number of step events required to complete this block
39 35
   long accelerate_until;                    // The index of the step event on which to stop acceleration
40 36
   long decelerate_after;                    // The index of the step event on which to start decelerating
@@ -49,7 +45,7 @@ typedef struct {
49 45
   #endif
50 46
 
51 47
   // Fields used by the motion planner to manage acceleration
52
-//  float speed_x, speed_y, speed_z, speed_e;        // Nominal mm/sec for each axis
48
+  // float speed_x, speed_y, speed_z, speed_e;          // Nominal mm/sec for each axis
53 49
   float nominal_speed;                               // The nominal speed for this block in mm/sec 
54 50
   float entry_speed;                                 // Entry speed at previous-current junction in mm/sec
55 51
   float max_entry_speed;                             // Maximum allowable junction entry speed in mm/sec
@@ -65,48 +61,44 @@ typedef struct {
65 61
   unsigned long acceleration_st;                     // acceleration steps/sec^2
66 62
   unsigned long fan_speed;
67 63
   #ifdef BARICUDA
68
-  unsigned long valve_pressure;
69
-  unsigned long e_to_p_pressure;
64
+    unsigned long valve_pressure;
65
+    unsigned long e_to_p_pressure;
70 66
   #endif
71 67
   volatile char busy;
72 68
 } block_t;
73 69
 
74
-#ifdef ENABLE_AUTO_BED_LEVELING
75
-// this holds the required transform to compensate for bed level
76
-extern matrix_3x3 plan_bed_level_matrix;
77
-#endif // #ifdef ENABLE_AUTO_BED_LEVELING
70
+#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
78 71
 
79 72
 // Initialize the motion plan subsystem      
80 73
 void plan_init();
81 74
 
82
-// Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
83
-// millimaters. Feed rate specifies the speed of the motion.
75
+void check_axes_activity();
84 76
 
85
-#ifdef ENABLE_AUTO_BED_LEVELING
86
-void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
77
+// Get the number of buffered moves
78
+extern volatile unsigned char block_buffer_head;
79
+extern volatile unsigned char block_buffer_tail;
80
+FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
87 81
 
82
+#ifdef ENABLE_AUTO_BED_LEVELING
83
+  #include "vector_3.h"
84
+  // this holds the required transform to compensate for bed level
85
+  extern matrix_3x3 plan_bed_level_matrix;
86
+  // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
87
+  // millimaters. Feed rate specifies the speed of the motion.
88
+  void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
89
+  // Set position. Used for G92 instructions.
90
+  void plan_set_position(float x, float y, float z, const float &e);
88 91
   #ifndef DELTA
89
-  // Get the position applying the bed level matrix if enabled
90
-  vector_3 plan_get_position();
92
+    // Get the position applying the bed level matrix if enabled
93
+    vector_3 plan_get_position();
91 94
   #endif
92
-#else
93
-void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
94
-#endif // ENABLE_AUTO_BED_LEVELING
95
-
96
-// Set position. Used for G92 instructions.
97
-#ifdef ENABLE_AUTO_BED_LEVELING
98
-void plan_set_position(float x, float y, float z, const float &e);
99
-#else
100
-void plan_set_position(const float &x, const float &y, const float &z, const float &e);
101
-#endif // ENABLE_AUTO_BED_LEVELING
95
+#else //!ENABLE_AUTO_BED_LEVELING
96
+  void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
97
+  void plan_set_position(const float &x, const float &y, const float &z, const float &e);
98
+#endif //!ENABLE_AUTO_BED_LEVELING
102 99
 
103 100
 void plan_set_e_position(const float &e);
104 101
 
105
-
106
-
107
-void check_axes_activity();
108
-uint8_t movesplanned(); //return the nr of buffered moves
109
-
110 102
 extern unsigned long minsegmenttime;
111 103
 extern float max_feedrate[NUM_AXIS]; // set the max speeds
112 104
 extern float axis_steps_per_unit[NUM_AXIS];
@@ -122,44 +114,41 @@ extern float mintravelfeedrate;
122 114
 extern unsigned long axis_steps_per_sqr_second[NUM_AXIS];
123 115
 
124 116
 #ifdef AUTOTEMP
125
-    extern bool autotemp_enabled;
126
-    extern float autotemp_max;
127
-    extern float autotemp_min;
128
-    extern float autotemp_factor;
117
+  extern bool autotemp_enabled;
118
+  extern float autotemp_max;
119
+  extern float autotemp_min;
120
+  extern float autotemp_factor;
129 121
 #endif
130 122
 
131
-    
132
-
133
-
134
-extern block_t block_buffer[BLOCK_BUFFER_SIZE];            // A ring buffer for motion instfructions
123
+extern block_t block_buffer[BLOCK_BUFFER_SIZE];            // A ring buffer for motion instructions
135 124
 extern volatile unsigned char block_buffer_head;           // Index of the next block to be pushed
136 125
 extern volatile unsigned char block_buffer_tail; 
137
-// Called when the current block is no longer needed. Discards the block and makes the memory
138
-// availible for new blocks.    
139
-FORCE_INLINE void plan_discard_current_block()  
140
-{
141
-  if (block_buffer_head != block_buffer_tail) {
142
-    block_buffer_tail = (block_buffer_tail + 1) & (BLOCK_BUFFER_SIZE - 1);  
143
-  }
126
+
127
+// Returns true if the buffer has a queued block, false otherwise
128
+FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
129
+
130
+// Called when the current block is no longer needed. Discards
131
+// the block and makes the memory available for new blocks.
132
+FORCE_INLINE void plan_discard_current_block() {
133
+  if (blocks_queued())
134
+    block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
144 135
 }
145 136
 
146 137
 // Gets the current block. Returns NULL if buffer empty
147
-FORCE_INLINE block_t *plan_get_current_block() 
148
-{
149
-  if (block_buffer_head == block_buffer_tail) { 
150
-    return(NULL); 
138
+FORCE_INLINE block_t *plan_get_current_block() {
139
+  if (blocks_queued()) {
140
+    block_t *block = &block_buffer[block_buffer_tail];
141
+    block->busy = true;
142
+    return block;
151 143
   }
152
-  block_t *block = &block_buffer[block_buffer_tail];
153
-  block->busy = true;
154
-  return(block);
144
+  else
145
+    return NULL;
155 146
 }
156 147
 
157
-// Returns true if the buffer has a queued block, false otherwise
158
-FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
159
-
160 148
 #ifdef PREVENT_DANGEROUS_EXTRUDE
161
-void set_extrude_min_temp(float temp);
149
+  void set_extrude_min_temp(float temp);
162 150
 #endif
163 151
 
164 152
 void reset_acceleration_rates();
165
-#endif
153
+
154
+#endif //PLANNER_H

+ 53
- 54
Marlin/stepper.cpp Переглянути файл

@@ -370,7 +370,7 @@ ISR(TIMER1_COMPA_vect) {
370 370
       step_events_completed = 0;
371 371
 
372 372
       #ifdef Z_LATE_ENABLE
373
-        if (current_block->steps_z > 0) {
373
+        if (current_block->steps[Z_AXIS] > 0) {
374 374
           enable_z();
375 375
           OCR1A = 2000; //1ms wait
376 376
           return;
@@ -411,7 +411,7 @@ ISR(TIMER1_COMPA_vect) {
411 411
 
412 412
     #define UPDATE_ENDSTOP(axis,AXIS,minmax,MINMAX) \
413 413
       bool axis ##_## minmax ##_endstop = (READ(AXIS ##_## MINMAX ##_PIN) != AXIS ##_## MINMAX ##_ENDSTOP_INVERTING); \
414
-      if (axis ##_## minmax ##_endstop && old_## axis ##_## minmax ##_endstop && (current_block->steps_## axis > 0)) { \
414
+      if (axis ##_## minmax ##_endstop && old_## axis ##_## minmax ##_endstop && (current_block->steps[AXIS ##_AXIS] > 0)) { \
415 415
         endstops_trigsteps[AXIS ##_AXIS] = count_position[AXIS ##_AXIS]; \
416 416
         endstop_## axis ##_hit = true; \
417 417
         step_events_completed = current_block->step_event_count; \
@@ -420,54 +420,54 @@ ISR(TIMER1_COMPA_vect) {
420 420
 
421 421
     // Check X and Y endstops
422 422
     if (check_endstops) {
423
-      #ifndef COREXY
424
-        if (TEST(out_bits, X_AXIS))   // stepping along -X axis (regular cartesians bot)
425
-      #else
423
+      #ifdef COREXY
426 424
         // Head direction in -X axis for CoreXY bots.
427 425
         // If DeltaX == -DeltaY, the movement is only in Y axis
428
-        if (current_block->steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) == TEST(out_bits, Y_AXIS)))      
429
-            if (TEST(out_bits, X_HEAD))
430
-      #endif
431
-            { // -direction
432
-              #ifdef DUAL_X_CARRIAGE
433
-                // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
434
-                if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
435
-              #endif          
436
-                {
437
-                  #if defined(X_MIN_PIN) && X_MIN_PIN >= 0
438
-                    UPDATE_ENDSTOP(x, X, min, MIN);
439
-                  #endif
440
-                }
441
-            }
442
-            else { // +direction
443
-              #ifdef DUAL_X_CARRIAGE
444
-                // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
445
-                if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
446
-              #endif
447
-                {
448
-                  #if defined(X_MAX_PIN) && X_MAX_PIN >= 0
449
-                    UPDATE_ENDSTOP(x, X, max, MAX);
450
-                  #endif
451
-                }
452
-            }
453
-      #ifndef COREXY
454
-        if (TEST(out_bits, Y_AXIS))   // -direction
426
+        if (current_block->steps[A_AXIS] != current_block->steps[B_AXIS] || (TEST(out_bits, A_AXIS) == TEST(out_bits, B_AXIS)))
427
+          if (TEST(out_bits, X_HEAD))
455 428
       #else
429
+          if (TEST(out_bits, X_AXIS))   // stepping along -X axis (regular cartesians bot)
430
+      #endif
431
+          { // -direction
432
+            #ifdef DUAL_X_CARRIAGE
433
+              // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
434
+              if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
435
+            #endif          
436
+              {
437
+                #if defined(X_MIN_PIN) && X_MIN_PIN >= 0
438
+                  UPDATE_ENDSTOP(x, X, min, MIN);
439
+                #endif
440
+              }
441
+          }
442
+          else { // +direction
443
+            #ifdef DUAL_X_CARRIAGE
444
+              // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
445
+              if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
446
+            #endif
447
+              {
448
+                #if defined(X_MAX_PIN) && X_MAX_PIN >= 0
449
+                  UPDATE_ENDSTOP(x, X, max, MAX);
450
+                #endif
451
+              }
452
+          }
453
+      #ifdef COREXY
456 454
         // Head direction in -Y axis for CoreXY bots.
457 455
         // If DeltaX == DeltaY, the movement is only in X axis
458
-        if (current_block->steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) != TEST(out_bits, Y_AXIS)))
459
-            if (TEST(out_bits, Y_HEAD))             
456
+        if (current_block->steps[A_AXIS] != current_block->steps[B_AXIS] || (TEST(out_bits, A_AXIS) != TEST(out_bits, B_AXIS)))
457
+          if (TEST(out_bits, Y_HEAD))
458
+      #else
459
+          if (TEST(out_bits, Y_AXIS))   // -direction
460 460
       #endif
461
-            { // -direction
462
-              #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
463
-                UPDATE_ENDSTOP(y, Y, min, MIN);
464
-              #endif
465
-            }
466
-            else { // +direction
467
-              #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
468
-                UPDATE_ENDSTOP(y, Y, max, MAX);
469
-              #endif
470
-            }
461
+          { // -direction
462
+            #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
463
+              UPDATE_ENDSTOP(y, Y, min, MIN);
464
+            #endif
465
+          }
466
+          else { // +direction
467
+            #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
468
+              UPDATE_ENDSTOP(y, Y, max, MAX);
469
+            #endif
470
+          }
471 471
     }
472 472
 
473 473
     if (TEST(out_bits, Z_AXIS)) {   // -direction
@@ -515,7 +515,7 @@ ISR(TIMER1_COMPA_vect) {
515 515
       #endif
516 516
 
517 517
       #ifdef ADVANCE
518
-        counter_e += current_block->steps_e;
518
+        counter_e += current_block->steps[E_AXIS];
519 519
         if (counter_e > 0) {
520 520
           counter_e -= current_block->step_event_count;
521 521
           e_steps[current_block->active_extruder] += TEST(out_bits, E_AXIS) ? -1 : 1;
@@ -529,15 +529,14 @@ ISR(TIMER1_COMPA_vect) {
529 529
          * instead of doing each in turn. The extra tests add enough
530 530
          * lag to allow it work with without needing NOPs
531 531
          */
532
-        counter_x += current_block->steps_x;
533
-        if (counter_x > 0) X_STEP_WRITE(HIGH);
534
-        counter_y += current_block->steps_y;
535
-        if (counter_y > 0) Y_STEP_WRITE(HIGH);
536
-        counter_z += current_block->steps_z;
537
-        if (counter_z > 0) Z_STEP_WRITE(HIGH);
532
+        #define STEP_ADD(axis, AXIS) \
533
+         counter_## axis += current_block->steps[AXIS ##_AXIS]; \
534
+         if (counter_## axis > 0) { AXIS ##_STEP_WRITE(HIGH); }
535
+        STEP_ADD(x,X);
536
+        STEP_ADD(y,Y);
537
+        STEP_ADD(z,Z);
538 538
         #ifndef ADVANCE
539
-          counter_e += current_block->steps_e;
540
-          if (counter_e > 0) E_STEP_WRITE(HIGH);
539
+          STEP_ADD(e,E);
541 540
         #endif
542 541
 
543 542
         #define STEP_IF_COUNTER(axis, AXIS) \
@@ -557,7 +556,7 @@ ISR(TIMER1_COMPA_vect) {
557 556
       #else // !CONFIG_STEPPERS_TOSHIBA
558 557
 
559 558
         #define APPLY_MOVEMENT(axis, AXIS) \
560
-          counter_## axis += current_block->steps_## axis; \
559
+          counter_## axis += current_block->steps[AXIS ##_AXIS]; \
561 560
           if (counter_## axis > 0) { \
562 561
             AXIS ##_APPLY_STEP(!INVERT_## AXIS ##_STEP_PIN,0); \
563 562
             counter_## axis -= current_block->step_event_count; \

Завантаження…
Відмінити
Зберегти