DXF专题:DXF页面与导入 → 孔位表与工艺 → DXF后处理 → G196扩孔实例
DXF后处理一章已经把“选中的孔”连到了“生成的NC行”。本章沿这条路线增加一种实际工艺,把新增选项、输入区、每孔参数、JS输出和NC宏程序接起来,继续使用同一个四孔DXF文件。
这次在原DXF页面增加第四种方式“G196 圆插补扩孔”。 配套文件已经包含参数定义、原生UI、生成脚本和O9196宏程序。原G81/G82/G83继续保留;新方式只接管值为3的孔。
下载完整学习示例包 · 查看完整NC宏 · 本例生成的完整程序
DXF圆心 + 每孔工艺
↓
加工方式选“G196 圆插补扩孔”,内部保存类型3
↓
后处理输出 G196X…Y…Z…R…D…I…Q…F…
↓
NC解释器调用 O9196,分层铣孔,返回R平面,M99返回
点击截图可查看原图。
图1 下拉框增加第四项,保存值依次为0、1、2、3。G196是本例自定义编号,不是标准组态原有的第四种钻孔方式。
点击截图可查看原图。
图2 沿用原来的孔表、圆心选择、筛选、保存参数和生成按钮。右侧仅增加一种工艺区;图中选中了第二个孔。
本例使用前面的四孔DXF,勾选圆半径为2的三个孔,以直径3的刀把底孔扩大到直径10。加工前必须已有直径不小于刀径、深度覆盖加工终点的底孔;工件表面设为Z0。 图中的三个小圆可以作为直径4底孔的位置图。第四个圆不勾选。
新工艺的“成品孔径 D”由输入框决定,并不直接取表格“孔径”列。原列实际保存圆半径,本例仍为2;成品孔径另设为10。这两者用途不同。
点击截图可查看原图。
图3 新工艺区沿用原有刀号、转速、孔底Z、R平面及进给字段,新增D/I/Q。中文“钻孔速度”是原字段名称,在本工艺中作为铣孔进给F使用。
可以按以下顺序重现这个例子:
G0Z10、M30。点击“生成G代码”,再点击“保存载入”,保存为 dxf-g196.nc。G21G90G17G40G49G80G94G15
G54
G0Z10
示例按毫米、XY平面、绝对坐标和每分钟进给编程。刀号0沿用原后处理的规则:不输出换刀与G43刀长补偿,需预先装好刀具并建立本例所用工件坐标。R2和程序头的Z10必须能够避开实际工件、夹具及转移路径。图中的转速、进给和切深是教学数值,应按刀具、材料和机台调整。
点击截图可查看原图。
图4 每个勾选孔生成一条G196,第二孔为Z−7,另外两孔为Z−5;第四孔没有生成加工调用。
第二孔的调用如下,完整程序另见本章开头的下载链接:
G80
G90G17G21G94G40G15
G196X40.000Y10.000Z-7.000R2.000D10.000I3.000Q2.000F600.000
G80
点击截图可查看原图。
图5 生成程序在原NC解释器中展开O9196后的刀路预览。白色圆线是刀具中心路径,蓝色线连接各孔;显示的是路径,不是材料去除后的孔壁。俯视时不同Z层的圆线重叠。
第二孔的切削层为Z−2、−4、−6、−7,最后一层只再下1;另两孔为Z−2、−4、−5。各层最外圈的刀具中心半径为 (10−3)/2=3.5,加上刀具半径1.5后,对应成品孔半径5。
学习包按软件运行目录组织,env与extScripts放在同一级。先关闭学习副本,再将包中同名文件合并到该副本中;保存原文件和参数配置以便恢复。已有定制工程应按下面的修改点合并,不能用示例文件覆盖已有改动。
| 文件 | 在本例中做什么 |
|---|---|
env/dxfpage |
在创建DXF页面前补齐参数、选项和当前语言文字,然后执行原页面加载逻辑 |
env/dxf-custom/init |
单独列出上述初始化语句,便于阅读和移植;同样语句已直接放入dxfpage,不需要再调用一次 |
env/dxf/dxf.ui |
在原三个工艺区旁增加 boreFrame,使用原生QLabel、QLineEdit与网格布局 |
env/dxf/dxfloader |
保留原导入及赋值循环;在有效孔存在后选择第一孔,刷新孔表选项 |
env/dxf/generatecode |
保留原字段拼接;当生成函数返回空文本时,清空旧程序并提示检查参数 |
extScripts/processComplexVerticesMap.js |
增加 buildCustomBore,将类型3交给它;其他方式继续走原分支 |
env/slib-dxf-custom.nc |
登记O9196,提供G196的实际NC工艺 |
使用前核对G196、O9196及 #6013~#6015在目标工程中没有其他用途。初始化只把本例原有的10项扩展为13项,保留前10项;再次进入页面时不重置已保存的D/I/Q。首次扩展若发现项数不符合预期或新增参数已有子项,会提示参数分配冲突,应先合并定义。已有13项的工程也要确认其后三项确属本例。
新增库文件位于 env 顶层,启动时登记。修改库后可在NC空闲时由主脚本执行:
widgetFunc["SysFunc","","ReloadSystemLib",""]
这条命令只负责重新登记NC库。UI、参数和后处理仍由各自文件负责,不会因重载库而自动增加。
dxfpage中的初始化直接接在原加载逻辑之前,保证创建控件时选项和参数已经存在。这里不通过另一个解释器异步启动初始化。新增文字根据 #9980.item[2]选择中文或英文;学习时先选择界面语言,再进入DXF页面并导入图形。
中文选项为:
#6002.itemunit[0]="G81钻孔<<G82钻孔<<G83钻孔<<G196 圆插补扩孔"
英文选项为:
#6002.itemunit[0]="G81<<G82<<G83<<G196 Circular Bore Milling"
原导入循环把这些文字复制到 #6003.itemunit[p]。表格选择第四项,写入的仍是 #6003.item[p]=3。G196是指令号,3是页面中的选择值。
新增 boreFrame使用以下显示规则:
-C(#9048version>=0&⍘version<#6001itemnum&ᝳitem[#9048version]==3)
-V0
条件中的 #9048.version仍是原始孔号。切换列表或视图中的孔,新工艺区与原工艺区一样跟随这个孔号;不另建一套选孔状态。
| 新输入 | 默认值与位置 | 每孔值 | 控件名 | JS位置 |
|---|---|---|---|---|
| 成品孔径 D | #6002.item[10]=10 |
#6013.item[p] |
boreDiameter |
parts[11] |
| 刀具直径 I | #6002.item[11]=3 |
#6014.item[p] |
boreToolDiameter |
parts[12] |
| 每层切深 Q | #6002.item[12]=2 |
#6015.item[p] |
boreStep |
parts[13] |
这三个默认项设置为实数类型 itemtype=2,单位为mm。例如成品孔径输入的描述为:
-T(#6013item[#9048version])
-D
原导入脚本按 #6002.itemnum循环,分配 #[6003+项号]并复制默认值;原“保存参数”按相同项数把当前孔复制回默认值;生成脚本也按相同项数拼接。项数从10变成13,三条路线就一起接收新增数据,不需要在C++中新增参数接口。
G82的停留、G83的啄孔深度和间隙仍保留原位置。新工艺不用它们,也不使用“钻孔完成时停留位置”;本例始终返回R平面。以后切回G81/G82/G83时,旧数据的含义没有改变。
导入末尾只刷新 entityTable,让下拉项按新孔数据建立。不要在“导入DXF”按钮自己的事件中直接销毁并重建整个 dxfframe,否则也会销毁仍在处理该事件的按钮。标准工艺退刀选项的整页刷新方法仍见孔位表一章第5节,在独立主脚本中执行。
完整生成函数已放入包中的后处理文件。在原 processDrillKey开头只增加这一条分派:
if (key.split(":")[1] === "3") return buildCustomBore(key, outerArray);
原十项后面追加D/I/Q后,第二孔的数据形状如下:
{
"drill1:3:0:1000:0:-7:2:1:2:1:600:10:3:2": [
[ { "x": 40, "y": 10, "z": 0 } ]
]
}
JS读取 parts[11..13],检查 D>I>0、Q>0、F>0、Z<0、R>0,再为每个圆心输出G196。原总处理继续负责刀号排序、换刀及主轴语句。输入不满足条件时不保留上一次成功生成的程序;修正输入后重新生成。
调用前后各放一行G80。前一行取消已有固定循环,后一行取消本例自定义指令的续效状态。本系统M99会恢复调用前的G组,不能仅凭宏内最后执行过G0就认为外层G196已经取消。也不要把 G80G196...合并在同一行,G80所在组会影响该行的分派路线。
本系统通用扩展将G196映射到 9000+196,即O9196。这里用到的传参表如下:
| 编程字 | O9196局部变量 | 本行明确给出的标志 |
|---|---|---|
| X、Y、Z | #0、#1、#2 |
#22、#23、#24 |
| R | #9 |
#31 |
| D | #14 |
#36 |
| I | #6 |
#28 |
| Q | #13 |
#35 |
| F | #15 |
#37 |
标志为1表示本行明确给出。宏入口还检查 #56=1(绝对坐标)、#57=1(毫米单位倍率)、#58=17(XY平面)。Z在 #2,R在 #9;不能照抄G81专用宏的传参位置,也不能用普通M98调用来替代这条G196。
完整文件中的入口检查之后,将输入复制到 #60~#67,后续计算使用 #68~#71,避开本次通用扩展占用的 #0~#58。核心切削段如下;入口检查及错误出口见完整宏文件。
#60=#0
#61=#1
#62=#2
#63=#9
#64=#14
#65=#6
#66=#13
#67=#15
#68=[#64-#65]/2
#69=#65*0.4
#70=0
G80
G90G17G40G94G15
G0Z#63
G0X#60Y#61
G1Z0F#67
WHILE#70>#62DO1
#70=#70-#66
IF#70<#62THEN#70=#62
G1Z#70F#67
#71=0
WHILE#71<#68DO2
#71=#71+#69
IF#71>#68THEN#71=#68
G1X[#60+#71]Y#61F#67
G3X[#60+#71]Y#61I-#71J0
END2
G1X#60Y#61
END1
G0Z#63
读这段程序时抓住两个循环:
(D−I)/2;本例每次增加 0.4×刀径。刀径3时,依次切半径1.2、2.4、3.5的圆。最后一步同样截到目标半径,避免超出成品孔径。内层先沿X走到该圈的起点,再用G3绕一整圈。外层结束后回孔中心并快速抬到R。外面的JS传入I时,I表示本例规定的刀具直径;宏内部G3行中的I则表示圆心相对起点的X偏移,所以这里写 I-#71。两层指令使用同一个编程字,含义由各自指令确定。
这是一种便于学习的分层、同心圆扩孔工艺:切削步距固定为刀径的40%,使用给定F,也没有另设精加工余量。需要更细致的工艺时,可以沿同一路线再增加径向步距、精加工余量或独立下刀进给;底孔条件也应随所用刀具和进刀方式重新设计。
参数不满足约定时,宏在任何本例移动之前写入 #9997提示,并设置 #319.item[6]=1终止执行,防止后面的主程序继续走。正常路径和错误路径最终使用同一个M99;库结构扫描以M99结束O程序,不要在中间放一个M99后再写属于该宏的错误分支。
铣螺纹可以继续追加类型4和一个未占用的扩展G号。保留孔位、筛选与排序,另加螺距、有效螺纹直径、刀具直径、旋向、进退刀等参数,分别接到默认定义、每孔输入、工艺字符串、JS和NC宏。螺距不沿用G82停留时间乘1000的处理;螺旋刀路则由新宏明确实现。
本例可复用的是已有页面 → 每孔参数 → 指令生成 → NC工艺的接入过程。下一种工艺仍应先把单孔宏做完整,再接入DXF批量孔位。
| 现象 | 优先检查 |
|---|---|
| 新加工方式没有出现对应参数区 | 表格是否写入正确的 #6003.item[p],右侧条件使用的是否同一个原始孔号 |
| 新方式显示了名称,却没有生成加工行 | JS是否按保存的类型值3分派;只追加选项文字不会增加输出规则 |
| 已生成G196,执行时找不到O程序 | O9196是否存在、是否重号、slib文件是否位于库目录顶层,以及修改后是否重新登记库 |
| 自定义G代码读取的孔深或孔径不正确 | 按通用扩展参数表取值,并核对追加工艺字段顺序;不要套用固定循环或普通M98的参数表 |
沿这套接入过程增加其他工艺时,先确定单孔程序及其输入,再逐项接回选项、每孔参数和后处理。上面的学习包保留完整文件,可按文件对照修改位置。