下载中英双语离线手册(ZIP,8.7 MB,含原始分辨率截图)
前面已经讲过选择文件、运行程序和查看状态。这一组课程换到已有“教导”页面:选择指令、填写参数,先记录成一行行代码,最后生成文件,交给程序页面显示和使用。
我们用现成的“延时指令”走完这条路。它只有三个参数,便于把整个过程看清楚。读完后,你应当能找到某个教导项目的参数页、生成脚本和修改脚本,并理解它们为什么要配合使用。本篇不增加教导项目。
在顶部选择“教导”,再选右侧的“延时指令”。左边是已经记录的程序,右边是当前项目的参数,右下方是“生成代码行”。左下方的“保存”“打开”和“加载代码”另有用途,后面分别说明。
本次从空的教导程序开始。在自己的软件副本中练习时,如果左边已有需要保留的内容,先“保存”,再“新建”并确认清空。
按下面的值填写,输入时间后按回车提交:
| 页面位置 | 本次选择或输入 |
|---|---|
| 延时策略 | 单行延时 |
| 延时时间(秒) | 1.25,提交后显示 1.250 |
| 同一行的数据源 | 数值 |
| 程序行号左边的“选取” | 不勾选;右边的 1 因而不会加到生成代码中 |
点击截图可放大查看,原始分辨率图片见离线包。
总览图只用于找位置,具体文字和数值看下面的局部放大图。浏览器图文版还可以点击图片放大,用“+/−”调整大小,按 Esc 或“关闭”返回正文。
点击截图可放大查看,原始分辨率图片见离线包。
图 1a 右上角显示“仿真”。本例学习参数编辑和代码生成,不需要操作“移动/定位”等机床动作按钮。
按右下方“生成代码行”:
点击截图可放大查看,原始分辨率图片见离线包。
左边第 1 行出现:
G04P1250
点击截图可放大查看,原始分辨率图片见离线包。
这一步同时做了几件事:记住本行属于哪种指令,保存生成它时的参数,写入代码文字,再把当前位置移到下一行。图 2 中蓝色条在第 2 行,但已经记录的程序仍然只有一行。表格预先显示十个行位置,空位置不等于已有十行程序。
右边还显示 1.250,也不代表它与左边第 1 行始终相连。右边是正在准备的参数;左边是按下按钮时保存的结果。只改输入值,已经记录的行不会自动变化。
从操作上,可以按下面这条顺序读现有设计:
进入教导 → 选择延时指令 → 填写参数 → 生成代码行 → 在程序表中选回原行并修改 → 加载代码 → 程序页面显示 program.nc。
这条顺序对应的文件如下。表内路径都从运行目录开始,例如 env/teach/pause 指的是软件运行目录下的这个文件。
| 负责的事情 | 现有文件 | 本篇要注意什么 |
|---|---|---|
| 顶部“教导”入口 | env/maininterface/maininterface.ui |
先切换主页面,再运行进入脚本 |
| 把教导页面装入主界面 | env/teachpage |
这是实际入口,不是 env/teach/teachpage |
| 程序表、项目按钮、保存和加载按钮 | env/teach/teach.ui |
这些都属于同一个教导页面 |
| 选择某种指令时准备参数页 | env/teach/codeselect |
按当前项目号拼出 UI 文件名 |
| 延时项目的参数表 | env/teach/ui/teach_7.ui |
表格从参数中取得名称、数值和选项 |
| 按“生成代码行”后选择生成脚本 | env/teach/addcode |
延时项目走到 N7,再调用 pause |
| 保存本行参数并组成延时代码 | env/teach/pause |
页面上的秒数在这里变成代码文字 |
| 选回某一行 | env/teach/refreshnode1、parsenode |
把该行原先的参数填回右侧 |
| 保存、打开教导文件 | env/teach/savefile、openfile |
使用 .program 文件 |
| 按“加载代码” | env/teach/codeGenerate |
写入 .nc 文件并切回程序页面 |
不要被脚本名字带偏:界面按钮叫“加载代码”,它调用的脚本却叫 codeGenerate;pause 在这里是延时代码的生成脚本,不是操作面板的加工暂停按钮。
顶部“教导”的点击动作是:
-A:(clickedEvent:/env/teachpage[0](#810permission=4))
其中 #810.permission=4 使主界面显示教导区域。该入口及区域还受 #929.item[8] 控制;如果自己的标准配置没有显示“教导”,应先检查这个条件。
env/teachpage 前七行按当前功能键配置更新 #9995.itemdesc[0] 到 [6]。后半段负责第一次装入页面:
IF#837.version==1GOTO1
#837.version=1
#837.itemdesc[0]="/env/teach/teach.ui"
widgetFunc["QFrame","teachFrame","refresh",""]
widgetFunc["setWidgetAttribute","codeParamTable","",#1500.description]
N1
这里的 #837.version 记录教导外层页面是否已准备。再次进入时,脚本跳过这段准备。倒数第二行是原脚本保留的表格属性设置;本例实际使用的是后面装入的 codeParamTable7,不要把两个表格名称混为一谈。
再看“延时指令”按钮的点击动作:
-A: (clickedEvent:/env/teach/codeselect[0](#1500=6))
选择延时项目时,先把 #1500 设为 6,再运行下面这份完整的 codeselect 脚本:
#1500.channel=0
IF#[1800+#1500].version!=0GOTO3
#[1800+#1500].version=1
#[1800+#1500].itemdesc[0]="/env/teach/ui/teach_"+INT[#1500+1]+".ui"
widgetFunc["QFrame","teachFrame"+INT[#1500+1],"refresh",""]
N3
代入 #1500=6 就容易看懂:
| 原写法 | 延时项目实际用到的对象 |
|---|---|
#[1800+#1500] |
#1806,记录这个参数页的准备状态和文件名 |
"teach_"+INT[#1500+1]+".ui" |
teach_7.ui |
"teachFrame"+INT[#1500+1] |
原页面内的 teachFrame7 区域 |
外层页面准备一次,各项目的参数页也分别准备一次。env/main 在启动准备中重置相关状态;不是每次点击项目都重新定义参数。这里的 6 是从零开始的项目号,文件名中的 7 是它加一后的编号。
当前项目号在 #1500,而每个项目使用的参数号放在 #1500.item[...] 中。本例的对应关系是:
#1500 = 6
#1500.item[6] = 1513
上面是本次配置的读数,不是要求你重新执行的定义脚本。沿着这两个数值,就能找到延时项目的工作参数 #1513,以及配合控制选取等状态的 #1514。
| 参数位置 | 页面含义 | 图 1 中的值 |
|---|---|---|
#1513.item[0] |
延时策略 | 0,对应“单行延时” |
#1513.item[1] |
延时时间,单位为秒 | 1.25 |
#1513.itemversion[1] |
这一行的数据源 | 0,对应“数值” |
#1513.item[2] |
可选的程序行号 | 1 |
#1514.item[2] |
是否生成程序行号 | 未选取 |
teach_7.ui 的表格名是 codeParamTable7。它从 #[#1500.item[#1500]] 读取当前工作参数:.itemtitle 提供参数名称,.item 提供数值,相关字段决定使用输入框、下拉框或勾选框。因此,同一套组态写法可以配合不同项目的参数。
表格第四列的“数值/配方参数索引”选项来自语言文字参数 #1104.itemtitle[25]、[26]。选中哪个数据源,写到的是工作参数该行的 .itemversion;改变它后,refresh7 重新准备表格:
widgetFunc["QTableWidget","codeParamTable7","refresh",""]
这样,选择数据源和输入具体数值是两件相互配合的事。以图 1 为例,1.25 表示直接使用的秒数。如果改成“配方参数索引”,这个位置的含义就变成选择配方参数,不能继续把它当成秒数。
还有一个定制时容易忽略的地方:这张表用字段说明中的文字 可配置源 判断是否提供数据源选择。这是原组态参与判断的标记,不能把它当成普通显示文字随意改名。真正显示给操作者的标题则通过参数标题和语言包取得。
“生成代码行”的原事件为:
-A: (MouseButtonRelease:/env/teach/addcode[1])
addcode 开头先保证当前位置有一条可写记录,并取出当前项目的两组参数号:
IF#1551==-1THEN#1551.itemnum=1
IF#1551==-1THEN#1551=0
IF#1551>=#1551.itemnumTHEN#1551.itemnum=#1551+1
#11=#1500.item[#1500]
#12=#1500.item[#1500]+1
本例得到 #11=1513、#12=1514。后面的 ^11.item[1] 表示“先取 #11 中的参数号,再访问那组参数的第 1 项”,所以本例等同于 #1513.item[1]。
当 #1500==6 时,addcode 跳到 N7 并调用 /env/teach/pause。下面是这份生成脚本的完整内容:
#1551.itemversion[#1551]=7
#1551.itemtitle[#1551]="A"+^11.item[0]
#1551.itemtitle[#1551]=#1551.itemtitle[#1551]+"B"+^11.itemversion[1]
#1551.itemtitle[#1551]=#1551.itemtitle[#1551]+"C"+^11.item[1]
#1551.itemtitle[#1551]=#1551.itemtitle[#1551]+"D"+^12.item[2]
#1551.itemtitle[#1551]=#1551.itemtitle[#1551]+"E"+^11.item[2]
#1558.item[0]=""
#1558.item[2]=""
IF^12.item[2]==1THEN#1558.item[0]="N"+^11.item[2]
IF^11.item[0]==1GOTO1
IF^11.itemversion[1]==1THEN#1558.item[2]="P"+"INT[#1550.item["+INT[^11.item[1]]+"]*1000]"
IF^11.itemversion[1]==0THEN#1558.item[2]="P"+INT[^11.item[1]*1000]
N1
IF^11.item[0]==0THEN#1558.item[1]="G04"
IF^11.item[0]==1THEN#1558.item[1]="#1513=#9990.channel"
IF^11.item[0]==2THEN#1558.item[1]="G104"
#1551.item[#1551]=#1558.item[0]+#1558.item[1]+#1558.item[2]
#1551.itemdesc[#1551]=#1551.item[#1551]
#1551=#1551+1
#1551.channel=FIX[#1551/10]
widgetFunc["SysFunc","0","parser","/env/teach/parsenode"]
先沿本次选中的分支读,不必一次记住所有策略:
#1558.item[0] 保持空文字。"P"+INT[1.25*1000],得到 P1250。0,选择 G04。G04P1250,写入程序行和显示文字。+ 在这些语句中连接文字,INT[...] 在这里把结果按整数形式放入文字。秒数乘以 1000 是这份实际脚本的处理规则,不是从其他数控系统的习惯推出来的。
这份脚本还保留另外两种策略:1 生成时间戳赋值文字,2 生成 G104。如果数据源选“配方参数索引”,它保存的是包含 #1550.item[...] 的表达式文字,而不是立即把配方当前值代入。相关运行时规则需要结合加工解释器继续核查;本次界面操作只验证“单行延时+数值”这一支。
如果教导表只保留 G04P1250,以后就得从代码文字重新猜输入参数。现有设计在记录代码时,同时保存了用于编辑的资料:
#1551 中的位置 |
在这份组态里的用途 | 首次生成后的第 0 项 |
|---|---|---|
#1551 主值 |
当前准备写入或选回的记录位置,从 0 开始 |
生成后已经前进到 1 |
.itemnum |
已有记录数量 | 1 |
.itemversion[0] |
本行指令类型 | 7,延时 |
.itemtitle[0] |
供重新编辑使用的参数文字 | A0B0C1.250DfalseE1 |
.item[0] |
实际代码文字 | G04P1250 |
.itemdesc[0] |
左侧程序表显示的文字 | G04P1250 |
A 后保存策略,B 后保存数据源,C 后保存秒数或配方索引,D 后保存是否加行号,E 后保存行号。本次未勾选状态实际写成 false;不要擅自假设所有位置都会保存为整数 0。这里的 .itemtitle 用来保存编辑资料,并不是让操作者看到的行标题。
在图 2 的状态下,先把右侧时间暂时改为 9 并提交,但不按“生成代码行”。然后单击左侧第 1 行的程序体。这次选回后,右侧时间恢复为 1.250。恢复值来自该行已经保存的资料。
原表格点击事件把行位置交给 refreshnode1:
-A: (clickedEvent:/env/teach/refreshnode1[0](#1551=%%+#1551channel*10))
%% 是当前可见行的序号,从 0 开始;再加上页码乘 10,得到整张程序表中的位置。第 1 页的第 1 行就是记录 0。refreshnode1 在需要切换记录时调用 parsenode,其中延时分支如下:
N7
#11=#1500.item[6]
#12=#1500.item[6]+1
^11.item[0]=#1551.itemtitle[#1551]/"A"*"B"
^11.itemversion[1]=#1551.itemtitle[#1551]/"B"*"C"
^11.item[1]=#1551.itemtitle[#1551]/"C"*"D"
^12.item[2]=#1551.itemtitle[#1551]/"D"*"E"
^11.item[2]=#1551.itemtitle[#1551]/"E"
#1500=6
widgetFunc["SysFunc","3","parser","/env/teach/codeselect"]
GOTO100
例如 文字/"C"*"D" 取出 C 与 D 之间的内容,本例为 1.250。这些带文字的 /、* 是本系统的文字提取写法,和普通数字除法、乘法要结合操作数区分。
接着把恢复出的时间改成 2.5 并提交。此时右侧显示 2.500,左边仍是原来的 G04P1250:
点击截图可放大查看,原始分辨率图片见离线包。
同一时刻,程序表中选中的第 1 行仍是旧代码:
点击截图可放大查看,原始分辨率图片见离线包。
再按一次“生成代码行”,第 1 行才变为 G04P2500,记录数量仍为 1,选择位置再次前进到第 2 行:
点击截图可放大查看,原始分辨率图片见离线包。
“生成代码行”写入的是当前位置。 选中已有行时覆盖它,在末尾空位置时才增加记录。要在中间腾出位置,应使用“插入”,再填写、生成。
左下方的三个按钮应这样区分:
| 按钮 | 保存或读取什么 | 适合什么时候使用 |
|---|---|---|
| 保存 | 把 #1551 的记录及相关资料保存为 .program |
保留可继续编辑的教导程序 |
| 打开 | 从 .program 读回 #1551,再尝试恢复当前项目参数 |
继续修改以前保存的教导程序 |
| 加载代码 | 把各行代码写入 env/teach/doc/program.nc,然后在程序页面载入 |
查看、交接当前生成的 NC 结果 |
“保存”脚本先打开 *.program 文件选择窗口,取得文件名后执行:
widgetFunc["SysFunc",#1551.description,"saveParamItemAs1",1551]
“打开”取得路径后执行:
widgetFunc["SysFunc",#1551.description,"readParamItemFrom1",1551]
.program 保存的不只是代码文字,还包括类型、编辑参数等资料;它不是可直接当 NC 文件读的纯文本。另一页“配方参数表”使用 #1550,配方保存、读取另有 .formula 文件,不能因为保存了教导程序,就认为配方也一起打包保存了。
当前只有一条 G04P2500。按左下方“加载代码”,进入 codeGenerate:
点击截图可放大查看,原始分辨率图片见离线包。
脚本的第一行是:
widgetFunc["systemParamToFile",1551,0,"/env/teach/doc/program.nc"]
这里的 1551 是要输出的参数号,0 表示输出各记录的 .item 文字;空文字记录会被跳过。文件放在运行目录下的 env/teach/doc/program.nc,每次写入同一路径。它不会在这一刻重新运行各指令的生成脚本,所以必须先把需要修改的行重新“生成代码行”。
接下来原脚本把文件接入加工文件列表和文字显示:
#334.itemnum=0
#334.item[1]=#405+"teach/doc/program.nc"
#9047=#334.item[1]
#9048.channel=0
#9048.permission=widgetFunc["getFileLineNum","","",#9047]
#403=#9047
#333.item[1]=0
#333.item[13]=1
#405 在标准运行环境中指向运行目录下的 env/,末尾带 /。上面的路径应与实际输出文件一致。如果调整了运行目录或文件输出位置,输出、加载两处都要核对,不能只改其中一个。
随后脚本记录加载信息,并执行:
#810.permission=0
#810=0
这使界面切回“程序”下的“刀路预览”。与文件加载篇说明的一样,#334 保存加工文件列表,#403 是当前加工文件,#9047 提供给程序文字显示,#9048 记录显示位置和行数。原脚本还请求清除旧画板;加载文字与重新解释刀路仍应分开理解。
点击截图可放大查看,原始分辨率图片见离线包。
本次实际生成的文件只有 G04P2500 一行及行结束符;文字区下面显示的空白第 2 行来自末尾换行。输出脚本不会自动补程序头、结束指令或其他工艺动作。这是用来读懂组态过程的单行结果,不是一份完整加工程序。本次核对到文件写入和文字显示为止,没有启动 NC 执行。
掌握一条记录的来去以后,再看其他按钮就容易了:
| 原有操作 | 实际处理方式 | 定制时应注意 |
|---|---|---|
| 上一项/下一项 | 改变 #1551 当前记录位置,再恢复该行参数 |
当前位置还决定下次生成写到哪里 |
| 上一页/下一页 | 按每页十个位置改变页码及当前位置 | 不能只改表格显示行数而不改脚本中的 10 |
| 插入 | 在有效的当前位置插入一条记录 | 原脚本在末尾空位置直接结束;末尾可直接生成追加 |
| 删除 | 确认后删除当前记录,并恢复当前位置的参数 | 不只是清空表格中的显示文字 |
| 复制 | 把当前记录号记在 #1551.version |
此时没有独立备份该行内容;之后删行、插行可能改变这个记录号所指的内容 |
| 粘贴 | 从记住的记录号复制代码、编辑参数、显示文字和类型 | 写入当前位置,必要时扩展记录数;不是总在中间插入一行 |
| 新建 | 确认后把记录数量、当前位置和页码清零 | 它清理的是当前教导程序;不要推断它同时清空配方或磁盘文件 |
再次单击同一行时,refreshnode1 还可能进入 #9519 菜单分支。该行为有“上次位置和类型匹配”等条件,不是每次点击都会恢复参数;菜单内容还取决于对应参数的配置。本例选回第 1 行时,使用的是正常换行后的恢复分支。
“抓取当前位置”“记录点”“移动/定位”和“运行”也不能仅凭名称放在一起理解。有的入口读取坐标,有的会记录代码,有的会进入 NC 执行。遇到运动类教导项目时,应沿具体事件继续追到 localpos、custom/recordLinePoint、custom/local、custom/run 等脚本,确认它究竟做到哪一步。本篇没有操作这些动作。
这个已有实例给出了一个清楚的工作顺序:先让操作者填写参数,再把参数记成一条可修改的记录,最后输出代码。以后调整同类功能时,可以按下面的表逐项找文件,不必从 C++ 开始。
| 想调整的内容 | 先找哪里 | 还要一起核对什么 |
|---|---|---|
| 项目名称和参数标题 | #1500.itemtitle[...]、工作参数标题、语言包 |
中英文实际显示是否一致;判断用的固定标记不要当标题翻译 |
| 参数页显示内容 | 对应的 teach_*.ui 与工作参数定义 |
#1500.item[...] 是否仍指向正确参数组,辅助参数是否匹配 |
| 生成的代码格式 | addcode 对应分支及实际生成脚本 |
别只改显示文字;输出读取的是 .item |
| 某个参数怎样保存并恢复 | 生成脚本的 .itemtitle 写入和 parsenode 对应分支 |
保存、提取的字母分隔位置要配对;旧 .program 文件能否继续读取另行验证 |
| 新的一种教导项目 | 项目入口、参数对应表、UI、生成分支、恢复分支 | 不能只增加一个按钮;类型号与项目号的对应应逐项查证,不能都按“加一”推算 |
| 输出文件路径 | codeGenerate 的输出与加载语句 |
#405、#334、#403、#9047 指向同一个结果 |
常见问题可以这样查:
| 现象 | 先检查 |
|---|---|
| 右侧改了时间,左侧没变 | 是否提交输入后,又按了“生成代码行” |
| 想追加,结果改掉了原行 | 生成时 #1551 是否仍选在已有记录上 |
| 想改原行,却多了一行 | 是否先选回左侧原行;生成后当前位置会前进 |
| 代码看起来正确,选回时参数错误 | 本行 .itemtitle 的保存顺序与 parsenode 是否匹配 |
| 切换数据源后输入方式没变 | 是否触发对应的 refresh7,参数说明标记是否被误改 |
“程序行号”填了数,却没生成 N |
左边的选取框是否勾选 |
| “加载代码”仍得到旧时间 | 是否仅改输入框,尚未改写那条已记录代码 |
保存 .program 后换电脑,配方不一致 |
是否另行保存和加载了所需 .formula 配方 |
| 修改 UI 文件后,切走再切回没有变化 | 页面是否已准备过;原进入脚本会复用已装入页面 |
下一篇继续讲透教导中的表格:分页、配方编辑、行筛选、输入方式切换、刷新和格内位置按钮。随后连续学习直线与空间圆弧采点、配方引用和教导文件保存。
上一课:进度、提示与报警 · 下一课:教导表格 · 阅读目录