开源改变世界

从重新映射返回不会破坏队列 #588

推推 grbl 3年前 (2023-01-29) 151次浏览
打开
rene-dev 打开了这个问题 2019 年 5 月 13 日 · 5 条评论
打开

从重新映射返回不会破坏队列#588

rene-dev 打开了这个问题 2019 年 5 月 13 日 · 5 条评论

注释

从重新映射返回不会破坏队列 #588
合作者

以下是我重现该问题所遵循的步骤:

在 configs/sim/axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/manual_change.ngc 中的第 62 行恢复后,添加任何 gcode,例如 g0 x0
2.
运行 configs/sim/axis/remap /manual-toolchange-with-tool-length-switch/manualtoolchange.ini
3.
启用、启动并运行程序
4.
在等待工具更改时单击更改完成。
不要按模拟接触,等待它以 -2
5失败。
g0 x0 不执行。
在 if 中,只执行 return。
6.
代码被执行,如果在返回之前添加m66 p0 l0一个queue buster。

否则,就不可能从换刀器故障中恢复,或者在换刀失败后将机器置于安全状态。

这是我期望发生的事情:

返回前要运行的代码。

这是发生了什么:

代码未执行,在预读期间返回返回。

在此之前它工作正常:

我认为这行不通。我试过 2.7 和 2.8-pre

有关我的硬件和软件的信息:

2.8-pre

从重新映射返回不会破坏队列 #588
合作者

我认为这也导致#579

从重新映射返回不会破坏队列 #588
合作者作者

我不认为它相关,它也会在没有 ON_ABORT_COMMAND 的情况下发生。

从重新映射返回不会破坏队列 #588 mozmck 将此 添加到 2.8里程碑 2019 年 5 月 18 日
从重新映射返回不会破坏队列 #588
贡献者

我运行了您的程序来重现此错误。感谢您提供清晰的步骤:通过“单击更改完成”和其他详细信息,我能够运行它DEBUG=2147483647并很快看到发生了什么。

Interp::read:|    G0 X10|
[...]
emcTaskPlanCommand(    G0 X10) called. (line_number=63)
execute:auto line='    G0 X10' mdi_int=0 o_type=O_none o_name=(null) cl=1 rl=1 type=*unset* state=CS_NORMAL
NML_INTERP_LIST(0x5624cf2c7a00)::append(nml_msg_ptr{size=128,type=EMC_TRAJ_LINEAR_MOVE}) : list_size=1, line_number=63

命令进入G0 X10队列。到目前为止,一切都很好。

[...]
Interp::read:|O300    return [-2] ; indicate probe contact failure to epilog|
In: read_o line:-1 |o300return[-2]; indicate probe contact failure to epilog| subroutine=|300|
global case:|300|
o_type:O_return o_name: 300  line:-1 o300return[-2]; indicate probe contact failure to epilog
return 300 value -2.000000
[...]
emcTaskPlanCommand(O300    return [-2] ; indicate probe contact failure to epilog) called. (line_number=64)
execute:auto line='O300    return [-2] ; indicate probe contact failure to epilog' mdi_int=0 o_type=O_return o_name=300 cl=1 rl=1 type=*unset* state=CS_NORMAL
convert_control_functions O_return
execute_return manual_change type=CT_REMAP state=CS_NORMAL
pycall(remap.change_epilog) 

unwind_call: call_level=1 status=INTERP_ERROR - error: 5 from execute emc/rs274ngc/rs274ngc_pre.cc:523
unwind_call leaving sub ''
unwind_call: reopening './nc_files/tcdemo.ngc' at 10
unwind_call: setting sequence number=0 from frame 1
unwind_call: exiting current sub 'manual_change'

emc/task/emctask.cc 405: interp_error: M6 aborted (return code -2.0)
M6 aborted (return code -2.0)
Interpreter stack: 	 - Python  - int Interp::handler_returned(setup_pointer, context_pointer, const char*, bool)  - int Interp::execute_return(setup_pointer, context_pointer, int)  - int Interp::convert_control_functions(block_pointer, setup_pointer)  - int Interp::_execute(const char*) 
[...]

O300 return [-2]行(实际上应该是o<manual_change> return [-2])从发出错误信号(负返回代码)的子例程返回,并且 interp 中止。

NML_INTERP_LIST(0x5624cf2c7a00)::clear(): discarding 1 items
on_abort reason=9 message='interpreter error'
unwind_call: call_level=0 status=INTERP_OK - 0 from reset emc/rs274ngc/rs274ngc_pre.cc:1758
Interp::read:[cmd]:|O <on_abort> call [9]|
In: read_o line:-1 |o<on_abort>call[9]| subroutine=|on_abort|
global case:|on_abort|

作为中止的一部分,中断列表被清除,解释了G0 X10命令消失的原因。

当正常的、未重新映射的块返回错误时,这实际上看起来与我们预期的完全一样:错误触发中止,为了安全停止运动并清除 interp 队列(包括任何排队的运动命令)。

M6我认为这个问题是关于NGC 子例程返回负结果以指示重新映射块中的错误而导致的反直觉行为。我们希望子例程执行子例程结束之前排队的所有内容,并且仅中止Q300 return. 相反,中止仅在最后一个队列破坏者之后发生,这可能是该块之前的许多块return [-2]

如您所示,在M66之前添加块return [-2]是一个很好的解决方法。

重新映射代码中的适当修复将捕获失败的重新映射产生的负返回代码,并在返回错误之前破坏队列。我认为这不应该在成功M6重新映射后发生,但对此可能存在争议。

查看第 198 行nc_files/remap_lib/python-stdglue/stdglue.py附近change_epilog()报告错误和产量INTERP_ERROR的位置。可能可以在此yield INTERP_EXECUTE_FINISH之前添加一个。几年前,我解决了一个问题,即 python 在 yield 太多次后重新映射 barfed,但我不确定它是否得到了非常严格的锻炼,所以 YMMV。

有 PR 和伴随的测试会很棒。

从重新映射返回不会破坏队列 #588
贡献者

再看一遍,队列破坏者的目标似乎不应该是所有重映射命令,而只是M6. 在这里破解特殊逻辑?

https://github.com/LinuxCNC/linuxcnc/blob/2.8/src/emc/rs274ngc/interp_convert.cc#L3079-L3091

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

还没有

发展

没有分支机构或拉取请求

4人参加
从重新映射返回不会破坏队列 #588从重新映射返回不会破坏队列 #588从重新映射返回不会破坏队列 #588从重新映射返回不会破坏队列 #588

喜欢 (0)