371 lines
18 KiB
JavaScript
371 lines
18 KiB
JavaScript
"use strict";
|
||
|
||
let signals = gtl.options.record.signalsModel;
|
||
let options = gtl.options;
|
||
let record = gtl.options.record;
|
||
let point = gtl.options.point;
|
||
|
||
// let fnc = gtl.import("user-functions.js"); // используемые функции
|
||
|
||
let plot_0 = gtl.plots.add("Спектр ускорения (канал 0)"); // спектр ускорения канала 0
|
||
let plot_1 = gtl.plots.add("Спектр ускорения (канал 1)"); // спектр ускорения канала 1
|
||
let plot_2 = gtl.plots.add("Спектр ускорения (канал 2)"); // спектр ускорения канала 2
|
||
let plot_3 = gtl.plots.add("Спектр силы (канал 3)"); // спектр ускорения канала 3
|
||
let plot_FreqResp_0_3 = gtl.plots.add("Частотный отклик (каналы 0 и 3)"); // частотный отклик между каналами 0 и 3
|
||
let plot_FreqResp_1_3 = gtl.plots.add("Частотный отклик (каналы 1 и 3)"); // частотный отклик между каналами 1 и 3
|
||
let plot_FreqResp_2_3 = gtl.plots.add("Частотный отклик (каналы 2 и 3)"); // частотный отклик между каналами 2 и 3
|
||
|
||
|
||
// ***************************************************************
|
||
// ********** ВЫЧИСЛЕНИЕ ЧАСТОТНОГО ОТКЛИКА (ВНИИЖТ) ***********
|
||
// ***************************************************************
|
||
|
||
// Алгоритм
|
||
// 1. Получить спектры ускорения и силы в комплексном виде (вибропреобразователь и молоток).
|
||
// 2. Преобразовать спектр силы (молотка) в комплексно-сопряжённый вид.
|
||
// 3. Получить кросс-спектр (перекрёстный) между ускорением и силой.
|
||
// 4. Вычислить деление кросс-спектра на спектр силы.
|
||
|
||
|
||
// ОБРАБОТКА СИГНАЛОВ
|
||
// ФИЛЬТРЫ
|
||
// Входной сигнал - виброускорение
|
||
|
||
// Файл импорта функций
|
||
// var imp = gtl.import("...");
|
||
|
||
// ПАРАМЕТРЫ и их ПОРОГОВЫЕ ЗНАЧЕНИЯ (уставки)
|
||
|
||
// Настройки спектров
|
||
// Цвета
|
||
// #ff0000 - красный
|
||
// #00ff00 - зелёный
|
||
// #0000ff - синий
|
||
// #00ddff - голубой
|
||
// #ff3dcc - фиолетовый
|
||
// #ffff00 - жёлтый
|
||
|
||
|
||
// *** Формирование спектров сигналов ***
|
||
|
||
// Настройки для спектров и АФЧХ
|
||
let frequency = gtl.options.customOptions.frequency; // граничная частота
|
||
let resolution = gtl.options.customOptions.resolution; // частотное разрешение
|
||
let lines = 1 / resolution; // количество линий
|
||
let average = gtl.options.customOptions.average; // количество усреднений
|
||
let overlap = gtl.options.customOptions.overlap; // наложение
|
||
|
||
// Задание диапазона сигнала для анализа
|
||
let ranges = gtl.player.stored_ranges;
|
||
|
||
// Спектры каналов ускорения (каналы датчиков вибрации)
|
||
|
||
// Канал_0
|
||
let ausp_acсel_0 = gtl.create_ausp(
|
||
{
|
||
"src": gtl.analog_inputs[signals[0].portNumber], // сигнал вибрации сырой
|
||
"frequency": frequency,
|
||
"resolution": resolution,
|
||
"average": average,
|
||
"overlap": overlap,
|
||
"window": gtl.spec.rectangular,
|
||
"view": gtl.spec.unit
|
||
}
|
||
);
|
||
|
||
// Канал_1
|
||
let ausp_acсel_1 = gtl.create_ausp(
|
||
{
|
||
"src": gtl.analog_inputs[signals[1].portNumber], // сигнал вибрации сырой
|
||
"frequency": frequency,
|
||
"resolution": resolution,
|
||
"average": average,
|
||
"overlap": overlap,
|
||
"window": gtl.spec.rectangular,
|
||
"view": gtl.spec.unit
|
||
}
|
||
);
|
||
|
||
// Канал_2
|
||
let ausp_acсel_2 = gtl.create_ausp(
|
||
{
|
||
"src": gtl.analog_inputs[signals[2].portNumber], // сигнал вибрации сырой
|
||
"frequency": frequency,
|
||
"resolution": resolution,
|
||
"average": average,
|
||
"overlap": overlap,
|
||
"window": gtl.spec.rectangular,
|
||
"view": gtl.spec.unit
|
||
}
|
||
);
|
||
|
||
// Спектр силы (канал сигнала молотка)
|
||
// Канал_3
|
||
let ausp_force_3 = gtl.create_ausp(
|
||
{
|
||
"src": gtl.analog_inputs[signals[3].portNumber], // сигнал вибрации сырой
|
||
"frequency": frequency,
|
||
"resolution": resolution,
|
||
"average": average,
|
||
"overlap": overlap,
|
||
"window": gtl.spec.rectangular,
|
||
"view": gtl.spec.unit
|
||
}
|
||
);
|
||
|
||
|
||
|
||
//*******************ДИАГНОСТИКА*********************
|
||
//***************************************************
|
||
|
||
// Задаем период проведения диагностики в секундах
|
||
var acq_time = Math.max(ausp_acсel_0.acq_time, ausp_acсel_1.acq_time, ausp_acсel_2.acq_time,
|
||
ausp_force_3.acq_time) + 0.3;
|
||
gtl.diagnostic.interval = acq_time;
|
||
// gtl.diagnostic.interval = 10; // время в секундах (константа)
|
||
// примечание: наблюдается зависимость результатов АФЧХ от времени диагностики
|
||
|
||
function diagnose() {
|
||
|
||
let n = ausp_force_3.data.length; // переменная для цикла
|
||
|
||
gtl.log.info("n (ausp_data.length)", ausp_force_3.data.length);
|
||
gtl.log.info("Минимально необходимая длительность сигнала", gtl.diagnostic.interval);
|
||
|
||
|
||
// Получение массивов для формулы определения частотного отклика
|
||
|
||
// Канал_3 (ausp_force_3) - комплексно-сопряжённый вид
|
||
// меняется знак мнимой части на противоположный
|
||
// действительная часть без изменений
|
||
let ausp_force_3_imag_anti = []; // мнимая часть с противоположным знаком
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
ausp_force_3_imag_anti.push(ausp_force_3.imag[i] * (-1));
|
||
}
|
||
// Кросс-спектры
|
||
// Канал_0 & Канал_3
|
||
let ausp_cross_0_3_real = []; // действительная часть кросс-спектра 0 & 3
|
||
let ausp_cross_0_3_imag = []; // мнимая часть кросс-спектра 0 & 3
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
ausp_cross_0_3_real.push(ausp_acсel_0.real[i] * ausp_force_3.real[i] -
|
||
(ausp_acсel_0.imag[i] * ausp_force_3_imag_anti[i]));
|
||
ausp_cross_0_3_imag.push(ausp_acсel_0.real[i] * ausp_force_3_imag_anti[i] +
|
||
ausp_acсel_0.imag[i] * ausp_force_3.real[i]);
|
||
}
|
||
// Канал_1 & Канал_3
|
||
var ausp_cross_1_3_real = []; // действительная часть кросс-спектра 1 & 3
|
||
var ausp_cross_1_3_imag = []; // мнимая часть кросс-спектра 1 & 3
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
ausp_cross_1_3_real.push(ausp_acсel_1.real[i] * ausp_force_3.real[i] -
|
||
(ausp_acсel_1.imag[i] * ausp_force_3_imag_anti[i]));
|
||
ausp_cross_1_3_imag.push(ausp_acсel_1.real[i] * ausp_force_3_imag_anti[i] +
|
||
ausp_acсel_1.imag[i] * ausp_force_3.real[i]);
|
||
}
|
||
// Канал_2 & Канал_3
|
||
var ausp_cross_2_3_real = []; // действительная часть кросс-спектра 2 & 3
|
||
var ausp_cross_2_3_imag = []; // мнимая часть кросс-спектра 2 & 3
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
ausp_cross_2_3_real.push(ausp_acсel_2.real[i] * ausp_force_3.real[i] -
|
||
(ausp_acсel_2.imag[i] * ausp_force_3_imag_anti[i]));
|
||
ausp_cross_2_3_imag.push(ausp_acсel_2.real[i] * ausp_force_3_imag_anti[i] +
|
||
ausp_acсel_2.imag[i] * ausp_force_3.real[i]);
|
||
}
|
||
|
||
// Частотный отклик (деление кросс-спектра на спектр силы)
|
||
// (Канал_0 & Канал_3) / Канал_3
|
||
let freq_resp_0_3_real = []; // действительная часть частотного отклика между 0 и 3
|
||
let freq_resp_0_3_imag = []; // мнимая часть частотного отклика между 0 и 3
|
||
let freq_resp_0_3_ampl = []; // амплитуда частотного отклика между 0 и 3
|
||
let freq_resp_0_3_phase = []; // фаза частотного отклика между 0 и 3 (корректировка)
|
||
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_0_3_real.push((ausp_cross_0_3_real[i] * ausp_force_3.real[i] +
|
||
ausp_cross_0_3_imag[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
|
||
freq_resp_0_3_imag.push((ausp_force_3.real[i] * ausp_cross_0_3_imag[i] -
|
||
ausp_cross_0_3_real[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
}
|
||
// запись массива амплитуды и фазы
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_0_3_ampl.push(Math.sqrt(Math.pow(freq_resp_0_3_real[i],2) + Math.pow(freq_resp_0_3_imag[i],2)));
|
||
if (freq_resp_0_3_real[i] > 0 & freq_resp_0_3_imag[i] > 0)
|
||
{freq_resp_0_3_phase.push(Math.atan(freq_resp_0_3_imag[i] / freq_resp_0_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_0_3_real[i] < 0 & freq_resp_0_3_imag[i] > 0)
|
||
{freq_resp_0_3_phase.push(180 - Math.atan(freq_resp_0_3_imag[i] / freq_resp_0_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_0_3_real[i] < 0 & freq_resp_0_3_imag[i] < 0)
|
||
{freq_resp_0_3_phase.push(180 + Math.atan(freq_resp_0_3_imag[i] / freq_resp_0_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_0_3_real[i] > 0 & freq_resp_0_3_imag[i] < 0)
|
||
{freq_resp_0_3_phase.push(360 - Math.atan(freq_resp_0_3_imag[i] / freq_resp_0_3_real[i]) * 180 / Math.PI)}
|
||
}
|
||
// корректировка угла для предотвращения превышения 360 град
|
||
for (let i = 0; i < freq_resp_0_3_phase.length; i += 1)
|
||
{
|
||
if (freq_resp_0_3_phase[i] >= 360)
|
||
{freq_resp_0_3_phase[i] = freq_resp_0_3_phase[i] - 360}
|
||
else {freq_resp_0_3_phase[i] = freq_resp_0_3_phase[i]}
|
||
}
|
||
|
||
// (Канал_1 & Канал_3) / Канал_3
|
||
let freq_resp_1_3_real = []; // действительная часть частотного отклика между 0 и 3
|
||
let freq_resp_1_3_imag = []; // мнимая часть частотного отклика между 0 и 3
|
||
let freq_resp_1_3_ampl = []; // амплитуда частотного отклика между 0 и 3
|
||
let freq_resp_1_3_phase = []; // фаза частотного отклика между 0 и 3
|
||
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_1_3_real.push((ausp_cross_1_3_real[i] * ausp_force_3.real[i] +
|
||
ausp_cross_1_3_imag[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
|
||
freq_resp_1_3_imag.push((ausp_force_3.real[i] * ausp_cross_1_3_imag[i] -
|
||
ausp_cross_1_3_real[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
}
|
||
// запись массива амплитуды и фазы
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_1_3_ampl.push(Math.sqrt(Math.pow(freq_resp_1_3_real[i],2) + Math.pow(freq_resp_1_3_imag[i],2)));
|
||
if (freq_resp_1_3_real[i] > 0 & freq_resp_1_3_imag[i] > 0)
|
||
{freq_resp_1_3_phase.push(Math.atan(freq_resp_1_3_imag[i] / freq_resp_1_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_1_3_real[i] < 0 & freq_resp_1_3_imag[i] > 0)
|
||
{freq_resp_1_3_phase.push(180 - Math.atan(freq_resp_1_3_imag[i] / freq_resp_1_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_1_3_real[i] < 0 & freq_resp_1_3_imag[i] < 0)
|
||
{freq_resp_1_3_phase.push(180 + Math.atan(freq_resp_1_3_imag[i] / freq_resp_1_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_1_3_real[i] > 0 & freq_resp_1_3_imag[i] < 0)
|
||
{freq_resp_1_3_phase.push(360 - Math.atan(freq_resp_1_3_imag[i] / freq_resp_1_3_real[i]) * 180 / Math.PI)}
|
||
}
|
||
// корректировка угла для предотвращения превышения 360 град
|
||
for (let i = 0; i < freq_resp_1_3_phase.length; i += 1)
|
||
{
|
||
if (freq_resp_1_3_phase[i] >= 360)
|
||
{freq_resp_1_3_phase[i] = freq_resp_1_3_phase[i] - 360}
|
||
else {freq_resp_1_3_phase[i] = freq_resp_1_3_phase[i]}
|
||
}
|
||
|
||
// (Канал_2 & Канал_3) / Канал_3
|
||
let freq_resp_2_3_real = []; // действительная часть частотного отклика между 2 и 3
|
||
let freq_resp_2_3_imag = []; // мнимая часть частотного отклика между 2 и 3
|
||
let freq_resp_2_3_ampl = []; // амплитуда частотного отклика между 2 и 3
|
||
let freq_resp_2_3_phase = []; // фаза частотного отклика между 2 и 3
|
||
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_2_3_real.push((ausp_cross_2_3_real[i] * ausp_force_3.real[i] +
|
||
ausp_cross_2_3_imag[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
|
||
freq_resp_2_3_imag.push((ausp_force_3.real[i] * ausp_cross_2_3_imag[i] -
|
||
ausp_cross_2_3_real[i] * ausp_force_3.imag[i]) /
|
||
(Math.pow(ausp_force_3.real[i], 2) + Math.pow(ausp_force_3.imag[i], 2)));
|
||
}
|
||
// запись массива амплитуды и фазы
|
||
for (let i = 0; i < n; i += 1)
|
||
{
|
||
freq_resp_2_3_ampl.push(Math.sqrt(Math.pow(freq_resp_2_3_real[i],2) + Math.pow(freq_resp_2_3_imag[i],2)));
|
||
if (freq_resp_2_3_real[i] > 0 & freq_resp_2_3_imag[i] > 0)
|
||
{freq_resp_2_3_phase.push(Math.atan(freq_resp_2_3_imag[i] / freq_resp_2_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_2_3_real[i] < 0 & freq_resp_2_3_imag[i] > 0)
|
||
{freq_resp_2_3_phase.push(180 - Math.atan(freq_resp_2_3_imag[i] / freq_resp_2_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_2_3_real[i] < 0 & freq_resp_2_3_imag[i] < 0)
|
||
{freq_resp_2_3_phase.push(180 + Math.atan(freq_resp_2_3_imag[i] / freq_resp_2_3_real[i]) * 180 / Math.PI)}
|
||
else if (freq_resp_2_3_real[i] > 0 & freq_resp_2_3_imag[i] < 0)
|
||
{freq_resp_2_3_phase.push(360 - Math.atan(freq_resp_2_3_imag[i] / freq_resp_2_3_real[i]) * 180 / Math.PI)}
|
||
}
|
||
// корректировка угла для предотвращения превышения 360 град
|
||
for (let i = 0; i < freq_resp_2_3_phase.length; i += 1)
|
||
{
|
||
if (freq_resp_2_3_phase[i] >= 360)
|
||
{freq_resp_2_3_phase[i] = freq_resp_2_3_phase[i] - 360}
|
||
else {freq_resp_2_3_phase[i] = freq_resp_2_3_phase[i]}
|
||
}
|
||
|
||
// Построение пользовательских графиков
|
||
|
||
plot_0.add(
|
||
{
|
||
color: 0x04ff00,
|
||
name: "Спектр ускорения (канал 0)",
|
||
x: 1/lines,
|
||
y: ausp_acсel_0.data
|
||
});
|
||
|
||
plot_1.add(
|
||
{
|
||
color: 0xcad714,
|
||
name: "Спектр ускорения (канал 1)",
|
||
x: 1/lines,
|
||
y: ausp_acсel_1.data
|
||
});
|
||
|
||
plot_2.add(
|
||
{
|
||
color: 0xff8800,
|
||
name: "Спектр ускорения (канал 2)",
|
||
x: 1/lines,
|
||
y: ausp_acсel_2.data
|
||
});
|
||
|
||
plot_3.add(
|
||
{
|
||
color: 0xff00f7,
|
||
name: "Спектр силы (канал 3)",
|
||
x: 1/lines,
|
||
y: ausp_force_3.data
|
||
});
|
||
|
||
plot_FreqResp_0_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Амплитуда частотный отклик (каналы 0 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_0_3_ampl
|
||
});
|
||
plot_FreqResp_0_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Фаза частотного отклика (каналы 0 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_0_3_phase
|
||
});
|
||
|
||
plot_FreqResp_1_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Амплитуда частотный отклик (каналы 1 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_1_3_ampl
|
||
});
|
||
plot_FreqResp_1_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Фаза частотного отклика (каналы 1 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_1_3_phase
|
||
});
|
||
|
||
plot_FreqResp_2_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Амплитуда частотный отклик (каналы 2 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_2_3_ampl
|
||
});
|
||
plot_FreqResp_2_3.add(
|
||
{
|
||
color: 0xedc887,
|
||
name: "Фаза частотного отклика (каналы 2 и 3)",
|
||
x: 1/lines,
|
||
y: freq_resp_2_3_phase
|
||
});
|
||
|
||
|
||
gtl.diagnostic.stop();
|
||
} |