zeevy / grblcontroller

Compact android mobile application for gcode streaming and controlling a cnc machine with grbl firmware
GNU General Public License v3.0
200 stars 71 forks source link

Manual programming helpers #105

Open mkaluza opened 5 years ago

mkaluza commented 5 years ago

Hi, I'm using grbl mostly manually and I'm missing few features very much compared to a professional cnc (mine is with Sinumeric control), which grbl doesn't support (and even cannot support due to Arduino limitations), but that could easily be supported by the controller app UI:

GCODE: Those features would require a bit of gcode preprocessing, but maybe they would be possible (in order from the easiest and most wanted):

Tell me what you think. Although I don't like java and don't program in java too much, maybe I could help with coding.

mkaluza commented 5 years ago

Oh, and user messages (useful for tool changes for long programs with many tools). When encountering a comment that starts i.e. with exclamation mark, it should stop sending gcodes and display that message in a window with OK (and maybe Abort) buttons (not a bubble).

It would make those programs more self contained.

zeevy commented 5 years ago

@mkaluza those are good points which you gave, but current goal of the app is to support only grbl supported features. I think many more features will be possible to add once official grbl arm firmware is out.

Typed command history is one think i can think of in next version. Subprograms i am not sure about them, how much they will be helpful Labels, forward jumps, Variables (can you explain them a little)

mkaluza commented 5 years ago

I'm writing all this because I've seen you saying you have no experience with professional cnc machines, so you may even not realize that there are some very useful features to have. All those I've written about (except variables) should be fairly easy to implement (I would not all for things requiring a lot of work)

Those are either already supported features or features that no version of grbl will ever support, arm or not arm (lack of permanent storage, to little memory) and actually completely independent from grbl

As for those gcode features, I'll write some examples when I get to some PC, because from phone is not very convenient. They are very useful and very needed if you do any kind of gcode programming and not only run files from cad/cam.

On Thu, 2 May 2019, 11:01 zeevy, notifications@github.com wrote:

@mkaluza https://github.com/mkaluza those are good points which you gave, but current goal of the app is to support only grbl supported features. I think many more features will be possible to add once official grbl arm firmware is out.

Typed command history is one think i can think of in next version. Subprograms i am not sure about them, how much they will be helpful Labels, forward jumps, Variables (can you explain them a little)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/zeevy/grblcontroller/issues/105#issuecomment-488598733, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHSF5YTRKP2JGRBXC7URUDPTKUYFANCNFSM4HJ4KI5A .

mkaluza commented 5 years ago

Capture+_2019-05-02-11-12-38

Just realized that email attachments don't get displayed, so here is the image

zeevy commented 5 years ago

@mkaluza Thanks for the image. That is a good option, i will sure look into this.

You are correct i don't have any knowledge of professional cnc machines, I developed this app only with grbl in mind.

I did not get clarity on waiting for the user to press ok if some line like "(!drillbit hss 6)" is found. If user has to do a tool change after this message then its little complicated (not impossible). Supporting M6 with user macro is in my todo list, when it is done it may address this issue.

It would be great help for me, if you can provide some gcode samples.

The image looks wired to me, why the text "Step Size | Jog Feed" in two lines? App is supposed to be open in full screen, mobile status bar should not be visible. What is the mobile model? os version? and resolution? For me it looks like you have increased the text size in mobile settings.

mkaluza commented 5 years ago

I did not get clarity on waiting for the user to press ok if some line like "(!drillbit hss 6)" is found. If user has to do a tool change after this message then its little complicated (not impossible). Supporting M6 with user macro is in my todo list, when it is done it may address this issue.

Let's assume the following code to change the tool (just example not meant to be working for real or very correct)

...
N1 G0 G91 Z20
N2 M5 M9
N3 G53 G90 X100 Y300
N4 G53 Z50
N5 M0
(!Endmill flat hss 6)
N6 G53 Z20
N7 M0
N8 G53 Z50
...

Right now on grbl this code would go to X100 Y300 in absolute machine coordinates (tool change place, tool probe location) with spindle and coolant off and a little above it (N4), and hold the program so that I can remove the endmill and insert another. After that it would go down and wait again so that I can tighten the endmill at a reference level (I don't have a tool probe yet so it's the way I deal with tool length setting). After that it goes up and on with the milling.

