草庐IT

随机振动信号的特征——PSD(功率谱密度)

huangma. 2023-10-25 原文

理论知识

1、背景
信号可分为确定性信号和随机信号。确定性信号是每个时间点上的值可以用某个数学表达式或图标唯一地确定的信号;而随机信号(random signal),幅度未可预知但又服从一定统计特性的信号,又称不确定信号(百度百科的解释)。随机信号是普遍存在的,也不能用一个确切的数学公式来描述,因为也不能准确进行预测的信号。正是因为随机信号是随机的,所以只能用统计的方法进行描述,在一定的准确性或可信性范围内用统计学规律去表征随机信号的特性。
如果随机信号的概率特性不随时间变化而变化,则成为平稳随机信号。

2、统计特征量

以上这些统计学特征用于分析信号的特征,并计算出PSD,功能如下:
数学期望值,描述随机信号的平均值。
方差值,描述随机信号幅度变化的强度。
概率密度函数,是描述信号振幅数值的概率。
相关函数,描述随机信号的每两个具有一定时间间隔的幅度值之间的联系程度的数值,它是时间间隔的一个函数。
功率谱密度,描述随机信号在平均意义上的功率谱特性。

3、功率谱密度
由中心极限定理:大量相互独立的随机变量,其平均值正态分布。可知平稳随机信号是趋于正态分布的,所以可以用统计学上特征量来描述随机信号。平稳随机信号的数学期望基本为零,数学期望为0时,方差等于均方值,也就是平均功率。为了描述平均功率,需要使用频谱分析。对于一个随机信号而言,时域信息是杂乱无章的,唯一的确定性信息但是在统计意义下得到的,即幅值呈正态分布,均方值也就是平均功率是固定的。

根据帕塞瓦尔定理,信号在时域的总功率等于在频域的总功率,所以只需要对时域信号进行傅里叶变换即可转换到频域,得到频域分布,只需要将频域分布平方积分就可以得到功率谱密度(PSD)。
但是因为时域的信号是随机的,无法用数学表达式描述,随机信号的不满足傅里叶变换绝对值可积的条件,严格意义傅里叶变换不存在,也就无法通过傅里叶变换将时域转成频域。(傅里叶理论认为任何复杂的波形都可以分解成不同正弦波,而不同的正弦波也能叠加成复杂波形。)

为了解决这个问题,引入自相关函数,它反映了随机信号本身在不同时刻的相互关系,再直白一点:把一个信号平移一段距离,跟原来有多相似。自相关函数将信号的蕴含的周期信号识别出来,并将相位信息去掉(相位不影响平均功率)。

维纳-辛钦定理:功率谱密度函数与自相关是傅里叶变换对。即一个信号的功率密度谱,就是其自相关函数的傅里叶变换。

总结:随机信号的幅值是满足正态分布的,用它的自相关函数求均方值即得到功率谱密度(PSD),一个随机的信号(随机振动)用PSD来描述其特征。

理论实践
传感器采集的样本为离散的点,没必要把离散点还原为原始信号,直接将离散的点用普估计方法求PSD。普估计方法由周期图法和welch方法,周期图法属于有偏估计,误差很大,所以采用welch方法,python或matlab有welch方法的库函数,可直接调用求得PSD。

python代码示例

#该加速度传感器的数据是三轴的X/Y/Z,默认Z轴为1g。
#返回四个值分别为频率和三个轴的PSD值,可用于绘图
def get_psd(payload):
	SAMPLES_NUM = 1024
    TicksInSamplingTimePeriod = int(0.5 + (0.0025 / (1 / 32768)))
    Fs_Acc = 32768 / TicksInSamplingTimePeriod  # 400 Hz
    NFFT_Acc = 512  # SAMPLES_NUM_PER_PIN    # 512
    Sensitivity_Acc = 1 / 1024  # LSB = 1/1024 [g] for the +/-2g range
    window = hamming(M=NFFT_Acc)

    samples = np.array(struct.unpack("<{}h".format(SAMPLES_NUM * 3), payload))#从payload中解析出来数据sample
    samples = np.array(samples) * Sensitivity_Acc
    acc_x_units_g, acc_y_units_g, acc_z_units_g = samples[0::3], samples[1::3], samples[2::3]
    (freq_Acc, Pxxf_Acc) = welch(x=acc_x_units_g, fs=Fs_Acc, window=window, noverlap=NFFT_Acc / 2,
                                 nfft=NFFT_Acc, return_onesided=True, detrend=False)
    Pxxf_AccX_dBg = 10. * np.log10(abs(Pxxf_Acc) + epsilon)
    (freq_Acc, Pxxf_Acc) = welch(x=acc_y_units_g, fs=Fs_Acc, window=window, noverlap=NFFT_Acc / 2,
                                 nfft=NFFT_Acc, return_onesided=True, detrend=False)
    Pxxf_AccY_dBg = 10. * np.log10(abs(Pxxf_Acc) + epsilon)
    (freq_Acc, Pxxf_Acc) = welch(x=acc_z_units_g, fs=Fs_Acc, window=window, noverlap=NFFT_Acc / 2,
                                 nfft=NFFT_Acc, return_onesided=True, detrend=False)
    Pxxf_AccZ_dBg = 10. * np.log10(abs(Pxxf_Acc) + epsilon)
    return freq_Acc, Pxxf_AccX_dBg, Pxxf_AccY_dBg, Pxxf_AccZ_dBg

