搜索
bottom↓
回复: 19

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

[复制链接]

出50入135汤圆

发表于 2023-9-26 11:15:25 | 显示全部楼层 |阅读模式
各位大佬,小弟参考S形加减速,使用python编写了对应的程序。生成了对应的速度曲线,对速度曲线每隔1ms进行采样,并计算1ms里面对应的速度点发多少个脉冲,累计下来算出整个行程的脉冲个数,发现总的脉冲个数与我设定的值存在一定的偏差,请问各位大佬有什么好办法解决没?

阿莫论坛20周年了!感谢大家的支持与爱护!!

有一句段子是这样说的,身家过亿的只关心自己的身体,身家千万的,在担心传承,勉强糊口度日才天天看国际新闻,关心国家大事。

出50入135汤圆

 楼主| 发表于 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=[JCal(i) for i in x]
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=[ACal(i) for i in x]
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=[VCal(i) for i in x]
#计算定时器匹配值
mcuDaata=[round(1/i*1000000*16/2) for i in vt]
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=[i/1600*60 for i in vt]
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=[round(SCal(i)) for i in x]
print(st[len(x)-1])
#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()

出50入135汤圆

 楼主| 发表于 2023-9-26 11:22:39 | 显示全部楼层
我设定的脉冲个数为6400个,通过速度采样计算出来的脉冲个数6334,少了66个脉冲,按脉冲计算的时间为427ms,程序规划的时候是431ms。主要问题还是要脉冲个数与设置的相等.

出10入12汤圆

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

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

出50入135汤圆

 楼主| 发表于 2023-9-26 11:29:46 来自手机 | 显示全部楼层
终止速度不零,实际使用不能有偏差

出50入135汤圆

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

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

出50入135汤圆

 楼主| 发表于 2023-9-26 15:20:52 | 显示全部楼层
本帖最后由 Stm32Motor 于 2023-9-26 15:24 编辑

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2023-9-26 15:44:53 | 显示全部楼层
楼主可以把源代码更新一下,给大家一个学习模板

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

出0入115汤圆

发表于 2023-9-26 16:10:54 来自手机 | 显示全部楼层
偏差必然有,只能四舍五入不同频率段下的步数,总步数准确就行了。

出50入135汤圆

 楼主| 发表于 2023-9-26 16:33:04 | 显示全部楼层
boycn 发表于 2023-9-26 15:44
楼主可以把源代码更新一下,给大家一个学习模板

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

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

出50入135汤圆

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

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

出50入135汤圆

 楼主| 发表于 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曲线网上有详细的规划方法。

出0入115汤圆

发表于 2023-9-26 16:42:12 来自手机 | 显示全部楼层
动态算单片机也可以的,s模型不能太复杂,我以前做过标准7段s加减速,arm算好频率和步数后,发给fpga运行,说实话,s加减速和t型加减速我感觉都差不多,除了用来水论文,t型加减速大部分工程完全够用了

出50入135汤圆

 楼主| 发表于 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[TAB3_LEN]={\n  '
    for x in list_data:
        list_str += '0x{:04X},  '.format(x-34)  #转换成十六进制并大写
        #print(x)
        index+=1
        if  index%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=[JCal(i) for i in x]
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=[ACal(i) for i in x]
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=[VCal(i) for i in x]
#计算定时器匹配值
mcuDaata=[round(1/i*1000000*16/2) for i in vt]
#计算真实时间与实际脉冲个数

Rvt=[i/1600*60 for i in vt]
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=[round(SCal(i)) for i in x]
ff=np.diff(st)
totalsteps=0
totaltime=0
for i in range(len(ff)):
    totalsteps=totalsteps+(ff[i])
    totaltime=totaltime+(ff[i])*round(mcuDaata[i]/16*2)

totaltime=totaltime/1000

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

data=list()
for i in range(len(ff)):
    for j in range(ff[i]):
        data.append(mcuDaata[i])  
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()

出50入135汤圆

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

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

出100入85汤圆

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

期待你讲讲fpga加减速

出10入12汤圆

发表于 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并且和最大加速度一样大时。 或者路程非常小只有几个脉冲时。  

出50入135汤圆

 楼主| 发表于 2023-9-27 08:47:09 | 显示全部楼层
本帖最后由 Stm32Motor 于 2023-9-27 08:49 编辑

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

出50入135汤圆

 楼主| 发表于 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/

出50入135汤圆

 楼主| 发表于 2023-9-27 17:36:55 | 显示全部楼层
以下为生成数据样本,在Atmega128上使用一个16MHz的定时器。
//20230927--17:34:48
//目标步数=6400
//启动速度=100
//最大速度=900
//最大加速度=9000
//最大加加速度=60000
//实际最大速度=900
//实际最大加速度=6928
//规划步数=6400
//耗时=472.145
//data[0]=数据长度  data[1]=加速步数 data[2]=脉冲个数超始地址 data[3]=匀速步数高16位 data[4]=匀速步数低16位
//data[5]=总步数高16位 data[6]=总步数低16位
#define TAB_LEN 480
__flash unsigned int SpeedTable[TAB_LEN]={
  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
};
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-12-10 13:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表