freq_responce/scripts/Частотный_отклик v2.js

371 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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();
}