Extruder Speed Control Puzzle

The Retraction speed in the Skeinforge Dimension plugin sets the E axis speed while it’s inhaling molten filament at the end of each thread and exhaling it at the start of the next thread. For a Retraction speed of 60 mm/s = 3600 mm/min and a Retraction Distance of 2 mm, the G-Code at the very start of the Skirt thread looks like this:

G1 F3600.0
G1 E2.0

So far, so good; that, I can understand. The extruder spins at a pretty good clip, but only while moving 2 mm of filament.

The Dimension plugin doc explains the settings for its parameters, but isn’t forthcoming on the subject of what to use for the Flow rate in the Speed plugin. The Speed plugin doc doesn’t help much; it seems the Flow rate uses either PWM or mm/s, depending on something imponderable. Per that discussion, you should apparently set both Feed and Flow to the same value (in mm/s), which I have done. Given that G-Code has only one speed setting for coordinated motion, that seems reasonable.

For a Feed speed of 60 mm/s = 3600 mm/s (which may seem aggressive, but that’s what acceleration limiting enables), the G-Code at the start of the second layer looks like this:

G1 X-3.5302 Y-26.3671 Z0.5 F3600.0 E141.3026
G1 X2.7622 Y-22.7342 Z0.5 F3600.0 E141.4484
G1 X9.0546 Y-26.3671 Z0.5 F3600.0 E141.5941

However, that seems to mean the extruder rams filament into the hot end at 3600 mm/min = 60 mm/s, which simply isn’t what’s going on. The pinch wheel / gear / whatever turns at maybe 2 rev/min, which corresponds to about 60 mm/min: roughly 1/60 the speed indicated by the F3600.0 parameter.

The SJFW M201 parameter was set to E60, which should set 60 mm/min as the minimum speed. But Skeinforge doesn’t know anything about the firmware’s internal minimum (or maximum!) speed limits.

So I tried a few manual variations with the extruder heated up, feeding in commands like G1 E10 Fnn, with various nn values for the F speed, while measuring the elapsed time. If F sets the extruder speed in mm/min, then the time to extrude 10 mm of filament should vary inversely with the speed. Some results:

  • F240 → 10 s
  • F360 → 10 s
  • F400 → 11 s
  • F450 → 1 s
  • F480 → 1 s

Huh. Now that, I do not understand.

Setting M201 E120, which should double the minimum speed, produces these reasonable results:

  • F1 → 10 s
  • F2 → 7 s
  • F3 → 6 s
  • F4 → 3 s
  • F5 → stalls because the extruder can’t maintain that pace

The first line seems to indicate that extruding 10 mm of filament at 1 mm/min requires 10 seconds, which is off by a neat factor of 1/60. The ratio of the lines is more-or-less right, as long as you allow more measurement windage than seems appropriate and ignore the gross overall speed mismatch. The difference between the two sequences is not the ratio of the two M201 settings, however.

I have the extruder set to accelerate at 250 mm/s2, which implies it can reach 120 mm/min = 2 mm/s in 0.008 mm, which is basically instantly. Relevant equation: x = v2/2a.

Given the incoming filament diameter and the outgoing extrusion thread dimensions, Skeinforge knows their cross-sectional areas.  Multiplying the extrusion thread’s cross-section area by the Pythagorean XY distance for a segment gives the extrusion volume, dividing that by the filament cross-section area gives the incoming filament length, and dividing that by the Filament Packing Density fudges the answer to come out right.

From the coordinates in the first two lines of G-Code we have:

  • XY distance = 7.27 mm
  • extrusion distance = 0.15 mm

Given the corresponding extrusion settings:

  • 0.25 mm layer height and 0.50 mm width = 0.125 mm2
  • 2.89 mm filament dia = 6.56 mm2
  • FPD=0.95

The incoming distance works out to (0.125 * 7.27 / 6.56) / 0.95 = 0.15 mm, which is dead on the G-Code value. So I understand the volume part, at least.

At the Feed rate of 60 mm/s, the extruder covers the XY distance in 7.27 / 60 = 0.12 s. The extruder must consume 0.15 mm of filament in that same time, which works out to 0.15 / 0.12 = 1.2 mm/s = 72 mm/min.

