This is a more prosaic idea prompted by G Codes and the fact that several people are doing stepper-motor-driven extruders or ones using Zach's neat shaft encoder. I hope I haven't stolen it from Nophead and recycled it as my own idea...
Clearly if you have a stepper extruder there is a precise relationship between the length in mm of filament extruded and the number of steps (this ignores time delays, melt compression and so on - run with me on this). So, why not incorporate the number of mm of filament to extrude as a dimension on each movement? You'd have things like
G1 W50.0 X30.0 Y40.0 F560.0
Where the W coordinate is the number of mm of filament to extrude. This could either get bigger and bigger as a build progresses (we're not going to run out of floating point numbers...) or we could have a convention that zeros it before each move, so it's Pythagoras on the X and Y numbers.
With that we can then control the machine with a 4D Bressenham DDA, which is just as easy to write as the current 3D one and takes hardly any more microcontroller space.
We can then obviously play tricks to get more or less extrudate:
G1 W100.0 X30.0 Y40.0 F560.0
would make a fat splongy line and
G1 W25.0 X30.0 Y40.0 F560.0
would make a jejune one. You can run the extruder without moving to take up any slack:
G1 W10.0 F560.0
and of course you can move with it turned off by omitting the W value altogether.
I'm not sure if this is:
- Clever,
- Dumb,
- Obvious, or
- Useless.
Looks like a good idea - and I do have one spare stepper kicking about, could be worth playing with.
ReplyDeleteIs this usable when using multiple extruders? (thinking out loud)
ReplyDeleteFilament tends to have non-linear behavior that I think might make it more tricky than a simple bresenhem algorithm. See http://forums.reprap.org/read.php?14,20418 for example.
ReplyDeleteI use a stepper on the hercules extruder (www.ooeygui.com). A concern with either a stepper or rotary encoded motor is measuring how much filament actually exits the extruder - which can differ due to slippage or stalling. I've been toying with the idea of using a separate rotary encoder pinch-pulleyed to the filament directly - disconnected from the drive system.
ReplyDeleteSkeinforge has had a version of this in since last summer, but it's only used for the raft at this point. I believe it was Nophead's idea, but basically we set a feed rate with an M code, ie:
ReplyDeleteM108 S31.9
sets the extruder controller to 31.9 RPM on my machine, which corresponds to an ideal head feed rate of 8 mm/s.
The first raft layer gets built with a lower than ideal head (not extruder) feedrate, resulting in a fat filament that fills up holes, and then the rest of the part is built at a faster head feedrate, to get finer resolution and better gap spanning.
Generally I don't change the extruder rate during a build, as my build rate is limited by my extruder rate, so I set the extruder to a fixed speed near it's maximum speed, and then vary the head rate with the F parameter. Instead of the W command, right now it will work if you just send a new M108 Sxx before your move.
I use a GM3 with Zach's magnetic encoder, and a PID loop to keep it in synch; but it's not perfect, there's a bit of delay as the GM3 gear train gets up to speed when I change speeds, so I've been trying to minimize the number of speed changes or extruder stops and starts. A geared stepper might be a bit quicker, but you'd still have to account for acceleration.
I don't think there's a functional difference between setting the filament speed and head speed for a given distance, vs setting the filament distance vs head speed (and distance) for a given distance. Different parameters, but same result.
Wade
Batist Leman - Multiple extruders: yes, as long as they all have a steps per mm of extrudate value. So it works for screw-driven syringe extruders too.
ReplyDeleteOoeygui - Slipping and stalling: yes - these obviously have to be absent, or at least minimal (a few steps in every m of filament obviously wouldn't matter).
BeagleFury - Extruder non-linearities: yes - there are these, and you can reverse the extruder just by asking for a negative (or lower than current) W value. You can also stop the extruder before the end of a line just by splitting the line at the stop point, then plotting the last bit with the extruder turned off (that's what the Java code does at the moment), and you can have a dwell at the start of plotting by making a zero-length-in-real-space line with a 20mm (o.w.e.) filament length.
Wade: Yes - the Java uses those M codes too. But it seemed mathematically and computationally neater to wrap it up in a G code as an extra dimension.
Of course once you start down this (hyper)road, you can go anywhere. Temperature as a dimension? Conceptually, building something in a RepRap then becomes an exercise in moving a point about in hyperspace in straight line segments using a universal DDA. Freaky and elegant and guaranteed to scare away non-geeks in equal measure...
As long as the extruder speed can be accurately controlled I don't see the need to lock it step by step with a 4D Bresenham. Doing so would be very easy with a single controller but complex with separate head controllers on a serial bus, e.g. the sync lines of the PIC system.
ReplyDeleteIn fact as pointed out above there isn't a simple linear relationship due the non Newtonian nature of the molten filament. The extruder should start first and the XY motion ramp up to match the filament output. At the end of the line the extruder should stop early and the XY slow down exponentially to match the flow rate.
Enrique's s/w attempts to do that within the constraints of g-code with stepwise approximation, but really the XY movement should have non linear acceleration to match a model of the extruder output. My firmware can do that but I haven't got round to setting it up yet. Each move command contains a table of steps delays. Currently they are calculated for short linear acceleration to allow faster movement, but they could be set to give a very slow start and finish.
Not sure if g-code can do that.
Nophead: Yes, I see the point of the non-linear start and end sections. But in practice it must be OK to approximate those with a number of linear steps with appropriate gradients, which again could be done with my scheme.
ReplyDeleteHowever, I now find myself getting defensive over something I thought was probably rubbish when I first thought of it :-)
"However, I now find myself getting defensive over something I thought was probably rubbish when I first thought of it :-)"
ReplyDeleteRotflmao! I'm glad I'm not the only one who paints themselves into corners like that.
I also think it's a good idea to have a distance in the gcode. The primary reason is that sending the feed as a distance rather than a speed means that the microprocessor does not have to do a time consuming square root calculation. The square root calculation would instead be done by the script on the computer before fabrication, so no root calculation time would be spent during extrusion and therefore there would be a smaller segment pause.
ReplyDeleteThe other reason, is that eventually we'll have a Stuart platform version. With a Stuart platform the distance between points is not the Pythagorean distance between actuator positions as in the Cartesian platform, and it would be way easier to evaluate the complicated expression for distance before fabrication, rather than on the microprocessor.
I suggest you might want to use D instead of W, because the parameter is distance rather than a fourth dimension.
For compatibility reasons, it would be best to have an option of which format to output. The option would not take much extra code, probably less than fifty lines.
Skeinforge varies the feed rate when building a raft and it adds steps with the appropriate gradients at the line ends, but in my opinion this is a separate issue than in what form the feed is sent. If we were using the distance parameter, skeinforge would output the same number of lines, just with a different feed format.
Regarding the format, I'd suggest zeroing the W coordinate between each move. If nothing else, it allows tools to cut and paste together G code, without having to worry from which place in the build it is. Much more modular than having a constantly incrementing number. It can also be stored in a smaller space byte-wise.
ReplyDeleteAnother idea, might not be practical, but negative W coordinates could be used to backtrack the extruder, e.g. when ending a layer, to prevent some ooze.
Does it make sense to add other parameters? E.g. speed (= a time parameter specifying how long the movement should take), temperature, etc?
A year or two ago, I suggested using cubic spline equations rather than linear line segments as the basis for controlling the extruder and/or 3D axies.
ReplyDeleteWhether this is a good idea or bad, I've put the equations needed to compute the spline path using only integer arithmetic on my blog:
http://beaglefury.blogspot.com/2009/01/spline-path-computation-using-integer.html
In principle the idea looks like a good one.
ReplyDeleteCan I suggest that the 4th dimension not be distance but feed in flow rate. This being constant for the move. In say mm per second.
Differing flow rates within a sequence can then be coded as separate moves. ie start, body, end instead of ramps etc becomes three moves.
On flow rates and distance I would guess that at the current speeds we are printing at we are getting away with fairly simple calculations because the speed is relatively slow compared to the rate of control.
As the whole machine though is refined and speeded up, the approximations we are using will become more critical and introduce distortion. The question I guess is how much.
On flow rates and movement, I agree with the idea of a negative flow rate indicating a reversal of the filament feed.
Finally, sorry guys, I agree that a method to track filament feed in accurately is needed if going down this route. Either using a non driven pinch wheel and encoder. Or probably much better what about revisiting the idea of using an optical mouse pick-up reading off of the filament directly.
Overall Adrian I think an excellent idea. The devil is as ever in the detail.
I think that having movement synchronised extrusion rate is an excellent idea.
ReplyDeleteFundamentally, we want the right filament volume:distance ratio regardless of the speed of the head.
The rest is just a matter of implementation details. :-)
Let's get the abstraction layers right and the rest will follow more easily. I like to look at G code as a set of instructions: it says what path a controlled point should follow. The G code view abstracts away the details of how to get a physical machine to follow that path, and those details are down to the motion planner and machine controller.
I suggest that, as much as possible, we say what we want in the G code and leave the rest to the interpreter/planner/controller. That decouples the path generator (SkeinForge etc.) from the details of the machine.
This frees the machine designer to make whatever compromises they want to regarding complexity, feedback, compensation, mechanical power, stiffness, etc that they want to without reference to the path generation software.
That means that, if I have (say) a very springy extruder head and you have a very stiff one, then we can still run the same G-codes to get (in theory) the same object.
We need motion in all relevant axies to be synchronised to an acceptable degree. We already have XYZ in sync, and since spatial movments are slow and near constant we currently get filament feed approximately synchronised for free if we just feed the filament at a constant rate.
As we run at progressively higher head and filament feed rates our machines will run further form constant speed because of cornering acceleration, etc. As the head speed (as opposed to specified feed rate) becomes more variable, it will become more important to have a mechanism to keep the filament feed in sync (including limiting the acceleration and top speed of the position axies, if necessary).
If we can generalise whatever mechanisms we have for synchronising X, Y, and Z (despite inertia, flex, slop, etc. in the machine) to include the filament feed too, then that would be a big win.
I plan on building an EMC2 CNC router table based RepStap. This offers two easy(ish) ways to do filament feed synchronised movement:
- Put the filament feed rate on the spindle as it is with nophead's setup. Use G33 Xx Yy Zz Kk, where k is the distance to feed the head per unit of filament ('spindle') motion.
- Put the filament feed on a notionally infinte rotary axis, A, B, or C. Use G1 Xx Yy Zx Cc, with c for the filament feed amount in ml, starting at 0 and increasing without limit (never resetting).
This is my preferred solution because it is general: all the usual G codes are avalible and sync comes "for free".
Either scheme allows me to hijack the EMC synchronised axis motion logic as is, and should be applicable to other setups too.
If my setup needs compensation for melt compression etc, I'll treat it like a motor moving a low stiffnes high inertia axis, and put the compensation in the HAL (a modular part of the interpreter/controller).
I think i'm late to the party, but along these lines, I've been planning on implementing my extruder as a rotary axis.
ReplyDeleteIn my case, the extruder is the "A" axis. I compute the distance to extrude while spitting out the gcode-- this allows the machien controler to match flow to linear motion as the machine ramps up the profiles on the linear axes.
to handle the non-linear portion, i'm planning for my extruder to compensate for meltflow. In essense, my extruder responds to a step-dir interface, and the machine controler ( EMC) commands it to move the correct distance.
the extruder itself ( pic based ) uses melt-flow compensation to adjust what speed to move.
to avoid running out of axis space, i use incremental coordinate mode.
I would have to agree with "Leo Dearden" in that the abstraction layers should be our guide on this issue.
ReplyDeleteCould we somehow directly sense the width of the extruded plastic?
ReplyDeletePerhaps using aka47 idea of optically measuring the filament.
Then the microcontroller could compare that width to the commanded G code "width" coordinate, and make appropriate adjustments:
if it's too fat, slow down the extruder motor -- and because there is a delay before that takes effect, also immediately stretch the extruded filament out by speeding up the X and Y speeds.