@sailingrotevista/rotevista-dash 7.0.39 → 7.0.41
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 +5 -2
- package/charts.js +1 -17
- package/gauge.js +28 -20
- package/package.json +1 -1
- package/utils.js +7 -3
package/app.js
CHANGED
|
@@ -705,11 +705,14 @@ function startDisplayLoop() {
|
|
|
705
705
|
"navigation.speedThroughWater": ui.stw, "navigation.speedOverGround": ui.sog,
|
|
706
706
|
"navigation.headingTrue": ui.hdg, "navigation.courseOverGroundTrue": ui.cog,
|
|
707
707
|
"environment.wind.speedApparent": ui.awsSvg, "environment.depth.belowTransducer": ui.depth,
|
|
708
|
-
"environment.wind.speedTrue": ui.tws
|
|
708
|
+
"environment.wind.speedTrue": ui.tws,
|
|
709
|
+
"environment.wind.angleApparent": ui.awaAvg,
|
|
710
|
+
"environment.wind.angleTrueWater": ui.twaAvg,
|
|
711
|
+
"environment.wind.directionTrue": ui.twdAvg
|
|
709
712
|
};
|
|
710
713
|
for (let p in watch) {
|
|
711
714
|
if (!store.timestamps[p] || (now - store.timestamps[p] > TIMEOUT_MS)) {
|
|
712
|
-
safeSetText(watch[p], "---");
|
|
715
|
+
if (watch[p]) safeSetText(watch[p], "---");
|
|
713
716
|
delete store.raw[p];
|
|
714
717
|
|
|
715
718
|
// Forza lo scorrimento dei dati fuori dallo schermo per i sensori in timeout
|
package/charts.js
CHANGED
|
@@ -90,29 +90,13 @@ function calculateScale(type, data, mode) {
|
|
|
90
90
|
|
|
91
91
|
if (mode === 'hercules') {
|
|
92
92
|
const roundStep = s.hercSpan;
|
|
93
|
+
// Finestra di calcolo ad alta risoluzione: ancorata rigorosamente all'ultimo terzo dei dati
|
|
93
94
|
const oneThirdCount = Math.max(1, Math.floor(data.length / 3));
|
|
94
95
|
const recentThirdData = data.slice(-oneThirdCount);
|
|
95
96
|
|
|
96
97
|
let localMin = Math.min(...recentThirdData);
|
|
97
98
|
let localMax = Math.max(...recentThirdData);
|
|
98
99
|
|
|
99
|
-
// SMART MOTORING DETECTION (Specifica per i grafici di velocità: STW, SOG, VMG)
|
|
100
|
-
const isSpeedType = (type === 'stw' || type === 'sog' || type === 'vmg');
|
|
101
|
-
if (isSpeedType && data.length > oneThirdCount) {
|
|
102
|
-
const olderData = data.slice(0, data.length - oneThirdCount);
|
|
103
|
-
const olderMin = Math.min(...olderData);
|
|
104
|
-
const olderMax = Math.max(...olderData);
|
|
105
|
-
const olderRange = olderMax - olderMin; // Variazione nello storico passato
|
|
106
|
-
|
|
107
|
-
// Se lo storico passato non era piatto (range > 0.2 nodi) oppure eravamo fermi/all'ancora (< 1.5 nodi),
|
|
108
|
-
// significa che il passato è rilevante per il trend. Includiamo il passato nel calcolo della scala Y.
|
|
109
|
-
// Se invece era piatto (motore), lo ignoriamo per zoomare subito sulla vela attuale.
|
|
110
|
-
if (olderRange > 0.2 || olderMin < 0.77) {
|
|
111
|
-
localMin = Math.min(localMin, olderMin);
|
|
112
|
-
localMax = Math.max(localMax, olderMax);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
100
|
let targetMin = Math.max(0, Math.floor(localMin / roundStep) * roundStep);
|
|
117
101
|
let targetMax = Math.ceil(localMax / roundStep) * roundStep;
|
|
118
102
|
|
package/gauge.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ==========================================================================
|
|
5
5
|
* Gestisce l'aggiornamento grafico dei puntatori analogici (AWA, TWA),
|
|
6
6
|
* dello scarroccio (Leeway), della rotta (Track) e dei trend della bussola.
|
|
7
|
-
* file gauge
|
|
7
|
+
* file gauge.js
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// 1. VARIABILI DI STATO DELLE ROTAZIONI (Estratte da app.js)
|
|
@@ -54,29 +54,37 @@ function updateCentralGauge(store, ui, now, isNavigating, sogKts, stwKts, rawAws
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// B. Rotazione dei puntatori analogici di AWA (Apparent) e TWA (True)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
// B. Rotazione dei puntatori analogici di AWA (Apparent) e TWA (True) con passaggio di timestamp "now"
|
|
58
|
+
const smAwa = getCircularAverageFromBuffer(store.smoothBuf.awa, 2000, true, now);
|
|
59
|
+
const smTwa = getCircularAverageFromBuffer(store.smoothBuf.twa, 2000, true, now);
|
|
60
|
+
if (smAwa) ui.awa.setAttribute('transform', `rotate(${curAwaRot = getShortestRotation(curAwaRot, radToDeg(smAwa.val))}, 200, 200)`);
|
|
61
|
+
if (smTwa) ui.twa.setAttribute('transform', `rotate(${curTwaRot = getShortestRotation(curTwaRot, radToDeg(smTwa.val))}, 200, 200)`);
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
// C. Calcolo dello Scarroccio (Leeway) e orientamento del vettore Track
|
|
64
|
+
if (store.raw["navigation.courseOverGroundTrue"] !== undefined && store.raw["navigation.headingTrue"] !== undefined) {
|
|
65
|
+
let driftDeg = radToDeg((store.raw["navigation.courseOverGroundTrue"] - store.raw["navigation.headingTrue"] + Math.PI * 3) % (2 * Math.PI) - Math.PI);
|
|
66
|
+
smoothedLeeway = (sogKts < CONFIG.averaging.minSpeed) ? 0 : (smoothedLeeway * 0.9) + (driftDeg * 0.1);
|
|
67
|
+
curTrackRot = getShortestRotation(curTrackRot, smoothedLeeway);
|
|
68
|
+
ui.track.setAttribute('transform', `rotate(${curTrackRot}, 200, 200)`);
|
|
69
|
+
ui.leewayVal.style.color = (Math.abs(sogKts - stwKts) > 0.5 && Math.abs(smoothedLeeway) > 7) ? "#ff9800" : "";
|
|
70
|
+
updateLeewayDisplay(Math.max(-20, Math.min(20, smoothedLeeway)));
|
|
71
|
+
}
|
|
72
72
|
|
|
73
73
|
// D. Orientamento delle icone della barca e del vento nel Mini-Compass (TWD)
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
// Sincronizzato con la media a 30s (longBuf) e fallback istantaneo su store.raw per allineamento al testo
|
|
75
|
+
const longWindow = CONFIG.averaging.longWindow || 30000;
|
|
76
|
+
const smHdgIcons = getCircularAverageFromBuffer(store.longBuf.hdg, longWindow * 2, false, now);
|
|
77
|
+
const smTwdIcons = getCircularAverageFromBuffer(store.longBuf.twd, longWindow, false, now);
|
|
78
|
+
|
|
79
|
+
const twdAngleRad = smTwdIcons ? smTwdIcons.val : store.raw["environment.wind.directionTrue"];
|
|
80
|
+
if (twdAngleRad !== undefined && twdAngleRad !== null) {
|
|
81
|
+
curWindCompassRot = getShortestRotation(curWindCompassRot, radToDeg(twdAngleRad));
|
|
78
82
|
ui.twdArrow.setAttribute('transform', `rotate(${curWindCompassRot}, 20, 20)`);
|
|
79
|
-
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const hdgAngleRad = smHdgIcons ? smHdgIcons.val : store.raw["navigation.headingTrue"];
|
|
86
|
+
if (hdgAngleRad !== undefined && hdgAngleRad !== null) {
|
|
87
|
+
curBoatCompassRot = getShortestRotation(curBoatCompassRot, radToDeg(hdgAngleRad));
|
|
80
88
|
ui.twdBoat.setAttribute('transform', `rotate(${curBoatCompassRot}, 20, 20)`);
|
|
81
89
|
}
|
|
82
90
|
}
|
package/package.json
CHANGED
package/utils.js
CHANGED
|
@@ -36,8 +36,11 @@ function getCircularAverageFromBuffer(bufferArray, windowMs, signed = false, now
|
|
|
36
36
|
const len = bufferArray.length;
|
|
37
37
|
if (len === 0) return null;
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
const
|
|
39
|
+
const currentTime = now || Date.now();
|
|
40
|
+
const newestSampleTime = bufferArray[len - 1].time;
|
|
41
|
+
|
|
42
|
+
// Se l'ultimo pacchetto registrato nel buffer ha più di 15 secondi di silenzio, il sensore è offline
|
|
43
|
+
if ((currentTime - newestSampleTime) > 15000) return null;
|
|
41
44
|
|
|
42
45
|
let sSin = 0, sCos = 0, count = 0;
|
|
43
46
|
let newestTime = 0, oldestTime = 0;
|
|
@@ -53,7 +56,8 @@ function getCircularAverageFromBuffer(bufferArray, windowMs, signed = false, now
|
|
|
53
56
|
|
|
54
57
|
for (let i = len - 1; i >= 0; i--) {
|
|
55
58
|
const item = bufferArray[i];
|
|
56
|
-
|
|
59
|
+
// Decadimento temporale reale ancorato sull'orologio corrente
|
|
60
|
+
if ((currentTime - item.time) > windowMs) break;
|
|
57
61
|
|
|
58
62
|
let diffRad = Math.atan2(Math.sin(item.val - pilotRad), Math.cos(item.val - pilotRad));
|
|
59
63
|
let finalSin, finalCos;
|