From 7f7df545307adb220fdf74e4508db2c0477e8a7a Mon Sep 17 00:00:00 2001 From: demvlad Date: Fri, 2 May 2025 12:07:51 +0300 Subject: [PATCH 1/5] Resolved issue of magnitude computing at the spectrum charts --- src/graph_spectrum_calc.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/graph_spectrum_calc.js b/src/graph_spectrum_calc.js index b358dc22..ecbaff7f 100644 --- a/src/graph_spectrum_calc.js +++ b/src/graph_spectrum_calc.js @@ -458,27 +458,33 @@ GraphSpectrumCalc._normalizeFft = function(fftOutput, fftLength) { fftLength = fftOutput.length; } - // Make all the values absolute, and calculate some useful values (max noise, etc.) + // Make all the values absolute, and calculate some useful values (max noise, etc + // The fft output contains complex values (re, im pairs) of two-side spectrum + // Compute magnitudes for one spectrum side + const magnitudeLength = Math.floor(fftLength / 2); const maxFrequency = (this._blackBoxRate / 2.0); - const noiseLowEndIdx = 100 / maxFrequency * fftLength; + const noiseLowEndIdx = 100 / maxFrequency * magnitudeLength; + const magnitudes = new Float64Array(magnitudeLength); let maxNoiseIdx = 0; let maxNoise = 0; - for (let i = 0; i < fftLength; i++) { - fftOutput[i] = Math.abs(fftOutput[i]); - if (i > noiseLowEndIdx && fftOutput[i] > maxNoise) { - maxNoise = fftOutput[i]; + for (let i = 0; i < magnitudeLength; i++) { + const re = fftOutput[2 * i], + im = fftOutput[2 * i + 1]; + magnitudes[i] = Math.hypot(re, im); + if (i > noiseLowEndIdx && magnitudes[i] > maxNoise) { + maxNoise = magnitudes[i]; maxNoiseIdx = i; } } - maxNoiseIdx = maxNoiseIdx / fftLength * maxFrequency; + maxNoiseIdx = maxNoiseIdx / magnitudeLength * maxFrequency; const fftData = { fieldIndex : this._dataBuffer.fieldIndex, fieldName : this._dataBuffer.fieldName, - fftLength : fftLength, - fftOutput : fftOutput, + fftLength : magnitudeLength, + fftOutput : magnitudes, maxNoiseIdx : maxNoiseIdx, blackBoxRate : this._blackBoxRate, }; From 4044877fd02704d26e2e820a7f3b3c14faafb127 Mon Sep 17 00:00:00 2001 From: demvlad Date: Fri, 2 May 2025 15:02:50 +0300 Subject: [PATCH 2/5] Decreased spectrum points drawing step --- src/graph_spectrum_plot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph_spectrum_plot.js b/src/graph_spectrum_plot.js index b43d4aea..1a916036 100644 --- a/src/graph_spectrum_plot.js +++ b/src/graph_spectrum_plot.js @@ -212,7 +212,7 @@ GraphSpectrumPlot._drawFrequencyGraph = function (canvasCtx) { canvasCtx.fillStyle = barGradient; const fftScale = HEIGHT / (this._zoomY * 100); - for (let i = 0; i < PLOTTED_BUFFER_LENGTH; i += 10) { + for (let i = 0; i < PLOTTED_BUFFER_LENGTH; i += 5) { const barHeight = this._fftData.fftOutput[i] * fftScale; canvasCtx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight); x += barWidth + 1; From f2088737b4471ecbb7f7a4ca3a63d9894fb6ac57 Mon Sep 17 00:00:00 2001 From: demvlad Date: Fri, 2 May 2025 22:27:03 +0300 Subject: [PATCH 3/5] Resolved issue of magnitude computing at the spectrum charts by throttle and rpm --- src/graph_spectrum_calc.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/graph_spectrum_calc.js b/src/graph_spectrum_calc.js index ecbaff7f..121e6210 100644 --- a/src/graph_spectrum_calc.js +++ b/src/graph_spectrum_calc.js @@ -118,7 +118,8 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi let maxNoise = 0; // Stores the maximum amplitude of the fft over all chunks // Matrix where each row represents a bin of vs values, and the columns are amplitudes at frequencies - const matrixFftOutput = new Array(NUM_VS_BINS).fill(null).map(() => new Float64Array(fftChunkLength * 2)); + const magnitudeLength = Math.floor(fftChunkLength / 2); + const matrixFftOutput = new Array(NUM_VS_BINS).fill(null).map(() => new Float64Array(magnitudeLength)); const numberSamples = new Uint32Array(NUM_VS_BINS); // Number of samples in each vs value, used to average them later. @@ -135,12 +136,15 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi fft.simple(fftOutput, fftInput, 'real'); - fftOutput = fftOutput.slice(0, fftChunkLength); - // Use only abs values - for (let i = 0; i < fftChunkLength; i++) { - fftOutput[i] = Math.abs(fftOutput[i]); - maxNoise = Math.max(fftOutput[i], maxNoise); + const magnitudes = new Float64Array(magnitudeLength); + + // Compute magnitude + for (let i = 0; i < magnitudeLength; i++) { + const re = fftOutput[2 * i], + im = fftOutput[2 * i + 1]; + magnitudes[i] = Math.hypot(re, im); + maxNoise = Math.max(magnitudes[i], maxNoise); } // calculate a bin index and put the fft value in that bin for each field (e.g. eRPM[0], eRPM[1]..) sepparately @@ -158,8 +162,8 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi numberSamples[vsBinIndex]++; // add the output from the fft to the row given by the vs value bin index - for (let i = 0; i < fftOutput.length; i++) { - matrixFftOutput[vsBinIndex][i] += fftOutput[i]; + for (let i = 0; i < magnitudeLength; i++) { + matrixFftOutput[vsBinIndex][i] += magnitudes[i]; } } } @@ -180,7 +184,7 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi const fftData = { fieldIndex : this._dataBuffer.fieldIndex, fieldName : this._dataBuffer.fieldName, - fftLength : fftChunkLength, + fftLength : magnitudeLength, fftOutput : matrixFftOutput, maxNoise : maxNoise, blackBoxRate : this._blackBoxRate, From 3838cf56361d44a821da3bbe324712eb73b01c4e Mon Sep 17 00:00:00 2001 From: demvlad Date: Tue, 6 May 2025 11:52:38 +0300 Subject: [PATCH 4/5] Added round for data length computing --- src/graph_spectrum_calc.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graph_spectrum_calc.js b/src/graph_spectrum_calc.js index 121e6210..1ad0bc13 100644 --- a/src/graph_spectrum_calc.js +++ b/src/graph_spectrum_calc.js @@ -113,7 +113,7 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi // We divide it into FREQ_VS_THR_CHUNK_TIME_MS FFT chunks, we calculate the average throttle // for each chunk. We use a moving window to get more chunks available. - const fftChunkLength = this._blackBoxRate * FREQ_VS_THR_CHUNK_TIME_MS / 1000; + const fftChunkLength = Math.round(this._blackBoxRate * FREQ_VS_THR_CHUNK_TIME_MS / 1000); const fftChunkWindow = Math.round(fftChunkLength / FREQ_VS_THR_WINDOW_DIVISOR); let maxNoise = 0; // Stores the maximum amplitude of the fft over all chunks @@ -156,9 +156,9 @@ GraphSpectrumCalc._dataLoadFrequencyVsX = function(vsFieldNames, minValue = Infi } // Translate the average vs value to a bin index const avgVsValue = sumVsValues / fftChunkLength; - let vsBinIndex = Math.floor(NUM_VS_BINS * (avgVsValue - flightSamples.minValue) / (flightSamples.maxValue - flightSamples.minValue)); + let vsBinIndex = Math.round(NUM_VS_BINS * (avgVsValue - flightSamples.minValue) / (flightSamples.maxValue - flightSamples.minValue)); // ensure that avgVsValue == flightSamples.maxValue does not result in an out of bounds access - if (vsBinIndex === NUM_VS_BINS) { vsBinIndex = NUM_VS_BINS - 1; } + if (vsBinIndex >= NUM_VS_BINS) { vsBinIndex = NUM_VS_BINS - 1; } numberSamples[vsBinIndex]++; // add the output from the fft to the row given by the vs value bin index @@ -349,7 +349,7 @@ GraphSpectrumCalc._getFlightSamplesFreqVsX = function(vsFieldNames, minValue = I } // Calculate min max average of the VS values in the chunk what will used by spectrum data definition - const fftChunkLength = this._blackBoxRate * FREQ_VS_THR_CHUNK_TIME_MS / 1000; + const fftChunkLength = Math.round(this._blackBoxRate * FREQ_VS_THR_CHUNK_TIME_MS / 1000); const fftChunkWindow = Math.round(fftChunkLength / FREQ_VS_THR_WINDOW_DIVISOR); for (let fftChunkIndex = 0; fftChunkIndex + fftChunkLength < samplesCount; fftChunkIndex += fftChunkWindow) { for (const vsValueArray of vsValues) { From fa3129faada21cc5857efd233e1612e5ffbd05ed Mon Sep 17 00:00:00 2001 From: demvlad Date: Tue, 6 May 2025 13:51:57 +0300 Subject: [PATCH 5/5] SCALE_HEATMAP value is decreased from 1.3 to 1.1, to get same brightness as before --- src/graph_spectrum_plot.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graph_spectrum_plot.js b/src/graph_spectrum_plot.js index 1a916036..113fd18b 100644 --- a/src/graph_spectrum_plot.js +++ b/src/graph_spectrum_plot.js @@ -382,7 +382,8 @@ GraphSpectrumPlot._drawFrequencyVsXGraph = function (canvasCtx) { GraphSpectrumPlot._drawHeatMap = function () { const THROTTLE_VALUES_SIZE = 100; - const SCALE_HEATMAP = 1.3; // Value decided after some tests to be similar to the scale of frequency graph + //The magnitude is greate then seperete Re or Im value up to 1.4=sqrt(2). Therefore the SCALE_HEATMAP is decreased from 1.3 to 1.1 + const SCALE_HEATMAP = 1.1; // Value decided after some tests to be similar to the scale of frequency graph. // This value will be maximum color const heatMapCanvas = document.createElement("canvas"); @@ -395,7 +396,7 @@ GraphSpectrumPlot._drawHeatMap = function () { const fftColorScale = 100 / (this._zoomY * SCALE_HEATMAP); // Loop for throttle - for (let j = 0; j < 100; j++) { + for (let j = 0; j < THROTTLE_VALUES_SIZE; j++) { // Loop for frequency for (let i = 0; i < this._fftData.fftLength; i++) { const valuePlot = Math.round(