gtld2-diag-scripts/peakClass.js

220 lines
9.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

export class peakClass {
constructor(args) {
this.wave = args.src;
this.freq = args.freq;
this.visible = args.visible;
if (args.spec != undefined) { this.spec = args.spec };
}
getLevels(rpm = this.freq * 60) {
let __allert = 0; //уровень предупреждения, g
switch (true) {
case rpm <= 900:
__allert = 3.0 * (rpm / 900) ** 0.75; //1.5 => 3.0 для формы Peak-To-Peak
break;
case (rpm > 900) && (rpm <= 4000):
__allert = 3.0; //1.5 => 3.0 для формы Peak-To-Peak
break;
case (rpm > 4000) && (rpm <= 10000):
__allert = 3.0 * (rpm / 4000) ** 0.5; //1.5 => 3.0 для формы Peak-To-Peak
break;
case rpm > 10000:
__allert = 5.0; //3.0 => 5.0 для формы Peak-To-Peak
default:
break;
};
return __allert
}; //рассчет пороговых уровней
getParams(rpm = this.freq * 60) {
let __wdt = 0; //граничная частота ФВЧ
let __frq = 40 * this.freq; //граничная частота спектра
let __lns = 800; //количество линий спектра
let __avg = 1; //количество усреднений спектра
switch (true) {
case rpm <= 700:
__wdt = 500;
__lns = 800;
break;
case (rpm > 700) && (rpm <= 1500):
__wdt = 1000;
__lns = 800;
break;
case (rpm > 1500) && (rpm <= 3000):
__wdt = 2000;
__lns = 1600;
break;
case (rpm > 3000) && (rpm <= 4000):
__wdt = 2000;
__lns = 1600;
case rpm > 4000:
__wdt = 5000;
__lns = 1600;
default:
break;
};
return {
filter: { frequency: __wdt },
spec: {
frequency: __frq,
lines: __lns,
resolution: __frq / __lns,
avg: __avg
}
};
}; //рассчет параметров спектра
getWave() {
let __allert = this.getLevels();
let __fault = 2 * __allert;
if (this.visible == true) {
let __canvas = gtl.plots.add("Waveform");
let __alr = this.wave.values.map((item) => (item = __allert));
let __flt = this.wave.values.map((item) => (item = __fault));
__canvas.add({
color: this.wave.color,
name: this.wave.name,
x: this.wave.time,
y: this.wave.values
}); //рисуем форму сигнала
__canvas.add({
color: 0xFFFF00,
name: "allert",
x: this.wave.time,
y: __alr
}); //рисуем порог предупреждения
__canvas.add({
color: 0xFF0000,
name: "fault",
x: this.wave.time,
y: __flt
}); //рисуем порог опасности
}
return __allert
}
getCorr() {
let __plot = []; //массив значений корреляции для графика
let arr = this.wave.values;
let arr2 = arr.concat(arr); //расширяем массив данных
let lag = 0.5;
let X = 0; //аргумент 1
let Y = 0; //аргумент 2
let T = Math.floor(arr.length * lag); //определяем количество индексов (шагов) для смещения массива
let avg = arr.reduce((acc, item) => (acc + item)) / arr.length; //среднее значение массива
Y = arr.reduce((acc, item) => (acc + (item - avg) ** 2), 0); //рассчитываем знаменатель функции
for (let i = 0; i < T; i++) {
X = 0;
for (let j = 0; j < arr.length; j++) { X += (arr[j] - avg) * (arr2[j + i] - avg) };
__plot.push(X / Y); //записываем значение в массив коэффициентов
}; //смещение массива
let __plot0 = __plot.slice(Math.floor(0.01 * __plot.length)); //убираем из массива первый 1% значений коэффициента (т.к. в нуле всегда значение 1.0)
let __max = Math.max(...__plot0); //определяем максимальное значение коэффициента
if (this.visible == true) {
let __canvas = gtl.plots.add("Correlation");
__canvas.add({
color: 0x00A550,
name: "Корреляционная функция",
x: this.wave.time,
y: __plot
});
}; //отрисовка графика на plot
return __max;
}; //рассчет автокорреляции
getSpecSquare() {
if (this.spec != undefined) {
let __base = this.spec.base; //массив значений средней линии
let __data = this.spec.data; //массив значений амплитуд
let __lines = this.spec.data.length; //количества линий спектра
let __res = this.spec.resolution; //частотное разрешения спектра (высота прямоугольной трапеции)
let __start = 0; //стартовый индекс в массиве
let __end = __lines; //конечный индекс в массиве
let s0 = 0; //площадь под базовой линией
let s1 = 0; //площадь всего спектра
let s2 = 0; //площадь над базовой линией
let s3 = 0; //площадь обнаруженных гармоник
for (let i = __start; i <= __end - 1; i++) {
s0 += __base[i] * __res;
s1 += __data[i] * __res;
let __delta = __data[i] - __base[i];
if (__delta >= 0) { s2 += __delta * __res };
if (__delta >= this.spec.peak_level) { s3 += __delta * __res };
};
return {
base: s0,
spec: s1,
harm: s2,
peak: s3
};
}; //определение площадей спектра
}
getResult() {
let __result = {}; //результат
let __mech = 0; //механические проблемы
let __lubr = 0; //проблемы со смазкой
let __allert = this.getWave(); //рисуем пиковую форму сигнала и получаем порог предупреждения, g
let __corr = this.getCorr(); //вычисляем автокорреляционную функцию (получаем максимум)
let MaxPK = Math.max(...this.wave.values); //максимальное значение амплитуды на пиковой форме, g
let FaultLevel = 2 * __allert; //уровень аварии для пиковой формы (Fault = 2 * Allert)
let EstPE = Math.sqrt(__corr) * 100; //расчетный процент периодической энергии
if (this.spec != undefined) {
let GS = MaxPK / FaultLevel; //общая серьезность проблемы
let SQpeak = this.getSpecSquare().peak; //площадь обнаруженных гармонических составляющих
let SQspec = this.getSpecSquare().harm; //площадь над базовой линией
let PE = (SQpeak ** 2 / SQspec ** 2); //доля периодической энергии
let NPE = (SQspec ** 2 - SQpeak ** 2) / SQspec ** 2; //доля непериодической энергии
__mech = GS * PE * 100;
__lubr = GS * NPE * 100;
__result = {
mechBS: __mech * 0.8, //нормализованное значение (для индикатора 0-100 единиц)
lubrBS: __lubr * 0.8, //нормализованное значение (для индикатора 0-100 единиц)
};
} else {
switch (true) {
case EstPE >= 50:
__mech = EstPE * MaxPK / FaultLevel;
__lubr = (100 - EstPE) * MaxPK / FaultLevel;
break;
case (EstPE <= 50) && (EstPE > 30):
EstPE = EstPE / 2;
__mech = EstPE * MaxPK / FaultLevel;
__lubr = (100 - EstPE) * MaxPK / FaultLevel;
break;
case EstPE < 30:
__mech = 0
__lubr = MaxPK / FaultLevel;
break;
default:
break;
}; //определяем действительный расчетный процент периодической энергии
__result = {
mechBS: __mech,
lubrBS: __lubr
};
};
return __result;
}; //оценка состояния методом PeakVM
}