DiagnosisLib.py 86 KB

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