基于音频和SCADA数据融合的诊断方案测试报告

Author

叶月光

Published

January 10, 2025

目录

1. 模型概述

1.1 模型针对的问题

主要识别机组运行过程中的异响或噪音,以使得无人场站或监控人员进行关注异响来源;

  • 变桨时异响;

  • 偏航异响;

  • 机组转动过程中的异响等,比如齿轮箱或发电机运行过程中的异响等;

  • 其他异响:如打雷、风暴、爆音、尖叫等其他异常侵入或的机组子系统的报警声等其他声音;

1.2 模型原理

1.2.1 基本原理

机组运行异响主要通过机组的运行状态和机组的音频录音融合识别,通过机组的各子系统的工作状态和机组的录音文件进行时间点的关联。

  • 读取机组的运行状态数据和音频文件列表;

  • 读取机组的变桨系统的状态点、偏航系统的状态点、转速(如有齿轮箱时可考虑发电机和齿轮箱的不同转速)

  • 时间点关联:对各子系统的动作时间和音频采集时间进行关联;

  • 状态识别:对不同的子系统的状态进行降维归一化,多个子系统动作时,进行归一化,降低数据的状态遗漏;

  • 音频文件读取与特征选择:倒谱计算并选择波动最大的谱系数。

  • 识别谱系数波动较大的情况并进行结合状态信息,噪音与哪些状态同时产生,诊断信息合并。

1.2.2 算法说明

  • 读取状态数据字段相关数据:
  • 音频信息获取:读取对应设备对应时间的音频数据文件基本信息列表;

  • 状态数据处理分别对偏航动作和变桨动作变化(差分检测)进行降维处理,降维到一维,判别变桨动作的时间点和偏航动作的时间点,输出布尔量。

  • 音频数据处理:对音频数据文件信息的时间信息进行解析,确保格式和状态数据的日期时间格式类型一致;

  • 状态数据和音频数据关联:时间点最近距离法进行关联,状态数据的时间和音频数据的对应的时间进行关联;同时,关联上的还有对应时间点的音频文件路径信息

  • 音频读取计算:对关联上的不同时间点音频文件进行读取,并进行将音频信号的音量调整到标准单位水平(使得音频信号统一归一化到16位,归一化可以提高可听性,确保所有的声音细节都能被听到)。具体来说,主要是提高或降低音频信号的响度,使其在播放时达到预定的音量标准。

  • 音频信号的梅尔频率倒谱系数(MFCC)计算:计算的梅尔频率倒谱系数15个特征系数值;

  • MFCC异常系数计算:通过标准差识别变化最大的特征系数,抽取系数中波动最大的记录进行识别并设定变化参数(标准差>4.5时表示异响noise_exist存在)作为噪音识别条件(一般是1阶系数特征最明显);

  • 最大特征系数波动的峰值点计算:通过峰值点计算识别音符的峰值或音频信号的瞬时强度变化(设置参数峰值点peak_range > 20);

  • 异响条件:如果noise_exist或峰值点超过设定值,说明异响存在;

  • 信息输出异响来源:如果状态信息中多次变桨时出现异响,则告警信息输出机组变桨时出现异响。如果偏航时出现异响但机组没有变桨时出现的异响,则告警信息输出机组偏航时有异响;如果机组同时变桨和偏航时多次出现异响但只是偏航时没有发现异响,则告警信息也输出机组变桨时出现异响。

1.2.2.1 峰值点计算原理

峰值点主要目的是在给定的一维数值数据(时间序列)中找到局部峰值(局部最大值)。局部峰值(或极大值)就是在特定范围内的值大于其周围的值。具体来说,给定一个数值序列 ( x[i] ),如果满足以下条件,则 ( x[i] ) 是一个局部峰值:

\[ x[i] > x[i-1] \quad \text{且} \quad x[i] > x[i+1] \]

这意味着当前值大于其左侧和右侧的值。为了解决噪声和小的波动,计算时引入“上升步骤”(nups)和“下降步骤”(ndowns)的概念。即:

  • nups: 在达到峰值之前,数据必须经历至少 ( nups ) 次连续的上升。
  • ndowns: 在峰值之后,数据必须经历至少 ( ndowns ) 次连续的下降。

这可以用以下条件表示:

\[ \text{从 } x[i-nups] \text{ 到 } x[i] \text{ 的值应是单调递增的。} \] \[ \text{从 } x[i] \text{ 到 } x[i+ndowns] \text{ 的值应是单调递减的。} \]

