Gcode interpreter


Yes, I am a bit afraaid that term is not really correct, In industrial planning Takt is also used in english, but presumably in electronics its not …
So clock-line would have been more correct, but also lacks part of the meaning here, actually it is more an additional time reference but neither for the operation of the processor nor for the serial line (although in theory maybe one of those could be mis-used for this purpose).

As I said I would assume a good frequency for normal operation would be around or below 1kHz.[quote=“dlang, post:19, topic:83”]
I’m not worried about the need for something to break things down into chunks that take the same amount of time on all axis. This is a very similar problem to how to draw curves. Every CNC machine I know already has to break any curve down into a series of straight line segments. It’s either done at the CAM stage and shows up in the g-code as a ton of tiny line segments, or if the g-code uses G2/G3, it’s done in the g-code interpreter. In either case, it’s not a problem unless you have pauses between steps.

You are right with this statement. The reasons I would try to avoid this are the following, first (and more obvious) the number of commands to be issued will be drastically increased, especially if you are going to implement higher order acceleration schemes (which I find an appealing concept, although their proof of use is neither given nor declined for me yet) but more severe I think it makes sense to have the transformation from the arc to line segments on the lowest possible level to preserve as much accuracy as possible. For controllers unable to do this, it could be done at the master but e.g. on the ODrive it should be done there, because I assume the controller knows the best how accurate it could follow.

On this point I may have been a bit imprecise again, you are totally right, that the actual planning cannot be at two different levels and it should be at the highest possible. Actually I am lacking a bit of experience on how effectively this could be achieved even with only a serial interface without the mentioned external time reference. The idea of the look ahead on controller side (you can also call it a buffer) is more focused on the layout of the position or speed regulator and allowing it to compensate on errors differently depending on the future conditions (Probably this is not really working with a one layer standard PID scheme but could be more helpful when higher level or multi layer regulators are applied).

Actually some time ago I was following some discussions in the mechaduino forum, but didnt since a while, so maybe they did overcome these issues, but it was quite obvious that the PID tuning was extremely hard and from what I understood there were mainly two issues causing it:

  1. The used AMS encoder seems to be quite high latency at least depending on the output mode choosen (this is only my impression, so i never tested or compared those, although they are very promising looking at the specs)

  2. The change of nominal position with Step-dir input. As especially the I-term evolves over time and is quite helpful for long term stable positioning, it is often reset when nominals are changing as part of the anti-windup strategy. if a known rate of change for the nominal exists, the strategy would change on this point allowing for more effective regulation and use of all terms, however with step/dir you can only derive the rate of change from the past which may be completely wrong.


I also agree on this :wink: Its a good technical discussion and I am very glad to go into the details of it, it also helps to refine the ideas bringing it from thoughts to words :slight_smile:


well, remember that perfect is the enemy of good enough.

I’d rather start wit a conceptually simpler system, even if it has performance issues, and then optimize from there than try to design a system that provides the best possible performance and becomes too complicated to build reliably.

or another way to put it, "premature optimization is the root of all evil’


Realistically, we have three common cases here.

  1. odrive running solo that wants to consume g-code.

  2. odrive running as the master, with something else as the slave (could be odrive, could be other)

  3. external controller managing one or more odrive and/or one or more other boards

(plus the case where we don’t care about g-code, but in that case, something issues native commands directly)

I’m thinking that it makes sense to distill this into two categories.

A. the odrive is a slave of another system and is fed line segments to execute

In this case, it needs to understand a command set (ideally one common with other boards) to set the axis speed, acceleration, and distance movements, including some synchronizing primitives.

B. the odrive is the master and controls axis on itself, and possibly dispatching some axis movements to another board.

In this case, running something like grbl on it and internally calling the axis movement with the possibility of sending axis movements to other boards (with sync) would work

I haven’t spotted the documentation on the existing serial protocol that the odrive implements, but if it was possible to use the same commands as the pthat, it would make it easier to justify adding a driver to send commands in the serial format to upstream projects like grbl and linuxcnc (anything that supports multiple projects is going to be more readily accepted than something that only supports one board)

does this sound reasonable to the odrive folks?


Actually after reading Oskars latest mail on the log, I was curious by the profile pic of the guy with the Ananas Stepper board, and on the discussion on his side Oskar referred to the CanOpen CiA 402 protocol.

I just did a quick browse on it but it seems to be a standardised serial control protocol (I came across that term sometime before at commercial servos, but only thought it was referring to the transmission protocol not the actual command set).

So before fully got the details, I have a gut feeling that this could be the right thing and for sure any existing standard is preferred over something new.


Hey guys thanks for the very interesting discussion!

On replacing step/dir:
I completely agree that step/dir is garbage and needs to be replaced yesterday. Still, I need to support it for connecting to legacy motion controllers.

