doujiang 发表于 2019-8-3 14:02:07

步进电机不同加减速曲线实现思路

本帖最后由 doujiang 于 2019-8-3 14:03 编辑

最近项目结题了,有空余时间研究了下步进电机不同加减速曲线的实现方法。下面发出来和大家一起讨论下。
1、梯型加减速:
梯形加减速算法是步进电机控制算法中最简单的一种,常见的实现思路是等时间间隔计算v=at,t一般选择1ms,即每毫秒改变一次速度,但这种控制方法会造成速度平滑度低,特别是速度较高时,每一毫秒内可能会有很多个脉冲发出,为了提高曲线的平滑性就需要提高计算频率,但计算频率的提高会造成最低启停速度较大(启停速度无法低于计算频率),同时还会出现短尾或拖拉现象。另一种实现思路是不以时间作为计算标准而以位移(单脉冲),这种思路大家更多的是参考AVR446这篇应用手册来实现,这篇文章实现的运行效果是步进电机在加减速过程中每一步的速度都会改变,使电机的运行平滑性相对于前面提到的等时间间隔计算得到了较大的提高,里面的核心思路是步进电机运行每一步的位移相同,然后反推每个脉冲的运行时间,文章最终通过泰勒展开式推导出了每个脉冲运行时间的递推公式:

在这个公式中,n表示第n个脉冲,Cn是第n个脉冲持续的时间。通过递推公式可以仅仅通过一个除法运算和加减法移位运算实现步进电机的单脉冲调速功能,但在实际应用中,需要使用浮点数运算来减少递推时的累计误差,如果是在FPGA中实现也会增加逻辑资源的消耗量。最后一种是通过SPTA算法来实现,速度是加速度的积分,位移是速度的积分,实际上通过加法运算即可实现梯形加减速单脉冲调速控制。下图是通过逻辑分析仪实际抓取的三种不同的控制算法实现的加速过程,可以看出SPTA算法几乎与理论曲线重合。

2、S型加减速:
S型加减速算法在实际实现过程中最困难的是不同情况下状态改变的条件判断,同时计算时涉及到开方等数学运算,不适合在FPGA中实现,这里给大家提供一种简单的方法实现S型加减速曲线:通过对梯形速度曲线进行滑动滤波得到的数值即是S型速度曲线的速度值,下面是我在EXCEL中模拟的曲线:

可以看出通过滑动滤波实现的S型加减速算法和梯形加减速规化的位置相等,同时也可以证明滑动滤波实现的S型加减速与标准S型加减速算法是等效的。参与滑动滤波的数据量大小决定S曲线的加加速大小。这里我也实际通过单片机跑出了曲线如下图:

当然,S型加减速曲线仍然可以通过SPTA算法来实现,加加速的积分是加速度,加速度积分是速度,速度积分是位移,S型曲线只需要比梯形曲线多用一个加法器就可实现。实际上,如果把梯形加减速的位移曲线拿来做速度曲线便是S型。下面是我在FPGA上仅用加法器实现的单步调速S型加减速曲线,通过逻辑分析仪直接抓取FPGA生成的脉冲频率绘制而成,通过下图也可以看出,计算频率越高,高速时速度曲线误差越小,也越平滑。

FPGA实现单轴S型T型曲线,逻辑资源消耗约900个,如下图:

3、串级PID伪闭环步进电机控制:
这个实际上是利用步进电机在不丢步的情况下把理论位移作为位置反馈,通过速度、位置环串级PID控制,我是看到坛友有讨论过,自己也试了下,但是效果并不是特别好,速度曲线如下图,希望大家能够指点下。谢谢!

Feeling_MCU 发表于 2019-8-3 14:27:02

能共享下FPGA的S曲线速度吗?我一直没弄好,只能用单片机通过S曲线公式计算

hkjabcd 发表于 2019-8-3 16:00:17

讲得不错,有过程有总结,我单片机简单的应用,一般查表,上位机S曲线公式生成数组,S曲线原始公式:y=K/(1+Exp(a-b*x))(K>0,b>0)

doujiang 发表于 2019-8-3 16:33:48

