Browse Source

Planner acceleration bugfix and speedup v2

.) Use already existing inverse_millimeters instead of /
block->millimeters.
.) Prevent overflow during acceleration calculation by checking if float
is necessary. Idea modified from Sailfish.
.) Save two uint32_t or even float multiplications by checking if
step[AXIS] has steps and if max acceleration is lower than accel. If
not, there is no need to check this axis.
Sebastianv650 8 years ago
parent
commit
c397b9d60a
2 changed files with 36 additions and 9 deletions
  1. 31
    9
      Marlin/planner.cpp
  2. 5
    0
      Marlin/planner.h

+ 31
- 9
Marlin/planner.cpp View File

115
 
115
 
116
 long Planner::position[NUM_AXIS] = { 0 };
116
 long Planner::position[NUM_AXIS] = { 0 };
117
 
117
 
118
+uint32_t Planner::cutoff_long;
119
+
118
 float Planner::previous_speed[NUM_AXIS],
120
 float Planner::previous_speed[NUM_AXIS],
119
       Planner::previous_nominal_speed;
121
       Planner::previous_nominal_speed;
120
 
122
 
1013
   }
1015
   }
1014
 
1016
 
1015
   // Compute and limit the acceleration rate for the trapezoid generator.
1017
   // Compute and limit the acceleration rate for the trapezoid generator.
1016
-  float steps_per_mm = block->step_event_count / block->millimeters;
1018
+  float steps_per_mm = block->step_event_count * inverse_millimeters;
1017
   uint32_t accel;
1019
   uint32_t accel;
1018
   if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) {
1020
   if (!block->steps[X_AXIS] && !block->steps[Y_AXIS] && !block->steps[Z_AXIS]) {
1019
     // convert to: acceleration steps/sec^2
1021
     // convert to: acceleration steps/sec^2
1020
     accel = ceil(retract_acceleration * steps_per_mm);
1022
     accel = ceil(retract_acceleration * steps_per_mm);
1021
   }
1023
   }
1022
   else {
1024
   else {
1023
-    #define LIMIT_ACCEL(AXIS) do{ \
1024
-      if (max_acceleration_steps_per_s2[AXIS] < (accel * block->steps[AXIS]) / block->step_event_count) \
1025
-        accel = (max_acceleration_steps_per_s2[AXIS] * block->step_event_count) / block->steps[AXIS]; \
1025
+    #define LIMIT_ACCEL_LONG(AXIS) do{ \
1026
+      if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS] < accel) { \
1027
+        const uint32_t comp = max_acceleration_steps_per_s2[AXIS] * block->step_event_count; \
1028
+        if (accel * block->steps[AXIS] > comp) accel = comp / block->steps[AXIS]; \
1029
+      } \
1030
+    }while(0)
1031
+	
1032
+    #define LIMIT_ACCEL_FLOAT(AXIS) do{ \
1033
+      if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS] < accel) { \
1034
+        const float comp = (float)max_acceleration_steps_per_s2[AXIS] * (float)block->step_event_count; \
1035
+        if ((float)accel * (float)block->steps[AXIS] > comp) accel = comp / (float)block->steps[AXIS]; \
1036
+      } \
1026
     }while(0)
1037
     }while(0)
1027
 
1038
 
1028
     // Start with print or travel acceleration
1039
     // Start with print or travel acceleration
1029
     accel = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm);
1040
     accel = ceil((block->steps[E_AXIS] ? acceleration : travel_acceleration) * steps_per_mm);
1030
 
1041
 
1031
     // Limit acceleration per axis
1042
     // Limit acceleration per axis
1032
-    LIMIT_ACCEL(X_AXIS);
1033
-    LIMIT_ACCEL(Y_AXIS);
1034
-    LIMIT_ACCEL(Z_AXIS);
1035
-    LIMIT_ACCEL(E_AXIS);
1043
+    if (block->step_event_count <= cutoff_long){
1044
+      LIMIT_ACCEL_LONG(X_AXIS);
1045
+      LIMIT_ACCEL_LONG(Y_AXIS);
1046
+      LIMIT_ACCEL_LONG(Z_AXIS);
1047
+      LIMIT_ACCEL_LONG(E_AXIS);
1048
+    } else {
1049
+      LIMIT_ACCEL_FLOAT(X_AXIS);
1050
+      LIMIT_ACCEL_FLOAT(Y_AXIS);
1051
+      LIMIT_ACCEL_FLOAT(Z_AXIS);
1052
+      LIMIT_ACCEL_FLOAT(E_AXIS);
1053
+    }
1036
   }
1054
   }
1037
   block->acceleration_steps_per_s2 = accel;
1055
   block->acceleration_steps_per_s2 = accel;
1038
   block->acceleration = accel / steps_per_mm;
1056
   block->acceleration = accel / steps_per_mm;
1303
 
1321
 
1304
 // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
1322
 // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
1305
 void Planner::reset_acceleration_rates() {
1323
 void Planner::reset_acceleration_rates() {
1306
-  LOOP_XYZE(i)
1324
+  uint32_t highest_acceleration_allaxes_steps_per_s2;
1325
+  LOOP_XYZE(i) {
1307
     max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
1326
     max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
1327
+    if (max_acceleration_steps_per_s2[i] > highest_acceleration_allaxes_steps_per_s2) highest_acceleration_allaxes_steps_per_s2 = max_acceleration_steps_per_s2[i];
1328
+  }
1329
+  cutoff_long = 4294967295UL / highest_acceleration_allaxes_steps_per_s2;
1308
 }
1330
 }
1309
 
1331
 
1310
 // Recalculate position, steps_to_mm if axis_steps_per_mm changes!
1332
 // Recalculate position, steps_to_mm if axis_steps_per_mm changes!

+ 5
- 0
Marlin/planner.h View File

166
      * Nominal speed of previous path line segment
166
      * Nominal speed of previous path line segment
167
      */
167
      */
168
     static float previous_nominal_speed;
168
     static float previous_nominal_speed;
169
+	
170
+	/**
171
+ 	 * Limit where 64bit math is necessary for acceleration calculation
172
+ 	 */
173
+ 	static uint32_t cutoff_long;
169
 
174
 
170
     #if ENABLED(DISABLE_INACTIVE_EXTRUDER)
175
     #if ENABLED(DISABLE_INACTIVE_EXTRUDER)
171
       /**
176
       /**

Loading…
Cancel
Save