| 作者 | 主题 |
|---|---|
|
伊默 至圣
经验值:19233 发帖数:4257 精华帖:118 |
楼主
主题:斜坡函数与扫描周期的事情... ...
以前都是自己写了个FB块实现斜坡函数功能。 比如控制一台机器线速度为150m/Min, 而设定加速度为30m/Min/s , 那么程序控制输出在5秒时间(150/30)将输出线性增加。
I can do it
|
|
westcowboy 奇侠 经验值:6746 发帖数:833 精华帖:46 |
2楼
主题:回复:斜坡函数与扫描周期的事情... ...
Let's build the automation future!
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
4楼
主题:回复:斜坡函数与扫描周期的事情... ...回到这个问题本身。 原来论坛上也有过几个贴子,问起如何计算1500/1200的扫描周期。 其中一个方案就是用RD_SYS_T指令读取当前系统的时间, 然后两个扫描周期读取的时间用T_DIFF指令做减法,就计算出来扫描周期了。 #iTMP_Int0 := RD_SYS_T(OUT=>#ACTUAL_TIME); //读取当前系统时间 #rDELTA_TIME := 1.0E-3*DINT_TO_REAL(TIME_TO_DINT(T_DIFF(IN1:=#ACTUAL_TIME, IN2:=#LAST_TIME))); //两次调用之时间差(S) #LAST_TIME := #ACTUAL_TIME; //为下一次调用做准备 #rDELTA_TIME就是计算出来的扫描周期了(单位:秒) 然后按照我顶楼提出的问题, 加速度度为30,目标速度150。 那么每个扫描周期我的速度增量为30*#rDELTA_TIME, 每个扫描周期将输出叠加,直到达到目标速度150为止 看起来,思路和程序都完全没问题? 而且这个块我也用了有几年了!!! 可是昨天在调一台小机器的时候,忽然发现不对劲。 我在触摸屏上有显示当前目标速度的,触摸屏对应的变量刷新周期为一秒, 那么原则上我在触摸屏上观察到的目标速度应该是以30为增量了,比如第一眼看到12,那么第二个数据应该是42,第三下就是72。。。。 可是事实却是每次增加20多点..... 这是为何???
I can do it
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
6楼
主题:回复:斜坡函数与扫描周期的事情... ...我吼了几嗓子,结果没什么人起哄呀... ... 我本来是想带节奏的,结果被ZANE版带沟里去了 ^_^ 算了,我还是自己写出来吧。 #iTemp0 := RD_SYS_T(OUT=>#ACTUAL_TIME); //读取当前系统时间 #rCycleTime := 1.0E-3*DINT_TO_REAL(TIME_TO_DINT(T_DIFF(IN1:=#ACTUAL_TIME, IN2:=#LAST_TIME))); //两次调用之时间差(S) #LAST_TIME := #ACTUAL_TIME; //为下一次调用做准备 对照图片,DTL数据类型可以读取到 纳秒单位。 而事实上T_DIFF指令是将两个DTL类型做减法,可是结果却只保留到 毫秒 单位! 毫秒就毫秒吧,最“可怕”的却是它的减法不是四舍五入,而是去尾留整!!! 比如我的扫描周期为2.1ms,它计算出来的结果显示为2ms, 扫描周期为2.99毫秒,它也显示是2ms ! 这就尴尬了.... .... 当我在加速过程中,PLC的扫描周期平均为2.6ms时,计算的最终结果也还是2ms, 意味着,我的实际加速度就变成了 30 * 2 / 2.6 = 23 ... ... 问题就是这么出来的... ... 嘿嘿,怎么解决???
I can do it
|
|
西山炮台 侠圣 经验值:2827 发帖数:148 精华帖:7 |
7楼
主题:回复:斜坡函数与扫描周期的事情... ...假设ACTUAL_TIME.NANOSECOND的取值范围为0-1000,则: //////////////////////////////////////////////////////////////////////// NOW_TIME:=ACTUAL_TIME.NANOSECOND;//获取当前的毫秒数 IF (NOW_TIME>= LAST_TIME) #rCycleTime:= NOW_TIME - LAST_TIME;//毫秒数未溢出时 ELSE #rCycleTime:= 1000-(LAST_TIME - NOW_TIME);//毫秒数溢出时 END_IF LAST_TIME := NOW_TIME;//为下一次调用做准备 //////////////////////////////////////////////////////////////////////// 以上是个人想法,可以根据实际情况,灵活变更下。 既然系统是自动的取整(不进行四舍五入),那就自己做计算咯 |
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
10楼
主题:回复:斜坡函数与扫描周期的事情... ...@西山炮台 思路正确,结果错误 @kayome 中断可以,但不是最好的方法。 一是中断占用程序资源,当我的机器有十几个斜坡函数时更是如此。 二是即使是中断,也是有时间抖动的,对1500来讲一般抖动为0.2ms, 如果我的中断时间为2ms(和我提出问题中的扫描周期差不多),那么误差也能到达10% (0.2/2)... ...
I can do it
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
12楼
主题:回复:斜坡函数与扫描周期的事情... ...就是用 “西山炮台” 说的方法,自己做减法了。 #iTemp := RD_SYS_T(OUT=>#ACTUAL_TIME); //读取当前系统时间 IF #ACTUAL_TIME.YEAR=#LAST_TIME.YEAR AND #ACTUAL_TIME.MONTH=#LAST_TIME.MONTH AND #ACTUAL_TIME.DAY=#LAST_TIME.DAY AND #ACTUAL_TIME.HOUR=#LAST_TIME.HOUR AND #ACTUAL_TIME.MINUTE=#LAST_TIME.MINUTE THEN #rCycleTime := LREAL_TO_REAL(#ACTUAL_TIME.SECOND-#LAST_TIME.SECOND+LReal#1.0E-9*(UDINT_TO_LREAL(#ACTUAL_TIME.NANOSECOND)-UDINT_TO_LREAL(#LAST_TIME.NANOSECOND))); END_IF; #rDeltaTime := 1.0E-3*DINT_TO_REAL(TIME_TO_DINT(T_DIFF(IN1:=#ACTUAL_TIME, IN2:=#LAST_TIME))); #LAST_TIME := #ACTUAL_TIME; //为下一次调用做准备 测试程序在附件内。
I can do it
|
|
小釉 至圣 经验值:10421 发帖数:2758 精华帖:26 |
13楼
主题:回复:斜坡函数与扫描周期的事情... ...伊默 你的意思是说用时间的减法和中断的精度差不多? 有一个问题怎么考虑呢? 如果OB1的前后两个扫描周期差很多的,是不是用中断更合适一些呢? 虽然精度差不多,但是固定的时间计算一次总比不固定的时间计算好一些吧 纯粹个人看法 |
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
17楼
主题:回复:斜坡函数与扫描周期的事情... ...@小釉 我觉得 用时间的减法和中断的精度差不多 , 特别是针对我们这种斜坡函数做速度给定的话,扫描周期的波动影响几乎没有影响。 我的PLC扫描周期一般也就几毫秒到十几毫秒。 另外,定时中断的抖动,有数据的。它受中断的优先级影响,也受映像寄存区的刷新影响, 还有硬件中断也一样的响应的抖动.
I can do it
|
|
小釉 至圣 经验值:10421 发帖数:2758 精华帖:26 |
21楼
主题:回复:斜坡函数与扫描周期的事情... ...举例说明一下, 假设 10ms增加10 10ms定时中断是每次是加10。 而用你的算法 有可能第一个周期是3ms,那在你的程序里是加3的,第二个扫描周期是12ms,在你的程序里是加12的 从数据的一致性上来说,有没有差别,想得不是太清楚。 你是怎么看呢 |
|
Zane 版主 经验值:85161 发帖数:21047 精华帖:399 |
22楼
主题:回复:斜坡函数与扫描周期的事情... ...按照A=A+B,增量累加思路实现斜坡函数, 在OB1里调用,其变化是不均匀的,扫描周期本身就是变化的,计算精度如果以TIME输出的话,每次最大误差不大于1毫秒,若果平均扫描周期为10毫秒的话,10秒钟的斜坡,最大时间误差可能会达到少1秒(极值),如果平均扫描周期为50毫秒的话,最大时间误差则是少0.2秒(极值),可见斜坡时间确定的前提下,扫描周期越长,精度反而越高,但曲线变得不光滑了,成锯齿状。 在定时中断里调用,由于定时中断属于较低级的中断,因此中断的间隔是有抖动的,取决于CPU的性能及高级中断的任务的多少,但是如果采用的时间增量是固定值(即中断间隔时间)的话,就不会有累计误差,因此不建议在定时中断里调用的斜坡函数再做时间间隔测量的工作,这样做反而会导致误差累计及增大。 综合来说,中断方式的精度高,累积误差小,信号变化均匀,曲线平滑,但占用资源;而OB1调用方式,信号变化不均匀,累积误差大,曲线相对粗糙,但不占用系统资源。 另外,还需要注意的是如果是用32位单精度浮点数计算的话,那么增量值与累积值的倍数是受单精度浮点数的有效位数限制的,尤其是在增量值较小,而斜坡时间很长的情况下,采用整型量累加可避免此类问题。
Zane
注册自动化系统工程师
Always save before download
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
23楼
主题:回复:斜坡函数与扫描周期的事情... ...to 小釉: 程序是为工艺服务的! 具体到我的项目,是一台机器有多轴同步启停,过程中控制张力。 假设三轴A,B,C 它们的目标速度为1000RPM, 加速时间为1秒。 那么某一个扫描周期为3ms, ABC三轴的速度增量均为3RPM,下一扫描周期为12ms,ABC三轴的速度增量都为12RPM... ... 这三轴都是同步累加的。 所以即使每次的增量有些微差别, 但是对我整机的加减速来讲,能有什么影响呢? 根据自己的工艺,选择适合的程序实现方法,才是好的!
I can do it
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
24楼
主题:回复:斜坡函数与扫描周期的事情... ...to Zane : 你讲的问题,正是我在首楼提出的问题! 问题的根源在于T_DIFF的结果使用了Time类型, 而偏偏系统默认的又不是四舍五入,反而是去尾留整。 所以导致计算得到的扫描周期会比平均扫描周期要小! 最大的误差就是是1ms 。 所以当我的平均扫描周期为10ms时,加速度偏差为10%, 而我的平均扫描周期为3ms,那么最大误差可能达到50%了! 那么问题的解决方法就是后来我直接的,直接用DTL.NANOSECOND去做减法, 这样精确到纳秒级别。 由于1毫秒=1000 000纳秒! 绝多数的扫描周期都是毫秒级以上, 所以精确到纳秒后,整个的误差就可以完全忽悠不计! 顶多顶多, 在#iTemp0 := RD_SYS_T(OUT=>#ACTUAL_TIME); 这一句刚扫描完,来了一个更高级别的中断, 那么这一个扫描周期的计算值就会有偏差了(偏差值就是高优先级中断的执行时间)。 而这种概率可以忽略不计,因为我的加减速会有上百个扫描周期。 而且即使是用定时中断,碰到更高级别的中断也一样存在这问题... ...
I can do it
|
|
伊默 至圣 经验值:19233 发帖数:4257 精华帖:118 |
26楼
主题:回复:斜坡函数与扫描周期的事情... ...对呀,就是为了简化计算,当 年=年;月=月;日=日;时=时;分=分;的情况下进行计算 就不计算了! 这样意味着每分钟可能有一次不计算, 不过没有关系,不计算的话,就会保持前一次的值而已! 而且一般扫描周期以10ms为例,那么每分钟有6000个扫描周期,而仅仅有一次不计算,完全可以忽略不计咯... ...
I can do it
|
|
Zane 版主 经验值:85161 发帖数:21047 精华帖:399 |
29楼
主题:回复:斜坡函数与扫描周期的事情... ...过高的计算精度有些浪费,我至今还是使用毫秒级的计算精度,但要求高的我会用5毫秒的中断,甚至等时同步的中断。 再快,机械响应也来不及。
Zane
注册自动化系统工程师
Always save before download
|