Browse Source

♻️ Planner flags refactor

Scott Lahteine 2 years ago
parent
commit
307dfb15ca

+ 1
- 1
Marlin/src/gcode/motion/G2_G3.cpp View File

315
         // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
315
         // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
316
         // To reduce stuttering, the sin and cos could be computed at different times.
316
         // To reduce stuttering, the sin and cos could be computed at different times.
317
         // For now, compute both at the same time.
317
         // For now, compute both at the same time.
318
-        const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment);
318
+        const float Ti = i * theta_per_segment, cos_Ti = cos(Ti), sin_Ti = sin(Ti);
319
         rvec.a = -offset[0] * cos_Ti + offset[1] * sin_Ti;
319
         rvec.a = -offset[0] * cos_Ti + offset[1] * sin_Ti;
320
         rvec.b = -offset[0] * sin_Ti - offset[1] * cos_Ti;
320
         rvec.b = -offset[0] * sin_Ti - offset[1] * cos_Ti;
321
       }
321
       }

+ 1
- 1
Marlin/src/gcode/motion/G6.cpp View File

50
   // No speed is set, can't schedule the move
50
   // No speed is set, can't schedule the move
51
   if (!planner.last_page_step_rate) return;
51
   if (!planner.last_page_step_rate) return;
52
 
52
 
53
-  const page_idx_t page_idx = (page_idx_t) parser.value_ulong();
53
+  const page_idx_t page_idx = (page_idx_t)parser.value_ulong();
54
 
54
 
55
   uint16_t num_steps = DirectStepping::Config::TOTAL_STEPS;
55
   uint16_t num_steps = DirectStepping::Config::TOTAL_STEPS;
56
   if (parser.seen('S')) num_steps = parser.value_ushort();
56
   if (parser.seen('S')) num_steps = parser.value_ushort();

+ 2
- 2
Marlin/src/gcode/temp/M106_M107.cpp View File

90
   // Set speed, with constraint
90
   // Set speed, with constraint
91
   thermalManager.set_fan_speed(pfan, speed);
91
   thermalManager.set_fan_speed(pfan, speed);
92
 
92
 
93
-  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
93
+  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_BIT_SYNC_FANS));
94
 
94
 
95
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
95
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
96
     thermalManager.set_fan_speed(1 - pfan, speed);
96
     thermalManager.set_fan_speed(1 - pfan, speed);
111
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
111
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
112
     thermalManager.set_fan_speed(1 - pfan, 0);
112
     thermalManager.set_fan_speed(1 - pfan, 0);
113
 
113
 
114
-  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
114
+  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_BIT_SYNC_FANS));
115
 }
115
 }
116
 
116
 
117
 #endif // HAS_FAN
117
 #endif // HAS_FAN

+ 74
- 81
Marlin/src/module/planner.cpp View File

739
     block_t * const block = &block_buffer[block_buffer_tail];
739
     block_t * const block = &block_buffer[block_buffer_tail];
740
 
740
 
741
     // No trapezoid calculated? Don't execute yet.
741
     // No trapezoid calculated? Don't execute yet.
742
-    if (TEST(block->flag, BLOCK_BIT_RECALCULATE)) return nullptr;
742
+    if (block->flag.recalculate) return nullptr;
743
 
743
 
744
     // We can't be sure how long an active block will take, so don't count it.
744
     // We can't be sure how long an active block will take, so don't count it.
745
     TERN_(HAS_WIRED_LCD, block_buffer_runtime_us -= block->segment_time_us);
745
     TERN_(HAS_WIRED_LCD, block_buffer_runtime_us -= block->segment_time_us);
948
 
948
 
949
     // Compute maximum entry speed decelerating over the current block from its exit speed.
949
     // Compute maximum entry speed decelerating over the current block from its exit speed.
950
     // If not at the maximum entry speed, or the previous block entry speed changed
950
     // If not at the maximum entry speed, or the previous block entry speed changed
