Stm32Motor 发表于 2023-9-26 11:15:25

7段式S曲线脉冲误差问题求助

各位大佬,小弟参考S形加减速,使用python编写了对应的程序。生成了对应的速度曲线,对速度曲线每隔1ms进行采样,并计算1ms里面对应的速度点发多少个脉冲,累计下来算出整个行程的脉冲个数,发现总的脉冲个数与我设定的值存在一定的偏差,请问各位大佬有什么好办法解决没?

Stm32Motor 发表于 2023-9-26 11:17:38

本帖最后由 Stm32Motor 于 2023-9-26 11:24 编辑

我写的python程序如下:
import matplotlib.pyplot as pyplot
import numpy
import numpy as np
import sympy as sp
import math
import re
from sympy import *
from datetime import datetime

#pyplot.close
fig = pyplot.figure()
fig.set_size_inches(10, 8)

F=800            #最大速度         转/分
Amax=6000    #最大加速度   转/分**2
Jmax=80000   #最大加加速度  转/分**3
Vs=Ve=200    #启动速度与停止速度相同
S=6400          #行程

Amax=Amax/60*1600
Jmax=Jmax/60*1600

#转速圈/分 转换成脉冲/S
F=F/60*1600
#q启动速度转找成脉冲/S
Vs=Vs/60*1600
Ve=Vs
T0=0
T1=0
T2=0
T3=0
T4=0
T5=0
T6=0
T7=0
VRmax=0   #实际最大速度
ARmax=0   #实际最大加速度
print('计算当系统刚好能够达到最大加速度Amax,且无匀加减速和匀速段')
T2=T4=T6=0
T1=Amax/Jmax
T3=T5=T7=T1
Vmax=Vs+Jmax*T1*T1
Vmax=Vmax
print('Vmax1=',Vmax/1600*60)
V3=Vmax
Sref1=(2*Vs*T1+2*V3*T5)
print("Sref1=",Sref1)
if S<=Sref1 and F>=Vmax:
    print('距离不足以加速加速到最大加速度')
    a=S*np.sqrt(Jmax)/4
    b=np.sqrt(S*S*Jmax/16+8*Vs**3/27)
    a1=a+b
    a2=a-b
    print(a1,a2)
    a=np.power(a1,1/3)
    if a2<0 :
      b=-np.power(-a2,1/3)
    else:
      b=np.power(a2,1/3)
    T1=(a+b)/np.sqrt(Jmax)

    T2=T4=T6=0
    T3=T5=T7=T1
    VRmax=Jmax*T1*T1+Vs
    ARmax=Jmax*T1

if S<=Sref1 and F<=Vmax:
    T1=np.sqrt((F-Vs)/Jmax)
    T3=T5=T7=T1
    Sa=Jmax*T1*T1*T1+2*Vs*T1
    print('Sa=',Sa)
    if S-2*Sa>=0:
      T4=(S-2*Sa)/F
      VRmax=F
      ARmax=Jmax*T1
    else:
      a=S*np.sqrt(Jmax)/4
      b=np.sqrt(S*S*Jmax/16+8*Vs**3/27)
      a1=a+b
      a2=a-b
      print(a1,a2)
      a=np.power(a1,1/3)
      if a2<0 :
            b=-np.power(-a2,1/3)
      else:
            b=np.power(a2,1/3)
      T1=(a+b)/np.sqrt(Jmax)
      T2=0
      T3=T5=T7=T1
      VRmax=Jmax*T1*T1+Vs
      ARmax=Jmax*T1
      T2=T6=0
   
if S>Sref1 and F<=Vmax:
    T1=np.sqrt((F-Vs)/Jmax)
    T3=T5=T7=T1
    Sa=Jmax*T1*T1*T1+2*Vs*T1
    print('Sa2=',Sa)
    T4=(S-2*Sa)/F
    T2=T6=0
    VRmax=F
    ARmax=Jmax*T1

if S>Sref1 and F>=Vmax:
    print('F>Vmax,F为最大速度,有匀加速段与匀减速段')
    T5=T1=Amax/Jmax
    T2=(F-Vs)/Amax-T1
    T6=(F-Ve)/Amax-T5
    Sref2=(F+Vs)/2*(2*T1+T2)+(F+Ve)/2*(2*T5+T6)
    print("Sref2=",Sref2)
    print('最大速度=',F)
    ARmax=Amax
   
    if S<=Sref2:
      T4=0
      Vmax=(-Amax**2 + np.sqrt(Amax**4 - 2*Amax**2*Jmax*Ve - 2*Amax**2*Jmax*Vs + 4*Amax*Jmax**2*S + 2*Jmax**2*Ve**2 + 2*Jmax**2*Vs**2))/(2*Jmax)
      T5=T1=Amax/Jmax
      T2=(Vmax-Vs)/Amax-T1   #匀加速段时间
      T6=(Vmax-Ve)/Amax-T5   #匀减速段时间
      print('6段式')
      VRmax=Vmax
    else:
      VRmax=F
      T4=(S-Sref2)/VRmax
      print('7段式')
