speedandcurrent 1.7.0 → 1.7.1

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/README.md CHANGED
@@ -5,10 +5,11 @@ This SignalK plugin estimates **corrected speed through water**, **leeway**, and
5
5
 
6
6
  ## Quick Start
7
7
  1. Install / enable the plugin in the Signal K Server admin UI.
8
- 2. Specify the dimensions of the correction table in the plugin settings.
9
- 3. Enable the plugin.
10
- 4. Open the plugin's WebApp from the Signal K App list.
11
- 5. Watch the corrected speed, leeway, and current fields begin populating as data arrives. Initial stabilization may take some sailing at varying speeds and heel angles.
8
+ 2. Open the plugin webapp (Signal K: Apps → Speed and Current).
9
+ 3. Go to **Correction Table** and click **New** to create your first correction table (or use the default that was created for you).
10
+ 4. Start learning by enabling **Correction Table Learning** in the webapp.
11
+ 5. Once your correction table is filled enable **Boatspeed Estimation** in the webapp.
12
+ 6. Watch the corrected speed, leeway, and current fields begin populating as data arrives. Initial stabilization may take some sailing at varying speeds and heel angles.
12
13
 
13
14
  ## Requirements & Data Inputs
14
15
  The plugin automatically starts collecting and learning once enabled, but waits the first ~60 seconds before producing estimates to stabilize.
@@ -43,104 +44,125 @@ At the heart of the plugin is a correction table that provides a correction vect
43
44
  Every time the paddle wheel provides a measurement the plugin does two things. First it corrects boat speed and estimates leeway and current using the correction table. Second, using boat speed, ground speed and current estimation the correction table is updated. So the correction table is used and updated simultaneously.
44
45
 
45
46
  ## Configuration
46
- All settings are managed from the Signal K Server plugin configuration UI.
47
+ All settings are managed from the plugin webapp. The Signal K admin UI is not used for configuration.
47
48
 
48
49
  ### Core
49
50
  | Setting | Default | Description | When to Change |
50
51
  |---------|---------|-------------|----------------|
51
- | Estimate Boat Speed | false | Enables speed correction, leeway and current estimation. | Normally on. |
52
- | Update Correction Table | true | Learns / refines correction table. | Temporarily disable in abnormal conditions (heavy seas, abnormal current). |
53
- | Start with new table | false | Discards existing table and starts fresh. | Only if you want to start all over with correcting. |
52
+ | Estimate Boat Speed | Off | Enables speed correction, leeway and current estimation. | Turn on after creating a correction table. |
53
+ | Update Correction Table | On | Learns / refines correction table. | Temporarily disable in abnormal conditions (heavy seas, abnormal current). |
54
54
 
55
55
  ### Learning & Stability
56
56
  | Setting | Default | Description | Guidance |
57
57
  |---------|---------|-------------|----------|
58
58
  | Correction Table Stability | 7 | Higher = slower changes (more conservative). | Increase once table broadly populated; lower briefly if you think the sensor error has changed. |
59
- | Assume Current (experimental) | false | Learns table while assuming a current may be present. | Enable cautiously on tidal waters. |
59
+ | Assume Current (experimental) | Off | Learns table while assuming a current may be present. | Enable cautiously on tidal waters. |
60
+ | Show Statistics | Off | Displays σ (standard deviation) next to smoothed values. | Enable for debugging or to inspect signal quality. |
61
+
62
+ ### Smoother
63
+ Controls how raw sensor signals are smoothed before being fed into the correction and learning calculations. The smoother type and its parameter apply to heading, boat speed, ground speed, and attitude.
60
64
 
61
- ### Table Definition
62
65
  | Setting | Default | Description |
63
66
  |---------|---------|-------------|
64
- | Step size for speed | 1 kn | Speed increment for table rows. |
65
- | Maximum speed in table | 9 kn | Upper speed coverage. |
66
- | Step size for heel | 8° | Heel increment for table columns (positive & negative). |
67
- | Maximum heel in table | 32° | Max absolute heel covered (± value). |
67
+ | Smoother type | Moving average (window) | Moving average (window), Exponential (τ), or Kalman filter. |
68
+ | Window (s) | 5 s | (Moving average) Integration window in seconds. Minimum 2 s. |
69
+ | Time constant τ (s) | 3 s | (Exponential) Exponential decay time constant in seconds. Minimum 1 s. |
70
+ | Steady-state gain | 0.2 | (Kalman) Kalman gain at steady state. Range 0.01–0.99. Lower = smoother but slower. |
71
+
72
+ ### Table Dimensions
73
+ Table dimensions are set when creating or resizing a table via the webapp (New / Resize buttons). The parameters are:
74
+
75
+ | Parameter | Default | Description |
76
+ |-----------|---------|-------------|
77
+ | Name | — | Identifier used as the filename on disk. |
78
+ | Max speed (kn) | 9 kn | Upper speed coverage. |
79
+ | Speed step (kn) | 1 kn | Speed increment for table rows. |
80
+ | Max heel (°) | 32° | Max absolute heel covered (± value). |
81
+ | Heel step (°) | 8° | Heel increment for table columns (positive & negative). |
68
82
 
