-
Notifications
You must be signed in to change notification settings - Fork 526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gcode parameters (#...=...) looks as processed incorrectly #334
Comments
i tryed to change # most probably an assignment like #nnn = expr
if line[0]=='_':
line = re.sub("\([^\)]*\)", "", line) # this is my correction
try:
return compile(line,"","exec")
except:
# FIXME show the error!!!!
return None now line:
and compile without exception, but anyway on sender.py -> serialIO -> tosend
ok, will continue in the next post (i afraid of bsod) |
..continue ok, elif c == "F": # cmd = "F#103"
self.feed = value*self.unit # value = 0 but, try:
value = float(cmd[1:]) # cmd[1:] = "#103"
except:
value = 0 # and value == 0 with any parameter ok, lets try to repire in the next post |
in the "GCode.vars" dict are all the parameters, but i can't receive them from cnc.py:1139 Cnc.motionStart ! |
changes to support parameters cnc.py 117: (global space) GCODE_PARAMS = {}
def value_of_cmd(cmd):
value = 0.0
try:
if cmd[1] == '_':
pat = re.match("^_\d+", cmd[1:])
if pat and pat.group(0) in GCODE_PARAMS.keys():
value = float(GCODE_PARAMS[pat.group(0)])
else:
value = float(cmd[1:])
except:
value = 0.0
return value ~2140: (GCode class) class GCode:
LOOP_MERGE = False
#----------------------------------------------------------------------
def __init__(self):
global GCODE_PARAMS
self.cnc = CNC()
self.header = ""
self.footer = ""
self.undoredo = undo.UndoRedo()
self.probe = Probe()
self.orient = Orient()
self.vars = {} # local variables
self.init()
GCODE_PARAMS = self.vars # my horrible hack ~735 @staticmethod
def updateG():
for g in CNC.vars["G"]:
if g[0] == "F":
CNC.vars["feed"] = value_of_cmd(g) #float(g[1:])
elif g[0] == "S":
CNC.vars["rpm"] = value_of_cmd(g) #float(g[1:])
elif g[0] == "T":
CNC.vars["tool"] = value_of_cmd(g) #int(g[1:])
else:
var = MODAL_MODES.get(g)
if var is not None:
CNC.vars[var] = g ~1156: def motionStart(self, cmds):
#print "\n<<<",cmds
for cmd in cmds:
c = cmd[0].upper()
value = value_of_cmd(cmd) # my change
# try:
# value = float(cmd[1:])
# except:
# value = 0
if c == "X": ~1604 for cmd in cmds:
c = cmd[0]
value = value_of_cmd(cmd) # my change
#try: float(cmd[1:])
#except: value = 0.0
if c.upper() in ("F","X","Y","Z","I","J","K","R","P"):
cmd = CNC.fmt(c,value) ~3964: for cmd in cmds:
c = cmd[0]
value = value_of_cmd(cmd) # my change
#try: float(cmd[1:])
#except: value = 0.0
if c.upper() in ("F","X","Y","Z","I","J","K","R","P"):
cmd = self.fmt(c,value)
else: this is not a finish. continue will be tomorrow |
with changes from the post #334 (comment) it fixes parameters, but looks like grbl doesn't like F0 commands. try to remove or change them by the word, i wrote gcode parser lib in python. it can be used as for parsing, as for drawing, as for checking. and it's easy to use (i hope) and much easier to customise comparint with handwriting parsers. https://github.com/bhgv/python_gcode_parser_library docs in README.md file |
@bhgv : Please keep in mind that gcode is not universally the same. Meaning there are slight variations between manufacturers and controllers. Grbl uses LinuxCNCs gcode descriptions. As far as an F0 error, this value is undefined. You cannot move at zero feed. I don't explicitly remember where LinuxCNCs gcode descriptions say this is an error but I can't see how it wouldn't be. If you can point where it says that F0 is valid, please let me know and I'll update Grbls parser. |
@bhgv bCNC is handling the gcode parameters in the following way
it is done in this way to be easier to use the python interpreter, and all his capabilities So your example has to written as
|
I forgot to mention that there is a variable in the CNC class called stdexpr that is set to False |
hi today, sorry for reverse order. next, take a look to the post #334 (comment)
(collected values stored in GCode.vars, look by yourself) gEDA output file used to testing: link (in this file too many # parameters and i want to do their fixing automatically. the more that isn't so difficult) i not propose to install my changes to bCNC, but if you help me to find links and usings of internal gcode parser, in future, maybe, it will be easier to configure, customise and extend. @chamnit about many variations of g-codes. parser.set_callback_dict( # set callback-foos for executing different g-codes and situations
{
"G0": G0_callback, # foo(key, param) should return executed g-code as string
"G1": G1_callback, # foo(key, param) --//--
"G2": G2_callback, # foo(key, param) --//--
# ...etc
"default": G_def_cb, # foo(key, param) default g-codes callback
"set_param": set_param_callback, # foo(key, value)
"get_param": get_param_callback, # foo(key) must return value or None
"eol": New_line_callback, # foo()
"non_gcode_cmd":
"no_callback": no_callback_callback, # foo(key, param, (line, row))
"self": self_or_None # self value used to call callbacks
# if self_or_None is not defined or None
# callbacks call as foo(key_params)
# else if self_or_None defined and not None
# callbacks call as foo(self_or_None, key_params)
}
) you can see that you only send callbacks-executors to different g-codes and situations before pasing. it's easiest and fastest way as for me. you can draw by them, you can send commands to stepper etc. without walking in-depth of parser. changing the parser, adding/removing etc. PRODUCTIONS
GCode = (.
if self.gcode_test:
self._int_init()
.)
{
ParamDecl
|
NonGcodeCmd
|
{ GcodeCmd }
eolTok (. self.call("eol") .)
}
EOF (.
if self.gcode_test:
self.print_gcode_out()
.)
.
ParamDecl =
param (. key = self.token.val .)
"="
Number<out num> (. self.set_param(key, num) .)
eolTok
.
NonGcodeCmd =
nonGcodeCmdBody (. self.call("non_gcode_cmd", self.token.val[1:]) .)
eolTok
.
GcodeCmd = (.
cmd = ""
num = ""
.)
(
CmdNoMoveAloneLetter<out cmdLetter> (. cmd = cmdLetter .)
[
Number<out num> (. cmd += num .)
] (. self.call(cmd) .)
|
CmdNoMoveParamLetter<out cmdLetter> (. cmd = cmdLetter .)
Number<out num> (. self.call(cmd, num) .)
|
CmdMoveLetter<out cmdLetter> (. cmd = cmdLetter .)
Number<out num> (. self.call(cmd, num) .)
)
.
CmdNoMoveAloneLetter<out cmdLetter> = (. cmdLetter = "" .)
(
"G"
| "M"
| "T"
) (. cmdLetter = self.token.val.upper() .)
.
CmdNoMoveParamLetter<out cmdLetter> = (. cmdLetter = "" .)
(
"S"
| "F"
| "P"
| "D"
| "E"
| "H"
| "L"
| "N"
| "O"
) (. cmdLetter = self.token.val.upper() .)
.
CmdMoveLetter<out cmdLetter> = (. cmdLetter = "" .)
(
"X"
| "Y"
| "Z"
| "A"
| "B"
| "C"
| "U"
| "V"
| "W"
| "I"
| "J"
| "K"
| "R"
) (. cmdLetter = self.token.val.upper() .)
.
Number<out num> =
number (. num = self.token.val .)
| param (. num = self.get_param(self.token.val) .)
. |
() - is () in regexp i think you can understand and begin to customise this parser just now, without reading the full documentation |
for example how to add [parameters] handling? it needs only add 1 string into the Number block: Number<out num> =
number (. num = self.token.val .)
| param (. num = self.get_param(self.token.val) .)
// -VV this one -
| "[" number (. num = self.get_param("#" + self.token.val) .)
"]"
. that's all |
i only ask you to help me with this experiment. as it so hard to receive all the information only from debugger. in the case of success bcnc become quicker as regexps are too slow, more changeable (for example: to add support of other cnc/3d printers or to drive steppers/heaters/directly by parallel gpio, etc) i only ask you to help me to find links of bcnc gcode parser to other bcnc code as it's your code and you know it much better than me. sorry for my persistence, but bcnc is a very wonderful product and i want to deveop it for my purposes. and add support for some other controllers except grbl. |
@bhgv sorry but I didn't understand what you need? |
i've replaced the parser and now parameters handled well. both types
but needs more tests and move some parts of the parser to other file(s) for more easy development in the future |
i've replaced parser. in start part, draw part and send-to-controller part. if anyone want to test - welcome.
|
Hi @bhgv. There's really a lot of stuff here :) |
it's slower. last version (not from github) is 2-2.5 times slower than original. but i want to receive correct work now. |
new version was uploaded to github.
(speed of parsing isn't a big problem as it may be easily rewriten to C or C++. as coco support many of languages) one thing in original bCNC: if time.time() - startTime > DRAW_TIME:
raise AlarmException() DRAW_TIME should be bigger or to remove this strings as they doesn't allow to draw big g-codes |
i've rewritten the parser on the C++ fork of coco. it ~2 times faster now than original. supported both types of parameters, mathematics in parameters, variables. ex
after adding callback connectors like in python one i will upload it to test |
@bhgv it is nice what you are doing, however the whole idea having it in python was to profit from the python extensions, not only to simply evaluate an expression but to be able to embed a python program as a generator of gcode. Also another benefit in pure python is that it wont require any re-compilation therefore it can ran on any platform (windows, linux, mac etc...) |
@vlachoudis python and C++ gcode coco pasers have very same look and very same interface. and each can be used instead other. only the little change in the configs (on/off).
i think the best is - to upload & show. maybe tomorrow. |
bCNC with both Py and C++ parsers was uploaded. now drawing take more time than parsing (C++).
|
i tryed to use bcnc with geda pcb g-code. it contains many strings like:
after run it, bcnc showed me "error: Undefined feed rate" and stoped.
i uncommented string
and it wrote into console
can anyone point me where it processes parameters?
i tryed to find.
this point my debugger go to 1026
is the compile here - https://docs.python.org/2/library/functions.html#compile ?
the line value here is:
and python compiler gives a error.
ok, will continue in the next post
PS (maybe it would be better to write non-handwrited parser? i can help if you want)
The text was updated successfully, but these errors were encountered: