G00/G01, speed/acceleration/(not) jerk, and Marlin/grbl

I’ve been doing some investigating, using a grbl setup on my desk. I’ve found some things that have been a little confusing, but I think I’ve got to the bottom of it all, and I wanted to share what I’ve found. This is mostly from the viewpoint of CNC milling, not 3D printing.

Background information:

  • G00 is a "rapid" movement command, G01 is the "linear move" command. Linear in this sense is like a line, as in not the arc commands.
  • G00 is "meant" to be repositioning the bit somewhere, to do more cutting later. G01 is meant to be a cut in a line. (((I don't like to say what is "meant", but grbl acts this way, and Marlin was originally based on grbl, so I'm going with that)))
  • The configuration for grbl and marlin have a max "speed", "acceleration" defined for x, y, and z.
  • Marlin also has a "jerk", but it is not the derivative of the acceleraion, more on that later.
  • There is also a "Feedrate" that can be set with each movement command. This is the F#, like F15 on a G01 command.

Some example G code for moving around:

Move to 100,100,0:
G00 X100 Y100 Z0
Move to 0,0,0 with feedrate set to 100:
G01 X0 Y0 Z0 F100
Set the feedrate to 1500:
G01 1500</blockquote>

* (Marlin uses the term MAX_FEEDRATE, but I think that’s confusing, so I’m always calling it “max speed” in this writeup. grbl calls it "max rate

For both grbl and Marlin:

  • 1) The max speed and acceleration for each axis should be set to reasonable defaults so that you don't skip steps without doing any cutting. That will mean that when your gcode is driving around from part to part, without cutting, it won't be skipping steps. Be aware of units, because they are different in grbl and marlin.
  • The feedrate determines how fast you are moving along a line. So if you are moving from 0,0,0 to 100,100,0, with a feedrate of 100mm/s, it will take 1.42 seconds to cover the 142mm along the line of travel.
  • 3) The speed the machine will actually go is limited by:
    • a) No single axis can go faster than it's max speed.
    • b) No single axis can accelerate faster than it's max acceleration.
    • c) The combined speed has to be less than the feed rate.
    Otherwise, it goes as fast as possible. So if you have speed rates set to 100,100,10 (for x,y,z in mm/s) and you ask for G01 X100 Y100 Z0 move with a feedrate of 120 mm/s starting at 0,0,0, then the tool will start slow, accelerating at your max acceleration values, then reach 120mm/s along the line, but not exceeed 100mm/s in x or y.
<li>The feedrate is remembered for any G01 commands. If you have a G01 ... F100 command followed by a G01 ..., then the second command will still be limited to the F100 speed.</li>
<li>The commands are taken as movement along a line, so even if you have dramatically different speed limits, the path that is taken will always be along the line. For example, if you move to X10 Y10 Z10, the z speed is a lot slower, so the controller will slow down the X and Y movement to stay on the line. It wouldn't make sense for the controller to finish the X,Y movements really quickly, and then do the Z movement.</li>
<li>Since the feedrate is along the cutline, and not along any specific axis, it is not a good limit on the z axis. I think this will really have an effect on toolpaths that are doing 2.5D cutting. If the feedrate is 15mm/s, it could possibly dive into or out of the material close to 15mm/s, which is probably not a good thing for the z axis. This will eventually be clipped by the max z speed, but that still might be too high when also doing a cut. Maybe the CAM software is smart enough to figure that out and ask for a lower feedrate, I don't know.</li>

For grbl:

  • G00 ignores the stored feedrate, and will move at the limits for each axis. It is assuming you aren't cutting, and you're just making a rapid movement.
  • G00 doesn't clear out the feedrate, so the next G01 command will use the feedrate from the previous command.
  • If you set a feedrate on a G00 command, it will be stored, and ignored for this move. So G00 F100 G01 ... will have the feedrate set to 100.
  • G00 still honors the speed and acceleration limits you set on each dimension.

For Marlin:

  • Marlin treats every G00 command as a G01 command. This caused a few goofy behaviors for me: After a slow cut, the bit would move very slowly to the next part. This is because the CAM program I used did something like this:
    G01 X.. Y.. Fslow
    G00 X.. Y..

    The G00 was interpreted as a G01, which had the previous feedrate set. Switching your CAM software to use G01 instead of G00 won’t help. One possible solution is to add a G01 F<some fast number> to the end of each part. Then the movement between parts will be limited by the firmware again.

  • The “Jerk” setting isn’t what I thought it was. I assumed it was the derivative of the acceleration, like the speed of acceleration. It actually is a step that won’t be limited by acceleration. So if the jerk is set to 4, then the speed can go from 0 to 4 instantaneously, and then follow a smooth acceleration after that. If you are trying to limit acceleration, it’s important to set this to something really small. (As a side note, Marlin’s movement code is based on grbl, but I can’t find this setting anywhere in grbl. Maybe they ditched it, or are trying to determine it themselves somehow).

How do I use this information?

  • Set your firmware speed to keep from skipping steps. This is the most important. The feedrate in the CAM software isn't a good limit, because it's not being enforced when:
    • You are jogging around using the screen.
    • You are using G00 with a grbl controller. This may not seem like it affects you, but a lot of CAM is written for grbl like controllers, not 3D printers.
    • Your firmware acceleration settings might need to change on which tool you use.
      • If you are using a heavy tool, then the force needed to stop at a higher acceleration might be enough for a skip. I don't have a good idea yet of what kind of accelerations can cause step skipping problems.
      • A lighter tool might be able to go faster. If you don't want to deal with that, then make it lower.
      • A tool like the laser depends on the amount of time you are spending at a certain spot... Lower acceleration values mean that the laser might be spending more time on an area than the gcode intended. I haven't spent much time looking at the laser stuff, maybe there's a clever way they fix that, but if not, setting the acceleration higher would minimize this issue.
    • When using marlin, add a feedrate command before any non-cutting movement commands. This will let the bit move as fast as the firmware will allow, which still shouldn't skip steps. In EstlCAM, I think there's an area where you can define some gcode when a path is finished.

    What do you think? Is this explaining anything you’ve had questions about? Am I wrong about anything up there? Is there more useful info anyone can share?