需要注意零值处理方法,即相同值的后续步骤一般做不计入上升下降处理。比如zero参数设置:

  • “+”: 将相同值视为“上升”。
  • “-”: 将相同值视为“下降”。
  • “0”: 将相同值视为“特殊”,不计入上升或下降,默认设置参数为不计入。

计算时可调的参数峰值高度和距离:

  • minpeakheight: 峰值必须超过的最小高度。
  • minpeakdistance: 峰值之间的最小距离(以索引为单位)。

峰值点的计算主要过程:

  • 遍历数值序列,检查每个数据点。
  • 判断当前点是否满足局部峰值的条件(包括上升与下降步骤,以及其他用户定义的条件)。
  • 如果满足条件,则记录该峰值的高度、位置和开始与结束的索引。

1.2.2.2 梅尔频率倒谱系数(MFCC)计算原理

梅尔频率倒谱系数(MFCC)是一种广泛用于音频信号处理、语音识别及音乐信息检索的特征表示方法。MFCC通过模拟人耳对声音频率的感知特性,将音频信号转换为一组特征向量。梅尔频率尺度是一种基于人耳听觉感知的非线性频率尺度。其定义为:

\[ f_{mel} = 2595 \cdot \log_{10}(1 + \frac{f}{700}) \]

其中,( f ) 是赫兹(Hz)为单位的频率,(f_{mel} ) 是梅尔频率。

短时傅里叶变换(STFT):为了计算MFCC,首先需要对音频信号进行短时傅里叶变换(STFT),将信号从时域转换到频域。STFT的公式为:

\[ X(t, f) = \sum_{n=-\infty}^{\infty} x[n] \cdot w[n - t] \cdot e^{-j 2 \pi f n} \]

其中,( x[n] ) 是时域信号,( w[n] ) 是窗函数,( t ) 是时间索引,( f ) 是频率索引。

梅尔滤波器组:在频域中,将信号通过梅尔滤波器组。梅尔滤波器组的设计基于梅尔频率尺度,通常使用三角形滤波器。每个滤波器的输出可以表示为:

\[ Y_m = \sum_{k} X_k \cdot H_{mk} \]

其中,( Y_m ) 是梅尔频率通道的输出,( X_k ) 是STFT的频谱值,( H_{mk} ) 是第( m )个梅尔滤波器对频率( k )的响应。

对数运算:对梅尔滤波器组的输出取对数,以增强特征的可分性:

\[ Z_m = \log(Y_m) \]

离散余弦变换(DCT):最后,通过离散余弦变换(DCT)将对数梅尔频率特征转换为MFCC:

\[ c_n = \sum_{m=0}^{M-1} Z_m \cdot \cos\left(\frac{\pi n}{M} \left(m + \frac{1}{2}\right)\right) \]

其中,( c_n ) 是第( n )个MFCC系数,( M ) 是梅尔滤波器的数量。梅尔频率倒谱系数(MFCC)通过将音频信号转换为梅尔频率特征,并利用对数运算和离散余弦变换,提取出能够有效表示音频特征的向量。这使得MFCC在语音识别和音频分析中成为一种重要的特征表示方法。

1.3 模型计算周期

音频文件:音频文件采集时长10秒一个,因此状态数据与音频数据关联时,时间差不超过14秒(即音频录音的时间偏差不超过相邻2条状态数据的时间差);

计算周期:2小时-24小时计算1次均可,根据实际需求进行可调范围;

2. 测试案例

2.1 案例说明

由于没有案例,从状态数据的状态标识上进行识别同时间的音频信号对应的机组状态与子系统的状态。同时播放音频通过人耳进行判别录音中是否存在异响。

可以参考的音频路径:

机组1(532528038):\10.12.3.224\532528\10000038\西安翔讯\

本地参数配置测试:

pjmResult$ScadaWTID =  '532528038'  
pjmResult$trigger_time = '2024-07-24 23:59:59'
pjmResult$apath =  "\\\\10.12.3.224\\e\\CMSDATA\\AUDIODATA\\532528\\10000038\\西安翔讯/2024-07-23/"

机组2(532528031):\10.12.3.224\532528\10000031\西安翔讯\

本地参数配置测试:

pjmResult$ScadaWTID =  '532528031'  
pjmResult$trigger_time = '2024-08-01 23:59:59'  # 实时库没有数据,云服务有数据
pjmResult$apath = apath = "\\\\10.12.3.224\\e\\CMSDATA\\AUDIODATA\\532528\\10000031\\西安翔讯/2024-07-31/"

3. 模型测试

3.1 测试方案

因数据文件和案例所限,测试的音频文件参考:\\10.12.3.224\e\CMSDATA\AUDIODATA