There are many ways the ODrives could speak to the outside world and to each other, but indeed I have been keeping my eye on CiA 402, as I know that is what’s used in industrial servo drives. Hence, many software stacks meant to interface with industrial servo drives speak it, such as ROS.

For reference, the intoductory paragraph of chapeter titled interpolated position mode on page 105 of the CiA 402 spec reads:
“The interpolated position mode is used to control multiple coordinated axles or a single axle with the
need for time-interpolation of set-point data. The interpolated position mode normally uses time
synchronization mechanisms like the sync object defined in /3/ for a time coordination of the related
drive units”.

Further the spec says you must implement linear interpolation of position over time. However, they allow for manufacturer specific modes, which is good if we want to have higher order planning.

They also specify a standard mechanism for how to check for tracking error (i.e. ability to keep up), and how to signal them and what should be done when one occurs.
By the way @Giornoxx, it is not standard to slow down or take any sort of intermediary recovery action at the master: suppose you are decellerating, and one of your axes goes into torque limit, what do you do? You can’t slow down, that makes it worse. Changing the trajectory plan to mitigate is too complicated for most applications. Usually the approach taken is to plan the trajectory with sufficient margin that a limiting condition should “never” occur, and any small deviation/error is servo’d by the individual axis.

On G-Code interpreter on ODrive
Conceptually we have in a robotics/motion system (both using ODrive only, or otherwise): High level motion commands -> motion planner -> motion controller -> motion primitives -> motion execution.
While there are many other options too, for the purposes of this discussion, the high level motion commands could be original (not split into 1000 lines) G-Code, and the motion primitives could be CiA 402 “interpolation points”, or step/dir signals from an existing controller.

As both @dlang and @wetmelon mentioned, it is unclear if the ODrive is trying to be just a servo drive or both the motion controller and a servo drive, and if so, how much effort will be spent on the motion controller and planning part. I am intentionally leaving this unspecified.
I will put in place a simple cubic trajectories planner and motion controller, and something that can read just the G1 command. The main reason to do just that is because it is required for very simple point-to-point movements for standalone applications and demos.
Beyond that, I think we can use the step/dir interface (for now) to interface to existing motion controllers, and get working systems up and running quickly. We can in the mean while spend our time with making the servo drive part of the project really good. Stuff like automatic tuning, ease of use, etc.
Then we can come back to this topic once machines are running.

That said, if there is any of you who are really interested in starting to work on any of the following this early anyway, let me know, and I can provide any direction you may need.

  • Porting any G-Code interpreter
  • Runnnig an interpreter on the host, and converting to other primitives, to be sent over USB
  • Motion planning, in general
  • Implementing/porting CiA 402

Thanks again for the well thought out and civil discussion. This is how I always hoped the forum would be like ;D


complying with any spec is good, I was just picking one I ran across that seemed well defined. If there’s an actual industry spec that’s available to be implemented (no fees for access to the spec or licensing costs to implement it), that’s even better.

Thanks for the pointer.


by the way, do you know of any opensource code that implement CiA402?


I started gathering the relevant portions of code together to get an overview and try to dig into it, however I won’t make any promises at the moment (with respect to my coding skills and available time).
But my personal goal is to get to manage the connection of an existing firmware with Odrive without step/dir im willing to contribute somehow. In the end it should be attached to the duet boards, but I’ll start with plain grbl as it’s probably easier to understand the system working and set up some demo stuff.

Ok, let’s say the basic idea was to allow for more options for the closed loop control based on the trajectory. Additionally I could imagine that for some as fast as possible moves out could be good to let the master know let’s say if 80% of achievable torque are reached (but for sure it’s no current issue and any reaction to such information should be handled thoughtful and based on validated strategies and scenarios) :smirk:
Which also implies its probably not a standard scheme …


I think adding the motion control is too much to ask of the Odrive because besides controlling the motors you need more IO to do anything. My vote is to make the drive do what it is designed for really well. To add the motion control will add a lot of complexity and will never be able to handle all the IO needed for even just a mill. for a mill you would need 2 Odrives and at least 3 endstops and that is bare minimum.


Well, first off, here’s hoping that a later version uses a larger chip with more motor controls :slight_smile:

but even this limited version could be used for a laser cutter (2D + PWM signal for the laser), which is what I have in mind.

but the real issue is the I/O rate, doing step/direction pulses has a very low limit in how fast you can give direction to the odrive, so there needs to be some higher-level protocol in play (including the ability to sync
movements across multiple boards)


4 posts were merged into an existing topic: Step / Direction


Hi everyone, resurrecting this old thread to let you know that thanks to @Hello1024, we now have the G-Code parsing and motion planning features of GRBL stripped out and half-integrated into ODrive firmware here: ODrive PR 47.
Like it says in the PR, this hasn’t been tested on hardware, and is more of a proof of concept than a finished feature. Nevertheless, if someone want’s to work on finishing this off, you are more than welcome!
Let me know, and I can coordinate.