有关随机振动信号的特征——PSD(功率谱密度)的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  3. ruby - cucumber 特征和步骤定义 - 2

    我是Cucumber测试的新手。我创建了两个特征文件:events.featurepartner.feature并将我的步骤定义放在step_definitions文件夹中:./step_definitions/events.rbpartner.rbCucumber似乎在所有.rb文件中查找步骤信息。有没有办法限制该功能查看特定的步骤定义文件?我之所以要这样做,是因为即使我使用了--guess标志,我也会遇到不明确的匹配错误。我之所以要这样做,有以下几个原因。我正在测试CMS,并希望在不同的功能中测试每种不同的内容类型(事件和合作伙伴)。事件.特征Feature:AddpartnerA

  4. ruby - 如何在 Ruby 中生成一个非常大的随机整数? - 2

    我想在ruby​​中生成一个64位整数。我知道在Java中你有很多渴望,但我不确定你会如何在Ruby中做到这一点。另外,64位数字中有多少个字符?这是我正在谈论的示例......123456789999。@num=Random.rand(9000)+Random.rand(9000)+Random.rand(9000)但我认为这是非常低效的,必须有一种更简单、更简洁的方法来做到这一点。谢谢! 最佳答案 rand可以将范围作为参数:pa=rand(2**32..2**64-1)#=>11093913376345012184putsa.

  5. ruby-on-rails - 多次选择一个随机数,但绝不会两次选择相同的随机数 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?

  6. ruby - 以随机顺序将数组拆分为多个数组 - Ruby - 2

    我试图在每次运行时以随机顺序将一个名称数组拆分为多个数组。我知道如何拆分它们:name_array=["bob","john","rob","nate","nelly","michael"]array=name_array.each_slice(2).to_a=>[["bob","john"],["rob","nate"],["nelly","michael"]]但是,如果我希望它每次都以随机顺序吐出它们怎么办? 最佳答案 在做同样的事情之前,打乱数组。(Array#shuffle)name_array.shuffle.each_s

  7. ruby-on-rails - 特征未注册 : attribute name - 2

    完成这个有困难。我正在使用seed.rb+factory_girl来使用rakedb:seed填充数据库。(我知道固定装置存在,但我想以这种方式完成,这只是一个示例,数据库将填充复杂的关联对象。)我的种子.rb:require'factory_girl_rails'["QM","CDC","SI","QS"].eachdo|n|FactoryGirl.create(:grau,nome:n)end还有我的/factories/graus.rbFactoryGirl.definedofactory:graudonomeendend但是当我运行时:rakedb:seed我得到:rakeab

  8. Verilog使用inout信号的方法 - 2

    目录一、inout在设计文件中的使用方法1.1、inout的第一种使用方法1.2、inout实现的第二种使用方法1.3、inout使用总结 二、inout在仿真测试中的使用方法一、inout在设计文件中的使用方法在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPIFlash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。1.1、inout的第一种使用方法  实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电

  9. ruby - 生成X和Y之间的随机数,不包括某些数字 - 2

    有没有办法在ruby​​中生成介于1-100但不包括20、30和40之间的随机数?我可以做类似的事情defrandom_numberrandom_number=rand(100)whilerandom_number==20||30||40random_number=rand(100)endreturnrandom_numberend...但这似乎不是很有效(再加上那个特定的例子可能根本行不通)。有没有更简单的方法?任何帮助深表感谢! 最佳答案 创建一个1到100的数组。从该数组中删除不需要的元素。然后从数组中选择一个随机数。([*1

  10. ruby-on-rails - 给定长度的完全随机标识符 - 2

    我想生成一个包含数字、字母和特殊字符的给定(长度可能不同)长度的完全随机的“唯一”(我将确保使用我的模型)标识符例如:161551960578281|2.AQAIPhEcKsDLOVJZ.3600.1310065200.0-514191032|有人可以建议在RubyonRails中最有效的方法吗?编辑:重要:如果可能,请评论您提出的解决方案的效率,因为每次用户进入网站时都会使用它!谢谢 最佳答案 将其用于访问token与UUID不同。您不仅需要伪随机性,而且还需要加密安全PRNG.如果您真的不关心您使用的是什么字符(它们不会增加任何

随机推荐