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

304 lines
15 KiB
JavaScript
Raw Permalink 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_ausp_j = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_FreqResp_ampl_j = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_FreqResp_phase_j = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
// Алгоритм
// 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 view_ = gtl.options.customOptions.view; // отображение амплитуды спектра db / unit (1 / 0)
let view = gtl.spec.unit; // значение view по умолчанию
let view_freq_resp = gtl.options.customOptions.view_freq_resp; // отображение амплитуды спектра частотного отклика db / unit (1 / 0)
let variant_freq_resp = gtl.options.customOptions.variant_freq_resp; // вариант вычисления: 0 - через кросс, 1 - через автоспектр
let ausp_j = []; // массив объектов спектров вибрации
let phase_delta_j = []; // массив объектов дельты фазовых спектров вибрации и спектра силы
let counter = 1; // счётчик для цикла по каналам вибрации
let counter_ranges = 0; // счётчик для цикла по выделенным диапазонам сигналов записи
let ausp_cross_real = []; // массив объектов действительной части кросс-спектров канала силы [0] и канала вибрации [j]
let ausp_cross_imag = []; // массив объектов мнимой части кросс-спектров канала силы [0] и канала вибрации [j]
let freq_resp_real = []; // действительная часть частотного отклика между каналом силы [0] и каналом вибрации [j]
let freq_resp_imag = []; // мнимая часть частотного отклика между каналом силы [0] и каналом вибрации [j]
let freq_resp_ampl = []; // амплитуда частотного отклика между каналом силы [0] и каналом вибрации [j]
let freq_resp_phase = []; // фаза частотного отклика между каналом силы [0] и каналом вибрации [j]
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.custom_ranges;
// ranges.custom_ranges = [{min : 0.0172949, max: 0.4528125}, ranges[0]];
// gtl.player.custom_ranges = [gtl.player.stored_ranges[1,2,3]];
gtl.log.info("Количество выделенных диапазонов", gtl.player.stored_ranges.length);
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
// Условие отображения спектров в дБ или линейном виде
if (view_ == 1) {view = gtl.spec.db}
else if (view_ == 0) {view = gtl.spec.unit}
// Спектр амплитудный для цикла по всем каналам вибрации
for (let j = 1; j < signals.length; j++) {
ausp_j.push(
gtl.create_ausp(
{
"src": gtl.analog_inputs[signals[j].portNumber], // сигнал вибрации
"frequency": frequency,
"resolution": resolution,
"average": average,
"overlap": overlap,
"window": gtl.spec.rectangular,
"view": view
}
)
);
}
// Спектр фазовый для цикла по всем каналам вибрации
for (let j = 1; j < signals.length; j++) {
phase_delta_j.push(
gtl.create_pfc(
{
"src0" : gtl.analog_inputs[signals[j].portNumber], // сигнал вибрации
"src1" : gtl.analog_inputs[signals[0].portNumber], // сигнал силы
"frequency" : frequency,
"resolution" : resolution,
"average" : average,
"overlap" : overlap,
"window" : gtl.spec.rectangular,
"view" : gtl.phase.deg,
"range" : gtl.phase.positive,
"is_single" : false
}
)
);
}
gtl.log.info("Количество спектров", ausp_j.length);
// Спектр силы (канал сигнала молотка)
// Канал_0
let ausp_force_0 = gtl.create_ausp(
{
"src": gtl.analog_inputs[signals[0].portNumber], // сигнал силы
"frequency": frequency,
"resolution": resolution,
"average": average,
"overlap": overlap,
"window": gtl.spec.rectangular,
"view": view
}
);
//*******************ДИАГНОСТИКА*********************
//***************************************************
// Задаем период проведения диагностики в секундах
var acq_time = Math.max(ausp_force_0.acq_time) + 0.3;
gtl.diagnostic.interval = acq_time;
// gtl.diagnostic.interval = 10; // время в секундах (константа)
// примечание: наблюдается зависимость результатов АФЧХ от времени диагностики
function diagnose() {
// gtl.log.info("ranges", JSON.stringify(ranges));
// gtl.log.info("ranges", JSON.stringify(gtl.player.stored_ranges));
let n = ausp_force_0.data.length; // переменная для цикла по гармоникам спектра
// signals.length - переменная для цикла по каналам
gtl.log.info("n (ausp_data.length)", ausp_force_0.data.length);
gtl.log.info("Минимально необходимая длительность сигнала", gtl.diagnostic.interval);
// Канал[0] (ausp_force_0) - комплексно-сопряжённый вид
// меняется знак мнимой части на противоположный
// действительная часть без изменений
let ausp_force_0_imag_anti = []; // мнимая часть с противоположным знаком
for (let i = 0; i < n; i += 1)
{
ausp_force_0_imag_anti.push(ausp_force_0.imag[i] * (-1));
}
// Графики амплитудных спектров вибрации и спектров дельты фаз между каналами вибрации и силы
for (let j = 0; j < ausp_j.length; j++) {
if (counter > 0) {
plot_ausp_j.add(
{
color: 0x34C924,
name: `Спектр канала ${j+1}, g`,
x: ausp_j[j].resolution,
y: ausp_j[j].data,
tags: ["Амплитудный спектр вибрации, g"]
}
);
// plot_ausp_j.add(
// {
// color: 0x00ddff,
// name: `Разница фаз канала ${j+1} и канала силы`,
// x: phase_delta_j[j].resolution,
// y: phase_delta_j[j].data,
// tags: ["Разница фаз вибрации и силы"]
// }
// );
// plot_FreqResp_phase_j.add(
// {
// color: 0x00ddff,
// name: `Разница фаз канала ${j+1} и канала силы`,
// x: phase_delta_j[j].resolution,
// y: phase_delta_j[j].data,
// tags: ["Разница фаз вибрации и силы"]
// }
// );
// Кросс-спектры
// Канал[0] & Канал[j]
ausp_cross_real[j] = [];
ausp_cross_imag[j] = [];
for (let i = 0; i < n; i += 1)
{
ausp_cross_real[j].push(ausp_j[j].real[i] * ausp_force_0.real[i] -
(ausp_j[j].imag[i] * ausp_force_0_imag_anti[i]));
ausp_cross_imag[j].push(ausp_j[j].real[i] * ausp_force_0_imag_anti[i] +
ausp_j[j].imag[i] * ausp_force_0.real[i]);
}
freq_resp_real[j] = []; // массив массивов действительной части отклика
freq_resp_imag[j] = []; // массив массивов мнимой части отклика
if (variant_freq_resp == 0)
{
// Частотный отклик (деление кросс-спектра на спектр силы)
// (Канал[0] & Канал[j]) / Канал[0]
for (let i = 0; i < n; i += 1)
{
freq_resp_real[j].push((ausp_cross_real[j][i] * ausp_force_0.real[i] +
ausp_cross_imag[j][i] * ausp_force_0.imag[i]) /
(Math.pow(ausp_cross_real[j][i], 2) + Math.pow(ausp_force_0.imag[i], 2)));
freq_resp_imag[j].push((ausp_force_0.real[i] * ausp_cross_imag[j][i] -
ausp_cross_real[j][i] * ausp_force_0.imag[i]) /
(Math.pow(ausp_cross_real[j][i], 2) + Math.pow(ausp_force_0.imag[i], 2)));
}
} else {
// Частотный отклик (деление спектра вибрации на спектр силы)
// Канал[j] / Канал[0]
for (let i = 0; i < n; i += 1)
{
freq_resp_real[j].push((ausp_j[j].real[i] * ausp_force_0.real[i] +
ausp_j[j].imag[i] * ausp_force_0.imag[i]) /
(Math.pow(ausp_j[j].real[i], 2) + Math.pow(ausp_force_0.imag[i], 2)));
freq_resp_imag[j].push((ausp_force_0.real[i] * ausp_j[j].imag[i] -
ausp_j[j].real[i] * ausp_force_0.imag[i]) /
(Math.pow(ausp_j[j].real[i], 2) + Math.pow(ausp_force_0.imag[i], 2)));
}
}
// запись массива амплитуды и фазы
freq_resp_ampl[j] = [];
freq_resp_phase[j] = [];
for (let i = 0; i < n; i += 1)
{
// Условие отображения спектров в дБ или линейном виде
if (view_freq_resp == 0) {
freq_resp_ampl[j].push(Math.sqrt(Math.pow(freq_resp_real[j][i],2) + Math.pow(freq_resp_imag[j][i],2)));
} else if (view_freq_resp == 1) {
freq_resp_ampl[j].push(20 * Math.log10((Math.sqrt(Math.pow(freq_resp_real[j][i],2) + Math.pow(freq_resp_imag[j][i],2))) / Math.pow(10,-6)));
}
if (freq_resp_real[j][i] > 0 & freq_resp_imag[j][i] > 0)
{freq_resp_phase[j].push(Math.atan(freq_resp_imag[j][i] / freq_resp_real[j][i]) * 180 / Math.PI)}
else if (freq_resp_real[j][i] < 0 & freq_resp_imag[j][i] > 0)
{freq_resp_phase[j].push(180 - Math.atan(freq_resp_imag[j][i] / freq_resp_real[j][i]) * 180 / Math.PI)}
else if (freq_resp_real[j][i] < 0 & freq_resp_imag[j][i] < 0)
{freq_resp_phase[j].push(180 + Math.atan(freq_resp_imag[j][i] / freq_resp_real[j][i]) * 180 / Math.PI)}
else if (freq_resp_real[j][i] > 0 & freq_resp_imag[j][i] < 0)
{freq_resp_phase[j].push(360 - Math.atan(freq_resp_imag[j][i] / freq_resp_real[j][i]) * 180 / Math.PI)}
}
// корректировка угла для предотвращения превышения 360 град
for (let i = 0; i < freq_resp_phase[j].length; i += 1)
{
if (freq_resp_phase[j][i] >= 360)
{freq_resp_phase[j][i] = freq_resp_phase[j][i] - 360}
else {freq_resp_phase[j][i] = freq_resp_phase[j][i]}
}
plot_FreqResp_ampl_j.add(
{
color: 0x3b30b6,
name: `Амплитуда частотного отклика канала ${j+1}, g/N`,
x: 1/lines,
y: freq_resp_ampl[j],
tags: ["Амплитуда частотного отклика, g/N"]
});
plot_FreqResp_phase_j.add(
{
color: 0xb6306f,
name: `Фаза частотного отклика канала ${j+1}, °`,
x: 1/lines,
y: freq_resp_phase[j],
tags: ["Фаза частотного отклика, °"]
});
}
};
// #b6306f - жёлтый
counter += 1;
plot_ausp_j.add(
{
color: 0xff00f7,
name: "Спектр силы (канал [0]), N",
x: 1/lines,
y: ausp_force_0.data,
tags: ["Спектр силы (канал [0]), N"]
});
gtl.diagnostic.stop();
}