Obviously, the extruder filament drive is not running at the F3600.0 value set by the G-Code, nor is it running at 1/60 that speed.

I have not the foggiest idea what’s going on in there, but … it seems to work. Equally obviously, because Skeinforge doesn’t know which firmware I’m using, all the firmware usable with Dimension behaves the same way.

One possibility: perhaps the E axis (definitely not XY and probably not Z) runs in something resembling EMC2’s inverse time mode, wherein the firmware adjusts the speed to complete the move in a fixed time. In this case, the firmware knows both the distance (given by Skeinforge in the E parameter) and the time for the XY move (found by dividing that XY Pythagorean distance by the F parameter), so it can compute the speed required to make the extruder poot out the right amount of plastic in that time, presumably while imposing (trapezoidal?) acceleration limiting along the way.

That might also account for the weird behavior with M201 E60 shown above: perhaps the firmware uses a stale time left over from the most recent XY motion to compute the speed for a move involving only the E axis. I suppose I could puzzle through the source; it’s rather daunting.

Anybody have any clues or pointers to the obvious doc I’ve overlooked?

6 thoughts on “Extruder Speed Control Puzzle

  1. My understanding is the extruder is considered as another dimension in the Bresenham loop, so it starts and ends at the same time as the other axes and moves the E distance.The F parameter sets the speed along the movement vector and I assume the E distance is ignored in that calculation, unless E is the only axis moving.

    1. so it starts and ends at the same time as the other axes and moves the E distance

      That’s pretty much what I thought: the F parameter controls the XY speed and sets the overall time, with E controlling the filament “distance” and that speed determined by the time. Perhaps the saving grace here is that normal extrusions run the E axis at speeds so far under its upper limit that everything Just Works.

      Which means the bizarre speed behavior with moves involving only the E axis may expose an error inside SJFW: retraction moves (seem to) work OK, at least eyeballometrically, but anything more complex falls off the rails.

  2. Ed,
    My understanding is the same as nophead’s and your suspicions. The E velocity is a product of the time it takes for vector XYZ to complete at speed F with acceleration A . That is what I came up with when building an arm based controller and MACH 3 seems to exhibit the same functionality.

    Having to loop up the M201 gcode I don’t think it is setting the parameter you expect it to. according to the wiki ( http://reprap.org/wiki/Sjfw ) it sets the instantaneous start speed Vo not the velocity limit. It also states that as of 1.8 it uses 1/2 the configured value because, ‘it is the right thing to do’ [groan]. I wonder what happens when acceleration is applied over a small distance that limits Vf to be less than 1/2 Vo. Take into consideration that I am no expert on SJFW and could be talking out my butt…

    1. it sets the instantaneous start speed

      Sooooo I’d expect that to be the minimum speed, rather than having it start like a bat outta hell, then instantly slow down to nose-pickin’ speed… which it certainly doesn’t do. In any event, changing that value doesn’t seem to affect the results in any predictable way.

      On the other paw, that probably explains what’s going on: if the speed would exceed the minimum limit, then motion starts at the minimum speed and accelerates. If it’s less (dramatically less, in this case), then that limit doesn’t apply and motion trundles along (perhaps without acceleration limiting) at the calculated rate.

      EMC2 doesn’t do coordinated motion with rotary axes, either, because it can’t determine what the rotary axis does to the controlled point. It applies trapezoidal acceleration limiting to the rotary axis over the XYZ elapsed time, although in a predictable manner. At least, that’s true for the trivial kinematics used for the Sherline XYZ+A milling machine; I’d expect quite different results from, say, the hexpod kinematics module.

  3. How timely. I wrote this E computation code for my slicer just last night. I’ll find out later today if I am actually doing it right when I try to print it.

    void gcodegen_lineto( QVector& history, const gcodegen_options& options, float X, float Y, float F, QString& output )
    gcode_state& last=history.last();

    float deltaE=0;
    float len=(last._X-X)*(last._X-X)+(last._Y-Y)*(last._Y-Y);
    if( len>0.0001f )

    gcodegen_G1( history, options, X, Y, last._Z, F, last._E+deltaE, “lineto”, output );

Comments are closed.