Ts=T1+T2+T3+T4+T5+T6+T7
print('总时间=',Ts,'T1=',T1,'T2=',T2,'T3=',T3,'T4=',T4,'T5=',T5,'T6=',T6,'T7=',T7)
print('Amax=',Amax,'Jmax=',Jmax,'F=',F,'S=',S)
print('VRmax=',VRmax,'ARmax=',ARmax)

#J曲线
t1=T1
t2=t1+T2
t3=t2+T3
t4=t3+T4
t5=t4+T5
t6=t5+T6
t7=t6+T7

#加加速度计算
def JCal(tx):
    if tx>=0 and tx<=t1:
      j=Jmax
    if tx>t1 and tx<=t2:
      j=0
    if tx>t2 and tx<=t3:
      j=-Jmax
    if tx>t3 and tx<=t4:
      j=0
    if tx>t4 and tx<=t5:
      j=-Jmax
    if tx>t5 and tx<=t6:
      j=0
    if tx>t6 and tx<=t7:
      j=Jmax
    return j

x=numpy.linspace(0,Ts,round(Ts*1000)-1)
jt=
pyplot.subplot(2,2,3)
pyplot.plot(x,jt)
pyplot.title('J/t')

#加速度计算
def ACal(tx):
    if tx>=0 and tx<=t1:
      a=Jmax*tx
    if tx>t1 and tx<=t2:
      a=ARmax
    if tx>t2 and tx<=t3:
      a=ARmax-Jmax*(tx-t2)
    if tx>t3 and tx<=t4:
      a=0
    if tx>t4 and tx<=t5:
      a=-Jmax*(tx-t4)
    if tx>t5 and tx<=t6:
      a=-ARmax
    if tx>t6 and tx<=t7:
      a=-ARmax+Jmax*(tx-t6)
    return a/1600*60

at=
pyplot.subplot(2,2,2)
pyplot.plot(x,at)
pyplot.title('a/t')

#速度计算
def VCal(tx):
    if tx>=0 and tx<=t1:
      v=Vs+Jmax*tx*tx/2
    if tx>t1 and tx<=t2:
      v=Vs+Jmax*T1*T1/2+ARmax*(tx-t1)
    if tx>t2 and tx<=t3:
      v=Vs+Jmax*T1*T1/2+ARmax*T2+ARmax*(tx-t2)-Jmax*(tx-t2)**2/2
    if tx>t3 and tx<=t4:
      v=VRmax
    if tx>t4 and tx<=t5:
      v=VRmax-Jmax*(tx-t4)**2/2
    if tx>t5 and tx<=t6:
      v=VRmax-Jmax*T5**2/2-ARmax*(tx-t5)
    if tx>t6 and tx<=t7:
      v=VRmax-Jmax*T5**2/2-ARmax*T6-ARmax*(tx-t6)+Jmax*(tx-t6)**2/2
    return v

vt=
#计算定时器匹配值
mcuDaata=
print(mcuDaata)
#print(mcuDaata)
#计算真实时间与实际脉冲个数
steps=0
totaltime=0
for i in range(len(mcuDaata)):
    steps=steps+round(1000/(mcuDaata/16*2))
    totaltime=totaltime+round(1000/(mcuDaata/16*2))*(round(mcuDaata/16*2))

totaltime=totaltime/1000
#steps=steps*2+T4*VRmax
print("总时间=",totaltime,"总步数=",steps,'匀速步数=',T4*VRmax)

Rvt=
pyplot.subplot(2,2,1)
pyplot.plot(x,Rvt)
pyplot.title('v/t')

#速度计算
S1=0
S2=0
S3=0
S4=0
S5=0
S6=0
S7=0

