Browse Source

Merge pull request #5445 from thinkyhead/rc_reduce_jerk_code

Slightly shrink jerk and advance code
Scott Lahteine 8 years ago
parent
commit
8383f35b40
1 changed files with 66 additions and 73 deletions
  1. 66
    73
      Marlin/planner.cpp

+ 66
- 73
Marlin/planner.cpp View File

141
 #endif
141
 #endif
142
 
142
 
143
 #if ENABLED(LIN_ADVANCE)
143
 #if ENABLED(LIN_ADVANCE)
144
-  float Planner::extruder_advance_k = LIN_ADVANCE_K;
145
-  float Planner::position_float[NUM_AXIS] = { 0 };
144
+  float Planner::extruder_advance_k = LIN_ADVANCE_K,
145
+        Planner::position_float[NUM_AXIS] = { 0 };
146
 #endif
146
 #endif
147
 
147
 
148
 #if ENABLED(ENSURE_SMOOTH_MOVES)
148
 #if ENABLED(ENSURE_SMOOTH_MOVES)
654
   // The target position of the tool in absolute steps
654
   // The target position of the tool in absolute steps
655
   // Calculate target position in absolute steps
655
   // Calculate target position in absolute steps
656
   //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
656
   //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
657
-  long target[XYZE] = {
657
+  const long target[XYZE] = {
658
     lround(a * axis_steps_per_mm[X_AXIS]),
658
     lround(a * axis_steps_per_mm[X_AXIS]),
659
     lround(b * axis_steps_per_mm[Y_AXIS]),
659
     lround(b * axis_steps_per_mm[Y_AXIS]),
660
     lround(c * axis_steps_per_mm[Z_AXIS]),
660
     lround(c * axis_steps_per_mm[Z_AXIS]),
670
   #endif
670
   #endif
671
 
671
 
672
   #if ENABLED(LIN_ADVANCE)
672
   #if ENABLED(LIN_ADVANCE)
673
-    float target_float[XYZE] = {a, b, c, e};
674
-    float de_float = target_float[E_AXIS] - position_float[E_AXIS];
675
-    float mm_D_float = sqrt(sq(target_float[X_AXIS] - position_float[X_AXIS]) + sq(target_float[Y_AXIS] - position_float[Y_AXIS]));
673
+    const float target_float[XYZE] = { a, b, c, e },
674
+                de_float = target_float[E_AXIS] - position_float[E_AXIS],
675
+                mm_D_float = sqrt(sq(target_float[X_AXIS] - position_float[X_AXIS]) + sq(target_float[Y_AXIS] - position_float[Y_AXIS]));
676
     
676
     
677
     memcpy(position_float, target_float, sizeof(position_float));
677
     memcpy(position_float, target_float, sizeof(position_float));
678
   #endif
678
   #endif
679
 
679
 
680
-  long da = target[X_AXIS] - position[X_AXIS],
681
-       db = target[Y_AXIS] - position[Y_AXIS],
682
-       dc = target[Z_AXIS] - position[Z_AXIS];
680
+  const long da = target[X_AXIS] - position[X_AXIS],
681
+             db = target[Y_AXIS] - position[Y_AXIS],
682
+             dc = target[Z_AXIS] - position[Z_AXIS];
683
 
683
 
684
   /*
684
   /*
685
   SERIAL_ECHOPAIR("  Planner FR:", fr_mm_s);
685
   SERIAL_ECHOPAIR("  Planner FR:", fr_mm_s);
755
   #endif
755
   #endif
756
   if (de < 0) SBI(dm, E_AXIS);
756
   if (de < 0) SBI(dm, E_AXIS);
757
 
757
 
758
-  float esteps_float = de * volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01;
759
-  int32_t esteps = abs(esteps_float) + 0.5;
758
+  const float esteps_float = de * volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01;
759
+  const int32_t esteps = abs(esteps_float) + 0.5;
760
 
760
 
761
   // Calculate the buffer head after we push this byte
761
   // Calculate the buffer head after we push this byte
762
-  int8_t next_buffer_head = next_block_index(block_buffer_head);
762
+  const uint8_t next_buffer_head = next_block_index(block_buffer_head);
763
 
763
 
764
   // If the buffer is full: good! That means we are well ahead of the robot.
764
   // If the buffer is full: good! That means we are well ahead of the robot.
765
   // Rest here until there is room in the buffer.
765
   // Rest here until there is room in the buffer.
852
 
852
 
853
     #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder
853
     #if ENABLED(DISABLE_INACTIVE_EXTRUDER) // Enable only the selected extruder
854
 
854
 
855
-      for (int8_t i = 0; i < EXTRUDERS; i++)
855
+      for (uint8_t i = 0; i < EXTRUDERS; i++)
856
         if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--;
856
         if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--;
857
 
857
 
858
       switch(extruder) {
858
       switch(extruder) {
980
   // Calculate moves/second for this move. No divide by zero due to previous checks.
980
   // Calculate moves/second for this move. No divide by zero due to previous checks.
981
   float inverse_mm_s = fr_mm_s * inverse_millimeters;
981
   float inverse_mm_s = fr_mm_s * inverse_millimeters;
982
 
982
 
983
-  int moves_queued = movesplanned();
983
+  const uint8_t moves_queued = movesplanned();
984
 
984
 
985
   // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill
985
   // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill
986
   #if ENABLED(SLOWDOWN)
986
   #if ENABLED(SLOWDOWN)
1037
         // If the index has changed (must have gone forward)...
1037
         // If the index has changed (must have gone forward)...
1038
         if (filwidth_delay_index[0] != filwidth_delay_index[1]) {
1038
         if (filwidth_delay_index[0] != filwidth_delay_index[1]) {
1039
           filwidth_e_count = 0; // Reset the E movement counter
1039
           filwidth_e_count = 0; // Reset the E movement counter
1040
-          int8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char
1040
+          const int8_t meas_sample = thermalManager.widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char
1041
           do {
1041
           do {
1042
             filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot
1042
             filwidth_delay_index[1] = (filwidth_delay_index[1] + 1) % MMD_CM; // The next unused slot
1043
             measurement_delay[filwidth_delay_index[1]] = meas_sample;         // Store the measurement
1043
             measurement_delay[filwidth_delay_index[1]] = meas_sample;         // Store the measurement
1050
   // Calculate and limit speed in mm/sec for each axis
1050
   // Calculate and limit speed in mm/sec for each axis
1051
   float current_speed[NUM_AXIS], speed_factor = 1.0; // factor <1 decreases speed
1051
   float current_speed[NUM_AXIS], speed_factor = 1.0; // factor <1 decreases speed
1052
   LOOP_XYZE(i) {
1052
   LOOP_XYZE(i) {
1053
-    float cs = fabs(current_speed[i] = delta_mm[i] * inverse_mm_s);
1053
+    const float cs = fabs(current_speed[i] = delta_mm[i] * inverse_mm_s);
1054
     if (cs > max_feedrate_mm_s[i]) NOMORE(speed_factor, max_feedrate_mm_s[i] / cs);
1054
     if (cs > max_feedrate_mm_s[i]) NOMORE(speed_factor, max_feedrate_mm_s[i] / cs);
1055
   }
1055
   }
1056
 
1056
 
1058
   #ifdef XY_FREQUENCY_LIMIT
1058
   #ifdef XY_FREQUENCY_LIMIT
1059
 
1059
 
1060
     // Check and limit the xy direction change frequency
1060
     // Check and limit the xy direction change frequency
1061
-    unsigned char direction_change = block->direction_bits ^ old_direction_bits;
1061
+    const unsigned char direction_change = block->direction_bits ^ old_direction_bits;
1062
     old_direction_bits = block->direction_bits;
1062
     old_direction_bits = block->direction_bits;
1063
     segment_time = lround((float)segment_time / speed_factor);
1063
     segment_time = lround((float)segment_time / speed_factor);
1064
 
1064
 
1083
     }
1083
     }
1084
     ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time;
1084
     ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time;
1085
 
1085
 
1086
-    long max_x_segment_time = MAX3(xs0, xs1, xs2),
1087
-         max_y_segment_time = MAX3(ys0, ys1, ys2),
1088
-         min_xy_segment_time = min(max_x_segment_time, max_y_segment_time);
1086
+    const long max_x_segment_time = MAX3(xs0, xs1, xs2),
1087
+               max_y_segment_time = MAX3(ys0, ys1, ys2),
1088
+               min_xy_segment_time = min(max_x_segment_time, max_y_segment_time);
1089
     if (min_xy_segment_time < MAX_FREQ_TIME) {
1089
     if (min_xy_segment_time < MAX_FREQ_TIME) {
1090
-      float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME);
1090
+      const float low_sf = speed_factor * min_xy_segment_time / (MAX_FREQ_TIME);
1091
       NOMORE(speed_factor, low_sf);
1091
       NOMORE(speed_factor, low_sf);
1092
     }
1092
     }
1093
   #endif // XY_FREQUENCY_LIMIT
1093
   #endif // XY_FREQUENCY_LIMIT
1100
   }
1100
   }
1101
 
1101
 
1102
   // Compute and limit the acceleration rate for the trapezoid generator.
1102
   // Compute and limit the acceleration rate for the trapezoid generator.
1103
-  float steps_per_mm = block->step_event_count * inverse_millimeters;
1103
+  const float steps_per_mm = block->step_event_count * inverse_millimeters;
1104
   uint32_t accel;
1104
   uint32_t accel;
1105
   if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) {
1105
   if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) {
1106
     // convert to: acceleration steps/sec^2
1106
     // convert to: acceleration steps/sec^2
1204
   static float previous_safe_speed;
1204
   static float previous_safe_speed;
1205
 
1205
 
1206
   float safe_speed = block->nominal_speed;
1206
   float safe_speed = block->nominal_speed;
1207
-  bool limited = false;
1207
+  uint8_t limited = 0;
1208
   LOOP_XYZE(i) {
1208
   LOOP_XYZE(i) {
1209
-    float jerk = fabs(current_speed[i]);
1210
-    if (jerk > max_jerk[i]) {
1211
-      // The actual jerk is lower if it has been limited by the XY jerk.
1209
+    const float jerk = fabs(current_speed[i]), maxj = max_jerk[i];
1210
+    if (jerk > maxj) {
1212
       if (limited) {
1211
       if (limited) {
1213
-        // Spare one division by a following gymnastics:
1214
-        // Instead of jerk *= safe_speed / block->nominal_speed,
1215
-        // multiply max_jerk[i] by the divisor.
1216
-        jerk *= safe_speed;
1217
-        float mjerk = max_jerk[i] * block->nominal_speed;
1218
-        if (jerk > mjerk) safe_speed *= mjerk / jerk;
1212
+        const float mjerk = maxj * block->nominal_speed;
1213
+        if (jerk * safe_speed > mjerk) safe_speed = mjerk / jerk;
1219
       }
1214
       }
1220
       else {
1215
       else {
1221
-        safe_speed = max_jerk[i];
1222
-        limited = true;
1216
+        ++limited;
1217
+        safe_speed = maxj;
1223
       }
1218
       }
1224
     }
1219
     }
1225
   }
1220
   }
1236
     vmax_junction = prev_speed_larger ? block->nominal_speed : previous_nominal_speed;
1231
     vmax_junction = prev_speed_larger ? block->nominal_speed : previous_nominal_speed;
1237
     // Factor to multiply the previous / current nominal velocities to get componentwise limited velocities.
1232
     // Factor to multiply the previous / current nominal velocities to get componentwise limited velocities.
1238
     float v_factor = 1.f;
1233
     float v_factor = 1.f;
1239
-    limited = false;
1234
+    limited = 0;
1240
     // Now limit the jerk in all axes.
1235
     // Now limit the jerk in all axes.
1241
     LOOP_XYZE(axis) {
1236
     LOOP_XYZE(axis) {
1242
       // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
1237
       // Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
1247
         v_entry *= v_factor;
1242
         v_entry *= v_factor;
1248
       }
1243
       }
1249
       // Calculate jerk depending on whether the axis is coasting in the same direction or reversing.
1244
       // Calculate jerk depending on whether the axis is coasting in the same direction or reversing.
1250
-      float jerk = 
1251
-        (v_exit > v_entry) ?
1252
-          ((v_entry > 0.f || v_exit < 0.f) ?
1253
-            // coasting
1254
-            (v_exit - v_entry) : 
1255
-            // axis reversal
1256
-            max(v_exit, -v_entry)) :
1257
-          // v_exit <= v_entry
1258
-          ((v_entry < 0.f || v_exit > 0.f) ?
1259
-            // coasting
1260
-            (v_entry - v_exit) :
1261
-            // axis reversal
1262
-            max(-v_exit, v_entry));
1245
+      const float jerk = (v_exit > v_entry)
1246
+          ? //                                  coasting             axis reversal
1247
+            ( (v_entry > 0.f || v_exit < 0.f) ? (v_exit - v_entry) : max(v_exit, -v_entry) )
1248
+          : // v_exit <= v_entry                coasting             axis reversal
1249
+            ( (v_entry < 0.f || v_exit > 0.f) ? (v_entry - v_exit) : max(-v_exit, v_entry) );
1250
+
1263
       if (jerk > max_jerk[axis]) {
1251
       if (jerk > max_jerk[axis]) {
1264
         v_factor *= max_jerk[axis] / jerk;
1252
         v_factor *= max_jerk[axis] / jerk;
1265
-        limited = true;
1253
+        ++limited;
1266
       }
1254
       }
1267
     }
1255
     }
1268
     if (limited) vmax_junction *= v_factor;
1256
     if (limited) vmax_junction *= v_factor;
1269
     // Now the transition velocity is known, which maximizes the shared exit / entry velocity while
1257
     // Now the transition velocity is known, which maximizes the shared exit / entry velocity while
1270
     // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints.
1258
     // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints.
1271
-    float vmax_junction_threshold = vmax_junction * 0.99f;
1259
+    const float vmax_junction_threshold = vmax_junction * 0.99f;
1272
     if (previous_safe_speed > vmax_junction_threshold && safe_speed > vmax_junction_threshold) {
1260
     if (previous_safe_speed > vmax_junction_threshold && safe_speed > vmax_junction_threshold) {
1273
       // Not coasting. The machine will stop and start the movements anyway,
1261
       // Not coasting. The machine will stop and start the movements anyway,
1274
       // better to start the segment from start.
1262
       // better to start the segment from start.
1285
   block->max_entry_speed = vmax_junction;
1273
   block->max_entry_speed = vmax_junction;
1286
 
1274
 
1287
   // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED.
1275
   // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED.
1288
-  float v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters);
1276
+  const float v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters);
1289
   block->entry_speed = min(vmax_junction, v_allowable);
1277
   block->entry_speed = min(vmax_junction, v_allowable);
1290
 
1278
 
1291
   // Initialize planner efficiency flags
1279
   // Initialize planner efficiency flags
1305
 
1293
 
1306
   #if ENABLED(LIN_ADVANCE)
1294
   #if ENABLED(LIN_ADVANCE)
1307
 
1295
 
1308
-    // Don't use LIN_ADVANCE for blocks if:
1309
-    // !block->steps[E_AXIS]: We don't have E steps todo (Travel move)
1310
-    // !block->steps[X_AXIS] && !block->steps[Y_AXIS]: We don't have a movement in XY direction (Retract / Prime moves)
1311
-    // extruder_advance_k == 0.0: There is no advance factor set
1312
-    // block->steps[E_AXIS] == block->step_event_count: A problem occurs when there's a very tiny move before a retract.
1313
-    // In this case, the retract and the move will be executed together.
1314
-    // This leads to an enormous number of advance steps due to a huge e_acceleration.
1315
-    // The math is correct, but you don't want a retract move done with advance!
1316
-    // de_float <= 0.0: Extruder is running in reverse direction (for example during "Wipe while retracting" (Slic3r) or "Combing" (Cura) movements)
1317
-    if (!esteps || (!block->steps[X_AXIS] && !block->steps[Y_AXIS]) || extruder_advance_k == 0.0 || (uint32_t)esteps == block->step_event_count || de_float <= 0.0) {
1318
-      block->use_advance_lead = false;
1319
-    }
1320
-    else {
1321
-      block->use_advance_lead = true;
1296
+    //
1297
+    // Use LIN_ADVANCE for blocks if all these are true:
1298
+    //
1299
+    // esteps                                          : We have E steps todo (a printing move)
1300
+    // 
1301
+    // block->steps[X_AXIS] || block->steps[Y_AXIS]    : We have a movement in XY direction (i.e., not retract / prime).
1302
+    // 
1303
+    // extruder_advance_k                              : There is an advance factor set.
1304
+    // 
1305
+    // block->steps[E_AXIS] != block->step_event_count : A problem occurs if the move before a retract is too small.
1306
+    //                                                   In that case, the retract and move will be executed together.
1307
+    //                                                   This leads to too many advance steps due to a huge e_acceleration.
1308
+    //                                                   The math is good, but we must avoid retract moves with advance!
1309
+    // de_float > 0.0                                  : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
1310
+    //
1311
+    block->use_advance_lead =  esteps
1312
+                            && (block->steps[X_AXIS] || block->steps[Y_AXIS])
1313
+                            && extruder_advance_k
1314
+                            && (uint32_t)esteps != block->step_event_count
1315
+                            && de_float > 0.0;
1316
+    if (block->use_advance_lead)
1322
       block->abs_adv_steps_multiplier8 = lround(extruder_advance_k * (de_float / mm_D_float) * block->nominal_speed / (float)block->nominal_rate * axis_steps_per_mm[E_AXIS_N] * 256.0);
1317
       block->abs_adv_steps_multiplier8 = lround(extruder_advance_k * (de_float / mm_D_float) * block->nominal_speed / (float)block->nominal_rate * axis_steps_per_mm[E_AXIS_N] * 256.0);
1323
-    }
1324
 
1318
 
1325
   #elif ENABLED(ADVANCE)
1319
   #elif ENABLED(ADVANCE)
1326
 
1320
 
1327
     // Calculate advance rate
1321
     // Calculate advance rate
1328
-    if (!esteps || (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS])) {
1329
-      block->advance_rate = 0;
1330
-      block->advance = 0;
1331
-    }
1332
-    else {
1333
-      long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_steps_per_s2);
1334
-      float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * HYPOT(current_speed[E_AXIS], EXTRUSION_AREA) * 256;
1322
+    if (esteps && (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS])) {
1323
+      const long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_steps_per_s2);
1324
+      const float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * HYPOT(current_speed[E_AXIS], EXTRUSION_AREA) * 256;
1335
       block->advance = advance;
1325
       block->advance = advance;
1336
       block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
1326
       block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
1337
     }
1327
     }
1328
+    else
1329
+      block->advance_rate = block->advance = 0;
1330
+
1338
     /**
1331
     /**
1339
      SERIAL_ECHO_START;
1332
      SERIAL_ECHO_START;
1340
      SERIAL_ECHOPGM("advance :");
1333
      SERIAL_ECHOPGM("advance :");

Loading…
Cancel
Save