signalk-racer 1.3.0 → 1.3.2
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 +14 -34
- package/ReleaseNotes.md +32 -1
- package/index.js +74 -46
- package/package.json +1 -1
- package/public/index.html +32 -206
- package/public/line-view.js +430 -0
- package/racer.js +115 -75
- package/tests/racer-ttl.test.js +8 -3
- package/tests/racer-vmg.test.js +12 -64
- package/tests/racer-zone.test.js +184 -0
package/README.md
CHANGED
|
@@ -25,7 +25,8 @@ This plugin calculates and publishes the following Signal K paths:
|
|
|
25
25
|
| `navigation.racing.bestVmg.toPortEnd` | Best VMG along the line towards the port end (pin) | `m/s` | |
|
|
26
26
|
| `navigation.racing.bestVmg.toStbEnd` | Best VMG along the line towards the stb end (boat) | `m/s` | |
|
|
27
27
|
| `navigation.racing.bestVmg.*.override` | The manual adjustment behind each best VMG, `null` when not adjusted | `m/s` | |
|
|
28
|
-
| `navigation.racing.
|
|
28
|
+
| `navigation.racing.effectiveVmg.toLine` | VMG the perpendicular leg of the time to line is divided by | `m/s` | |
|
|
29
|
+
| `navigation.racing.effectiveVmg.alongLine` | VMG the along-line leg is divided by, 0 when inside the start zone | `m/s` | |
|
|
29
30
|
| `navigation.racing.startLinePort` | Location of the port (pin) end of the start line | `{latitude,longitude}` | Y |
|
|
30
31
|
| `navigation.racing.startLineStb` | Location of the starboard (boat) end of the start line | `{latitude,longitude}` | Y |
|
|
31
32
|
| `navigation.racing.nextLegHeading` | True heading for the next leg of the course | `rad` | |
|
|
@@ -60,6 +61,7 @@ You can configure the plugin via the Signal K web interface or by editing `setti
|
|
|
60
61
|
| `period` | How often to update values (in milliseconds) | `1000` |
|
|
61
62
|
| `updateStartLineWaypoint` | Should the waypoints be updated if the line is set/adjusted | `true` |
|
|
62
63
|
| `createStartLineWaypoint` | Should the waypoints be created if the line is set | `true` |
|
|
64
|
+
| `minEffectiveVmg` | Floor under each effective VMG used for time to line (in knots) | `0.5` |
|
|
63
65
|
| `lines` | Array of named lines | null |
|
|
64
66
|
|
|
65
67
|
---
|
|
@@ -97,18 +99,13 @@ If `navigation.headingTrue` is not available, then `navigation.courseOverGroundT
|
|
|
97
99
|
|
|
98
100
|
- Uses the effective VMG as the maximum VMG of either the current COG/SOG or the 90th percentile of the VMG recently achieved (approx in the last 10 minutes).
|
|
99
101
|
This allows a boat to luff / delay without changing the time to line.
|
|
102
|
+
- Each effective VMG is floored at `minEffectiveVmg` (default 0.5 knots), so a direction
|
|
103
|
+
with nothing collected yet - or a drifting boat - still yields a time rather than none.
|
|
104
|
+
The floor is not applied to the along-line leg when the boat is inside the start zone,
|
|
105
|
+
there being no such leg to sail.
|
|
100
106
|
- A boat within the start zone has the time calculated by the perpendicular distance to the line divided by their effective VMG to the line.
|
|
101
107
|
- A boat outside the start zone also has the perpendicular time plus the time calculated by the parallel distance to the zone divided by their effective VMG in that direction.
|
|
102
108
|
- If the line is changed, then the samples used to calculate the effective VMGs are cleared.
|
|
103
|
-
- Every sample keeps the `cog` and `sog` that produced it, so the course behind the 90th
|
|
104
|
-
percentile VMG towards the line can be recovered and is published as
|
|
105
|
-
`navigation.racing.bestApproach`. The direction is chosen exactly as the time to line
|
|
106
|
-
chooses its legs, and is reported alongside the course:
|
|
107
|
-
- Inside the start zone the line is closed across it, so `toCourseSide` is used, or
|
|
108
|
-
`fromCourseSide` when OCS.
|
|
109
|
-
- Outside the start zone the boat must first run along the line, so the along-line
|
|
110
|
-
samples are used, in the direction *away* from the closest end: beyond the pin it
|
|
111
|
-
must travel towards the starboard end, so `toStbEnd` governs, and vice versa.
|
|
112
109
|
- The four collected VMGs are published under `navigation.racing.bestVmg.*` and may be manually
|
|
113
110
|
adjusted. An adjustment stands in for the 90th percentile of the samples, but the VMG the boat
|
|
114
111
|
is actually sailing still wins if it is better, so an adjustment can never make the estimate
|
|
@@ -145,11 +142,11 @@ line and the boat, so it zooms as the boat closes. The line length and the headi
|
|
|
145
142
|
the line are marked on the line itself, and the boat is drawn as a triangle pointing along its
|
|
146
143
|
heading, amber when OCS.
|
|
147
144
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
A projection runs from the boat, drawn to the same scale as the rest of the drawing, so its **tip
|
|
146
|
+
can be read directly against the line**. Hovering the boat reports its SOG and COG and names the
|
|
147
|
+
line running from it.
|
|
151
148
|
|
|
152
|
-
####
|
|
149
|
+
#### Course projection — "Current cog/sog to start"
|
|
153
150
|
|
|
154
151
|
Runs along the boat's present `navigation.courseOverGroundTrue`. While the start timer is counting
|
|
155
152
|
down, its length is `SOG × timeToStart`: the distance the boat will cover before the gun if nothing
|
|
@@ -162,24 +159,6 @@ changes. Its tip is therefore **where the boat will be when the start fires**:
|
|
|
162
159
|
With no timer running there is nothing to project against, so it degrades to a short fixed-length
|
|
163
160
|
stub showing course only.
|
|
164
161
|
|
|
165
|
-
#### Thin faint line — "Best VMG to start"
|
|
166
|
-
|
|
167
|
-
Runs along `navigation.racing.bestApproach`, with its length that course's own
|
|
168
|
-
`SOG × timeToStart`. This is **not** a synthetic best case: it is a course the boat has genuinely
|
|
169
|
-
sailed in the last few minutes, being the `cog`/`sog` recorded against the 90th percentile VMG
|
|
170
|
-
sample for the direction that actually matters (across the line, or along it when outside the start
|
|
171
|
-
zone — see [Time To Line](#time-to-line-navigationracingtimetoline)). Because it is a real point of
|
|
172
|
-
sail it runs on its **own bearing**, not the current one, so it will diverge from the thick line
|
|
173
|
-
whenever the boat is not sailing as well as it recently has.
|
|
174
|
-
|
|
175
|
-
Comparing the two tips is the point of the pair: if the thin line reaches the line and the thick one
|
|
176
|
-
falls short, then sailing the boat as well as it has already been sailed would get you there, and
|
|
177
|
-
the difference between the tips is what is being left on the table. If no samples have been
|
|
178
|
-
collected yet, or the timer is not running, this line is not drawn.
|
|
179
|
-
|
|
180
|
-
Over a long countdown both projections run well off the drawing and are simply clipped at its edge;
|
|
181
|
-
the part that matters — where they cross the line — stays visible.
|
|
182
|
-
|
|
183
162
|
---
|
|
184
163
|
|
|
185
164
|
## 🌐 API Access
|
|
@@ -226,14 +205,15 @@ Used to **adjust** or **reset** the best VMGs used to estimate the time to line.
|
|
|
226
205
|
"vmg": "toCourseSide" | "fromCourseSide" | "toPortEnd" | "toStbEnd",
|
|
227
206
|
"value": 5.0,
|
|
228
207
|
"delta": 0.0514,
|
|
229
|
-
"command": "reset"
|
|
208
|
+
"command": "reset" | "clear"
|
|
230
209
|
}
|
|
231
210
|
```
|
|
232
211
|
|
|
233
212
|
- `vmg`: which best VMG to adjust. Optional for `reset`, which otherwise clears all four.
|
|
234
213
|
- `value`: absolute best VMG in `m/s`.
|
|
235
214
|
- `delta`: adjustment in `m/s` applied to the current best VMG.
|
|
236
|
-
- `command`: `"reset"` to clear the override and revert to the collected samples
|
|
215
|
+
- `command`: `"reset"` to clear the override and revert to the collected samples, or
|
|
216
|
+
`"clear"` to throw away the collected samples themselves and start again.
|
|
237
217
|
|
|
238
218
|
An absolute value may also be put directly to `navigation.racing.bestVmg.<name>`.
|
|
239
219
|
|
package/ReleaseNotes.md
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
## 1.2
|
|
1
|
+
## 1.3.2 Distance to length
|
|
2
|
+
+ Set the metadata for distance to line as a length rather than as a distance.
|
|
3
|
+
|
|
4
|
+
## 1.3.1 Start line approach
|
|
5
|
+
+ Fixed the distance to the start zone being measured against a 54.7 degree wedge while
|
|
6
|
+
the zone itself was tested at 45 degrees, so `distanceStartline` and `timeToLine`
|
|
7
|
+
jumped by 0.29 times the offset as a boat crossed the boundary. They are now continuous
|
|
8
|
+
and the along-line leg reaches zero exactly at the wedge
|
|
9
|
+
+ The start zone geometry moved from `index.js` into `racer.js` as `startZoneDistances`,
|
|
10
|
+
where it is unit tested - it had no coverage at all, which is how the above survived
|
|
11
|
+
+ `navigation.racing.timeToBurn` is now published when OCS as well. The time to line is
|
|
12
|
+
then the time to get back over the line from the course side, so the spare time before
|
|
13
|
+
you have to turn and do it is just as real, and goes negative once it is too late
|
|
14
|
+
+ Removed `navigation.racing.bestApproach` and the `cog`/`sog` each VMG sample carried
|
|
15
|
+
to produce it. It described one course the boat had genuinely sailed, which was useful
|
|
16
|
+
but not the path the time to line is computed over, so it read as a second answer to a
|
|
17
|
+
question that already had one. Best VMG angles will be revisited once the polar plugin
|
|
18
|
+
offers an API for them, by which point the shape is likely to be quite different
|
|
19
|
+
+ Each effective VMG is now floored at a configurable minimum, `minEffectiveVmg`,
|
|
20
|
+
defaulting to 0.5 knots. A direction with nothing collected reported no VMG at all, which
|
|
21
|
+
left the time to line falling back to the time to start rather than estimating anything
|
|
22
|
+
+ `navigation.racing.setBestVmg` accepts `command: "clear"`, which discards the collected
|
|
23
|
+
samples themselves rather than just the manual adjustments
|
|
24
|
+
+ Published the two VMGs the time to line is actually divided by as
|
|
25
|
+
`navigation.racing.effectiveVmg.{toLine,alongLine}`: the collected best for each
|
|
26
|
+
direction, or the VMG being sailed right now when that is better. `bestVmg.*` reports
|
|
27
|
+
only the collected half, so a client drawing the approach from it disagreed with the
|
|
28
|
+
published time whenever the boat was going well
|
|
29
|
+
|
|
30
|
+
## 1.3.0 Visualize line and best VMGs
|
|
2
31
|
+ Added `navigation.racing.swapStartLine` to swap the port and starboard ends of the line,
|
|
3
32
|
carrying the collected VMG samples across with the ends
|
|
4
33
|
+ Published the four best VMGs behind the time to line as `navigation.racing.bestVmg.`
|
|
@@ -18,6 +47,8 @@
|
|
|
18
47
|
+ Fixed the start line bias not being cleared when the line is lost
|
|
19
48
|
+ Fixed the webapp race countdown never being displayed
|
|
20
49
|
|
|
50
|
+
## 1.2.0 Never released
|
|
51
|
+
|
|
21
52
|
## 1.1.2 TTL fixes
|
|
22
53
|
+ use a FIFO queue for VMGs towards the line.
|
|
23
54
|
+ avoid undefined values in deltas
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ module.exports = (app) => {
|
|
|
5
5
|
// Last published best VMGs, so we only send deltas when they actually change.
|
|
6
6
|
publishedBestVmg: {toCourseSide: null, fromCourseSide: null, toPortEnd: null, toStbEnd: null},
|
|
7
7
|
publishedBestVmgOverrides: {toCourseSide: null, fromCourseSide: null, toPortEnd: null, toStbEnd: null},
|
|
8
|
-
|
|
8
|
+
publishedEffectiveVmg: {toLine: null, alongLine: null},
|
|
9
9
|
};
|
|
10
10
|
const geolib = require('geolib')
|
|
11
11
|
const racerSchema = {
|
|
@@ -62,6 +62,11 @@ module.exports = (app) => {
|
|
|
62
62
|
title: 'Minimum VMG component in m/s for a sample to be collected in that direction',
|
|
63
63
|
default: 0.01
|
|
64
64
|
},
|
|
65
|
+
minEffectiveVmg: {
|
|
66
|
+
type: 'number',
|
|
67
|
+
title: 'Minimum effective VMG in knots used to estimate time to line',
|
|
68
|
+
default: 0.5
|
|
69
|
+
},
|
|
65
70
|
maxDistance: {
|
|
66
71
|
type: 'number',
|
|
67
72
|
title: 'Maximum distance to line and/or line zone in meters to consider for VMG calculations',
|
|
@@ -116,13 +121,14 @@ module.exports = (app) => {
|
|
|
116
121
|
collectVmgSamples,
|
|
117
122
|
resetVmgSamples,
|
|
118
123
|
computeTimeToLine,
|
|
124
|
+
startZoneDistances,
|
|
125
|
+
effectiveVmg,
|
|
119
126
|
vmgNames,
|
|
120
127
|
getAllBestVmg,
|
|
121
128
|
getBestVmgOverrides,
|
|
122
129
|
setBestVmg,
|
|
123
130
|
clearBestVmgOverrides,
|
|
124
131
|
swapVmgEnds,
|
|
125
|
-
getBestApproach
|
|
126
132
|
} = require('./racer');
|
|
127
133
|
|
|
128
134
|
const unsubscribes = [];
|
|
@@ -139,11 +145,23 @@ module.exports = (app) => {
|
|
|
139
145
|
"value": {
|
|
140
146
|
"type": "number",
|
|
141
147
|
"units": "m",
|
|
148
|
+
"displayUnits": { "category": "length" },
|
|
142
149
|
"description": "Length of the start line",
|
|
143
150
|
"displayName": "Length of the start line",
|
|
144
151
|
"shortName": "SLL"
|
|
145
152
|
}
|
|
146
153
|
},
|
|
154
|
+
{
|
|
155
|
+
"path": "navigation.racing.distanceStartline",
|
|
156
|
+
"value": {
|
|
157
|
+
"type": "number",
|
|
158
|
+
"units": "m",
|
|
159
|
+
"displayUnits": { "category": "length" },
|
|
160
|
+
"description": "The minimum distance from the bow to the start line, via perpendicular approach",
|
|
161
|
+
"displayName": "Distance to the start line",
|
|
162
|
+
"shortName": "DTL"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
147
165
|
{
|
|
148
166
|
"path": "navigation.racing.startLineBearing",
|
|
149
167
|
"value": {
|
|
@@ -155,12 +173,23 @@ module.exports = (app) => {
|
|
|
155
173
|
}
|
|
156
174
|
},
|
|
157
175
|
{
|
|
158
|
-
"path": "navigation.racing.
|
|
176
|
+
"path": "navigation.racing.effectiveVmg.toLine",
|
|
159
177
|
"value": {
|
|
160
|
-
"type": "
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
178
|
+
"type": "number",
|
|
179
|
+
"units": "m/s",
|
|
180
|
+
"description": "VMG the perpendicular leg of the time to line was divided by: the collected best across the line, or the VMG being sailed right now if that is better",
|
|
181
|
+
"displayName": "Effective VMG to line",
|
|
182
|
+
"shortName": "VMG>Line"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"path": "navigation.racing.effectiveVmg.alongLine",
|
|
187
|
+
"value": {
|
|
188
|
+
"type": "number",
|
|
189
|
+
"units": "m/s",
|
|
190
|
+
"description": "VMG the along-line leg of the time to line was divided by, zero when inside the start zone",
|
|
191
|
+
"displayName": "Effective VMG along line",
|
|
192
|
+
"shortName": "VMG>Zone"
|
|
164
193
|
}
|
|
165
194
|
},
|
|
166
195
|
{
|
|
@@ -208,6 +237,7 @@ module.exports = (app) => {
|
|
|
208
237
|
"value": {
|
|
209
238
|
"type": "number",
|
|
210
239
|
"units": "m",
|
|
240
|
+
"displayUnits": { "category": "length" },
|
|
211
241
|
"description": "Bias of the start line for the starboard end",
|
|
212
242
|
"displayName": "Bias of the start line for the starboard end",
|
|
213
243
|
"shortName": "Bias"
|
|
@@ -322,9 +352,6 @@ module.exports = (app) => {
|
|
|
322
352
|
function publishBestVmg(position = {}) {
|
|
323
353
|
const best = state.startLine ? getAllBestVmg() : null;
|
|
324
354
|
const overrides = state.startLine ? getBestVmgOverrides() : null;
|
|
325
|
-
const approach = state.startLine
|
|
326
|
-
? getBestApproach(position.ocs, position.toZoneVz, position.closestEnd)
|
|
327
|
-
: null;
|
|
328
355
|
const deltas = [];
|
|
329
356
|
|
|
330
357
|
for (const name of Object.keys(vmgNames)) {
|
|
@@ -344,17 +371,20 @@ module.exports = (app) => {
|
|
|
344
371
|
}
|
|
345
372
|
}
|
|
346
373
|
|
|
347
|
-
// The
|
|
348
|
-
//
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
374
|
+
// The two VMGs the time to line was actually divided by. These are what a client
|
|
375
|
+
// needs to draw the legs the estimate was built from; the collected bests above
|
|
376
|
+
// are only half the story, since the boat sailing better than its history right
|
|
377
|
+
// now wins. Only published once there is a position to resolve them against.
|
|
378
|
+
if (position.lineBearing != null) {
|
|
379
|
+
const effective = effectiveVmg(position.cog, position.sog, position.lineBearing,
|
|
380
|
+
position.toZoneVz, position.ocs, position.closestEnd);
|
|
381
|
+
for (const leg of ['toLine', 'alongLine']) {
|
|
382
|
+
const value = state.startLine ? Math.round(effective[leg] * 1000) / 1000 : null;
|
|
383
|
+
if (state.publishedEffectiveVmg[leg] !== value) {
|
|
384
|
+
state.publishedEffectiveVmg[leg] = value;
|
|
385
|
+
deltas.push({path: `navigation.racing.effectiveVmg.${leg}`, value});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
358
388
|
}
|
|
359
389
|
|
|
360
390
|
if (deltas.length > 0)
|
|
@@ -720,6 +750,14 @@ module.exports = (app) => {
|
|
|
720
750
|
if (!args)
|
|
721
751
|
return complete(callback, 400, 'Failed to set best VMG: no value');
|
|
722
752
|
|
|
753
|
+
if (args.command === 'clear') {
|
|
754
|
+
// Throw away everything collected, not just the manual adjustments, so
|
|
755
|
+
// the estimate starts again from what the boat does next.
|
|
756
|
+
resetVmgSamples();
|
|
757
|
+
publishBestVmg();
|
|
758
|
+
return complete(callback, 200, 'Cleared best VMG samples: OK');
|
|
759
|
+
}
|
|
760
|
+
|
|
723
761
|
if (args.command === 'reset') {
|
|
724
762
|
// No vmg name clears every override.
|
|
725
763
|
if (!clearBestVmgOverrides(args.vmg))
|
|
@@ -1036,12 +1074,11 @@ module.exports = (app) => {
|
|
|
1036
1074
|
angle = 180 - (bearingToEnd - startLine.bearing);
|
|
1037
1075
|
}
|
|
1038
1076
|
angle = ((angle + 180) % 360 + 360) % 360 - 180;
|
|
1039
|
-
const ocs = angle < 0;
|
|
1040
1077
|
|
|
1041
|
-
//
|
|
1042
|
-
// -
|
|
1043
|
-
// -
|
|
1044
|
-
// perpendicular distance
|
|
1078
|
+
// The start zone is a 45 degree wedge off each end of the line.
|
|
1079
|
+
// - Inside the zone, distanceToLine = perpendicular to the line (or extension).
|
|
1080
|
+
// - Outside it, distanceToLine = distance parallel to the line out to the
|
|
1081
|
+
// wedge, plus that perpendicular distance: an L whose corner sits on the 45.
|
|
1045
1082
|
// This is illustrated for the starboard closest end of the line below:
|
|
1046
1083
|
// \ /
|
|
1047
1084
|
// \ /
|
|
@@ -1053,24 +1090,10 @@ module.exports = (app) => {
|
|
|
1053
1090
|
// / \
|
|
1054
1091
|
//
|
|
1055
1092
|
// P=pin; B=boat; x=extension; b=perpToBoat; z=zoneEntry; V=vessel; N=north
|
|
1056
|
-
// bearing = NBP
|
|
1057
|
-
//
|
|
1058
|
-
//
|
|
1059
|
-
|
|
1060
|
-
// PBV = abs(angle)
|
|
1061
|
-
// VBx = 180 - PBV
|
|
1062
|
-
// Vx = toEnd * sin (VBx)
|
|
1063
|
-
// bBV = 90 - VBx
|
|
1064
|
-
// Vb = toEnd * sin (bBV)
|
|
1065
|
-
// zb = sqrt((Vx * Vx) / 2)
|
|
1066
|
-
// Vz = Vb - zb
|
|
1067
|
-
const anglePBV = Math.abs(angle);
|
|
1068
|
-
const inStartZone = anglePBV <= 135;
|
|
1069
|
-
const angleVBx = 180 - anglePBV;
|
|
1070
|
-
const perpToLineVx = toEnd * Math.sin(toRadians(angleVBx));
|
|
1071
|
-
let toZoneVz = inStartZone ? 0 : ( toEnd * Math.sin(toRadians(90 - angleVBx)) - Math.sqrt(perpToLineVx * perpToLineVx / 2.0));
|
|
1072
|
-
const toLine = Math.round( 10 * (toZoneVz + perpToLineVx)) / 10;
|
|
1073
|
-
const distanceToLine = ocs ? -toLine : toLine;
|
|
1093
|
+
// bearing = NBP, PBz == 135, bBz == zBx == 45, Bb == bz == Vx == perpendicular
|
|
1094
|
+
// distance to the line or extension, PBV = abs(angle), VBx = 180 - PBV.
|
|
1095
|
+
// The geometry itself lives in racer.js so it can be unit tested.
|
|
1096
|
+
const {ocs, perpToLineVx, toZoneVz, distanceToLine} = startZoneDistances(toEnd, angle);
|
|
1074
1097
|
app.debug('distanceToLine:' + distanceToLine);
|
|
1075
1098
|
state.distanceToLine = distanceToLine;
|
|
1076
1099
|
|
|
@@ -1081,14 +1104,18 @@ module.exports = (app) => {
|
|
|
1081
1104
|
collectVmgSamples(cog, sog, startLine.bearing, toZoneVz, perpToLineVx);
|
|
1082
1105
|
}
|
|
1083
1106
|
const ttl = computeTimeToLine(cog, sog, startLine.bearing, toZoneVz, perpToLineVx, ocs, closestEnd, state.timeToStart ?? 0);
|
|
1084
|
-
|
|
1107
|
+
// Time to burn stands when OCS too: the time to line is then the time to get
|
|
1108
|
+
// back over the line from the course side, so the spare time before you have
|
|
1109
|
+
// to turn and do it is just as real - and goes negative when you have left it
|
|
1110
|
+
// too late, which is exactly when it is worth reading.
|
|
1111
|
+
const ttb = state.timerRunning && state.timeToStart > 0 && ttl != null ? (state.timeToStart - ttl) : null;
|
|
1085
1112
|
|
|
1086
1113
|
sendDeltas([
|
|
1087
1114
|
{path: 'navigation.racing.distanceStartline', value: distanceToLine},
|
|
1088
1115
|
{path: "navigation.racing.timeToLine", value: ttl},
|
|
1089
1116
|
{path: "navigation.racing.timeToBurn", value: ttb}
|
|
1090
1117
|
]);
|
|
1091
|
-
publishBestVmg({ocs, toZoneVz, closestEnd});
|
|
1118
|
+
publishBestVmg({ocs, toZoneVz, closestEnd, cog, sog, lineBearing: startLine.bearing});
|
|
1092
1119
|
|
|
1093
1120
|
} else if (state.distanceToLine) {
|
|
1094
1121
|
state.distanceToLine = null;
|
|
@@ -1242,6 +1269,7 @@ module.exports = (app) => {
|
|
|
1242
1269
|
initRacer({
|
|
1243
1270
|
minSog: options.minSog ?? 1.0,
|
|
1244
1271
|
minVmg: options.minVmg ?? 0.01,
|
|
1272
|
+
minEffectiveVmg: (options.minEffectiveVmg ?? 0.5) * 0.514444,
|
|
1245
1273
|
maxDistance: options.maxDistance ?? 2000,
|
|
1246
1274
|
maxSamples: options.maxSamples ?? 600,
|
|
1247
1275
|
percentile: options.percentile ?? 0.9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signalk-racer",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Signalk plugin to calculate values of interest to sail racers, such as: Time to Start; Time of Start, Time to Burn; Distance to Line; Next leg TWA.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|