This commit is contained in:
s.savelievrem 2026-07-22 15:46:20 +03:00
parent bcc5f6b461
commit 0aa99eb2b6
11 changed files with 1266 additions and 670 deletions

View File

@ -1,7 +1,7 @@
{
"autoStartRecorder": false,
"expendTreeOnStart": true,
"lastTag": "частотный отклик freq-1000 resol-10 (искл 4,7,8)",
"lastTag": "4096Гц_разр1[4]",
"projectTitle": "Частотный отклик",
"projectUUID": "{91ae6936-d7c1-41f2-ac73-1fb5692a4011}",
"reportOptions": {

View File

@ -43,277 +43,7 @@
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n\"ranges\": [\n{\n\"max\": 13.766053515625,\n\"min\": 13.355623828125\n},\n{\n\"max\": 17.592342578125,\n\"min\": 17.181912892625\n},\n{\n\"max\": 21.179315234374997,\n\"min\": 20.768885546874998\n},\n{\n\"max\": 24.162000781249997,\n\"min\": 23.751571093749998\n},\n{\n\"max\": 27.704744921874997,\n\"min\": 27.294315234375\n},\n{\n\"max\": 32.293602343749995,\n\"min\": 31.883172656249997\n},\n{\n\"max\": 37.146190234375,\n\"min\": 36.735760546875\n},\n{\n\"max\": 40.513612109374996,\n\"min\": 40.103182421875\n},\n{\n\"max\": 44.100897265624994,\n\"min\": 43.690467578124995\n}\n],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 1000,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 10\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ верх горизонталь",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": астотный_отклик v12.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{1ee51458-2b67-4738-8832-24a883abe26a}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ верх вертикаль",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response 2.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{d5f70fb9-1e58-4e23-b3e8-5270c02d0904}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ низ горизонталь",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response 2.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{da645bbe-04b5-4d5e-86de-3b5ba633addc}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ низ вертикаль",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{5aba8185-bd6d-4469-a877-366899f020e9}"
}
],
"masterScriptName": "",
"name": "Частотный отклик по размеченным сигналам",
"nodeType": 1,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{4309f187-2cb5-463c-a4cd-520050c00401}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 40000,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 100\n}",
"customOptionsString": "{\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 4096,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 1\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
@ -583,7 +313,7 @@
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 13.4652234375,\n \"min\": 13.3556140625\n },\n {\n \"max\": 17.291522265625,\n \"min\": 17.181912890625\n },\n {\n \"max\": 20.87848515625,\n \"min\": 20.76887578125\n },\n {\n \"max\": 23.86118046875,\n \"min\": 23.751571093749998\n },\n {\n \"max\": 27.403924609375,\n \"min\": 27.294315234375\n },\n {\n \"max\": 31.992782031249998,\n \"min\": 31.883172656249997\n },\n {\n \"max\": 36.845369921875,\n \"min\": 36.735760546875\n },\n {\n \"max\": 40.212791796874995,\n \"min\": 40.103182421875\n },\n {\n \"max\": 43.80007695312499,\n \"min\": 43.690467578124995\n }\n ],\n\n\"remove_resp_arr\": [4,7,8],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 1000,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 10\n}",
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 15.3656140625,\n \"min\": 13.3556140625\n },\n {\n \"max\": 19.191912890624998,\n \"min\": 17.181912890625\n },\n {\n \"max\": 22.77887578125,\n \"min\": 20.76887578125\n },\n {\n \"max\": 25.76157109375,\n \"min\": 23.751571093749998\n },\n {\n \"max\": 29.30431534374997,\n \"min\": 27.294315234375\n },\n {\n \"max\": 32.893172656249995,\n \"min\": 31.883172656249997\n },\n {\n \"max\": 38.745760546875,\n \"min\": 36.735760546875\n },\n {\n \"max\": 42.113182421874995,\n \"min\": 40.103182421875\n },\n {\n \"max\": 45.70046757812499,\n \"min\": 43.690467578124995\n }\n ],\n\n\"window_spec_force_comment\": \"окно спектра силы\",\n\"window_spec_force\": \"gtl.spec.rectangular\",\n\n\"window_spec_vibr_comment\": \"окно спектра вибрации\",\n\"window_spec_vibr\": \"gtl.spec.rectangular\",\n\n\"remove_resp_arr_comment\": \"удары, которые нужно исключить из усреднения\",\n\"remove_resp_arr\": [4,6],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 4096,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 0.5\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
@ -1015,7 +745,7 @@
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n\"ranges\": [\n{\n\"max\": 13.766053515625,\n\"min\": 13.355623828125\n},\n{\n\"max\": 17.592342578125,\n\"min\": 17.181912892625\n},\n{\n\"max\": 21.179315234374997,\n\"min\": 20.768885546874998\n},\n{\n\"max\": 24.162000781249997,\n\"min\": 23.751571093749998\n},\n{\n\"max\": 27.704744921874997,\n\"min\": 27.294315234375\n},\n{\n\"max\": 32.293602343749995,\n\"min\": 31.883172656249997\n},\n{\n\"max\": 37.146190234375,\n\"min\": 36.735760546875\n},\n{\n\"max\": 40.513612109374996,\n\"min\": 40.103182421875\n},\n{\n\"max\": 44.100897265624994,\n\"min\": 43.690467578124995\n}\n],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 10000,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 10\n}",
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 14.3656140625,\n \"min\": 13.3556140625\n },\n {\n \"max\": 18.191912890625,\n \"min\": 17.181912890625\n },\n {\n \"max\": 21.77887578125,\n \"min\": 20.76887578125\n },\n {\n \"max\": 24.76157109375,\n \"min\": 23.751571093749998\n },\n {\n \"max\": 28.304315234375,\n \"min\": 27.294315234375\n },\n {\n \"max\": 32.893172656249995,\n \"min\": 31.883172656249997\n },\n {\n \"max\": 37.745760546875,\n \"min\": 36.735760546875\n },\n {\n \"max\": 41.113182421874995,\n \"min\": 40.103182421875\n },\n {\n \"max\": 44.70046757812499,\n \"min\": 43.690467578124995\n }\n ],\n\n\"window_spec_force_comment\": \"окно спектра силы\",\n\"window_spec_force\": \"gtl.spec.rectangular\",\n\n\"window_spec_vibr_comment\": \"окно спектра вибрации\",\n\"window_spec_vibr\": \"gtl.spec.rectangular\",\n\n\"remove_resp_arr_comment\": \"удары, которые нужно исключить из усреднения\",\n\"remove_resp_arr\": [3,4],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 4096,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 1\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
@ -1074,7 +804,7 @@
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response 2.js",
"scriptName": "freq_response_multichannel_new.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
@ -1083,7 +813,7 @@
}
],
"masterScriptName": "",
"name": "Новый объект",
"name": "Частотный отклик \"верх горизонталь\" все каналы",
"nodeType": 1,
"objectType": 0,
"pgN": 0,
@ -1106,6 +836,330 @@
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{a5e1df73-9f23-451b-83f1-719a5ec4bb7e}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 3.9452332031250004,\n \"min\": 2.935233203125\n },\n {\n \"max\": 12.82114140625,\n \"min\": 11.81114140625\n },\n {\n \"max\": 15.887362109375,\n \"min\": 14.877362109375\n },\n {\n \"max\": 18.64137578125,\n \"min\": 17.63137578125\n },\n {\n \"max\": 21.4958875,\n \"min\": 20.485887499999997\n },\n {\n \"max\": 24.302557421875,\n \"min\": 23.292557421875\n },\n {\n \"max\": 27.007244921875,\n \"min\": 25.997244921874998\n },\n {\n \"max\": 39.888377734375,\n \"min\": 28.878377734374997\n },\n {\n \"max\": 33.000780078125,\n \"min\": 31.990780078125\n },\n {\n \"max\": 36.1985828125,\n \"min\": 35.1885828125\n }\n ],\n\n\"window_spec_force_comment\": \"окно спектра силы\",\n\"window_spec_force\": \"gtl.spec.rectangular\",\n\n\"window_spec_vibr_comment\": \"окно спектра вибрации\",\n\"window_spec_vibr\": \"gtl.spec.rectangular\",\n\n\"remove_resp_arr_comment\": \"удары, которые нужно исключить из усреднения\",\n\"remove_resp_arr\": [1,3,4,9],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 4096,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 1\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ верх вертикаль",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response_multichannel_new.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{d5f70fb9-1e58-4e23-b3e8-5270c02d0904}"
}
],
"masterScriptName": "",
"name": "Частотный отклик \"верх вертикаль\" все каналы",
"nodeType": 1,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{e5d691d4-86bb-443f-888c-a1e6d84baab3}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 3.610701953125,\n \"min\": 2.600701953125\n },\n {\n \"max\": 5.802049609375,\n \"min\": 4.792049609375\n },\n {\n \"max\": 8.326619921875,\n \"min\": 7.3166199218750005\n },\n {\n \"max\": 10.77871953125,\n \"min\": 9.76871953125\n },\n {\n \"max\": 13.341903125,\n \"min\": 12.331903125\n },\n {\n \"max\": 16.122684375000002,\n \"min\": 15.112684375\n },\n {\n \"max\": 18.762537890625,\n \"min\": 17.752537890625\n },\n {\n \"max\": 21.7115515625,\n \"min\": 20.701551562499997\n },\n {\n \"max\": 24.54731328125,\n \"min\": 23.537313281249997\n }\n ],\n\n\"window_spec_force_comment\": \"окно спектра силы\",\n\"window_spec_force\": \"gtl.spec.rectangular\",\n\n\"window_spec_vibr_comment\": \"окно спектра вибрации\",\n\"window_spec_vibr\": \"gtl.spec.rectangular\",\n\n\"remove_resp_arr_comment\": \"удары, которые нужно исключить из усреднения\",\n\"remove_resp_arr\": [0,2,3,4,5,6,7,8],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 1024,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 1\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ низ горизонталь",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response_multichannel_new.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{da645bbe-04b5-4d5e-86de-3b5ba633addc}"
}
],
"masterScriptName": "",
"name": "Частотный отклик \"низ горизонталь\" все каналы",
"nodeType": 1,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{66c77abc-0e7f-4323-8948-b64e1699cfad}"
},
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{\n \"ranges\": [\n {\n \"max\": 3.365506640625,\n \"min\": 2.3555066406250003\n },\n {\n \"max\": 5.5229744921875,\n \"min\": 4.5197449218750005\n },\n {\n \"max\": 7.533407031125,\n \"min\": 6.5234090312500005\n },\n {\n \"max\": 9.59793828125,\n \"min\": 8.58793828125\n },\n {\n \"max\": 11.86055546875,\n \"min\": 10.85055546875\n },\n {\n \"max\": 14.112264453125,\n \"min\": 13.102264453125\n },\n {\n \"max\": 16.379608203125002,\n \"min\": 15.369608203125\n },\n {\n \"max\": 18.68203984375,\n \"min\": 17.67203984375\n },\n {\n \"max\": 20.864783984375,\n \"min\": 19.8547839984374997\n }\n ],\n\n\"window_spec_force_comment\": \"окно спектра силы\",\n\"window_spec_force\": \"gtl.spec.rectangular\",\n\n\"window_spec_vibr_comment\": \"окно спектра вибрации\",\n\"window_spec_vibr\": \"gtl.spec.rectangular\",\n\n\"remove_resp_arr_comment\": \"удары, которые нужно исключить из усреднения\",\n\"remove_resp_arr\": [4],\n\n\"frequency_comment\": \"граничная частота спектра\",\n\"frequency\": 1024,\n\n\"view_comment\": \"отображение амплитуды спектра в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view\": 0,\n\n\"view_freq_resp_comment\": \"отображение амплитуды частотного отклика в дБ или линейных единицах: 1 - db, 0 - unit\",\n\"view_freq_resp\": 0,\n\n\"average_comment\": \"усреднение спектра\",\n\"average\": 1,\n\n\"overlap_comment\": \"наложение сигнала для спектра\",\n\"overlap\": 0,\n\n\"variant_freq_resp_comment\": \"вариант вычисления частотного отклика: 0 - через кросс, 1 - через автоспектр\",\n\"variant_freq_resp\": 0,\n\n\"thresh_level_comment\": \"уровень удара для засчитывания импульса\",\n\"thresh_level\": 500,\n\n\"time_impulse_comment\": \"длина импульса, если не задано вручную, то вычисляется в скрипте\",\n\"time_impulse\": 0,\n\n\"resolution_comment\": \"разрешение спектра\",\n\"resolution\": 1\n}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
{
"U_freq": 50,
"async_N_rotor": 0,
"bdD1": 0,
"bdD2": 0,
"bdL": 0,
"bsAngle": 0,
"bsInnerD": 0,
"bsModelName": "",
"bsOuterD": 0,
"bsRollerCount": 0,
"bsRollerD": 0,
"bsVendor": "",
"cbdZ1": 0,
"cbdZ2": 0,
"cbdZ3": 0,
"customOptionsString": "{}",
"dpt_K": 0,
"dpt_M": 0,
"dpt_N": 0,
"dpt_freq": 50,
"elType": 0,
"groupType": 0,
"gtZ1": 0,
"gtZ2": 0,
"isQMLViewActive": false,
"isRouteStarter": false,
"items": [
],
"masterScriptName": "",
"name": "СТ низ вертикаль",
"nodeType": 2,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "default_point.qml",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "freq_response_multichannel_new.js",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{5aba8185-bd6d-4469-a877-366899f020e9}"
}
],
"masterScriptName": "",
"name": "Частотный отклик \"низ вертикаль\" все каналы",
"nodeType": 1,
"objectType": 0,
"pgN": 0,
"pgZ1": 0,
"pgZ2": 0,
"pgZ3": 0,
"pmBlades": 0,
"pointComment": "",
"qmlScriptName": "",
"rbAngle": 0,
"rbInnerD": 0,
"rbModelName": "",
"rbOuterD": 0,
"rbRollerCount": 0,
"rbRollerD": 0,
"rbVendor": "",
"scriptName": "",
"sync_M_rotor": 0,
"sync_M_stator": 0,
"tachoRatio": 1,
"trBlades": 0,
"uuid": "{0a32cd83-1f67-4edd-8af6-47cd5c5b12a7}"
}
],
"masterScriptName": "master_script.js",

