实时性
开发机器人控制器是个繁重的工作,要明确一系列性能要求,首先就是实时性。
如果问PLC或者机器人控制器与普通计算机的本质区别是什么,你会如何回答?是PLC更稳定吗,还是它的抗干扰能力更强、又或者是接口更丰富、或是编程语言更符合工业控制。笔者认为这些都不是,真正本质的区别在于PLC是实时的,而普通计算机不是实时的。家用电脑的信息处理能力可以轻松甩出PLC几条街(想想你玩大型游戏或者看高清视频的计算量),那么为什么工业上还是使用“落后的”PLC呢?答案就是实时性,实时性对于工业机器人来说是必须的(至于服务机器人笔者认为可以不强求)。一般人很容易错把“实时性”理解为计算速度快或者响应延时短,但其实“实时性”表示时间上的“确定性”,例如实时操作系统(RTOS)中的中断响应或者进程切换的延迟时间一定是在一个时间范围内,我们常用的操作系统(Windows、Linux)都不是实时操作系统,因为它们设计的出发点是大吞吐量,不能保证每个事件都在一定范围内得到处理。再比如,标准以太网的传输速度比实时工业以太网(比如EtherCAT)快多了,但是标准以太网却不是实时的,因为它同样不能保证数据在确定的时间内完成传输。
以上都是定性的描述,能不能定量说明呢?当然了,确定性肯定是有具体指标的,脱离具体数字分析实时性没有意义。如果我们将反应时间规定为1个小时,那么就连Windows这样的操作系统也是实时的了,因为它响应再慢也不会花一个小时。工业上很多场合1个小时显然是太夸张了,我们至少要缩小到10ms这样的量级,例如一个控制或插补周期执行时间不能超过1ms,这样Windows系统肯定满足不了要求。最近炒的比较火的5G通信技术可以将延时控制在1ms左右,虽然它也不是实时的,但是由于速度足够快所以也可以用于工业控制领域取代有线通信,这就是为什么5G这么火的原因。
理解实时性不太难,但是影响实时性的因素有哪些呢?这方面讨论涉及操作系统原理,各大机器人厂家肯定不会公开自己的测试和试验结果。评价实时性的主要指标是latency和jitter,jitter受到操作系统调度算法的影响很大,其它的例如系统负载也有影响,调度算法的影响大概是十微妙级的。jitter对机器人性能的影响不容易量化,因为中间环节有些复杂(底层伺服闭环)。
影响实时性的另一个主要因素是内存分配。动态内存的分配耗时非常不确定,这也是为什么很多实时系统都避免采用动态内存。这里我举两个例子:
1. 在PLC中不提供动态数组,只能用定长数组,也就是说使用之前必须先分配好数组长度。这显然很不方便,例如我们有时在函数调用时传递一个数组,而事先并不想考虑数组的大小。这样一来,我们只好计算好每次传递的数组长度,或者设置一个尽量大的数组,显然这会造成空间的浪费。
2. 如果你有过在MATLAB Simulink中编写S函数或者用户自定义函数的经历,你就会发现,S函数中要求你在使用变量之前必须先进行定义或分配空间,不能像在m文件中一样不事先定义就赋值(可以看这个MATLAB自带的例子:Integrate MATLAB Algorithm in Model)。因为Simulink中的模块是可以生成C语言并导出到硬件上直接运行的,这意味着它对实时性有要求。一些PLC,例如前面提到的菲尼克斯和倍福,都支持将Simulink中仿真好的控制模型直接生成为控制程序,而无需重新编程。难怪我们在Simulink中编写S函数的时候总感觉不像在MATLAB写程序那么自由随意。
高精度定时器
我们经常提到“实时”,实时需要高精度的时间标准,那么谁来提供这个高精度的时间呢?答案就是时钟周期,它是是实时操作系统的心跳(或者脉搏)。周期性采集数据、任务定时切换、延时输出,这些功能都要求实时操作系统必须要有一个稳定的时钟周期来作为整个系统的时间标准。
什么是时钟周期呢?时钟周期依赖一个定时器,它是个函数,其本质是一个计数器。定时器开始预先存储一个值,每次硬件(例如晶振)产生一个脉冲,就将这个值减一,减到0时再重置为初始值,同时产生一个中断,这个特定的周期性的中断称为“时钟周期”(Tick,有的也叫“时钟节拍”、“心跳”或“滴答”)。举个例子,假如晶振的频率是72MHz,则时钟周期(Clock Period)就是1/72M,如果预先存储的值是72000,那么时钟节拍就是1/72M × \times × 72000= 0.001s,也就说1ms产生一个中断,此时控制器无法分辨低于1ms的时间间隔。