DiagnosisLib.py 86 KB

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