signalk-sailboat-simulator 0.3.0 → 0.4.0
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 +9 -0
- package/README.md +2 -0
- package/index.js +17 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2026-09-15
|
|
4
|
+
|
|
5
|
+
- Update `polar-math` to 1.1.1 so sparse polar rows are supported and beat-angle handling includes its latest fixes.
|
|
6
|
+
- Disable polar extrapolation so the simulator follows explicitly entered speeds below the calculated beat angle instead of enforcing performance-oriented sailing limits.
|
|
7
|
+
|
|
8
|
+
## [0.3.1] - 2026-09-09
|
|
9
|
+
|
|
10
|
+
- Report polar loading and validation failures through the Signal K plugin error channel with their detailed cause.
|
|
11
|
+
|
|
3
12
|
## [0.3.0] - 2026-09-09
|
|
4
13
|
|
|
5
14
|
- Calculate simulated boat speed directly from the active `signalk-polar-management` polar resource via `polar-math`.
|
package/README.md
CHANGED
|
@@ -96,6 +96,8 @@ The simulator publishes virtual wind for the rest of the Signal K stack. The pub
|
|
|
96
96
|
|
|
97
97
|
The simulator uses the same true wind values with the active polar resource to calculate boat speed. The active polar must use the canonical `polar-format` structure provided by `signalk-polar-management`.
|
|
98
98
|
|
|
99
|
+
Polar extrapolation is disabled: below the calculated beat angle, the simulator follows the speeds present in the entered polar curve. If the polar has no usable speed for the requested conditions, the boat stops instead of inventing a performance value.
|
|
100
|
+
|
|
99
101
|
The simulator uses the calculated polar speed as boat speed, integrates heading from `steering.autopilot.output.turnRate`, and integrates position along that simulated heading. Current, leeway, route following and manoeuvre rules are intentionally left as separate steps.
|
|
100
102
|
|
|
101
103
|
## Configuration
|
package/index.js
CHANGED
|
@@ -199,7 +199,8 @@ module.exports = function createPlugin (app) {
|
|
|
199
199
|
const result = polar.speedAt({
|
|
200
200
|
tws: inputs.windSpeedTrue,
|
|
201
201
|
twa: windAngleTrueWater,
|
|
202
|
-
performanceFactor
|
|
202
|
+
performanceFactor,
|
|
203
|
+
extrapolate: false
|
|
203
204
|
})
|
|
204
205
|
status.speedState = result.state
|
|
205
206
|
if (Number.isFinite(result.value)) {
|
|
@@ -479,8 +480,13 @@ module.exports = function createPlugin (app) {
|
|
|
479
480
|
}
|
|
480
481
|
|
|
481
482
|
function setStatus () {
|
|
482
|
-
if (
|
|
483
|
-
|
|
483
|
+
if (runtime.status === 'polarError') {
|
|
484
|
+
setError(`Polar error: ${runtime.polar && runtime.polar.error ? runtime.polar.error : 'unable to calculate boat speed'}`)
|
|
485
|
+
} else if (runtime.status === 'error') {
|
|
486
|
+
setError(`Simulator error: ${runtime.error || 'unexpected runtime failure'}`)
|
|
487
|
+
} else if (!app.setPluginStatus) {
|
|
488
|
+
return
|
|
489
|
+
} else if (runtime.status === 'sailing') {
|
|
484
490
|
app.setPluginStatus(`Sailing at ${runtime.speedOverGround.toFixed(2)} m/s, heading ${runtime.headingTrueDeg.toFixed(1)} deg`)
|
|
485
491
|
} else if (runtime.status === 'groundingProtection') {
|
|
486
492
|
app.setPluginStatus(`Stopped: distance to shore ${runtime.distanceToShore.toFixed(1)} m`)
|
|
@@ -489,6 +495,14 @@ module.exports = function createPlugin (app) {
|
|
|
489
495
|
}
|
|
490
496
|
}
|
|
491
497
|
|
|
498
|
+
function setError (message) {
|
|
499
|
+
if (typeof app.setPluginError === 'function') {
|
|
500
|
+
app.setPluginError(message)
|
|
501
|
+
} else if (typeof app.setPluginStatus === 'function') {
|
|
502
|
+
app.setPluginStatus(message)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
492
506
|
function registerWithRouter (router) {
|
|
493
507
|
router.get('/api/status', (req, res) => {
|
|
494
508
|
res.json({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signalk-sailboat-simulator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Signal K plugin that simulates a sailing boat from autopilot turn-rate output, weather and an active polar resource.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"node": ">=20"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"polar-math": "^1.
|
|
39
|
+
"polar-math": "^1.1.1"
|
|
40
40
|
},
|
|
41
41
|
"signalk-plugin-enabled-by-default": false,
|
|
42
42
|
"signalk": {
|