LUA脚本
1.1 本章简介¶
本章将介绍下载在控制器中运行的程序:Lua脚本程序。用户想要使用脚本程序,需要了解相应的语法,以及下载运行步骤。本章将一一介绍。
为了实现运控工艺实现灵活以及脱机运行,使用Lua脚本升级替换运动程序脚本。脚本程序的特点:易开发、独立、实时、并行。
1. 面向原型的编程语言,语法与C类似, 易于开发和调试。
2. 运动程序能够脱离主机在运动控制器上独立执行,主机能够将CPU资源分配给其它任务,从而将主机从繁琐的运动逻辑管理中解放出来。当然,如果需要,主机仍然可以在任何时候向控制器发送指令,即使运动控制卡器的运动程序正在执行。
3. 运动控制器上执行脚本程序由于不需要通过总线和主机进行频繁的数据交换,因此具有更高的实时性。和在主机上执行的应用程序不同之处在于,脚本程序对GTN指令调用不必再通过PC总线,因此具有更高的执行效率。逻辑指令平均执行速度小于0.3微秒/指令,GTN指令平均执行速度约为50微秒/指令。
4. 支持多任务,每个核允许多达8个脚本程序在运动控制器上同时执行。
提示
详细说明和测试可参考MotionStudio。
1.2 Lua脚本的使用¶
1.2.1 编写脚本¶
用户编写脚本程序时应遵照Lua语法及“1.4 Lua语法”中的说明,否则有可能编译不通过。
脚本程序可以和应用程序一样调用GTN指令。用户可查阅“5 可用程序指令”知道哪些指令可以在运动程序中调用。
1.2.2 指令列表¶
| 指令 | 说明 |
|---|---|
| GTN_ClearMp | 清除运动程序相关信息。 |
| GTN_DownLoadFileMP | 下载运动程序脚本。 |
| GTN_BindMP | 运动程序和task绑定。 |
| GTN_RunMP | 启动线程。 |
| GTN_StopMP | 终止线程。 |
| GTN_SetPublicInt32VarValueMP | 设置注册整型变量值。 |
| GTN_GetPublicInt32VarValueMP | 读取注册整型变量值。 |
| GTN_SetPublicFloat64VarValueMP | 设置注册浮点型变量值。 |
| GTN_GetPublicFloat64VarValueMP | 读取注册浮点型变量值。 |
| GTN_DownloadAxisRefMP | 下载轴相关参数。 |
| GTN_UploadAxisRefMP | 获取轴相关参数。 |
1.2.3 下载¶
使用GTN_DownLoadFileMP指令将文件下载到控制器,每个核最多可下载24个非同名文件,同名文件会覆盖原有文件。超过最大文件限制时会下载失败,需调用GTN_ClearMp清理已下载文件。
1.2.4 绑定线程¶
每个核可同时执行8个程序,需要使用GTN_BindMP将文件绑定到对应线程才可以执行该线程。
1.2.5 启动和停止¶
绑定线程后,可使用GTN_RunMP启动线程,以及GTN_StopMP停止线程。
1.2.6 注册变量¶
每个核具有50000个整型以及50000个浮点型数组变量用于线程间以及和上位机进行数据交互。
上位机可通过GTN_SetPublicInt32VarValueMP和GTN_SetPublicFloat64VarValueMP写入变量,以及GTN_GetPublicInt32VarValueMP和GTN_GetPublicFloat64VarValueMP读取变量。
代码中可直接使用GI(整型) 以及 GR(浮点型)调用数组。例:
1.2.7 轴参数¶
上位机可通过GTN_DownloadAxisRefMP和GTN_UploadAxisRefMP直接向控制器内读写轴参数,脚本中可作为对象直接调用。例:
1.3 lua语法¶
1.3.1 数据类型¶
lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
当前可用类型分别为:nil、boolean、number、string、userdata、function 和 table。
| 数据类型 | 描述 |
|---|---|
| nil | 只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
| boolean | 包含两个值:false和true。 |
| number | 表示双精度类型的实浮点数。 |
| string | 字符串由一对双引号或单引号来表示。 |
| function | 由 C 或 Lua 编写的函数。 |
| userdata | 表示任意存储在变量中的C数据结构。 |
| table |
Lua中的表(table)是一个"关联数组"(associative arrays)。 数组的索引可以是数字、字符串或表类型。 table的创建是通过"构造表达式"来完成,简单构造表达式是{},用来创建一个空表。 |
1. 字符串(String)
字符串是由数字、字母、下划线组成的一串字符。字符串可以使用以下三种方式来表示:
(1) 单引号间的一串字符。
(2) 双引号间的一串字符。
(3) [[ 与 ]] 间的一串字符。
| 转义字符 | 意义 | ASCII码值(十进制) |
|---|---|---|
| \a | 响铃(BEL)。 | 007 |
| \b | 退格(BS) ,将当前位置移到前一列。 | 008 |
| \f | 换页(FF),将当前位置移到下页开头。 | 012 |
| \n | 换行(LF) ,将当前位置移到下一行开头。 | 010 |
| \r | 回车(CR) ,将当前位置移到本行开头。 | 013 |
| \t | 水平制表(HT) (跳到下一个TAB位置)。 | 009 |
| \v | 垂直制表(VT)。 | 011 |
| \ | 代表一个反斜线字符。 | 092 |
| ' | 代表一个单引号(撇号)字符 ''\ '。 | 039 |
| " | 代表一个双引号字符。 | 034 |
| \0 | 空字符(NULL)。 | 000 |
| \ddd | 1到3位八进制数所代表的任意字符。 | 三位八进制 |
| \xhh | 1到2位十六进制所代表的任意字。 | 二位十六进制 |
2. 数组(Array)
一维数组实例:
多维数组实例:
3. 表(Table)
1.3.2 运算符¶
运算符是一个特殊的符号,用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 其他运算符
1. 算术运算符
下表列出了Lua语言中的常用算术运算符,设定A的值为10,B的值为 20:
| 操作符 | 描述 | 实例 |
|---|---|---|
| + | 加法 | A+B输出结果30 |
| - | 减法 | A-B输出结果-10 |
| * | 乘法 | A*B输出结果200 |
| / | 除法 | B/A输出结果2 |
| % | 取余 | B%A输出结果0 |
| ^ | 乘幂 | A^2输出结果100 |
| - | 负号 | -A输出结果-10 |
| // | 整除运算符 | 5//2输出结果2 |
2. 关系运算符
下表列出了 Lua 语言中的常用关系运算符,设定A的值为10,B的值为20:
| 操作符 | 描述 | 实例 |
|---|---|---|
| == | 等于,检测两个值是否相等,相等返回 true,否则返回 false | (A==B)为false |
| ~= | 不等于,检测两个值是否相等,不相等返回 true,否则返回 false | (A ~= B) 为 true |
| > | 大于,如果左边的值大于右边的值,返回true,否则返回false | (A > B)为false |
| < | 小于,如果左边的值大于右边的值,返回 false,否则返回 true | (A < B)为true |
| >= | 大于等于,如果左边的值大于等于右边的值,返回 true,否则返回 false | (A >= B)返回false |
| <= | 小于等于,如果左边的值小于等于右边的值,返回 true,否则返回 false | (A <= B) 返回 true |
3. 逻辑运算符
下表列出了 Lua 语言中的常用逻辑运算符,设定 A 的值为 true,B 的值为 false:
| 操作符 | 描述 | 实例 |
|---|---|---|
| and | 逻辑与操作符。 若 A 为 false,则返回 A,否则返回 B | (A and B) 为 false |
| or | 逻辑或操作符。 若 A 为 true,则返回 A,否则返回 B | (A ~= B) 为 true |
| > | 大于,如果左边的值大于右边的值,返回true,否则返回false | (A or B) 为 true |
| not | 逻辑非操作符。与逻辑运算结果相反,如果条件为 true,逻辑非为 false | not(A and B) 为 true |
4. 位运算符
下表列出了 Lua 语言中的常用位运算符,设定 A 的值为1,B 的值为 0:
| 操作符 | 描述 | 实例 |
|---|---|---|
| & | 按位与运算符 | A & B 为 0 |
| | | 按位或运算符 | A | B 为 1 |
| ~ | 按位异或运算符 | A ~ B 为 1 |
| >> | 右移运算符 | A >> 1 为 0 |
| << | 左移运算符 | A << 1 为 2 |
| ~ | 按位非运算符 | ~ A 为 0 |
所有的位操作都将操作数先转换为整数, 然后按位操作,其结果是一个整数。
对于右移和左移,均用零来填补空位。移动的位数若为负,则向反方向位移;若移动的位数的绝对值大于等于整数本身的位数,其结果为零 (所有位都被移出)。
5. 其他运算符
下表列出了 Lua 语言中的连接运算符与计算表或字符串长度的运算符:
| 操作符 | 描述 | 实例 |
|---|---|---|
| .. | 连接两个字符串 | a..b, 其中 a 为 "Hello " , b 为 "World", 输出结果为 "Hello World" |
| # | 一元运算符,返回字符串或表的长度 | #"Hello" 返回 5 |
1.3.3 变量¶
变量在使用前,需要在代码中进行声明,即创建该变量。Lua 变量有三种类型:全局变量、局部变量、表中的域。未使用 local 显式声明为局部变量的变量全部为全局变量,即使是语句块或函数内。局部变量的作用域为从声明位置开始到所在语句块结束。变量的默认值均为 nil。
1.3.4 循环¶
Lua 语言提供了以下几种循环处理方式:
| 循环类型 | 描述 |
|---|---|
| while 循环 | 在条件为 true 时,让程序重复地执行某些语句。执行语句前会先检查条件是否为 true。 |
| for 循环 | 重复执行指定语句,重复次数可在 for 语句中控制。 |
| repeat...until | 重复执行循环,直到 指定的条件为真时为止。 |
| 循环嵌套 | 可以在循环内嵌套一个或多个循环语句(while do ... end;for ... do ... end;repeat ... until;)。 |
循环控制语句用于控制程序的流程, 以实现程序的各种结构方式。Lua 支持以下循环控制语句:
| 循环类型 | 描述 |
|---|---|
| break语句 | 退出当前循环或语句,并开始脚本执行紧接着的语句。 |
| goto 语句 | 将程序的控制点转移到一个标签处。 |
1. while循环
- 格式
- 说明
- 实例
Statements(循环体语句)可以是一条或多条语句,condition(条件)可以是任意表达式,在 condition(条件)为 true 时执行循环体语句。
2. for循环
- 格式
- 说明
- 实例
var 从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 “执行体”。exp3 是可选的,如果不指定,默认为1。
实例:
3. repeat...until
- 格式
- 说明
- 实例
Condition(条件)在statements(循环体语句)末尾,每执行一次statements(循环体语句)进行一次判断。
4. 循环嵌套
Lua 编程语言中允许循环中嵌入循环。
实例:
1.3.5 流程控制¶
Lua 提供了以下控制结构语句:
| 语句 | 描述 |
|---|---|
| if语句 | if语句由一个布尔表达式作为条件判断,其后紧跟其他语句组成。 |
| if...else语句 | if语句可以与else语句搭配使用, 在if条件表达式为false时执行else语句代码。 |
| if 嵌套语句 | 可以在if或else if中使用一个或多个if或else if语句。 |
1. if语句
- 格式
- 说明
- 实例
在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,紧跟在 if 语句 end 之后的代码会被执行。false和nil为假,true 和非nil为真。Lua中 0 为 true。
实例:
2. if...else 语句
- 格式
- 说明
- 实例
在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,else 的代码块会被执行。
实例:
2. if嵌套语句
- 格式
- 实例
实例:
1.3.6 函数¶
1. 函数定义
- 格式
- 解析
Lua 编程语言函数定义格式如下:
optional_function_scope function function_name( argument1, argument2..., argumentn)
function_body
return result_params_comma_separated
end
optional_function_scope:该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。
function_name:指定函数名称。
argument1, argument2, ..., argumentn:函数参数,多个参数以逗号隔开,函数也可以不带参数。
function_body:函数体,函数中需要执行的代码语句块。
result_params_comma_separated:函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。
2. 实例
- 常用函数
- 函数作为参数传递
- 多返回值
- 可变参数
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
myprint = function(param)
print(param)
end
function add(num1,num2,functionPrint)
result = num1 + num2
-- 调用传递的函数参数
functionPrint(result)
end
myprint(10)
-- myprint 函数作为参数传递
add(2,5,myprint)
function maximum (a)
-- 最大值索引
local mi = 1
-- 最大值
local m = a[mi]
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
1.4 例程¶
例程
- Trap点位运动
- 插补运动