But right now each time the machine waits I need to look into the code to find the comment containing the tool that the machine is expecting. The modification I'm proposing would allow me to see on the screen the message permanently so that I know that now I should insert 6mm endmill and either click 'OK' when I've found it or abort if there's a problem (but it isn't strictly nevessary as I could abort when the machine is waiting on M0, so just "OK" button is enough for a start, but it would be good to have it).

By the way, you've given me the idea on how to implement M6 in grbl easily and flexibly :) I'm not sure if the UI should do it... I think it's more a grbl job...

Besides - that kind of message would be universal - user could get all kinds of messages, like for example about stock and initial setup: "Stock 100x150, zero in the center", some safety checks or some other messages/info the operator should get in the middle of the operation, like "Close the cover".

It would be great help for me, if you can provide some gcode samples.

Ok, lets assume we have 20 holes to drill (that is the immediate problem I have right now). Right now I would need to have such gcode:

G0 G90 X20 Y20
G0 Z4

(drill the first hole)
G0 G91 Z-3
G1 Z-5 f300
G0 Z8

G0 X10

(and another)
G0 G91 Z-3
G1 Z-5 f300
G0 Z8

G0 X10

and repeat that last 4 lines 18 more times...

That's a very long, ugly code to edit on a cell phone... Now imagine that this drilling isn't that simple (approach the material, drill, go up). Imagine it's a peck drilling going down 5 or 6 times and you have to repeat that code 20 times in the file... It sucks even more.

But if I have subprograms, I could do this:

file: drill_5.sub
G0 G91 Z-3
G1 Z-5 f300
(many other lines of code that should be repeated for each hole)
G0 Z8
M17
file: rail.gcode
G0 G90 X20 Y20
G0 Z4

