Extend to also limit the feed rate if the extruder max speed is exceeded.
authorJim Morris <morris@wolfman.com>
Mon, 17 Aug 2015 00:34:03 +0000 (17:34 -0700)
committerJim Morris <morris@wolfman.com>
Mon, 17 Aug 2015 00:34:03 +0000 (17:34 -0700)
  M203 E0 will turn off the extruder speed check
  M203 V0 will turn off volumetric limiting if in volumetric extrusion mode
  defaults are M203 E50 (set in config) and V0
  For now volumetric speed limit can only be set with M203 Vxxx

src/modules/robot/Robot.cpp
src/modules/tools/extruder/Extruder.cpp
src/modules/tools/extruder/Extruder.h

index 938a4ac..c640f02 100644 (file)
@@ -740,15 +740,16 @@ void Robot::append_milestone(Gcode *gcode, float target[], float rate_mm_s )
 
     // if we have volumetric limits enabled we calculate the volume for this move and limit the rate if it exceeds the stated limit
     // Note we need to be using volumetric extrusion for this to work as Ennn is in mm³ not mm
-    // We ask Extruder to do all the work, but as Extruder won;t even see this gcode until after it has been planned
-    // we need to ask it now passing in the relative data.
+    // We also check we are not exceeding the E max_speed for the current extruder
+    // We ask Extruder to do all the work, but as Extruder won't even see this gcode until after it has been planned
+    // we need to ask it now passing in the relevant data.
     if(gcode->has_letter('E')) {
         float data[2];
         data[0]= gcode->get_value('E'); // E target (maybe absolute or relative)
-        data[1]= isecs; // inverted seconds
+        data[1]= isecs; // inverted seconds for the move
         if(PublicData::set_value(extruder_checksum, target_checksum, data)) {
             rate_mm_s *= data[1];
-            //THEKERNEL->streams->printf("Extuder has changed the rate by %f to %f\n", data[1], rate_mm_s);
+            //THEKERNEL->streams->printf("Extruder has changed the rate by %f to %f\n", data[1], rate_mm_s);
         }
     }
 
index 50d3d2e..c4e3564 100644 (file)
@@ -209,6 +209,52 @@ void Extruder::on_get_public_data(void* argument){
     }
 }
 
+// check against maximum speeds and return the rate modifier
+float Extruder::check_max_speeds(float target, float isecs)
+{
+    float rm= 1.0F; // default no rate modification
+    float delta;
+    // get change in E (may be mm or mm³)
+    if(milestone_absolute_mode) {
+        delta= fabsf(target - milestone_last_position); // delta move
+        milestone_last_position= target;
+
+    }else{
+        delta= target;
+        milestone_last_position += target;
+    }
+
+    if(this->max_volumetric_rate > 0 && this->filament_diameter > 0.01F) {
+        // volumetric enabled and check for volumetric rate
+        float v= delta * isecs; // the flow rate in mm³/sec
+
+        // return the rate change needed to stay within the max rate
+        if(v > max_volumetric_rate) {
+            rm = max_volumetric_rate / v;
+            isecs *= rm; // this slows the rate down for the next test
+        }
+        //THEKERNEL->streams->printf("requested flow rate: %f mm³/sec, corrected flow rate: %f  mm³/sec\n", v, v * rm);
+    }
+
+    // check for max speed as well
+    float max_speed= this->stepper_motor->get_max_rate();
+    if(max_speed > 0) {
+        if(this->filament_diameter > 0.01F) {
+            // volumetric so need to convert delta which is mm³ to mm
+            delta *= volumetric_multiplier;
+        }
+
+        float sm= 1.0F;
+        float v= delta * isecs; // the speed in mm/sec
+        if(v > max_speed) {
+            sm *= (max_speed / v);
+        }
+        //THEKERNEL->streams->printf("requested speed: %f mm/sec, corrected speed: %f  mm/sec\n", v, v * sm);
+        rm *= sm;
+    }
+    return rm;
+}
+
 void Extruder::on_set_public_data(void *argument)
 {
     PublicDataRequest *pdr = static_cast<PublicDataRequest *>(argument);
@@ -218,32 +264,16 @@ void Extruder::on_set_public_data(void *argument)
     // handle extrude rates request from robot
     // TODO if not in volumetric mode then limit speed based on max_speed
     if(pdr->second_element_is(target_checksum)) {
-        if(!this->enabled || this->max_volumetric_rate == 0 || this->filament_diameter == 0) return;
+        // disabled extruders do not reply NOTE only one enabled extruder supported
+        if(!this->enabled) return;
 
         float *d= static_cast<float*>(pdr->get_data_ptr());
         float target= d[0]; // the E passed in on Gcode is in mm³ (maybe absolute or relative)
         float isecs= d[1]; // inverted secs
-        float delta;
 
-        if(milestone_absolute_mode) {
-            delta= fabsf(target - milestone_last_position); // delta move
-            milestone_last_position= target;
-
-        }else{
-            delta= target;
-            milestone_last_position += target;
-        }
+        // check against maximum speeds and return rate modifier
+        d[1]= check_max_speeds(target, isecs);
 
-        // return the rate change needed to stay within the max rate
-        float v= delta * isecs; // the flow rate in mm³/sec
-
-        // TODO need to take filament diameter into account for limiting to mm/sec of stepper
-        if(v > max_volumetric_rate) {
-            d[1] = max_volumetric_rate / v;
-        }else{
-            d[1]= 1.0F;
-        }
-        //THEKERNEL->streams->printf("requested flow rate: %f, corrected flow rate: %f\n", v, v * d[1]);
         pdr->set_taken();
         return;
     }
@@ -556,7 +586,6 @@ void Extruder::on_gcode_execute(void *argument)
                     // We move proportionally to the robot's movement
                     this->mode = FOLLOW;
                     this->travel_ratio = (relative_extrusion_distance * this->volumetric_multiplier * this->extruder_multiplier) / gcode->millimeters_of_travel; // adjust for volumetric extrusion and extruder multiplier
-                    // TODO: check resulting flowrate, limit robot speed if it exceeds max_speed
                 }
 
                 this->en_pin.set(0);
index 5c1cc8e..f6a3502 100644 (file)
@@ -40,6 +40,7 @@ class Extruder : public Tool {
         void on_get_public_data(void* argument);
         void on_set_public_data(void* argument);
         uint32_t rate_increase() const;
+        float check_max_speeds(float target, float isecs);
 
         StepperMotor*  stepper_motor;
         Pin            step_pin;                     // Step pin for the stepper driver