def SCal(tx):
    global S1,S2,S3,S4,S5,S6,S7
    if tx>=0 and tx<=t1:
      s=Vs*tx+Jmax*tx**3/6
      S1=s
      S2=S1
    if tx>=t1 and tx<=t2:
      s=S1+(Vs+Jmax*T1*T1/2)*(tx-t1)+Jmax*T1*(tx-t1)**2/2      #ARmax*(tx-t1)**2/2
      S2=s
    if tx>=t2 and tx<=t3:
      s=S2+(Vs+Jmax*T1*T1/2+ARmax*T2)*(tx-t2)+Jmax*T1*(tx-t2)**2/2-Jmax*(tx-t2)**3/6
      S3=s
      S4=S3
    if tx>=t3 and tx<=t4:
      s=S3+VRmax*(tx-t3)
      S4=s
    if tx>=t4 and tx<=t5:
      s=S4+VRmax*(tx-t4)-Jmax*(tx-t4)**3/6
      S5=s
      S6=S5
    if tx>=t5 and tx<=t6:
      s=S5+(VRmax-Jmax*T5**2/2)*(tx-t5)-Jmax*T5*(tx-t5)**2/2
      S6=s
    if tx>=t6 and tx<=t7:
      s=S6+(VRmax-Jmax*T5**2/2-ARmax*T6)*(tx-t6)-Jmax*T5*(tx-t6)**2/2+Jmax*(tx-t6)**3/6
      S7=s
    return s

st=
print(st)
#print(st)
ff=np.diff(st)
#print(ff)
pyplot.subplot(2,2,4)
temp=np.delete(x, 0)
pyplot.plot(x,st)
#pyplot.plot(temp,ff)
pyplot.title('S/t')
fig.text(0.5,0.95,'S={:.4f},F={:.4f},Amax={:.4f},Jmax={:.4f},SR={:d},VRmax={:.4f},ARmax={:.4f},Ts={:.4f}'.format(S,F/1600*60,Amax/1600*60,Jmax/1600*60,steps,VRmax/1600*60,ARmax/1600*60,Ts*1000),
      fontsize=10, fontweight='bold',color='r', ha='center', va='center', bbox=dict(facecolor='yellow'))
print(S2-S1,S3-S2,S4-S3,S5-S4,S6-S5,S7-S6)
pyplot.show()

Stm32Motor 发表于 2023-9-26 11:22:39

我设定的脉冲个数为6400个,通过速度采样计算出来的脉冲个数6334,少了66个脉冲,按脉冲计算的时间为427ms,程序规划的时候是431ms。主要问题还是要脉冲个数与设置的相等.

wowangru 发表于 2023-9-26 11:28:28

Stm32Motor 发表于 2023-9-26 11:22
我设定的脉冲个数为6400个,通过速度采样计算出来的脉冲个数6334,少了66个脉冲,按脉冲计算的时间为427ms, ...
(引用自3楼)

我用FPGA执行也会有出入。 不能让终止速度为0.否则可能出现脉冲没发完速度已经为0 了

Stm32Motor 发表于 2023-9-26 11:29:46

终止速度不零,实际使用不能有偏差

Stm32Motor 发表于 2023-9-26 15:09:52

wowangru 发表于 2023-9-26 11:28
我用FPGA执行也会有出入。 不能让终止速度为0.否则可能出现脉冲没发完速度已经为0 了 ...
(引用自4楼)

现在可以对上,用位置曲线的微分做每个采样点的脉冲个数。{:lol:}……太复杂,不知道能不能在STM32F407里面实时计算哈

Stm32Motor 发表于 2023-9-26 15:20:52

本帖最后由 Stm32Motor 于 2023-9-26 15:24 编辑

S为设定步数,Sr为规划后的步数.Ts为规划时间,Tr为转换成定时器时间后再换算回去的总时间。
电机8细分,1600个脉冲转一圈,定时器频率为16MHz。启动速度100圈/分,最大速度800圈/分.

boycn 发表于 2023-9-26 15:44:53

楼主可以把源代码更新一下,给大家一个学习模板

另外上图中加速度还是突变的,是不是还有优化的空间?

三年模拟 发表于 2023-9-26 16:10:54

偏差必然有,只能四舍五入不同频率段下的步数,总步数准确就行了。

Stm32Motor 发表于 2023-9-26 16:33:04

boycn 发表于 2023-9-26 15:44
楼主可以把源代码更新一下,给大家一个学习模板

另外上图中加速度还是突变的,是不是还有优化的空间? ...
(引用自8楼)

现在是7段式,用15段就可以解决加速度突变的问题,也就再加一个加加加速度,让现在加加速度连续变化,再进一步就是31段式,数学不好,搞这个7段的都搞了好久。

Stm32Motor 发表于 2023-9-26 16:34:23

三年模拟 发表于 2023-9-26 16:10
偏差必然有,只能四舍五入不同频率段下的步数,总步数准确就行了。
(引用自9楼)

