Gcode interpreter

so now that these are shipping (I received mine yesterday), the question comes up as to how to go from g-code to controlling these motors.

the examples I’ve seen show control via USB, but not with g-code, but with other commands. There are comments about a direction/step interface, but that seems like a very inefficient way to do things (and would require a pretty beefy processor feeding the odrive board the steps)

I assume that you are not intending to roll your own g-code interpreter (lots of work to re-invent that wheel :slight_smile: ), so what do you suggest?

1 Like

Currently the control via the simple interface seen in the video is what’s ready. This is only really meant for testing.
Planned is to support at the very least the G1 command of G-Code: we can put this in with a very simple scanf. But we may want to support more commands, and in that case porting over an existing interpreter may be useful.
Which other commands may be useful?

I was afraid that it would be something like this. Going this route opens you up to an endless wack-a-mole process and compatibility questions with g-code generation software. you need absolute and relative modes, metric and imperial, straight lines and arcs, tool change (even if only to pause), spindle on-off, feed rate.

G0, G1, G2, G3, G10, G20, G21, G38, G90, G91 T, M3, M5, F

Plus the need to move each axis individually (both a given distance, and at a given speed/power level)

I’m working with the maslow folks on their CNC (maslowcnc.com) and the g-code support there causes almost as much grief as handling the special mechanics of the system. The list above is the minimum we’ve found needed there so far.

I would suggest that you take a close look at grbl https://github.com/gnea/grbl/wiki (GPLv3+) It’s widely used so it’s well supported as a target, and has a sophisticated acceleration and speed planning system (that can take into account the angle between line segments to figure out how fast you can be going at the end of the one line segment to transition to the next one). With the high speeds that the odrive will be able to produce, this will be extremely important. They support traditional cartesian machines and corexy layouts (which I suspect will be common for odrive systems)

grbl is optimized for the atmega found in the arduino family (8 bit 16MHz) and the planning is separate from the driving of the motors, so it should scale well to a faster cpu. All the motor movement is done in the stepper.c file, most of it in a single interrupt routine, so you should be able to replace that portion with what’s needed to drive your existing routines.

We’ve definitely talked about grbl in general, discussing its interpreter and motion planning.

I think the best way to do an interpreter would be to support grbl/mach3/Haas/Fanuc/Reprap etc G/M-Codes. We’d probably have to implement a configuration file there. Since ODrive is both the front end AND the servo amplifier, and it will be used in many different applications, it might be smart to create a unification layer that accepts various interpreters based on a config flag.

well, the more the merrier.

If the o-drive stuff can be turned into a library that can trivially be called from withing grbl or the others, it will make using any of them much easier.

But there’s a really tight limit to the programming manpower of any project, so I think getting any one of them working well is the big thing.

I’m not familiar with all the different options, so I don’t know if they have the motion planning the way that grbl does, but given the power of these motors, I think it’s important that whatever option gets picked, it include motion planning (I’d be very interested in hearing on the capabilities of the other options you mention)

I’d also be very interested in learning about the ability to tie odrive in with linuxcnc, as that would open up a whole new level of capabilities.