I messed up all that formatting. I should never have tried to use the bullets :slight_smile: Oh well.

Looks great!

I think I absorbed all of that, and the stuff I knew looks correct. Thank you! I am sure that will help some people.

I wish marlin used the g00 and g01. I never checked but I wonder if it can be turned back on in the firmware. Any idea if there is something that is easier to use than the arduino IDE to browse large programs?

There are a lot of good IDEs. You can really start a war by asking that question. The Atom editor is a good one: https://atom.io/

That is awesome I actually had no idea. I have only ever seen arduino and notepad++, and notepad. I sense a rabbit hole about to happen.

In school we had to program in a text editor, all the test were by hand with a pencil. In c++, mostly just complex iterative equation solvers.

I use vim, but I use it all day, so the efficiency is worth the steep learning curve. So if you see a bunch of jjjjjkkkkkywjjjPkkkD in one of my posts, that’s why.

This editor is based on atom, but integrates with platform.io, which can compile and upload for arduino (and esp8266): http://platformio.org/platformio-ide

Hehehe, at least you are not using emacs… :slight_smile:

Sorry to dig up this post from 3 years ago but did you ever investigate this?
I just came across this in the marlin Configuration_adv.h . This led me to search for that.

I’ve dismantled my mpcnc for repairs so I can’t really test it out at the moment.

I just realized that you can search code on github but you can’t search forked projects.

1 Like

Jamie wrote a PR to make G0 work, if you enable it. It at least doesn’t affect the G1 F speed.

What? :thinking: Hmm I don’t think so. I have a few, not even that many, and that isn’t one of them.

That’s right, it was @thesfreader, Sorry!

Since this thread has already been resurrected and I was just reading the v1 Engineering Doc on the subject thought it worth for future readers to mention the presence of:

//#define G0_FEEDRATE 3000 // (mm/m)
#ifdef G0_FEEDRATE
    //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode


If you define G0_FEEDRATE , then that will always get used for G0 commands (and still be subject to the max speeds and accelerations).

If you define that and VARIABLE_G0_FEEDRATE , then any feedrate defined on a G0 command will stick and any future G0 commands will use that speed (unless they define their own).

One useful configuration might be to set your max speeds and accelerations to something that will never skip (in air) and then set the G0_FEEDRATE to something high. All travel moves will be as fast as possible after that.

(Which I assume you found @jeffeb3 after the original above investigations!)

It would be great if these parameter/code make it into the nightly builds (at least for 32 bit boards if there is a space issue). Then once proven to be good and it makes it to a release version then maybe the milling or firmware page or subpage can detail some of these specifics so the “features” of the firmware don’t requiring going into the flags or MarlinBuilder to discover/validate.

The way for new features like this to make it into the marlinbuilder would be with an issue there, and a pull request. I think that we will drag our feet more on new features first, preferring changes that make things more robust.

This particular feature does have a down side, which is that it will be a bit of a surprise to someone who is familiar with Marlin for 3D printing.

If this is set to 3000, and VARIABLE is off, what happens when the gcode explicitly sets the feedrate on a G0?

Most user are currently explicitly setting the Feedrate on every line of the GCode. Anyone continuing that practice will not see a change as long as VARIABLE_G0_FEEDRATE is also enabled in the firmware.

The only time a user may be surprised is if they are currently setting Feedrate on a G0 and not on a cutting operation. This is likely a tiny fraction of people, or an error, as this would mean that they are setting their G0 Feedrates to be slow enough so that they can be used for Cutting operations.

Setting the following in the firmware:

#define G0_FEEDRATE 3000 // (mm/m)
#ifdef G0_FEEDRATE
    #define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode

means the following:

  • If Feedrates are specified on every line, like most Marlin users do, then there will be no change in what most users see
  • That Cut operations:
    – with a Feedrate will set the default Feedrate for following cut operations
    – without a Feedrate will use the default set by an earlier cut operations
  • That G0s:
    – with a Feedrate will set the default Feedrate for following G0s
    – without a Feedrate will use 3000 mm/min unless there was an earlier G0 with a Feedrate
  • That placing a single G0 F<speed> at the top of the GCode will set a new G0 default if 3000 mm/min is too fast
  • That issues associated with transmitting GCode will improve as there will be less code sent as a majority of the F<speed>s can be eliminated

I did a quick review of Marlin-bugfix as the impact of these defines looks localizes and a pretty simple implementation.

How do others feel about this being in the standard firmware?

I am going to give it a try and feedback if any problem

1 Like

Love to hear feedback also if all good.

1 Like

As promissed feedback following a play with this:

Current settings in firmware as follows:

#define G0_FEEDRATE 3000 // (mm/m)
#ifdef G0_FEEDRATE
    #define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode
  • Travelling when sending manual G0 via terminal are great (nice a fast)
  • When using jog function in my weapon of choice (Octoprint); appears Octoprint is hard coded to send the feedrate with G0 which over rides the speed (cant find anywhere to change this)…if I am brave enough to override #define VARIABLE_G0_FEEDRATE then this should over come this problem but at the risk of some funky cutting speeds if there are any accidently G0 instructions slipped into my machining programs