就是怎么保证总步数正确有点难,我现在太复杂了,在电脑端算是可以,估计不适合在STM32F407上用。我目标是在STM32F407动态计算。

Stm32Motor 发表于 2023-9-26 16:41:18

boycn 发表于 2023-9-26 15:44
楼主可以把源代码更新一下,给大家一个学习模板

另外上图中加速度还是突变的,是不是还有优化的空间? ...
(引用自8楼)

上周搞了基于sigmoid曲线的方式,你可以看看我的另外一个贴子。y=b+k/(1+e(-x+a)/n))的方法的,这种方式加速度连续,没有突变。还没有完成行程规划部分。没找到对应规划的方法(给定距离,平滑度,加速时间,启动速度与最大速度算出定时器的值,目前只实现距离足够长的计算,在SMT32F407里面实际计算200个点,139us可以计算完成)。7段式S曲线网上有详细的规划方法。

三年模拟 发表于 2023-9-26 16:42:12

动态算单片机也可以的,s模型不能太复杂,我以前做过标准7段s加减速,arm算好频率和步数后,发给fpga运行,说实话,s加减速和t型加减速我感觉都差不多,除了用来水论文,t型加减速大部分工程完全够用了

Stm32Motor 发表于 2023-9-26 16:45:15

以下是最新的代码,运行后会在同目录下生成data.c文件,开一个16MHZ的定时器,每中断一次取反一下
脉冲脚电平,输出一个脉冲后换下一个数(50%占空比)
import matplotlib.pyplot as pyplot
import numpy
import numpy as np
import sympy as sp
import math
import re
from sympy import *
from datetime import datetime
import matplotlib
matplotlib.rc("font", family='Microsoft YaHei')


def list_to_hex_string(list_data,s,f,a,j,vr,ar,sr,tr):
    index=0
    current_time = datetime.now().strftime("%Y%m%d--%H:%M:%S")
    list_str='//'+current_time+'\n'
    list_str+= '//目标步数='+ str(s)+'\n'
    list_str+= '//最大速度='+ str(f)+'\n'
    list_str+= '//最大加速度='+ str(a)+'\n'
    list_str+= '//最大加加速度='+ str(j)+'\n'
    list_str+= '//实际最大速度='+ str(vr)+'\n'
    list_str+= '//实际最大加速度='+ str(ar)+'\n'
    list_str+= '//规划步数='+ str(sr)+'\n'
    list_str+= '//耗时='+ str(tr)+'\n'
    list_str+= '//define TAB3_LEN '+ str(len(list_data))+'\n'
    list_str += '__flash unsigned int SpeedTable3={\n'
    for x in list_data:
      list_str += '0x{:04X},'.format(x-34)#转换成十六进制并大写
      #print(x)
      index+=1
      ifindex%10==0:
            list_str+='\n'
   
    if index%10==0:
      list_str = list_str[:-6] # 最后一个',' 不取
    else:
       list_str = list_str[:-3] # 最后一个',' 不取

    list_str += '\n}'
    return list_str

fig = pyplot.figure()
fig.set_size_inches(10, 8)

F=800      #最大速度
Amax=6000    #最大加速度   转/分**2
Jmax=80000   #最大加加速度  转/分***3
Vs=Ve=200    #启动速度与停止速度相同
S=800      #行程

Amax=Amax/60*1600
Jmax=Jmax/60*1600

#转速圈/分 转换成脉冲/S
F=F/60*1600
#q启动速度转找成脉冲/S
Vs=Vs/60*1600
Ve=Vs
T0=0
T1=0
T2=0
T3=0
T4=0
T5=0
T6=0
T7=0
VRmax=0   #实际最大速度
ARmax=0   #实际最大加速度
print('计算当系统刚好能够达到最大加速度Amax,且无匀加减速和匀速段')
T2=T4=T6=0
T1=Amax/Jmax
T3=T5=T7=T1
Vmax=Vs+Jmax*T1*T1
Vmax=Vmax
print('Vmax1=',Vmax/1600*60)
V3=Vmax
Sref1=(2*Vs*T1+2*V3*T5)
print("Sref1=",Sref1)
if S<=Sref1 and F>=Vmax:
    print('距离不足以加速加速到最大加速度')
    a=S*np.sqrt(Jmax)/4
    b=np.sqrt(S*S*Jmax/16+8*Vs**3/27)
    a1=a+b
    a2=a-b
    print(a1,a2)
    a=np.power(a1,1/3)
    if a2<0 :
      b=-np.power(-a2,1/3)
    else:
      b=np.power(a2,1/3)
    T1=(a+b)/np.sqrt(Jmax)

    T2=T4=T6=0
    T3=T5=T7=T1
    VRmax=Jmax*T1*T1+Vs
    ARmax=Jmax*T1