it would probably be good to pick one of the ‘embedded’/limited g-code interpreters and port it to run on the odrive directly, and also make a full-blown system (is there really a competitor to linuxcnc? if so what?) and make that work as well (and this could be as much drivers in the large system as it is anything running on the odrive

doing some more digging, it looks like the grbl project has an arm port in the works at https://github.com/gnea/gnea

no code there today, but from the threads talking about it, people have a working arm port that should show up there very soon.

Connection ODrive with LinuxCNC probably is a simplest way to implement G-codes interpretation.
Adding G-code interpreter into ODrive is quite difficult job (for example in most cases 3 axis should be
synchronized while ODrive can control only two motors (in a difference from gShield).

I thought that multiple odrive boards could work together from the writeup.

I was thinking in terms of a laser cutter for my odrive board, 2 axis + ‘spindle speed’

https://github.com/gnea/grbl-LPC is a port that runs on the smoothie board (also arm based), this looks like it’s getting real updates, unlike the gena repo I posted a couple messages up.

Yes, a couple (or more) ODrives can work together, but G-code must be interpreted by single controller, so such interpreter must be separated from ODrive. ODrive replaces steppers or traditional servos, not a G-code interpreter.

I am thinking of a serial protocol to replace step/dir which requires many resources on both sides.
However this should allow for synchronized movements between different motion controllers, therefore it can’t be g code.
I am also not sure if something similar exists e.g. on commercial cnc or if it is more simple to rely on guaranteed reaction time on the controllers (and keep just parsing g code).

So what I was thinking of is a master controller/g code receiver with the motion planner that translates the g code into the speed/position profile per axis. These are send to all motion controllers (should be possible with a single bus line) these also should have a certain buffer for movements and also 0-motion should be stored.
Additionally to the serial line, there should be a Takt Line controlled by the master to allow also speed override and sync and the controllers should lag by some takts to allow for synced adaption to the takts speeds.
Also errors of low severity could be reported and handled by the serial interface from the controllers to the master (like speed/torque limit close or a certain tolerance can not be kept). However for serious faults the controllers can pull down that line hard to achieve a e-stop condition on all axes …

I personally think that also in hobby/diy setups they will be less huge monolithic controller boards like we see nowadays on the 3d printers (if you have a 5 axis board and want a 3rd extruder our a fancy multi motor bed leveling you have to replace the interpreter and heater control as well) but more modular set ups like with the odrive or maybe separated heater control boards close to the nozzle and I think step/dir is also causing problems on the controllers or at least eradicating the benefit of alook ahead and motion planning on the controller side.

hmm mailing list mode didn’t seem to accept my reply

the grbl code has a sophisticated planner that converts everything into small line segment moves, with

starting speed (F1)
time/distance to ramp up to speed (F2)
time/distance to run at speed F2
time/distance to ramp down to ending speed (F3)

where the ending speed of one line segment matches the starting speed of the next segment (taking acceleration limits and angle changes between the line segments into account)

The stepper driver then executes these line segments across all the axis.

It should be very possible to have the g-code interpreter dispatch one or more axis motions to a different board based on this sort of logic.

Commercial CNC machines typically have a PLC, a Motion Controller, and then inverters/amplifiers/drivers. Sometimes the PLC and Motion Controller are integrated into one package, sometimes not. The current capability of ODrive would put it into the “Servo Amplifier” category, where it can take a commanded position, velocity, and acceleration, and execute it. If ODrive is also capable of motion planning and synchronizing several axes with other ODrive boards, it would fall into the Motion Controller category.

For industrial use, doing one thing very well is good, and probably preferred. For hobby use though, most people expect a fully packaged, plug and play solution. They don’t want to have to chain together a half dozen boards and a separate power supply on a backplane… they just want to press “Print” or “make”.

I’ll leave it up to Oksar to decide the scope of the project :slight_smile:

Ok, thanks for that, I think this would be a good starting point and as many of the known firmwares are based on grbl and almost all use line segments (except g2core/tinyG) this should also allow an adaption. Anyhow a later implementation of higher level segments seems to be a good idea especially for beyond 3d printing applications​.

I agree that on the entry level people expect to have a plug and play solution.
However moving past that point this is not the case anymore I would guess.

On the one hand we’re taking not only about a singular application (3d printing e.g. where there is also a huge demand in numbers justifying a specialised highly sophisticated monolithic board with all in) but e.g. building robot arms win 3 to n axis and possibly different effectors.
On the other hand and this is different from the very recent past the number of options for motor control evolved. So for the last few years a new 3d printer control board only implemented a lot sophisticated stepper driver (higher microstepping, more current, direct current control …) But recently - and Odrive is only one of those, although it is the most promising from my point of view - there are different concepts arising with the aim to overcome the stepper limitations. Which is a sign that obviously either on the demand or on the opportunity side something has change. The point here is, that these modules will not be integrated into a big controller board any more. Therefore at the moment Step/dir is the only existing interface, but that keeps one of the most severe limitations of the stepper concept alive.

For sure i didn’t want to imply any duty on Oskar to implement such concept. The great thing is it is open source and anyone can add a further option. Only it would help to define a concept which many people think makes sense.

On the other hand Odrive is already and has to be both of your mentioned systems:
A 2 axis driver by itself can’t be a complete motion controller for more complex projects but for simple things it may work on its own and with step/dir it will already be a great servo controller.

I’ll point out that my original post wasn’t that odrive needed to be the gcode interpreter, but rather that it needed to be able to be controlled by one.

If LinuxCNC can be taught to send the appropriate commands to the odrive, then there is little need to have a g-code interpreter on the odrive itself

Another project that needs a similar interface is the pthat http://pthat.com/ It’s driving stepper motors, but has a text interface that’s not g-code and not step/direction. It would be nice if projects that are going in this direction could get together and agree on a protocol standard so that the interface doesn’t need to be re-invented for every board.

They have published a command set at http://pthat.com/index.php/command-set/ It’s a bit limiting in that they have it defined to support 4 axis, but it would not take a lot of effort to extend it to more (some thought would have to be put as to how to sync multiple boards)

Unfortunately, they have so far taken the attitude that they don’t want to be limited to g-code, so they don’t plan on trying to make their hardware supported by any CNC software :frowning:

I hope my comments didn’t sound to impolite.

For the moment I think the gcode is for most applications still the best and standard way to interface with machine control, so there is clearly the need to have some sort of gcode interface - my basic idea is also that for simple projects it could also run on the Odrive board itself, but taking your comment from the top into account it is true that this will introduce also some problems (especially where to draw the line of supported commands).

My first comment was just pointing to the problem that gcode is not a suitable standard to interface multiple boards synced, and therefore usually step/dir is used, but at a high price.

However looking at linuxcnc (as far as I got it) they seem to use step/dir in most of the cases (gecko drives seem to be interfaced in this way also e.g.) but therefore they often implement specific fpga boards as step drivers which looks a bit anachronistic with all these specialised 3d printer boards out nowadays (but step rates on CNCs are probably much higher when trying to achieve fast moves on spindled axes).

From the discussions at the Duetwifi forum David Crooker stated that driving 4 axes the duet board is able to put out ~100kHz step rate as a max (~300kHz if only one axis is moved), so having very fine movement steps this is a severe limit to the max speed (Normally on 32bit boards this is no real issue with a stepper setup, only if you decide to go for the actual 128 microsteps mode. However the dynamics for a decent BLDC servo should be much higher).

My question on the commercial CNCs was more related if there is a standardized protocol for this which could be used as a start, but so far I didn’t come across anything.

I assume every manufacturer implements something proprietary (there are some servos with RS485 interface, but i think they always use a specific command set) At work I have one machine which does actually have Step/dir to control a stepper axis but there it is nothing synchronized, all multi-axis machines have a kind of CNC control where to start a process you usually do a reset with the override at 0 and then ramp up to full speed, which was the starting point for my thought, if the poti controls the takt frequency it would initialize syncronized movements by the first takt and the motion segments imply a certain time reference to that takt line.

I didn’t plan to be suggesting anything when I initially posted, I just wanted to know what direction to go.

but when the idea of rolling a new g-code interpreter came up, I felt I needed to suggest better options.

I also suspect that the big CNC machines all have proprietary stuff inside, there’s not a one of them that allows any other controller to be used so compatibility with anything is a non-issue for them.

I don’t know what odrive had in mind to sync multiple boards to be able to do a coordinated move across boards, but I’d like to see it be something that could actually work with other boards (for example, use odrive for the big motors to move a gantry and then pthat to do Z axis, 4th axis, extruder or similar)

I think it’s fair to say that the thing that issues the commands should take into account the speed needed for each axis so that coordinated motion will still happen across boards. It’s just a matter of having a way to tell all boards to start at the same time.

the pthat command structure already supports defining coordinated moves within one board. We could extend that command set to include a ‘delayed start’ command

Define a GPIO on each board to be part of a bus that has a pull-up resister on it. Have every board (possibly including the master computer) pull the pin low under normal conditions.

Once they get a ‘delayed start’, they would switch from pulling the pin low to it being an input (possibly an interrupt). Once all boards stop pulling it low, the line will go high and all boards would start at the same time (and after a very short window, pull it low again)

the same command could be used in the middle of a sequence of commands to make sure that all the boards are in sync (modern clocks are pretty accurate, but we want to deal with what drift does happen)

Yes, that could work quite well for the start, it would be like having every command (or every n-th) synced by that pulse.

I also agree that this should not be focused on ODrive alone but an implementation should be simply made for different boards, so it will be key to easily implement at least the most basic layers.

I thought about something similar in the beginning, but I see two main disadvantages:

  • the reaction time and the look ahead on the motor controller is limited. In case the pulse is not at the expected point the controller has to issue an abrupt stop which should lead to jerk of the machine, as the “master” will not know this happened it will also not take the acceleration to get back to sync into consideration. With the takt line the servo controller can self correct a certain mismatch in position by a deviation from its expected position without a hard cut, also with the one or two takts ahead all controllers can adapt to upcoming changes (with a frequency not too low to make it recognizable by human eye, but still not too high to reduce effort on controllers side so few hundreds to 1kHz is whats on my mind, so a decent controller has plenty of time to react within two periods)

  • The “master” would have to segment all moves for all axes into identical lengths, even if motion on different axes have different scales (e.g. a sinusiodical machining will be done with one axes moving ahead with constant speed over a long run, wheras second axis is alternating all the way long. With a takt-line this is only a matter of the same time base which can be self controlled.

On the other hand I do agree with the concept of the master planner which has to have the information which axis has which capability,
I think the concept applied by LinuxCNC is quite good to have the configuration/scaling done at the lowest possible level, so the position commands could be in “natural” numbers and the servo controller does its own scaling (however the configuration could be distributed at startup from the main controller)

I also agree with the general Idea of different servo controllers for different purposes on the same machine. E.g. as I am building a coreXY printer, the main motion stage for XY is where I want to apply ODrive, but for slow Z-axis a different driver is required, where maybe additional motors could be added to have motorized bed levelling, also the extruders should be driven by cheaper brushed DC motors in the long term with feedback from an actual filament feed sensor…

Again a long post … I apologize :grin:

We’re having a good discussion here, until someone else jumps in and tells us to shut up, let’s keep going :slight_smile:

As for the disadvantages you note:

If you are doing a multi-axis move that involves multiple controller boards, you cannot have the look-ahead being done on the controller, you need to have it done at the higher level that is working across controllers. If one controller can’t do what’s been asked, the result is not going to be good (just slowing down the axis managed by that one board will not be good), the most that an individual board can do is to report that it was unable to comply.

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.

As long as you can buffer commands, so that you can send the next movement while the board is executing a previous movement (and the communications and processor are fast enough to keep up), the mechanics of the machine should not be able to tell when one command ends and the next starts.

Since some software is going to generate lots of line segments anyway, this is something we are going to have to handle in any case.

by the way, I’m unfamiliar with the term “takt-line” I think I have a fair idea of what it is from the context, but could you point me at the definition you are using?