View File

@ -1,213 +0,0 @@
export function getResponse(args) {
let force = args.spec_force; //спектр силы
let vibro = args.spec_vibro; //спектр вибрации
let type = args.type; //способ вычисления отклика
let view = args.view; //способ отображения спектра в линейных единицах или дБ
/* Алгоритм
1. Получить спектры ускорения и силы в комплексном виде (вибропреобразователь и молоток).
2. Преобразовать спектр силы (молотка) в комплексно-сопряжённый вид.
3. Получить кросс-спектр (перекрёстный) между ускорением и силой.
4. Вычислить деление кросс-спектра на спектр силы.
*/
/* Кросс-спектры
Сигнал силы в комплексно-сопряжённом виде
сигнал вибрации умножается на сигнал силы, а НЕ наоборот
умножение комплексных чисел по формуле:
(a1+b1i)*(a2+b2i)=(a1*a2-b1*b2)*(a1*b2+b1*a2)i
(a1*a2-b1*b2) - действительная часть
(a1*b2+b1*a2)i - мнимая часть
*/
let n = force.data.length; // длина массива спектра
let cross_real = new Float64Array(n); // типизированный массив для действительной части
let cross_imag = new Float64Array(n); // типизированный массив для мнимой части
for (let i = 0; i < n; i++) {
const vReal = vibro.real[i]; // действительная часть спектра вибрации
const vImag = vibro.imag[i]; // мнимая часть спектра вибрации
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = -force.imag[i]; // мнимая часть спектра силы сразу берём с обратным знаком
cross_real[i] = vReal * fReal - vImag * fImag;
cross_imag[i] = vReal * fImag + vImag * fReal;
}
// let cross_real2 = getCrossSpectrum(vibro.real, vibro.imag, force.real, force.imag).reXY;
// gtl.log.info('Амплитуда кросс', cross_real)
// gtl.log.info('Амплитуда кросс 2', cross_real2)
/* Вычисление частотного отклика
деление комплексных чисел по формуле:
(a+bi)/(c+di)=(a*c-b*d)*(a*d+b*c)i
(a*c-b*d) - действительная часть
(a*d+b*c)i - мнимая часть
*/
let resp_real = new Float64Array(n); // типизированный массив для действительной части
let resp_imag = new Float64Array(n); // типизированный массив для мнимой части
if (type == 0) {
// Вариант 1: Частотный отклик как деление кросс-спектра вибрации и силы на автоспектр силы
// ОШИБКА в моей формуле вычисления частотного отклика
// ИПРАВИЛ на:
// деление комплексных чисел по формуле:
// (a+bi)/(c+di)=(a*c + b*d)/(c^2 + d^2) + (c*b - a*d)/(c^2 + d^2)i
// (a*c + b*d)/(c^2 + d^2) - действительная часть
// (c*b - a*d)/(c^2 + d^2)i - мнимая часть
for (let i = 0; i < n; i++) {
const cReal = cross_real[i]; // действительная часть кросс спектра
const cImag = cross_imag[i]; // мнимая часть кросс спектра
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = force.imag[i]; // мнимая часть спектра силы
const denominator = fReal * fReal + fImag * fImag;
resp_real[i] = (cReal * fReal + cImag * fImag) / denominator;
resp_imag[i] = (fReal * cImag - cReal * fImag) / denominator;
}
} else {
// Вариант 2: Частотный отклик как деление автоспектра вибрации на автоспектр силы
// Канал[j] / Канал[0]
for (let i = 0; i < n; i++) {
const vReal = vibro.real[i]; // действительная часть спектра вибрации
const vImag = vibro.imag[i]; // мнимая часть спектра вибрации
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = force.imag[i]; // мнимая часть спектра силы
const denominator = fReal * fReal + fImag * fImag;
resp_real[i] = (vReal * fReal + vImag * fImag) / denominator;
resp_imag[i] = (fReal * vImag - vReal * fImag) / denominator;
}
}
// запись массива амплитуды и фазы
let resp_ampl = new Float64Array(n); // типизированный массив для амплитуды
let resp_phase = new Float64Array(n); // типизированный массив для фазы
const RAD_TO_DEG = 180 / Math.PI; //перевод радиан в градусы
for (let i = 0; i < n; i++) {
const rReal = resp_real[i]; // действительная часть спектра отклика
const rImag = resp_imag[i]; // мнимая часто спектра отклика
resp_ampl[i] = Math.sqrt(rReal * rReal + rImag * rImag);
if (view > 0) { resp_ampl = resp_ampl.map((item) => (item = 20 * Math.log10(item / 1e-6))) }; //переводим в дБ
resp_phase[i] = Math.atan2(rImag, rReal) * RAD_TO_DEG;
}
// Приводим фазу к диапазону [0°, 360°]
for (let i = 0; i < n; i++) {
resp_phase[i] = resp_phase[i] % 360;
if (resp_phase[i] < 0) { resp_phase[i] += 360 }
}
let resp2 = getFrequencyResponse(vibro.real, vibro.imag, force.real, force.imag);
let resp_ampl2 = resp2.magnitude;
let resp_phase2 = resp2.phase;
// gtl.log.info('Амплитуда отклика', resp_ampl[0]);
// gtl.log.info('Амплитуда отклика 2', resp_ampl2[0]);
// gtl.log.info('Фаза отклика', resp_phase[0]);
// gtl.log.info('Фаза отклика 2', resp_phase2[0]);
return {
data: resp_ampl2,
phase: resp_phase2,
resolution: force.resolution
}
}; //рассчет перекрестного спектра
export function getAvgArray(arrays) {
const length = arrays[0].length; //длина вложенного массива
const result = new Array(length); //новый массив фиксированной длины, чтобы не пушить
const numArrays = arrays.length; //количество вложенных массивов
for (let i = 0; i < length; i++) {
let sum = 0;
for (let j = 0; j < numArrays; j++) { sum += arrays[j][i] }
result[i] = sum / numArrays;
}
return result;
}; //вычисление среднего массива
function getCrossSpectrum(reX, imX, reY, imY) {
const n = reX.length;
const reXY = new Array(n); // действительная часть
const imXY = new Array(n); // мнимая часть
const power = new Array(n); // мощность кросс-спектра
let phase = new Array(n); // фаза (радианы)
for (let i = 0; i < n; i++) {
// Комплексное сопряжение спектра imY* (мнимая часть спектра силы сразу берём с обратным знаком)
const a = reX[i], b = imX[i]; // X(f) = a + ib
const c = reY[i], d = -imY[i]; // Y(f) = c + id
// Почастотное умножение
reXY[i] = a * c - b * d; // действительная часть
imXY[i] = b * c + a * d; // мнимания часть
// Мощность кросс-спектра
power[i] = reXY[i] * reXY[i] + imXY[i] * imXY[i];
// Фаза = arctan(Im/Re)
phase[i] = Math.atan2(imXY[i], reXY[i]);
}
return { reXY, imXY, power, phase };
}
function getFrequencyResponse(reX, imX, reY, imY) {
const n = reX.length;
const magnitude = new Array(n); // амплитуда (линейная)
const magnitudeDB = new Array(n); // амплитуда (дБ)
let phase = new Array(n); // фаза (радианы)
const RAD_TO_DEG = 180 / Math.PI; //перевод радиан в градусы
for (let i = 0; i < n; i++) {
const a = reX[i], b = imX[i]; // X(f) = a + ib
const c = reY[i], d = imY[i]; // Y(f) = c + id
// Знаменатель
const denominator = c * c + d * d; // знаменатель исходный вариант
// const denominator = a * a + b * b; // знаменатель вариант 2
// Избегаем деления на ноль
if (Math.abs(denominator) < 1e-10) {
magnitude[i] = 0;
magnitudeDB[i] = -Infinity;
phase[i] = 0;
continue;
}
// Почастотное умножение
const reH = (a * c + b * d) / denominator; // действительная часть
const imH = (c * b - a * d) / denominator; // мнимая часть исходный вариант
// const imH = (a * d - b * c) / denominator; // мнимая часть вариант 2 (поменял местами вычитаемые)
// Амплитуда
magnitude[i] = Math.sqrt(reH * reH + imH * imH);
// Амплитуда в дБ
magnitudeDB[i] = 20 * Math.log10(magnitude[i] / 1e-6);
// Приводим фазу сразу к диапазону [0°, 360°]
phase[i] = Math.atan2(imH, reH) * RAD_TO_DEG % 360;
if (phase[i] < 0) { phase[i] += 360 };
}
return { magnitude, magnitudeDB, phase };
}

