曲线生成:Python实现S型曲线、摆线曲线与修正梯形曲线

好,咱们进入第三章。前两章我们把电子凸轮的基础概念和数学工具捋了一遍,现在该动真格的了——用Python把三种最常用的运动曲线写出来。

我个人习惯,写曲线生成代码之前,先想清楚一件事:这个曲线用在什么场景? 你想想看,S型曲线适合启停平稳的场合,摆线曲线适合高速轻载,修正梯形曲线则是两者的折中。搞混了,机器就该抖了。

3.1 S型曲线生成

S型曲线,说白了就是让速度从零慢慢加速,再慢慢减速。它没有加速度突变,所以冲击最小。我在项目中遇到过一台贴片机,用梯形曲线时末端抖动得厉害,换成S型曲线后,定位精度直接提升了0.02mm。

它的核心公式其实不复杂,就是分段函数。我一般把整个运动分成七段:加加速、匀加速、减加速、匀速、加减速、匀减速、减减速。嗯,这里要注意,如果行程太短,匀加速段和匀减速段可能会消失。

import numpy as np

def s_curve_generate(t, T, S):
    """
    生成S型曲线位置
    t: 当前时间
    T: 总时间
    S: 总位移
    """
    # 归一化时间
    tau = t / T
    
    # 七段S型曲线位置公式
    if tau <= 1/8:
        # 加加速段
        pos = 2 * S * tau**2
    elif tau <= 3/8:
        # 匀加速段
        pos = S * (8*tau - 1) / 8
    elif tau <= 1/2:
        # 减加速段
        pos = S * (1 - 2*(1-2*tau)**2) / 2
    elif tau <= 5/8:
        # 匀速段
        pos = S * (4*tau - 1) / 4
    elif tau <= 7/8:
        # 加减速段
        pos = S * (1 - 2*(tau-5/8)**2) / 2
    elif tau <= 1:
        # 匀减速段
        pos = S * (1 - (1-tau)**2)
    else:
        pos = S
    
    return pos

# 生成100个点
t_array = np.linspace(0, 1, 100)
pos_array = [s_curve_generate(t, 1, 100) for t in t_array]
我的小技巧: 调试S型曲线时,先画速度曲线看看。如果速度曲线有尖角,说明分段点没算对。我曾经花了一整天找bug,最后发现是匀加速段的时间比例算错了。

3.2 摆线曲线生成

摆线曲线,也叫Cycloidal曲线。它的特点是速度曲线是正弦波,加速度曲线是余弦波。说白了,就是让运动像车轮上一点滚过的轨迹一样平滑。

为什么用摆线?因为它的加速度变化率(Jerk)是连续的,没有突变。我在做高速分拣机时,摆线曲线是首选。不过要注意,摆线曲线的最大加速度比S型曲线大,所以不适合重载。

def cycloidal_curve_generate(t, T, S):
    """
    生成摆线曲线位置
    t: 当前时间
    T: 总时间
    S: 总位移
    """
    tau = t / T
    
    # 摆线曲线位置公式
    pos = S * (tau - np.sin(2*np.pi*tau) / (2*np.pi))
    
    return pos

# 生成100个点
pos_array = [cycloidal_curve_generate(t, 1, 100) for t in t_array]
避坑指南: 我曾经在一条包装线上用摆线曲线,结果末端执行器在高速时出现振动。后来发现是摆线曲线的加速度在起点和终点不为零,导致与前后运动衔接时产生冲击。解决办法是在曲线两端各加一段过渡段。

3.3 修正梯形曲线生成

修正梯形曲线,是梯形曲线和S型曲线的混血儿。它保留了梯形曲线的高效率,又加入了S型曲线的平滑特性。怎么做到的?就是把梯形曲线的直角拐角处,用圆弧或正弦曲线过渡一下。

我个人觉得,修正梯形曲线是工程中最实用的。它不像S型曲线那么复杂,又比梯形曲线平滑。我在很多项目中都用它,比如数控机床的进给轴、印刷机的滚筒。

def modified_trapezoidal_generate(t, T, S):
    """
    生成修正梯形曲线位置
    t: 当前时间
    T: 总时间
    S: 总位移
    """
    tau = t / T
    
    # 修正梯形曲线位置公式
    if tau <= 1/8:
        # 加速段(正弦过渡)
        pos = S * (tau - np.sin(4*np.pi*tau) / (4*np.pi))
    elif tau <= 3/8:
        # 匀速段
        pos = S * (2*tau - 1/4)
    elif tau <= 1/2:
        # 减速段(正弦过渡)
        pos = S * (1 - (tau - 1/2) + np.sin(4*np.pi*(tau-3/8)) / (4*np.pi))
    else:
        pos = S
    
    return pos

# 生成100个点
pos_array = [modified_trapezoidal_generate(t, 1, 100) for t in t_array]
关键对比: 三种曲线的最大加速度比值大约是——S型:摆线:修正梯形 = 1:1.57:1.33。摆线最大加速度最大,S型最小。选型时,如果电机扭矩有限,优先考虑S型;如果追求效率,修正梯形更合适。

3.4 三种曲线对比分析

好了,三种曲线都写出来了。咱们做个对比,方便你选型时参考。

特性 S型曲线 摆线曲线 修正梯形曲线
加速度连续性 连续 连续 连续
最大加速度
运动效率
适用场景 重载、高精度 高速轻载 通用场合
代码复杂度 高(7段) 低(1段) 中(4段)

你想想看,如果只是做简单的传送带,用梯形曲线就够了。但要是做精密定位,比如芯片封装,那就必须上S型曲线。摆线曲线嘛,适合那些对加速度不敏感、但要求速度快的场合。

三种曲线生成流程对比 S型曲线(7段) 加加速 → 匀加速 → 减加速 匀速 → 加减速 → 匀减速 → 减减速 摆线曲线(1段) 正弦函数位置公式 速度连续,加速度连续 修正梯形曲线(4段) 加速(正弦过渡)→ 匀速 减速(正弦过渡)→ 停止 选型建议 ● S型曲线:重载、高精度定位 ● 摆线曲线:高速轻载、连续运动 ● 修正梯形曲线:通用场合、效率优先 最大加速度:S型 < 修正梯形 < 摆线 代码复杂度:摆线 < 修正梯形 < S型 运动效率:S型 < 摆线 < 修正梯形

嗯,代码写完了,但别急着用。我建议你先把三种曲线画出来看看,确认位置、速度、加速度曲线都平滑。我曾经在调试时发现加速度曲线有毛刺,最后查出来是浮点数精度问题——把时间步长改小就好了。

调试小技巧: 用matplotlib把位置、速度、加速度三条曲线画在同一张图上。如果速度曲线有折点,说明分段函数没衔接好;如果加速度曲线有跳变,说明Jerk不连续。这两种情况都会导致机器振动。

好了,这一章就到这儿。三种曲线都给你了,代码可以直接拿去用。记住,没有最好的曲线,只有最合适的曲线。选型时多想想你的机器到底需要什么——是精度?是速度?还是两者兼顾?


公众号:蓝海资料掘金营,微信deep3321