Browse Source

E1+ Autotemp and Planner comments

Scott Lahteine 3 years ago
parent
commit
9823a37362
3 changed files with 130 additions and 76 deletions
  1. 0
    2
      Marlin/src/lcd/extui/ui_api.cpp
  2. 102
    69
      Marlin/src/module/planner.cpp
  3. 28
    5
      Marlin/src/module/planner.h

+ 0
- 2
Marlin/src/lcd/extui/ui_api.cpp View File

587
 
587
 
588
   void setAxisMaxAcceleration_mm_s2(const float &value, const axis_t axis) {
588
   void setAxisMaxAcceleration_mm_s2(const float &value, const axis_t axis) {
589
     planner.set_max_acceleration(axis, value);
589
     planner.set_max_acceleration(axis, value);
590
-    planner.reset_acceleration_rates();
591
   }
590
   }
592
 
591
 
593
   void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) {
592
   void setAxisMaxAcceleration_mm_s2(const float &value, const extruder_t extruder) {
594
     UNUSED_E(extruder);
593
     UNUSED_E(extruder);
595
     planner.set_max_acceleration(E_AXIS_N(extruder - E0), value);
594
     planner.set_max_acceleration(E_AXIS_N(extruder - E0), value);
596
-    planner.reset_acceleration_rates();
597
   }
595
   }
598
 
596
 
599
   #if HAS_FILAMENT_SENSOR
597
   #if HAS_FILAMENT_SENSOR

+ 102
- 69
Marlin/src/module/planner.cpp View File

1248
   recalculate_trapezoids();
1248
   recalculate_trapezoids();
1249
 }
1249
 }
1250
 
1250
 
1251
-#if ENABLED(AUTOTEMP)
1252
-
1253
-  void Planner::getHighESpeed() {
1254
-    static float oldt = 0;
1255
-
1256
-    if (!autotemp_enabled) return;
1257
-    if (thermalManager.degTargetHotend(0) + 2 < autotemp_min) return; // probably temperature set to zero.
1258
-
1259
-    float high = 0.0;
1260
-    for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
1261
-      block_t* block = &block_buffer[b];
1262
-      if (block->steps.x || block->steps.y || block->steps.z) {
1263
-        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
1264
-        NOLESS(high, se);
1265
-      }
1266
-    }
1267
-
1268
-    float t = autotemp_min + high * autotemp_factor;
1269
-    LIMIT(t, autotemp_min, autotemp_max);
1270
-    if (t < oldt) t = t * (1 - float(AUTOTEMP_OLDWEIGHT)) + oldt * float(AUTOTEMP_OLDWEIGHT);
1271
-    oldt = t;
1272
-    thermalManager.setTargetHotend(t, 0);
1273
-  }
1274
-
1275
-#endif // AUTOTEMP
1276
-
1277
 /**
1251
 /**
1278
  * Maintain fans, paste extruder pressure,
1252
  * Maintain fans, paste extruder pressure,
1279
  */
1253
  */
1398
   #endif
1372
   #endif
1399
 }
1373
 }
1400
 
1374
 