if S<=Sref1 and F<=Vmax:
    T1=np.sqrt((F-Vs)/Jmax)
    T3=T5=T7=T1
    Sa=Jmax*T1*T1*T1+2*Vs*T1
    print('Sa=',Sa)
    if S-2*Sa>=0:
      T4=(S-2*Sa)/F
      VRmax=F
      ARmax=Jmax*T1
    else:
      a=S*np.sqrt(Jmax)/4
      b=np.sqrt(S*S*Jmax/16+8*Vs**3/27)
      a1=a+b
      a2=a-b
      print(a1,a2)
      a=np.power(a1,1/3)
      if a2<0 :
            b=-np.power(-a2,1/3)
      else:
            b=np.power(a2,1/3)
      T1=(a+b)/np.sqrt(Jmax)
      T2=0
      T3=T5=T7=T1
      VRmax=Jmax*T1*T1+Vs
      ARmax=Jmax*T1
      T2=T6=0
   
if S>Sref1 and F<=Vmax:
    T1=np.sqrt((F-Vs)/Jmax)
    T3=T5=T7=T1
    Sa=Jmax*T1*T1*T1+2*Vs*T1
    print('Sa2=',Sa)
    T4=(S-2*Sa)/F
    T2=T6=0
    VRmax=F
    ARmax=Jmax*T1

if S>Sref1 and F>=Vmax:
    print('F>Vmax,F为最大速度,有匀加速段与匀减速段')
    T5=T1=Amax/Jmax
    T2=(F-Vs)/Amax-T1
    T6=(F-Ve)/Amax-T5
    Sref2=(F+Vs)/2*(2*T1+T2)+(F+Ve)/2*(2*T5+T6)
    print("Sref2=",Sref2)
    print('最大速度=',F)
    ARmax=Amax
   
    if S<=Sref2:
      T4=0
      Vmax=(-Amax**2 + np.sqrt(Amax**4 - 2*Amax**2*Jmax*Ve - 2*Amax**2*Jmax*Vs + 4*Amax*Jmax**2*S + 2*Jmax**2*Ve**2 + 2*Jmax**2*Vs**2))/(2*Jmax)
      T5=T1=Amax/Jmax
      T2=(Vmax-Vs)/Amax-T1   #匀加速段时间
      T6=(Vmax-Ve)/Amax-T5   #匀减速段时间
      print('6段式')
      VRmax=Vmax
    else:
      VRmax=F
      T4=(S-Sref2)/VRmax
      print('7段式')
Ts=T1+T2+T3+T4+T5+T6+T7
print('总时间=',Ts,'T1=',T1,'T2=',T2,'T3=',T3,'T4=',T4,'T5=',T5,'T6=',T6,'T7=',T7)
print('Amax=',Amax,'Jmax=',Jmax,'F=',F,'S=',S)
print('VRmax=',VRmax,'ARmax=',ARmax)

#J曲线
t1=T1
t2=t1+T2
t3=t2+T3
t4=t3+T4
t5=t4+T5
t6=t5+T6
t7=t6+T7

#加加速度计算
def JCal(tx):
    if tx>=0 and tx<=t1:
      j=Jmax
    if tx>t1 and tx<=t2:
      j=0
    if tx>t2 and tx<=t3:
      j=-Jmax
    if tx>t3 and tx<=t4:
      j=0
    if tx>t4 and tx<=t5:
      j=-Jmax
    if tx>t5 and tx<=t6:
      j=0
    if tx>t6 and tx<=t7:
      j=Jmax
    return j

x=numpy.linspace(0,Ts,round(Ts*1000)-1)
jt=
pyplot.subplot(2,2,3)
pyplot.plot(x,jt)
pyplot.title('J/t')

#加速度计算
def ACal(tx):
    if tx>=0 and tx<=t1:
      a=Jmax*tx
    if tx>t1 and tx<=t2:
      a=ARmax
    if tx>t2 and tx<=t3:
      a=ARmax-Jmax*(tx-t2)
    if tx>t3 and tx<=t4:
      a=0
    if tx>t4 and tx<=t5:
      a=-Jmax*(tx-t4)
    if tx>t5 and tx<=t6:
      a=-ARmax
    if tx>t6 and tx<=t7:
      a=-ARmax+Jmax*(tx-t6)
    return a/1600*60