69
83
  ### Data Sources (optional overrides)
70
84
  | Setting | Description |
71
85
  |---------|-------------|
72
86
  | Heading Source | Force a specific source for navigation.headingTrue. |
73
87
  | Boat Speed Source | Force a specific source for navigation.speedThroughWater. |
74
- | Course over ground (COG Source) | Source for navigation.courseOverGroundTrue. |
75
88
  | Ground Speed Source (SOG Source) | Source for navigation.speedOverGround. |
76
89
  | Attitude Source | Source for navigation.attitude (roll/heel). |
77
90
 
78
- If there are multiple sources available for a single path, one should specify the preferred source for the plugin. Alternatively, one could set source priorities in the signalK server settings (under data sources).
91
+ Leave a source blank or set to *(any)* to accept values from all sources. If multiple sources exist for a path, you can also set source priorities in the Signal K Server settings (under data sources).
79
92
 
80
93
  ### Output Behavior
81
94
  | Setting | Default | Description | Notes |
82
95
  |---------|---------|-------------|-------|
83
- | Prevent duplication of boat speed | true | Overwrites navigation.speedThroughWater with corrected value. | Disable to compare raw vs corrected via distinct source attributes under same path. |
96
+ | Prevent duplication of boat speed | On | Overwrites navigation.speedThroughWater with corrected value. | Disable to compare raw vs corrected via distinct source attributes under the same path. |
97
+ | SOG fallback | Off | Copy navigation.speedOverGround (GPS) to navigation.speedThroughWater (Paddle wheel) if paddle wheel malfunction is detected. | SOG fallback activates when navigation.speedThroughWater = 0 and navigation.speedOverGround > treshold.|
84
98
 
85
99
  ### Tips
86
- 1. Be patient with the correction table. Its corrections will improve over time.
100
+ 1. Be patient with the correction table. Its corrections will improve over time.
87
101
  2. Once corrections stabilize, raise Stability to lock in values.
88
102
  3. Freeze learning (disable Update Correction Table) before performance-sensitive events (e.g., racing) or in unstable conditions (waves, currents).
89
103
  4. After paddle wheel cleaning or if fouling suspected: temporarily LOWER Stability (e.g., from 7 → 5) to let corrections adapt, then raise again; do not rebuild unless the grid itself must change.
90
104
  5. The plugin will always estimate currents when Estimate boat speed is enabled. Even when Assume currents is disabled, as this setting is only used in updating the correction table.
91
105
 
92
106
  ## Persistence & Data Storage
93
- The correction table is persisted inside the plugin configuration (saved approximately every 5 seconds while learning). It is reloaded automatically on restart.
107
+ Each correction table is saved as a `.json` file in Signal K's plugin data directory (typically `~/.signalk/plugin-config-data/speedandcurrent/`). The active table name is stored in the plugin options and reloaded automatically on restart. While learning is active, the table is written to disk approximately every 5 seconds.
94
108
 
95
109
  Safety & backup:
96
- - If you have a well-populated table, consider copying the plugin configuration JSON (via server backup) before major changes.
110
+ - Tables can be copied to a new name with the **Copy** button before experimenting.
111
+ - The data directory can be backed up directly; each table is a self-contained `.json` file.
97
112
 
98
113
  ## Experimental Note
99
- The "Assume Current" option is experimental. It works best on a stable correction table as it takes time for the plugin to properly distinguish currents from paddle wheel eerors.
114
+ The "Assume Current" option is experimental. It works best on a stable correction table as it takes time for the plugin to properly distinguish currents from paddle wheel errors.
100
115
 
101
116
  ## WebApp Usage Guide
102
117
  Open via Signal K Server: Apps → Speed and current.
103
118
 
