开源改变世界

从上次命令恢复指南(UI 开发) #305

推推 grbl 3年前 (2023-01-21) 249次浏览
关闭
arkypita 打开了这个问题 2017 年 11 月 9 日 · 20条评论
关闭

从上次命令恢复指南(UI 开发)#305

arkypita 打开了这个问题 2017 年 11 月 9 日 · 20条评论

注释

从上次命令恢复指南(UI 开发) #305
阿尔基皮塔 评论了 2017 年 11 月 9 日  

大家好。我正在尝试开发一种功能,以帮助用户在流式传输 G 代码文件时从 Grbl 的最后一个命令“完全执行”继续恢复中断的作业(挂起、重置、断开连接)。

我知道的信息是收到“OK/ERROR”响应的最后一条命令以及我通过 COM 发送的最后一条命令。

我用来做resume的操作是:

  • 询问用户从哪里重新开始(位置)建议一些重要的选项
  • 分析文件直到这个位置,并计算最后的速度、功率和激光器的状态以及 G90/G91 绝对和相对坐标
  • 分析文件并计算上一个命令的正确最终坐标

然后我:

  • 发送 $H 归位以修复不确定位置(可选)
  • 快速移动到那个坐标
  • 重新应用速度、功率、状态和 G90/91
  • 从该位置开始排队文件

从上次命令恢复指南(UI 开发) #305

这工作得很好,但我看到当命令“完全执行”时“OK”响应不会到达,但只有当它被转移到计划的缓冲区时(我认为)。所以这项工作并不是完全从左边开始,而是向前/下一步。

显然,我可以从某些命令中任意恢复:双重覆盖某些部分的风险比遗漏某些部分更令人讨厌。

但是我问:有没有一种简单的方法可以猜测最后一个“完全执行的命令”是什么?

从上次命令恢复指南(UI 开发) #305
jahnj0584 评论了 2017 年 11 月 9 日 通过电子邮件
从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 9 日  

@jahnj0584你的意思是从 GUI 发送的行数?它非常接近但向前

从上次命令恢复指南(UI 开发) #305
jahnj0584 评论了 2017 年 11 月 9 日 通过电子邮件
从上次命令恢复指南(UI 开发) #305
贡献者
绕线机 评论了 2017 年 11 月 9 日  

我认为您必须分析 XYZ 坐标和 Gcode 以确定哪个命令处于活动状态。您可以将其缩小到已收到ok,但随后需要验证的命令。

@chamnit是否有一种确定性的方法来决定您需要搜索多远以确保您会找到哪个OK命令负责当前位置?

为了分析 gcode,我认为线性移动应该是验证当前位置是否在端点之间的问题。

如果圆弧大于圆的 1/4,则圆弧运动会更复杂。我可能会首先检查点到圆弧中心的距离,然后将圆弧分成线段并应用相同的线性移动检查。可能有更精确的方法来查找点是否在圆直径上,但您需要确保您的算法可以容忍舍入误差。

从上次命令恢复指南(UI 开发) #305
贡献者

一种不理想的选择:您可以使用行号报告,这需要在 config.h 中取消注释 USE_LINE_NUMBERS。一些原始设备制造商使用它来跟踪某行执行的内容和时间。但是,它需要 GUI 为每一行发送一个唯一的行号N。它还会占用大量内存(减少规划器缓冲区以腾出空间)和通信带宽,这两者都不利于激光雕刻(性能会受到影响)。

另一种方法是在中止作业之前观察并记录计划程序缓冲区大小。如果您知道 Grbl 已经“确定”了什么,它可能是准确的,但是 G2/3 arcs 可能会使它变得不确定,因为它用小线填充规划器缓冲区以生成弧。

我确信还有其他方法,但这是我一直想在 ARM 版本中改进的事情之一,我有空间来实现更好的东西。

@arkypita:您要求的是 CNC 世界中称为“程序重启”的东西。您必须对此非常小心,尤其是在处理可能引起火灾的激光时。很容易错误地设置 g 代码模式状态和恢复点的初始位置。像这样的错误会导致机器做一些不可预测的事情,并可能毁掉工作或更糟。