951
-    if (current->entry_speed_sqr != max_entry_speed_sqr || (next && TEST(next->flag, BLOCK_BIT_RECALCULATE))) {
951
+    if (current->entry_speed_sqr != max_entry_speed_sqr || (next && next->flag.recalculate)) {
952
 
952
 
953
       // If nominal length true, max junction speed is guaranteed to be reached.
953
       // If nominal length true, max junction speed is guaranteed to be reached.
954
       // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then
954
       // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then
958
       // the reverse and forward planners, the corresponding block junction speed will always be at the
958
       // the reverse and forward planners, the corresponding block junction speed will always be at the
959
       // the maximum junction speed and may always be ignored for any speed reduction checks.
959
       // the maximum junction speed and may always be ignored for any speed reduction checks.
960
 
960
 
961
-      const float new_entry_speed_sqr = TEST(current->flag, BLOCK_BIT_NOMINAL_LENGTH)
961
+      const float new_entry_speed_sqr = current->flag.nominal_length
962
         ? max_entry_speed_sqr
962
         ? max_entry_speed_sqr
963
         : _MIN(max_entry_speed_sqr, max_allowable_speed_sqr(-current->acceleration, next ? next->entry_speed_sqr : sq(float(MINIMUM_PLANNER_SPEED)), current->millimeters));
963
         : _MIN(max_entry_speed_sqr, max_allowable_speed_sqr(-current->acceleration, next ? next->entry_speed_sqr : sq(float(MINIMUM_PLANNER_SPEED)), current->millimeters));
964
       if (current->entry_speed_sqr != new_entry_speed_sqr) {
964
       if (current->entry_speed_sqr != new_entry_speed_sqr) {
965
 
965
 
966
         // Need to recalculate the block speed - Mark it now, so the stepper
966
         // Need to recalculate the block speed - Mark it now, so the stepper
967
         // ISR does not consume the block before being recalculated
967
         // ISR does not consume the block before being recalculated
968
-        SBI(current->flag, BLOCK_BIT_RECALCULATE);
968
+        current->flag.recalculate = true;
969
 
969
 
970
         // But there is an inherent race condition here, as the block may have
970
         // But there is an inherent race condition here, as the block may have
971
         // become BUSY just before being marked RECALCULATE, so check for that!
971
         // become BUSY just before being marked RECALCULATE, so check for that!
973
           // Block became busy. Clear the RECALCULATE flag (no point in
973
           // Block became busy. Clear the RECALCULATE flag (no point in
974
           // recalculating BUSY blocks). And don't set its speed, as it can't
974
           // recalculating BUSY blocks). And don't set its speed, as it can't
975
           // be updated at this time.
975
           // be updated at this time.
976
-          CBI(current->flag, BLOCK_BIT_RECALCULATE);
976
+          current->flag.recalculate = false;
977
         }
977
         }
978
         else {
978
         else {
979
           // Block is not BUSY so this is ahead of the Stepper ISR:
979
           // Block is not BUSY so this is ahead of the Stepper ISR:
1011
     // Perform the reverse pass
1011
     // Perform the reverse pass
1012
     block_t *current = &block_buffer[block_index];
1012
     block_t *current = &block_buffer[block_index];
1013
 
1013
 
1014
-    // Only consider non sync-and-page blocks
1015
-    if (!(current->flag & BLOCK_MASK_SYNC) && !IS_PAGE(current)) {
1014
+    // Only process movement blocks
1015
+    if (current->is_move()) {
1016
       reverse_pass_kernel(current, next);
1016
       reverse_pass_kernel(current, next);
1017
       next = current;
1017
       next = current;
1018
     }
1018
     }
1041
     // change, adjust the entry speed accordingly. Entry speeds have already been reset,
1041
     // change, adjust the entry speed accordingly. Entry speeds have already been reset,
1042
     // maximized, and reverse-planned. If nominal length is set, max junction speed is
1042
     // maximized, and reverse-planned. If nominal length is set, max junction speed is
1043
     // guaranteed to be reached. No need to recheck.
1043
     // guaranteed to be reached. No need to recheck.
1044
-    if (!TEST(previous->flag, BLOCK_BIT_NOMINAL_LENGTH) &&
1045
-      previous->entry_speed_sqr < current->entry_speed_sqr) {
1044
+    if (!previous->flag.nominal_length && previous->entry_speed_sqr < current->entry_speed_sqr) {
1046
 
1045
 
1047
       // Compute the maximum allowable speed
1046
       // Compute the maximum allowable speed
1048
       const float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
1047
       const float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
1052
 
1051
 
1053
         // Mark we need to recompute the trapezoidal shape, and do it now,
1052
         // Mark we need to recompute the trapezoidal shape, and do it now,
1054
         // so the stepper ISR does not consume the block before being recalculated
1053
         // so the stepper ISR does not consume the block before being recalculated
1055
-        SBI(current->flag, BLOCK_BIT_RECALCULATE);
1054
+        current->flag.recalculate = true;
1056
 
1055
 
1057
         // But there is an inherent race condition here, as the block maybe
1056
         // But there is an inherent race condition here, as the block maybe
1058
         // became BUSY, just before it was marked as RECALCULATE, so check
1057
         // became BUSY, just before it was marked as RECALCULATE, so check
1061
           // Block became busy. Clear the RECALCULATE flag (no point in
1060
           // Block became busy. Clear the RECALCULATE flag (no point in
1062
           //  recalculating BUSY blocks and don't set its speed, as it can't
1061
           //  recalculating BUSY blocks and don't set its speed, as it can't
1063
           //  be updated at this time.
1062
           //  be updated at this time.
1064
-          CBI(current->flag, BLOCK_BIT_RECALCULATE);
1063
+          current->flag.recalculate = false;
1065
         }
1064
         }
1066
         else {
1065
         else {
1067
           // Block is not BUSY, we won the race against the Stepper ISR:
1066
           // Block is not BUSY, we won the race against the Stepper ISR:
1106
     // Perform the forward pass
1105
     // Perform the forward pass
1107
     block = &block_buffer[block_index];
1106
     block = &block_buffer[block_index];
1108
 
1107
 
1109
-    // Skip SYNC and page blocks
1110
-    if (!(block->flag & BLOCK_MASK_SYNC) && !IS_PAGE(block)) {
1108
+    // Only process movement blocks
1109
+    if (block->is_move()) {
1111
       // If there's no previous block or the previous block is not
1110
       // If there's no previous block or the previous block is not
1112
       // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
1111
       // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
1113
       // the previous block became BUSY, so assume the current block's
1112
       // the previous block became BUSY, so assume the current block's
1131
   // The tail may be changed by the ISR so get a local copy.
1130
   // The tail may be changed by the ISR so get a local copy.
1132
   uint8_t block_index = block_buffer_tail,
1131
   uint8_t block_index = block_buffer_tail,
1133
           head_block_index = block_buffer_head;
1132
           head_block_index = block_buffer_head;
1134
-  // Since there could be a sync block in the head of the queue, and the
1133
+
1134
+  // Since there could be non-move blocks in the head of the queue, and the
1135
   // next loop must not recalculate the head block (as it needs to be
1135
   // next loop must not recalculate the head block (as it needs to be
1136
-  // specially handled), scan backwards to the first non-SYNC block.
1136
+  // specially handled), scan backwards to the first move block.
1137
   while (head_block_index != block_index) {
1137
   while (head_block_index != block_index) {
1138
 
1138
 
1139
     // Go back (head always point to the first free block)
1139
     // Go back (head always point to the first free block)
1142
     // Get the pointer to the block
1142
     // Get the pointer to the block
1143
     block_t *prev = &block_buffer[prev_index];
1143
     block_t *prev = &block_buffer[prev_index];
1144
 
1144
 
1145
-    // If not dealing with a sync block, we are done. The last block is not a SYNC block
1146
-    if (!(prev->flag & BLOCK_MASK_SYNC)) break;
1145
+    // It the block is a move, we're done with this loop
1146
+    if (prev->is_move()) break;
1147
 
1147
 
1148
     // Examine the previous block. This and all following are SYNC blocks
1148
     // Examine the previous block. This and all following are SYNC blocks
1149
     head_block_index = prev_index;
1149
     head_block_index = prev_index;
1156
 
1156
 
1157
     next = &block_buffer[block_index];
1157
     next = &block_buffer[block_index];
1158
 
1158
 
1159
-    // Skip sync and page blocks
1160
-    if (!(next->flag & BLOCK_MASK_SYNC) && !IS_PAGE(next)) {
1159
+    // Only process movement blocks
1160
+    if (next->is_move()) {
1161
       next_entry_speed = SQRT(next->entry_speed_sqr);
1161
       next_entry_speed = SQRT(next->entry_speed_sqr);
1162
 
1162
 
1163
       if (block) {
1163
       if (block) {
1164
-        // Recalculate if current block entry or exit junction speed has changed.
1165
-        if (TEST(block->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE)) {
1166
 
1164
 
1167
-          // Mark the current block as RECALCULATE, to protect it from the Stepper ISR running it.
1168
-          // Note that due to the above condition, there's a chance the current block isn't marked as
1169
-          // RECALCULATE yet, but the next one is. That's the reason for the following line.
1170
-          SBI(block->flag, BLOCK_BIT_RECALCULATE);
1165
+        // If the next block is marked to RECALCULATE, also mark the previously-fetched one
1166
+        if (next->flag.recalculate) block->flag.recalculate = true;
1167
+
1168
+        // Recalculate if current block entry or exit junction speed has changed.
1169
+        if (block->flag.recalculate) {
1171
 
1170
 
1172
           // But there is an inherent race condition here, as the block maybe
1171
           // But there is an inherent race condition here, as the block maybe
1173
           // became BUSY, just before it was marked as RECALCULATE, so check
1172
           // became BUSY, just before it was marked as RECALCULATE, so check
1190
 
1189
 
1191
           // Reset current only to ensure next trapezoid is computed - The
1190
           // Reset current only to ensure next trapezoid is computed - The
1192
           // stepper is free to use the block from now on.
1191
           // stepper is free to use the block from now on.
1193
-          CBI(block->flag, BLOCK_BIT_RECALCULATE);
1192
+          block->flag.recalculate = false;
1194
         }
1193
         }
1195
       }
1194
       }
1196
 
1195
 
1204
   // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
1203
   // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
1205
   if (next) {
1204
   if (next) {
1206
 
1205
 
1207
-    // Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it.
1206
+    // Mark the last block as RECALCULATE, to prevent the Stepper ISR running it.
1208
     // As the last block is always recalculated here, there is a chance the block isn't
1207
     // As the last block is always recalculated here, there is a chance the block isn't
1209
     // marked as RECALCULATE yet. That's the reason for the following line.
1208
     // marked as RECALCULATE yet. That's the reason for the following line.
1210
-    SBI(next->flag, BLOCK_BIT_RECALCULATE);
1209
+    block->flag.recalculate = true;
1211
 
1210
 
1212
     // But there is an inherent race condition here, as the block maybe
1211
     // But there is an inherent race condition here, as the block maybe
1213
     // became BUSY, just before it was marked as RECALCULATE, so check
1212
     // became BUSY, just before it was marked as RECALCULATE, so check
1229
 
1228
 
1230
     // Reset next only to ensure its trapezoid is computed - The stepper is free to use
1229
     // Reset next only to ensure its trapezoid is computed - The stepper is free to use
1231
     // the block from now on.
1230
     // the block from now on.
1232
-    CBI(next->flag, BLOCK_BIT_RECALCULATE);
1231
+    next->flag.recalculate = false;
1233
   }
1232
   }
1234
 }
1233
 }
1235
 
1234
 
1460
     for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
1459
     for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
1461
       const block_t * const block = &block_buffer[b];
1460
       const block_t * const block = &block_buffer[b];
1462
       if (NUM_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k, || block->steps.u, || block->steps.v, || block->steps.w)) {
1461
       if (NUM_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k, || block->steps.u, || block->steps.v, || block->steps.w)) {
1463
-        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
1462
+        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec
1464
         NOLESS(high, se);
1463
         NOLESS(high, se);
1465
       }
1464
       }
1466
     }
1465
     }
1782
 bool Planner::_buffer_steps(const xyze_long_t &target
1781
 bool Planner::_buffer_steps(const xyze_long_t &target
1783
   OPTARG(HAS_POSITION_FLOAT, const xyze_pos_t &target_float)
1782
   OPTARG(HAS_POSITION_FLOAT, const xyze_pos_t &target_float)
1784
   OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
1783
   OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
1785
-  , feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters
1784
+  , feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters/*=0.0*/
1786
 ) {
1785
 ) {
1787
 
1786
 
1788
   // Wait for the next available block
1787
   // Wait for the next available block
1796
 
1795
 
1797
   // Fill the block with the specified movement
1796
   // Fill the block with the specified movement
1798
   if (!_populate_block(block, false, target
1797
   if (!_populate_block(block, false, target
1799
-    OPTARG(HAS_POSITION_FLOAT, target_float)
1800
-    OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
1801
-    , fr_mm_s, extruder, millimeters
1802
-  )) {
1798
+        OPTARG(HAS_POSITION_FLOAT, target_float)
1799
+        OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
1800
+        , fr_mm_s, extruder, millimeters
1801
+      )
1802
+  ) {
1803
     // Movement was not queued, probably because it was too short.
1803
     // Movement was not queued, probably because it was too short.
1804
     //  Simply accept that as movement queued and done
1804
     //  Simply accept that as movement queued and done
1805
     return true;
1805
     return true;
1856
   );
1856
   );
1857
 
1857
 
1858
   /* <-- add a slash to enable
1858
   /* <-- add a slash to enable
1859
-    SERIAL_ECHOLNPGM(
1860
-      "  _populate_block FR:", fr_mm_s,
1861
-      " A:", target.a, " (", da, " steps)"
1862
-      #if HAS_Y_AXIS
1863
-        " B:", target.b, " (", db, " steps)"
1864
-      #endif
1865
-      #if HAS_Z_AXIS
1866
-        " C:", target.c, " (", dc, " steps)"
1867
-      #endif
1868
-      #if HAS_I_AXIS
1869
-        " " STR_I ":", target.i, " (", di, " steps)"
1870
-      #endif
1871
-      #if HAS_J_AXIS
1872
-        " " STR_J ":", target.j, " (", dj, " steps)"
1873
-      #endif
1874
-      #if HAS_K_AXIS
1875
-        " " STR_K ":", target.k, " (", dk, " steps)"
1876
-      #endif
1877
-      #if HAS_U_AXIS
1878
-        " " STR_U ":", target.u, " (", du, " steps)"
1879
-      #endif
1880
-      #if HAS_V_AXIS
1881
-        " " STR_V ":", target.v, " (", dv, " steps)"
1882
-      #endif
1883
-      #if HAS_W_AXIS
1884
-        " " STR_W ":", target.w, " (", dw, " steps)"
1885
-      #if HAS_EXTRUDERS
1886
-        " E:", target.e, " (", de, " steps)"
1887
-      #endif
1888
-    );
1859
+    #define _ALINE(A) " " STR_##A  ":", target[_AXIS(A)], " (", int32_t(target[_AXIS(A)] - position[_AXIS(A)]), " steps)"
1860
+    SERIAL_ECHOLNPGM("  _populate_block FR:", fr_mm_s, LOGICAL_AXIS_MAP(_ALINE));
1889
   //*/
1861
   //*/
1890
 
1862
 
1891
   #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
1863
   #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
1978
   #endif
1950
   #endif
1979
 
1951
 
1980
   // Clear all flags, including the "busy" bit
1952
   // Clear all flags, including the "busy" bit
1981
-  block->flag = 0x00;
1953
+  block->flag.clear();
1982
 
1954
 
1983
   // Set direction bits
1955
   // Set direction bits
1984
   block->direction_bits = dm;
1956
   block->direction_bits = dm;
2449
   if (speed_factor < 1.0f) {
2421
   if (speed_factor < 1.0f) {
2450
     current_speed *= speed_factor;
2422
     current_speed *= speed_factor;
2451
     block->nominal_rate *= speed_factor;
2423
     block->nominal_rate *= speed_factor;
2452
-    block->nominal_speed_sqr = block->nominal_speed_sqr * sq(speed_factor);
2424
+    block->nominal_speed_sqr *= sq(speed_factor);
2453
   }
2425
   }
2454
 
2426
 
2455
   // Compute and limit the acceleration rate for the trapezoid generator.
2427
   // Compute and limit the acceleration rate for the trapezoid generator.
2651
         vmax_junction_sqr = sq(float(MINIMUM_PLANNER_SPEED));
2623
         vmax_junction_sqr = sq(float(MINIMUM_PLANNER_SPEED));
2652
       }
2624
       }
2653
       else {
2625
       else {
2654
-        NOLESS(junction_cos_theta, -0.999999f); // Check for numerical round-off to avoid divide by zero.
2655
-
2656
         // Convert delta vector to unit vector
2626
         // Convert delta vector to unit vector
2657
         xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec;
2627
         xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec;
2658
         normalize_junction_vector(junction_unit_vec);
2628
         normalize_junction_vector(junction_unit_vec);
2659
 
2629
 
2660
-        const float junction_acceleration = limit_value_by_axis_maximum(block->acceleration, junction_unit_vec),
2661
-                    sin_theta_d2 = SQRT(0.5f * (1.0f - junction_cos_theta)); // Trig half angle identity. Always positive.
2630
+        const float junction_acceleration = limit_value_by_axis_maximum(block->acceleration, junction_unit_vec);
2631
+
2632
+        NOLESS(junction_cos_theta, -0.999999f); // Check for numerical round-off to avoid divide by zero.
2633
+
2634
+        const float sin_theta_d2 = SQRT(0.5f * (1.0f - junction_cos_theta)); // Trig half angle identity. Always positive.
2662
 
2635
 
2663
         vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / (1.0f - sin_theta_d2);
2636
         vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / (1.0f - sin_theta_d2);
2664
 
2637
 
2888
   // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
2861
   // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
2889
   // the reverse and forward planners, the corresponding block junction speed will always be at the
2862
   // the reverse and forward planners, the corresponding block junction speed will always be at the
2890
   // the maximum junction speed and may always be ignored for any speed reduction checks.
2863
   // the maximum junction speed and may always be ignored for any speed reduction checks.
2891
-  block->flag |= block->nominal_speed_sqr <= v_allowable_sqr ? BLOCK_FLAG_RECALCULATE | BLOCK_FLAG_NOMINAL_LENGTH : BLOCK_FLAG_RECALCULATE;
2864
+  block->flag.set_nominal(block->nominal_speed_sqr <= v_allowable_sqr);
2892
 
2865
 
2893
   // Update previous path unit_vector and nominal speed
2866
   // Update previous path unit_vector and nominal speed
2894
   previous_speed = current_speed;
2867
   previous_speed = current_speed;
2913
  * Add a block to the buffer that just updates the position,
2886
  * Add a block to the buffer that just updates the position,
2914
  * or in case of LASER_SYNCHRONOUS_M106_M107 the fan PWM
2887
  * or in case of LASER_SYNCHRONOUS_M106_M107 the fan PWM
2915
  */
2888
  */
2916
-void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag)) {
2889
+void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, const BlockFlagBit sync_flag/*=BLOCK_BIT_SYNC_POSITION*/)) {
2917
   #if DISABLED(LASER_SYNCHRONOUS_M106_M107)
2890
   #if DISABLED(LASER_SYNCHRONOUS_M106_M107)
2918
-    constexpr uint8_t sync_flag = BLOCK_FLAG_SYNC_POSITION;
2891
+    constexpr BlockFlagBit sync_flag = BLOCK_BIT_SYNC_POSITION;
2919
   #endif
2892
   #endif
2920
 
2893
 
2921
   // Wait for the next available block
2894
   // Wait for the next available block
2925
   // Clear block
2898
   // Clear block
2926
   memset(block, 0, sizeof(block_t));
2899
   memset(block, 0, sizeof(block_t));
2927
 
2900
 
2928
-  block->flag = sync_flag;
2901
+  block->flag.apply(sync_flag);
2929
 
2902
 
2930
   block->position = position;
2903
   block->position = position;
2931
   #if ENABLED(BACKLASH_COMPENSATION)
2904
   #if ENABLED(BACKLASH_COMPENSATION)
3073
   if (!_buffer_steps(target
3046
   if (!_buffer_steps(target
3074
       OPTARG(HAS_POSITION_FLOAT, target_float)
3047
       OPTARG(HAS_POSITION_FLOAT, target_float)
3075
       OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
3048
       OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
3076
-      , fr_mm_s, extruder, millimeters)
3077
-  ) return false;
3049
+      , fr_mm_s, extruder, millimeters
3050
+  )) return false;
3078
 
3051
 
3079
   stepper.wake_up();
3052
   stepper.wake_up();
3080
   return true;
3053
   return true;
3141
 
3114
 
3142
 #if ENABLED(DIRECT_STEPPING)
3115
 #if ENABLED(DIRECT_STEPPING)
3143
 
3116
 
3117
+  /**
3118
+   * @brief Add a direct stepping page block to the buffer
3119
+   *        and wake up the Stepper ISR to process it.
3120
+   *
3121
+   * @param page_idx Page index provided by G6 I<index>
3122
+   * @param extruder The extruder to use in the move
3123
+   * @param num_steps Number of steps to process in the ISR
3124
+   */
3144
   void Planner::buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps) {
3125
   void Planner::buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps) {
3145
     if (!last_page_step_rate) {
3126
     if (!last_page_step_rate) {
3146
       kill(GET_TEXT_F(MSG_BAD_PAGE_SPEED));
3127
       kill(GET_TEXT_F(MSG_BAD_PAGE_SPEED));
3150
     uint8_t next_buffer_head;
3131
     uint8_t next_buffer_head;
3151
     block_t * const block = get_next_free_block(next_buffer_head);
3132
     block_t * const block = get_next_free_block(next_buffer_head);
3152
 
3133
 
3153
-    block->flag = BLOCK_FLAG_IS_PAGE;
3134
+    block->flag.reset(BLOCK_BIT_PAGE);
3154
 
3135
 
3155
     #if HAS_FAN
3136
     #if HAS_FAN
3156
       FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
3137
       FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
3238
   }
3219
   }
3239
 }
3220
 }
3240
 
3221
 
3222
+/**
3223
+ * @brief Set the Planner position in mm
3224
+ * @details Set the Planner position from a native machine position in mm
3225
+ *
3226
+ * @param xyze A native (Cartesian) machine position
3227
+ */
3241
 void Planner::set_position_mm(const xyze_pos_t &xyze) {
3228
 void Planner::set_position_mm(const xyze_pos_t &xyze) {
3242
   xyze_pos_t machine = xyze;
3229
   xyze_pos_t machine = xyze;
3243
   TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine, true));
3230
   TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine, true));
3273
 
3260
 
3274
 #endif
3261
 #endif
3275
 
3262
 
3276
-// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
3263
+/**
3264
+ * @brief Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
3265
+ * @details Update planner movement factors after a change to certain settings:
3266
+ *          - max_acceleration_steps_per_s2 from settings max_acceleration_mm_per_s2 * axis_steps_per_mm (M201, M92)
3267
+ *          - acceleration_long_cutoff based on the largest max_acceleration_steps_per_s2 (M201)
3268
+ *          - max_e_jerk for all extruders based on junction_deviation_mm (M205 J)
3269
+ */
3277
 void Planner::reset_acceleration_rates() {
3270
 void Planner::reset_acceleration_rates() {
3278
   uint32_t highest_rate = 1;
3271
   uint32_t highest_rate = 1;
3279
   LOOP_DISTINCT_AXES(i) {
3272
   LOOP_DISTINCT_AXES(i) {
3286
 }
3279
 }
3287
 
3280
 
3288
 /**
3281
 /**
3289
- * Recalculate 'position' and 'mm_per_step'.
3290
- * Must be called whenever settings.axis_steps_per_mm changes!
3282
+ * @brief Recalculate 'position' and 'mm_per_step'.
3283
+ * @details Required whenever settings.axis_steps_per_mm changes!
3291
  */
3284
  */
3292
 void Planner::refresh_positioning() {
3285
 void Planner::refresh_positioning() {
3293
   LOOP_DISTINCT_AXES(i) mm_per_step[i] = 1.0f / settings.axis_steps_per_mm[i];
3286
   LOOP_DISTINCT_AXES(i) mm_per_step[i] = 1.0f / settings.axis_steps_per_mm[i];

+ 65
- 43
Marlin/src/module/planner.h View File

70
 
70
 
71
 #if ENABLED(DIRECT_STEPPING)
71
 #if ENABLED(DIRECT_STEPPING)
72
   #include "../feature/direct_stepping.h"
72
   #include "../feature/direct_stepping.h"
73
-  #define IS_PAGE(B) TEST(B->flag, BLOCK_BIT_IS_PAGE)
74
-#else
75
-  #define IS_PAGE(B) false
76
 #endif
73
 #endif
77
 
74
 
78
 #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
75
 #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
92
   #define HAS_DIST_MM_ARG 1
89
   #define HAS_DIST_MM_ARG 1
93
 #endif
90
 #endif
94
 
91
 
95
-enum BlockFlagBit : char {
92
+#if ENABLED(LASER_POWER_INLINE)
93
+
94
+  typedef struct {
95
+    bool isPlanned:1;
96
+    bool isEnabled:1;
97
+    bool dir:1;
98
+    bool Reserved:6;
99
+  } power_status_t;
100
+
101
+  typedef struct {
102
+    power_status_t status;    // See planner settings for meaning
103
+    uint8_t power;            // Ditto; When in trapezoid mode this is nominal power
104
+    #if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
105
+      uint8_t   power_entry;  // Entry power for the laser
106
+      #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
107
+        uint8_t   power_exit; // Exit power for the laser
108
+        uint32_t  entry_per,  // Steps per power increment (to avoid floats in stepper calcs)
109
+                  exit_per;   // Steps per power decrement
110
+      #endif
111
+    #endif
112
+  } block_laser_t;
113
+
114
+#endif
115
+
116
+/**
117
+ * Planner block flags as boolean bit fields
118
+ */
119
+enum BlockFlagBit {
96
   // Recalculate trapezoids on entry junction. For optimization.
120
   // Recalculate trapezoids on entry junction. For optimization.
97
   BLOCK_BIT_RECALCULATE,
121
   BLOCK_BIT_RECALCULATE,
98
 
122
 
109
 
133
 
110
   // Direct stepping page
134
   // Direct stepping page
111
   #if ENABLED(DIRECT_STEPPING)
135
   #if ENABLED(DIRECT_STEPPING)
112
-    , BLOCK_BIT_IS_PAGE
136
+    , BLOCK_BIT_PAGE
113
   #endif
137
   #endif
114
 
138
 
115
   // Sync the fan speeds from the block
139
   // Sync the fan speeds from the block
118
   #endif
142
   #endif
119
 };
143
 };
120
 
144
 
121
-enum BlockFlag : char {
122
-    BLOCK_FLAG_RECALCULATE          = _BV(BLOCK_BIT_RECALCULATE)
123
-  , BLOCK_FLAG_NOMINAL_LENGTH       = _BV(BLOCK_BIT_NOMINAL_LENGTH)
124
-  , BLOCK_FLAG_CONTINUED            = _BV(BLOCK_BIT_CONTINUED)
125
-  , BLOCK_FLAG_SYNC_POSITION        = _BV(BLOCK_BIT_SYNC_POSITION)
126
-  #if ENABLED(DIRECT_STEPPING)
127
-    , BLOCK_FLAG_IS_PAGE            = _BV(BLOCK_BIT_IS_PAGE)
128
-  #endif
129
-  #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
130
-    , BLOCK_FLAG_SYNC_FANS          = _BV(BLOCK_BIT_SYNC_FANS)
131
-  #endif
132
-};
145
+/**
146
+ * Planner block flags as boolean bit fields
147
+ */
148
+typedef struct {
149
+  union {
150
+    uint8_t bits;
133
 
151
 
134
-#define BLOCK_MASK_SYNC ( BLOCK_FLAG_SYNC_POSITION | TERN0(LASER_SYNCHRONOUS_M106_M107, BLOCK_FLAG_SYNC_FANS) )
152
+    struct {
153
+      bool recalculate:1;
135
 
154
 
136
-#if ENABLED(LASER_POWER_INLINE)
155
+      bool nominal_length:1;
137
 
156
 
138
-  typedef struct {
139
-    bool isPlanned:1;
140
-    bool isEnabled:1;
141
-    bool dir:1;
142
-    bool Reserved:6;
143
-  } power_status_t;
157
+      bool continued:1;
144
 
158
 
145
-  typedef struct {
146
-    power_status_t status;    // See planner settings for meaning
147
-    uint8_t power;            // Ditto; When in trapezoid mode this is nominal power
148
-    #if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
149
-      uint8_t   power_entry;  // Entry power for the laser
150
-      #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
151
-        uint8_t   power_exit; // Exit power for the laser
152
-        uint32_t  entry_per,  // Steps per power increment (to avoid floats in stepper calcs)
153
-                  exit_per;   // Steps per power decrement
159
+      bool sync_position:1;
160
+
161
+      #if ENABLED(DIRECT_STEPPING)
162
+        bool page:1;
154
       #endif
163
       #endif
155
-    #endif
156
-  } block_laser_t;
157
 
164
 
158
-#endif
165
+      #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
166
+        bool sync_fans:1;
167
+      #endif
168
+    };
169
+  };
170
+
171
+  void clear() volatile { bits = 0; }
172
+  void apply(const uint8_t f) volatile { bits |= f; }
173
+  void apply(const BlockFlagBit b) volatile { SBI(bits, b); }
174
+  void reset(const BlockFlagBit b) volatile { bits = _BV(b); }
175
+  void set_nominal(const bool n) volatile { recalculate = true; if (n) nominal_length = true; }
176
+
177
+} block_flags_t;
159
 
178
 
160
 /**
179
 /**
161
- * struct block_t
162
- *
163
- * A single entry in the planner buffer.
164
- * Tracks linear movement over multiple axes.
180
+ * A single entry in the planner buffer, used to set up and
181
+ * track a coordinated linear motion for one or more axes.
165
  *
182
  *
166
  * The "nominal" values are as-specified by G-code, and
183
  * The "nominal" values are as-specified by G-code, and
167
  * may never actually be reached due to acceleration limits.
184
  * may never actually be reached due to acceleration limits.
168
  */
185
  */
169
 typedef struct block_t {
186
 typedef struct block_t {
170
 
187
 
171
-  volatile uint8_t flag;                    // Block flags (See BlockFlag enum above) - Modified by ISR and main thread!
188
+  volatile block_flags_t flag;              // Block flags
189
+
190
+  volatile bool is_fan_sync() { return TERN0(LASER_SYNCHRONOUS_M106_M107, flag.sync_fans); }
191
+  volatile bool is_sync() { return flag.sync_position || is_fan_sync(); }
192
+  volatile bool is_page() { return TERN0(DIRECT_STEPPING, flag.page); }
193
+  volatile bool is_move() { return !(is_sync() || is_page()); }
172
 
194
 
173
   // Fields used by the motion planner to manage acceleration
195
   // Fields used by the motion planner to manage acceleration
174
   float nominal_speed_sqr,                  // The nominal speed for this block in (mm/sec)^2
196
   float nominal_speed_sqr,                  // The nominal speed for this block in (mm/sec)^2
759
      * case of LASER_SYNCHRONOUS_M106_M107 the fan pwm
781
      * case of LASER_SYNCHRONOUS_M106_M107 the fan pwm
760
      */
782
      */
761
     static void buffer_sync_block(
783
     static void buffer_sync_block(
762
-      TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag=BLOCK_FLAG_SYNC_POSITION)
784
+      TERN_(LASER_SYNCHRONOUS_M106_M107, const BlockFlagBit flag=BLOCK_BIT_SYNC_POSITION)
763
     );
785
     );
764
 
786
 
765
   #if IS_KINEMATIC
787
   #if IS_KINEMATIC

+ 9
- 12
Marlin/src/module/stepper.cpp View File

1699
     }while(0)
1699
     }while(0)
1700
 
1700
 
1701
     // Direct Stepping page?
1701
     // Direct Stepping page?
1702
-    const bool is_page = IS_PAGE(current_block);
1702
+    const bool is_page = current_block->is_page();
1703
 
1703
 
1704
     #if ENABLED(DIRECT_STEPPING)
1704
     #if ENABLED(DIRECT_STEPPING)
1705
       // Direct stepping is currently not ready for HAS_I_AXIS
1705
       // Direct stepping is currently not ready for HAS_I_AXIS
1977
             count_position[_AXIS(AXIS)] += page_step_state.bd[_AXIS(AXIS)] * count_direction[_AXIS(AXIS)];
1977
             count_position[_AXIS(AXIS)] += page_step_state.bd[_AXIS(AXIS)] * count_direction[_AXIS(AXIS)];
1978
         #endif
1978
         #endif
1979
 
1979
 
1980
-        if (IS_PAGE(current_block)) {
1980
+        if (current_block->is_page()) {
1981
           PAGE_SEGMENT_UPDATE_POS(X);
1981
           PAGE_SEGMENT_UPDATE_POS(X);
1982
           PAGE_SEGMENT_UPDATE_POS(Y);
1982
           PAGE_SEGMENT_UPDATE_POS(Y);
1983
           PAGE_SEGMENT_UPDATE_POS(Z);
1983
           PAGE_SEGMENT_UPDATE_POS(Z);
2167
     if ((current_block = planner.get_current_block())) {
2167
     if ((current_block = planner.get_current_block())) {
2168
 
2168
 
2169
       // Sync block? Sync the stepper counts or fan speeds and return
2169
       // Sync block? Sync the stepper counts or fan speeds and return
2170
-      while (current_block->flag & BLOCK_MASK_SYNC) {
2170
+      while (current_block->is_sync()) {
2171
 
2171
 
2172
-        #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
2173
-          const bool is_sync_fans = TEST(current_block->flag, BLOCK_BIT_SYNC_FANS);
2174
-          if (is_sync_fans) planner.sync_fan_speeds(current_block->fan_speed);
2175
-        #else
2176
-          constexpr bool is_sync_fans = false;
2177
-        #endif
2178
-
2179
-        if (!is_sync_fans) _set_position(current_block->position);
2172
+        if (current_block->is_fan_sync()) {
2173
+          TERN_(LASER_SYNCHRONOUS_M106_M107, planner.sync_fan_speeds(current_block->fan_speed));
2174
+        }
2175
+        else
2176
+          _set_position(current_block->position);
2180
 
2177
 
2181
         discard_current_block();
2178
         discard_current_block();
2182
 
2179
 
2196
       #endif
2193
       #endif
2197
 
2194
 
2198
       #if ENABLED(DIRECT_STEPPING)
2195
       #if ENABLED(DIRECT_STEPPING)
2199
-        if (IS_PAGE(current_block)) {
2196
+        if (current_block->is_page()) {
2200
           page_step_state.segment_steps = 0;
2197
           page_step_state.segment_steps = 0;
2201
           page_step_state.segment_idx = 0;
2198
           page_step_state.segment_idx = 0;
2202
           page_step_state.page = page_manager.get_page(current_block->page_idx);
2199
           page_step_state.page = page_manager.get_page(current_block->page_idx);

+ 1
- 2
Marlin/src/module/stepper.h View File

524
     // Discard current block and free any resources
524
     // Discard current block and free any resources
525
     FORCE_INLINE static void discard_current_block() {
525
     FORCE_INLINE static void discard_current_block() {
526
       #if ENABLED(DIRECT_STEPPING)
526
       #if ENABLED(DIRECT_STEPPING)
527
-        if (IS_PAGE(current_block))
528
-          page_manager.free_page(current_block->page_idx);
527
+        if (current_block->is_page()) page_manager.free_page(current_block->page_idx);
529
       #endif
528
       #endif
530
       current_block = nullptr;
529
       current_block = nullptr;
531
       axis_did_move = 0;
530
       axis_did_move = 0;

Loading…
Cancel
Save