This is part of my series of material that I edited out from my books prior to publishing. I usually cut whole sections like this when I realize they’re redundant or don’t fit well in the context. This is copy/pasted directly from my draft files with no additional editing, just for fun.
Note: a “velocity jump” is what many 3D printer firmwares refer to as a “jerk,” an instantaneous change in commanded velocity or direction of motion.
I wrote this a few weeks ago for a section in Volume 3: Stepper Motors, and then decided I didn’t want to get into this much depth in that chapter.
At complete starts/stops for each motor, such as a 90 degree turn from X motion to Y motion, it is fairly simple to apply a velocity jump limit such as 20 mm/sec. Approaching the corner, the X motor would decelerate smoothly to 20 mm/sec and then jump to 0 mm/sec entering the corner. Likewise, exiting the corner the Y motor would jump from 0 to 20 mm/sec, then accelerate smoothly up to the target feedrate. This is simple to implement and there isn’t much room to argue about the desired behavior.
However, things are less clear in more complex motion cases:
- During a full direction reversal, should the motor jump from 20 to 0 entering the corner and then immediately jump from 0 to -20 exiting the corner? That would be a total jump of 40, not 20. [ILLUSTRATE THIS]
- Consider a 90 degree turn from a 45 degree heading (+X+Y) to a 135 degree heading (-X+Y). In that case, the Y axis has the same speed before and after the turn, while the X axis must reverse direction. The axes have to stay synchronized, so all motors must slow down to accommodate the one experiencing the most severe jump. [ILLUSTRATE THIS]
- What about a 10 degree turn from 30 degrees (+X+Y) to 40 degrees (also +X+Y), where both X and Y keep moving in the same direction, but at different speeds than before? [ILLUSTRATE THIS]
- If a ramp phase spans multiple motion segments, is it permissible to jump between each segment? [ILLUSTRATE THIS]
More questions arise for how the firmware should take into account the hardware arrangement of the specific machine architecture in use. There are differences between motors/joints and coordinate axes in many types of printers, and the firmware developers must decide how to approach this. For example:
- In Mendel / Prusa i3 style printers where the X and Y axes use independent mechanisms, should velocity jump be controlled separately for each motor/axis, or should it be controlled as a change in the tool’s velocity vector in XY space?
- Should CoreXY printers where the motors’ “joint” travel is not aligned with the coordinate axes, should firmware look at tool velocity vectors, or U and V joints, or X and Y axes?
- Should Deltas look at tool XY motions, column joint motions, or both?
- Do extruders or other synchronized tools require their own velocity jump and acceleration limits?
Reasonable people can differ on the proper way to handle these cases. Making matters worse, it may be quite computationally-intensive to calculate appropriate corner speed limits for all motors/axes, identify accel/decel/coast periods, and then iterate through a buffer queue to ensure consecutive corner limits and desired ramps don’t conflict, while also toggling output pins at a high frequency to run the motors — all within the tiny length of time between reading a gcode command and executing it. This may or may not seem difficult to the casual reader, but real-time synchronized motor control is a considerable engineering challenge.
GRBL mill firmware provided the first popular open-source solution to these problems that could run on low-cost microprocessors. It succeeded in large part by reducing the math and physics down to a minimum viable algorithm for light-duty CNC motion. That involved many shortcuts and simplifying assumptions, such as neglecting radial acceleration through arcs.
A large family of 3D printer firmwares such as Sprinter, Marlin, Sailfish, and Repetier subsequently adapted GRBL’s core motion control algorithms.