1375
+#if ENABLED(AUTOTEMP)
1376
+
1377
+  #if ENABLED(AUTOTEMP_PROPORTIONAL)
1378
+    void Planner::_autotemp_update_from_hotend() {
1379
+      const int16_t target = thermalManager.degTargetHotend(active_extruder);
1380
+      autotemp_min = target + AUTOTEMP_MIN_P;
1381
+      autotemp_max = target + AUTOTEMP_MAX_P;
1382
+    }
1383
+  #endif
1384
+
1385
+  /**
1386
+   * Called after changing tools to:
1387
+   *  - Reset or re-apply the default proportional autotemp factor.
1388
+   *  - Enable autotemp if the factor is non-zero.
1389
+   */
1390
+  void Planner::autotemp_update() {
1391
+    _autotemp_update_from_hotend();
1392
+    autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
1393
+    autotemp_enabled = autotemp_factor != 0;
1394
+  }
1395
+
1396
+  /**
1397
+   * Called by the M104/M109 commands after setting Hotend Temperature
1398
+   *
1399
+   */
1400
+  void Planner::autotemp_M104_M109() {
1401
+    _autotemp_update_from_hotend();
1402
+
1403
+    if (parser.seenval('S')) autotemp_min = parser.value_celsius();
1404
+    if (parser.seenval('B')) autotemp_max = parser.value_celsius();
1405
+
1406
+    // When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp.
1407
+    // Normally, leaving off F also disables autotemp.
1408
+    autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
1409
+    autotemp_enabled = autotemp_factor != 0;
1410
+  }
1411
+
1412
+  /**
1413
+   * Called every so often to adjust the hotend target temperature
1414
+   * based on the extrusion speed, which is calculated from the blocks
1415
+   * currently in the planner.
1416
+   */
1417
+  void Planner::getHighESpeed() {
1418
+    static float oldt = 0;
1419
+
1420
+    if (!autotemp_enabled) return;
1421
+    if (thermalManager.degTargetHotend(active_extruder) < autotemp_min - 2) return; // Below the min?
1422
+
1423
+    float high = 0.0;
1424
+    for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
1425
+      block_t* block = &block_buffer[b];
1426
+      if (block->steps.x || block->steps.y || block->steps.z) {
1427
+        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
1428
+        NOLESS(high, se);
1429
+      }
1430
+    }
1431
+
1432
+    float t = autotemp_min + high * autotemp_factor;
1433
+    LIMIT(t, autotemp_min, autotemp_max);
1434
+    if (t < oldt) t *= (1.0f - (AUTOTEMP_OLDWEIGHT)) + oldt * (AUTOTEMP_OLDWEIGHT);
1435
+    oldt = t;
1436
+    thermalManager.setTargetHotend(t, active_extruder);
1437
+  }
1438
+
1439
+#endif
1440
+
1401
 #if DISABLED(NO_VOLUMETRICS)
1441
 #if DISABLED(NO_VOLUMETRICS)
1402
 
1442
 
1403
   /**
1443
   /**
2959
   TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk());
2999
   TERN_(HAS_LINEAR_E_JERK, recalculate_max_e_jerk());
2960
 }
3000
 }
2961
 
3001
 
2962
-// Recalculate position, steps_to_mm if settings.axis_steps_per_mm changes!
3002
+/**
3003
+ * Recalculate 'position' and 'steps_to_mm'.
3004
+ * Must be called whenever settings.axis_steps_per_mm changes!
3005
+ */
2963
 void Planner::refresh_positioning() {
3006
 void Planner::refresh_positioning() {
2964
   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i];
3007
   LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i];
2965
   set_position_mm(current_position);
3008
   set_position_mm(current_position);
2966
   reset_acceleration_rates();
3009
   reset_acceleration_rates();
2967
 }
3010
 }
2968
 
3011
 
3012
+// Apply limits to a variable and give a warning if the value was out of range
2969
 inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
3013
 inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
2970
   const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis;
3014
   const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis;
2971
   const float before = val;
3015
   const float before = val;
2978
   }
3022
   }
2979
 }
3023
 }
2980
 
3024
 
2981
-void Planner::set_max_acceleration(const uint8_t axis, float targetValue) {
3025
+/**
3026
+ * For the specified 'axis' set the Maximum Acceleration to the given value (mm/s^2)
3027
+ * The value may be limited with warning feedback, if configured.
3028
+ * Calls reset_acceleration_rates to precalculate planner terms in steps.
3029
+ *
3030
+ * This hard limit is applied as a block is being added to the planner queue.
3031
+ */
3032
+void Planner::set_max_acceleration(const uint8_t axis, const float &inMaxAccelMMS2) {
2982
   #if ENABLED(LIMITED_MAX_ACCEL_EDITING)
3033
   #if ENABLED(LIMITED_MAX_ACCEL_EDITING)
2983
     #ifdef MAX_ACCEL_EDIT_VALUES
3034
     #ifdef MAX_ACCEL_EDIT_VALUES
2984
       constexpr xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES;
3035
       constexpr xyze_float_t max_accel_edit = MAX_ACCEL_EDIT_VALUES;
2987
       constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION;
3038
       constexpr xyze_float_t max_accel_edit = DEFAULT_MAX_ACCELERATION;
2988
       const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2;
3039
       const xyze_float_t max_acc_edit_scaled = max_accel_edit * 2;
2989
     #endif
3040
     #endif
2990
-    limit_and_warn(targetValue, axis, PSTR("Acceleration"), max_acc_edit_scaled);
3041
+    limit_and_warn(inMaxAccelMMS2, axis, PSTR("Acceleration"), max_acc_edit_scaled);
2991
   #endif
3042
   #endif
2992
-  settings.max_acceleration_mm_per_s2[axis] = targetValue;
3043
+  settings.max_acceleration_mm_per_s2[axis] = inMaxAccelMMS2;
2993
 
3044
 
2994
   // Update steps per s2 to agree with the units per s2 (since they are used in the planner)
3045
   // Update steps per s2 to agree with the units per s2 (since they are used in the planner)
2995
   reset_acceleration_rates();
3046
   reset_acceleration_rates();
2996
 }
3047
 }
