freq_responce/modules/getResponse_old.js

110 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}; //рассчет перекрестного спектра