104
- ### Layout & Elements
105
- | Element | What You See | Notes |
106
- |---------|--------------|-------|
107
- | Graphical vector panel | Heading, raw & corrected boat speed, ground speed, current, correction, residual | Drawn with consistent color coding (see below). |
108
- |Deltas| the different inputs and outputs to the plugin along with their uncertainty (trace)| For some paths also smoothed values are shown. The smoothed values are used to update the correction table|
109
- | Correction table grid | 2D heel (columns) × speed (rows) cells containing correction vectors | Displays interpolated usage & last-updated cell highlighting. |
110
-
111
- - Labels and graphical vectors use corresponding colors.
112
- - Green text (selectedCell): the most recently updated table cell.
113
- - Blue background shading: cells contributing to the current interpolation. Deeper blue = higher interpolation weight.
114
- - Empty cells: not yet populated by learning (appear without vector magnitude / direction details initially).
115
- - Trace is an indication of the uncertainty of the measurement or estimatin. The higher the Trace the less reliable the corresponding value is.
116
-
117
- ### The menu
118
- The menu allows you to:
119
- - select the unit of choice for speed and angle
120
- - select the values to be displayed in the correction table.
121
- - Correction. The correction vector (x,y).
122
- - Factor. The factor for correcting the speed component.
123
- - Leeway. The leeway angle.
124
- - Trace. The uncertainty of the correction vector.
125
- - N. The number of observations the correction vector is based on.
126
- - select the color mode for the correction table:
127
- - None. No background colring of the correction table.
128
- - Weight. Colors cells according to their contribution in speed correction, the darker the cell the more weight is givin to its correction vector.
129
- - Leeway. Colors cells according to the amount of estimated leeway. The darker, the more leeway.
130
- - Factor. Colors cell according the the amount of forward speed correction (ignoring leeway).
131
- - Trace. Colors cells according to their uncertainty, the lighter the cell the more uncertain its correction vector.
132
-
133
-
134
-
135
- ### Interpreting Vectors
136
- - Corrected Speed vs Raw: Convergence occurs when their magnitudes diverge by a stable, plausible bias and the correction vector stops oscillating wildly.
137
- - The corrected speed includes leeway, it therefore is not aligned with the ships axis.
138
- - Residual: This is the part of the observed speed that is not explained by the sensor error or current estimation. Should trend toward small values as learning progresses.
119
+ The webapp has a collapsible sidebar with four sections, and a status message in the top-right of the nav bar (blue = stabilizing, amber = SOG fallback active, red = error or stopped).
120
+
121
+ ### Inputs
122
+ The **Inputs** section contains two sub-sections:
123
+ - **Signal K Sources**: Drop-downs to pin specific Signal K sources for heading, boat speed, SOG, and attitude. Leave blank to accept any source.
124
+ - **Live Values**: Real-time display of the raw sensor values being fed into the plugin.
125
+
126
+ ### Boatspeed Estimation
127
+ The **Boatspeed Estimation** section has an On/Off toggle at the top of the card and contains:
128
+ - **Settings**: `SOG fallback` and `Prevent duplication of boat speed`.
129
+ - **Inputs**: The raw signal values used for correction (heading, raw STW, SOG, attitude).
130
+ - **Intermediates**: Internally derived quantities such as the correction vector and leeway.
131
+ - **Outputs**: Corrected STW, leeway angle, and estimated current.
132
+
133
+ ### Correction Table Learning
134
+ The **Correction Table Learning** section has an On/Off toggle and contains:
135
+ - **Settings**: Stability, Assume Current, and Show Statistics (σ display toggle).
136
+ - **Smoother**: Type selector (Moving average / Exponential / Kalman) and its single tuning parameter. Only the parameter relevant to the selected smoother is shown.
137
+ - **Inputs**: Smoothed values fed into the learning algorithm. When Show Statistics is on, σ values are shown.
138
+ - **Intermediates**: Derived observations used to update correction table cells.
139
+
140
+ ### Correction Table
141
+ The **Correction Table** section shows the current correction table grid. Table management buttons appear top-right:
142
+ - **New** — create a new table, setting its name and grid dimensions.
143
+ - **Load** — switch to a previously saved table.
144
+ - **Copy** — duplicate the current table under a new name.
145
+ - **Resize** — resize the grid (existing cells are mapped to the new grid; some data may be lost).
146
+
147
+ Each populated cell shows:
148
+ - **Factor** (±%): how much the paddle wheel over- or under-reads at this speed and heel (green = reads slow, orange = reads fast).
149
+ - **Leeway** (°): the estimated sideways drift angle at this speed and heel.
150
+
151
+ Cell highlighting:
152
+ - **Bold border**: the most recently updated table cell.
153
+ - **Faint blue tint**: cells contributing to the current interpolation. Deeper = higher weight.
154
+ - **No content**: not yet populated by learning.
139
155
 
140
156
  ### Correction Table Health Checklist