(drill the first hole)
L_drill_5 (<--- call "subprograms/drill_15.sub subprogram)

G0 G91 X10

(and another)
L_drill_5 (<--- call "subprograms/drill_15.sub subprogram)

G0 G91 X10

and repeat that last 2 lines 18 more times...

This already looks better, because by looking at the main program you can easily figure out what it does (drill, advance 10mm, drill, advance etc...)

Now let's add a loop here. drill_5.sub stays the same, only the main program changes

file: rail.gcode
G0 G90 X20 Y20
G0 Z4

drill_label:
(drill the hole)
L_drill_5 (<--- call "subprograms/drill_15.sub subprogram)

G0 G91 X10

REPEAT drill_label P=19

the last line instructs the UI to repeat the gcode from there to "drill_label" 19 times (it's been already executed once, so there'll be 20 holes in total). After that it continues further with the program. Doesn't it look better?

Subprograms are the simplest thing - when parsing gcode, if you encounter L_(filename), you should just send the contents of subprograms/filename.sub opened from folder relative to the main script. It doesn't require keeping any state and should not be complicated. Think of it as an "include".

REPEAT is more complicated because you have to keep track of the labels and the number of repeats already done, but still should be quite doable. It doesn't change any syntax and doesn't create confusion (label could be detected with a regexp: alnum characters without parentheses (we ignore comments) ending with a colon. And REPEAT is well... repeat :D also parseable with a regular expression. It also doesn't require any preprocessing since REPEAT always goes backwards, so you have either already encountered the label in the code or it is an error.

A forward jump is just a GOTOF label with the difference being that the label is after the goto, not before as in repeat. It's very useful if you had to abort a program at some point and you want to restart it at the same point. Then you just add a label there and a GOTOF at the beginning and don't need to delete all the lines. The difficulty here is that at that point you have to scan the file forward to find the label. Or maybe it isn't - you just skip all the lines until you find the label or the program ends (in which case it is an error, but it would stop the program nevertheless).

I'll skip the variables for now as it becomes more complicated then.

I hope you get the point. No version of grbl will ever implement those features because it doesn't have access to the entire gcode at once, so it cannot 'remember' the labels for REPEAT (besides, the repeated code block could be too large to fit in uP memory anyway) or look for them for GOTOF (ok, it could just skip the lines until the label is found).

It also won't have any way to show messages to the user without gui support.

The image looks wired to me, why the text "Step Size | Jog Feed" in two lines? App is supposed to be open in full screen, mobile status bar should not be visible.

It is fullscreen - status bar being visible is the side effect of taking a screenshot

What is the mobile model? os version? and resolution?

LG K7 2017

For me it looks like you have increased the text size in mobile settings.

Yes, I had large font size set. I didn't even notice it :)

zeevy commented 5 years ago

Thanks for the great explanation. Is that a standard practice to include "!" in comments for user confirmation messages?

By the way, you've given me the idea on how to implement M6 in grbl easily and flexibly :) I'm not sure if the UI should do it... I think it's more a grbl job...

Desktop sender like UGS and BCNC supports M6 macro, where M6 command is replaced with the user defined gcode block.

Ok, lets assume we have 20 holes to drill (that is the immediate problem I have right now). Right now I would need to have such gcode:

For simple repeatable gcode blocks, i think we can use custom buttons where we place the repeatable code in the custom button and press the button for n number of times. Or even we can have an option of "Repeat n times" in button configuration. Actually I wanted to have a simple cam tool in the app it self where i can do drilling, profiling and cutting basic shapes but due to lack of time i am unable implement it.

Supporting "L_", "labels" and "REPEAT" will only be good idea if those are the standard practice in CNC world. (I doubt may people have different labels/letter to indicate them) Current architecture of the app prevents any thing to be done like these (M6 macro is still not implemented due to this), i am planning to rewrite the structure so that these type of implementations can be done. Unless "REPEAT" is implemented for me its not looking good (calling the sub program multiple times)

When i do rewrite the core of the app i will keep these points in mind.

mkaluza commented 5 years ago

Thanks for the great explanation. Is that a standard practice to include "!" in comments for user confirmation messages?

Not that I know of. It's as good as any other. That was my first idea. In fact instead of hardcoding it you could add a config option to enter a regular expression that would match the messages that should be displayed as dialog boxes - then anyone could set anything they like/want with the default being for example /^!(?P<message>[\w ]+)/

By the way, you've given me the idea on how to implement M6 in grbl easily and flexibly :) I'm not sure if the UI should do it... I think it's more a grbl job...

Desktop sender like UGS and BCNC supports M6 macro, where M6 command is replaced with the user defined gcode block.

Yes, I know, but it's because grbl's author refused to implement it... I still think it's the machine controller responsibility - this way it's implemented once and independent of the higher level application

Ok, lets assume we have 20 holes to drill (that is the immediate problem I have right now). Right now I would need to have such gcode:

For simple repeatable gcode blocks, i think we can use custom buttons where we place the repeatable code in the custom button and press the button for n number of times. Or even we can have an option of "Repeat n times" in button configuration.

You're missing the point. I can do that already - I write a script to drill one hole and execute it 20 times - this way I'm not limited by any buttons. I want to be able to quickly and conveniently write scripts that will do it all at once and more - can repeat many things many times. Just fire and forget.

By the way - can the app remember last file location and start the "open file" dialog there? Every time I want to open a script I must click from the top level something down to my one - always the same - directory with my scripts...

Actually I wanted to have a simple cam tool in the app it self where i can do drilling, profiling and cutting basic shapes but due to lack of time i am unable implement it.

There's no such thing as "simple cam tool" - cam is complicated almost "by definition". Or there is - it's called gcode :) And loops and jumps is everything you need to do "basic shapes" like helix, pocket, planning etc... And it will be way easier to implement ... and use - I can't really image using any graphical design software on a cell phone, or any other touch screen for that matter.

Supporting "L_", "labels" and "REPEAT" will only be good idea if those are the standard practice in CNC world. (I doubt may people have different labels/letter to indicate them)

You do realize "label" can be any name... I suggested using L_xxx instead of Lxxx to avoid collisions. That's what Sinumerik uses and thats what I know. But I think Fanuc is more popular and a kind of "standard" and there is an M98/M99 call to subprograms. (https://www.cnccookbook.com/m98-m99-g-code-cnc-subprograms/). Mach 3 also appears to be using Fanuc syntax. As long as you implement anything that is used in the industry, you're good - there's no "standard" way probably because at some point every vendor introduced their own extensions, but I think Fanuc is a good template.

Current architecture of the app prevents any thing to be done like these (M6 macro is still not implemented due to this), i am planning to rewrite the structure so that these type of implementations can be done.

Ok, so that's a problem - I haven't looked into the code hoping that I won't have to, but I will at some point (that is when I have all the environment set up, because right now I have nothing...)

Unless "REPEAT" is implemented for me its not looking good (calling the sub program multiple times)

No - REPEAT and subprograms are two separate things and one doesn't depend on the other. And while I could live without REPEAT/GOTO, subprograms are essential.

When i do rewrite the core of the app i will keep these points in mind.

Great. If you need anything, just ask. And you can have a look into this cnccookbook page - it has many good info on how professional cnc machines work.

zeevy commented 5 years ago

Sure i will have look at cnccookbook

mkaluza commented 5 years ago

I've tried to look into your code but no - I still don't like java in general and java for Android in particular :P, so I won't be able to help you directly. But... If you know python, or at least can read it and understand it more or less, I could write a proof of concept (fully working) gcode preprocessor for REPEATs, GOTOs and subprograms. I would of course make the code as readable as possible.

Because I've been thinking - implementation of loops, jumps and includes is fuly static. It means all we need is one function - preprocessGCode() - that will take the main input file, go through it, replace REPEATs with multiple instances of the repeated block, remove lines that are jumped over and include subprograms' code (also with preprocessing, so it has to be recursive, but that shouldn't be a problem), and generate a temporary file with "vanilla" gcode for grbl. Then your code could send that file instead of the original one! Therefore it won't require any modifications to your current code. This function would also handle M6 macro expansion.

Also if you could show/explain to me in your code where file reading is initiated, where it is done and where the gcode is sent, maybe I could help you figure out how to easily insert those user messages from comments in there, or at least we could think about it together.

And if you won't be able to read python, maybe I'll be able to translate that code later into vanilla java, and all you would have to do is include it and do all the android stuff like file reading etc. It'll probably be ugly, but hopefully it'll work.

zeevy commented 5 years ago

I know python a little, If you can provide the python code, i can covert that into java.

File streaming process in app is handled in FileStreamerIntentService.java

https://github.com/zeevy/grblcontroller/blob/master/app/src/main/java/in/co/gorest/grblcontroller/service/FileStreamerIntentService.java#L199
Line number: 199
mkaluza commented 5 years ago

I know python a little, If you can provide the python code, i can covert that into java.

Ok, that's great, because writing it in java would take me ages. Here it is: https://github.com/mkaluza/gcode_preprocessor

One difference from what I suggested is that it doesn't handle subprograms (separate files), but only subroutines (in the same file). It's an "official" syntax that Fanuc and Mach3 use. I also added Sinumerik-like label, because I think verbose labels are way better than numeric-only. And when I thought about it more, subroutines in one file are better (simpler) for 99% of cases than multiple files. And if someone requests multiple files, they could be added easily.

It's far from perfect, but if I wanted to make it perfect, I would've probably never finished it. I'm for as-needed improvements and good-enough code. One obvious missing thing is the recursion limit for subroutines to avoid endless loops, but again - it's in author's best interest not to fuck up his gcode to that extent so I wouldn't worry about it too much from the start;)

If you have any questions, feel free to ask.

File streaming process in app is handled in FileStreamerIntentService.java

Ok, as for those user messages - I think it's very simple with your current code:

Also in this function you would call the preprocessor and instead of opening a stream for the original file, you would read the temporary file created by the preprocessor. Or the preprocessor function could also return a stream and could be a generator and produce code on demand instead of processing the whole file, but that would complicate things a bit (error checking would be deferred and besides it needs to read whole file at least once anyway to scan for labels) - I think reading whole files will be easier to begin with.

Having thought about it - I don't know how android handles intents and if this.stream and FileStreamerIntentService would survive dialog box call, but then you could just pass that stream to the dialog box and replace resume parameter with stream that if given, would be read further, and if null, would cause reopening of the file. Or - if possible - you could mark a service as "important" of some kind so that it's not accidentaly destroyed...

zeevy commented 5 years ago

I will go with the preprocessor option as it would be much faster solution and does not need any major changes in the current structure. it might take a couple of weeks for me to start with this. I will update the progress here.

mkaluza commented 5 years ago

I've been thinking... If you could do the android part (with which I definitely won't be able to help you), I could probably take a shot at the processor itself during the weekend. For now just use a stub class with one entry point that receives a filename and returns a stream.