程序如何重新启动也可能取决于机器。您需要以某种方式将机器移动到正确的位置并设置其状态(主轴、冷却液等)。如果您支持铣削,您还必须处理在作业中途更换工具时如何处理。每台机器都会略有不同,需要自定义例程来处理此类问题。

从上次命令恢复指南(UI 开发) #305
贡献者

@chamnit从 GRBL 需要提供哪些信息来实现“程序重启”而不同时实现 gcode 解析器的角度考虑这个问题可能会很有趣。

$G即使在今天,您也可以通过以检查模式运行程序并在发送要跳过的行后发出请求来欺骗 GRBL 在任意代码行报告状态。您仍然需要解析程序以找到每个命令的起始位置。

从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 10 日  

我认为您必须分析 XYZ 坐标和 Gcode 才能找出哪个命令处于活动状态

@winder它无法完成,但正如您所指出的那样,这不是一种简单可靠的方法。你也可能从归档中得到错误的坐标信息(记住他们只更新每 n° 毫秒所以你可能有旧信息)

@chamnit正如你所说,行号报告是最可靠的,但由于非常重要的原因,它是不可行的。

我还考虑使用缓冲区信息是状态报告(即 <Run|….|Bf: 4,83>)来计算计划缓冲区中有多少移动(其中我已经收到 ok) .
无论如何,我也怀疑这种用法是否可靠,因为它仅每 n° 毫秒传送一次,因此它可能是旧信息。

我确定还有其他方法

我认为确保不会遗漏一点的唯一方法是从最后收到的 OK 重新开始“返回某条线”。根据您的文档,一些回线意味着 17 条移动线是计划的缓冲区大小。当然,您可能会冒着重复一些已经执行的任务的风险,但您不会错过任何东西。

您要求的是 CNC 世界中称为“程序重启”的东西。您必须对此非常小心,尤其是在处理可能引起火灾的激光时。很容易错误地设置 g 代码模式状态和恢复点的初始位置。

你是对的!不仅有从何下手的问题,还有重建国家的问题。

我做的第一个测试是简单地跳过恢复点之前的所有行,然后开始推送剩余的行。你可以很容易地想象结果:-)

所以我实现了对跳过的行的读取和解析(我已经拥有所有功能)来重建 S、F、M3/M4/M5、G90/G91 的状态和位置,直到重新启动点。因此,当用户要求从我重建这些状态的位置开始时,我会在所有设备关闭的情况下移动到重启点,然后恢复情况。

当然,正如您已经提到的,我什么都不应该忘记……例如,我刚刚忘记了冷却液 :-)

@winder

即使在今天,您也可以通过以检查模式运行程序并在发送要跳过的行后发出 $G 请求来欺骗 GRBL 在任意代码行报告状态。

这是一个不错的想法 :-)
如果你是对的,我想我可以重建执行 $C 的确切状态,运行所有前面的行,查询 $G 并解析结果 – 退出检查模式并使用该值来恢复状态,而不是通过我的例程从 gcode 分析中收集。(好主意,但有点慢)

从上次命令恢复指南(UI 开发) #305
贡献者

Grbl的检查模式������������������������ℎ�ℎ����������������′��������������′,���������������ℎ���ℎ�����������ℎ������������.�������,������′�����������ℎ�����������������.����������ℎ�������������,��������������ℎ�����������# 重置前的参数状态。

在重新启动点之前,您还需要确保 $# 参数内的更改以及来自探测周期的任何输入(例如工具更改)得到正确处理。

从上次命令恢复指南(UI 开发) #305

关于计算从哪里重新开始的确切点,这就是我最终的想法:

  • 如果引起问题的是“电缆断开连接”,则 grbl 会继续执行其缓冲区中的所有命令,因此请从上次发送的命令重新开始。
  • 如果问题是hard reset, soft reset or grbl hang,grbl不会执行buffer中的数据,所以从最后一个OK接收到之前的17个位置重新开始(planned buffer的大小)

如果你知道你停在哪里,你可以请求 gcode 状态����# 重置前的参数状态。

有时这是不可能的。如果停止是由于重置(硬或软)引起的,则 $G 不可靠:更好地从文件重建状态信息。

