You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用NumPy和SciPy创建指定上升沿的梯形信号及带过冲信号?

用NumPy生成带上升/下降沿的梯形波(解决周期<1的问题)

之前周期小于1时出错,核心原因是上升时间+下降时间必须小于周期,否则高电平持续时间会出现负数逻辑冲突。下面是鲁棒性强的实现方案:

实现代码

import numpy as np
import matplotlib.pyplot as plt

def generate_trapezoidal_wave(fs, duration, T, tr, tf, amp=1):
    # 参数校验:避免上升/下降时间之和超过周期
    if tr + tf >= T:
        raise ValueError("上升时间+下降时间必须小于周期T")
    
    t = np.linspace(0, duration, int(fs * duration), endpoint=False)
    t_mod = np.mod(t, T)  # 映射到单个周期内的时间点
    t_high = T - tr - tf  # 高电平持续时长
    
    # 分段计算信号值
    signal = np.where(
        t_mod < tr,
        amp * t_mod / tr,  # 上升沿:线性从0到目标幅度
        np.where(
            t_mod < tr + t_high,
            amp,  # 高电平保持阶段
            np.where(
                t_mod < T,
                amp * (T - t_mod) / tf,  # 下降沿:线性从目标幅度回到0
                0
            )
        )
    )
    return t, signal

# 测试:周期T=0.5s(小于1),上升/下降时间各0.1s
fs = 1000  # 采样率(Hz)
duration = 2  # 信号总时长(s)
T = 0.5
tr = 0.1
tf = 0.1

t, trapezoid = generate_trapezoidal_wave(fs, duration, T, tr, tf)

plt.plot(t, trapezoid)
plt.xlabel("时间 (s)")
plt.ylabel("幅度")
plt.title("梯形波(周期0.5s)")
plt.grid(True)
plt.show()

参数说明

  • fs:采样率,单位Hz
  • duration:信号总时长,单位s
  • T:周期,支持小于1的数值
  • tr:上升时间,需满足 tr < T - tf
  • tf:下降时间,需满足 tf < T - tr
  • amp:高电平幅度

带过冲的梯形波简便实现

过冲可以通过修改上升沿曲线实现:先超调到高于目标幅度,再通过指数衰减回到稳定高电平。下面是轻量实现:

实现代码

def generate_trapezoidal_with_overshoot(fs, duration, T, tr, tf, amp=1, overshoot=0.2, tau=0.02):
    if tr + tf >= T:
        raise ValueError("上升时间+下降时间必须小于周期T")
    
    t = np.linspace(0, duration, int(fs * duration), endpoint=False)
    t_mod = np.mod(t, T)
    t_high = T - tr - tf
    
    # 带过冲的上升阶段:先线性超调,再指数衰减回目标幅度
    rise_phase = amp * (1 + overshoot) * t_mod / tr
    overshoot_phase = amp * (1 + overshoot) * np.exp(-(t_mod - tr)/tau)
    # 确保衰减后不低于目标幅度
    overshoot_phase = np.maximum(overshoot_phase, amp)
    
    signal = np.where(
        t_mod < tr,
        rise_phase,
        np.where(
            t_mod < tr + tau*3,  # 取3倍衰减常数作为过冲收敛时间
            overshoot_phase,
            np.where(
                t_mod < tr + tau*3 + t_high,
                amp,
                np.where(
                    t_mod < T,
                    amp * (T - t_mod) / tf,
                    0
                )
            )
        )
    )
    return t, signal

# 测试
t, overshoot_wave = generate_trapezoidal_with_overshoot(fs, duration, T, tr, tf, overshoot=0.2, tau=0.02)

plt.plot(t, overshoot_wave)
plt.xlabel("时间 (s)")
plt.ylabel("幅度")
plt.title("带过冲的梯形波")
plt.grid(True)
plt.show()

参数说明

  • overshoot:过冲比例,例如0.2表示超调20%
  • tau:过冲衰减时间常数,数值越小衰减速度越快

内容的提问来源于stack exchange,提问作者Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:06:32