Skip to content

Commit 02e5a39

Browse files
authored
Using of number input field for PSD segments length (#867)
* Using of number input field for PSD segments lengthpower at 2 value * removed useless variable * Code improvement: Use Number.parseInt * Resolved issue computing PSD for full file length segment size * Added debounce in analyserSegmentLengthPowerAt2.on handler * Added checking maximalSegmentsLength values before log2
1 parent d82f4e4 commit 02e5a39

File tree

4 files changed

+98
-35
lines changed

4 files changed

+98
-35
lines changed

index.html

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,21 +505,28 @@ <h4>Workspace</h4>
505505
/>
506506
<input id="analyserZoomY" class="onlyFullScreen" type="range" name="analyserZoomY" value="100" min="10" max="1000" step="10" list="analyserZoomYTicks"
507507
/>
508+
<input id="analyserSegmentLengthPowerAt2" class="onlyFullScreen" type="number" name="analyserSegmentLengthPowerAt2" value="9" min="6" max="20" step="1"
509+
/>
510+
<label id="analyserSegmentLengthPowerAt2Label" name="analyserSegmentLengthPowerAt2Label" class="onlyFullScreen" >
511+
Segment&nbsp;length&nbsp;<br>power&nbsp;at&nbsp;2:
512+
</label>
508513
<input id="analyserLowLevelPSD" class="onlyFullScreen" type="number" name="analyserLowLevelPSD" value="-40" min="-40" max="10" step="5"
509514
/>
515+
<label id="analyserLowLevelPSDLabel" name="analyserLowLevelPSDLabel" class="onlyFullScreen" >
516+
Limit&nbsp;dBm
517+
</label>
510518
<input id="analyserMaxPSD" class="onlyFullScreen" type="number" name="analyserMaxPSD" value="10" min="-35" max="100" step="5"
511519
/>
512-
<input id="analyserMinPSD" class="onlyFullScreen" type="number" name="analyserMinPSD" value="-40" min="-100" max="5" step="5"
513-
/>
514520
<label id="analyserMaxPSDLabel" name="analyserMaxPSDLabel" class="onlyFullScreen" >
515521
Max&nbsp;dBm
516522
</label>
523+
<input id="analyserMinPSD" class="onlyFullScreen" type="number" name="analyserMinPSD" value="-40" min="-100" max="5" step="5"
524+
/>
517525
<label id="analyserMinPSDLabel" name="analyserMinPSDLabel" class="onlyFullScreen" >
518526
Min&nbsp;dBm
519527
</label>
520-
<label id="analyserLowLevelPSDLabel" name="analyserLowLevelPSDLabel" class="onlyFullScreen" >
521-
Limit&nbsp;dBm
522-
</label>
528+
529+
523530

524531
<datalist id="analyserZoomXTicks">
525532
<option>100</option>

src/css/main.css

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,9 @@ html.has-analyser-fullscreen.has-analyser
692692
.analyser input#analyserMaxPSD::-webkit-inner-spin-button,
693693
.analyser input#analyserMaxPSD::-webkit-outer-spin-button,
694694
.analyser input#analyserLowLevelPSD::-webkit-inner-spin-button,
695-
.analyser input#analyserLowLevelPSD::-webkit-outer-spin-button {
695+
.analyser input#analyserLowLevelPSD::-webkit-outer-spin-button ,
696+
.analyser input#analyserSegmentLengthPowerAt2::-webkit-inner-spin-button,
697+
.analyser input#analyserSegmentLengthPowerAt2::-webkit-outer-spin-button {
696698
-webkit-appearance: auto !important;
697699
-moz-appearance: auto !important;
698700
appearance: auto !important;
@@ -708,42 +710,58 @@ html.has-analyser-fullscreen.has-analyser
708710
top: 30px;
709711
}
710712

713+
.analyser label#analyserMaxPSDLabel {
714+
position:absolute;
715+
color:gray;
716+
left: 0px;
717+
top: 30px;
718+
font-size: 12px;
719+
}
720+
711721
.analyser input#analyserMinPSD {
712722
width: 50px;
713723
height: 20px;
714724
left: 0px;
715725
top: 55px;
716726
}
717727

728+
.analyser label#analyserMinPSDLabel {
729+
position:absolute;
730+
color:gray;
731+
left: 0px;
732+
top: 55px;
733+
font-size: 12px;
734+
}
735+
718736
.analyser input#analyserLowLevelPSD {
719737
width: 50px;
720738
height: 20px;
721739
left: 0px;
722740
top: 80px;
723741
}
724742

