balancer_calc/scripts/1 пл - шаг 5.js

498 lines
23 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");
var fnc = gtl.import("user-functions.js");
// Цвета (для справки)
// #ff0000 - красный
// #00ff00 - салатовый
// #0fae1a - зелёный
// #0000ff - синий
// #00ddff - голубой
// #ff3dcc - фиолетовый
// #ffff00 - жёлтый
// ***** БАЛАНСИРОВОЧНЫЙ КАЛЬКУЛЯТОР. ОДНА ПЛОСКОСТЬ с фазой *****
// ***************************************************************
// Получение входных сигналов
// Определение частоты вращения по параметру freq.dc
let freq = gtl.add_value_freq(gtl.analog_inputs[record.tachoOptions.tachoChannel]);
freq.time = 1; // длина (время) отрезка сигнала
freq.avg_cnt = 3; // количество усреднений
freq.dc = -0.05; // уровень, при переходе через который вычисляются периоды
// ФИЛЬТР 2...1000 Гц, полосовой фильтр для СКЗ виброскорости и спектра
let 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 = 501; // центральная частота полосового фильтра
filter_2_1000.width = 998; // ширина полосы фильтра
let filter_2_1000v = gtl.add_intg(filter_2_1000); // интегрирование
filter_2_1000v.taps = 1; // степень интегрирования (скорость из ускорения - 1-нарное)
// Фильтр для виброперемещения
let filter_2_300s = gtl.add_filter_iir(gtl.analog_inputs[signals[0].portNumber]);
filter_2_300s.kind = gtl.filter_iir.butterworth;
filter_2_300s.type = gtl.filter_iir.bandpass; // полосовой фильтр
filter_2_300s.order = 4;
filter_2_300s.frequency = 151; // центральная частота
filter_2_300s.width = 298; // ширина полосы
// Настройки для спектров и АФЧХ
let frequency; // граничная частота
let resolution = 0.5; // частотное разрешение
let average = 3; // количество усреднений
let overlap = 0; // наложение
let filter_vibr; // фильтр сигнала вибрации
// Переключатель источника сигнала - относительная / абсолютная вибрация
// 0 - относительная вибрация (датчик виброперемещения)
// 1 - абсолютная вибрация (датчик виброускорения)
let select_vibr_sign = gtl.options.customOptions.select_vibr_sign;
// Выбор фильтра и параметров спектров в зависимости от значения переключателя источника сигнала вибрации
if (select_vibr_sign == 1)
{
filter_vibr = filter_2_1000v;
frequency = 1000;
}
else if (select_vibr_sign == 0)
{
filter_vibr = filter_2_300s;
frequency = 300;
}
// Спектр для получения 1-й гармоники частоты вращения
var AUSP = gtl.add_ausp(filter_vibr); // объявление переменной спектра
AUSP.color = 0x00ff0000; // цвет спектра
AUSP.name = "AUSP"; // имя спектра
AUSP.frequency = frequency; // граничная частота спектра
AUSP.lines = AUSP.frequency * 1/resolution; // разрешение спектра (количество линий)
AUSP.average = average; // количество усреднений
AUSP.unit = gtl.spec.unit; // отображение амплитуды в мм/с
AUSP.smoothing_factor = 100; // усреднение средней линии
AUSP.smoothed_line_color = 0xff004dff; // цвет средней линии
AUSP.peak_level = 0.001; // порог обнаружения гармоник (необходим самый минимальный)
AUSP.tolerance = AUSP.resolution; // диапазон поиска гармоник +/-
// СКЗ
var RMS = gtl.add_value_rms(filter_vibr);
RMS.time = 1;
RMS.avg_cnt = 3;
// Спектр вибрации
var AUSP_pl = gtl.create_ausp(
{
"src" : filter_vibr,
"frequency" : frequency,
"resolution" : resolution,
"average" : average,
"overlap" : overlap,
"window" : gtl.spec.rectangular,
"view" : gtl.spec.unit
}
);
// ФЧХ
var pfc_pl = gtl.create_pfc(
{
"src0" : filter_vibr,
"src1" : gtl.analog_inputs[record.tachoOptions.tachoChannel],
"frequency" : frequency,
"resolution" : resolution,
"average" : average,
"overlap" : overlap,
"window" : gtl.spec.rectangular,
"view" : gtl.phase.deg,
// "range" : gtl.phase.positive,
"is_single" : false
}
);
// "range": gtl.phase.negative,
// "delay" : .1, // по умолчанию - 0
// "start" : false // по умолчанию - true
// Объявление графических плоскостей для построения графиков
let plot_pfc = gtl.plots.add("ФЧХ"); // фазо-частотная характеристика
let plot_ausp = gtl.plots.add("Спектр вибрации"); // объект для спектра
let plot_vibr = gtl.plots.add("Векторы вибрации"); // объект для векторов вибрации
let plot_disb = gtl.plots.add("Расположение дисбаланса"); // объект для дисбаланса
// gtl.log.info("размер массива AUSPv_pl", AUSPv_pl.data.length);
// gtl.log.info("размер массива pfc_pl", pfc_pl.data.length);
// Переменные основные
// параметр вибрации (модуль вектора) - виброскорость (мм/с)
// угол (фаза) вектора - градусы
// масса груза (модуль ветора) - граммы
// DCI - Dynamic Coefficient of Influence (динамический коэффициент влияния)
// * - значение получаем из измерительного блока при нажатии кнопки
// ** - значение вводится пользователем
// *** - значение получаем в результате расчёта программы балансировки
// значение переменной с нижним подчёркиванием (..._) берётся из "дополнительных опций"; если оно не задано, то рассчитывается в скрипте
let A0_ = gtl.options.customOptions.A0; // модуль вектора начальной вибрации */**
let A0 = A0_; // модуль вектора начальной вибрации */** (конечное значение)
let A0_phase_ = gtl.options.customOptions.A0_phase; // фаза вектора начальной вибрации */**
let A0_phase = A0_phase_; // фаза вектора начальной вибрации */** (конечное значение)
let dA2; // модуль вектора дельты вибрации после установки пробного груза ***
let dA2_phase; // фаза вектора дельты вибрации после установки пробного груза ***
let A2_ = gtl.options.customOptions.A2; // модуль вектора вибрации после установки балансировочного груза */**
let A2; // модуль вектора вибрации после установки балансировочного груза */** (конечное значение)
let A2_phase_ = gtl.options.customOptions.A2_phase; // фаза вектора вибрации после установки балансировочного груза */**
let A2_phase; // фаза вектора вибрации после установки балансировочного груза */** (конечное значение)
// Переменные вспомогательные необходимые для расчётов и визуализации
let A0_phase_X; // угол наклона вектора A0 к оси X
let A0_phase_Y; // угол наклона вектора A0 к оси Y
let A0_1_X; // начальная координата вектора A0 по оси X
let A0_2_X; // конечная координата вектора A0 по оси X
let A0_1_Y; // начальная координата вектора A0 по оси Y
let A0_2_Y; // конечная координата вектора A0 по оси Y
let dA2_1_X; // начальная координата вектора dA2 по оси X
let dA2_2_X; // конечная координата вектора dA2 по оси X
let dA2_1_Y; // начальная координата вектора dA2 по оси Y
let dA2_2_Y; // конечная координата вектора dA2 по оси Y
let A2_phase_X; // угол наклона вектора A2 к оси X
let A2_phase_Y; // угол наклона вектора A2 к оси Y
let A2_1_X; // начальная координата вектора A2 по оси X
let A2_2_X; // конечная координата вектора A2 по оси X
let A2_1_Y; // начальная координата вектора A2 по оси Y
let A2_2_Y; // конечная координата вектора A2 по оси Y
// ***** РАСЧЁТЫ *****
// gtl.diagnostic.interval = 15;
gtl.diagnostic.interval = Math.max(AUSP.acq_time, AUSP_pl.acq_time) + 0.1;
// gtl.diagnostic.interval = gtl.acq_time + 1;
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 = Math.max(AUSP.acq_time, AUSP_pl.acq_time, pfc_pl.acq_time) + 0.1;
state = 3;
break;
case 1: // Частота вращения фиксированная
// Определение минимально необходимой длительности сигнала для проведения диагностики
gtl.diagnostic.interval = Math.max(AUSP.acq_time, AUSP_pl.acq_time, pfc_pl.acq_time) + 0.1;
state = 3;
break;
case 2: // Частота вращения из поля INFO (виброметр)
// Определение минимально необходимой длительности сигнала для проведения диагностики
gtl.diagnostic.interval = Math.max(AUSP.acq_time, AUSP_pl.acq_time, pfc_pl.acq_time) + 0.1;
state = 3;
break;
case 3: // Выполняем анализ спектов
// Очистка партретов спектров
AUSP.clear_harms_sets();
let __AUSP_tools = gtl.create_spec_tools(
{
data: AUSP_pl.data,
df: AUSP_pl.resolution,
base: {
factor: 100,
visible: true,
color: 0x00ff00
},
peaks: {
color: 0xff0000,
visible: true,
level: 0.000001
},
harms: {
tolerance: 1
}
});
let __row_AUSP = __AUSP_tools.harms.add(freq.value, 1, 0x0000ff, 1); // добавление набора гармоник (частота, количество, цвет, вес)
__row_AUSP.name = "F1 (гарм. ряд част. вращ.)"; // название гармонического ряда
// __row1.modulate(5, 2, 0x00ff00, 1); // добавление амплитудной модуляции для набора гармоник (частота, количество, цвет, вес)
let __pfc_tools = gtl.create_spec_tools(
{
data: pfc_pl.data,
df: pfc_pl.resolution,
base: {
factor: 100,
visible: true,
color: 0x0000ff
},
peaks: {
color: 0xff0000,
visible: true,
level: 0.000001
},
harms: {
tolerance: 1
}
});
let __row1_phase = __pfc_tools.harms.add(freq.value, 1, 0x00ff00, 1); // добавление набора гармоник (частота, количество, цвет, вес)
__row1_phase.name = "F1_phase (гарм. ряд част. вращ.)"; // название гармонического ряда
// Построение графиков
plot_ausp.add(
{
color: 0x0000ff,
name: "Спектр вибрации",
x: AUSP_pl.resolution,
y: AUSP_pl.data,
spec_tools: __AUSP_tools.to_json()
});
plot_pfc.add(
{
color: 0xff0000,
name: "ФЧХ",
x: pfc_pl.resolution,
y: pfc_pl.data,
spec_tools: __pfc_tools.to_json()
});
let __result1 = __AUSP_tools.to_json();
let __result2 = __pfc_tools.to_json();
// Амплитуда гармонического ряда частоты вращения
var F1_1_a = __result1.harms.rows[0].harms[0].ampl;
// Частота гармонического ряда частоты вращения
var F1_1_f = __result1.harms.rows[0].harms[0].freq;
// Фаза (амплитуда) гармонического ряда частоты вращения
var F1_1_ph = __result2.harms.rows[0].harms[0].ampl;
// Проверка наличия оборотной гармоники и необходимости проведения баалнсировки
var test_balance = ""; // переменная для текста о необходимости проведения балансировки
if (F1_1_a >= RMS * 0.4) // вклад оборотной гармоники в СКЗ
{test_balance = "необходимо провести балансировку";}
else {test_balance = "проведение балансировки не требуется или нецелесообразно";}
// РАСЧЁТЫ (балансировочный калькулятор)
// ШАГ 5 - контрольный пуск:
// измерение вибрации A2 после установки балансировочного груза
// определение целесообразности проведения добалансировки
// из предыдущих шагов переносятся: вибрация A0
// построение графика вибрации A0, A2 и dA2
// Определение конечных значений переменных
// A2 вибрация после установки балансировочного груза
if (A2_ != 0) {A2 = A2_} // принимает значение из опций
else {A2 = F1_1_a} // принимает значение из спектра сигнала
if (A2_phase_ != 0) {A2_phase = A2_phase_} // принимает значение из опций
else {A2_phase = F1_1_ph} // принимает значение из спектра сигнала
// определение угла наклона вектора 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
var xA0_array = []; // массив координат точек вектора A0 по оси X
var yA0_array = []; // массив координат точек вектора A0 по оси Y
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)}
xA0_array[0] = A0_1_X;
xA0_array[1] = A0_2_X;
yA0_array[0] = A0_1_Y;
yA0_array[1] = A0_2_Y;
// определение угла наклона вектора A2 к осям X и Y
if (A2_phase <= 90) {
A2_phase_X = 90 - A2_phase}
if (A2_phase <= 180) {
A2_phase_X = A2_phase - 90}
if (A2_phase <= 270) {
A2_phase_X = 270 - A2_phase}
if (A2_phase <= 360) {
A2_phase_X = A2_phase - 270}
if (A2_phase <= 90) {
A2_phase_Y = A2_phase}
if (A2_phase <= 180) {
A2_phase_Y = 180 - A2_phase}
if (A2_phase <= 270) {
A2_phase_Y = A2_phase - 180}
if (A2_phase <= 360) {
A2_phase_Y = 360 - A2_phase}
// определение координат вектора A2
var xA2_array = []; // массив координат точек вектора A2 по оси X
var yA2_array = []; // массив координат точек вектора A2 по оси Y
A2_1_X = 0;
if (A2_phase <= 180) {A2_2_X = Math.abs(Math.cos(A2_phase_X * 3.1415/180)) * A2
} else {A2_2_X = Math.abs(Math.cos(A2_phase_X * 3.1415/180)) * A2 * (-1)}
A2_1_Y = 0;
if (A2_phase <= 90 || A2_phase >= 270) {A2_2_Y = Math.abs(Math.cos(A2_phase_Y * 3.1415/180)) * A2
} else {A2_2_Y = Math.abs(Math.cos(A2_phase_Y * 3.1415/180)) * A2 * (-1)}
xA2_array[0] = A2_1_X;
xA2_array[1] = A2_2_X;
yA2_array[0] = A2_1_Y;
yA2_array[1] = A2_2_Y;
// определение модуля вектора dA2
var xdA2_array = []; // массив координат точек вектора dA2 по оси X
var ydA2_array = []; // массив координат точек вектора dA2 по оси Y
dA2_1_X = A0_2_X;
dA2_2_X = A2_2_X;
dA2_1_Y = A0_2_Y;
dA2_2_Y = A2_2_Y;
dA2 = Math.sqrt(Math.pow(dA2_2_X - dA2_1_X, 2) + Math.pow(dA2_2_Y - dA2_1_Y, 2))
xdA2_array[0] = dA2_1_X;
xdA2_array[1] = dA2_2_X;
ydA2_array[0] = dA2_1_Y;
ydA2_array[1] = dA2_2_Y;
// определение фазы вектора dA2
if ((dA2_2_Y < dA2_1_Y) && (dA2_2_X < dA2_1_X)) {
dA2_phase = 180 + (((Math.acos((Math.abs(dA2_2_Y - dA2_1_Y)) / dA2)) * 180 ) / 3.1415)}
if ((dA2_2_Y > dA2_1_Y) && (dA2_2_X > dA2_1_X)) {
dA2_phase = (((Math.acos((Math.abs(dA2_2_Y - dA2_1_Y)) / dA2)) * 180 ) / 3.1415)}
if ((dA2_2_Y > dA2_1_Y) && (dA2_2_X < dA2_1_X)) {
dA2_phase = 360 - (((Math.acos((Math.abs(dA2_2_Y - dA2_1_Y)) / dA2)) * 180 ) / 3.1415)}
if ((dA2_2_Y < dA2_1_Y) && (dA2_2_X > dA2_1_X)) {
dA2_phase = 180 - (((Math.acos((Math.abs(dA2_2_Y - dA2_1_Y)) / dA2)) * 180 ) / 3.1415)}
if (dA2_phase > 360) {dA2_phase = dA2_phase - 360}
// определение координат точек окружности графика для отображения векторов вибрации
var xV_array = []; // массив координат точек окружности V по оси X
var yV_array = []; // массив координат точек окружности V по оси Y
var x0V = 0; // центр в начале координат
var y0V = 0; // центр в начале координат
for (let i=0; i<=359; i++ ) {
xV_array.push(x0V + (Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.1) * (Math.sin((i) * Math.PI / 180)));
yV_array.push(y0V + (Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.1) * (Math.cos((i) * Math.PI / 180)));}
// Графики вибрации
plot_vibr.add(
{
color: 0x00ff00,
name: "Вибрация_A0",
x: xA0_array,
y: yA0_array,
});
plot_vibr.add(
{
color: 0x0000ff,
name: "Вибрация_A2",
x: xA2_array,
y: yA2_array,
});
plot_vibr.add(
{
color: 0xff0000,
name: "Вибрация_dA2",
x: xdA2_array,
y: ydA2_array,
});
plot_vibr.add(
{
color: 0x00ffffff,
name: "График векторов вибрации",
x: xV_array,
y: yV_array,
});
plot_vibr.add(
{
color: 0x00ffffff,
name: "границы",
x: [-(Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), -(Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), (Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), (Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2)],
y: [(Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), -(Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), -(Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2), (Math.max(A0,A2,dA2)+Math.max(A0,A2,dA2)*0.2)]
});
gtl.log.info("RMS",RMS.value);
gtl.log.info("A0",A0);
gtl.log.info("A0_phase",A0_phase);
gtl.log.info("A2",A2);
gtl.log.info("A2_phase",A2_phase);
gtl.log.info("F1_1_ph (фаза)",F1_1_ph);
gtl.log.info("F1_1_a (ампл)",F1_1_a);
gtl.log.info("F1_1_f (част)",F1_1_f);
gtl.log.info("Частота вращения, Гц", freq.value);
gtl.log.info("Необходимость проведения балансировки",test_balance);
gtl.log.info("Нестабильность частоты вращения, %", instability*100);
// Выдача результата (results)
let __result = {
_001астотаращения_F1: freq.value,
_002_Ампл_гарм_1F1: F1_1_a,
_003азаастращ_F1: F1_1_ph,
_004_Ампл_вибр_пуска_A0: A0,
_005аза_вибр_пуска_A0: A0_phase,
_006_Ампл_вибр_пуска_A2: A2,
_007аза_вибр_пуска_A2: A2_phase,
_008_СКЗ_вибрации: RMS.value,
_009_Тестирование: test_balance,
_010_Нестабастращ: instability*100,
};
gtl.results = {"result": __result};
gtl.diagnostic.stop();
break;
default:
break;
}
}