View File

@ -1,110 +0,0 @@
export function getResponse(args) {
let force = args.spec_force; //спектр силы
let vibro = args.spec_vibro; //спектр вибрации
let type = args.type; //способ вычисления отклика
let view = args.view; //способ отображения спектра в линейных единицах или дБ
/* Алгоритм
1. Получить спектры ускорения и силы в комплексном виде (вибропреобразователь и молоток).
2. Преобразовать спектр силы (молотка) в комплексно-сопряжённый вид.
3. Получить кросс-спектр (перекрёстный) между ускорением и силой.
4. Вычислить деление кросс-спектра на спектр силы.
*/
/* Кросс-спектры
Сигнал силы в комплексно-сопряжённом виде
сигнал вибрации умножается на сигнал силы, а НЕ наоборот
умножение комплексных чисел по формуле:
(a1+b1i)*(a2+b2i)=(a1*a2-b1*b2)*(a1*b2+b1*a2)i
(a1*a2-b1*b2) - действительная часть
(a1*b2+b1*a2)i - мнимая часть
*/
let n = force.data.length; // длина массива спектра
let cross_real = new Float64Array(n); // типизированный массив для действительной части
let cross_imag = new Float64Array(n); // типизированный массив для мнимой части
for (let i = 0; i < n; i++) {
const vReal = vibro.real[i]; // действительная часть спектра вибрации
const vImag = vibro.imag[i]; // мнимая часть спектра вибрации
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = -force.imag[i]; // мнимая часть спектра силы сразу берём с обратным знаком
cross_real[i] = vReal * fReal - vImag * fImag;
cross_imag[i] = vReal * fImag + vImag * fReal;
}
/* Вычисление частотного отклика
деление комплексных чисел по формуле:
(a+bi)/(c+di)=(a*c-b*d)*(a*d+b*c)i
(a*c-b*d) - действительная часть
(a*d+b*c)i - мнимая часть
*/
let resp_real = new Float64Array(n); // типизированный массив для действительной части
let resp_imag = new Float64Array(n); // типизированный массив для мнимой части
// ОШИБКА в моей формуле вычисления частотного отклика
// ИПРАВИЛ на:
// деление комплексных чисел по формуле:
// (a+bi)/(c+di)=(a*c + b*d)/(c^2 + d^2) + (c*b - a*d)/(c^2 + d^2)i
// (a*c + b*d)/(c^2 + d^2) - действительная часть
// (c*b - a*d)/(c^2 + d^2)i - мнимая часть
// ПЕРЕВОД формулы в используемые переменные:
// const CF = fReal * fReal + fImag * fImag;
// resp_real[i] = (cReal * fReal + cImag * fImag) / CF;
// resp_imag[i] = (fReal * cImag - cReal * fImag) / CF;
if (type == 0) {
// Вариант 1: Частотный отклик как деление кросс-спектра вибрации и силы на автоспектр силы
// (Канал[0] & Канал[j]) / Канал[0]
for (let i = 0; i < n; i++) {
const cReal = cross_real[i]; // действительная часть кросс спектра
const cImag = cross_imag[i]; // мнимая часть кросс спектра
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = force.imag[i]; // мнимая часть спектра силы
const CF = fReal * fReal + fImag * fImag;
resp_real[i] = (cReal * fReal + cImag * fImag) / CF;
resp_imag[i] = (fReal * cImag - cReal * fImag) / CF;
}
} else {
// Вариант 2: Частотный отклик как деление автоспектра вибрации на автоспектр силы
// Канал[j] / Канал[0]
for (let i = 0; i < n; i++) {
const vReal = vibro.real[i]; // действительная часть спектра вибрации
const vImag = vibro.imag[i]; // мнимая часть спектра вибрации
const fReal = force.real[i]; // действительная часть спектра силы
const fImag = force.imag[i]; // мнимая часть спектра силы
const VF = vReal * vReal + fImag * fImag;
resp_real[i] = (vReal * fReal - vImag * fImag) / VF;
resp_imag[i] = (fReal * vImag + vReal * fImag) / VF;
}
}
// запись массива амплитуды и фазы
let resp_ampl = new Float64Array(n); // типизированный массив для амплитуды
let resp_phase = new Float64Array(n); // типизированный массив для фазы
const RAD_TO_DEG = 180 / Math.PI; //перевод радиан в градусы
for (let i = 0; i < n; i++) {
const rReal = resp_real[i]; // действительная часть спектра отклика
const rImag = resp_imag[i]; // мнимая часто спектра отклика
resp_ampl[i] = Math.sqrt(rReal * rReal + rImag * rImag);
if (view > 0) { resp_ampl = resp_ampl.map((item) => (item = 20 * Math.log10(item / 1e-6))) }; //переводим в дБ
resp_phase[i] = Math.atan2(rImag, rReal) * RAD_TO_DEG;
}
// Приводим фазу к диапазону [0°, 360°]
for (let i = 0; i < n; i++) {
resp_phase[i] = resp_phase[i] % 360;
if (resp_phase[i] < 0) { resp_phase[i] += 360 }
}
return {
data: resp_ampl,
phase: resp_phase,
resolution: force.resolution
}
}; //рассчет перекрестного спектра

