DiagnosisLib.py 89 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006
  1. """
  2. @Time : 2024-03-04
  3. @Author : Wei
  4. @FileName: DiagnosisLib.py
  5. @Software: 故障诊断函数库
  6. """
  7. import numpy as np
  8. import matplotlib.pyplot as plt
  9. from math import pi
  10. from scipy import signal
  11. from scipy import interpolate
  12. import math
  13. class DiagnosisLib:
  14. def __init__(self):
  15. pass
  16. ###############################################################################
  17. ###############################################################################
  18. # 半带滤波器系数
  19. def halfbandcoefficient(self):
  20. halfbandcoefficient = np.array([0.00000063557331607068,0,-0.00000627255234261115,0,0.00002474955105003003,0,\
  21. -0.00007140981582044673,0,0.00017237915446870680,0,-0.00036863887543283979,0,\
  22. 0.00072039609678193576,0,-0.00131147951710543810,0,0.00225360507770744260,0,\
  23. -0.00369069002024503300,0,0.00580407535380912750,0,-0.00882079299392407940,0,\
  24. 0.01302944110367636400,0,-0.01881320502983020000,0,0.02672090662754737100,0,\
  25. -0.03762627155576255700,0,0.05311294860790129200,0,-0.07653440360979835200,0,\
  26. 0.11663131038150232000,0,-0.20562506738991029000,0,0.63439761518650584000,1,\
  27. 0.63439761518650584000,0,-0.20562506738991029000,0,0.11663131038150232000,0,\
  28. -0.07653440360979835200,0,0.05311294860790129200,0,-0.03762627155576255700,0,\
  29. 0.02672090662754737100,0,-0.01881320502983020000,0,0.01302944110367636400,0,\
  30. -0.00882079299392407940,0,0.00580407535380912750,0,-0.00369069002024503300,0,\
  31. 0.00225360507770744260,0,-0.00131147951710543810,0,0.00072039609678193576,0,\
  32. -0.00036863887543283979,0,0.00017237915446870680,0,-0.00007140981582044673,0,\
  33. 0.00002474955105003003,0,-0.00000627255234261115,0,0.00000063557331607068])
  34. return halfbandcoefficient
  35. ###############################################################################
  36. ###############################################################################
  37. # 计算时域波形均值
  38. def Average(self,xTimeWave):
  39. return sum(xTimeWave) / len(xTimeWave)
  40. ###############################################################################
  41. ###############################################################################
  42. # 计算时域波形xTimeWave的频谱
  43. # fs是时域波形的采样频率,单位是Hz
  44. # 调用代码须保证输入时域波形xTimeWave的数据点数为2的N幂
  45. # 频谱计算默认采用汉宁窗
  46. # 输出为频谱的x轴freq即频率,单位是Hz, 和频谱的y轴,单位是时域波形的幅值单位
  47. # x轴和y轴的数据点数为输入时域波形xTimeWave数据点数的1/2.56倍+1,即1024点时域波形
  48. # 输出频谱的x轴和y轴分别有401点数据,2048点时域波形时,输出频谱的x轴和y轴分别有801点数据。
  49. def Spectrum(self,xTimeWave,fs):
  50. DataLen = len(xTimeWave)
  51. xSpec = abs(np.fft.fft((xTimeWave*np.hanning(DataLen))))/DataLen*4
  52. freq = np.arange(0, fs / 2.56 + fs / DataLen, fs / DataLen)
  53. return [freq, xSpec[0:int(DataLen/2.56)+1]]
  54. ###############################################################################
  55. ###############################################################################
  56. # 计算时域波形xTimeWave的幅值谱倒频谱
  57. # fs是时域波形的采样频率,单位是Hz
  58. # 调用代码须保证输入时域波形xTimeWave的数据点数为2的N幂
  59. # 输出为倒谱的x轴quefrency,单位是秒,倒谱的幅值单位是dB
  60. def Cepstrum(self,xTimeWave,fs):
  61. # cepstrum = np.abs(np.fft.ifft(np.log(np.absolute(np.fft.fft(xTimeWave)))))
  62. cepstrum = 20*np.log((np.abs(np.fft.ifft(np.log(np.abs(np.fft.fft(xTimeWave))))))/0.1)
  63. quefrency = np.array(range(len(xTimeWave)))/fs
  64. return [quefrency,cepstrum]
  65. ###############################################################################
  66. ###############################################################################
  67. # 计算频谱xSpec的固定频率特征值,xSpec是频谱的y轴数组,其数据点数为101,201,401,801,1601,3201,6401,12801
  68. # fMax是频谱的分析频宽,单位为Hz
  69. # fTarget是特征频率的目标值,单位为Hz。比如轴的转频,齿轮啮合频率,水泵叶片通过频率等等
  70. # fRange是特征频率的搜索范围,其输入值根据fRangeMode的不同值而不一样,
  71. # fRangeMode可以赋值0或1,默认值是0。当fRangeMode = 0时,fRange的值是xx%, 比如 2%(实际输入为0.02) ,
  72. # 此时搜索范围是 fTarge +/- fTarge*fRange/2。
  73. # 当fRangeMode = 1时,fRange的值是频率值,比如2Hz,
  74. # 此时的搜索范围就是 fTarge +/- fRange/2
  75. # Detection是特征值的峰值(此时输入0),有效值(输入1),峰峰值(输入2)
  76. # numHarmonics为谐波数,0代表不需要考虑谐波即只有特征频率的基频,1代表包括基频和2倍频,2代表包括基频和2、3倍频
  77. # def FixedFreqFeature(self,xSpec, fMax, fTarget, fRange, fRangeMode, Detection, numHarmonics):
  78. # # if fRangeMode == '百分比':
  79. # # fRange = fRange*fTarget
  80. # # if fRangeMode == '数值':
  81. # # fRange = fRange
  82. # if fRangeMode == 'Per':
  83. # fRange = fRange*fTarget
  84. # if fRangeMode == 'Num':
  85. # fRange = fRange
  86. # # print(fRange)
  87. # SpecResolution = fMax/(len(xSpec)-1)
  88. # index_SearchRangeMax = int(math.ceil((fTarget + fRange/2)/SpecResolution))
  89. # index_SearchRangeMin = int(math.floor((fTarget - fRange/2)/SpecResolution))
  90. # if index_SearchRangeMin < 3:
  91. # index_SearchRangeMin = 3
  92. # index_SearchRange = index_SearchRangeMax - index_SearchRangeMin
  93. # xArray = xSpec[index_SearchRangeMin:(index_SearchRangeMax+1)]
  94. # while((int(np.argmax(xArray))==0) or (int(np.argmax(xArray))==len(xArray)-1)):
  95. # index_SearchRangeMin = index_SearchRangeMin -1
  96. # index_SearchRange = index_SearchRange + 1
  97. # xArray = xSpec[int(index_SearchRangeMin-math.floor(index_SearchRange/2)):int(index_SearchRangeMin+math.ceil(index_SearchRange/2+1))]
  98. # ActualTargetFreq = self.FundamentalFreqActualValue(xArray, SpecResolution,index_SearchRangeMin)
  99. # # print(ActualTargetFreq)
  100. # featureValue = self.FreqFeatureValue(xSpec, SpecResolution, ActualTargetFreq, index_SearchRange, Detection, numHarmonics)
  101. # return featureValue
  102. def FixedFreqFeature(self, xSpec, fMax, fTarget, fRange, fRangeMode, Detection, numHarmonics):
  103. if fRangeMode == 'Per':
  104. fRange = fRange * fTarget
  105. if fRangeMode == 'Num':
  106. fRange = fRange
  107. SpecResolution = fMax / (len(xSpec) - 1)
  108. index_SearchRangeMax = int(math.ceil((fTarget + fRange / 2) / SpecResolution))
  109. index_SearchRangeMin = int(math.floor((fTarget - fRange / 2) / SpecResolution))
  110. if index_SearchRangeMin < 3:
  111. index_SearchRangeMin = 3
  112. # 检查索引是否有效
  113. if index_SearchRangeMin >= len(xSpec) or index_SearchRangeMax >= len(xSpec):
  114. return [0] * (numHarmonics + 1) # 返回全零数组
  115. index_SearchRange = index_SearchRangeMax - index_SearchRangeMin
  116. # 检查搜索范围是否有效
  117. if index_SearchRange <= 0:
  118. return [0] * (numHarmonics + 1) # 返回全零数组
  119. xArray = xSpec[index_SearchRangeMin:(index_SearchRangeMax + 1)]
  120. # 检查 xArray 是否为空
  121. if len(xArray) == 0:
  122. return [0] * (numHarmonics + 1) # 返回全零数组
  123. # 确保 xArray 不为空
  124. while (int(np.argmax(xArray))) == 0 or (int(np.argmax(xArray)) == len(xArray) - 1):
  125. index_SearchRangeMin = index_SearchRangeMin - 1
  126. index_SearchRange = index_SearchRange + 1
  127. xArray = xSpec[int(index_SearchRangeMin - math.floor(index_SearchRange / 2)):int(index_SearchRangeMin + math.ceil(index_SearchRange / 2 + 1))]
  128. # 再次检查 xArray 是否为空
  129. if len(xArray) == 0:
  130. return [0] * (numHarmonics + 1) # 返回全零数组
  131. ActualTargetFreq = self.FundamentalFreqActualValue(xArray, SpecResolution, index_SearchRangeMin)
  132. featureValue = self.FreqFeatureValue(xSpec, SpecResolution, ActualTargetFreq, index_SearchRange, Detection, numHarmonics)
  133. return featureValue
  134. ###############################################################################
  135. ###############################################################################
  136. # 该函数只用于内部调用,其调用函数为 FixedFreqFeature
  137. def FundamentalFreqActualValue(self,xArray, SpecResolution, index_SearchRangeMin):
  138. indexPeak = int(self.PeakFinderInArray(xArray))
  139. indexCenter = int(indexPeak + index_SearchRangeMin)
  140. ActualFundamentalFreq = self.FrequencyCompensation(indexCenter,xArray[indexPeak],xArray[indexPeak-1],xArray[indexPeak+1],SpecResolution)
  141. return ActualFundamentalFreq
  142. ###############################################################################
  143. ###############################################################################
  144. # 该函数只用于内部调用,其调用函数为 FundamentalFreqActualValue
  145. def PeakFinderInArray(self,xArray):
  146. NoElements = len(xArray)
  147. index_peak = int(np.argmin(xArray)) # initialize the peak index with the minimal value's index
  148. peak = xArray[index_peak] # initialize the peak value with the minimal value
  149. for i in range(0, NoElements-2):
  150. if (xArray[i+1] > xArray[i]) and (xArray[i+1] > xArray[i+2]) and (xArray[i+1] > peak):
  151. index_peak = i+1
  152. peak = xArray[i+1]
  153. return index_peak
  154. ###############################################################################
  155. ###############################################################################
  156. # 该函数只用于内部调用,其调用函数为 FundamentalFreqActualValue
  157. def FrequencyCompensation(self,indexCenter, AmpCenter, AmpLeft, AmpRight, xSpecResolution):
  158. if AmpRight >= AmpLeft:
  159. delta_k = (2*AmpRight-AmpCenter)/(AmpRight+AmpCenter)
  160. else:
  161. delta_k = (AmpCenter-2*AmpLeft)/(AmpLeft+AmpCenter)
  162. ActualFrequency = (indexCenter + delta_k)*xSpecResolution
  163. return ActualFrequency
  164. ###############################################################################
  165. ###############################################################################
  166. # 该函数只用于内部调用,其调用函数为 FixedFreqFeature
  167. def FreqFeatureValue(self,xSpec, SpecResolution, ActualTargetFreq, index_SearchRange, Detection, numHarmonics = 0):
  168. sumation = 0
  169. # print(ActualTargetFreq)
  170. featureValue = []
  171. featureValue = [0 for i in range(numHarmonics+1)]
  172. for i in range(0,numHarmonics+1):
  173. index_i = int(round((i+1)*ActualTargetFreq/SpecResolution))
  174. a = xSpec[int(index_i-math.floor(index_SearchRange/2)):int(index_i+math.ceil(index_SearchRange/2+1))]
  175. while((int(np.argmax(a))==0) or (int(np.argmax(a))==len(a)-1)):
  176. index_SearchRange = index_SearchRange + 2
  177. a = xSpec[int(index_i-math.floor(index_SearchRange/2)):int(index_i+math.ceil(index_SearchRange/2+1))]
  178. indexPeak = int(self.PeakFinderInArray(a) + index_i-math.floor(index_SearchRange/2))
  179. # print(int(index_i-math.floor(index_SearchRange/2)),indexPeak,int(index_i+math.ceil(index_SearchRange/2)))
  180. for j in range(indexPeak-2,indexPeak+2+1):
  181. sumation = sumation + xSpec[j]*xSpec[j]
  182. featureValue[i] = np.sqrt(sumation/1.5)
  183. sumation = 0
  184. # print(featureValue[i])
  185. # if Detection == '峰值':
  186. # pass
  187. # if Detection == '有效值':
  188. # featureValue = [x/math.sqrt(2) for x in featureValue]
  189. # if Detection == '峰峰值':
  190. # featureValue = [x*2 for x in featureValue]
  191. if Detection == 'Peak':
  192. pass
  193. if Detection == 'RMS':
  194. featureValue = [x/math.sqrt(2) for x in featureValue]
  195. if Detection == 'PP':
  196. featureValue = [x*2 for x in featureValue]
  197. return featureValue
  198. ###############################################################################
  199. ###############################################################################
  200. # 计算频域积分
  201. # xSpecOrig需要对其计算积分的频谱数组,其长度为:101,201,401,801,1601,3201,6401,12801
  202. # fMax为频谱的分析频宽,单位为Hz
  203. # fCut为计算积分的低频截止频率,单位为Hz
  204. def FreqIntegration(self,xSpecOrig, fMax, fCut):
  205. nLine = len(xSpecOrig) - 1
  206. lineResolution = fMax / nLine
  207. iStarting = int(math.floor(fCut / lineResolution))
  208. if iStarting == 0:
  209. iStarting = 1
  210. xSpecOut = np.zeros(len(xSpecOrig))
  211. for i in range(iStarting, len(xSpecOrig)):
  212. xSpecOut[i] = xSpecOrig[i]/(2*pi*lineResolution*i)
  213. return xSpecOut
  214. ###############################################################################
  215. ###############################################################################
  216. # 巴特沃斯高通滤波
  217. # xTimeWave是时域波形数组, fs是采样频率,单位为Hz
  218. # fco 为高通截止频率,单位为Hz
  219. # Order为滤波器阶数,通常为偶数,2,4,6,8一般不超过8
  220. def HighPassButter(self,xTimeWave, fs, fco, Order):
  221. sos = signal.butter(Order, fco/(fs/2), 'hp', output='sos')
  222. filtered = signal.sosfilt(sos, xTimeWave)
  223. return filtered
  224. ###############################################################################
  225. ###############################################################################
  226. # 巴特沃斯低通滤波
  227. # xTimeWave是时域波形数组, fs是采样频率,单位为Hz
  228. # fco 为低通截止频率,单位为Hz
  229. # Order为滤波器阶数,通常为偶数,2,4,6,8一般不超过8
  230. def LowPassButter(self,xTimeWave, fs, fco, Order):
  231. sos = signal.butter(Order, fco/(fs/2), 'lp', output='sos')
  232. filtered = signal.sosfilt(sos, xTimeWave)
  233. return filtered
  234. ###############################################################################
  235. ###############################################################################
  236. # 计算包络
  237. # xTimeWave是时域波形数组
  238. # DownSampleRate是降采样率,调用函数需提供此数值,其计算公式为
  239. # 原始波形xTimeWave的分析频宽/包络后时域波形的分析频宽,比如原始波形分析频宽是10000Hz(采样频率是25600Hz),包络后时域
  240. # 波形的分析频宽是1000Hz,那 DownSampleRate = 10000/1000 = 10
  241. # Method是SKF的包络方法,还是PeakHold包络方法
  242. def EnvLopInTime(self,xTimeWave, DownSampleRate, Method = "SKF"):
  243. xOut = np.zeros(math.floor(len(xTimeWave)/DownSampleRate))
  244. if Method == "SKF":
  245. scale = 2.2
  246. xTimeWave = np.absolute(scale*xTimeWave)
  247. w = 1/(1.28*DownSampleRate)
  248. Order = 4
  249. sos = signal.butter(Order, w, 'lp', output='sos')
  250. xTimeWave = signal.sosfilt(sos, xTimeWave)
  251. xOut =xTimeWave[::DownSampleRate]
  252. if Method == "PeakHold":
  253. for i in range(0, len(xOut)):
  254. xOut[i] = np.amax(np.absolute(xTimeWave[i*DownSampleRate:((i+1)*DownSampleRate-1)]))
  255. return xOut - np.mean(xOut)
  256. ###############################################################################
  257. ###############################################################################
  258. # 内部调用函数
  259. def DownSampleBy2(self,xTimeWave):
  260. xTimeWave = signal.resample_poly(xTimeWave, 1, 2)
  261. return xTimeWave
  262. def DownSampleBy4(self,xTimeWave):
  263. xTimeWave = signal.resample_poly(xTimeWave,1,4)
  264. return xTimeWave
  265. def DownSampleBy5(self,xTimeWave):
  266. xTimeWave = signal.resample_poly(xTimeWave,1,5)
  267. return xTimeWave
  268. def DownSampleBy8(self,xTimeWave):
  269. xTimeWave = signal.resample_poly(xTimeWave,1,8)
  270. return xTimeWave
  271. def DownSampleBy10(self,xTimeWave):
  272. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  273. return xTimeWave
  274. def DownSampleBy20(self,xTimeWave):
  275. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  276. xTimeWave = signal.resample_poly(xTimeWave,1,2)
  277. return xTimeWave
  278. def DownSampleBy40(self,xTimeWave):
  279. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  280. xTimeWave = signal.resample_poly(xTimeWave,1,4)
  281. return xTimeWave
  282. def DownSampleBy50(self,xTimeWave):
  283. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  284. xTimeWave = signal.resample_poly(xTimeWave,1,5)
  285. return xTimeWave
  286. def DownSampleBy80(self,xTimeWave):
  287. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  288. xTimeWave = signal.resample_poly(xTimeWave,1,8)
  289. return xTimeWave
  290. def DownSampleBy100(self,xTimeWave):
  291. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  292. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  293. return xTimeWave
  294. def DownSampleBy200(self,xTimeWave):
  295. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  296. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  297. xTimeWave = signal.resample_poly(xTimeWave,1,2)
  298. return xTimeWave
  299. def DownSampleBy400(self,xTimeWave):
  300. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  301. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  302. xTimeWave = signal.resample_poly(xTimeWave,1,4)
  303. return xTimeWave
  304. def DownSampleBy500(self,xTimeWave):
  305. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  306. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  307. xTimeWave = signal.resample_poly(xTimeWave,1,5)
  308. return xTimeWave
  309. def DownSampleBy800(self,xTimeWave):
  310. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  311. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  312. xTimeWave = signal.resample_poly(xTimeWave,1,8)
  313. return xTimeWave
  314. def DownSampleBy1000(self,xTimeWave):
  315. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  316. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  317. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  318. return xTimeWave
  319. def DownSampleBy2000(self,xTimeWave):
  320. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  321. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  322. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  323. xTimeWave = signal.resample_poly(xTimeWave,1,2)
  324. return xTimeWave
  325. def DownSampleBy4000(self,xTimeWave):
  326. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  327. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  328. xTimeWave = signal.resample_poly(xTimeWave,1,10)
  329. xTimeWave = signal.resample_poly(xTimeWave,1,4)
  330. return xTimeWave
  331. def DownSample(self, xTimeWave, fsIn, fsOut, nPointIn, nPointOut):
  332. #输入: xTimeWave: 时域波形数据
  333. # Fs: xTimeWave波形数据的采样频率(Hz)
  334. # fs: 降采样后时域波形数据的采样频率(Hz)
  335. # nPointIn: 输入波形的数据点数
  336. # nPointOut: 返回的波形的数据点数
  337. #
  338. #返回: 返回一个长度为nPointOut的时域波形数组
  339. DownSampleRate = int(fsIn/fsOut)
  340. if int(nPointIn/nPointOut) < DownSampleRate:
  341. print('Input data length is not enough')
  342. return -1
  343. if DownSampleRate == 2:
  344. return self.DownSampleBy2(xTimeWave[0:int(nPointOut*2)])
  345. if DownSampleRate == 4:
  346. return self.DownSampleBy4(xTimeWave[0:int(nPointOut*4)])
  347. if DownSampleRate == 5:
  348. return self.DownSampleBy5(xTimeWave[0:int(nPointOut*5)])
  349. if DownSampleRate == 8:
  350. return self.DownSampleBy8(xTimeWave[0:int(nPointOut*8)])
  351. if DownSampleRate == 10:
  352. return self.DownSampleBy10(xTimeWave[0:int(nPointOut*10)])
  353. if DownSampleRate == 20:
  354. return self.DownSampleBy20(xTimeWave[0:int(nPointOut*20)])
  355. if DownSampleRate == 40:
  356. return self.DownSampleBy40(xTimeWave[0:int(nPointOut*40)])
  357. if DownSampleRate == 50:
  358. return self.DownSampleBy50(xTimeWave[0:int(nPointOut*50)])
  359. if DownSampleRate == 100:
  360. return self.DownSampleBy100(xTimeWave[0:int(nPointOut*100)])
  361. if DownSampleRate == 200:
  362. return self.DownSampleBy200(xTimeWave[0:int(nPointOut*200)])
  363. if DownSampleRate == 400:
  364. return self.DownSampleBy400(xTimeWave[0:int(nPointOut*400)])
  365. if DownSampleRate == 500:
  366. return self.DownSampleBy500(xTimeWave[0:int(nPointOut*500)])
  367. if DownSampleRate == 1000:
  368. return self.DownSampleBy1000(xTimeWave[0:int(nPointOut*1000)])
  369. if DownSampleRate == 2000:
  370. return self.DownSampleBy2000(xTimeWave[0:int(nPointOut*2000)])
  371. if DownSampleRate == 4000:
  372. return self.DownSampleBy4000(xTimeWave[0:int(nPointOut*4000)])
  373. ###############################################################################
  374. ###############################################################################
  375. def OrderAnalysis(self, xTimeWave, Fs, xTimeSpeedPulse, nPulsePerRev, nRev, nLine, TransLevel, TransLevelPara):
  376. #输入: xTimeWave: 时域波形数据
  377. # Fs: xTimeWave波形数据的采样频率(Hz)
  378. # xTimeSpeedPulse: 相邻转速脉冲信号的时间间隔(s)
  379. # nPulsePerRev: 每周的脉冲个数
  380. # nRev: 阶次分析整周数(整周数必须是2的N次幂,比如:4、8、16、32、64、128、256、512等等)
  381. # nLine: 阶次频谱的谱线数(谱线数可选项为:100、200、400、800、1600、3200、6400)
  382. # TransLevel: 阶次分析轴与转速测量轴的转速等级关系,
  383. # 0:表示阶次分析轴与转速分析轴是同一根轴
  384. # 1:表示阶次分析轴与转速分析轴不在同一根轴上,有1次转速比变化
  385. # 2:表示阶次分析轴与转速分析轴不在同一根轴上,有2次转速比变化
  386. # 3:表示阶次分析轴与转速分析轴不在同一根轴上,有3次转速比变化, 以此类推
  387. # TransLevelPara: 齿轮齿数数组,
  388. # 当 TransLevel == 0 时,这个数组只有1个元素,可以是[0]
  389. # 当 TransLevel == 1 时,有一对齿轮啮合,2根轴。这个数组有2个元素,第一个元素是转速测量轴(1轴)上的齿轮齿数,
  390. # 第二个元素是与转速测量轴啮合(2轴)的齿轮的齿数,
  391. # 当 TransLevel == 2 时,有二对齿轮啮合,3根轴。这个数组有4个元素,第一个元素是转速测量轴(2轴)上的齿轮齿数,
  392. # 第二个元素是与转速测量轴啮合(2轴)的齿轮的齿数,第三个元素是2轴与下一级(3轴)啮合的齿轮的齿数,
  393. # 第四个元素是3轴与2轴啮合的齿轮的齿数。
  394. #返回: 等角度采样的角度轴坐标,等角度采样的波形,阶次谱的阶次轴坐标,阶次谱的幅值
  395. nRevSpeedSensorShaft = int(len(xTimeSpeedPulse)/nPulsePerRev) # 计算转速测量轴的转速测量信号有多少个整周数
  396. xTimeSpeedPulse = xTimeSpeedPulse[0:0+int(nRevSpeedSensorShaft*nPulsePerRev)] # 整周数以外多余的脉冲信号去掉
  397. xTimeSpeedPerRevSpeedSensorShaft = np.sum(np.reshape(xTimeSpeedPulse,(nRevSpeedSensorShaft,nPulsePerRev)),axis = 1) # 计算转速测量轴每转一周的时间
  398. if TransLevel == 0:
  399. xTimeSpeedPerRevCurrentShaft = xTimeSpeedPerRevSpeedSensorShaft
  400. xTimeSpeedPerRevCurrentShaft_ave = np.average(xTimeSpeedPerRevCurrentShaft) # 当转速测量轴就是阶次分析的轴时,转速脉冲可以直接使用
  401. fMax_MAX = 1/xTimeSpeedPerRevCurrentShaft_ave*nLine/nRev
  402. else:
  403. xTemp = np.cumsum(xTimeSpeedPerRevSpeedSensorShaft) # 转速脉冲时间累积
  404. xTemp = np.append(0,xTemp) # 添加起始点 # 当转速测量轴不是阶次分析轴时,传输脉冲信号必须转换到阶次分析轴上
  405. for i in range (TransLevel):
  406. up = TransLevelPara[i] # 转速测量轴齿轮齿数
  407. down = TransLevelPara[i+1] # 啮合轴齿轮齿数
  408. dataLength = int(len(xTemp)*up) # 转速测量轴增采样后的数据长度
  409. flipelements = int(len(xTemp)*0.5) # 转速信号加长50%防止长度不够
  410. extention = np.zeros(flipelements)
  411. for j in range(flipelements): # 转速信号加长算法,以最后一点为对称中心
  412. extention[j] = xTemp[-1]-(xTemp[-1-j-1]-xTemp[-1])
  413. xTemp1 = np.append(xTemp,extention) # 转速信号加长后的转速脉冲时间累积
  414. xTemp2 = np.zeros(xTemp1.size*(up),xTemp1.dtype)
  415. xTemp2[::up] = xTemp1 # 脉冲时间累积信号增采样,增采样率为转速测量轴齿轮的齿数
  416. # plt.figure(30)
  417. # plt.plot(xTemp2)
  418. #==============================================================
  419. delta1 = 0.00000001
  420. delta2 = 0.0000001
  421. freq1 = 0.39/up
  422. freq2 = 0.61/up
  423. AA = np.matrix([[-4.278e-1,-4.761e-1,0],[-5.941e-1,7.114e-2,0],[-2.66e-3,5.309e-03,0]])
  424. d1 = np.log10(delta1)
  425. d2 = np.log10(delta2)
  426. D = np.array([1,d1,d1*d1])*AA*np.array([[1],[d2],[d2*d2]])
  427. bb = np.array([11.01217,0.51244])
  428. fK = np.dot(np.array([1.0,(d1-d2)]),bb)
  429. df = np.abs(freq2-freq1)
  430. N = int(D[0]/df-fK*df+1)
  431. if np.remainder(N,2) == 0:
  432. N = N+1
  433. upSampleFilterCoefficients = signal.remez(N, [0,0.39,0.61,up/2], [1,0],Hz = up,maxiter = 500)
  434. # [freq, response] = signal.freqz(upSampleFilterCoefficients)
  435. # ampl = np.abs(response)
  436. # plt.figure(31)
  437. # plt.plot(freq,ampl)
  438. #==============================================================
  439. groupDelay = int((len(upSampleFilterCoefficients)+1)/2)
  440. xTemp3 = signal.convolve(xTemp2,upSampleFilterCoefficients)
  441. xTemp4 = (xTemp3[groupDelay-1:groupDelay-1+dataLength])*up
  442. plt.figure(30)
  443. plt.plot(xTemp4)
  444. xTemp5 = xTemp4[0::down]
  445. xTimeSpeedPerRevCurrentShaft = np.diff(xTemp5)
  446. xTimeSpeedPerRevCurrentShaft_ave = np.average(xTimeSpeedPerRevCurrentShaft) # 当转速测量轴就是阶次分析的轴时,转速脉冲可以直接使用
  447. fMax_MAX = 1/xTimeSpeedPerRevCurrentShaft_ave*nLine/nRev
  448. xTimeSpeedPerRevCurrentShaft_min = np.min(xTimeSpeedPerRevCurrentShaft) # 计算轴转得最快的一周的时间
  449. fMax_MAX = 1/xTimeSpeedPerRevCurrentShaft_min*nLine/nRev # 根据最快的一周的时间得出阶次频谱最高分析频宽的频率
  450. Order = 6
  451. if fMax_MAX <= Fs/2.56:
  452. xTimeWave = self.LowPassButter(xTimeWave, Fs, fMax_MAX, Order) # 低通滤波消除大于fMax_MAX的信号,然后才能做阶次分析
  453. xTimeSpeedCurrentShaftCumulative = np.cumsum(xTimeSpeedPerRevCurrentShaft) # 计算轴每转一周所用时间的累积值
  454. nVibDataPoint = nLine*2.56 # 计算时域波形点数
  455. up = nVibDataPoint/nRev # 计算每周等角度采样点数
  456. # down = 1
  457. halfbandWeight = self.halfbandcoefficient()
  458. groupDelay = int((len(halfbandWeight)+1)/2)
  459. numIteration = int(np.log10(up)/np.log10(2))
  460. temp = np.append(0,xTimeSpeedCurrentShaftCumulative)
  461. flipelements = int(len(temp)*0.5)
  462. extention = np.zeros(flipelements)
  463. for i in range(numIteration):
  464. dataLength = int(len(temp)*2)
  465. for j in range(flipelements):
  466. extention[j] = temp[-1]-(temp[-1-j-1]-temp[-1])
  467. temp1 = np.append(temp,extention)
  468. temp2 = np.insert(temp1,np.arange(1,len(temp1),1),0)
  469. temp3 = np.append(temp2,0)
  470. temp4 = signal.convolve(temp3,halfbandWeight)
  471. temp = temp4[groupDelay-1:groupDelay-1+dataLength]
  472. xTimeNewSamplePoint = temp
  473. flipelements = int(len(xTimeWave)*0.25)
  474. extention = np.zeros(flipelements)
  475. for j in range(flipelements):
  476. extention[j] = xTimeWave[-1]-(xTimeWave[-1-j-1]-xTimeWave[-1])
  477. xTimeWave = np.append(xTimeWave,extention)
  478. xTimeSamplePoint = np.arange(0,len(xTimeWave)/Fs,1/Fs) # 计算输入波形的采样时间点
  479. # spl = UnivariateSpline(xTimeSamplePoint,xTimeWave)
  480. # Waveform = spl(xTimeNewSamplePoint)
  481. fx = interpolate.interp1d(xTimeSamplePoint,xTimeWave,kind= 'cubic')
  482. Waveform = fx(xTimeNewSamplePoint)
  483. OrderWaveform = Waveform[0:int(nLine*2.56)]
  484. ct = 360/(nLine*2.56/nRev)
  485. orderTimeLine = np.arange(0,nLine*2.56*ct,ct)
  486. fOT = nLine*2.56/nRev
  487. fMax = fOT/2.56
  488. fCut = 10*fMax/nLine
  489. WinType = 0
  490. AverageType = 0
  491. OverLapType = 0
  492. [f, xSpectrum, xSpectrumPhase] = self.Spectrum(OrderWaveform,nLine,fMax,fCut,WinType, AverageType ,OverLapType) # 计算插值函数
  493. len(OrderWaveform)
  494. return [orderTimeLine, OrderWaveform, f, xSpectrum]
  495. ###############################################################################
  496. ###############################################################################
  497. def halfBandDesign(self, filterLength, transitionBand):
  498. invalidInput = False
  499. # check if integer
  500. if (np.abs(filterLength - int(filterLength)) > 1e-10):
  501. print('halfBandDesign.py: filterLength must be an integer')
  502. invalidInput = True
  503. # check if too small
  504. if (filterLength < 7):
  505. print('halfBandDesign.py: filterLength must be larger than 6')
  506. invalidInput = True
  507. # check if proper length
  508. if (np.mod(filterLength+1, 4) != 0):
  509. print('halfBandDesign.py: filterLength+1 must be divisble by 4')
  510. invalidInput = True
  511. # check range for transition band
  512. if (transitionBand <= 0 or transitionBand >= 0.5):
  513. print('halfBandDesign.py: transitionBand must be greater than 0 and less than 0.5')
  514. invalidInput = True
  515. if (invalidInput):
  516. return []
  517. else:
  518. # design a half band filter with remez
  519. cutoff = 0.25
  520. fPass = cutoff - (transitionBand/2)
  521. fStop = cutoff + (transitionBand/2)
  522. fVec = [0, fPass, fStop, 0.5]
  523. aVec = [1, 0]
  524. weights = signal.remez(filterLength, fVec, aVec)
  525. # force zero weights
  526. zeroWeightIndicesHalf = np.arange(2, (filterLength-1)/2, 2, dtype=int)
  527. zeroWeightIndicesNegative = np.concatenate((-zeroWeightIndicesHalf[::-1], zeroWeightIndicesHalf))
  528. zeroWeightIndices = zeroWeightIndicesNegative - zeroWeightIndicesNegative[0] + 1
  529. weights[zeroWeightIndices] = 0
  530. return weights
  531. ###############################################################################
  532. ###############################################################################
  533. # def Pk_Search_BW(self):
  534. # BW = 0.03
  535. # return BW
  536. ###############################################################################
  537. ###############################################################################
  538. # @staticmethod
  539. def gE_Bearing_Defect_HM_Threshhold(self,alert, danger, defectType):
  540. gE_Bearing_Defect_HM_alert = np.zeros(5)
  541. gE_Bearing_Defect_HM_danger = np.zeros(5)
  542. if defectType == 'BPFO' :
  543. gE_Bearing_Defect_HM_alert[0] = alert*0.167
  544. gE_Bearing_Defect_HM_alert[1] = alert*0.131
  545. gE_Bearing_Defect_HM_alert[2] = alert*0.098
  546. gE_Bearing_Defect_HM_alert[3] = alert*0.089
  547. gE_Bearing_Defect_HM_alert[4] = alert*0.082
  548. gE_Bearing_Defect_HM_danger[0] = danger*0.167
  549. gE_Bearing_Defect_HM_danger[1] = danger*0.131
  550. gE_Bearing_Defect_HM_danger[2] = danger*0.098
  551. gE_Bearing_Defect_HM_danger[3] = danger*0.089
  552. gE_Bearing_Defect_HM_danger[4] = danger*0.082
  553. return gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger
  554. if defectType == 'BPFI':
  555. gE_Bearing_Defect_HM_alert[0] = alert*0.088
  556. gE_Bearing_Defect_HM_alert[1] = alert*0.064
  557. gE_Bearing_Defect_HM_alert[2] = alert*0.056
  558. gE_Bearing_Defect_HM_alert[3] = alert*0.035
  559. gE_Bearing_Defect_HM_alert[4] = alert*0.024
  560. gE_Bearing_Defect_HM_danger[0] = danger*0.088
  561. gE_Bearing_Defect_HM_danger[1] = danger*0.064
  562. gE_Bearing_Defect_HM_danger[2] = danger*0.056
  563. gE_Bearing_Defect_HM_danger[3] = danger*0.035
  564. gE_Bearing_Defect_HM_danger[4] = danger*0.024
  565. return gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger
  566. if defectType == 'BSF':
  567. gE_Bearing_Defect_HM_alert[0] = alert*0.088
  568. gE_Bearing_Defect_HM_alert[1] = alert*0.064
  569. gE_Bearing_Defect_HM_alert[2] = alert*0.056
  570. gE_Bearing_Defect_HM_alert[3] = alert*0.035
  571. gE_Bearing_Defect_HM_alert[4] = alert*0.024
  572. gE_Bearing_Defect_HM_danger[0] = danger*0.088
  573. gE_Bearing_Defect_HM_danger[1] = danger*0.064
  574. gE_Bearing_Defect_HM_danger[2] = danger*0.056
  575. gE_Bearing_Defect_HM_danger[3] = danger*0.035
  576. gE_Bearing_Defect_HM_danger[4] = danger*0.024
  577. return gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger
  578. if defectType == 'FTF':
  579. gE_Bearing_Defect_HM_alert[0] = alert*0.088
  580. gE_Bearing_Defect_HM_alert[1] = alert*0.064
  581. gE_Bearing_Defect_HM_alert[2] = alert*0.056
  582. gE_Bearing_Defect_HM_alert[3] = alert*0.035
  583. gE_Bearing_Defect_HM_alert[4] = alert*0.024
  584. gE_Bearing_Defect_HM_danger[0] = danger*0.088
  585. gE_Bearing_Defect_HM_danger[1] = danger*0.064
  586. gE_Bearing_Defect_HM_danger[2] = danger*0.056
  587. gE_Bearing_Defect_HM_danger[3] = danger*0.035
  588. gE_Bearing_Defect_HM_danger[4] = danger*0.024
  589. return gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger
  590. ###############################################################################
  591. ###############################################################################
  592. # @staticmethod
  593. def Vel_Bearing_Defect_HM_Threshhold(self,alert, danger, defectType):
  594. Vel_Bearing_Defect_HM_alert = np.zeros(5)
  595. Vel_Bearing_Defect_HM_danger = np.zeros(5)
  596. if defectType == 'BPFO':
  597. Vel_Bearing_Defect_HM_alert[0] = alert*1.0
  598. Vel_Bearing_Defect_HM_alert[1] = alert*1.0
  599. Vel_Bearing_Defect_HM_alert[2] = alert*1.0
  600. Vel_Bearing_Defect_HM_alert[3] = alert*1.0
  601. Vel_Bearing_Defect_HM_danger[0] = danger*1.0
  602. Vel_Bearing_Defect_HM_danger[1] = danger*1.0
  603. Vel_Bearing_Defect_HM_danger[2] = danger*1.0
  604. Vel_Bearing_Defect_HM_danger[3] = danger*1.0
  605. return Vel_Bearing_Defect_HM_alert, Vel_Bearing_Defect_HM_danger
  606. if defectType == 'BPFI':
  607. Vel_Bearing_Defect_HM_alert[0] = alert*1.0
  608. Vel_Bearing_Defect_HM_alert[1] = alert*1.0
  609. Vel_Bearing_Defect_HM_alert[2] = alert*1.0
  610. Vel_Bearing_Defect_HM_alert[3] = alert*1.0
  611. Vel_Bearing_Defect_HM_danger[0] = danger*1.0
  612. Vel_Bearing_Defect_HM_danger[1] = danger*1.0
  613. Vel_Bearing_Defect_HM_danger[2] = danger*1.0
  614. Vel_Bearing_Defect_HM_danger[3] = danger*1.0
  615. return Vel_Bearing_Defect_HM_alert, Vel_Bearing_Defect_HM_danger
  616. if defectType == 'BSF':
  617. Vel_Bearing_Defect_HM_alert[0] = alert*1.0
  618. Vel_Bearing_Defect_HM_alert[1] = alert*0.5
  619. Vel_Bearing_Defect_HM_alert[2] = alert*0.5
  620. Vel_Bearing_Defect_HM_alert[3] = alert*0.5
  621. Vel_Bearing_Defect_HM_danger[0] = danger*1.0
  622. Vel_Bearing_Defect_HM_danger[1] = danger*0.5
  623. Vel_Bearing_Defect_HM_danger[2] = danger*0.5
  624. Vel_Bearing_Defect_HM_danger[3] = danger*0.5
  625. return Vel_Bearing_Defect_HM_alert, Vel_Bearing_Defect_HM_danger
  626. ###############################################################################
  627. ###############################################################################
  628. # @staticmethod
  629. def Vel_Bearing_RunningSpd_HM_Threshhold(self,alert, danger, defectType):
  630. Vel_Bearing_RunningSpd_HM_alert = np.zeros(5)
  631. Vel_Bearing_RunningSpd_HM_danger = np.zeros(5)
  632. if defectType == 'BSF':
  633. Vel_Bearing_RunningSpd_HM_alert[0] = alert*1.0
  634. Vel_Bearing_RunningSpd_HM_alert[1] = alert*0.5
  635. Vel_Bearing_RunningSpd_HM_alert[2] = alert*0.5
  636. Vel_Bearing_RunningSpd_HM_alert[3] = alert*0.5
  637. Vel_Bearing_RunningSpd_HM_alert[4] = alert*0.5
  638. Vel_Bearing_RunningSpd_HM_danger[0] = danger*1.0
  639. Vel_Bearing_RunningSpd_HM_danger[1] = danger*0.5
  640. Vel_Bearing_RunningSpd_HM_danger[2] = danger*0.5
  641. Vel_Bearing_RunningSpd_HM_danger[3] = danger*0.5
  642. Vel_Bearing_RunningSpd_HM_danger[4] = danger*0.5
  643. return Vel_Bearing_RunningSpd_HM_alert, Vel_Bearing_RunningSpd_HM_danger
  644. ###############################################################################
  645. ###############################################################################
  646. # @staticmethod
  647. def Vel_Unbalance_HM_Threshold(self,alert, danger):
  648. Vel_Unbalance_HM_alert = np.zeros(5)
  649. Vel_Unbalance_HM_danger = np.zeros(5)
  650. Vel_Unbalance_HM_alert[0] = alert*1.0
  651. Vel_Unbalance_HM_alert[1] = alert*0.5
  652. Vel_Unbalance_HM_alert[2] = alert*0.5
  653. Vel_Unbalance_HM_alert[3] = alert*0.5
  654. Vel_Unbalance_HM_alert[4] = alert*0.5
  655. Vel_Unbalance_HM_danger[0] = danger*1.0
  656. Vel_Unbalance_HM_danger[1] = danger*0.5
  657. Vel_Unbalance_HM_danger[2] = danger*0.5
  658. Vel_Unbalance_HM_danger[3] = danger*0.5
  659. Vel_Unbalance_HM_danger[4] = danger*0.5
  660. return Vel_Unbalance_HM_alert, Vel_Unbalance_HM_danger
  661. ###############################################################################
  662. ###############################################################################
  663. # @staticmethod
  664. def Vel_Misalignment_HM_Threshold(self,alert, danger):
  665. Vel_Misalignment_HM_alert = np.zeros(5)
  666. Vel_Misalignment_HM_danger = np.zeros(5)
  667. Vel_Misalignment_HM_alert[0] = alert*1.0
  668. Vel_Misalignment_HM_alert[1] = alert*0.5
  669. Vel_Misalignment_HM_alert[2] = alert*0.5
  670. Vel_Misalignment_HM_alert[3] = alert*0.5
  671. Vel_Misalignment_HM_alert[4] = alert*0.5
  672. Vel_Misalignment_HM_danger[0] = danger*1.0
  673. Vel_Misalignment_HM_danger[1] = danger*0.5
  674. Vel_Misalignment_HM_danger[2] = danger*0.5
  675. Vel_Misalignment_HM_danger[3] = danger*0.5
  676. Vel_Misalignment_HM_danger[4] = danger*0.5
  677. return Vel_Misalignment_HM_alert, Vel_Misalignment_HM_danger
  678. ###############################################################################
  679. ###############################################################################
  680. # @staticmethod
  681. def Vel_Looseness_HM_Threshold(self,alert, danger):
  682. Vel_Looseness_HM_alert = np.zeros(5)
  683. Vel_Looseness_HM_danger = np.zeros(5)
  684. Vel_Looseness_HM_alert[0] = alert*1.0
  685. Vel_Looseness_HM_alert[1] = alert*0.5
  686. Vel_Looseness_HM_alert[2] = alert*0.5
  687. Vel_Looseness_HM_alert[3] = alert*0.5
  688. Vel_Looseness_HM_alert[4] = alert*0.5
  689. Vel_Looseness_HM_danger[0] = danger*1.0
  690. Vel_Looseness_HM_danger[1] = danger*0.5
  691. Vel_Looseness_HM_danger[2] = danger*0.5
  692. Vel_Looseness_HM_danger[3] = danger*0.5
  693. Vel_Looseness_HM_danger[4] = danger*0.5
  694. return Vel_Looseness_HM_alert, Vel_Looseness_HM_danger
  695. ###############################################################################
  696. ###############################################################################
  697. # @staticmethod
  698. def gE_2XLF_HM_Threshhold(self,alert, danger):
  699. gE_2XLF_HM_alert = np.zeros(5)
  700. gE_2XLF_HM_danger = np.zeros(5)
  701. gE_2XLF_HM_alert[0] = alert*0.167
  702. gE_2XLF_HM_alert[1] = alert*0.131
  703. gE_2XLF_HM_alert[2] = alert*0.098
  704. gE_2XLF_HM_alert[3] = alert*0.089
  705. gE_2XLF_HM_alert[4] = alert*0.082
  706. gE_2XLF_HM_danger[0] = danger*0.167
  707. gE_2XLF_HM_danger[1] = danger*0.131
  708. gE_2XLF_HM_danger[2] = danger*0.098
  709. gE_2XLF_HM_danger[3] = danger*0.089
  710. gE_2XLF_HM_danger[4] = danger*0.082
  711. return gE_2XLF_HM_alert, gE_2XLF_HM_danger
  712. ###############################################################################
  713. ###############################################################################
  714. # @staticmethod
  715. def Vel_2XLF_HM_Threshhold(self,alert, danger):
  716. Vel_2XLF_HM_alert = np.zeros(1)
  717. Vel_2XLF_HM_danger = np.zeros(1)
  718. Vel_2XLF_HM_alert[0] = alert*1.0
  719. Vel_2XLF_HM_danger[0] = danger*1.0
  720. return Vel_2XLF_HM_alert, Vel_2XLF_HM_danger
  721. ###############################################################################
  722. ###############################################################################
  723. # @staticmethod
  724. def Acc_GMF_HM_Threshhold(self,alert, danger):
  725. Acc_GMF_HM_alert = np.zeros(3)
  726. Acc_GMF_HM_danger = np.zeros(3)
  727. Acc_GMF_HM_alert[0] = alert*1.0
  728. Acc_GMF_HM_alert[1] = alert*1.0
  729. Acc_GMF_HM_alert[2] = alert*1.0
  730. Acc_GMF_HM_danger[0] = danger*1.0
  731. Acc_GMF_HM_danger[1] = danger*1.0
  732. Acc_GMF_HM_danger[2] = danger*1.0
  733. return Acc_GMF_HM_alert, Acc_GMF_HM_danger
  734. ###############################################################################
  735. ###############################################################################
  736. # @staticmethod
  737. def Vel_GMF_HM_Threshhold(self,alert, danger):
  738. Vel_GMF_HM_alert = np.zeros(3)
  739. Vel_GMF_HM_danger = np.zeros(3)
  740. Vel_GMF_HM_alert[0] = alert*1.0
  741. Vel_GMF_HM_alert[1] = alert*1.0
  742. Vel_GMF_HM_alert[2] = alert*1.0
  743. Vel_GMF_HM_danger[0] = danger*1.0
  744. Vel_GMF_HM_danger[1] = danger*1.0
  745. Vel_GMF_HM_danger[2] = danger*1.0
  746. return Vel_GMF_HM_alert, Vel_GMF_HM_danger
  747. ###############################################################################
  748. ###############################################################################
  749. # @staticmethod
  750. def gE_GMF_HM_Threshhold(self,alert, danger):
  751. gE_GMF_HM_alert = np.zeros(3)
  752. gE_GMF_HM_danger = np.zeros(3)
  753. gE_GMF_HM_alert[0] = alert*0.167
  754. gE_GMF_HM_alert[1] = alert*0.131
  755. gE_GMF_HM_alert[2] = alert*0.098
  756. gE_GMF_HM_danger[0] = danger*0.167
  757. gE_GMF_HM_danger[1] = danger*0.131
  758. gE_GMF_HM_danger[2] = danger*0.098
  759. return gE_GMF_HM_alert, gE_GMF_HM_danger
  760. ###############################################################################
  761. ###############################################################################
  762. # @staticmethod
  763. def gE_GTIF_HM_Threshhold(self,alert, danger):
  764. gE_GTIF_HM_alert = np.zeros(5)
  765. gE_GTIF_HM_danger = np.zeros(5)
  766. gE_GTIF_HM_alert[0] = alert*0.167
  767. gE_GTIF_HM_alert[1] = alert*0.131
  768. gE_GTIF_HM_alert[2] = alert*0.098
  769. gE_GTIF_HM_alert[3] = alert*0.089
  770. gE_GTIF_HM_alert[4] = alert*0.082
  771. gE_GTIF_HM_danger[0] = danger*0.167
  772. gE_GTIF_HM_danger[1] = danger*0.131
  773. gE_GTIF_HM_danger[2] = danger*0.098
  774. gE_GTIF_HM_danger[3] = danger*0.089
  775. gE_GTIF_HM_danger[4] = danger*0.082
  776. return gE_GTIF_HM_alert, gE_GTIF_HM_danger
  777. ###############################################################################
  778. ###############################################################################
  779. # @staticmethod
  780. def Vel_VPF_HM_Threshhold(self,alert, danger):
  781. Vel_VPF_HM_alert = np.zeros(2)
  782. Vel_VPF_HM_danger = np.zeros(2)
  783. Vel_VPF_HM_alert[0] = alert*1.0
  784. Vel_VPF_HM_alert[1] = alert*1.0
  785. Vel_VPF_HM_danger[0] = danger*1.0
  786. Vel_VPF_HM_danger[1] = danger*1.0
  787. return Vel_VPF_HM_alert, Vel_VPF_HM_danger
  788. ###############################################################################
  789. ###############################################################################
  790. # @staticmethod
  791. def Vel_BTF_HM_Threshhold(self,alert, danger):
  792. Vel_BTF_HM_alert = np.zeros(2)
  793. Vel_BTF_HM_danger = np.zeros(2)
  794. Vel_BTF_HM_alert[0] = alert*1.0
  795. Vel_BTF_HM_alert[1] = alert*1.0
  796. Vel_BTF_HM_danger[0] = danger*1.0
  797. Vel_BTF_HM_danger[1] = danger*1.0
  798. return Vel_BTF_HM_alert, Vel_BTF_HM_danger
  799. ###############################################################################
  800. ###############################################################################
  801. # @staticmethod
  802. def Vel_SHF_HM_Threshhold(self,alert, danger):
  803. Vel_SHF_HM_alert = np.zeros(1)
  804. Vel_SHF_HM_danger = np.zeros(1)
  805. Vel_SHF_HM_alert[0] = alert*1.0
  806. Vel_SHF_HM_danger[0] = danger*1.0
  807. return Vel_SHF_HM_alert, Vel_SHF_HM_danger
  808. ###############################################################################
  809. ###############################################################################
  810. # @staticmethod
  811. def Vel_RBPF_HM_Threshhold(self,alert, danger):
  812. Vel_RBPF_HM_alert = np.zeros(1)
  813. Vel_RBPF_HM_danger = np.zeros(1)
  814. Vel_RBPF_HM_alert[0] = alert*1.0
  815. Vel_RBPF_HM_danger[0] = danger*1.0
  816. return Vel_RBPF_HM_alert, Vel_RBPF_HM_danger
  817. ###############################################################################
  818. ###############################################################################
  819. # @staticmethod
  820. def Acc_RBPF_HM_Threshhold(self,alert, danger):
  821. Acc_RBPF_HM_alert = np.zeros(1)
  822. Acc_RBPF_HM_danger = np.zeros(1)
  823. Acc_RBPF_HM_alert[0] = alert*1.0
  824. Acc_RBPF_HM_danger[0] = danger*1.0
  825. return Acc_RBPF_HM_alert, Acc_RBPF_HM_danger
  826. ###############################################################################
  827. ###############################################################################
  828. # @staticmethod
  829. def Bearing_Fault_Diag(self,gE_Bearing_Defect_HM, Vel_Bearing_Defect_HM, Vel_RunningSpd_HM, gE_alert, gE_danger, Vel_alert, Vel_danger, defectType):
  830. BrDefDetection = False
  831. BrDefSev = 0
  832. gE_Bearing_Defect_HM_alert = np.zeros(5)
  833. gE_Bearing_Defect_HM_danger = np.zeros(5)
  834. Vel_Bearing_Defect_HM_alert = np.zeros(5)
  835. Vel_Bearing_Defect_HM_danger = np.zeros(5)
  836. Vel_Bearing_RunningSpd_HM_alert = np.zeros(5)
  837. Vel_Bearing_RunningSpd_HM_danger = np.zeros(5)
  838. ###############################################################################
  839. # Check bearing outer race and inner race defect
  840. if (defectType == 'BPFO') or (defectType == 'BPFI'):
  841. [gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger] = self.gE_Bearing_Defect_HM_Threshhold(gE_alert, gE_danger, defectType)
  842. # [Vel_Bearing_RunningSpd_HM_alert, Vel_Bearing_RunningSpd_HM_danger] = self.Vel_Bearing_RunningSpd_HM_Threshhold(Vel_alert, Vel_danger, defectType)
  843. [Vel_Bearing_Defect_HM_alert, Vel_Bearing_Defect_HM_danger] = self.Vel_Bearing_Defect_HM_Threshhold(Vel_alert, Vel_danger, defectType)
  844. # Bearing outer race frequency, severe, confirmed by velocity spectrum, CF = 8, Severity = 10
  845. # AND
  846. # OR
  847. # ge_BPFO_1 >= Alert
  848. # ge_BPFO_2 >= Alert
  849. # OR
  850. # Vel_BPFO_1 >= Alert
  851. # Vel_BPFO_2 >= Alert
  852. #
  853. # above logics apply to BPFI as well
  854. if (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] or gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_alert[1]) and \
  855. (Vel_Bearing_Defect_HM[0] >= Vel_Bearing_Defect_HM_alert[0] or Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1]):
  856. BrDefDetection = True
  857. BrDefSev = 8
  858. return BrDefDetection, BrDefSev
  859. # Bearing outer race frequency, severe, no confirming by velocity spectrum, CF = 6, Severity = 10
  860. # AND
  861. # OR
  862. # AND
  863. # ge_BPFO_1 >= Danger
  864. # ge_BPFO_2 >= Alert
  865. # AND
  866. # gE_BPFO_1 >= Danger
  867. # gE_BPFO_3 >= Alert
  868. # AND
  869. # gE_BPFO_1 >= Danger
  870. # gE_BPFO_4 >= Alert
  871. # NOR
  872. # Vel_BPFO_1 >= Alert
  873. # Vel_BPFO_2 >= Alert
  874. #
  875. # above logics apply to BPFI as well
  876. else:
  877. if ((gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] and gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_alert[1]) or \
  878. (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] and gE_Bearing_Defect_HM[2] >= gE_Bearing_Defect_HM_alert[2]) or \
  879. (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] and gE_Bearing_Defect_HM[3] >= gE_Bearing_Defect_HM_alert[3])) and \
  880. (not(Vel_Bearing_Defect_HM[0] >= Vel_Bearing_Defect_HM_alert[0] or Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1])):
  881. BrDefDetection = True
  882. BrDefSev = 6
  883. return BrDefDetection, BrDefSev
  884. # Bearing outer race frequency, severe, not confirmed by gE spectrum, CF = 6, Severity = 10
  885. # OR
  886. # Vel_BPFO_1 >= Alert
  887. # Vel_BPFO_2 >= Alert
  888. #
  889. # above logics apply to BPFI as well
  890. else:
  891. if (Vel_Bearing_Defect_HM[0] >= Vel_Bearing_Defect_HM_alert[0] or Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1]):
  892. BrDefDetection = True
  893. BrDefSev = 6
  894. return BrDefDetection, BrDefSev
  895. # Bearing outer race frequency, moderate, several defect peaks, no confirming by velocity spectrum, CF = 5, Severity = 5
  896. # AND
  897. # OR
  898. # AND
  899. # ge_BPFO_1 >= Alert
  900. # ge_BPFO_2 >= Alert
  901. # AND
  902. # gE_BPFO_1 >= Alert
  903. # gE_BPFO_3 >= Alert
  904. # AND
  905. # gE_BPFO_1 >= Alert
  906. # gE_BPFO_4 >= Alert
  907. # NOR
  908. # Vel_BPFO_1 >= Alert
  909. # Vel_BPFO_2 >= Alert
  910. #
  911. # above logics apply to BPFI as well
  912. else:
  913. if ((gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] and gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_alert[1]) or \
  914. (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] and gE_Bearing_Defect_HM[2] >= gE_Bearing_Defect_HM_alert[2]) or \
  915. (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] and gE_Bearing_Defect_HM[3] >= gE_Bearing_Defect_HM_alert[3])) and \
  916. (not(Vel_Bearing_Defect_HM[0] >= Vel_Bearing_Defect_HM_alert[0] or Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1])):
  917. BrDefDetection = True
  918. BrDefSev = 3
  919. return BrDefDetection, BrDefSev
  920. # Bearing outer race frequency, suspect, only 1x defect peak evaluated, CF = 3, Severity = 5
  921. # ge_BPFO_1 >= Alert
  922. #
  923. # above logics apply to BPFI as well
  924. else:
  925. if (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0]):
  926. BrDefDetection = True
  927. BrDefSev = 1
  928. return BrDefDetection, BrDefSev
  929. return BrDefDetection, BrDefSev
  930. ###############################################################################
  931. # Check bearing rolling element defect
  932. if defectType == 'BSF':
  933. [gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger] = self.gE_Bearing_Defect_HM_Threshhold(gE_alert, gE_danger, defectType)
  934. [Vel_Bearing_RunningSpd_HM_alert, Vel_Bearing_RunningSpd_HM_danger] = self.Vel_Bearing_RunningSpd_HM_Threshhold(Vel_alert, Vel_danger, defectType)
  935. [Vel_Bearing_Defect_HM_alert, Vel_Bearing_Defect_HM_danger] = self.Vel_Bearing_Defect_HM_Threshhold(Vel_alert, Vel_danger, defectType)
  936. # print(Vel_Bearing_RunningSpd_HM_alert, Vel_Bearing_RunningSpd_HM_danger)
  937. # Bearing rolling element frequency, severe, CF = 9, Severity = 10
  938. # AND
  939. # AND
  940. # Vel_BSF_2 >= Alert
  941. # Vel_BSF_4 >= Alert
  942. # NOR
  943. # Vel_RS_2 >= Alert
  944. # Vel_RS_3 >= Alert
  945. # Vel_RS_4 >= Alert
  946. # Vel_RS_5 >= Alert
  947. if (Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1] and Vel_Bearing_Defect_HM[3] >= Vel_Bearing_Defect_HM_alert[3]) and \
  948. (not(Vel_RunningSpd_HM[1] >= Vel_Bearing_RunningSpd_HM_alert[1] or Vel_RunningSpd_HM[2] >= Vel_Bearing_RunningSpd_HM_alert[2] or \
  949. Vel_RunningSpd_HM[3] >= Vel_Bearing_RunningSpd_HM_alert[3] or Vel_RunningSpd_HM[4] >= Vel_Bearing_RunningSpd_HM_alert[4])):
  950. BrDefDetection = True
  951. BrDefSev = 9
  952. return BrDefDetection, BrDefSev
  953. # Bearing rolling element frequency, moderate, CF = 9, Severity = 5
  954. # AND
  955. # AND
  956. # gE_BSF_1 >= Alert
  957. # NOR
  958. # Vel_BSF_2 >= Alert
  959. # Vel_BSF_4 >= Alert
  960. # Vel_RS_2 >= Alert
  961. # Vel_RS_3 >= Alert
  962. # Vel_RS_4 >= Alert
  963. # Vel_RS_5 >= Alert
  964. else:
  965. if gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] and \
  966. (not(Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1] or Vel_Bearing_Defect_HM[3] >= Vel_Bearing_Defect_HM_alert[3] or \
  967. Vel_RunningSpd_HM[1] >= Vel_Bearing_RunningSpd_HM_alert[1] or Vel_RunningSpd_HM[2] >= Vel_Bearing_RunningSpd_HM_alert[2] or \
  968. Vel_RunningSpd_HM[3] >= Vel_Bearing_RunningSpd_HM_alert[3] or Vel_RunningSpd_HM[4] >= Vel_Bearing_RunningSpd_HM_alert[4])):
  969. BrDefDetection = True
  970. BrDefSev = 5
  971. return BrDefDetection, BrDefSev
  972. # Bearing rolling element frequency, suspect, CF = 3, Severity = 5
  973. # AND
  974. # OR
  975. # gE_BSF_1 = Alert
  976. # gE_BSF_2 = Alert
  977. # gE_BSF_4 = Alert
  978. # NOR
  979. # gE_BSF_1 = Danger
  980. # gE_BSF_2 = Danger
  981. # gE_BSF_4 = Danger
  982. # Vel_BSF_2 >= Alert
  983. # Vel_BSF_4 >= Alert
  984. # Vel_RS_2 >= Alert
  985. # Vel_RS_3 >= Alert
  986. # Vel_RS_4 >= Alert
  987. # Vel_RS_5 >= Alert
  988. else:
  989. if ((gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] and gE_Bearing_Defect_HM[0] < gE_Bearing_Defect_HM_danger[0]) or \
  990. (gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_alert[1] and gE_Bearing_Defect_HM[1] < gE_Bearing_Defect_HM_danger[1]) or \
  991. (gE_Bearing_Defect_HM[3] >= gE_Bearing_Defect_HM_alert[3] and gE_Bearing_Defect_HM[3] < gE_Bearing_Defect_HM_danger[3] )) and \
  992. (not(gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] or gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_danger[1] or gE_Bearing_Defect_HM[3] >= gE_Bearing_Defect_HM_danger[3] or \
  993. Vel_Bearing_Defect_HM[0] >= Vel_Bearing_Defect_HM_alert[0] or Vel_Bearing_Defect_HM[1] >= Vel_Bearing_Defect_HM_alert[1] or \
  994. Vel_RunningSpd_HM[1] >= Vel_Bearing_RunningSpd_HM_alert[1] or Vel_RunningSpd_HM[2] >= Vel_Bearing_RunningSpd_HM_alert[2] or \
  995. Vel_RunningSpd_HM[3] >= Vel_Bearing_RunningSpd_HM_alert[3] or Vel_RunningSpd_HM[4] >= Vel_Bearing_RunningSpd_HM_alert[4])):
  996. BrDefDetection = True
  997. BrDefSev = 1
  998. return BrDefDetection, BrDefSev
  999. return BrDefDetection, BrDefSev
  1000. ###############################################################################
  1001. # Check bearing cage defect
  1002. if defectType == 'FTF':
  1003. [gE_Bearing_Defect_HM_alert, gE_Bearing_Defect_HM_danger] = self.gE_Bearing_Defect_HM_Threshhold(gE_alert, gE_danger, defectType)
  1004. # Bearing cage frequency, severe, CF = 6, Severity = 10
  1005. # OR
  1006. # gE_CG_1 >= Danger
  1007. # gE_CG_2 >= Danger
  1008. if gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] or gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_danger[1]:
  1009. BrDefDetection = True
  1010. BrDefSev = 6
  1011. return BrDefDetection, BrDefSev
  1012. # Bearing cage frequency, moderate, CF = 5, Severity = 5
  1013. # AND
  1014. # OR
  1015. # gE_CG_1 >= Alert
  1016. # gE_CG_2 >= Alert
  1017. # NOR
  1018. # gE_CG_1 = Danger
  1019. # gE_CG_2 = Danger
  1020. else:
  1021. if (gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_alert[0] or gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_alert[1]) and \
  1022. (not(gE_Bearing_Defect_HM[0] >= gE_Bearing_Defect_HM_danger[0] or gE_Bearing_Defect_HM[1] >= gE_Bearing_Defect_HM_danger[1])):
  1023. BrDefDetection = True
  1024. BrDefSev = 3
  1025. return BrDefDetection, BrDefSev
  1026. return BrDefDetection, BrDefSev
  1027. ###############################################################################
  1028. ###############################################################################
  1029. # @staticmethod
  1030. def RunningSpd_Symptom_Rule(self,Vel_RunningSpd_HM, Vel_RunningSpd_HM_alert, Vel_RunningSpd_HM_danger):
  1031. RPM1_MOD = False
  1032. RPM1_SEV = False
  1033. RPM2_MOD = False
  1034. RPM2_SEV = False
  1035. RPM345_MOD = False
  1036. RPM345_SEV = False
  1037. # 1x RPM, Moderate, CF=8, Severity = 5
  1038. # AND
  1039. # Vel_RS_1 = Alert
  1040. if Vel_RunningSpd_HM[0] >= Vel_RunningSpd_HM_alert[0] and Vel_RunningSpd_HM[0] < Vel_RunningSpd_HM_danger[0]:
  1041. RPM1_MOD = True
  1042. # 1x RPM, Severe, CF=8, Severity = 10
  1043. # AND
  1044. # Vel_RS_1 = Danger
  1045. if Vel_RunningSpd_HM[0] >= Vel_RunningSpd_HM_danger[0]:
  1046. RPM1_SEV = True
  1047. # 2x RPM, Moderate, CF=8, Severity = 5
  1048. # AND
  1049. # Vel_RS_2 = Alert
  1050. if Vel_RunningSpd_HM[1] >= Vel_RunningSpd_HM_alert[1] and Vel_RunningSpd_HM[1] < Vel_RunningSpd_HM_danger[1]:
  1051. RPM2_MOD = True
  1052. # 2x RPM, Severe, CF=8, Severity = 10
  1053. # AND
  1054. # Vel_RS_2 = Danger
  1055. if Vel_RunningSpd_HM[1] >= Vel_RunningSpd_HM_danger[1]:
  1056. RPM2_SEV = True
  1057. # 3x, 4x, 5x RPM, moderate, CF=8, Severity = 5
  1058. # AND
  1059. # OR
  1060. # Vel_RS_3 = Alert
  1061. # Vel_RS_4 = Alert
  1062. # Vel_RS_5 = Alert
  1063. # NOR
  1064. # Vel_RS_3 = Danger
  1065. # Vel_RS_4 = Danger
  1066. # Vel_RS_5 = Danger
  1067. if (Vel_RunningSpd_HM[2] >= Vel_RunningSpd_HM_alert[2] and Vel_RunningSpd_HM[2] < Vel_RunningSpd_HM_danger[2] or \
  1068. Vel_RunningSpd_HM[3] >= Vel_RunningSpd_HM_alert[3] and Vel_RunningSpd_HM[3] < Vel_RunningSpd_HM_danger[3] or \
  1069. Vel_RunningSpd_HM[4] >= Vel_RunningSpd_HM_alert[4] and Vel_RunningSpd_HM[4] < Vel_RunningSpd_HM_danger[4]) and \
  1070. (not(Vel_RunningSpd_HM[2] >= Vel_RunningSpd_HM_danger[2] or Vel_RunningSpd_HM[3] >= Vel_RunningSpd_HM_danger[3] or \
  1071. Vel_RunningSpd_HM[4] >= Vel_RunningSpd_HM_danger[4])):
  1072. RPM345_MOD = True
  1073. # 3x, 4x, 5x RPM, Sever, CF=8, Severity = 10
  1074. # OR
  1075. # Vel_RS_3 = Danger
  1076. # Vel_RS_4 = Danger
  1077. # Vel_RS_5 = Danger
  1078. if Vel_RunningSpd_HM[2] >= Vel_RunningSpd_HM_danger[2] or Vel_RunningSpd_HM[3] >= Vel_RunningSpd_HM_danger[3] or \
  1079. Vel_RunningSpd_HM[4] >= Vel_RunningSpd_HM_danger[4]:
  1080. RPM345_SEV = True
  1081. return RPM1_MOD, RPM1_SEV, RPM2_MOD, RPM2_SEV, RPM345_MOD, RPM345_SEV
  1082. ###############################################################################
  1083. ###############################################################################
  1084. # @staticmethod
  1085. # Note: The alert and danger threshold values (in mm/s RMS) are set according to ISO vibration standard for flexible mounting in group 3
  1086. def RunningSpd_Fault_Diag(self,Vel_RunningSpd_HM, Vel_alert , Vel_danger, defectType ):
  1087. RPM1_MOD = False
  1088. RPM1_SEV = False
  1089. RPM2_MOD = False
  1090. RPM2_SEV = False
  1091. RPM345_MOD = False
  1092. RPM345_SEV = False
  1093. UnbalanceDetection = False
  1094. UnbalanceSev = 0
  1095. MisalignmentDetction = False
  1096. MisalignmentSev = 0
  1097. LoosenessDetection = False
  1098. LoosenessSev = 0
  1099. Vel_Unbalance_HM_alert = np.zeros(5)
  1100. Vel_Unbalance_HM_danger = np.zeros(5)
  1101. Vel_Misalignment_HM_alert = np.zeros(5)
  1102. Vel_Misalignment_HM_danger = np.zeros(5)
  1103. Vel_Looseness_HM_alert = np.zeros(5)
  1104. Vel_Looseness_HM_danger = np.zeros(5)
  1105. ###############################################################################
  1106. # Check Unbalance
  1107. if defectType == 'Unbalance':
  1108. [Vel_Unbalance_HM_alert, Vel_Unbalance_HM_danger] = self.Vel_Unbalance_HM_Threshold(Vel_alert, Vel_danger)
  1109. [RPM1_MOD, RPM1_SEV, RPM2_MOD, RPM2_SEV, RPM345_MOD, RPM345_SEV] = self.RunningSpd_Symptom_Rule(Vel_RunningSpd_HM, Vel_Unbalance_HM_alert, Vel_Unbalance_HM_danger)
  1110. # print('RPM1_MOD,RPM1_SEV, RPM2_MOD, RPM2_SEV, RPM345_MOD, RPM345_SEV',' ',RPM1_MOD,' ', RPM1_SEV,' ', RPM2_MOD, ' ',RPM2_SEV, ' ',RPM345_MOD, ' ',RPM345_SEV)
  1111. # Unbalance, severe, rather confident, 1x RPM peak dominates, CF=8, Severity = 10
  1112. # AND
  1113. # RPM1_SEV == True
  1114. # NOR
  1115. # RPM2_MOD == True
  1116. # RPM2_SEV == True
  1117. # RPM345_MOD == True
  1118. # RPM345_SEV == True
  1119. if RPM1_SEV == True and (not (RPM2_MOD == True or RPM2_SEV == True or RPM345_MOD == True or RPM345_SEV == True )):
  1120. UnbalanceDetection = True
  1121. UnbalanceSev = 8
  1122. else:
  1123. # Unbalance, severe, somewhat confident 1x RPM peak dominates but low level of 2xRPM is possible, CF=6, Severity = 10
  1124. # AND
  1125. # RPM1_SEV == True
  1126. # NOR
  1127. # RPM2_SEV == True
  1128. # RPM345_MOD == True
  1129. # RPM345_SEV == True
  1130. if RPM1_SEV == True and (not(RPM2_SEV == True or RPM345_MOD == True or RPM345_SEV == True )):
  1131. UnbalanceDetection = True
  1132. UnbalanceSev = 6
  1133. else:
  1134. # Unbalance, moderate, rather confident since 1x RPM peak dominates, CF=8, Severity = 5
  1135. # AND
  1136. # RPM1_MOD == True
  1137. # NOR
  1138. # RPM2_MOD == True
  1139. # RPM2_SEV == True
  1140. # RPM345_MOD == True
  1141. # RPM345_SEV == True
  1142. if RPM1_MOD == True and (not(RPM2_MOD == True or RPM2_SEV == True or RPM345_MOD == True or RPM345_SEV == True )):
  1143. UnbalanceDetection = True
  1144. UnbalanceSev = 5
  1145. return UnbalanceDetection, UnbalanceSev
  1146. ###############################################################################
  1147. # Check Misalignment
  1148. if defectType == 'Misalignment':
  1149. [Vel_Misalignment_HM_alert, Vel_Misalignment_HM_danger] = self.Vel_Misalignment_HM_Threshold(Vel_alert, Vel_danger)
  1150. [RPM1_MOD, RPM1_SEV, RPM2_MOD, RPM2_SEV, RPM345_MOD, RPM345_SEV] = self.RunningSpd_Symptom_Rule(Vel_RunningSpd_HM, Vel_Misalignment_HM_alert, Vel_Misalignment_HM_danger)
  1151. # Misalignment, moderate CF = 8, Severity = 10
  1152. # AND
  1153. # RPM2_SEV == True
  1154. # OR
  1155. # RPM1_MOD == True
  1156. # RPM1_SEV == True
  1157. # RPM345_MOD == True
  1158. # NOR
  1159. # RPM345_SEV == True
  1160. if RPM2_SEV == True and (RPM1_MOD == True or RPM1_SEV == True or RPM345_MOD == True) and (not(RPM1_SEV == True)):
  1161. MisalignmentDetction = True
  1162. MisalignmentSev = 8
  1163. # Misalignment, moderate CF = 6, Severity 10
  1164. # AND
  1165. # RPM2_SEV == True
  1166. # NOR
  1167. # RPM1_MOD == True
  1168. # RPM1_SEV == True
  1169. # RPM345_MOD == True
  1170. # RPM345_SEV == True
  1171. else:
  1172. if RPM2_SEV == True and (not(RPM1_MOD == True or RPM1_SEV == True or RPM345_MOD == True or RPM345_SEV == True)):
  1173. MisalignmentDetction = True
  1174. MisalignmentSev = 6
  1175. # Misalignment, moderate CF = 8, Severity = 5
  1176. # AND
  1177. # RPM2_MOD == True
  1178. # OR
  1179. # RPM1_MOD == True
  1180. # RPM345_MOD == True
  1181. # NOR
  1182. # RPM1_SEV == True
  1183. # RPM345_SEV == True
  1184. else:
  1185. if RPM2_MOD == True and (RPM1_MOD == True or RPM345_MOD == True) and (not(RPM1_SEV == True or RPM345_SEV == True)):
  1186. MisalignmentDetction = True
  1187. MisalignmentSev = 5
  1188. # Misalignment, moderate CF = 6, Severity = 5
  1189. # AND
  1190. # RPM2_MOD == True
  1191. # NOR
  1192. # RPM1_MOD == True
  1193. # RPM1_SEV == True
  1194. # RPM345_MOD == True
  1195. # RPM345_SEV == True
  1196. else:
  1197. if RPM2_MOD == True and (not (RPM1_MOD == True or RPM1_SEV == True or RPM345_MOD == True or RPM345_SEV == True)):
  1198. MisalignmentDetction = True
  1199. MisalignmentSev = 4
  1200. return MisalignmentDetction, MisalignmentSev
  1201. ###############################################################################
  1202. # Check Looseness
  1203. if defectType == 'Looseness':
  1204. [Vel_Looseness_HM_alert, Vel_Looseness_HM_danger] = self.Vel_Looseness_HM_Threshold(Vel_alert, Vel_danger)
  1205. [RPM1_MOD, RPM1_SEV, RPM2_MOD, RPM2_SEV, RPM345_MOD, RPM345_SEV] = self.RunningSpd_Symptom_Rule(Vel_RunningSpd_HM, Vel_Looseness_HM_alert, Vel_Looseness_HM_danger)
  1206. # Mechanical looseness, sever CF = 8, Severity = 10
  1207. # OR
  1208. # AND
  1209. # RPM1_SEV == True
  1210. # OR
  1211. # RPM345_MOD == True
  1212. # RPM345_SEV == True
  1213. # AND
  1214. # RPM2_SEV == True
  1215. # OR
  1216. # RPM345_MOD == True
  1217. # RPM345_SEV == True
  1218. # AND
  1219. # RPM345_SEV == True
  1220. # OR
  1221. # RPM1_MOD == True
  1222. # RPM1_SEV == True
  1223. # AND
  1224. # RPM345_SEV == True
  1225. # OR
  1226. # RPM2_MOD == True
  1227. # RPM2_SEV == True
  1228. if (RPM1_SEV == True and (RPM345_MOD == True or RPM345_SEV == True )) or (RPM2_SEV == True and (RPM345_MOD == True or RPM345_SEV == True )) or \
  1229. (RPM345_SEV == True and (RPM1_MOD == True or RPM1_SEV == True )) or (RPM345_SEV == True and (RPM2_MOD == True or RPM2_SEV == True )):
  1230. LoosenessDetection = True
  1231. LoosenessSev = 8
  1232. # Mechanical looseness, sever CF = 6, Severity = 10
  1233. # AND
  1234. # RPM345_SEV == True
  1235. # NOR
  1236. # RPM1_MOD == True
  1237. # RPM1_SEV == True
  1238. # RPM2_MOD == True
  1239. # RPM2_SEV == True
  1240. else:
  1241. if RPM345_SEV == True and (not( RPM1_MOD == True or RPM1_SEV == True or RPM2_MOD == True or RPM2_SEV == True )):
  1242. LoosenessDetection = True
  1243. LoosenessSev = 6
  1244. # Mechanical looseness, moderate CF = 8, Severity = 5
  1245. # AND
  1246. # OR
  1247. # AND
  1248. # RPM1_MOD == True
  1249. # RPM345_MOD == True
  1250. # AND
  1251. # RPM2_MOD == True
  1252. # RPM345_MOD == True
  1253. # NOR
  1254. # RPM1_SEV == True
  1255. # RPM2_SEV == True
  1256. # RPM345_SEV == True
  1257. else:
  1258. if ((RPM1_MOD == True and RPM345_MOD == True )or(RPM2_MOD == True and RPM345_MOD == True))and\
  1259. (not(RPM1_SEV == True or RPM2_SEV == True or RPM345_SEV == True)):
  1260. LoosenessDetection = True
  1261. LoosenessSev = 5
  1262. # Mechanical looseness, moderate CF = 6, Severity = 5
  1263. # AND
  1264. # RPM345_MOD == True
  1265. # NOR
  1266. # RPM1_MOD == True
  1267. # RPM1_SEV == True
  1268. # RPM2_MOD == True
  1269. # RPM2_SEV == True
  1270. else:
  1271. if RPM345_MOD == True and (not( RPM1_MOD == True or RPM1_SEV == True or RPM2_MOD == True or \
  1272. RPM2_SEV == True )):
  1273. LoosenessDetection = True
  1274. LoosenessSev = 4
  1275. return LoosenessDetection, LoosenessSev
  1276. ###############################################################################
  1277. ###############################################################################
  1278. # @staticmethod
  1279. def GMF_GTIF_Symptom_Rule(self,Vel_GMF_HM, Acc_GMF_HM, gE_GMF_HM, gE_GTIF_HM, Vel_GMF_HM_alert, Vel_GMF_HM_danger, \
  1280. Acc_GMF_HM_alert, Acc_GMF_HM_danger, gE_GMF_HM_alert, gE_GMF_HM_danger, gE_GTIF_HM_alert, \
  1281. gE_GTIF_HM_danger):
  1282. GMF_MOD = False
  1283. GMF_SEV = False
  1284. GTIF = False
  1285. # Gear mesh frequency and harmonics, moderate, CF=8, Severity = 5
  1286. # AND
  1287. # OR
  1288. # Vel_GMF_1 = Alert
  1289. # Vel_GMF_2 = Alert
  1290. # Vel_GMF_3 = Alert
  1291. # Acc_GMF_1 = Alert
  1292. # Acc_GMF_2 = Alert
  1293. # Acc_GMF_3 = Alert
  1294. # gE_GMF_1 = Alert
  1295. # gE_GMF_2 = Alert
  1296. # gE_GMF_3 = Alert
  1297. # NOR
  1298. # Vel_GMF_1 = Danger
  1299. # Vel_GMF_2 = Danger
  1300. # Vel_GMF_3 = Danger
  1301. # Acc_GMF_1 = Danger
  1302. # Acc_GMF_2 = Danger
  1303. # Acc_GMF_3 = Danger
  1304. # gE_GMF_1 = Danger
  1305. # gE_GMF_2 = Danger
  1306. # gE_GMF_3 = Danger
  1307. if (Vel_GMF_HM[0] >= Vel_GMF_HM_alert[0] and Vel_GMF_HM[0] < Vel_GMF_HM_danger[0] or \
  1308. Vel_GMF_HM[1] >= Vel_GMF_HM_alert[1] and Vel_GMF_HM[1] < Vel_GMF_HM_danger[1] or \
  1309. Vel_GMF_HM[2] >= Vel_GMF_HM_alert[2] and Vel_GMF_HM[2] < Vel_GMF_HM_danger[2] or \
  1310. Acc_GMF_HM[0] >= Acc_GMF_HM_alert[0] and Acc_GMF_HM[0] < Acc_GMF_HM_danger[0] or \
  1311. Acc_GMF_HM[1] >= Acc_GMF_HM_alert[1] and Acc_GMF_HM[1] < Acc_GMF_HM_danger[1] or \
  1312. Acc_GMF_HM[2] >= Acc_GMF_HM_alert[2] and Acc_GMF_HM[2] < Acc_GMF_HM_danger[2] or \
  1313. gE_GMF_HM[0] >= gE_GMF_HM_alert[0] and gE_GMF_HM[0] < gE_GMF_HM_danger[0] or \
  1314. gE_GMF_HM[1] >= gE_GMF_HM_alert[1] and gE_GMF_HM[1] < gE_GMF_HM_danger[1] or \
  1315. gE_GMF_HM[2] >= gE_GMF_HM_alert[2] and gE_GMF_HM[2] < gE_GMF_HM_danger[2]) \
  1316. and \
  1317. (not(Vel_GMF_HM[0] >= Vel_GMF_HM_danger[0] or \
  1318. Vel_GMF_HM[1] >= Vel_GMF_HM_danger[1] or \
  1319. Vel_GMF_HM[2] >= Vel_GMF_HM_danger[2] or \
  1320. Acc_GMF_HM[0] >= Acc_GMF_HM_danger[0] or \
  1321. Acc_GMF_HM[1] >= Acc_GMF_HM_danger[1] or \
  1322. Acc_GMF_HM[2] >= Acc_GMF_HM_danger[2] or \
  1323. gE_GMF_HM[0] >= gE_GMF_HM_danger[0] or \
  1324. gE_GMF_HM[1] >= gE_GMF_HM_danger[1] or \
  1325. gE_GMF_HM[2] >= gE_GMF_HM_danger[2])):
  1326. GMF_MOD = True
  1327. # Gear mesh frequency and harmonics, sever, CF=8, Severity = 10
  1328. # OR
  1329. # Vel_GMF_1 = Danger
  1330. # Vel_GMF_2 = Danger
  1331. # Vel_GMF_3 = Danger
  1332. # Acc_GMF_1 = Danger
  1333. # Acc_GMF_2 = Danger
  1334. # Acc_GMF_3 = Danger
  1335. # gE_GMF_1 = Danger
  1336. # gE_GMF_2 = Danger
  1337. # gE_GMF_3 = Danger
  1338. if (Vel_GMF_HM[0] >= Vel_GMF_HM_danger[0] or \
  1339. Vel_GMF_HM[1] >= Vel_GMF_HM_danger[1] or \
  1340. Vel_GMF_HM[2] >= Vel_GMF_HM_danger[2] or \
  1341. Acc_GMF_HM[0] >= Acc_GMF_HM_danger[0] or \
  1342. Acc_GMF_HM[1] >= Acc_GMF_HM_danger[1] or \
  1343. Acc_GMF_HM[2] >= Acc_GMF_HM_danger[2] or \
  1344. gE_GMF_HM[0] >= gE_GMF_HM_danger[0] or \
  1345. gE_GMF_HM[1] >= gE_GMF_HM_danger[1] or \
  1346. gE_GMF_HM[2] >= gE_GMF_HM_danger[2]):
  1347. GMF_SEV = True
  1348. # Gear tooth impact frequency and harmonics, CF=8, Severity = 10
  1349. # OR
  1350. # gE_GTIF_1 >= Alert
  1351. # gE_GTIF_2 >= Alert
  1352. # gE_GTIF_3 >= Alert
  1353. # gE_GTIF_4 >= Alert
  1354. # gE_GTIF_5 >= Alert
  1355. if (gE_GTIF_HM[0] >= gE_GTIF_HM_alert[0] or \
  1356. gE_GTIF_HM[1] >= gE_GTIF_HM_alert[1] or \
  1357. gE_GTIF_HM[2] >= gE_GTIF_HM_alert[2] or \
  1358. gE_GTIF_HM[3] >= gE_GTIF_HM_alert[3] or \
  1359. gE_GTIF_HM[4] >= gE_GTIF_HM_alert[4]):
  1360. GTIF = True
  1361. return GMF_MOD, GMF_SEV, GTIF
  1362. ###############################################################################
  1363. ###############################################################################
  1364. # @staticmethod
  1365. def Gear_Fault_Diag(self,Acc_GMF_HM, Vel_GMF_HM, gE_GMF_HM, gE_GTIF_HM, Acc_GMF_alert_gPk = 0.299, Acc_GMF_danger_gPk = 0.344, \
  1366. Vel_GMF_alert_mmsRMS = 4.0, Vel_GMF_danger_mmsRMS = 8.0, gE_GMF_alert_gE = 3.0, \
  1367. gE_GMF_danger_gE = 6.0, gE_GTIF_alert_gE = 3.0, gE_GTIF_danger_gE = 6.0):
  1368. GMF_MOD = False
  1369. GMF_SEV = False
  1370. GTIF = False
  1371. Acc_GMF_HM_alert =[]
  1372. Acc_GMF_HM_danger = []
  1373. Vel_GMF_HM_alert =[]
  1374. Vel_GMF_HM_danger = []
  1375. gE_GMF_HM_alert = []
  1376. gE_GMF_HM_danger = []
  1377. gE_GTIF_HM_alert = []
  1378. gE_GTIF_HM_danger = []
  1379. GearToothWearDetection = False
  1380. GearToothWearSev = 0
  1381. GearToothCrackBrokenDetection = False
  1382. GearToothCrackBrokenSev = 0
  1383. [Acc_GMF_HM_alert, Acc_GMF_HM_danger] = self.Acc_GMF_HM_Threshhold(Acc_GMF_alert_gPk, Acc_GMF_danger_gPk)
  1384. [Vel_GMF_HM_alert, Vel_GMF_HM_danger] = self.Vel_GMF_HM_Threshhold(Vel_GMF_alert_mmsRMS, Vel_GMF_danger_mmsRMS)
  1385. [gE_GMF_HM_alert, gE_GMF_HM_danger] = self.gE_GMF_HM_Threshhold(gE_GMF_alert_gE, gE_GMF_danger_gE)
  1386. [gE_GTIF_HM_alert, gE_GTIF_HM_danger] = self.gE_GTIF_HM_Threshhold(gE_GTIF_alert_gE, gE_GTIF_danger_gE)
  1387. [GMF_MOD, GMF_SEV, GTIF] = self.GMF_GTIF_Symptom_Rule(Vel_GMF_HM, Acc_GMF_HM, gE_GMF_HM, gE_GTIF_HM, Vel_GMF_HM_alert, \
  1388. Vel_GMF_HM_danger, Acc_GMF_HM_alert, Acc_GMF_HM_danger, \
  1389. gE_GMF_HM_alert, gE_GMF_HM_danger, gE_GTIF_HM_alert, gE_GTIF_HM_danger)
  1390. # Gear wear, misalignment, or eccentricity, sever, CF = 8, severity = 10
  1391. # AND
  1392. # GMF_SEV = True
  1393. if GMF_SEV == True:
  1394. GearToothWearDetection = True
  1395. GearToothWearSev = 10
  1396. # Gear wear, misalignment, or eccentricity, moderate, CF = 8, severity = 5
  1397. # AND
  1398. # GMF_MOD = True
  1399. else:
  1400. if GMF_MOD == True:
  1401. GearToothWearDetection = True
  1402. GearToothWearSev = 5
  1403. # Gear tooth broken or cracked, CF = 8, severity = 5
  1404. # AND
  1405. # GTIF = True
  1406. # NOR
  1407. # GMF_MOD = True
  1408. # GMF_SEV = True
  1409. if GTIF == True and (not(GMF_MOD == True or GMF_SEV == True)):
  1410. GearToothCrackBrokenDetection = True
  1411. GearToothCrackBrokenSev = 5
  1412. return GearToothWearDetection, GearToothWearSev, GearToothCrackBrokenDetection, GearToothCrackBrokenSev
  1413. ###############################################################################
  1414. ###############################################################################
  1415. # @staticmethod
  1416. # Note: the default alert and danger threshold values (in mm/s RMS for velocity and g peak for acceleration) are set according a DSS AC motor model, it can be adjusted if necessary
  1417. def RBPF_Symptom_Rule(self,Vel_RBPF_HM, Acc_RBPF_HM, Vel_RBPF_HM_alert, Vel_RBPF_HM_danger, Acc_RBPF_HM_alert, \
  1418. Acc_RBPF_HM_danger):
  1419. RBPF_MOD = False
  1420. RBPF_SEV = False
  1421. # Rotorbar pass frequency, sever, CF=8, severity = 10
  1422. # OR
  1423. # Vel_RBPF_1 == Danger
  1424. # Acc_RBPF_1 == Danger
  1425. if (Vel_RBPF_HM[0] >= Vel_RBPF_HM_danger[0] or Acc_RBPF_HM[0] >= Acc_RBPF_HM_danger[0]):
  1426. RBPF_SEV = True
  1427. # Rotorbar pass frequency, moderate, CF=8, severity = 5
  1428. # OR
  1429. # Vel_RBPF_1 == Alert
  1430. # Acc_RBPF_1 == Alert
  1431. else:
  1432. if (Vel_RBPF_HM[0] >= Vel_RBPF_HM_alert[0] or Acc_RBPF_HM[0] >= Acc_RBPF_HM_alert[0]) and Vel_RBPF_HM[0] < Vel_RBPF_HM_danger[0] and Acc_RBPF_HM[0] < Acc_RBPF_HM_danger[0]:
  1433. RBPF_MOD = True
  1434. return RBPF_MOD, RBPF_SEV
  1435. ###############################################################################
  1436. ###############################################################################
  1437. # @staticmethod
  1438. # Note: the default alert and danger threshold values (in mm/s RMS for velocity and g peak for acceleration) are set according a DSS AC motor model, it can be adjusted if necessary
  1439. def Cracked_Rotorbar_Diag(self,Vel_RBPF_HM, Acc_RBPF_HM, Vel_RBPF_alert_mmsRMS = 0.064*25.4, \
  1440. Vel_RBPF_danger_mmsRMS = 0.127*25.4, Acc_RBPF_alert_gPk = 2.5, Acc_RBPF_danger_gPk = 3.75):
  1441. RBPF_MOD = False
  1442. RBPF_SEV = False
  1443. Vel_RBPF_HM_alert = []
  1444. Vel_RBPF_HM_danger = []
  1445. Acc_RBPF_HM_alert = []
  1446. Acc_RBPF_HM_danger = []
  1447. CrackedRotorbarDetection = False
  1448. CrackedRotorbarSev = 0
  1449. [Acc_RBPF_HM_alert, Acc_RBPF_HM_danger] = self.Acc_RBPF_HM_Threshhold(Acc_RBPF_alert_gPk, Acc_RBPF_danger_gPk)
  1450. [Vel_RBPF_HM_alert,Vel_RBPF_HM_danger] = self.Vel_RBPF_HM_Threshhold(Vel_RBPF_alert_mmsRMS, Vel_RBPF_danger_mmsRMS)
  1451. [RBPF_MOD, RBPF_SEV] = self.RBPF_Symptom_Rule(Vel_RBPF_HM, Acc_RBPF_HM, Vel_RBPF_HM_alert, Vel_RBPF_HM_danger, Acc_RBPF_HM_alert, Acc_RBPF_HM_danger)
  1452. # Cracked rotorbar, sever CF = 8, severity = 10
  1453. # AND
  1454. # RBPF_SEV = True
  1455. if RBPF_SEV == True:
  1456. CrackedRotorbarDetection = True
  1457. CrackedRotorbarSev = 8
  1458. # Cracked rotorbar, moderate CF = 8, severity = 5
  1459. # AND
  1460. # RBPF_MOD = True
  1461. # NOR
  1462. # RBPF_SEV = True
  1463. if RBPF_MOD == True and (not(RBPF_SEV == True)):
  1464. CrackedRotorbarDetection = True
  1465. CrackedRotorbarSev = 5
  1466. return CrackedRotorbarDetection, CrackedRotorbarSev
  1467. ###############################################################################
  1468. ###############################################################################
  1469. # @staticmethod
  1470. # Note: the default velocity alert and danger threshold (in mm/s RMS for velocity) is set according a DSS AC motor model, it can be adjusted if necessary
  1471. def LF2X_Symptom_Rule(self,Vel_2XLF_HM, gE_2XLF_HM, Vel_2XLF_HM_alert, Vel_2XLF_HM_danger, gE_2XLF_HM_alert, gE_2XLF_HM_danger):
  1472. LF2X_MOD = False
  1473. LF2X_SEV = False
  1474. # 2X line frequency, moderate, CF=8, severity = 5
  1475. # AND
  1476. # Vel_2XLF_1 = alert
  1477. if Vel_2XLF_HM[0] >= Vel_2XLF_HM_alert[0] and Vel_2XLF_HM[0] < Vel_2XLF_HM_danger[0]:
  1478. LF2X_MOD = True
  1479. # 2X line frequency, moderate, several defect peaks, no confirming velocity, CF=8, severity = 5
  1480. # AND
  1481. # OR
  1482. # AND
  1483. # gE_2XLF_1 = alert
  1484. # gE_2XLF_2 = alert
  1485. # AND
  1486. # gE_2XLF_1 = alert
  1487. # gE_2XLF_3 = alert
  1488. # AND
  1489. # gE_2XLF_1 = alert
  1490. # gE_2XLF_4 = alert
  1491. # AND
  1492. # gE_2XLF_1 = alert
  1493. # gE_2XLF_5 = alert
  1494. # NOR
  1495. # Vel_2XLF_1 >= alert
  1496. else:
  1497. if (((gE_2XLF_HM[0] >= gE_2XLF_HM_alert[0] and gE_2XLF_HM[0] < gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[1] >= gE_2XLF_HM_alert[1] and gE_2XLF_HM[1] < gE_2XLF_HM_danger[1])) or \
  1498. ((gE_2XLF_HM[0] >= gE_2XLF_HM_alert[0] and gE_2XLF_HM[0] < gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[2] >= gE_2XLF_HM_alert[2] and gE_2XLF_HM[2] < gE_2XLF_HM_danger[2])) or \
  1499. ((gE_2XLF_HM[0] >= gE_2XLF_HM_alert[0] and gE_2XLF_HM[0] < gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[3] >= gE_2XLF_HM_alert[3] and gE_2XLF_HM[3] < gE_2XLF_HM_danger[3])) or \
  1500. ((gE_2XLF_HM[0] >= gE_2XLF_HM_alert[0] and gE_2XLF_HM[0] < gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[4] >= gE_2XLF_HM_alert[4] and gE_2XLF_HM[4] < gE_2XLF_HM_danger[4]))) and \
  1501. (not(Vel_2XLF_HM[0] >= Vel_2XLF_HM_alert[0])):
  1502. LF2X_MOD = True
  1503. # 2X line frequency, severe, CF=8, severity = 10
  1504. # AND
  1505. # Vel_2XLF_1 = Danger
  1506. if Vel_2XLF_HM[0] >= Vel_2XLF_HM_danger[0]:
  1507. LF2X_SEV = True
  1508. # 2X line frequency, severe, several defect peaks, no confirming velocity, CF=8, severity = 10
  1509. # AND
  1510. # OR
  1511. # AND
  1512. # gE_2XLF_1 >= danger
  1513. # gE_2XLF_2 >= alert
  1514. # AND
  1515. # gE_2XLF_1 >= danger
  1516. # gE_2XLF_3 >= alert
  1517. # AND
  1518. # gE_2XLF_1 >= danger
  1519. # gE_2XLF_4 >= alert
  1520. # AND
  1521. # gE_2XLF_1 >= danger
  1522. # gE_2XLF_5 >= alert
  1523. # NOR
  1524. # Vel_2XLF_1 >= alert
  1525. else:
  1526. if (((gE_2XLF_HM[0] >= gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[1] >= gE_2XLF_HM_alert[1])) or \
  1527. ((gE_2XLF_HM[0] >= gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[2] >= gE_2XLF_HM_alert[2])) or \
  1528. ((gE_2XLF_HM[0] >= gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[3] >= gE_2XLF_HM_alert[3])) or \
  1529. ((gE_2XLF_HM[0] >= gE_2XLF_HM_danger[0]) and (gE_2XLF_HM[4] >= gE_2XLF_HM_alert[4]))) and \
  1530. (not(Vel_2XLF_HM[0] < Vel_2XLF_HM_alert[0])):
  1531. LF2X_SEV = True
  1532. # 2X line frequency, severe, confirmed by velocity spectrum, CF=8, severity = 10
  1533. # AND
  1534. # OR
  1535. # gE_2XLF_1 >= Alert
  1536. # gE_2XLF_2 >= Alert
  1537. # OR
  1538. # Vel_2XLF_1 >= Alert
  1539. else:
  1540. if (gE_2XLF_HM[0] >= gE_2XLF_HM_alert[0] or gE_2XLF_HM[1] >= gE_2XLF_HM_alert[1]) and \
  1541. Vel_2XLF_HM[0] >= Vel_2XLF_HM_alert[0]:
  1542. LF2X_SEV = True
  1543. return LF2X_MOD, LF2X_SEV
  1544. ###############################################################################
  1545. ###############################################################################
  1546. # @staticmethod
  1547. def Variable_AirGap_Diag(self,Vel_2XLF_HM, gE_2XLF_HM, Vel_2XLF_alert = 0.064*25.4, Vel_2XLF_danger = 0.127*25.4, gE_2XLF_alert = 3, gE_2XLF_danger = 10):
  1548. LF2X_MOD = False
  1549. LF2X_SEV = False
  1550. gE_2XLF_HM_alert = []
  1551. gE_2XLF_HM_danger = []
  1552. Vel_2XLF_HM_alert = []
  1553. Vel_2XLF_HM_danger = []
  1554. VariableAirgapDetection = False
  1555. VariableAirgapSev = 0
  1556. [gE_2XLF_HM_alert,gE_2XLF_HM_danger] = self.gE_2XLF_HM_Threshhold(gE_2XLF_alert, gE_2XLF_danger)
  1557. [Vel_2XLF_HM_alert,Vel_2XLF_HM_danger] = self.Vel_2XLF_HM_Threshhold(Vel_2XLF_alert, Vel_2XLF_danger)
  1558. [LF2X_MOD, LF2X_SEV] = self.LF2X_Symptom_Rule(Vel_2XLF_HM, gE_2XLF_HM, Vel_2XLF_HM_alert, Vel_2XLF_HM_danger,gE_2XLF_HM_alert, gE_2XLF_HM_danger)
  1559. # Variable air gap, sever CF = 8, severity = 10
  1560. # AND
  1561. # LF2X_SEV = True
  1562. if LF2X_SEV == True:
  1563. VariableAirgapDetection = True
  1564. VariableAirgapSev = 8
  1565. # Variable air gap, moderate CF = 8, severity = 5
  1566. # AND
  1567. # LF2X_MOD = True
  1568. # NOR
  1569. # LF2X_SEV = True
  1570. else:
  1571. if LF2X_MOD == True and LF2X_SEV == False:
  1572. VariableAirgapDetection = True
  1573. VariableAirgapSev = 5
  1574. return VariableAirgapDetection, VariableAirgapSev
  1575. ###############################################################################
  1576. ###############################################################################
  1577. def VPF_Symptom_Rule(self,Vel_VPF_HM, Vel_VPF_HM_alert, Vel_VPF_HM_danger):
  1578. VAN_VPFH_MOD = False
  1579. VAN_VPFH_SEV = False
  1580. # Vane pass frequency and harmonics (VPFH), sever, CF=8, Severity = 10
  1581. # OR
  1582. # Vel_VPF_1 = Danger
  1583. # Vel_VPF_2 = Danger
  1584. if Vel_VPF_HM[0] >= Vel_VPF_HM_danger[0] or Vel_VPF_HM[1] >= Vel_VPF_HM_danger[1] :
  1585. VAN_VPFH_SEV = True
  1586. # Vane pass frequency and harmonics (VPFH), moderate, CF=8, Severity = 5
  1587. # AND
  1588. # OR
  1589. # Vel_VPF_1 = Alert
  1590. # Vel_VPF_2 = Alert
  1591. # NOR
  1592. # Vel_VPF_1 = Danger
  1593. # Vel_VPF_2 = Danger
  1594. if (Vel_VPF_HM[0] >= Vel_VPF_HM_alert[0] and Vel_VPF_HM[0] < Vel_VPF_HM_danger[0] or\
  1595. Vel_VPF_HM[1] >= Vel_VPF_HM_alert[1] and Vel_VPF_HM[1] < Vel_VPF_HM_danger[1]) and\
  1596. (not(Vel_VPF_HM[0] >= Vel_VPF_HM_danger[0] or Vel_VPF_HM[1] >= Vel_VPF_HM_danger[1])):
  1597. VAN_VPFH_MOD = True
  1598. return VAN_VPFH_MOD, VAN_VPFH_SEV
  1599. ###############################################################################
  1600. ###############################################################################
  1601. # @staticmethod
  1602. def Vane_WearDamage_Diag(self,Vel_VPF_HM, Vel_VPF_alert_mmsRMS = 0.159*25.4, \
  1603. Vel_VPF_danger_mmsRMS = 0.318*25.4):
  1604. VAN_VPFH_MOD = False
  1605. VAN_VPFH_SEV = False
  1606. Vel_VPF_HM_alert = []
  1607. Vel_VPF_HM_danger = []
  1608. VaneWearDamageDetection = False
  1609. VaneWearDamageSev = 0
  1610. [Vel_VPF_HM_alert,Vel_VPF_HM_danger] = self.Vel_VPF_HM_Threshhold(Vel_VPF_alert_mmsRMS, Vel_VPF_danger_mmsRMS)
  1611. [VAN_VPFH_MOD, VAN_VPFH_SEV] = self.VPF_Symptom_Rule(Vel_VPF_HM, Vel_VPF_HM_alert, Vel_VPF_HM_danger)
  1612. # Vane wear or damage, severe CF = 8, severity = 10
  1613. # OR
  1614. # VAN_VPFH_SEV= True
  1615. if VAN_VPFH_SEV == True:
  1616. VaneWearDamageDetection = True
  1617. VaneWearDamageSev = 10
  1618. # Vane wear or damage, moderate CF = 6, severity = 5
  1619. # OR
  1620. # VAN_VPFH_MOD= True
  1621. else:
  1622. if VAN_VPFH_MOD == True:
  1623. VaneWearDamageDetection = True
  1624. VaneWearDamageSev = 5
  1625. return VaneWearDamageDetection, VaneWearDamageSev
  1626. ###############################################################################
  1627. ###############################################################################
  1628. # 巴特沃斯带通滤波
  1629. # xTimeWave是时域波形数组, fs是采样频率,单位为Hz
  1630. # lowcut 为低截止频率,单位为Hz
  1631. # highcut 为高截止频率,单位为Hz
  1632. # Order为滤波器阶数,通常为偶数,2,4,6,8一般不超过8
  1633. def BandPassButter(self,xTimeWave, lowcut, highcut, fs, order):
  1634. low = lowcut * 2 / fs
  1635. high = highcut * 2 / fs
  1636. sos = signal.butter(order, [low, high], 'bandpass', output='sos')
  1637. filtered = signal.sosfilt(sos, xTimeWave)
  1638. return filtered