3.2 测试结果说明

3.2.1 非偏航非变桨状态停机状态测试

没有明显异常噪音的,机组没有偏航动作或变桨动作且音频数据中没有明显异常声响的表现示例:

音频播放效果:

3.2.2 同时偏航变桨动作发电状态时音频特征测试

音频效果示例

"\\\\10.12.3.224\\e\\CMSDATA\\AUDIODATA\\532528\\10000031\\西安翔讯/2024-07-31/2024-07-31-17-23-38_192.168.182.81_0.000_2.3_17.6_2.9_5.wav" 

音频示例

"\\\\10.12.3.224\\e\\CMSDATA\\AUDIODATA\\532528\\10000031\\西安翔讯/2024-07-31/2024-07-31-14-37-59_192.168.182.82_0.000_2.2_14.1_2.8_5.wav" 

3.2.3 变桨时机组出现异响

"\\\\10.12.3.224\\e\\CMSDATA\\AUDIODATA\\532528\\10000031\\西安翔讯/2024-07-31/2024-07-31-17-37-42_192.168.182.81_0.000_2.3_7.1_2.7_5.wav" 

3.2.4 详细的告警结果

3.2.4.1 输出表示例

如果按1天计算周期,对多个音频文件进行测试,测试结果统计如下:

报警结果汇总,去除非报警的记录统计

3.2.4.2 告警特征图示例

汇总告警的多个告警的图如下图所示,将告警特征融合成动图示例如下所示:

3.2.4.3 未触发告警特征示例图

3.2.4.4 测试结果显示的不足

在测试第二个样例时,大部分机组未触发异常告警,只有少部分的音频中发现异响,异响的原因从音频的信息中可以看出,主要集中在维护、停机过程、停机、待机、启动过程中,因此,在运行的结果汇总表中也应该添加上一个机组的状态。触发的少部分音频记录中的异响状态音频文件示例如下:

从上面的这个从停机过程到维护、启动的过程中的异响可以考虑去除。217条可匹配的音频检测中只有15条异响且在停机维护过程中出现,因此可判断532528038在2024年7月23日中的音频异响检测中确定机组运行中未发现异响。

3.3 测试快照

初步测试,快照如上图所示,对于文本描述的长度和对齐方式前端是默认居中,对于长短不一的情况看起来效果可考虑润色。

3.4 模型适用场景

适用于具有机组运行的秒级状态数据和音频数据的场景,两种数据中缺少状态数据则识别时不能确定机组的具体状态,缺少音频数据则不适用于本次研究对象。

3.5 测试说明

对于只有音频数据的场景,没有SCADA运行数据的情况,考虑独立的音频的异响识别;

当前测试只对单独的一台机组音频数据进行测试,未批量的全场测试;

当前的音频文件一部分是wav音频,一部分加密无法直接播放和读取,给分析带来了不便

3.6 下一步规划说明

下一步测试:

  • 剔除异响中的机组维护中的异响、停机、待机过程中的异响,保留运行过程中的异响(添加风速、功率的条件,小风极低的功率或停机的功率条件下的异响与非运行条件下的异响可以考虑剔除);

  • 下一步需要继续考虑缺少状态数据时的音频识别和根据基本信息获取音频数据的方法;

  • fems上搜集异响案例和反馈文件测试;

  • 根据数据与案例样本进一步识别变桨异响、偏航异响、发电机转动异响、齿轮箱异响


附录

鉴于测试图例较多,报警和不报警的图不进行一一展示,将多图融合成一个动图文件,方便查看。这里先附录图片生成动态的代码,方便以后使用参考(比如有新的案例图添加到对应的案例文件夹内,直接运行下面的代码,可以更新动图)。

library(magick)
# 告警可视化图片播放
ap = '.\\images\\no_warning_pics'
image_files = list.files(ap,full.names = T,recursive  = F,ignore.case = T)
# 读取图片并合成动图
images <- image_read(image_files)
# 生成动图,设置每帧持续时间为500毫秒
animated_gif <- image_animate(images, fps = 10)
# 保存动图到本地
image_write(animated_gif, "animated_image_nowarning.gif")
library(magick)
# 告警可视化图片播放
ap = '.\\images\\warning_pics'
image_files = list.files(ap,full.names = T,recursive  = F,ignore.case = T)
# 读取图片并合成动图
images <- image_read(image_files)
# 生成动图,设置每帧持续时间为500毫秒
animated_gif <- image_animate(images, fps = 10)
# 保存动图到本地
image_write(animated_gif, "animated_image_warning.gif")