725-
.analyser label#analyserMaxPSDLabel {
743+
.analyser label#analyserLowLevelPSDLabel {
726744
position:absolute;
727745
color:gray;
728746
left: 0px;
729-
top: 30px;
747+
top: 80px;
730748
font-size: 12px;
731749
}
732750

733-
.analyser label#analyserMinPSDLabel {
734-
position:absolute;
735-
color:gray;
751+
.analyser input#analyserSegmentLengthPowerAt2 {
752+
width: 42px;
753+
height: 20px;
736754
left: 0px;
737-
top: 55px;
738-
font-size: 12px;
755+
top: 42px;
739756
}
740757

741-
.analyser label#analyserLowLevelPSDLabel {
758+
.analyser label#analyserSegmentLengthPowerAt2Label {
742759
position:absolute;
743760
color:gray;
761+
width: 50px;
762+
height: 20px;
744763
left: 0px;
745-
top: 80px;
746-
font-size: 12px;
764+
top: 20px;
747765
}
748766

749767
.analyser input.onlyFullScreen {

src/graph_spectrum.js

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
1717
const that = this,
1818
prefs = new PrefStorage(),
1919
DEFAULT_PSD_HEATMAP_MIN = -40,
20-
DEFAULT_PSD_HEATMAP_MAX = 10;
20+
DEFAULT_PSD_HEATMAP_MAX = 10,
21+
DEFAULT_PSD_SEGMENT_LENGTH_POWER = 9;
2122
let analyserZoomX = 1.0 /* 100% */,
2223
analyserZoomY = 1.0 /* 100% */,
2324
dataReload = false,
@@ -36,6 +37,7 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
3637
const analyserMinPSD = $("#analyserMinPSD");
3738
const analyserMaxPSD = $("#analyserMaxPSD");
3839
const analyserLowLevelPSD = $("#analyserLowLevelPSD");
40+
const analyserSegmentLengthPowerAt2 = $("#analyserSegmentLengthPowerAt2");
3941

4042

4143
const spectrumToolbarElem = $("#spectrumToolbar");
@@ -124,6 +126,12 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
124126
$("#analyserLowLevelPSDLabel", parentElem).css({
125127
left: `${newSize.width - 155}px`,
126128
});
129+
$("#analyserSegmentLengthPowerAt2", parentElem).css({
130+
left: `${newSize.width - 57}px`,
131+
});
132+
$("#analyserSegmentLengthPowerAt2Label", parentElem).css({
133+
left: `${newSize.width - 135}px`,
134+
});
127135
};
128136

129137
const dataLoad = function (fieldIndex, curve, fieldName) {
@@ -154,6 +162,9 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
154162

155163
case SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY:
156164
fftData = GraphSpectrumCalc.dataLoadPSD(analyserZoomY);
165+
if (fftData.maximalSegmentsLength > 0) {
166+
analyserSegmentLengthPowerAt2.prop("max", Math.ceil(Math.log2(fftData.maximalSegmentsLength)));
167+
}
157168
break;
158169

159170
case SPECTRUM_TYPE.FREQUENCY:
@@ -241,11 +252,6 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
241252
debounce(100, function () {
242253
analyserZoomY = 1 / (analyserZoomYElem.val() / 100);
243254
GraphSpectrumPlot.setZoom(analyserZoomX, analyserZoomY);
244-
// Recalculate PSD with updated samples per segment count
245-
if (userSettings.spectrumType == SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY) {
246-
dataLoad();
247-
GraphSpectrumPlot.setData(fftData, userSettings.spectrumType);
248-
}
249255
that.refresh();
250256
}),
251257
)
@@ -325,6 +331,25 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
325331
})
326332
.val(analyserMinPSD.val());
327333