2997
 
3048
 
2998
-void Planner::set_max_feedrate(const uint8_t axis, float targetValue) {
3049
+/**
3050
+ * For the specified 'axis' set the Maximum Feedrate to the given value (mm/s)
3051
+ * The value may be limited with warning feedback, if configured.
3052
+ *
3053
+ * This hard limit is applied as a block is being added to the planner queue.
3054
+ */
3055
+void Planner::set_max_feedrate(const uint8_t axis, const float &inMaxFeedrateMMS) {
2999
   #if ENABLED(LIMITED_MAX_FR_EDITING)
3056
   #if ENABLED(LIMITED_MAX_FR_EDITING)
3000
     #ifdef MAX_FEEDRATE_EDIT_VALUES
3057
     #ifdef MAX_FEEDRATE_EDIT_VALUES
3001
       constexpr xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES;
3058
       constexpr xyze_float_t max_fr_edit = MAX_FEEDRATE_EDIT_VALUES;
3004
       constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE;
3061
       constexpr xyze_float_t max_fr_edit = DEFAULT_MAX_FEEDRATE;
3005
       const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2;
3062
       const xyze_float_t max_fr_edit_scaled = max_fr_edit * 2;
3006
     #endif
3063
     #endif
3007
-    limit_and_warn(targetValue, axis, PSTR("Feedrate"), max_fr_edit_scaled);
3064
+    limit_and_warn(inMaxFeedrateMMS, axis, PSTR("Feedrate"), max_fr_edit_scaled);
3008
   #endif
3065
   #endif
3009
-  settings.max_feedrate_mm_s[axis] = targetValue;
3066
+  settings.max_feedrate_mm_s[axis] = inMaxFeedrateMMS;
3010
 }
3067
 }
3011
 
3068
 
3012
-void Planner::set_max_jerk(const AxisEnum axis, float targetValue) {
3013
-  #if HAS_CLASSIC_JERK
3069
+#if HAS_CLASSIC_JERK
3070
+
3071
+  /**
3072
+   * For the specified 'axis' set the Maximum Jerk (instant change) to the given value (mm/s)
3073
+   * The value may be limited with warning feedback, if configured.
3074
+   *
3075
+   * This hard limit is applied (to the block start speed) as the block is being added to the planner queue.
3076
+   */
3077
+  void Planner::set_max_jerk(const AxisEnum axis, const float &targetValue) {
3014
     #if ENABLED(LIMITED_JERK_EDITING)
3078
     #if ENABLED(LIMITED_JERK_EDITING)
3015
       constexpr xyze_float_t max_jerk_edit =
3079
       constexpr xyze_float_t max_jerk_edit =
3016
         #ifdef MAX_JERK_EDIT_VALUES
3080
         #ifdef MAX_JERK_EDIT_VALUES
3023
       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit);
3087
       limit_and_warn(targetValue, axis, PSTR("Jerk"), max_jerk_edit);
3024
     #endif
3088
     #endif
3025
     max_jerk[axis] = targetValue;
3089
     max_jerk[axis] = targetValue;
3026
-  #else
3027
-    UNUSED(axis); UNUSED(targetValue);
3028
-  #endif
3029
-}
3090
+  }
3091
+
3092
+#endif
3030
 
3093
 
3031
 #if HAS_WIRED_LCD
3094
 #if HAS_WIRED_LCD
3032
 
3095
 
3069
   }
3132
   }
3070
 
3133
 
3071
 #endif
3134
 #endif