at=
pyplot.subplot(2,2,2)
pyplot.plot(x,at)
pyplot.title('a/t')

#速度计算
def VCal(tx):
    if tx>=0 and tx<=t1:
      v=Vs+Jmax*tx*tx/2
    if tx>t1 and tx<=t2:
      v=Vs+Jmax*T1*T1/2+ARmax*(tx-t1)
    if tx>t2 and tx<=t3:
      v=Vs+Jmax*T1*T1/2+ARmax*T2+ARmax*(tx-t2)-Jmax*(tx-t2)**2/2
    if tx>t3 and tx<=t4:
      v=VRmax
    if tx>t4 and tx<=t5:
      v=VRmax-Jmax*(tx-t4)**2/2
    if tx>t5 and tx<=t6:
      v=VRmax-Jmax*T5**2/2-ARmax*(tx-t5)
    if tx>t6 and tx<=t7:
      v=VRmax-Jmax*T5**2/2-ARmax*T6-ARmax*(tx-t6)+Jmax*(tx-t6)**2/2
    return v

vt=
#计算定时器匹配值
mcuDaata=
#计算真实时间与实际脉冲个数

Rvt=
pyplot.subplot(2,2,1)
pyplot.plot(x,Rvt)
pyplot.title('v/t')

#速度计算
S1=0
S2=0
S3=0
S4=0
S5=0
S6=0
S7=0

def SCal(tx):
    global S1,S2,S3,S4,S5,S6,S7
    if tx>=0 and tx<=t1:
      s=Vs*tx+Jmax*tx**3/6
      S1=Vs*T1+Jmax*T1**3/6
      S2=S1
    if tx>=t1 and tx<=t2:
      s=S1+(Vs+Jmax*T1*T1/2)*(tx-t1)+Jmax*T1*(tx-t1)**2/2      #ARmax*(tx-t1)**2/2
      S2=S1+(Vs+Jmax*T1**2/2)*T2+Jmax*T1*T2**2/2
    if tx>=t2 and tx<=t3:
      s=S2+(Vs+Jmax*T1*T1/2+ARmax*T2)*(tx-t2)+Jmax*T1*(tx-t2)**2/2-Jmax*(tx-t2)**3/6
      S3=S2+(Vs+Jmax*T1*T1/2+ARmax*T2)*T3+Jmax*T1*T3**2/2-Jmax*T3**3/6
      S4=S3
    if tx>=t3 and tx<=t4:
      s=S3+VRmax*(tx-t3)
      S4=S3+VRmax*T4
    if tx>=t4 and tx<=t5:
      s=S4+VRmax*(tx-t4)-Jmax*(tx-t4)**3/6
      S5=S4+VRmax*T5-Jmax*T5**3/6
      S6=S5
    if tx>=t5 and tx<=t6:
      s=S5+(VRmax-Jmax*T5**2/2)*(tx-t5)-Jmax*T5*(tx-t5)**2/2
      S6=S5+(VRmax-Jmax*T5**2/2)*T6-Jmax*T5*T6**2/2
      S7=S6
    if tx>=t6 and tx<=t7:
      s=S6+(VRmax-Jmax*T5**2/2-ARmax*T6)*(tx-t6)-Jmax*T5*(tx-t6)**2/2+Jmax*(tx-t6)**3/6
      #S7=s
    return s
st=
ff=np.diff(st)
totalsteps=0
totaltime=0
for i in range(len(ff)):
    totalsteps=totalsteps+(ff)
    totaltime=totaltime+(ff)*round(mcuDaata/16*2)

totaltime=totaltime/1000

print("总时间=",totaltime,"总步数=",totalsteps)

data=list()
for i in range(len(ff)):
    for j in range(ff):
      data.append(mcuDaata)
writedata=list_to_hex_string(data,S,round(F/1600*60),round(Amax/1600*60),round(Jmax/1600*60),round(VRmax/1600*60),round(ARmax/1600*60),totalsteps,totaltime)
with open('data.c', 'w') as f:
    f.write(writedata)

pyplot.subplot(2,2,4)
temp=np.delete(x, 0)
pyplot.plot(x,st)
pyplot.title('S/t')
fig.text(0.5,0.95,'S={:d}MciroStep,F={:.2f}转/分,Vs=Ve={:.2f}转/分,Amax={:.2f}转/分**2,Jmax={:.2f}转/分**3,Ts={:.2f}ms'.format(S,F/1600*60,Vs/1600*60,Amax/1600*60,Jmax/1600*60,Ts*1000),
      fontsize=10, fontweight='bold',color='r', ha='center', va='center', bbox=dict(facecolor='yellow'))