334+
GraphSpectrumCalc.setPointsPerSegmentPSD(2 ** DEFAULT_PSD_SEGMENT_LENGTH_POWER);
335+
analyserSegmentLengthPowerAt2
336+
.on(
337+
"input",
338+
debounce(100, function () {
339+
// Recalculate PSD with updated samples per segment count
340+
GraphSpectrumCalc.setPointsPerSegmentPSD(2 ** Number.parseInt($(this).val()));
341+
dataLoad();
342+
GraphSpectrumPlot.setData(fftData, userSettings.spectrumType);
343+
that.refresh();
344+
}),
345+
)
346+
.dblclick(function (e) {
347+
if (e.ctrlKey) {
348+
$(this).val(DEFAULT_PSD_SEGMENT_LENGTH_POWER).trigger("input");
349+
}
350+
})
351+
.val(DEFAULT_PSD_SEGMENT_LENGTH_POWER);
352+
328353
// Spectrum type to show
329354
userSettings.spectrumType =
330355
userSettings.spectrumType || SPECTRUM_TYPE.FREQUENCY;
@@ -349,10 +374,16 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
349374
const psdHeatMapSelected =
350375
optionSelected === SPECTRUM_TYPE.PSD_VS_THROTTLE ||
351376
optionSelected === SPECTRUM_TYPE.PSD_VS_RPM;
377+
const psdCurveSelected =
378+
optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
352379
overdrawSpectrumTypeElem.toggle(!pidErrorVsSetpointSelected);
353380
analyserZoomYElem.toggleClass(
354381
"onlyFullScreenException",
355-
pidErrorVsSetpointSelected || psdHeatMapSelected,
382+
pidErrorVsSetpointSelected || psdHeatMapSelected || psdCurveSelected,
383+
);
384+
analyserSegmentLengthPowerAt2.toggleClass(
385+
"onlyFullScreenException",
386+
!psdCurveSelected,
356387
);
357388
analyserLowLevelPSD.toggleClass(
358389
"onlyFullScreenException",
@@ -378,6 +409,10 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
378409
"onlyFullScreenException",
379410
!psdHeatMapSelected,
380411
);
412+
$("#analyserSegmentLengthPowerAt2Label").toggleClass(
413+
"onlyFullScreenException",
414+
!psdCurveSelected,
415+
);
381416

382417

383418
const showSpectrumsComparisonPanel = optionSelected === SPECTRUM_TYPE.FREQUENCY || optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;

src/graph_spectrum_calc.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const GraphSpectrumCalc = {
3535
_flightLog : null,
3636
_sysConfig : null,
3737
_motorPoles : null,
38+
_pointsPerSegmentPSD : 64,
3839
};
3940

4041
GraphSpectrumCalc.initialize = function(flightLog, sysConfig) {
@@ -112,20 +113,21 @@ GraphSpectrumCalc.dataLoadFrequency = function() {
112113
return fftData;
113114
};
114115

116+
GraphSpectrumCalc.setPointsPerSegmentPSD = function(pointsCount) {
117+
this._pointsPerSegmentPSD = pointsCount;
118+
};
119+
115120
GraphSpectrumCalc.dataLoadPSD = function(analyserZoomY) {
116121
const flightSamples = this._getFlightSamplesFreq(false);
117-
const multiplier = Math.floor(1 / analyserZoomY); // 0. ... 10
118-
let pointsPerSegment = 2 ** (8 + multiplier); //256, 512, 1024 ...
119-
120-
let overlapCount;
121-
if (pointsPerSegment > flightSamples.samples.length) {
122-
pointsPerSegment = flightSamples.samples.length; // Use actual sample length. It will transform to power at 2 value inside the _psd() - fft_segmented
123-
overlapCount = 0;
124-
} else {
125-
overlapCount = pointsPerSegment / 2;
126-
}
127-
128-
const psd = this._psd(flightSamples.samples, pointsPerSegment, overlapCount);
122+
const totalCount = flightSamples.count; // actual samples, not padded length
123+
let pointsPerSegment = Math.min(this._pointsPerSegmentPSD, totalCount);
124+
// Non-overlapping when single full-segment; otherwise 75% overlap
125+
const overlapCount = (pointsPerSegment === totalCount) ? 0 : Math.floor(pointsPerSegment * 3 / 4);
126+
// Avoid bias from zero-padded tail
127+
const samplesForPsd = (flightSamples.samples.length === totalCount)
128+
? flightSamples.samples
129+
: flightSamples.samples.slice(0, totalCount);
130+
const psd = this._psd(samplesForPsd, pointsPerSegment, overlapCount);
129131

130132
const psdData = {
131133
fieldIndex : this._dataBuffer.fieldIndex,
@@ -136,6 +138,7 @@ GraphSpectrumCalc.dataLoadPSD = function(analyserZoomY) {
136138
minimum: psd.min,
137139
maximum: psd.max,
138140
maxNoiseFrequency: psd.maxNoiseFrequency,
141+
maximalSegmentsLength: this.getNearPower2Value(totalCount),
139142
};
140143
return psdData;
141144
};

0 commit comments

Comments
 (0)