首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何用Python来区分信号的下降边缘?

我如何用Python来区分信号的下降边缘?
EN

Stack Overflow用户
提问于 2014-07-21 19:08:44
回答 1查看 2.9K关注 0票数 1

我正致力于判别一些信号,用于计算弹簧质量系统(地震计)的自由周期振荡和阻尼比。我正在使用Python作为主要的处理程序。我需要做的是导入这个信号,解析这个信号,找出下降的边缘,然后从每个振荡的顶部返回一个峰值列表,这样我就可以计算阻尼比了。一旦我确定了数据集中振荡的位置,自由周期的计算就相当简单了。

我主要挂起的地方是如何解析列表,识别下降的边缘,然后捕获每个Z0..Zn元素。振荡频率可以很容易地使用FFT计算,一旦我知道下降的边缘在哪里,但是如果我处理整个文件,释放前系统的能量会迫使算法踢出一个超低频,它代表接近DC的偏移量,而不是实际的振荡。(尤其是在阻尼比较高的情况下,可能只有4到5个可测量的篮板)。

有人知道我该怎么做吗?现在,下面的代码对屏幕截图中的信号使用任意赋值。但是,我需要让代码计算这些值。此外,我还没有决定如何创建我的峰值列表,以计算阻尼比h。您帮助我们一起解决这个问题是非常受欢迎的。由于我有这么小的堆栈溢出的声誉,我已经把我的信号包括在一个示例屏幕截图在以下链接:(孩子,我希望这是可行的!)泰乔样本信号->

Damping%20Ratio.jpg

代码语言:javascript
复制
##########################################################
import os, sys, csv
from scipy import signal
from scipy.integrate import simps
import pylab as plt
import numpy as np
import scipy as sp
#
# code goes here that imports the data from the csv file into lists.
# One of those lists is called laser, a time-history list in counts from an analog-digital-converter
# sample rate is 130.28 samples / second.
#
                                      #            
                                      # Find the period of the observed signal
                                      #
delta = 0.00767                       # Calculated elsewhere in code, represents 130.28 samples/sec
                                      # laser is a list with about 20,000 elements representing time-history data from a laser position sensor
                                      # The release of the mass and system response occurs starting at sample number 2400 in this particular instance.

sense = signal.detrend(laser[2400:(2400+8192)]) # Remove the mean of the signal
N = len(sense)
W    = np.fft.fft(sense)
freq = np.fft.fftfreq(len(sense),delta) # First value represents the number of samples and delta is the sample rate

                                      #
                                      # Take the sample with the largest amplitude as our center frequency. 
                                      # This only works if the signal is heavily sinusoidal and stationary 
                                      # in nature, like our calibration data.
                                      #

idx = np.where(abs(W)==max(np.abs(W)))[0][-1]
Frequency = abs(freq[idx]) # Frequency in Hz
period = 1/(Frequency*delta) # represents the number of samples for one cycle of the test signal.
                                      #
                                      # create an axis representing time.
                                      #

dt = [] # Create an x axis that represents elapsed time in seconds. delta = seconds per sample, i represents sample count
for i in range(0,len(sensor)):
    dt.append(i*delta)


                                      #
                                      # At this point, we know the frequency interval, the delta, and we have the arrays 
                                      # for signal and laser. We can now discriminate out the peaks of each rebound and use them to process the damping ratio of either the 'undamped' system or the damping ratio of the 'electrically damped' system.
                                      #

print 'Frequency calcuated to ',Frequency,' Hz.'
EN

回答 1

Stack Overflow用户

发布于 2014-07-21 21:13:01

这里有一个有点非常规的想法,我认为它可能相当健壮,不需要太多的启发和猜测。您拥有的数据非常高质量,符合已知的曲线,所以这在这里有很大帮助。在这里,我假设你曲线的“好部分”是这样的:

代码语言:javascript
复制
V = a * exp(-γ * t) * cos(2 * π * f * t + φ) + V0     # [Eq1]
  • V:电压
  • t:时间
  • γ:阻尼常数
  • f:频率
  • a:起始振幅
  • φ:起始阶段
  • V0:直流偏置

算法概要

消除偏移量

首先是数值计算导数。由于数据质量很高,噪音对事物的影响不应该太大。

电压导数V_deriv具有与原始数据相同的形式:相同的频率和阻尼常数,但具有不同的相位ψ和振幅b

代码语言:javascript
复制
V_deriv = b * exp(-γ * t) * cos(2 * π * f * t + ψ)         # [Eq2]

好的是,这将自动摆脱您的DC偏移量

Alternative:这一步并不是完全需要的--偏移量是曲线拟合的一个相对较小的复杂因素,因为您可以通过平均整个曲线来为偏移量提供一个很好的猜测。交换条件是,如果你不使用导数,你就能得到更好的信号对噪声。

初步猜测

现在,考虑导数的曲线(如果跳过最后一步,则考虑原始曲线)。从最右边的数据点开始,然后尽可能地向左移动,直到达到幅度大于某个振幅阈值A的振荡为止。你想要找到一段曲线,其中包含一个振荡,有一个很好的信噪比

如何确定振幅阈值很难说。这取决于你的传感器有多好。我建议将此作为参数,以便稍后进行调整。

曲线拟合

现在您已经捕获了一个振荡,您可以做很多简单的事情:估计频率f和阻尼常数γ。使用这些初始估计,您可以对该振荡右侧的所有数据执行 非线性曲线拟合 (包括振荡本身)。

如果使用导数,则适合的函数是Eq2,如果使用原始曲线,则为Eq1 (但它们无论如何都是相同的函数,因此没有意义)。

你为什么需要这些初步估计?对于与衰减波相适应的非线性曲线,对参数,特别是频率和阻尼常数,给出一个很好的初步猜测是非常关键的。其他参数相对来说不太重要(至少这是我的经验),但下面是一些其他参数的方法,以防万一:

  • 如果您从最大值开始,则阶段是0,如果从最小值开始,则为π
  • 您也可以猜到起始幅度,尽管拟合算法通常会做得很好,即使您只是将其设置为1

找边

在这一点上,曲线拟合应该是非常好的--你可以看出来,因为你的曲线和适合度之间的差异非常低。现在,诀窍是试图将曲线的域增加到左边的。

如果你停留在正弦波区域,曲线拟合应该保持相当好(你如何判断“善良”需要一些实验)。然而,一旦你到达曲线的平坦区域,误差就会急剧增加,参数也会开始偏离。这可以用来确定“好”数据的结束位置。

不过,你不需要逐点做这件事--这是相当低效的。在这里,二进制搜索应该运行得很好(可能是它的“单边”变体)。

摘要

您不需要遵循这个精确的过程,但是基本的要点是您可以对从右边开始的一小部分数据执行一些分析,然后逐渐增加时间域,直到您发现错误越来越大,而不是应该是更小的。

此外,您还可以将不同的启发式方法结合起来,以查看它们是否一致。如果他们没有,那么这可能是一个相当粗略的数据点,需要一些人工干预。

请注意,我上面描述的算法的一个特别的优点是,您将得到您想要的结果(阻尼常数和频率)作为过程的一部分,以及不确定性估计。

我忽略了大部分血淋淋的数学和算法细节,以提供一个总体的概述,但如果需要,我可以提供更多的细节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24872785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档