balancer_calc/scripts/Одна_плоскость_с_фазой — ко...

371 lines
21 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";
var signals = gtl.options.record.signalsModel;
var options = gtl.options;
var record = gtl.options.record;
var point = gtl.options.point;
// Файл импорта функций
var imp = gtl.import("functions_for_balance.js");
// ***** БАЛАНСИРОВОЧНЫЙ КАЛЬКУЛЯТОР. ОДНА ПЛОСКОСТЬ с фазой *****
// ***************************************************************
// Получение входных сигналов
// ФИЛЬТР 2...1000 Гц, полосовой фильтр для СКЗ виброскорости и спектра
var filter_2_1000 = gtl.add_filter_iir(gtl.analog_inputs[signals[0].portNumber]);
filter_2_1000.kind = gtl.filter_iir.butterworth;
filter_2_1000.type = gtl.filter_iir.bandpass;
filter_2_1000.order = 6;
filter_2_1000.frequency = 502; // центральная частота полосового фильтра
filter_2_1000.width = 1000; // ширина полосы фильтра
var filter_2_1000v = gtl.add_intg(filter_2_1000); // интегрирование
filter_2_1000v.taps = 1; // степень интегрирования (скорость из ускорения - 1-нарное)
// Спектр виброскорости для получения 1-й гармоники частоты вращения
var AUSPv = gtl.add_ausp(filter_2_1000v); // объявление переменной спектра
AUSPv.color = 0x00ff0000; // цвет спектра
AUSPv.name = "AUSPv"; // имя спектра
AUSPv.frequency = 1000; // граничная частота спектра
AUSPv.lines = AUSPv.frequency * 4; // разрешение спектра (количество линий)
AUSPv.average = 4; // количество усреднений
AUSPv.unit = gtl.spec.unit; // отображение амплитуды в мм/с
AUSPv.smoothing_factor = 100; // усреднение средней линии
AUSPv.smoothed_line_color = 0xff004dff; // цвет средней линии
AUSPv.peak_level = 0.000001; // порог обнаружения гармоник (необходим самый минимальный)
AUSPv.tolerance = AUSPv.resolution; // диапазон поиска гармоник +/-
// СКЗv
var RMSv_2_1000 = gtl.add_value_rms(filter_2_1000v);
RMSv_2_1000.time = 1;
RMSv_2_1000.avg_cnt = 3;
// Определение частоты вращения по параметру freq.dc
var freq = gtl.add_value_freq(gtl.analog_inputs[signals[2].portNumber]);
freq.time = 1; // длина отрезка сигнала
freq.avg_cnt = 3; // усреднение
freq.dc = -0.05; // уровень, при переходе через который считаются периоды
// Фаза 1-й гармоники частоты вращения (виброскорости)
// var delta_phase_F1v = gtl.add_delta_phase_spec(filter_2_1000v, filter_freq);
// var delta_phase_F1v = gtl.add_delta_phase_spec(gtl.analog_inputs[0], filter_freq);
// var delta_phase_F1v = gtl.add_delta_phase_spec(gtl.analog_inputs[0], gtl.analog_inputs[record.tachoOptions.tachoChannel]);
var delta_phase_F1v = gtl.add_delta_phase_spec(filter_2_1000v, gtl.analog_inputs[signals[1].portNumber]);
var freq_begin = 54.25; // предположительное значение частоты вращения
var freq_round; // округлённая частота вращения для которой вычисляем фазу вибрации
var frq_arr = [freq_begin, freq_round]; // массив частот для которых определяем фазу
var i = 0;
var res_delta_phase_F1v = {}; // объект результатов вычислений разности фаз
delta_phase_F1v.max_frequency = AUSPv.frequency;
delta_phase_F1v.resolution = AUSPv.resolution;
delta_phase_F1v.frequency = frq_arr[0]; // частота, для которой вычисляется разница фаз, Гц
// Объявление переменных массивов
var level_AUSPv = []; // массив амплитуд гармоник канала 0
var delta_phase_AUSPv = []; // массив разностей фаз гармоник канала 0 относительно тахо
var index_AUSPv = []; // массив индексов гармоник канала 0
var frequency_AUSPv = []; // массив частот (перевод индексов) гармоник канала 0
// Переменные основные
// параметр вибрации (модуль вектора) - виброскорость (мм/с)
// угол (фаза) вектора - градусы
// масса груза (модуль ветора) - граммы
// * - значение получаем из измерительного блока при нажатии кнопки
// ** - значение вводится пользователем
// *** - значение получаем в результате расчёта программы балансировки
var A0=100; // модуль вектора начальной вибрации */**
var A0_phase=30; // фаза вектора начальной вибрации */**
var m_test=50; // модуль вектора пробного груза *
var m_test_corner=100; // угол вектора пробного груза *
var A1=75; // модуль вектора вибрации после установки пробного груза */**
var A1_phase=120; // фаза вектора вибрации после установки пробного груза */**
var dA; // модуль вектора дельты вибрации после установки пробного груза ***
var dA_phase; // фаза вектора дельты вибрации после установки пробного груза ***
var DCI; // модуль (мм/с/граммы) динамического коэффициента влияния (dinamic coefficient of influence) **/***
var DCI_phase; // фаза динамического коэффициента влияния **/***
var Mb; // модуль вектора балансировочного груза ***
var Mb_corner; // угол вектора балансировочного груза ***
var A2=1; // модуль вектора вибрации после установки балансировочного груза ***
var A2_phase=21; // фаза вектора вибрации после установки балансировочного груза ***
// Переменные вспомогательные
var A0_phase_X; // угол наклона вектора A0 к оси X
var A0_phase_Y; // угол наклона вектора A0 к оси Y
var A0_1_X; // начальная координата вектора A0 по оси X
var A0_2_X; // конечная координата вектора A0 по оси X
var A0_1_Y; // начальная координата вектора A0 по оси Y
var A0_2_Y; // конечная координата вектора A0 по оси Y
var A1_phase_X; // угол наклона вектора A1 к оси X
var A1_phase_Y; // угол наклона вектора A1 к оси Y
var A1_1_X; // начальная координата вектора A1 по оси X
var A1_2_X; // конечная координата вектора A1 по оси X
var A1_1_Y; // начальная координата вектора A1 по оси Y
var A1_2_Y; // конечная координата вектора A1 по оси Y
var dA_1_X; // начальная координата вектора dA по оси X
var dA_2_X; // конечная координата вектора dA по оси X
var dA_1_Y; // начальная координата вектора dA по оси Y
var dA_2_Y; // конечная координата вектора dA по оси Y
var m_test_corner_X;// угол наклона вектора m_test к оси X
var m_test_corner_Y;// угол наклона вектора m_test к оси Y
var m_test_1_X; // начальная координата вектора m_test по оси X
var m_test_2_X; // конечная координата вектора m_test по оси X
var m_test_1_Y; // начальная координата вектора m_test по оси Y
var m_test_2_Y; // конечная координата вектора m_test по оси Y
// ***** РАСЧЁТЫ *****
// gtl.diagnostic.interval = 10;
gtl.diagnostic.interval = Math.max(AUSPv.acq_time, delta_phase_F1v.acq_time);
// gtl.diagnostic.interval = delta_phase_F1v.acq_time; //интервал запуска функции диагностики
let state = record.tachoOptions.tachoState; // начальное состояние после выбора источника тахо сигнала
function diagnose() {
// Нестабильность частоты вращения
var freq_max = Math.max(...freq.values);
var freq_min = Math.min(...freq.values);
var instability = ((freq_max - freq_min) / freq.value) * 100; // * 100%
switch (state) {
case 0: // считаем частоту вращения и настраиваем спектры
var freq_max = Math.max(...freq.values);
var freq_min = Math.min(...freq.values);
var instability = (freq_max - freq_min) / freq.value;
// if (instability > imp.tolerance()) {
if (instability > 0.3) {
gtl.log.info("Критическая нестабильность частоты вращения, %", instability * 100);
gtl.log.info("Результат:", "Диагностика прервана");
//gtl.diagnostic.stop(); //принудительная остановка диагностики
let __result = {
Result: false
};
gtl.results = __result;
};
// Определение минимально необходимой длительности сигнала для проведения диагностики
gtl.diagnostic.interval = AUSPv.acq_time;
state = 3;
break;
case 1: // Частота вращения фиксированная
// Определение минимально необходимой длительности сигнала для проведения диагностики
gtl.diagnostic.interval = AUSPv.acq_time;
state = 3;
break;
case 2: // Частота вращения из поля INFO (виброметр)
// Определение минимально необходимой длительности сигнала для проведения диагностики
gtl.diagnostic.interval = AUSPv.acq_time;
state = 3;
break;
case 3: // Выполняем анализ спектов
// Очистка партретов спектров
AUSPv.clear_harms_sets();
// ТЕСТИРОВАНИЕ (получение фазы и амплитуды оборотной гармоники из массивов)
// Запись в массив значений уровня спектра
for (let i = 0; i < AUSPv.data.length; i++) {
index_AUSPv.push(i); // индексы гармоник
frequency_AUSPv.push(i * (AUSPv.frequency / AUSPv.lines)); // частоты гармоник
level_AUSPv.push(AUSPv.data[i]); // уровень гармоник, если отображение амплитуд в спектре unit
// level_AUSPv.push(AUSPv.data[i] - AUSPv.base[i]); // уровень гармоник, если отображение амплитуд в спектре db
}
var F_find = freq.value; // искомая частота
var F_find_round_min = Math.round(F_find); // округление значения искомой частоты до ближайшего
var F_find_round_max = Math.round(F_find) + AUSPv.resolution; // округление значения искомой частоты в большую сторону
if (level_AUSPv[frequency_AUSPv.indexOf(F_find_round_min)] >= level_AUSPv[frequency_AUSPv.indexOf(F_find_round_max)])
{freq_round = F_find_round_min;}
else {freq_round = F_find_round_max;}
var ind_F_find = frequency_AUSPv.indexOf(freq_round); // индекс искомой частоты в общем спектре
res_delta_phase_F1v[frq_arr[i]] = delta_phase_F1v.value; // записываем данные в объект
if (i < frq_arr.length - 1) {
i = i + 1;
delta_phase_F1v.frequency = frq_arr[i];
} else {
gtl.results = res_delta_phase_F1v; // записываем объект в резалт
};
// Спектр виброскорости (для визуализации)
// Набор гармоник частоты вращения F1v (виброскорость)
var F1v_harms = AUSPv.add_harms_set(freq_round, 1, 0x000000ff, 1); // синий цвет
for (let i=0; i <= 0; i++)
{F1v_harms.harms[i].tolerance = (1+i) * freq_round * 0.1}; // коридор обнаружения гармоник
F1v_harms.name = "F1v (гарм. ряд част. вращ.)";
// 1-я гармоника F1v
var F1v = F1v_harms.harms[0].amplitude; // параметр amplitude при спектре в абсолютной величине амплитуды
// var F1v = F1v_harms.harms[0].level; // параметр level при спектре в относительной величине амплитуды
// Проверка наличия оборотной гармоники необходимости проведения балансировки
if (F1v_harms.harms[0].is_present == true) // обнаружения оборотной гармоники
{var F1v_test_ampl = "амплитуда частоты вращения определена";}
else {var F1v_test_ampl = "амплитуда частоты вращения НЕ определена или имеет низкий уровень";}
if (F1v >= RMSv_2_1000.value * 0.4) // вклад оборотной гармоники в СКЗv
{var F1v_test_balance = "необходимо провести балансировку";}
else {var F1v_test_balance = "проведение балансировки не требуется или нецелесообразно";}
// РАСЧЁТЫ (балансировочный калькулятор)
// определение угла наклона вектора A0 к осям X и Y
if (A0_phase <= 90) {
A0_phase_X = 90 - A0_phase}
if (A0_phase <= 180) {
A0_phase_X = A0_phase - 90}
if (A0_phase <= 270) {
A0_phase_X = 270 - A0_phase}
if (A0_phase <= 360) {
A0_phase_X = A0_phase - 270}
if (A0_phase <= 90) {
A0_phase_Y = A0_phase}
if (A0_phase <= 180) {
A0_phase_Y = 180 - A0_phase}
if (A0_phase <= 270) {
A0_phase_Y = A0_phase - 180}
if (A0_phase <= 360) {
A0_phase_Y = 360 - A0_phase}
// определение координат вектора A0
A0_1_X = 0;
if (A0_phase <= 180) {A0_2_X = Math.abs(Math.cos(A0_phase_X * 3.1415/180)) * A0
} else {A0_2_X = Math.abs(Math.cos(A0_phase_X * 3.1415/180)) * A0 * (-1)}
A0_1_Y = 0;
if (A0_phase <= 90 || A0_phase >= 270) {A0_2_Y = Math.abs(Math.cos(A0_phase_Y * 3.1415/180)) * A0
} else {A0_2_Y = Math.abs(Math.cos(A0_phase_Y * 3.1415/180)) * A0 * (-1)}
// определение угла наклона вектора m_test к осям X и Y
if (m_test_corner <= 90) {
m_test_corner_X = 90 - m_test_corner}
if (m_test_corner <= 180) {
m_test_corner_X = m_test_corner - 90}
if (m_test_corner <= 270) {
m_test_corner_X = 270 - m_test_corner}
if (m_test_corner <= 360) {
m_test_corner_X = m_test_corner - 270}
if (m_test_corner <= 90) {
m_test_corner_Y = m_test_corner}
if (m_test_corner <= 180) {
m_test_corner_Y = 180 - m_test_corner}
if (m_test_corner <= 270) {
m_test_corner_Y = m_test_corner - 180}
if (m_test_corner <= 360) {
m_test_corner_Y = 360 - m_test_corner}
// определение координат вектора m_test
m_test_1_X = 0;
if (m_test_corner <= 180) {m_test_2_X = Math.abs(Math.cos(m_test_corner_X * 3.1415/180)) * m_test * (-1)
} else {m_test_2_X = Math.abs(Math.cos(m_test_corner_X * 3.1415/180)) * m_test}
m_test_1_Y = 0;
if (m_test_corner <= 90 || m_test_corner >= 270) {m_test_2_Y = Math.abs(Math.cos(m_test_corner_Y * 3.1415/180)) * m_test
} else {m_test_2_Y = Math.abs(Math.cos(m_test_corner_Y * 3.1415/180)) * m_test * (-1)}
// определение угла наклона вектора A1 к осям X и Y
if (A1_phase <= 90) {
A1_phase_X = 90 - A1_phase}
if (A1_phase <= 180) {
A1_phase_X = A1_phase - 90}
if (A1_phase <= 270) {
A1_phase_X = 270 - A1_phase}
if (A1_phase <= 360) {
A1_phase_X = A1_phase - 270}
if (A1_phase <= 90) {
A1_phase_Y = A1_phase}
if (A1_phase <= 180) {
A1_phase_Y = 180 - A1_phase}
if (A1_phase <= 270) {
A1_phase_Y = A1_phase - 180}
if (A1_phase <= 360) {
A1_phase_Y = 360 - A1_phase}
// определение координат вектора A1
A1_1_X = 0;
if (A1_phase <= 180) {A1_2_X = Math.abs(Math.cos(A1_phase_X * 3.1415/180)) * A1
} else {A1_2_X = Math.abs(Math.cos(A1_phase_X * 3.1415/180)) * A1 * (-1)}
A1_1_Y = 0;
if (A1_phase <= 90 || A1_phase >= 270) {A1_2_Y = Math.abs(Math.cos(A1_phase_Y * 3.1415/180)) * A1
} else {A1_2_Y = Math.abs(Math.cos(A1_phase_Y * 3.1415/180)) * A1 * (-1)}
// определение модуля вектора dA
dA_1_X = A0_2_X;
dA_2_X = A1_2_X;
dA_1_Y = A0_2_Y;
dA_2_Y = A1_2_Y;
dA = Math.sqrt(Math.pow(dA_2_X - dA_1_X, 2) + Math.pow(dA_2_Y - dA_1_Y, 2))
// определение фазы вектора dA
if ((dA_2_Y < dA_1_Y) && (dA_2_X < dA_1_X)) {
dA_phase = 180 + (((Math.acos((Math.abs(dA_2_Y - dA_1_Y)) / dA)) * 180 ) / 3.1415)}
if ((dA_2_Y > dA_1_Y) && (dA_2_X > dA_1_X)) {
dA_phase = (((Math.acos((Math.abs(dA_2_Y - dA_1_Y)) / dA)) * 180 ) / 3.1415)}
if ((dA_2_Y > dA_1_Y) && (dA_2_X < dA_1_X)) {
dA_phase = 360 - (((Math.acos((Math.abs(dA_2_Y - dA_1_Y)) / dA)) * 180 ) / 3.1415)}
if ((dA_2_Y < dA_1_Y) && (dA_2_X > dA_1_X)) {
dA_phase = 180 - (((Math.acos((Math.abs(dA_2_Y - dA_1_Y)) / dA)) * 180 ) / 3.1415)}
if (dA_phase > 360) {dA_phase = dA_phase - 360}
// определение модуля вектора DCI
DCI = dA / m_test;
// опредение фаза вектора DCI
DCI_phase = dA_phase - m_test_corner;
// определение модуля вектора Mb
Mb = (m_test * A0) / dA;
// определение модуля вектора Mb по известному ДКВ (DCI) **
//Mb = A0 / DCI;
// определение угла вектора Mb
if ((m_test_corner + A0_phase - dA_phase + 180) < 360) {
Mb_corner = (m_test_corner + A0_phase - dA_phase + 180)
} else {Mb_corner = (m_test_corner + A0_phase - dA_phase + 180) - 360}
// определение угла вектора Mb по известному ДКВ (DCI)
//if ((A0_phase - DCI_phase + 180) < 360) {
// Mb_corner = (A0_phase - DCI_phase + 180)
// } else {Mb_corner = (A0_phase - DCI_phase + 180) - 360}
gtl.log.info("Индекс", i);
gtl.log.info("Частота", frq_arr[i]);
gtl.log.info("Разница фаз на частоте", delta_phase_F1v.value);
gtl.log.info("искомая частота, Гц", F_find);
gtl.log.info("искомая частота округлённая до ближ, Гц", freq_round);
// gtl.log.info("верхняя граница поиска частоты, Гц", F_find_round_max);
// gtl.log.info("нижняя граница поиска частоты, Гц", F_find_round_min);
gtl.log.info("индекс искомой частоты в общем спектре", ind_F_find);
gtl.log.info("уровень искомой частоты (data)", level_AUSPv[ind_F_find]);
// gtl.log.info("Mb",Mb);
// gtl.log.info("Mb_corner",Mb_corner);
// gtl.log.info("freq.value (по dc)",freq.value);
gtl.log.info("F1v.level (гарм.ряд)",F1v);
gtl.log.info("RMSv_2_1000",RMSv_2_1000.value);
// gtl.log.info("F1v_test_ampl",F1v_test_ampl);
// gtl.log.info("F1v_test_balance",F1v_test_balance);
// gtl.log.info("F1v_harms.harms[0].tolerance",F1v_harms.harms[0].tolerance);
// gtl.log.info("delta_phase_F1v",delta_phase_F1v.value);
gtl.log.info("gtl.diagnostic.interval",gtl.diagnostic.interval);
// gtl.log.info("delta_phase_F1v.acq_time",delta_phase_F1v.acq_time);
// gtl.log.info("AUSPv.acq_time",AUSPv.acq_time);
// Выдача результата (results)
let __result = {
Частотаращения_F1_округл: freq_round,
Канал_вибрацииатчика1: "канал [0]",
Амплитуда_гармоники_F1: level_AUSPv[ind_F_find],
амплитуда_F1v_поСпектру: F1v,
дельтааза: delta_phase_F1v.value,
phase_res: res_delta_phase_F1v,
};
gtl.results = __result;
gtl.diagnostic.stop();
}
}