signalk-performance-processor 0.0.2 → 0.0.3
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/CHANGELOG.md +7 -0
- package/README.md +44 -6
- package/index.js +5 -3
- package/package.json +2 -2
- package/public/app.js +9 -5
- package/public/index.html +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.3 — 2026-10-29
|
|
4
|
+
|
|
5
|
+
Still a proof of concept: run it in Shadow mode alongside your instruments.
|
|
6
|
+
|
|
7
|
+
- Fix: the Calibration and Settings pages were empty on a real server. The plugin's `/config` endpoint was shadowed by the server's own route of that name; it is now `/calibration`, and the webapp says so if the calibration cannot be loaded.
|
|
8
|
+
- README and App Store description explain the problem this solves, who it is for, and the results on the boat it was built for.
|
|
9
|
+
|
|
3
10
|
## 0.0.2 — 2026-10-29
|
|
4
11
|
|
|
5
12
|
Still a proof of concept: run it in Shadow mode alongside your instruments.
|
package/README.md
CHANGED
|
@@ -2,13 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
# signalk-performance-processor
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**True wind direction that holds steady when you tack.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
If your TWD swings 5–10° every time you tack or gybe, the wind hasn't shifted: your true wind calibration is off. It makes real shifts hard to call, puts laylines in the wrong place, and feeds bad numbers into your polars and targets.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This plugin does the calibration job of a B&G H5000-class instrument processor inside Signal K. It corrects boat speed and leeway, then applies H5000-style TWA and TWS correction tables, and publishes corrected true wind and current. You edit everything in a webapp and can watch each correction work live. Run it in **Shadow mode** first: it publishes alongside your existing instruments without changing anything they do.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
> **Proof of concept (0.0.3).** Compare it against your instruments in Shadow mode before relying on it. See the [changelog](CHANGELOG.md).
|
|
12
|
+
|
|
13
|
+
## Why it exists
|
|
14
|
+
|
|
15
|
+
True wind is worked out from apparent wind, boat speed and heading, so it inherits every error in them. The masthead sensor reads a bent airflow upwind, the paddlewheel misreads when heeled, and the boat slides sideways. None of these is the same on every point of sail, and some flip from one tack to the other. That is why an uncalibrated TWD jumps through every tack.
|
|
16
|
+
|
|
17
|
+
Instrument processors fix this with calibration tables, but:
|
|
18
|
+
|
|
19
|
+
- **The tables are locked in the box.** You edit them through display menus, cannot see what each one is doing at any moment, and keep no history of what you changed or why.
|
|
20
|
+
- **Older and simpler systems have less to work with.** An H2000, for example, has a TWS correction that only applies downwind, and many systems have no tables at all.
|
|
21
|
+
- **Formula-based corrections don't fit every boat.** A single upwash formula cannot follow a boat whose correction is twice as big in light air as in a breeze at the same apparent wind angle. That was the case on the boat this was built for; a table can follow it.
|
|
22
|
+
|
|
23
|
+
This plugin moves the calibration into Signal K, where you can see it, change it, log it and fit it from your own race data:
|
|
24
|
+
|
|
25
|
+
- **The same shape as an H5000:** boat speed linearity and heel correction, leeway, and TWA/TWS tables by wind speed with upwind, reach and downwind rows. An existing calibration carries across, and the H5000 tuning rule ("TWD lifts on every tack: take half the error off TWA") works unchanged.
|
|
26
|
+
- **Every correction has a switch and a live readout,** so you can see what each one does to the numbers right now.
|
|
27
|
+
- **The calibration is a versioned JSON file,** easy to back up, compare and fit from logged races offline.
|
|
28
|
+
- **It is safe to try.** Shadow mode publishes `…Corrected` paths beside your instruments. Replace mode takes over the standard paths only when you choose it.
|
|
29
|
+
|
|
30
|
+
### On the boat it was built for
|
|
31
|
+
|
|
32
|
+
From the offline model the defaults were fitted with: trained on 2025 race logs, tested on Jan–Mar 2026 races it had not seen, and measured by how far true wind direction jumps through each manoeuvre (median). The shipped defaults differ slightly (the owner's leeway K, and the TWA table resampled to H5000 breakpoints).
|
|
33
|
+
|
|
34
|
+
| | Uncorrected | Instrument (H2000) | This plugin |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| Tacks (41) | 6.2° | 2.5° | 2.2° |
|
|
37
|
+
| Gybes (5) | 2.4° | 4.7° | 1.1° |
|
|
38
|
+
| Roundings (38) | 9.3° | 9.7° | 7.3° |
|
|
39
|
+
| Current step through manoeuvres | 0.65 kn | 0.65 kn | 0.37 kn |
|
|
40
|
+
|
|
41
|
+
These figures are one boat's, and the defaults are that boat's. On a different boat, start from the defaults in Shadow mode and refit. After the boat's own rig and log changes in late 2026, the defaults needed refitting too.
|
|
42
|
+
|
|
43
|
+
## Who it's for
|
|
44
|
+
|
|
45
|
+
- **Racing sailors running Signal K** who want TWD they can call shifts on, and polars built on corrected wind.
|
|
46
|
+
- **Boats with an older or limited instrument processor,** or none, that still have apparent wind, a paddlewheel, heading and heel on the network.
|
|
47
|
+
- **Anyone who wants to see and log** what their wind calibration is doing, rather than trust a box.
|
|
48
|
+
|
|
49
|
+
You need apparent wind, boat speed through the water and heading in Signal K. Heel (`navigation.attitude`) enables the heel and leeway corrections; SOG and COG enable current.
|
|
12
50
|
|
|
13
51
|
## What it does
|
|
14
52
|
|
|
@@ -109,8 +147,8 @@ Corrections live in `lib/processor.js` as entries in `CORRECTIONS`, each with a
|
|
|
109
147
|
|
|
110
148
|
Under `/plugins/signalk-performance-processor`:
|
|
111
149
|
|
|
112
|
-
- `GET /
|
|
113
|
-
- `PUT /
|
|
150
|
+
- `GET /calibration` returns the configuration in use and the defaults.
|
|
151
|
+
- `PUT /calibration` validates, saves and restarts with a new configuration. It returns 400 with the reasons if the configuration is invalid.
|
|
114
152
|
- `GET /live` returns the latest result, each step, input ages and the sources seen.
|
|
115
153
|
|
|
116
154
|
## Development
|
package/index.js
CHANGED
|
@@ -48,7 +48,7 @@ module.exports = function (app) {
|
|
|
48
48
|
const plugin = {
|
|
49
49
|
id: 'signalk-performance-processor',
|
|
50
50
|
name: 'gh - Performance Processor',
|
|
51
|
-
description: '
|
|
51
|
+
description: 'Steady true wind through tacks and gybes: H5000-style calibration of boat speed, leeway and TWA/TWS, configured in the Performance Processor webapp'
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
let config = null
|
|
@@ -356,12 +356,14 @@ module.exports = function (app) {
|
|
|
356
356
|
}
|
|
357
357
|
|
|
358
358
|
plugin.registerWithRouter = function (router) {
|
|
359
|
-
|
|
359
|
+
// Not /config: the server registers GET and POST /config on every plugin's router
|
|
360
|
+
// for its own options, ahead of the plugin's routes, so ours would never be reached.
|
|
361
|
+
router.get('/calibration', (req, res) => {
|
|
360
362
|
res.set('Cache-Control', 'no-store')
|
|
361
363
|
res.json({ config: config || normalizeConfig(loadStored()).config, defaults: DEFAULTS })
|
|
362
364
|
})
|
|
363
365
|
|
|
364
|
-
router.put('/
|
|
366
|
+
router.put('/calibration', async (req, res) => {
|
|
365
367
|
let body
|
|
366
368
|
try { body = await readBody(req) } catch (e) { return res.status(400).json({ errors: ['body is not valid JSON'] }) }
|
|
367
369
|
const { config: cfg, errors } = normalizeConfig(body)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signalk-performance-processor",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "H5000-style calibration
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "True wind direction that holds steady through tacks and gybes. H5000-style calibration in Signal K: boat speed, leeway, and TWA/TWS tables by wind speed, edited and watched live in a webapp. Try it in shadow mode beside your existing instruments.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "node --test",
|
package/public/app.js
CHANGED
|
@@ -50,14 +50,16 @@
|
|
|
50
50
|
|
|
51
51
|
async function loadConfig () {
|
|
52
52
|
try {
|
|
53
|
-
const body = await getJson('/
|
|
53
|
+
const body = await getJson('/calibration')
|
|
54
|
+
if (!body || !body.config || !body.config.corrections) throw new Error('the plugin returned no calibration')
|
|
54
55
|
state.saved = body.config
|
|
55
56
|
state.draft = clone(body.config)
|
|
56
57
|
state.defaults = body.defaults
|
|
57
|
-
|
|
58
|
+
state.configError = null
|
|
58
59
|
} catch (e) {
|
|
59
|
-
|
|
60
|
-
$
|
|
60
|
+
// Kept until a load succeeds: the live poll must not clear it.
|
|
61
|
+
state.configError = `Could not load the calibration (${e.message}). Is Performance Processor enabled and up to date?`
|
|
62
|
+
setTimeout(loadConfig, 5000)
|
|
61
63
|
}
|
|
62
64
|
renderAll()
|
|
63
65
|
}
|
|
@@ -80,7 +82,7 @@
|
|
|
80
82
|
state.saving = true
|
|
81
83
|
renderSaveBar()
|
|
82
84
|
try {
|
|
83
|
-
const res = await fetch(API + '/
|
|
85
|
+
const res = await fetch(API + '/calibration', {
|
|
84
86
|
method: 'PUT',
|
|
85
87
|
credentials: 'include',
|
|
86
88
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -138,6 +140,8 @@
|
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
function renderHeader () {
|
|
143
|
+
$('cfgError').textContent = state.configError || ''
|
|
144
|
+
$('cfgError').hidden = !state.configError
|
|
141
145
|
const mode = state.saved ? state.saved.mode : null
|
|
142
146
|
const badge = $('mode')
|
|
143
147
|
badge.textContent = mode === 'replace' ? 'Replace' : mode === 'shadow' ? 'Shadow' : '--'
|