在重新启动点之前,您还需要确保 $# 参数内的更改以及来自探测周期的任何输入(例如工具更改)得到正确处理。

由于我对数控世界的无知,我不知道这一切意味着什么。但如果你这么说,我相信也很重要。你能解释得更好吗?

  • $# 不会自动保存在 eeprom 中吗?
  • 什么是探测周期以及为什么我必须在“程序重启”期间重建其输入?
  • 如果程序停止,我想最后使用的工具可以继续工作……为什么我应该处理工具更改?
从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 11 日  

还有一个问题,如果可以的话。我在恢复 G2/G3 的模态状态时遇到一些问题
要恢复状态,我按照在 wiki中找到的这张表进行操作,该表显示了所有模态命令。

模态组 会员词
运动模式 G0、G1、G2、G3、G38.2、G38.3、G38.4、G38.5、G80
坐标系选择 G54、G55、G56、G57、G58、G59
平面选择 G17、G18、G19
维基中的完整表格 […]
  • 我分析文件寻找每个组的最后一个命令,直到请求的重启点。
  • 对于每个组,我发送一个带有找到的值的命令,以将正确的模态状态恢复到重新启动点。

我看到 G0/G1 也可以在没有 XYZ 参数的情况下发送,结果是改变模态状态,这很好,但我也看到 G2/G3 不能在没有 XYIJ 的情况下发送。当我尝试这样做时,我回来了Invalid gcode ID:26,这对我来说是邪恶的:-(

出于这个原因,当 G2/G3 用作模态来执行弧序列时,我无法正确恢复状态并恢复作业,当 gcode 被优化时,如下所示:

G1
X20. Y30.
X10. Y30.
G2 X9.8189 Y55.8487 I520.0261 J16.5689 <-- last modal Motion Mode to restore (G2)
X10.8904 Y82.787 I614.9038 J-10.969
X12.7298 Y104.07 I434.597 J-26.8386
X15.7268 Y122.7344 I193.8699 J-21.5579 <-- last XY position to move to
X21.0961 Y140.5441 I107.0443 J-22.5573 <--- ### I WANT TO RESTART FROM HERE ###
X26.8004 Y148.5746 I19.2816 J-7.6552
X34.7303 Y147.1757 I3.3962 J-3.9235
X43.2745 Y129.1779 I-134.2882 J-74.7786
G3 X52.135 Y110.4832 I149.7887 J59.5462
X61.0307 Y108.1798 I5.5429 J3.0773
  • 我重建信息“我们有 G2”。
  • 我还重建了信息“以前的位置是 X15.7268 Y122.7344”

但是如果我发送重启序列

G0 X15.7268 Y122.7344 <--- fast move to the previous position
G2 <--- set modal G2

我有错误Invalid gcode ID:26– 状态不会更改为 G2 – 下一个命令落入Invalid gcode ID:36并且它们没有正确执行。

从上次命令恢复指南(UI 开发) #305

我错了什么?为什么我不能像 G0/G1 一样发送没有 XYZIJ 的 G2/G3?

从上次命令恢复指南(UI 开发) #305
贡献者

你说得对,我最近也注意到了这一点。除此之外,如果尚未设置进给速率,则任何运动命令都会出错:(error:22) Feed rate has not yet been set or is undefined.

从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 11 日  

是的,但是对于进给率,这是正确的行为。(编辑:但即使进给率未定义,也应允许发送不带 XYZ 的简单 G1)。如果有 XYZ…参数,错误应该只上升

从上次命令恢复指南(UI 开发) #305

以下是单独发送时会出错的命令列表

从上次命令恢复指南(UI 开发) #305

从上次命令恢复指南(UI 开发) #305

根据标准,列出的错误是正确的。您提出的建议与标准背道而驰,我不同意这一点。

从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 12 日  

@109JB如果它们按照标准是正确的,我同意你和实施。
您知道这种行为是否有特殊原因吗?

我认为我可以轻松地处理这种情况,在我重新启动的下一个 XYZIJ 行中重新添加丢失的(优化的)G3/G4。

笔记。我不是在提议,我只是在请求。(也许我的英语和应该/可能会有一些误解)。

@chamnit(如果需要,可以关闭此问题)

从上次命令恢复指南(UI 开发) #305

根据定义,G01 是基于线性插补进给速率的移动。当机器启动时,默认进给速率为零。在执行 G1 之前,您必须先定义进给速率,无论是否定义了运动。

对于 G2/G3,您需要一个进给速率,但您还需要一个中心点和一个终点。如果省略终点,则假定终点与起点相同,为一个完整的圆。如果缺少定义圆弧中心的 I、J、K 字,则 G2/G3 无法运行。G2/G3 有点不同,因为 G2/G3 是模态的,而 I、J、K 词不是,所以每次你有一个 G2/G3 时你必须有一个 I、J、K。G2/G3 与 G0/G1 的不同之处还在于,G0/G1 可以自行调用而不暗示移动,而直线上的 G2/G3 则意味着弧形移动。一旦完成圆弧移动,G2/G3 就是模态的。举个例子

G2 << 这一行会出错

G2 I2 << 这行在某些解释器中是可以的,但在其他解释器中则不行。一些口译员也需要 X 或 Y。其他人假设一个完整的圆圈并使用起点作为终点。

G2 X2 I1 << 只要终点不造成半径冲突,这条线就可以了

G2 X2 I1 << 假设此行后跟这些:
X0 I-1 << 此行可以,并且就像 G2 X0 I-1 一样被解释,因为 G2 部分是模态的。
X2 << 这条线不OK,因为没有定义中心点

从上次命令恢复指南(UI 开发) #305

我想我已经明白了。
用我的话来说:G1/G2/G3 的意思是“执行一条线,顺时针弧,逆时针弧”并且仅作为次要效果“设置状态”。因此,只有在形式上有效时才能执行它们。

由于没有 IJK 就没有定义弧,因此没有这些参数的任何 G2 都会返回错误。

arkypita 向 arkypita/LaserGRBL 添加了引用此问题的提交 2017 年 11 月 13 日

从上次命令恢复指南(UI 开发) #305

谢谢大家。在您的建议的推动下,我开发了自己的“问题后工作恢复”程序。

从上次命令恢复指南(UI 开发) #305
贡献者

@arkypita @chamnit你认为制作一个描述这个算法的 wiki 页面值得吗?或者可能将它添加到界面页面的末尾,类似于记录操纵杆算法的方式?

从上次命令恢复指南(UI 开发) #305
作者
阿尔基皮塔 评论了 2017 年 11 月 28 日  

@winder
如何从严重中断的工作中恢复是一项只有 PC 软件(流媒体)而不是 grbl 本身感兴趣的任务。根据程序的设计方式,实现此功能的方式可能会大不相同。

然而,这里简要描述了如何在 LaserGRBL 中实现“工作恢复”:

在正常的文件流操作期间:

  1. 跟踪最后发送的命令 –行号
  2. 跟踪 grbl 管理/回答的最后一个命令(确定或错误响应)-行号
  3. 尝试检测流式传输过程中断的原因(用户软重置、断开连接、硬件重置)

第 2 步和第 3 步并不是真正必要的,但我已经实现了它们以建议从哪里重新启动的最佳行号。断开连接时,可能已经执行了所有已发送的行;在硬件重置时,执行可能在最后一次回答等之前停止了一些行。

当用户按下“发送文件”按钮时

  1. 认识到以前的工作没有完成
  2. 检测当前位置是好的还是受损的(如果有硬件重置,报告的位置是 0,0,0,但激光头可能在任何地方)。
  3. 打开一个对话框,询问从哪里重新开始的行号(建议一个好的行号)
  4. 如果位置受损,建议重新归位
  5. 让用户决定是否从特定行重新运行作业,是否重做归位,或者从头开始

当用户决定从特定行恢复作业时

  1. 解析整个文件直到该行并计算:
    从哪里重新开始
    该行所有模态状态值的位置 (xy)
  2. 将一系列命令排入队列:
    如果用户需要,请重做归位
    将激光器移动到上一步中确定的位置
    恢复上一步中计算的模态状态
喜欢 (0)