141
- - Leeway ≈ 0 at zero heel; increases logically with heel. Non‑zero leeway at zero heel may indicate heading offset.
142
- - Correction vectors should be visually consistent with adjacent cells (direction & magnitude trend smoothly).
143
- - Port / starboard symmetry: similar magnitudes at ± matching heel angles. Large asymmetry can indicate paddle wheel misalignment with the longitudal axis of the boat or off‑center mounting.
157
+ - Leeway ≈ 0 at zero heel; increases logically with heel. Non-zero leeway at zero heel may indicate a heading offset.
158
+ - Speed corrections should trend consistently with adjacent cells (direction & magnitude smooth across the table).
159
+ - Port / starboard symmetry: similar magnitudes at ± matching heel angles. Large asymmetry can indicate a paddle wheel mounting offset.
160
+
161
+ ### Interpreting Live Values
162
+ - **Corrected Speed vs Raw**: Stable, plausible separation between the two indicates the table is working.
163
+ - **Corrected speed** includes leeway and therefore is not aligned with the ship's axis.
164
+ - **Residual**: Remaining ground-speed discrepancy after applying corrected STW and estimated current. Should trend toward small values as learning progresses.
165
+ - **Trace**: Uncertainty indicator derived from internal variance (higher = less reliable). Shown alongside most values.
144
166
 
145
167
 
146
168
 
package/index.js CHANGED
@@ -448,7 +448,7 @@ module.exports = function (app) {
448
448
  if (Object.keys(changedOptions).length) applyOptionChanges();
449
449
 
450
450
  const wellUnderway = started < new Date() - 60 * 1000;
451
- const minSpeed = SI.fromKnots(options.speedStep / 2);
451
+ const minSpeed = table.step[0] / 2;
452
452
 
453
453
  if (options.sogFallback && fallingBackToSog(minSpeed)) {
454
454
  setStatus('Falling back to Speed Over Ground');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speedandcurrent",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "A plugin that automatically corrects boat speed and calculates current and leeway using sensor fusion.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,6 +16,9 @@
16
16
  "url": "https://github.com/Asw1n/speedandcurrent/issues"
17
17
  },
18
18
  "homepage": "https://github.com/Asw1n/speedandcurrent#readme",
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ },
19
22
  "keywords": [
20
23
  "signalk-webapp",
21
24
  "signalk-node-server-plugin",
@@ -12,7 +12,7 @@ const DEFAULT_HEEL_SYMBOL = '°';
12
12
  function fmtSpeed(mps) { return (mps * MPS_TO_KNOTS).toFixed(1); }
13
13
  function fmtHeel(rad) { return (rad * RAD_TO_DEG).toFixed(0); }
14
14
  function fmtFactor(f) { const p = (f - 1) * 100; return (p >= 0 ? '+' : '') + p.toFixed(1) + '%'; }
15
- function fmtLeeway(rad) { const d = rad * RAD_TO_DEG; return (d >= 0 ? '+' : '') + d.toFixed(0) + '° lwy'; }
15
+ function fmtLeeway(rad) { const d = rad * RAD_TO_DEG; return (d >= 0 ? '+' : '') + d.toFixed(0) + '°'; }
16
16
 
17
17
  class TableRenderer {
18
18
 
@@ -87,7 +87,17 @@ class TableRenderer {
87
87
  d.className = 'cell-factor';
88
88
  d.textContent = fmtFactor(factor);
89
89
  td.appendChild(d);
90
- td.style.backgroundColor = this._factorColor(factor, maxDev);
90
+ const color = this._factorColor(factor, maxDev);
91
+ if (leeway !== null) {
92
+ const angleDeg = 90 + leeway * RAD_TO_DEG * 1;
93
+ td.style.background = `repeating-linear-gradient(
94
+ ${angleDeg}deg,
95
+ ${color} 0px, ${color} 9px,
96
+ #f0f0f0 9px, #f0f0f0 10px
97
+ )`;
98
+ } else {
99
+ td.style.backgroundColor = color;
100
+ }
91
101
  }
92
102
  if (leeway !== null) {
93
103
  const d = document.createElement('div');
package/public/main.css CHANGED
@@ -45,7 +45,7 @@
45
45
  .cell--active { outline: 3px solid #1565c0; outline-offset: -3px; }
46
46
  .cell--neighbour { outline: 1px dashed #90a4ae; outline-offset: -2px; }
47
47
  .cell-factor { font-weight: 600; font-size: 12px; }
48
- .cell-leeway { font-size: 11px; color: #555; margin-top: 2px; }
48
+ .cell-leeway { font-weight: 600; font-size: 12px; margin-top: 2px; }
49
49
 
50
50
  /* ─── Stable table column widths inside cards ──────────────────────────────── */
51
51
  .card-body .table {