1.1 简介
ACSPL+是一款强大的编程语言,开发出来主要用于SPIIPLUS运动控制器。包含一些高级特征编程元素,比如算术和逻辑表达式,用户自定义的局部或全局变量,用户自定义的一维或二维数组。SPiiPlus ACSPL+有如下功能:
- 32个程序同时执行
- 程序隔离,每个程序在各自的缓存中
- 支持多种电机类型
- 主从模式电机的高级实现
- 轴独立无关的编程
- 基于条件触发的自动子程序
而且还提供了各种库供各种高级语言使用。
1.2 SPIIPlus架构
1.2.1 硬件架构
SPiiPlus控制器的硬件架构示意图如下,
运控处理单元MPU,执行大部分的控制器任务,是一款强大的X86架构的处理器。MPU作为Ethercat主站,伺服处理器SP,是作为Ethercat从站。一个主站可以连接多个从站。
MPU运行编译好的ACSPL+程序,生成路径规划命令给到下面的多个SP。它的主要工作包括:
- 与从站SPs通信
- 路径规划生成(APOS的计算)
- 参考位置(RPOS)的计算
- 安全控制
- 数据收集
- 位置事件生成PEG
- 索引处理和Mark输入
- 执行ACSPL+程序
- 串口和以太网通信
- 执行主机下发的即时命令
- 其他日常事件维护
MPU装备有Flash,Flash是非易失的存储器,即使掉电也能保持原先存储的数据。
SP执行实时任务,比如实时控制算法的实现,每个SP可以控制4个轴。SP包含所有必须的外设,保障高性能的控制电机轴。
单个MPU可以管理多个从站单元,通过Ethercat总线扩展,比如下面的拓扑连接,
1.2.2 用户应用程序
- 固件、应用程序和工具
- 固件是存在Flash中的一段小程序,用来定义控制器的基本功能,比如:准备,存储和执行我们的应用程序
- 应用程序是根据执行机构来定制控制器行为。控制器可以控制不同轴,机械构成,时序要求的各种控制对象。我们的程序就是要指定确切的运控和监控这些不同条件下执行的动作,包括:运动序列,输出的激活,输入的响应,与操作员的交互。
- SPiiPlus工具就是一些基于windows的应用程序,比如初始化和调控
- 用户应用程序成分
下图灰色部分展示了用户应用程序以及相关部分
- 基于主机Host的程序
用c,c++或其他编程语言写的程序,运行在主机上与控制器通信。主机程序通过使用通信通道:串口,以太网,FIFO,DPRAM。程序发送命令给控制器,并从控制器读回数据。
- ACSPL+的程序
ACSPL+命令序列可以下载到控制器中。总共有10个缓存留给ACSPL+程序。一个ACSPL+程序在控制器内部严格按时序运行,没有通信延时的影响。ACSPL+程序一般出现在用户程序中。
- 配置变量
固件中包含一些预先定义好的变量,这些变量可以被ACSPL+与即时命令使用。配置变量就在这些预定义变量中,比如ACC,定义了加速度。
- SP程序
固件包含作为控制器标准一部分的SP实时控制程序。
- 用户应用程序分类
- 单独的应用程序
仅仅由存储在flash中的ACSPL+程序来启动和运行应用程序功能。
- 主机驱动的应用程序
没有ACSPL+程序。主机发送指令,由控制器执行。这类应用程序仅仅适用于非实时型程序。
- 混杂程序
基于主机的程序加上一个或多个ACSPL+程序。大部分应用程序属于这一类。
- SPiiPlus MMI 应用程序套件
应用套件主要有如下作用:
- 程序管理器
- 电机运动管理器
- 通信终端
- 示波器
- 变量管理器与查看
- SPiiPlus中用到的文件扩展名
文件扩展名 |
存储内容 |
SPiiPlus MMI 相关组件 |
.acsw |
Workspace configuration |
Workspace |
.awd |
Drive database |
Adjuster Wizard |
.awf |
Feedback database |
Adjuster Wizard |
.awm |
Motor database |
Adjuster Wizard |
.frf |
FRF data |
FRF Analyzer |
.log |
MMI log files |
All components that generate logs |
.par |
Controller parameters |
Configuration Wizard |
.prg |
ACSPL+ Program |
Program Manager |
.rtf |
Print to file |
All components that enable printouts |
.sgn |
Scope data |
Scope |
.spi |
Application (includes controller parameters + adjustment parameters + ACSPL+ program + SP files) |
Upgrade and Recovery Wizard |
1.2.3 编程资源
- 命令
- 终端命令
- 缓存命令
- 程序缓存
- 声明缓存
- 命令执行
- ACSPL+标准变量
- 用户自定义变量
- 非易失存储器和启动进程
1.2.4 执行ACSPL+程序
- 单个程序执行
#0X 执行Buffer0中的程序
控制器从第一行命令开始执行。控制器执行程序基于如下简单模型:
- 每个程序行在一个控制器周期内完成,即使是一行有多个命令
- 如果程序是线性的,也就是说没有程序跳转命令,比如goto,也没有自动子程序。那么第一行命令在第一个控制器周期内完成,第二行在第二个控制器周期内完成。
- 不少命令可以延迟程序执行,比如命令:
WAIT 50 //将执行50毫秒,而不是一个控制器周期
TILL ^MST(0) //提供了延迟执行直至轴0运行结束
- 并发执行
假定在buffer0,1,2中的程序是线性的,不包含延时执行的命令。命令启动后,程序以预期的行为执行:一个控制器周期执行一行。
1T:
2T: 2nd line@buffer0 /2nd line@buffer1/ 2nd line@buffer2
......
如果有一个程序包含流程控制程序,它的执行不影响在其他buffer中运行的程序,因为它们是独立的。
- 即时执行
控制器在另一个没有连到任何buffer中的线程中执行通信通道命令。也就是说控制器提供了64+1个线程给ACSPL+程序执行用。64个线程给程序buffer用,另外一个线程预留给通信通道给即时命令执行用。
执行模型也适用于通信通道,一般一个命令一个控制器周期。
执行顺序是
- 即时执行和程序存储
控制器提供三种选项来执行ACSPL+命令:
1)即时执行命令
2)将程序存储在一个缓存中,然后再作为ACSPL+程序执行
3)在动态缓存中执行
如果控制器提示:No program buffer is open for editing,那么ACSPL+程序将传输到控制器立即执行
如果控制器提示包含行数,比如:2:00001》, 程序缓存用于开放,用来编辑ACSPL+命令。那么程序就会通过通信通道传输并存储到开放缓存中。
- 自动子程序执行
自动子程序是ACSPL+程序的一部分,可以被加载到任意的程序buffer中。任意的ACSPL+程序可以包含从0到任意数目的自动子程序。一个放置在缓存中的自动子程序与其他子程序以及ACSPL+共享局部变量和线程。
如果一个缓存包含一个或多个自动子程序,执行模型与上述描述情形稍微修改一下。在每个控制器周期里面,在每行命令执行前,先检查所有自动子程序的条件是否满足。如果满足,则先执行自动子程序中的代码,也就是说,自动子程序中断了同样buffer中的程序的运行。一个buffer中的自动子程序并不会影响到其他buffer中的程序或自动子程序的运行。
自动子程序提供了对外部或内部事件的中断响应机制。具体请查看自动事件章节。
- 同步与互斥
尽管控制器提供了并发程序的独立执行,应用程序常常需要在某个点,它们的子部分能够同步。控制器提供了一个简单而且灵活的方法来解决同步问题。ACSPL+程序的一行不仅仅是并发执行的单元,而且它还是互斥的单元。也就说,一行ACSPL+程序的执行不能由其他并发程序或自动子程序中断。
于是,一行ACSPL+提供了自动执行单元。假设一行ACSPL+程序包含了任意数目的ACSPL+命令,多个全局变量可以用来解决多个同步任务。
- 互斥
互斥在同步任务中经常使用,
global int Mutex Variable Mutex implements semaphore
. . . . . Any program actions
TILL ^Mutex; Mutex = 1 Enter critical section
. . . . . Critical section
Mutex = 0 Exit critical section
注意上面的两个命令一定要在同一行
TILL ^Mutex; Mutex = 1
- 同步
假设两个程序在大部分时间里面异步执行,但是必须有一段代码必须在同一个时间执行。这样在每个程序就必须保障任意一个程序到达这个点后,就等待直到另一个程序到达。然后在下一个控制器程序周期中同时执行,这个问题可如下构造解决:
global int Sem The SEM
. . . . . Asynchronous part of the program
Sem = Sem+1; till Sem = 2; Sem = 0 Synchronization point
. . . . . The line will be executed synchronously
同样的信号量变量定义和同样的同步点必须在两个程序中保持一致。
不管两个程序中哪一个先到达同步点,它必须等待直到TILL SEM=2. 后面的SEM=0 提供了重新应用这个构造的可能。
这个解决方案可以拓展到三个或更多的并发程序。
- 执行速率
在上面的执行模式中每个缓存中的程序执行速率是一样的。每个控制器周期运行一行命令,其实可以设置不同速率。ACSPL+中的变量PRATE和ONTRACE可以指定一个控制器周期可以执行多少行命令,最大不能超过10.
可以用#U命令来查看控制器的负载,一般不能超过90%
1.3 ACSPL+ 概览
- ACSPL+语法
命令是ACSPL+最小执行单位
一个程序行包含一个或多个命令,命令之间用;分隔。
v0= v1+ 2*(v2-v3)
v0 = v1 +2*(v2-v3); v4=0
空格可以任意插入命令之中;但不可以插入到关键字或变量名中。
另外还有命令块,它是以特殊命令开头,以END结尾。
- 变量
变量有如下属性:
- 名字
- 类别:标准或用户变量
- 范围:全局或局部
- 生命周期
- 存取权限:读写,可读,保护
- 类型:整形,实数型,或矩阵
- 大小
- 值
1)变量名
变量名要遵循一般的语法规范,用户自定义的变量,必须显式声明:
int Var1, Var2 !Declare local variables Var1 and Var2
global real RealVar !Declare global variable RealVar
2)变量类别
分为ACSPL+ 或用户自定义变量
ACSPL+内部变量不需要显式声明;
用户自定义变量需要显式声明。变量声明可以作为ACSPL+程序的一部分。也可以作为即时ACSPL+命令的一部分,只有全局变量才能用在命令终端中。
3)变量作用范围
变量分为局部变量和全局变量
全局:
Global real GlobVar !Declare the GLOBVAR
局部:
Real LocVar
与下面的声明一致,
Local real LocVar
4)变量生命周期
所有ACSPL+自身的变量的生命周期是与控制器固件一样的,也就是说从系统启动到系统关闭,变量都可以访问。
用户自定义变量是合法的当且仅当包含它的程序的编译过状态。
5)变量存取权限
所有用户自定义变量都是可读写的,没有任何保护
一个ACSPL+变量可以属于下面的类别中的一种:
读写:可在任意时刻赋值,比如VEL(速度) 和IST(索引状态)
可读:不能赋值,比如RPOS参考位置, FPOS反馈位置, MST电机状态
保护:受保护的变量,一般指那些配置变量,只有在配置状态下才可以赋值,比如ENTIME使能时间,和XACC最大加速度。
6)变量类型
变量类型有整数和实数
int Var1 !Declare Var1 integer variable
real Var2 !Declare Var2 real variable
Var1 = Var2 !Controller automatically converts real to integer
Var2 = Var1 !Controller automatically converts integer to real
7)矩阵类型
ACSPL+从版本3.10起支持MATRIX类型。MATRIX是2维实数数组。
语法:
MATRIX A(N)(N)
MATRIX B(N)(M)
例子
MATRIX A(2)(2) !define a square matrix of 2*2 size
Matrix在编译时间初始化
!///Compilation-time initializations///!
MATRIX A(2)(2)=((1,2),(3,4)) !Regular initialization of a 2x2 matrix
!///Compile-time initializations///!
MATRIX C(2)(2) !Default initialization, filled by zeros
8)字符串类型
ACSPL+支持STRING 原语。String类型声明为一个常数的buffer长度。所有赋值或修改字串,必须在这个事先声明的长度范围之内。
可以支持字串和字串数组(1维)
字串支持如下操作:
- 字串连接,
符号+算子支持字串的连接,例子,
String s1(12) = "Hello"
s1= s1 + " World"
DISP s1
- 字串比较
支持=与<>
相等算符=的例子,
String s1(8) = "abcde"
if (s1 = "abcde") DISP "EQUAL" ELSE DISP "NOT-EQUAL"
END
不等算符<>的例子
String s1(8) = "abcde"
if (s1 <> "abcde") DISP "EQUAL" ELSE DISP "NOT-EQUAL"
END
- 字串标准变量
支持三个标准字串变量:
SN:控制器的序列号
PN:控制器的批号
VR:控制器固件的版本
9)变量大小
变量可以是标量,一维或二维数组。
int ScalarVar !Declare the ScalarVar variable as a scalar variable
global real Ar1(100) !Declare Ar1 as a global array of 100 real numbers
int Ar2(10)(200) !Declare Ar2 as a 10x200 matrix of integers
10)变量值
值是变量的唯一属性。大部分是通过显式赋值来改变变量。只读变量是隐式修改的,比如FPOS,控制器在灭个控制器周期来更新。
- 变量声明
全局变量的声明
global int Var1 Var1 is declared as a global integer variable
global real Var2, Var3 Var2 and Var3 are declared as global real variables
global int Var4, Var5(2)(100) Var4 is declared as a global integer variable and Var5 is declared as a two-dimensional array of integers
永久全局变量
在终端上发送的全局变量,可以用#VGV清除
- 数组和索引
- 复合数据结构
- 使用变量
- 函数
- 带参数的函数
- 表达式
- 命令