fig.text(0.5,0.03,'Sr={:d}MciroStep,Tr={:.2f},VRmax={:.2f}转/分,ARmax={:.2f}转/分**2'.format(totalsteps,totaltime,VRmax/1600*60,ARmax/1600*60),
      fontsize=10, fontweight='bold',color='g', ha='center', va='center', bbox=dict(facecolor='yellow'))
pyplot.show()

Stm32Motor 发表于 2023-9-26 16:54:51

三年模拟 发表于 2023-9-26 16:42
动态算单片机也可以的,s模型不能太复杂,我以前做过标准7段s加减速,arm算好频率和步数后,发给fpga运行, ...
(引用自13楼)

能介绍一下你的T型算原理不,我计算三种都搞一下,在实际应该中哪种好就用哪种,我们有重负载的设备,也有轻负载的设备。

whatcanitbe 发表于 2023-9-26 22:20:59

三年模拟 发表于 2023-9-26 16:42
动态算单片机也可以的,s模型不能太复杂,我以前做过标准7段s加减速,arm算好频率和步数后,发给fpga运行, ...
(引用自13楼)

期待你讲讲fpga加减速

wowangru 发表于 2023-9-26 23:02:00

Stm32Motor 发表于 2023-9-26 16:41
上周搞了基于sigmoid曲线的方式,你可以看看我的另外一个贴子。y=b+k/(1+e(-x+a)/n))的方法的,这种方式 ...
(引用自12楼)

我算7段S加减速用407 8us, 用电脑不到1us。就是有时候会出错。 比如初始速度和初始加速度不为0并且和最大加速度一样大时。 或者路程非常小只有几个脉冲时。

Stm32Motor 发表于 2023-9-27 08:47:09

本帖最后由 Stm32Motor 于 2023-9-27 08:49 编辑

你这个这么牛,7us算完。是标准的7段式吗?里面有几条公式很长的.能否分享下,我准备把这个python的移植到STMF407上.

Stm32Motor 发表于 2023-9-27 17:30:36

今天把数据压缩了一下(只存加速区数据,存脉冲宽度与对应的脉冲个数),把生成的数据放到atmega128里面,效果不错哈。视频如下,欢迎查看。8细分,1600步/转,启动速度100,最大速度900,规划行程6400,运行时间实测试470ms。
5.82 u@f.OK OKJ:/ 03/16 复制打开抖音,看看7段式s曲线规划https://v.douyin.com/iev2XRMj/

Stm32Motor 发表于 2023-9-27 17:36:55

