Time as the Fundamental Variable in CNC (More Philosophy than Tech)

TinyG Executing Gcode

I’ve been working on the C code for TinyG for 2 years now and I still feel like a rank newbie. The more I get into the domain the more I find that I just don’t know. This weekend I was refactoring a part of the planner to get rid of a bug in some complex feedhold cases. As I got into it further I realized more of the implications that the fundamental variables in CNC (Gcode) are really just time and position.  This is obvious if you look at the math for the motion equations – the base equation is V = dr/dt  — velocity is the derivative of position (r) over time (t), and further derivatives on down to acceleration, jerk, (then snap, crackle and pop! Really. I’m not making this up.)

What was not obvious is how this manifests itself in Gcode and in the underlying motor controller code. First off, Gcode is typically stated as position and velocity, aka feed rate. So G1 F500 X100 Y100 Z-5 moves X, Y and Z from some starting position, say (0,0,0), to (100,100,-5) at a velocity of 500 mm per minute (or perhaps inches per minute, depending). This is the most common way to generate gcode.

But this gets really complicated when you add rotary axes. What exactly does G1 F500 X100 Y100 Z-5 A3600 B1800 mean? Kramer says what that is in the Gcode “Gold Source” specification (NIST RS274/NGCv3, section on Feed Rate. You can read more about that here if you want: Gcode Language Support – Feed Rates and Traverse Rates, but in short, feed rate is a complicated mashup of linear and rotary motion that somehow gets all the axes in the move to the right end point at the right time.

So it’s really just position and time, when it’s all said and done. My *real* machinist friends tell me that this is why machine generated Gcode for complicated machining centers is often produced using Inverse Time Mode – where the F word is interpreted as time, not as velocity. That way you con’t have to mess with these crazy transformations, you just tell the machine where to be, when.

I discovered a while ago that this has ramifications in the controller code. Basically, you want to ditch velocity as a variable as soon as you can, and do all your computation in time and position. These need to stay accurate or errors will creep into the work. Velocity, acceleration, jerk?   Not so much. Errors here are much more forgiving.

Another implication is that there is a quanta for time, or a Planck’s constant for the controller. It’s not 5.391 x 10(-44)th like in the real world, it’s the minimum interpolation interval that the firmware/hardware system can sustain. In EMC2 this is about 1 millisecond. In TinyG it’s closer to 2.5 milliseconds. This is the minimum update time that you can change the parameters for the motor drivers, or the update rate. If you go faster than this you won’t be able to compute the next update in time and the system will fail. Likewise there is a minimum quanta for position, which is basically how far an axis moves for one step (or for one microstep if you don’t really care about the increased relative error that introduces – microsteps are not perfect).

So the whole system needs to be constructed around these limits.  Thinking about the problem this way opens up a bunch of new possibilities. Like easier ways of doing splining, or better ways of coordinating axes in parallel robots. Or how to coordinate many-axis machines working in the same space – think multiple adaptive exclusion regions all competing for access to the same endpoints or regions.


  • Good post!

    There is another minimum quantum that has to do with how fast the controller can process moves. If you make the move too short in terms of distance, and the time it takes the controller to actually process that bit of g-code is too large relative to the time it actually takes to move the distance, the codes will start stacking up on the controller.

    This is one reason a lot of controllers work a lot better if you run an arc fitting program that converts lots of tiny little line segments into arcs, assuming an arc can be found that approximates the shape of the curve the segments simulated closely enough.


    Bob Warfield

    Bob WarfieldApril 24, 2012
  • Very interesting post. I think you are right in concluding that the key variable is position.

    There are many similarities to putting a space craft in orbit. To get into to a particular point in an orbit you have to end up at a particular point in space with a particular velocity at a given time. So the top level controller is a guidance one where the velocity required to meet the end conditions is periodically updated. Given the velocity required, the inner loop commands the acceleration magnitude and direction to achieve that. So the path you fly is not unique but has a multitude of possibilities depending on things like maximum acceleration.

    Does TinyG take into account both a final velocity and position for each quantum? Or a good velocity to use as initial conditions for the next step.

    Bruce Gable

    Bruce GableJune 4, 2012
  • Thanks for the comments, both of you.

    @Bruce: TinyG does take final velocity and position into account for each move – a move being defined as one to three discrete regions; an acceleration head, a cruise body, and a deceleration tail (many moves have only 2 or one of these regions). Acceleration/deceleration is performed by computing a 3rd order, constant jerk S-curve as a series of constant velocity, piecewise linear interpolation segments (as opposed to a constant acceleration curve which is more common).

    The final velocity for all terminal moves is zero. When a new move is added to the planner the previous “final” move velocity is recomputed and is typically non-zero. The velocity at the join point (aka way point or splice) is the minimum of the max velocity for the move, the velocity that would be required for the remainder of the chain to decelerate to zero (the braking velocity), or the velocity needed to stay within the centripetal acceleration limit of the join if the junction is not a straight line. This gets interesting when the junction has components of multiple axes (can be up to 6), each must be kept within their cornering acceleration limit. A vector sum is computed for the cornering acceleration and applied.

    The interpolation segments that implement the S curve are piecewise-linear constant velocity segments on the order of 2.5 ms each, so they don’t change velocity. I’d like to get that timing down, but that’s all I can do on the 32Mhz processor on TinyG. A port to a faster CPU/MCU is in the cards.

    @Bob: The backup doesn’t seem to occur in the gcode interpretation, but when the planner fills up and then the serial input buffer starts to back up. The firmware issues an XOFF when this happens, then issues an XON when the serial buffer empties sufficiently. The upstream controller can also sync on character responses, and there is a JSON object/model exchange implemented to make it more machine readable.

    The arcs are indeed broken up into tiny little segments, but this happens on the chip a part of the G2/G3 canonical machining function. The chip is fast enough to handle it. These segments are fed to the planner as short little lines that are in turn applied to the accel/decel methods described above.

    Thanks for your interest.


    AldenJune 4, 2012
  • Somewhat off topic question: With the complexity of the software you outlined above, is it safe to assume that is why the TinyG is considered alpha/pre-release?

    In other words, is the hardware generally stable? Is it a safe bet to order the hardware now (and buy the right AVR programmer)?

    GregJune 20, 2012
  • I actually think the current functionality is pretty stable at this point. It’s probably time to move it from alpha/pre-release to general release. It has now been shaken down in this form for about 6 months with very few issues. Those issues that were encountered were addressed, as you can see on the github (synthetos/tinyg).

    You will need the right AVR programmer (we use the AVRISP mkII) as I have not been happy with the boot loader chain we came up with. The boot loader itself is fine (Xboot) but we had enough issues with the AVRdude host to not want to wish that on others (and ultimately ourselves in support).

    AldenJune 20, 2012
  • Fascinating Alden, as a cnc ‘noob’ the simplicity of your explanation of cnc as a function of time and position is most refreshing – somehow my intuition tells me you grossly understate your understanding and masterful command this stuff.

    When I first read this some months back, it was from the daunting world of knowing nothing about cnc, now knowing little seems more comfortable than before though certainly not akin to anything like really comfortable.

    Somewhat surprisingly though, with only my recent elevation to miniscule understanding, your words found new meaning, bringing clarity to the main purpose of the cnc tool – to be at the right place at the right time to achieve a desired outcome. “…you just tell the machine where to be, when.” defines your notion beautifully.

    It is not often an expert stands up tall from their task and has a good look around at the proceedings, the odd foray into divergent thinking, particularly in an area where adept convergent thinking is essential for an electronics maestro such as yourself. You write of a wonderful effective moment, to bring all those future efficient moments in line with a more meaningful outcome.

    There is much for other disciplines to learn from what you present here, not the cnc time/position bit, though that’s certainly very wise an valuable in itself – the really broad spectrum value is to be found in your willingness to re explore the very foundations of of what you do – in the hope of finding an event horizon to a more meaningful and rich future.

    My very best you. 😀

    Max Metz (aka Fill)August 3, 2012
  • Thanks for your very kind words. There is always so much more to learn, as I’m reminded every time I talk with people who have been working these issues for years.

    aldenAugust 3, 2012
Comments Are Closed