开源改变世界

gcode 参数 (#334

推推 grbl 3年前 (2023-02-01) 371次浏览
打开
bhgv 打开了这个问题 2016 年 5 月 25 日 · 23条评论
打开

gcode 参数 (#…=…) 看起来处理不正确#334

bhgv 打开了这个问题 2016 年 5 月 25 日 · 23条评论

注释

gcode 参数 (#334
bhgv 评论了 2016 年 5 月 25 日  

我尝试将 bcnc 与 geda pcb g 代码一起使用。它包含许多字符串,例如:

#102=8.3  (comment 1)
#103=300.0  (comment 2)
..
..
F#103

运行后,bcnc 显示“错误:未定义进给率”并停止。
我取消注释字符串

Sender.py:725 -> def serialIO(self):  ...  print "+++",repr(tosend)

它写入控制台

+++ 'F0\n'
# should be F300.0

谁能指出我在哪里处理参数?
我试图找到。

cnc.py: 1567 -> def compile(program):
--//-- : 988 -> def parseLine2(line, space=False):
--//-- : 1022 ->        if line[0]=='_':            try:    return compile(line,"","exec")

这一点我的调试器转到 1026

except:
                # FIXME show the error!!!!
                return None

编译在这里 – https://docs.python.org/2/library/functions.html#compile ?
这里的行值为:

_103=300.0  (comment 2)

和 python 编译器给出了一个错误。

ok,下篇继续

PS(也许编写非手写解析器会更好?如果你愿意,我可以提供帮助)

gcode 参数 (#334
作者

我试图改变
cnc.py: 1021

        # 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

现在行:

_103=300.0

并毫无例外地编译,但无论如何在 sender.py -> serialIO -> tosend

+++ 'F0\n'

好的,会在下一篇继续(我怕蓝屏)

gcode 参数 (#334
作者

..继续

好的,
cnc.py: 1139 -> def motionStart(self, cmds):
–//– : 1170

            elif c == "F":       # cmd = "F#103"
                self.feed = value*self.unit  # value = 0

但是,
–//– : 1143

            try: 
                value = float(cmd[1:])  # cmd[1:] = "#103"
            except:
                value = 0  # and value == 0 with any parameter

好的,让我们尝试在下一篇文章中修复

gcode 参数 (#334
作者

在“GCode.vars”字典中是所有参数,但我无法从 cnc.py:1139 Cnc.motionStart 接收它们!

gcode 参数 (#334
作者

更改支持参数

数控.py

117:(全球空间)

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 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:

这不是结束。明天继续

gcode 参数 (#334
作者
bhgv 评论了 2016 年 5 月 26 日  

随着帖子#334(评论)的更改,它修复了参数,但看起来 grbl 不喜欢 F0 命令。尝试删除或更改它们

顺便说一下,我用 python 编写了 gcode 解析器库。它可以用作解析,用作绘图,用作检查。并且它易于使用(我希望如此)并且与手写解析器相比更容易定制。

https://github.com/bhgv/python_gcode_parser_library

README.md 文件
中的文档 example.py 文件中的示例

gcode 参数 (#334

@bhgv: 请记住,gcode 并非普遍相同。这意味着制造商和控制器之间存在细微差异。Grbl 使用 LinuxCNCs gcode 描述。至于 F0 错误,这个值是未定义的。您不能以零进给移动。我没有明确记得 LinuxCNC 的 gcode 描述在哪里说这是一个错误,但我不明白它不会是什么。如果您能指出 F0 有效的地方,请告诉我,我会更新 Grbls 解析器。

gcode 参数 (#334
所有者

@bhgvbCNC 通过以下方式处理 gcode 参数

  • 就像在蟒蛇中一样。所有以 % 开头的行都将由 python 执行,如果有结果将发送到 grbl。
  • 如果包含在方括号 [] 中,则可以访问变量
  • 所有#变量都改为_,以便python可以理解和解析
  • 表达式使用普通括号而不是方括号,例如 sin(angle)

这样做是为了更容易使用 python 解释器及其所有功能,
而不是提供非常严格的限制

所以你的例子必须写成

%feed_variable=300.0
..
F[feed_variable]
gcode 参数 (#334
所有者

我忘了提到 CNC 类中有一个名为 stdexpr 的变量,
如果您更改为 True,它通常设置为 False,它应该接受带有 #num 等的“标准”gcode 表达式。
但是我还没有测试它,并且我从不在配置中放置用户设置

gcode 参数 (#334
作者
bhgv 评论了 2016 年 5 月 26 日  

你好,今天

抱歉倒序。
@vlachoudis
#=
默认收集良好并存储在 GCode.vars 中,但在 CNC 类中不可访问(#334 后(评论))。

接下来,看看 上次 git中的#334 后(评论)示例

  • CNC.vars[“feed”] = float(g[1:])
  • 值 = 浮动(cmd[1:])

(收集到的值存储在GCode.vars中,自己看)
也许我没有找到它放置值的所有时刻,但是从#334(评论)更改后它开始修复参数。

用于测试的gEDA输出文件:链接
你可以自己测试。收集参数,但从未固定。

(在这个文件中太多#参数,我想自动修复它们。越多越好)

我不建议将我的更改安装到 bCNC,但如果你帮我找到内部 gcode 解析器的链接和用法,也许将来配置、定制和扩展会更容易。

@chamnit
关于F0错误。
嗯,我看起来更精确的gcode 。它包含许多字符串,例如“G1 Z#101 F#102”。它似乎只修复了第一个参数。我知道从哪里需要F0。

关于 g 代码的许多变体。
看看建议的gcode 解析器。定制的主要部分是

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)
  }
)

你可以看到你只在传递之前将回调执行器发送到不同的 g 代码和情况。对我来说这是最简单和最快的方法。您可以根据它们进行绘制,可以向步进器等发送命令,而无需深入解析器。

更改解析器,添加/删除等。
这是解析器的主要部分:

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) .)
        .
gcode 参数 (#334
作者
bhgv 评论了 2016 年 5 月 26 日  

() – 在正则表达式中是 ()
{} – 在正则表达式中是 ()*
[] – 是 ()?在正则表达式中
| – 是 | 在正则表达式中
(. .) – 是尾随当前正则表达式案例的代码字符串
<out val1, val2, val3 > – 是参数。val1为输出,val2、val3为输入

我认为您现在可以理解并开始自定义此解析器,而无需阅读完整的文档

gcode 参数 (#334
作者

例如如何添加[参数]处理?它只需要将 1 个字符串添加到 Number 块中:

 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) .)
          "]"
        .

就这样

gcode 参数 (#334
作者

我只请你帮我做这个实验。因为很难仅从调试器接收所有信息。在成功的情况下 bcnc 变得更快,因为正则表达式太慢,更多变(例如:添加对其他 cnc/3d 打印机的支持或驱动步进器/加热器/直接通过并行 gpio 等)
可能支持不同的gcode 通过将不同的解析器存储/更改为配置而不更改主 bcnc 代码来选择

我只要求你帮我找到 bcnc gcode 解析器到其他 bcnc 代码的链接,因为这是你的代码,你比我更了解它。

抱歉我的坚持,但 bcnc 是一个非常棒的产品,我想为我的目的开发它。并添加对除 grbl 之外的一些其他控制器的支持。

gcode 参数 (#334
所有者

@bhgv对不起,但我不明白你需要什么?

gcode 参数 (#334
作者

我已经更换了解析器,现在参数处理得很好。两种类型

但需要更多测试并将解析器的某些部分移动到其他文件以便将来更容易开发

gcode 参数 (#334
作者

我已经更换了解析器。在开始部分,绘制部分和发送到控制器部分。如果有人想测试 – 欢迎。

https://github.com/bhgv/bCNC

  • 解析器本身 – GCode_parser 文件夹
  • GCode_parser/Gparser.py – 包含所有回调、实用程序等的类。
  • GCode_parser/Parser_engine/GCode.atg – gcode 解析器声明
gcode 参数 (#334
贡献者

你好@bhgv. 这里真的有很多东西 :)
您是否使用 coco parse 进行了一些性能测试?尊重原始代码有多快?

gcode 参数 (#334
作者

它更慢。最新版本(不是来自 github)比原来慢 2-2.5 倍。但我现在想收到正确的工作。
现在它正确地绘制了小的 gcode,但是大的(> 1mb)它显示在编辑列表中但只绘制了部分代码。
我会在修复后上传

gcode 参数 (#334
作者

新版本已上传到github。

  • 比原来慢 ~2.5 倍。它在 1.5mb 代码文件上进行了测试。
  • 两种参数选择的处理都很好。前任:
#12=34
% tt = 2*(3+4.5)
g0 x#12 y [ tt]

(解析速度不是大问题,因为它可以很容易地重写为 C 或 C++。因为 coco 支持许多语言)


原始 bCNC 中的一件事:
CNCCanvas.py -> class CNCCanvas: -> def drawPaths()
strings:

                        if time.time() - startTime > DRAW_TIME:
                            raise AlarmException()

DRAW_TIME 应该更大或删除此字符串,因为它们不允许绘制大的 g 代码

gcode 参数 (#334
贡献者

DRAW_TIME 可以通过 Canvas 右上角的小组合框进行更改。这允许 bCNC 即使在低端硬件中也能运行,如果它花费太多时间,则通过删除重绘方法。

gcode 参数 (#334

gcode 参数 (#334
作者

我已经在 Coco 的 C++ 分支上重写了解析器。现在比原来快 2 倍。支持两种类型的参数,参数中的数学,变量。前任

#12=34
% tt = 2 * 3 
g2 x[tt]  y#12
% ttt = (1-2*(1-3)+1)*3^(-2+(8*3)^-4)
g0 x#12  ( Ber_gt: fgh 4 f 8.  ) y [ ttt]
% tt = ttt + 2*(#12 +8)  / 3^(1/2)
g8 y 45 x32.8 z -[tt] z + [ttt]

在像 python 一样添加回调连接器后,我将上传它进行测试

gcode 参数 (#334
所有者

@bhgv你在做什么很好,但是在 python 中拥有它的整个想法是从 python 扩展中获利,不仅是简单地评估表达式,而且能够嵌入 python 程序作为 gcode 的生成器。纯 python 的另一个好处是它不需要任何重新编译,因此它可以在任何平台上运行(windows、linux、mac 等…)

gcode 参数 (#334
作者

@vlachoudispython 和 C++ gcode coco pasers 具有非常相同的外观和非常相同的界面。每个都可以代替其他使用。配置中只有很小的变化(开/关)。
C++ 是作为常规 python 扩展编写的,它只是 python 的一个更快的克隆。无需更改其他 bCNC 代码,您可以像往常一样使用/编程 bCNC。


  • python 速度很快,gcode 不大或在快速计算机上运行(仅比原始解析器慢约 2 倍)。
  • C++ 可用于慢速平台(如树莓派或旧计算机)和重量级 gcode。
  • 您可以随时轻松地在它们之间切换(原始解析器在每次重绘/移动/编辑时解析整个 gcode 文件)。你根本不能使用 C++ 解析器。
  • coco C++ 解析器是高度平台独立的,在未来它可以重写为 C 以更好的可移植性。这个不使用 C++ 扩展。我更喜欢 C++ 只是为了更快的重写。

  • 非手写的coco解析器有什么好处?- 它可以扩展或更改为以最简单的方式解析其他矢量格式(svg、eps、gerber 等)。
  • bCNC 使用相同的解析器开始读取、填充编辑列表、绘图。通过仅更改解析器,它可以用于许多不同格式的文件或添加新功能(如#parameters)。并且可以单独调试。
  • 可能有许多针对不同格式的解析器,并且只对输入文件格式使用相应的解析器。

  • 像慢板一样使用树莓派有什么好处?- 它们可以直接安装在 cnc 上,作为功能强大的 cnc/3d 打印机控制器,具有大屏幕和丰富的界面、文件查看器/转换器/编辑器和其他好东西。通过局域网或无线网络连接到一台大电脑。现在它们的价格仅为 10 美元。

我认为最好的是 – 上传和展示。明天吧。

gcode 参数 (#334
作者

上传了带有 Py 和 C++ 解析器的 bCNC。现在绘图比解析 (C++) 花费更多时间。

  • 在它们之间切换 – 转到./conf/parser.py并设置py_parser False 或 True
  • 将 C++ 解析器编译到其他平台(不是 linux-armv7)——转到./GCode_parser/Parser_engine/c/tools/coco_cpp并编译 Coco 本身。有脚本可以在 windows 和 *nixes 上编译。之后,转到./GCode_parser/Parser_engine/c并构建解析器 – bld.sh。

免费注册 在 GitHub 上加入此对话。已有帐户? 登录评论
标签
还没有
项目

还没有

发展

没有分支机构或拉取请求

4人参加
gcode 参数 (#334gcode 参数 (#334gcode 参数 (#334gcode 参数 (#334

喜欢 (0)