hkjabcd 发表于 2019-8-3 16:00
讲得不错,有过程有总结,我单片机简单的应用,一般查表,上位机S曲线公式生成数组,S曲线原始公式:y=K/(1+ ...

谢谢,查表需要占用较大存储容量,而且也会出现等时间间隔计算遇到的速度曲线平滑性差的问题。

ap0705307 发表于 2019-8-3 18:22:06

没有高大上的FPGA 能出一个STM32案例么?

kinsno 发表于 2019-8-3 18:36:16

doujiang 发表于 2019-8-3 16:33
谢谢,查表需要占用较大存储容量,而且也会出现等时间间隔计算遇到的速度曲线平滑性差的问题。 ...

这个画曲线软件是自自己写的吗,请问这个曲线控件用的是啥啊?

ylei12 发表于 2019-8-3 19:45:59

进来学习一下

whatcanitbe 发表于 2019-8-14 11:04:00

还可以再细化一些,让大家都掌握

whatcanitbe 发表于 2019-8-14 11:15:05

另外,spta那个累加到多少算溢出,看代码左移17位,不是很清楚怎么来的?

qq854149876 发表于 2019-8-14 15:40:21

关注学习一下

ruxz@263.net 发表于 2019-8-15 00:18:22

MARK一下,谢谢!

doujiang 发表于 2019-8-15 22:07:57

附上S曲线实际运行视频:https://v.youku.com/v_show/id_XNDMxNTg0MjM2NA==.html?spm=a2h3j.8428770.3416059.1

doujiang 发表于 2019-8-15 22:09:22

用匿名科创的上位机实时显示运行速度曲线,方便调试。

whf199191 发表于 2019-8-16 02:02:00

SPTA算法靠谱!

liurangzhou 发表于 2019-8-16 15:00:15

whf199191 发表于 2019-8-16 02:02
SPTA算法靠谱!

哪里有黄金参考资料

15148406@qq.com 发表于 2019-8-17 13:59:40

1514840686 q 知道怎么弄步进电机pid

fengyunyu 发表于 2019-11-8 08:52:19

LZ大神!

zhunyan1 发表于 2020-1-11 00:23:58

不错啊!

zhangalex88 发表于 2020-1-11 17:07:38

曲线很漂亮!请问楼主分了多少段加速上去的,参数能实时调整吗?

doujiang 发表于 2020-1-11 22:16:48

zhangalex88 发表于 2020-1-11 17:07
曲线很漂亮!请问楼主分了多少段加速上去的,参数能实时调整吗?

在加速过程中,每个脉冲都在变频。也就是加速理论需要多少个脉冲,就多少段加速上去。

嘀嘀 发表于 2020-1-12 21:18:33

目前正在整三角洲结构的S曲线,谢谢

dearterry30 发表于 2020-1-12 21:52:35

非常不错的方法,之前一直用等时间间隔1毫秒的方法,学习了

raydsp 发表于 2020-1-13 09:37:41

很厉害。一直想这方面发展。

albert_lu 发表于 2020-1-27 17:45:55

謝謝分享,學習了。

wuhuan 发表于 2020-1-27 21:44:33

好资料,谢谢分享!

jxyctwt 发表于 2020-2-12 15:32:56


謝謝分享,學習了。

Wesson 发表于 2020-10-20 10:51:52

根据起始速度,加加速,最大加速度算出加速曲线是S型,但还是确定不了最大速度是多少。现在就是想通过起始速度、加加速(或者最大加速度)、最大速度来算出S加速度,可以实现吗?感谢指导一下。

picobox 发表于 2020-10-20 12:21:04

对FPGA实现S加速曲线感兴趣,能分享FPGA部分吗,或者这部分讲详细一点。

colinzhao 发表于 2020-10-20 15:29:10

需要做到可逆解算才有意义,比如给定运行总时间,总位移,加速度,自动计算最高速度,自适应4段5段等等,但跑一下S并不难

bsz84 发表于 2020-10-20 15:45:06

更麻烦是在运行的过程中还要改变速度。

colinzhao 发表于 2020-10-20 20:10:56

bsz84 发表于 2020-10-20 15:45
更麻烦是在运行的过程中还要改变速度。

那叫插补,讲CNC跟S曲线控制混为一谈要么不懂,要么耍流氓

9547818 发表于 2020-10-23 19:21:49

收藏一下

dukelec 发表于 2020-10-23 20:12:02

本帖最后由 dukelec 于 2020-10-23 20:33 编辑

colinzhao 发表于 2020-10-20 20:10
那叫插补,讲CNC跟S曲线控制混为一谈要么不懂,要么耍流氓

我的用法:
主控(譬如 STM32 或 x86_64 主機)細分后,把一小段一小段的位置訊息,按理論上對應的時間點逐一寫入電機,實時修改電機目標位置。如果寫的時間相對電機偏快一點(不同設備的時鐘精度有偏差),会導致電機跟不上,和目標距離越拉越遠。如果寫的太慢,会導致電機走一下停一下。所以一般是寫的偏慢一点点,或者是寫的速度值偏高一點點,這樣就可以實現剛開始減速的時候,又收到新的位置,重新恢復設定速度運行。從速度曲線上來看,就是每小段之間有一個小凹陷,盡量把它調小一點,雖然不是最優,但至少可以避免累積誤差。

特別是多軸聯動的情況需要此機制,否則不同電機的時鐘精度偏差也會導致不同步。
(在某些場合,連續走的時間短,可以走走停停的話,可以不考慮同步問題,在電機端做一個指令隊列,當前加減速曲線和下一條命令的曲線銜接,中間不用停。)

還有是動態追隨的情況,譬如攝像頭識別運動的物品,控制機械裝置同步運動作業。

所以,對於某些場景,電機的確要在中途重新規劃加減速曲線。

colinzhao 发表于 2020-10-23 23:03:16

dukelec 发表于 2020-10-23 20:12
我的用法:
主控(譬如 STM32 或 x86_64 主機)細分后,把一小段一小段的位置訊息,按理論上對應的時間點 ...

转不过弯没办法,我还是唠叨两句:S曲线目的在于最大程度使运行快速且平稳,加速度是平滑的,却要求又丝滑又有凹凸感,矛盾不?再强调一下,查补跟S曲线是完全不一样的东西,当然,整体插补也可以实现S曲线,但这似乎没什么用,高端CNC应该会做部分优化,但是大部分不需要这样做。

dukelec 发表于 2020-10-24 01:46:56

本帖最后由 dukelec 于 2020-10-24 01:53 编辑

colinzhao 发表于 2020-10-23 23:03
转不过弯没办法,我还是唠叨两句:S曲线目的在于最大程度使运行快速且平稳,加速度是平滑的,却要求又丝 ...

麻煩耐性講解一下唄。

我上面說的細分線段就是我理解的插補。插補一般是由一個控制多軸電機的主機完成,電機本身有獨立的 cpu,主機收到用戶發來的 G-code 等命令後,差補成各軸的數據實時下發給各軸電機 cpu。(主控和各軸之間用 RS-485 或者 EtherCat 等線路高頻同步,每次發送目標位置、目標速度、目標加速度等信息給電機 cpu。)

對於電機端的 cpu,我一般只跑 T 形加減速,如果是 FOC 電機,T 形曲線經過 PID 之後實際速度和 S 形也比較像,沒必要用各種 S 的算法,S 算法的缺點是整體耗時長,計算量大。選擇步進電機的行為本身就意味着要求不高,那麼 T 曲線也夠了。(有些系統的 FOC 電機端連 T 加減速都不要,直接把需要走的路程,按距離平均分幾個點,依次跳着走完這幾個點就到目標位置了,如果目標太遠,就報錯保護。)

如果主控跑 jerk 平滑的差補算法,電機 cpu 也給每小段距離跑一個 S 曲線,有點多餘。

還有些老派做法是,主控直接發步進脈衝給各軸電機(有些是發脈衝直接控制步進電機,也有些是發脈衝給伺服控制器再控制電機)。

appleboy 发表于 2020-10-24 07:09:56

colinzhao 发表于 2020-10-23 23:03
转不过弯没办法,我还是唠叨两句:S曲线目的在于最大程度使运行快速且平稳,加速度是平滑的,却要求又丝 ...

你那个产品放弃了?

chenhuiedu 发表于 2021-11-15 21:18:07

这个资料很详细,实用!

wowangru 发表于 2022-1-27 11:50:11

前两年自悟出这个S算法,没想到它叫STPA

whatcanitbe 发表于 2022-1-27 15:40:36

wowangru 发表于 2022-1-27 11:50
前两年自悟出这个S算法,没想到它叫STPA

你是怎么实现的?

doujiang 发表于 2022-4-1 22:11:25

wowangru 发表于 2022-1-27 11:50
前两年自悟出这个S算法,没想到它叫STPA
(引用自38楼)

厉害{:handshake:} {:handshake:} {:handshake:}

zhcj66 发表于 2022-9-17 16:17:55

doujiang 发表于 2020-1-11 22:16
在加速过程中,每个脉冲都在变频。也就是加速理论需要多少个脉冲,就多少段加速上去。 ...
(引用自20楼)

没用过步进电机   变频是不是,每个脉冲中断一次,然后改变定时器的频率?

zhcj66 发表于 2022-9-17 16:18:28

wowangru 发表于 2022-1-27 11:50
前两年自悟出这个S算法,没想到它叫STPA
(引用自38楼)

有公式可以参考吗

akey3000 发表于 2022-9-17 16:40:00

收藏,学习
页: [1]
查看完整版本: 步进电机不同加减速曲线实现思路