以下为生成数据样本,在Atmega128上使用一个16MHz的定时器。
//20230927--17:34:48
//目标步数=6400
//启动速度=100
//最大速度=900
//最大加速度=9000
//最大加加速度=60000
//实际最大速度=900
//实际最大加速度=6928
//规划步数=6400
//耗时=472.145
//data=数据长度  data=加速步数 data=脉冲个数超始地址 data=匀速步数高16位 data=匀速步数低16位
//data=总步数高16位 data=总步数低16位
#define TAB_LEN 480
__flash unsigned int SpeedTable={
0x00E6,0x0C08,0x00FA,0x0000,0x00F0,0x0000,0x1900,0x0000,0x0000,0x0000,
0x0BB8,0x0BB7,0x0BB4,0x0BB0,0x0BAA,0x0BA1,0x0B98,0x0B8C,0x0B7F,0x0B70,
0x0B60,0x0B4E,0x0B3B,0x0B26,0x0B10,0x0AF9,0x0AE0,0x0AC7,0x0AAC,0x0A91,
0x0A74,0x0A57,0x0A39,0x0A1A,0x09FB,0x09DB,0x09BB,0x099A,0x0979,0x0958,
0x0936,0x0914,0x08F3,0x08D1,0x08AF,0x088D,0x086B,0x0849,0x0828,0x0807,
0x07E6,0x07C5,0x07A4,0x0784,0x0764,0x0744,0x0725,0x0706,0x06E8,0x06CA,
0x06AC,0x068F,0x0672,0x0656,0x063A,0x061F,0x0604,0x05E9,0x05CF,0x05B5,
0x059C,0x0583,0x056B,0x0553,0x053C,0x0525,0x050E,0x04F8,0x04E3,0x04CD,
0x04B9,0x04A4,0x0490,0x047D,0x0469,0x0456,0x0444,0x0432,0x0420,0x040F,
0x03FE,0x03ED,0x03DD,0x03CD,0x03BD,0x03AE,0x039F,0x0390,0x0382,0x0373,
0x0366,0x0358,0x034B,0x033E,0x0331,0x0324,0x0318,0x030C,0x0300,0x02F5,
0x02E9,0x02DE,0x02D3,0x02C9,0x02BE,0x02B4,0x02AA,0x02A0,0x0297,0x028D,
0x0284,0x027B,0x0272,0x0269,0x0260,0x0258,0x0250,0x0248,0x0240,0x0239,
0x0232,0x022B,0x0224,0x021E,0x0218,0x0211,0x020C,0x0206,0x0200,0x01FB,
0x01F6,0x01F1,0x01EC,0x01E7,0x01E3,0x01DE,0x01DA,0x01D6,0x01D2,0x01CE,
0x01CA,0x01C6,0x01C3,0x01BF,0x01BC,0x01B8,0x01B5,0x01B2,0x01AF,0x01AC,
0x01A9,0x01A6,0x01A3,0x01A0,0x019E,0x019B,0x0198,0x0196,0x0194,0x0191,
0x018F,0x018D,0x018B,0x0189,0x0186,0x0184,0x0183,0x0181,0x017F,0x017D,
0x017B,0x0179,0x0178,0x0176,0x0175,0x0173,0x0172,0x0170,0x016F,0x016D,
0x016C,0x016B,0x0169,0x0168,0x0167,0x0166,0x0165,0x0163,0x0162,0x0161,
0x0160,0x015F,0x015E,0x015D,0x015D,0x015C,0x015B,0x015A,0x0159,0x0158,
0x0158,0x0157,0x0156,0x0156,0x0155,0x0154,0x0154,0x0153,0x0153,0x0152,
0x0152,0x0151,0x0151,0x0151,0x0150,0x0150,0x0150,0x014F,0x014F,0x014F,
0x014E,0x014E,0x014E,0x014E,0x014E,0x014E,0x014E,0x014D,0x014D,0x014D,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0003,0x0002,0x0003,0x0003,0x0002,0x0003,0x0003,0x0003,0x0002,0x0003,
0x0003,0x0003,0x0002,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,
0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0004,0x0003,0x0003,0x0004,
0x0003,0x0004,0x0003,0x0004,0x0003,0x0004,0x0004,0x0004,0x0003,0x0004,
0x0004,0x0004,0x0005,0x0004,0x0004,0x0004,0x0005,0x0004,0x0005,0x0005,
0x0004,0x0005,0x0005,0x0005,0x0005,0x0005,0x0006,0x0005,0x0005,0x0006,
0x0006,0x0005,0x0006,0x0006,0x0006,0x0006,0x0007,0x0006,0x0006,0x0007,
0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0007,
0x0008,0x0008,0x0009,0x0008,0x0008,0x0009,0x0009,0x0009,0x0009,0x0009,
0x0009,0x000A,0x0009,0x000A,0x000A,0x000A,0x000A,0x000B,0x000A,0x000B,
0x000B,0x000B,0x000B,0x000B,0x000C,0x000B,0x000C,0x000C,0x000D,0x000C,
0x000C,0x000D,0x000D,0x000D,0x000E,0x000D,0x000E,0x000E,0x000E,0x000E,
0x000E,0x000F,0x000F,0x000E,0x0010,0x000F,0x000F,0x0010,0x0010,0x000F,
0x0011,0x0010,0x0010,0x0011,0x0010,0x0011,0x0011,0x0012,0x0011,0x0011,
0x0012,0x0012,0x0012,0x0012,0x0012,0x0012,0x0013,0x0012,0x0013,0x0013,
0x0013,0x0013,0x0013,0x0013,0x0014,0x0013,0x0014,0x0014,0x0014,0x0014,
0x0014,0x0015,0x0014,0x0015,0x0014,0x0015,0x0015,0x0015,0x0015,0x0015,
0x0015,0x0015,0x0016,0x0015,0x0016,0x0016,0x0015,0x0016,0x0016,0x0016,
0x0016,0x0017,0x0016,0x0016,0x0017,0x0016,0x0017,0x0016,0x0017,0x0017,
0x0017,0x0017,0x0016,0x0018,0x0017,0x0017,0x0017,0x0017,0x0017,0x0018,
0x0017,0x0018,0x0017,0x0018,0x0017,0x0018,0x0017,0x0018,0x0018,0x0018,
0x0017,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,
0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0019
};
页: [1]
查看完整版本: 7段式S曲线脉冲误差问题求助