Browse Source

Adjust E-jerk in LA10 compatibility mode

When upgrading K values of a LA1.0 print, also adjust E-jerk settings
(<2) if permissible according to current accell limits. The same is also
true when jerk is set mid-print via 'M205 E'.

Existing values are always restored when switching to another
compatibility mode.

TODO: Since this is stateful, we will need to save the current print
mode / acceleration and jerk in the eeprom for this to survive a power
panic (see prusa3d#2456).
Yuri D'Elia 4 years ago
parent
commit
453f5dd874
3 changed files with 60 additions and 5 deletions
  1. 11 3
      Firmware/Marlin_main.cpp
  2. 41 1
      Firmware/la10compat.cpp
  3. 8 1
      Firmware/la10compat.h

+ 11 - 3
Firmware/Marlin_main.cpp

@@ -7075,9 +7075,17 @@ Sigma_Exit:
       if(code_seen('X')) cs.max_jerk[X_AXIS] = cs.max_jerk[Y_AXIS] = code_value();
       if(code_seen('Y')) cs.max_jerk[Y_AXIS] = code_value();
       if(code_seen('Z')) cs.max_jerk[Z_AXIS] = code_value();
-      if(code_seen('E')) cs.max_jerk[E_AXIS] = code_value();
-		if (cs.max_jerk[X_AXIS] > DEFAULT_XJERK) cs.max_jerk[X_AXIS] = DEFAULT_XJERK;
-		if (cs.max_jerk[Y_AXIS] > DEFAULT_YJERK) cs.max_jerk[Y_AXIS] = DEFAULT_YJERK;
+      if(code_seen('E'))
+      {
+          float e = code_value();
+#ifndef LA_NOCOMPAT
+
+          e = la10c_jerk(e);
+#endif
+          cs.max_jerk[E_AXIS] = e;
+      }
+      if (cs.max_jerk[X_AXIS] > DEFAULT_XJERK) cs.max_jerk[X_AXIS] = DEFAULT_XJERK;
+      if (cs.max_jerk[Y_AXIS] > DEFAULT_YJERK) cs.max_jerk[Y_AXIS] = DEFAULT_YJERK;
     }
     break;
 

+ 41 - 1
Firmware/la10compat.cpp

@@ -2,13 +2,24 @@
 #include "Marlin.h"
 
 
-static LA10C_MODE la10c_mode = LA10C_UNKNOWN;
+static LA10C_MODE la10c_mode = LA10C_UNKNOWN; // Current LA compatibility mode
+static float la10c_orig_jerk = 0;             // Unadjusted/saved e-jerk
+
+
+LA10C_MODE la10c_mode_get()
+{
+    return la10c_mode;
+}
 
 
 void la10c_mode_change(LA10C_MODE mode)
 {
     if(mode == la10c_mode) return;
 
+    // always restore to the last unadjusted E-jerk value
+    if(la10c_orig_jerk)
+        cs.max_jerk[E_AXIS] = la10c_orig_jerk;
+
     SERIAL_ECHOPGM("LA10C: Linear Advance mode: ");
     switch(mode)
     {
@@ -17,6 +28,9 @@ void la10c_mode_change(LA10C_MODE mode)
     case LA10C_LA10:    SERIAL_ECHOLNPGM("1.0"); break;
     }
     la10c_mode = mode;
+
+    // adjust the E-jerk if needed
+    cs.max_jerk[E_AXIS] = la10c_jerk(cs.max_jerk[E_AXIS]);
 }
 
 
@@ -46,3 +60,29 @@ float la10c_value(float k)
     else
         return (k >= 0? la10c_convert(k): -1);
 }
+
+
+float la10c_jerk(float j)
+{
+    la10c_orig_jerk = j;
+
+    if(la10c_mode != LA10C_LA10)
+        return j;
+
+    // check for a compatible range of values prior to convert (be sure that
+    // a higher E-jerk would still be compatible wrt the E accell range)
+    if(j < 4.5 && cs.max_acceleration_units_per_sq_second_normal[E_AXIS] < 2000)
+        return j;
+
+    // bring low E-jerk values into equivalent LA 1.5 values by
+    // flattening the response in the (1-4.5) range using a piecewise
+    // function. Is it truly worth to preserve the difference between
+    // 1.5/2.5 E-jerk for LA1.0? Probably not, but we try nonetheless.
+    j = j < 1.0? j * 3.625:
+        j < 4.5? j * 0.25 + 3.375:
+        j;
+
+    SERIAL_ECHOPGM("LA10C: Adjusted E-Jerk: ");
+    SERIAL_ECHOLN(j);
+    return j;
+}

+ 8 - 1
Firmware/la10compat.h

@@ -5,6 +5,9 @@
 // compatbility mode is active the K factor is converted to a LA15
 // equivalent (that is, the return value is always a LA15 value).
 //
+// E-jerk<2 is also bumped in LA10 mode to restore the the printing speed
+// to values comparable to existing settings.
+//
 // Once the interpretation mode has been set it is kept until the mode
 // is explicitly reset. This is done to handle transparent fallback for
 // old firmware revisions in combination with the following gcode
@@ -31,9 +34,13 @@ enum __attribute__((packed)) LA10C_MODE
     LA10C_LA10    = 2
 };
 
-// Explicitly set/reset the interpretation mode for la10c_value()
+// Explicitly set/get/reset the interpretation mode for la10c_value()
 void la10c_mode_change(LA10C_MODE mode);
+LA10C_MODE la10c_mode_get();
 static inline void la10c_reset() { la10c_mode_change(LA10C_UNKNOWN); }
 
 // Return a LA15 K value according to the supplied value and mode
 float la10c_value(float k);
+
+// Return an updated LA15 E-jerk value according to the current mode
+float la10c_jerk(float j);