balancer_calc/scripts/Одна_плоскость_с_фазой(old).js

437 lines
23 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";
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[0]);
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;
// Настройки для датчика оборотов
var freq_default = 5; // предполагаемая частота вращения
var filter_freq = gtl.add_filter_iir(gtl.analog_inputs[record.tachoOptions.tachoChannel]); // объявление переменной фильтра
filter_freq.kind = gtl.filter_iir.butterworth; // тип окна
filter_freq.type = gtl.filter_iir.bandpass; // тип фильтра (полосовой)
filter_freq.order = 6; // порядок фильтра
filter_freq.width = freq_default * 0.2; // полоса пропускания 20%
filter_freq.frequency = freq_default; // центральная частота фильтра
// Определение частоты вращения по фильтру предполагаемой частоты
var FREQ = gtl.add_value_freq(filter_freq);
FREQ.time = 1; // длина отрезка сигнала
FREQ.avg_cnt = 3; // усреднение частоты вращения
// Определение частоты вращения по параметру freq.dc
var freq = gtl.add_value_freq(gtl.analog_inputs[record.tachoOptions.tachoChannel]);
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(filter_2_1000v, gtl.analog_inputs[record.tachoOptions.tachoChannel]);
// 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 F_find_round; // перевоначальное значение
var freq_begin = 5.5; // предположительное значение частоты вращения
var frq_arr = [freq_begin, F_find_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]; // частота, для которой вычисляется разница фаз, Гц
// delta_phase_F1v.frequency = 5.5; // частота, на которой вычисляем дельта-фазу
// delta_phase_F1v.frequency = FREQ.value; // частота, на которой вычисляем дельта-фазу
// delta_phase_F1v.frequency = freq.value; // частота, на которой вычисляем дельта-фазу
// Формирование объекта apfc для получения амплитуды и фазы
var apfc = gtl.add_apfc(
{
// "src1" : filter_2_1000v,
// "src1" : filter_2_1000,
"src1" : gtl.analog_inputs[0],
"src2" : gtl.analog_inputs[record.tachoOptions.tachoChannel],
"name" : "coh",
"color" : 0xff0000,
"visible" : true,
"freq" : AUSPv.frequency,
"window" : gtl.spec.rectangular,
"resolution" : AUSPv.frequency / AUSPv.lines,
"average" : 1,
"overlap" : 0,
"afc" : gtl.apfc.magnitude,
"pfc" : gtl.apfc.deg
}
);
// Объявление переменных массивов
var level_AUSPv = []; // массив амплитуд гармоник канала 0
var delta_phase_AUSPv = []; // массив разностей фаз гармоник канала 0 относительно тахо
var index_AUSPv = []; // массив индексов гармоник канала 0
var frequency_AUSPv = []; // массив частот (перевод индексов) гармоник канала 0
var AUSPv_data = []; // массив спектра
var AUSPv_base = []; // массив средней линии спектра
// Переменные основные
// параметр вибрации (модуль вектора) - виброскорость (мм/с)
// угол (фаза) вектора - градусы
// масса груза (модуль ветора) - граммы
// * - значение получаем из измерительного блока при нажатии кнопки
// ** - значение вводится пользователем
// *** - значение получаем в результате расчёта программы балансировки
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, apfc.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();
// Спектр виброскорости
// Набор гармоник частоты вращения F1v (виброскорость)
var F1v_harms = AUSPv.add_harms_set(freq.value, 1, 0x00ff0000, 1); // красный цвет
for (let i=0; i <= 0; i++)
{F1v_harms.harms[i].tolerance = (1+i) * freq.value * 0.1}; // коридор обнаружения гармоник
F1v_harms.name = "F1v (гарм. ряд част. вращ.)";
// 1-я гармоника F1v
// Проверка наличия оборотной гармоники необходимости проведения балансировки
if (F1v_harms.harms[0].is_present == true) // обнаружения оборотной гармоники
{var F1v = F1v_harms.harms[0].level;
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 = "проведение балансировки не требуется или нецелесообразно";}
// ТЕСТИРОВАНИЕ (получение фазы и амплитуды оборотной гармоники из массивов)
// Запись в массив значений уровня спектра
for (let i = 0; i < AUSPv.data.length; i++) {
// Массив уровней (старый метод)
// level_AUSPv.push(AUSPv.data[i] - AUSPv.base[i]);
// Разница фаз гармоник
delta_phase_AUSPv.push(apfc.phase[i]);
// Амплитуда гармоник
level_AUSPv.push(apfc.data[i]);
// Индексы гармоник
index_AUSPv.push(i);
// Частоты гармоник
frequency_AUSPv.push(i * (AUSPv.frequency / AUSPv.lines));
// Запись массивов AUSPv.data и AUSPv.base для определения уровня (level)
AUSPv_data.push(AUSPv.data[i]);
AUSPv_base.push(AUSPv.base[i]);
}
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)])
{F_find_round = F_find_round_min;}
else {F_find_round = F_find_round_max;}
var ind_F_find = frequency_AUSPv.indexOf(F_find_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; // записываем объект в резалт
};
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("искомая частота округлённая до ближ, Гц", F_find_round);
gtl.log.info("верхняя граница поиска частоты, Гц", F_find_round_max);
gtl.log.info("нижняя граница поиска частоты, Гц", F_find_round_min);
gtl.log.info("индекс искомой частоты", ind_F_find);
gtl.log.info("уровень искомой частоты", level_AUSPv[ind_F_find]);
gtl.log.info("фаза искомой частоты", delta_phase_AUSPv[ind_F_find]);
gtl.log.info("проверка уровня AUSPv.data", AUSPv_data[ind_F_find] - AUSPv_base[ind_F_find]);
// gtl.log.info("размер массива frequency_AUSPv", frequency_AUSPv.length);
// gtl.log.info("AUSPv.lines", AUSPv.lines);
// gtl.log.info("AUSPv.frequency", AUSPv.frequency);
// РАСЧЁТЫ
// определение угла наклона вектора 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("Mb",Mb);
// gtl.log.info("Mb_corner",Mb_corner);
gtl.log.info("FREQ.value",FREQ.value);
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: F_find_round,
Канал_вибрацииатчика1: "канал [0]",
Амплитуда_гармоники_F1_apfc: level_AUSPv[ind_F_find],
Фаза_гармоники_F1_apfc: delta_phase_AUSPv[ind_F_find],
// проверка_ампл_F1v_поСпектру: AUSPv_data[ind_F_find] - AUSPv_base[ind_F_find],
проверка_ампл_F1v_поСпектру: AUSPv_data[ind_F_find],
амплитуда_F1v_поСпектру: F1v,
дельтааза: delta_phase_F1v.value,
res_delta_phase_F1v: res_delta_phase_F1v,
};
gtl.results = __result;
gtl.diagnostic.stop();
}
}