View File

@ -0,0 +1,188 @@
"use strict";
let signals = gtl.options.record.signalsModel;
let options = gtl.options;
let record = gtl.options.record;
let point = gtl.options.point;
let getResponse = gtl.import("getResponse.js").getResponse;
let getAvgArray = gtl.import("getResponse.js").getAvgArray;
let plot_ausp = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_resp_ampl = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_resp_phase = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
let plot_avg_resp = gtl.plots.add("Средний частотный отклик"); // средний частотный отклик
// Цвета
// #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; // отображение амплитуды спектра unit/dB (0/1)
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 thresh_level = gtl.options.customOptions.thresh_level; // уровень удара для засчитывания импульса
let time_impulse_ = gtl.options.customOptions.time_impulse; // задание длины импульса из опций
let remove_resp_arr = gtl.options.customOptions.remove_resp_arr;
gtl.log.info("remove_resp_arr", remove_resp_arr);
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.stored_ranges;
let ranges = gtl.options.customOptions.ranges;
gtl.player.custom_ranges = ranges; // задание диапазонов плеера
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
gtl.log.info("Граничная частота спектров", frequency);
gtl.log.info("Частотное разрешение спектров", resolution);
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force = gtl.analog_inputs[signals[0].portNumber]; // источник сигнала силы
let channel = 1; //номер первого канала вибрации
let window_spec_force = gtl.options.customOptions.window_spec_force; // окно спектра силы
let window_spec_vibr = gtl.options.customOptions.window_spec_vibr; // окно спектра вибрации
let force = gtl.create_ausp({
src: src_force, // сигнал силы
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_force,
view: view
});
// Спектр амплитудный для цикла по всем каналам вибрации
let ausps = []; //массив объектов спектров вибрации по каналам
let phases = []; //массив объектов ФЧХ по каналам
let ausps_data = []; //массив данных спектров после каздого удара
let resps_data = []; //массив данных откликов после каждого удара
for (let i = channel; i < signals.length; i++) { }; //цикл по каналам
let ausp = gtl.create_ausp({
src: gtl.analog_inputs[signals[channel].portNumber], // сырой сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_vibr,
view: spec_view
});
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: gtl.analog_inputs[signals[channel].portNumber], // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
// let time_impulse = time_impulse_ == 0 ? 1/resolution : time_impulse_; // условие выбора длительности импульса
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностки
let is_ranges = false; // состояние готовности диапазонов
/* Функция диагностики.
Первый запуск функции диагностики происходит после проигрывания всего сигнала и определения массива диапазонов по срабатыванию триггера
После этого происходит добавление массива пользовательских диапазонов в плеер, отрисовка (при необходимости) сигнала триггера
Затем устанавливается интервал запуска функции диагностики, равный временному окну диапазона и запускается отсчет циклов (попыток) диагностики
Как только количество циклов (попыток) сравнивается с количеством установленных пользовательских диапазонов, диагностика останавливается
*/
gtl.diagnostic.interval = time_impulse; // первичный интервал запуска функции диагностики
gtl.log.info('Время импульса', time_impulse);
function diagnose() {
if (!is_ranges) {
is_ranges = true; // пользовательские диапазоны готовы
gtl.log.info('creating ranges', true);
gtl.log.info('ranges', JSON.stringify(gtl.player.custom_ranges));
gtl.log.info("Количество диапазонов в плеере", ranges.length);
gtl.log.info("Установленный интервал запуска диагностики", time_impulse);
gtl.log.info("acq_time", gtl.acq_time);
}
if (tries > 0) {
gtl.log.info("Количество элементов массива force", force.data.length);
gtl.log.info("Количество элементов массива ausp", ausp.data.length);
gtl.log.info('diagnostic', `Цикл диагностики ${tries} - ${true}`);
gtl.log.info('Диапазон плеера', JSON.stringify(gtl.player.custom_ranges));
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Спектр силы - удар №${tries}, N`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
// Отображаем автоспектр вибрации
plot_ausp.add({
color: 0x34C924,
name: `Спектр канала 1 - удар №${tries}, g`,
x: ausp.resolution,
y: ausp.data,
tags: ["Cпектр вибрации, g"]
});
// Вычисляем спектр отклика
let rsp = getResponse({
spec_force: force, //спектр силы
spec_vibro: ausp, //спектр вибрации
type: variant_freq_resp, //способ вычисления отклика
view: 0 //способ отображения спектра в линейных единицах или дБ
});
// Отображаем спектр отклика
plot_resp_ampl.add({
color: 0x3b30b6,
name: `Амплитуда частотного отклика канала 1 - удар №${tries}, g/N`,
x: resolution,
y: rsp.data,
tags: ["Амплитуда частотного отклика, g/N"]
});
ausps_data.push(ausp.data);
resps_data.push(rsp.data);
}
tries++;
if (tries > ranges.length) {
gtl.log.info('Вычисление среднего отклика', `processing...`);
const avgResponse = getAvgArray(resps_data, remove_resp_arr); //вычисляем средний отклик
// Отображаем средний спектр отклика
plot_avg_resp.add({
color: 0xff3dcc,
name: `Амплитуда среднего частотного отклика, g/N`,
x: resolution,
y: avgResponse,
tags: ["Амплитуда среднего частотного отклика, g/N"]
});
gtl.log.info('Вычисление среднего отклика', `done!`);
gtl.diagnostic.stop();
}; // останавливаем диагностику после окончания диапазонов
}

View File

@ -47,6 +47,9 @@ gtl.log.info("Частотное разрешение спектров", resolut
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force = gtl.analog_inputs[signals[0].portNumber]; // источник сигнала силы
let channel = 1; //номер первого канала вибрации
let window_spec_force = gtl.options.customOptions.window_spec_force; // окно спектра силы
let window_spec_vibr = gtl.options.customOptions.window_spec_vibr; // окно спектра вибрации
let force = gtl.create_ausp({
src: src_force, // сигнал силы
@ -54,7 +57,7 @@ let force = gtl.create_ausp({
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
window: window_spec_force,
view: view
});
@ -72,7 +75,7 @@ let ausp = gtl.create_ausp({
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
window: window_spec_vibr,
view: spec_view
});
@ -91,6 +94,7 @@ let phase_delta = gtl.create_pfc({
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
// let time_impulse = time_impulse_ == 0 ? 1/resolution : time_impulse_; // условие выбора длительности импульса
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностки

View File

@ -0,0 +1,191 @@
"use strict";
let signals = gtl.options.record.signalsModel;
let options = gtl.options;
let record = gtl.options.record;
let point = gtl.options.point;
let getResponse = gtl.import("getResponse.js").getResponse;
let getAvgArray = gtl.import("getResponse.js").getAvgArray;
let plot_ausp = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_resp_ampl = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_resp_phase = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
let plot_avg_resp = gtl.plots.add("Средний частотный отклик"); // средний частотный отклик
// Цвета
// #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; // отображение амплитуды спектра unit/dB (0/1)
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 thresh_level = gtl.options.customOptions.thresh_level; // уровень удара для засчитывания импульса
let time_impulse_ = gtl.options.customOptions.time_impulse; // задание длины импульса из опций
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.stored_ranges;
let ranges = gtl.options.customOptions.ranges;
gtl.player.custom_ranges = ranges; // задание диапазонов плеера
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
gtl.log.info("Граничная частота спектров", frequency);
gtl.log.info("Частотное разрешение спектров", resolution);
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force = gtl.analog_inputs[signals[0].portNumber]; // источник сигнала силы
let channel = 1; //номер первого канала вибрации
let force = gtl.create_ausp({
src: src_force, // сигнал силы
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: view
});
// Спектр амплитудный для цикла по всем каналам вибрации
let ausps = []; //массив объектов спектров вибрации по каналам
let phases = []; //массив объектов ФЧХ по каналам
let ausps_data = []; //массив данных спектров после каздого удара
let resps_data = []; //массив данных откликов после каждого удара
for (let i = channel; i < signals.length; i++) { }; //цикл по каналам
let ausp = gtl.create_ausp({
src: gtl.analog_inputs[signals[channel].portNumber], // сырой сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: spec_view
});
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: gtl.analog_inputs[signals[channel].portNumber], // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностки
let is_ranges = false; // состояние готовности диапазонов
/* Функция диагностики.
Первый запуск функции диагностики происходит после проигрывания всего сигнала и определения массива диапазонов по срабатыванию триггера
После этого происходит добавление массива пользовательских диапазонов в плеер, отрисовка (при необходимости) сигнала триггера
Затем устанавливается интервал запуска функции диагностики, равный временному окну диапазона и запускается отсчет циклов (попыток) диагностики
Как только количество циклов (попыток) сравнивается с количеством установленных пользовательских диапазонов, диагностика останавливается
*/
gtl.diagnostic.interval = time_impulse; // первичный интервал запуска функции диагностики
gtl.log.info('Время импульса', time_impulse);
function diagnose() {
if (!is_ranges) {
is_ranges = true; // пользовательские диапазоны готовы
gtl.log.info('creating ranges', true);
gtl.log.info('ranges', JSON.stringify(gtl.player.custom_ranges));
gtl.log.info("Количество диапазонов в плеере", ranges.length);
gtl.log.info("Установленный интервал запуска диагностики", time_impulse);
gtl.log.info("acq_time", gtl.acq_time);
}
if (tries > 0) {
gtl.log.info("Количество элементов массива force", force.data.length);
gtl.log.info("Количество элементов массива ausp", ausp.data.length);
gtl.log.info('diagnostic', `Цикл диагностики ${tries} - ${true}`);
gtl.log.info('Диапазон плеера', JSON.stringify(gtl.player.custom_ranges));
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Спектр силы - удар №${tries}, N`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
// Отображаем автоспектр вибрации
plot_ausp.add({
color: 0x34C924,
name: `Спектр канала 1 - удар №${tries}, g`,
x: ausp.resolution,
y: ausp.data,
tags: ["Cпектр вибрации, g"]
});
// Вычисляем спектр отклика
let rsp = getResponse({
spec_force: force, //спектр силы
spec_vibro: ausp, //спектр вибрации
type: variant_freq_resp, //способ вычисления отклика
view: 0 //способ отображения спектра в линейных единицах или дБ
});
// Отображаем спектр отклика
plot_resp_ampl.add({
color: 0x3b30b6,
name: `Амплитуда частотного отклика канала 1 - удар №${tries}, g/N`,
x: resolution,
y: rsp.data,
tags: ["Амплитуда частотного отклика, g/N"]
});
ausps_data.push(ausp.data);
resps_data.push(rsp.data);
}
tries++;
if (tries > ranges.length) {
gtl.log.info('Вычисление среднего отклика', `processing...`);
const avgResponse = getAvgArray(resps_data,[4,7,8]); //вычисляем средний отклик
const avgResponse_2 = getAvgArray(resps_data,[]); //вычисляем средний отклик
// Отображаем средний спектр отклика
plot_avg_resp.add({
color: 0xff3dcc,
name: `Амплитуда среднего частотного отклика, g/N`,
x: resolution,
y: avgResponse,
tags: ["Амплитуда среднего частотного отклика, g/N"]
});
plot_avg_resp.add({
color: 0x0000ff,
name: `Амплитуда среднего частотного отклика, g/N`,
x: resolution,
y: avgResponse_2,
tags: ["Амплитуда среднего частотного отклика, g/N"]
});
gtl.log.info('Вычисление среднего отклика', `done!`);
gtl.diagnostic.stop();
}; // останавливаем диагностику после окончания диапазонов
}