3072
-
3073
-#if ENABLED(AUTOTEMP)
3074
-
3075
-void Planner::autotemp_update() {
3076
-  #if ENABLED(AUTOTEMP_PROPORTIONAL)
3077
-    const int16_t target = thermalManager.degTargetHotend(active_extruder);
3078
-    autotemp_min = target + AUTOTEMP_MIN_P;
3079
-    autotemp_max = target + AUTOTEMP_MAX_P;
3080
-  #endif
3081
-  autotemp_factor = TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
3082
-  autotemp_enabled = autotemp_factor != 0;
3083
-}
3084
-
3085
-  void Planner::autotemp_M104_M109() {
3086
-
3087
-    #if ENABLED(AUTOTEMP_PROPORTIONAL)
3088
-      const int16_t target = thermalManager.degTargetHotend(active_extruder);
3089
-      autotemp_min = target + AUTOTEMP_MIN_P;
3090
-      autotemp_max = target + AUTOTEMP_MAX_P;
3091
-    #endif
3092
-
3093
-    if (parser.seenval('S')) autotemp_min = parser.value_celsius();
3094
-    if (parser.seenval('B')) autotemp_max = parser.value_celsius();
3095
-
3096
-    // When AUTOTEMP_PROPORTIONAL is enabled, F0 disables autotemp.
3097
-    // Normally, leaving off F also disables autotemp.
3098
-    autotemp_factor = parser.seen('F') ? parser.value_float() : TERN(AUTOTEMP_PROPORTIONAL, AUTOTEMP_FACTOR_P, 0);
3099
-    autotemp_enabled = autotemp_factor != 0;
3100
-  }
3101
-#endif

+ 28
- 5
Marlin/src/module/planner.h View File

460
      * Static (class) Methods
460
      * Static (class) Methods
461
      */
461
      */
462
 
462
 
463
+    // Recalculate steps/s^2 accelerations based on mm/s^2 settings
463
     static void reset_acceleration_rates();
464
     static void reset_acceleration_rates();
465
+
466
+    /**
467
+     * Recalculate 'position' and 'steps_to_mm'.
468
+     * Must be called whenever settings.axis_steps_per_mm changes!
469
+     */
464
     static void refresh_positioning();
470
     static void refresh_positioning();
465
-    static void set_max_acceleration(const uint8_t axis, float targetValue);
466
-    static void set_max_feedrate(const uint8_t axis, float targetValue);
467
-    static void set_max_jerk(const AxisEnum axis, float targetValue);
468
 
471
 
472
+    // For an axis set the Maximum Acceleration in mm/s^2
473
+    static void set_max_acceleration(const uint8_t axis, const float &inMaxAccelMMS2);
474
+
475
+    // For an axis set the Maximum Feedrate in mm/s
476
+    static void set_max_feedrate(const uint8_t axis, const float &inMaxFeedrateMMS);
477
+
478
+    // For an axis set the Maximum Jerk (instant change) in mm/s
479
+    #if HAS_CLASSIC_JERK
480
+      static void set_max_jerk(const AxisEnum axis, const float &inMaxJerkMMS);
481
+    #else
482
+      static inline void set_max_jerk(const AxisEnum, const float&) {}
483
+    #endif
469
 
484
 
470
     #if EXTRUDERS
485
     #if EXTRUDERS
471
       FORCE_INLINE static void refresh_e_factor(const uint8_t e) {
486
       FORCE_INLINE static void refresh_e_factor(const uint8_t e) {
883
     #if ENABLED(AUTOTEMP)
898
     #if ENABLED(AUTOTEMP)
884
       static float autotemp_min, autotemp_max, autotemp_factor;
899
       static float autotemp_min, autotemp_max, autotemp_factor;
885
       static bool autotemp_enabled;
900
       static bool autotemp_enabled;
886
-      static void getHighESpeed();
887
-      static void autotemp_M104_M109();
888
       static void autotemp_update();
901
       static void autotemp_update();
902
+      static void autotemp_M104_M109();
903
+      static void getHighESpeed();
889
     #endif
904
     #endif
890
 
905
 
891
     #if HAS_LINEAR_E_JERK
906
     #if HAS_LINEAR_E_JERK
898
 
913
 
899
   private:
914
   private:
900
 
915
 
916
+    #if ENABLED(AUTOTEMP)
917
+      #if ENABLED(AUTOTEMP_PROPORTIONAL)
918
+        static void _autotemp_update_from_hotend();
919
+      #else
920
+        static inline void _autotemp_update_from_hotend() {}
921
+      #endif
922
+    #endif
923
+
901
     /**
924
     /**
902
      * Get the index of the next / previous block in the ring buffer
925
      * Get the index of the next / previous block in the ring buffer
903
      */
926
      */

Loading…
Cancel
Save