@sailingrotevista/rotevista-dash 7.0.32 → 7.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.js +53 -54
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -805,65 +805,64 @@ function startDisplayLoop() {
|
|
|
805
805
|
}
|
|
806
806
|
|
|
807
807
|
// --- SLOW TIER (Salvataggio stato ogni 10 secondi) ---
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
808
|
+
if (lastAvgUIUpdate++ % 10 === 0) {
|
|
809
|
+
saveDashboardState();
|
|
810
|
+
}
|
|
811
811
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
812
|
+
// AGGIORNAMENTO FLUIDO MEDIE UI (Esecuzione a 1Hz costante ad ogni secondo)
|
|
813
|
+
const baseThreshold = CONFIG.averaging.stabilityThreshold || 0.95;
|
|
814
|
+
const breakout = CONFIG.averaging.stabilityBreakout || 15;
|
|
815
|
+
|
|
816
|
+
// CALCOLO DIFFERENZIALE: Tolleranza del vento proporzionale alla sensibilità di base
|
|
817
|
+
const windThreshold = Math.max(0.60, baseThreshold - 0.13);
|
|
818
818
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}
|
|
835
|
-
safeSetText(ui.tackLabel, currentTackLabelMode);
|
|
819
|
+
let hObj = getCircularAverageFromBuffer(store.longBuf.hdg, CONFIG.averaging.longWindow * 2, false, now, baseThreshold, breakout);
|
|
820
|
+
let cObj = getCircularAverageFromBuffer(store.longBuf.cog, CONFIG.averaging.longWindow, false, now, baseThreshold, breakout);
|
|
821
|
+
|
|
822
|
+
// Applichiamo la soglia differenziale ottimizzata per i tre dati legati al vento
|
|
823
|
+
let awObj = getCircularAverageFromBuffer(store.longBuf.awa, CONFIG.averaging.longWindow, true, now, windThreshold, breakout);
|
|
824
|
+
let twObj = getCircularAverageFromBuffer(store.longBuf.twa, CONFIG.averaging.longWindow, true, now, windThreshold, breakout);
|
|
825
|
+
let twdObj = getCircularAverageFromBuffer(store.longBuf.twd, CONFIG.averaging.longWindow, false, now, windThreshold, breakout);
|
|
826
|
+
|
|
827
|
+
// --- GESTIONE DINAMICA ETICHETTA TACK/GYBE CON ISTERESI DI 10 GRADI ---
|
|
828
|
+
if (ui.tackLabel) {
|
|
829
|
+
const absTwa = Math.abs(radToDeg(store.raw["environment.wind.angleTrueWater"] || 0));
|
|
830
|
+
if (currentTackLabelMode === 'TACK' && absTwa > 95) {
|
|
831
|
+
currentTackLabelMode = 'GYBE';
|
|
832
|
+
} else if (currentTackLabelMode === 'GYBE' && absTwa < 85) {
|
|
833
|
+
currentTackLabelMode = 'TACK';
|
|
836
834
|
}
|
|
835
|
+
safeSetText(ui.tackLabel, currentTackLabelMode);
|
|
836
|
+
}
|
|
837
837
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
838
|
+
upUI(ui.hdg, hObj, store.raw["navigation.headingTrue"], true);
|
|
839
|
+
upUI(ui.cog, cObj, store.raw["navigation.courseOverGroundTrue"], true);
|
|
840
|
+
upUI(ui.awaAvg, awObj, store.raw["environment.wind.angleApparent"], false);
|
|
841
|
+
upUI(ui.twaAvg, twObj, store.raw["environment.wind.angleTrueWater"], false);
|
|
842
|
+
upUI(ui.twdAvg, twdObj, store.raw["environment.wind.directionTrue"], true);
|
|
843
|
+
|
|
844
|
+
if (hObj && twdObj) {
|
|
845
|
+
const reflectAngle = (targetRad, axisRad) => {
|
|
846
|
+
const dS = Math.sin(axisRad - targetRad);
|
|
847
|
+
const dC = Math.cos(axisRad - targetRad);
|
|
848
|
+
return Math.atan2(Math.sin(axisRad) * dC + Math.cos(axisRad) * dS, Math.cos(axisRad) * dC - Math.sin(axisRad) * dS);
|
|
849
|
+
};
|
|
850
|
+
const unstableH = !hObj.stable || !twdObj.stable || hObj.dev > CONFIG.averaging.stabilityBreakout;
|
|
851
|
+
if (!isNavigating) ui.tackHdg.innerHTML = "---°";
|
|
852
|
+
else if (unstableH) { ui.tackHdg.innerHTML = "---°"; ui.tackHdg.classList.add('unstable-data'); }
|
|
853
|
+
else {
|
|
854
|
+
const rH = (radToDeg(reflectAngle(hObj.val, twdObj.val)) + 360) % 360;
|
|
855
|
+
ui.tackHdg.innerHTML = `${Math.round(rH).toString().padStart(3, '0')}°`;
|
|
856
|
+
ui.tackHdg.classList.remove('unstable-data');
|
|
857
|
+
}
|
|
858
|
+
if (cObj) {
|
|
859
|
+
const unstableC = !cObj.stable || !twdObj.stable || cObj.dev > CONFIG.averaging.stabilityBreakout;
|
|
860
|
+
if (!isNavigating) ui.tackCog.innerHTML = "---°";
|
|
861
|
+
else if (unstableC) { ui.tackCog.innerHTML = "---°"; ui.tackCog.classList.add('unstable-data'); }
|
|
853
862
|
else {
|
|
854
|
-
const
|
|
855
|
-
ui.
|
|
856
|
-
ui.
|
|
857
|
-
}
|
|
858
|
-
if (cObj) {
|
|
859
|
-
const unstableC = !cObj.stable || !twdObj.stable || cObj.dev > CONFIG.averaging.stabilityBreakout;
|
|
860
|
-
if (!isNavigating) ui.tackCog.innerHTML = "---°";
|
|
861
|
-
else if (unstableC) { ui.tackCog.innerHTML = "---°"; ui.tackCog.classList.add('unstable-data'); }
|
|
862
|
-
else {
|
|
863
|
-
const rC = (radToDeg(reflectAngle(cObj.val, twdObj.val)) + 360) % 360;
|
|
864
|
-
ui.tackCog.innerHTML = `${Math.round(rC).toString().padStart(3, '0')}°`;
|
|
865
|
-
ui.tackCog.classList.remove('unstable-data');
|
|
866
|
-
}
|
|
863
|
+
const rC = (radToDeg(reflectAngle(cObj.val, twdObj.val)) + 360) % 360;
|
|
864
|
+
ui.tackCog.innerHTML = `${Math.round(rC).toString().padStart(3, '0')}°`;
|
|
865
|
+
ui.tackCog.classList.remove('unstable-data');
|
|
867
866
|
}
|
|
868
867
|
}
|
|
869
868
|
}
|