251
scripts/freq_response 3.js Normal file
View File

@ -0,0 +1,251 @@
"use strict";
let signals = gtl.options.record.signalsModel;
let options = gtl.options;
let record = gtl.options.record;
let point = gtl.options.point;
let getResponse = gtl.import("getResponse.js").getResponse;
let getAvgArray = gtl.import("getResponse.js").getAvgArray;
let plot_ausp = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_resp_ampl = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_resp_phase = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
let plot_avg_resp = gtl.plots.add("Средний частотный отклик"); // средний частотный отклик
// Цвета
// #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; // отображение амплитуды спектра unit/dB (0/1)
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 thresh_level = gtl.options.customOptions.thresh_level; // уровень удара для засчитывания импульса
let time_impulse_ = gtl.options.customOptions.time_impulse; // задание длины импульса из опций
let remove_resp_arr = gtl.options.customOptions.remove_resp_arr;
gtl.log.info("remove_resp_arr", remove_resp_arr);
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.stored_ranges;
let ranges = gtl.options.customOptions.ranges;
gtl.player.custom_ranges = ranges; // задание диапазонов плеера
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
gtl.log.info("Граничная частота спектров", frequency);
gtl.log.info("Частотное разрешение спектров", resolution);
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force; // источник сигнала силы
let channel = 1; // номер первого канала вибрации
let window_spec_force = gtl.options.customOptions.window_spec_force; // окно спектра силы
let window_spec_vibr = gtl.options.customOptions.window_spec_vibr; // окно спектра вибрации
let signal_source = gtl.options.customOptions.signal_source; // выбор источника сигнала: 0 - сырой / 1 - фильтр
let left_bord_filt = gtl.options.customOptions.left_bord_filt; // левая граница фильтра
let right_bord_filt = gtl.options.customOptions.right_bord_filt; // правая граница фильтра
let order_filt = gtl.options.customOptions.order_filt; // порядок фильтра
let kind_filt = gtl.options.customOptions.kind_filt; // тип окна фильтра gtl.filter_iir.butterworth
let width_filt; // полоса пропускания фильтра
width_filt = right_bord_filt - left_bord_filt;
let freq_filt; // центральная частота фильтра
freq_filt = right_bord_filt - width_filt/2;
// СИГНАЛ СИЛЫ (молоток)
// Фильтрация
let filter_force = gtl.add_filter_iir(gtl.analog_inputs[signals[0].portNumber]);
filter_force.kind = kind_filt;
filter_force.type = gtl.filter_iir.bandpass;
filter_force.order = order_filt;
filter_force.frequency = freq_filt; // центральная частота полосового фильтра
filter_force.width = width_filt; // ширина полосы фильтра
// Выбор источника сигнала силы: фильтр / сырой сигнал
if (signal_source == 1)
{
src_force = filter_force; // источник фильтр
}
else if (signal_source == 0)
{
src_force = gtl.analog_inputs[signals[0].portNumber]; // источник cырой сигнал
}
let force = gtl.create_ausp({
src: src_force,
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_force,
view: view
});
// СИГНАЛЫ ВИБРАЦИИ (отклик)
// Спектр амплитудный для цикла по всем каналам вибрации
let srs_vibr; // источник сигнала вибрации
let ausps = []; //массив объектов спектров вибрации по каналам
let ausp_arr = [];
let phases = []; //массив объектов ФЧХ по каналам
let phase_arr
let ausps_data = []; //массив данных спектров после каждого удара
let resps_data = []; //массив данных откликов после каждого удара
// Цикл по каналам
for (let j = channel; j < signals.length; j++) {
// Фильтрация
let filter_vibr = gtl.add_filter_iir(gtl.analog_inputs[signals[j].portNumber]);
filter_vibr.kind = kind_filt;
filter_vibr.type = gtl.filter_iir.bandpass;
filter_vibr.order = order_filt;
filter_vibr.frequency = freq_filt; // центральная частота полосового фильтра
filter_vibr.width = width_filt; // ширина полосы фильтра
// Выбор источника сигнала вибрации: фильтр / сырой сигнал
if (signal_source == 1)
{
src_vibr = filter_vibr; // источник фильтр
}
else if (signal_source == 0)
{
src_vibr = gtl.analog_inputs[signals[j].portNumber]; // источник cырой сигнал
}
let ausp = gtl.create_ausp({
src: src_vibr, // сырой сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_vibr,
view: spec_view
});
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: src_vibr, // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
};
// Запись массивовм спектров вибрации
ausp_arr.push(ausp);
phase_arr.push(phase_delta);
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностки
let is_ranges = false; // состояние готовности диапазонов
/* Функция диагностики.
Первый запуск функции диагностики происходит после проигрывания всего сигнала и определения массива диапазонов по срабатыванию триггера
После этого происходит добавление массива пользовательских диапазонов в плеер, отрисовка (при необходимости) сигнала триггера
Затем устанавливается интервал запуска функции диагностики, равный временному окну диапазона и запускается отсчет циклов (попыток) диагностики
Как только количество циклов (попыток) сравнивается с количеством установленных пользовательских диапазонов, диагностика останавливается
*/
gtl.diagnostic.interval = time_impulse; // первичный интервал запуска функции диагностики
gtl.log.info('Время импульса', time_impulse);
function diagnose() {
if (!is_ranges) {
is_ranges = true; // пользовательские диапазоны готовы
gtl.log.info('creating ranges', true);
gtl.log.info('ranges', JSON.stringify(gtl.player.custom_ranges));
gtl.log.info("Количество диапазонов в плеере", ranges.length);
gtl.log.info("Установленный интервал запуска диагностики", time_impulse);
gtl.log.info("acq_time", gtl.acq_time);
}
if (tries > 0) {
gtl.log.info("Количество элементов массива force", force.data.length);
gtl.log.info("Количество спектров вибрации ausp_arr", ausp_arr.data.length);
gtl.log.info('diagnostic', `Цикл диагностики ${tries} - ${true}`);
gtl.log.info('Диапазон плеера', JSON.stringify(gtl.player.custom_ranges));
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Спектр силы - удар №${tries}, N`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
// Отображаем автоспектр вибрации
// по всем каналам
for (let j = 0; j < ausp_arr.length; j++) {
plot_ausp.add({
color: 0x34C924,
name: `Спектр канала ${j+1} - удар №${tries}, g`,
x: ausp_arr[j].resolution,
y: ausp_arr[j].data,
tags: ["Cпектр вибрации, g"]
});
// Вычисляем спектр отклика
let rsp = getResponse({
spec_force: force, //спектр силы
spec_vibro: ausp_arr[j], //спектр вибрации
type: variant_freq_resp, //способ вычисления отклика
view: 0 //способ отображения спектра в линейных единицах или дБ
});
// Отображаем спектр отклика
plot_resp_ampl.add({
color: 0x3b30b6,
name: `Амплитуда частотного отклика канала ${j+1} - удар №${tries}, g/N`,
x: resolution,
y: rsp.data,
tags: ["Амплитуда частотного отклика, g/N"]
});
ausps_data.push(ausp.data);
resps_data.push(rsp.data);
}
tries++;
if (tries > ranges.length) {
gtl.log.info('Вычисление среднего отклика', `processing...`);
const avgResponse = getAvgArray(resps_data, remove_resp_arr); //вычисляем средний отклик
// Отображаем средний спектр отклика
plot_avg_resp.add({
color: 0xff3dcc,
name: `Амплитуда среднего частотного отклика, g/N`,
x: resolution,
y: avgResponse,
tags: ["Амплитуда среднего частотного отклика, g/N"]
});
gtl.log.info('Вычисление среднего отклика', `done!`);
gtl.diagnostic.stop();
}; // останавливаем диагностику после окончания диапазонов
}

View File

@ -4,10 +4,12 @@ let options = gtl.options;
let record = gtl.options.record;
let point = gtl.options.point;
let getResponse = gtl.import("getResponse.js").getResponse;
let getAvgArray = gtl.import("getResponse.js").getAvgArray;
let plot_ausp = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_resp_ampl = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_resp_phase = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
let plot_avg_resp = gtl.plots.add("Средний частотный отклик"); // средний частотный отклик
// Цвета
// #ff0000 - красный
@ -29,9 +31,13 @@ let view_freq_resp = gtl.options.customOptions.view_freq_resp; // отображ
let variant_freq_resp = gtl.options.customOptions.variant_freq_resp; // вариант вычисления: 0 - через кросс, 1 - через автоспектр
let thresh_level = gtl.options.customOptions.thresh_level; // уровень удара для засчитывания импульса
let time_impulse_ = gtl.options.customOptions.time_impulse; // задание длины импульса из опций
let remove_resp_arr = gtl.options.customOptions.remove_resp_arr;
gtl.log.info("remove_resp_arr", remove_resp_arr);
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.stored_ranges;
let ranges = gtl.options.customOptions.ranges;
gtl.player.custom_ranges = ranges; // задание диапазонов плеера
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
@ -41,76 +47,66 @@ gtl.log.info("Частотное разрешение спектров", resolut
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force = gtl.analog_inputs[signals[0].portNumber]; // источник сигнала силы
let channel = 1; //номер первого канала вибрации
let window_spec_force = gtl.options.customOptions.window_spec_force; // окно спектра силы
let window_spec_vibr = gtl.options.customOptions.window_spec_vibr; // окно спектра вибрации
//формируем спектр силы
let force = gtl.create_ausp({
src: src_force, // сигнал силы
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
window: window_spec_force,
view: view
});
// Спектр амплитудный для цикла по всем каналам вибрации
let ausps = []; //массив объектов спектров вибрации по каналам
let phases = []; //массив объектов ФЧХ по каналам
for (let i = 1; i <= signals.length -1; i++) {
let hits_data = {}; //объект результатов по каждому удару
// let ausps_data = []; //массив данных спектров после каждого удара
// let resps_data = []; //массив данных амплитуды откликов после каждого удара
// let resps_phase = []; //массив данных фазы откликов после каждого удара
for (let i = 1; i <= signals.length - 1; i++) {
let ausp = gtl.create_ausp({
src: gtl.analog_inputs[signals[i].portNumber], // сырой сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
window: window_spec_vibr,
view: spec_view
});
ausps.push(ausp);
}; //цикл по каналам
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: gtl.analog_inputs[signals[channel].portNumber], // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: gtl.analog_inputs[signals[i].portNumber], // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
phases.push(phase_delta);
}; //цикл по каналам
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
let time_pre = time_window / 2; // время предыстории
let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностки
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 0; // циклы диагностики
let is_ranges = false; // состояние готовности диапазонов
// Порог для отслеживание импульсов
let __thresh = gtl.create_moving_thresh({
src: src_force,
name: "thresh",
time: time_window,
level: thresh_level
});
__thresh.triggered.connect(thresh_triggered_event); //подключаем функцию
// Функция получения диапазонов импульсов
function thresh_triggered_event(flag, sample) {
if (is_ranges) return;
if (flag) {
let start = (sample / __thresh.rate) - time_pre; //время срабатывания триггера
gtl.log.info("trigger on time", start);
let range = {
min: start,
max: start + time_impulse
};
ranges.push(range); //добавляем диапазон в массив
};
};
/* Функция диагностики.
Первый запуск функции диагностики происходит после проигрывания всего сигнала и определения массива диапазонов по срабатыванию триггера
@ -119,40 +115,37 @@ function thresh_triggered_event(flag, sample) {
Как только количество циклов (попыток) сравнивается с количеством установленных пользовательских диапазонов, диагностика останавливается
*/
gtl.diagnostic.interval = gtl.options.record.playerTime; // первичный интервал запуска функции диагностики
gtl.log.info('Время импульса', time_impulse);
function diagnose() {
if (!is_ranges) {
gtl.player.custom_ranges = ranges; // добавляем пользовательские диапазоны в плеер
gtl.results = { ranges: ranges }; // добавляем диапазоны в результат
gtl.log.info('creating ranges', true);
gtl.log.info('ranges', JSON.stringify(ranges));
is_ranges = true; // пользовательские диапазоны готовы
gtl.diagnostic.interval = time_impulse; // задаем время запуска функции диагностики, равное длине импульса
gtl.log.info("Количество диапазонов в плеере", ranges.length);
gtl.log.info("Установленный интервал запуска диагностики", time_impulse);
gtl.log.info("acq_time", gtl.acq_time);
}
let resps_data = []; //массив данных амплитуды откликов после каждого удара
let resps_phase = []; //массив данных фазы откликов после каждого удара
if (tries > 0) {
gtl.log.info('diagnostic', `Цикл диагностики ${tries} - ${true}`)
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Спектр силы - удар №${tries}, N`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
if (tries > 0) {
for (let i = 0; i < ausps.length; i++) {
for (let i = 0; i < ausps.length; i++) {
gtl.log.info('diagnostic', `Цикл диагностики ${tries} - ${true}`)
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Спектр силы - удар №${tries}, N`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
// Отображаем автоспектр вибрации
plot_ausp.add({
color: 0x34C924,
name: `Спектр канала ${i+1} - удар №${tries}, g`,
name: `Спектр канала ${i + 1} - удар №${tries}, g`,
x: ausps[i].resolution,
y: ausps[i].data,
tags: ["Cпектр вибрации, g"]
@ -169,7 +162,7 @@ function diagnose() {
// Отображаем спектр отклика
plot_resp_ampl.add({
color: 0x3b30b6,
name: `Амплитуда частотного отклика канала ${i+1} - удар №${tries}, g/N`,
name: `Амплитуда частотного отклика канала ${i + 1} - удар №${tries}, g/N`,
x: resolution,
y: rsp.data,
tags: ["Амплитуда частотного отклика, g/N"]
@ -178,15 +171,47 @@ function diagnose() {
// Отображаем фазовый спектр отклика
plot_resp_phase.add({
color: 0xff3dcc,
name: `Фаза частотного отклика канала ${i+1} - удар №${tries}, °`,
name: `Фаза частотного отклика канала ${i + 1} - удар №${tries}, °`,
x: resolution,
y: rsp.phase,
tags: ["Фаза частотного отклика, °"]
});
}
// ausps_data.push(ausps.data);
resps_data.push(rsp.data);
resps_phase.push(rsp.phase);
}
tries++;
if (tries > ranges.length) gtl.diagnostic.stop(); // останавливаем диагностику после окончания диапазонов
tries++; // увеличение счётчика
}
if (tries > ranges.length) {
gtl.log.info('Вычисление среднего отклика', `processing...`);
const avgResponse = getAvgArray(resps_data, remove_resp_arr); //вычисляем средний отклик
// Отображаем средний спектр отклика
plot_avg_resp.add({
color: 0xff3dcc,
name: `Амплитуда среднего частотного отклика канала ${i + 1}, g/N`,
x: resolution,
y: avgResponse,
tags: ["Амплитуда среднего частотного отклика, g/N"]
});
gtl.log.info('Вычисление среднего отклика', `done!`);
}
gtl.diagnostic.stop(); // останавливаем диагностику после окончания диапазонов
}

View File

@ -0,0 +1,206 @@
"use strict";
let signals = gtl.options.record.signalsModel;
let options = gtl.options;
let record = gtl.options.record;
let point = gtl.options.point;
let getResponse = gtl.import("getResponse.js").getResponse;
let getAvgArray = gtl.import("getResponse.js").getAvgArray;
let plot_ausp = gtl.plots.add("Спектры по каналам"); // спектры по каналам вибрации
let plot_resp_ampl = gtl.plots.add("Частотный отклик по каналам (амплитуда)"); // амплитудные спектры по каналам вибрации
let plot_resp_phase = gtl.plots.add("Частотный отклик по каналам (фаза)"); // фазовые спектры по каналам вибрации
let plot_avg_resp = gtl.plots.add("Средний частотный отклик"); // средний частотный отклик
// Цвета
// #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; // отображение амплитуды спектра unit/dB (0/1)
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 thresh_level = gtl.options.customOptions.thresh_level; // уровень удара для засчитывания импульса
let time_impulse_ = gtl.options.customOptions.time_impulse; // задание длины импульса из опций
let remove_resp_arr = gtl.options.customOptions.remove_resp_arr;
gtl.log.info("remove_resp_arr", remove_resp_arr);
// Задание диапазона сигнала для анализа
// let ranges = gtl.player.stored_ranges;
let ranges = gtl.options.customOptions.ranges;
gtl.player.custom_ranges = ranges; // задание диапазонов плеера
// Спектры каналов ускорения (каналы датчиков вибрации)
gtl.log.info("Количество сигналов", signals.length);
gtl.log.info("Граничная частота спектров", frequency);
gtl.log.info("Частотное разрешение спектров", resolution);
let spec_view = view_ == 0 ? gtl.spec.unit : gtl.spec.db; // условие отображения спектров в дБ или линейном виде
let src_force = gtl.analog_inputs[signals[0].portNumber]; // источник сигнала силы
let channel = 1; //номер первого канала вибрации
let window_spec_force = gtl.options.customOptions.window_spec_force; // окно спектра силы
let window_spec_vibr = gtl.options.customOptions.window_spec_vibr; // окно спектра вибрации
//формируем спектр силы
let force = gtl.create_ausp({
src: src_force, // сигнал силы
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_force,
view: view
});
// Спектр амплитудный для цикла по всем каналам вибрации
let ausps = []; //массив объектов спектров вибрации по каналам
let phases = []; //массив объектов ФЧХ по каналам
let hits_data = {}; //объект результатов по каждому удару
for (let i = 1; i <= signals.length - 1; i++) {
let ausp = gtl.create_ausp({
src: gtl.analog_inputs[signals[i].portNumber], // сырой сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: window_spec_vibr,
view: spec_view
});
ausps.push(ausp);
let phase_delta = gtl.create_pfc({
src0: src_force, // сигнал силы, относительно него вычисляем дельту фазы
src1: gtl.analog_inputs[signals[i].portNumber], // сигнал вибрации
frequency: frequency,
resolution: resolution,
average: average,
overlap: overlap,
window: gtl.spec.rectangular,
view: gtl.phase.deg,
range: gtl.phase.positive,
is_single: false
});
phases.push(phase_delta);
}; //цикл по каналам
let time_window = 0.0001 // временное окно наблюдения
let time_impulse = time_impulse_ == 0 ? gtl.acq_time + 0.01 : time_impulse_; // условие выбора длительности импульса
// let time_pre = time_window / 2; // время предыстории
// let ranges = []; // массив диапазонов для импульсов
let tries = 1; // циклы диагностики
let is_ranges = false; // состояние готовности диапазонов
/* Функция диагностики.
Первый запуск функции диагностики происходит после проигрывания всего сигнала и определения массива диапазонов по срабатыванию триггера
После этого происходит добавление массива пользовательских диапазонов в плеер, отрисовка (при необходимости) сигнала триггера
Затем устанавливается интервал запуска функции диагностики, равный временному окну для анализа импульса и запускается отсчет циклов (попыток) диагностики
Как только количество циклов (попыток) сравнивается с количеством установленных пользовательских диапазонов, диагностика останавливается
*/
gtl.diagnostic.interval = gtl.options.record.playerTime; // первичный интервал запуска функции диагностики
gtl.log.info('Время импульса', time_impulse);
function diagnose() {
let resps_data = []; //массив данных амплитуды откликов после каждого удара
let resps_phase = []; //массив данных фазы откликов после каждого удара
for (let i = 0; i < ausps.length; i++) {
gtl.log.info('diagnostic', `Удар ${tries} - Канал ${i + 1}`)
// Отображаем спектр силы
plot_ausp.add({
color: 0xff00f7,
name: `Удар №${tries}, N - Спектр силы`,
x: force.resolution,
y: force.data,
tags: [`Спектр силы, N`]
});
// Отображаем автоспектр вибрации
plot_ausp.add({
color: 0x34C924,
name: `Удар №${tries}, g - Спектр канала ${i + 1}`,
x: ausps[i].resolution,
y: ausps[i].data,
tags: ["Cпектр вибрации, g"]
});
// Вычисляем спектр отклика
let rsp = getResponse({
spec_force: force, //спектр силы
spec_vibro: ausps[i], //спектр вибрации
type: variant_freq_resp, //способ вычисления отклика
view: 0 //способ отображения спектра в линейных единицах или дБ
});
// Отображаем спектр отклика
plot_resp_ampl.add({
color: 0x3b30b6,
name: `Удар №${tries}, g/N - Отклик канала ${i + 1}`,
x: resolution,
y: rsp.data,
tags: ["Амплитуда частотного отклика, g/N"]
});
// // Отображаем фазовый спектр отклика
// plot_resp_phase.add({
// color: 0xff3dcc,
// name: `Удар №${tries}, ° - Фаза частотного отклика канала ${i + 1}`,
// x: resolution,
// y: rsp.phase,
// tags: ["Фаза частотного отклика, °"]
// });
resps_data.push(rsp.data); //добавляем отклики по каждому каналу (амплитуда)
resps_phase.push(rsp.phase); //добавляем отклики по каждому каналу (фаза)
}
//собираем данные удара по всем каналам
hits_data[`hit${tries}`] = {
resps_data: resps_data,
resps_phase: resps_phase
}
tries++; // увеличение счётчика
if (tries > ranges.length) {
gtl.log.info('Вычисление среднего отклика по каналам', `processing...`);
// gtl.results = hits_data; //добавляем результат по всем ударам в ПО
for (let i = 0; i < ausps.length; i++) {
gtl.log.info(`Формируем данные по Каналу ${i + 1}`, `processing...`);
let channelData = [];
let channelPhase = [];
for (const hitKey in hits_data) {
let hit = hits_data[hitKey];
// gtl.log.info(`Канал ${i + 1}, удар ${hitKey}`, JSON.stringify(hit.resps_data[i]));
channelData.push(hit.resps_data[i]);
channelPhase.push(hit.resps_phase[i]);
}
let avgResponse = getAvgArray(channelData, remove_resp_arr); //вычисляем средний отклик
plot_avg_resp.add({
color: 0xff3dcc,
name: `Усредн.отклик кан.${i + 1}, g/N`,
x: resolution,
y: avgResponse,
tags: ["Усреднённый отклик, g/N"]
});
gtl.log.info(`Вычисление среднего отклика по Каналу ${i + 1}`, `done!`);
}
gtl.diagnostic.stop(); // останавливаем диагностику после окончания диапазонов
}
}