speedandcurrent 1.3.0 → 1.4.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/index.js +60 -86
- package/package.json +2 -2
- package/public/icon.png +0 -0
package/index.js
CHANGED
|
@@ -11,21 +11,21 @@ module.exports = function (app) {
|
|
|
11
11
|
let isRunning = false;
|
|
12
12
|
let corrTable = null;
|
|
13
13
|
let lastSave = null;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
let heading = null;
|
|
15
|
+
let attitude = null;
|
|
16
|
+
let current = null;
|
|
17
|
+
let currentStat = null;
|
|
18
|
+
let boatSpeed = null;
|
|
19
|
+
let boatSpeedStat = null;
|
|
20
|
+
let correctedBoatSpeed = null;
|
|
21
|
+
let boatSpeedRefGround = null;
|
|
22
|
+
let groundSpeed = null;
|
|
23
|
+
let groundSpeedStat = null;
|
|
24
|
+
let speedCorrection = null;
|
|
25
|
+
let residual = null;
|
|
26
|
+
let reportFull = null;
|
|
27
|
+
let reportVector = null;
|
|
28
|
+
let table = null;
|
|
29
29
|
|
|
30
30
|
const plugin = {};
|
|
31
31
|
plugin.id = "SpeedAndCurrent";
|
|
@@ -248,6 +248,7 @@ module.exports = function (app) {
|
|
|
248
248
|
plugin.start = (opts) => {
|
|
249
249
|
app.setPluginStatus("starting");
|
|
250
250
|
app.debug("plugin starting");
|
|
251
|
+
let outputs = [];
|
|
251
252
|
|
|
252
253
|
// make options survive to the stop function
|
|
253
254
|
options = opts;
|
|
@@ -261,20 +262,28 @@ module.exports = function (app) {
|
|
|
261
262
|
heading = new MessageHandler("heading", "navigation.headingTrue", options.headingSource);
|
|
262
263
|
heading.subscribe(app, plugin.id, true);
|
|
263
264
|
heading.setDisplayAttributes({ label: "heading" });
|
|
265
|
+
headingStat = new PolarDamped("headingDamped", heading, 1);
|
|
266
|
+
heading.onChange = () => {
|
|
267
|
+
headingStat.sample();
|
|
268
|
+
};
|
|
264
269
|
|
|
265
270
|
// attitude
|
|
266
271
|
attitude = new MessageHandler("attitude", "navigation.attitude", options.attitudeSource);
|
|
267
272
|
attitude.value = { pitch: 0, roll: 0, yaw: 0 }; //prevents errors when there is no attitude sensor
|
|
268
273
|
attitude.setDisplayAttributes({ label: "attitude" });
|
|
269
274
|
attitude.subscribe(app, plugin.id, true);
|
|
275
|
+
attitudeStat = new PolarDamped("attitudeDamped", attitude, 1);
|
|
276
|
+
attitude.onChange = () => {
|
|
277
|
+
attitudeStat.sample();
|
|
278
|
+
};
|
|
270
279
|
|
|
271
280
|
// current
|
|
272
281
|
current = new Polar("current", "self.environment.current.drift", "self.environment.current.setTrue");
|
|
273
282
|
current.setDisplayAttributes({ label: "current", plane: "Ground" });
|
|
274
283
|
current.setAngleRange('0to2pi');
|
|
275
|
-
currentStat = new PolarDamped("currentDamped", current);
|
|
284
|
+
currentStat = new PolarDamped("currentDamped", current, 1);
|
|
276
285
|
currentStat.setAngleRange('0to2pi');
|
|
277
|
-
|
|
286
|
+
outputs.push(current);
|
|
278
287
|
// Current should be initialised as no current
|
|
279
288
|
current.setVectorValue({ x: 0, y: 0 });
|
|
280
289
|
// There should be at least two samples, otherwise we can't calculate a valid speed
|
|
@@ -285,13 +294,19 @@ module.exports = function (app) {
|
|
|
285
294
|
boatSpeed = new Polar("boatSpeed", "navigation.speedThroughWater", options.boatSpeedSource);
|
|
286
295
|
boatSpeed.subscribe(app, plugin.id, true, false, !options.preventDuplication || !options.estimateBoatSpeed);
|
|
287
296
|
boatSpeed.setDisplayAttributes({ label: "boat speed", plane: "Boat" });
|
|
288
|
-
boatSpeedStat = new PolarDamped("boatSpeedDamped", boatSpeed);
|
|
297
|
+
boatSpeedStat = new PolarDamped("boatSpeedDamped", boatSpeed, 1);
|
|
289
298
|
boatSpeedStat.setDisplayAttributes({ label: "boat speed (damped)", plane: "Boat" });
|
|
299
|
+
boatSpeed.onChange = () => {
|
|
300
|
+
boatSpeedStat.sample();
|
|
301
|
+
};
|
|
290
302
|
|
|
291
|
-
correctedBoatSpeed = new Polar("correctedBoatSpeed", "navigation.speedThroughWater", "
|
|
303
|
+
correctedBoatSpeed = new Polar("correctedBoatSpeed", "navigation.speedThroughWater", "navigation.leewayAngle");
|
|
292
304
|
correctedBoatSpeed.setDisplayAttributes({ label: "corrected boat speed", plane: "Boat" });
|
|
305
|
+
outputs.push(correctedBoatSpeed);
|
|
293
306
|
//const correctedBoatSpeedStat = new PolarDamped("correctedBoatSpeedDamped", correctedBoatSpeed);
|
|
294
307
|
|
|
308
|
+
// TODO: Add navigation.speedThroughWaterTransverse and navigation.speedThroughWaterLongitudinal
|
|
309
|
+
|
|
295
310
|
boatSpeedRefGround = new Polar("boatSpeedRefGround");
|
|
296
311
|
boatSpeedRefGround.setDisplayAttributes("boat speed over ground", "Ground");
|
|
297
312
|
|
|
@@ -300,9 +315,12 @@ module.exports = function (app) {
|
|
|
300
315
|
groundSpeed.subscribe(app, plugin.id, true, true, true);
|
|
301
316
|
groundSpeed.setDisplayAttributes({ label: "ground speed", plane: "Ground" });
|
|
302
317
|
groundSpeed.setAngleRange('0to2pi');
|
|
303
|
-
groundSpeedStat = new PolarDamped("groundSpeedDamped", groundSpeed);
|
|
318
|
+
groundSpeedStat = new PolarDamped("groundSpeedDamped", groundSpeed, 1);
|
|
304
319
|
groundSpeedStat.setDisplayAttributes({ label: "ground speed (damped)", plane: "Ground" });
|
|
305
320
|
groundSpeedStat.setAngleRange('0to2pi');
|
|
321
|
+
groundSpeed.onChange = () => {
|
|
322
|
+
groundSpeedStat.sample();
|
|
323
|
+
};
|
|
306
324
|
|
|
307
325
|
// correction vector
|
|
308
326
|
speedCorrection = new Polar("speedCorrection");
|
|
@@ -336,63 +354,19 @@ module.exports = function (app) {
|
|
|
336
354
|
reportVector.addPolar(boatSpeed);
|
|
337
355
|
reportVector.addPolar(groundSpeed);
|
|
338
356
|
|
|
357
|
+
boatSpeed.onChange = () => {
|
|
358
|
+
boatSpeedStat.sample();
|
|
359
|
+
calculate();
|
|
360
|
+
};
|
|
339
361
|
|
|
340
362
|
|
|
341
|
-
app.debug("Analyzing input data");
|
|
342
|
-
let candidates = [heading, attitude, boatSpeed, groundSpeed];
|
|
343
|
-
// wait for all to settle
|
|
344
|
-
setTimeout(() => {
|
|
345
|
-
//app.debug(groundSpeed.magnitudeHandler);
|
|
346
|
-
//app.debug(groundSpeed.angleHandler);
|
|
347
|
-
// Check if all candidates get input data
|
|
348
|
-
candidates.forEach(candidate => {
|
|
349
|
-
if (candidate.lackingInputData()) {
|
|
350
|
-
app.setPluginStatus("Halted: insufficient input data");
|
|
351
|
-
app.debug("Insufficient input data for " + candidate.displayAttributes.label );
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
// determing slowest input path and use this as a heartbeat for calculations
|
|
357
|
-
candidates.sort((a, b) => (a.frequency || 0) - (b.frequency || 0));
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (!candidates[0].lackingInputData()) {
|
|
362
|
-
slowestInput = candidates[0];
|
|
363
|
-
app.debug("Using " + slowestInput.displayAttributes.label + " as heartbeat for calculations ( " + Math.round(candidates[0].frequency) + " updates per second)");
|
|
364
|
-
slowestInput.onChange = calculate;
|
|
365
|
-
if (slowestInput == groundSpeed) {
|
|
366
|
-
groundSpeed.onChange = () => {
|
|
367
|
-
groundSpeedStat.sample();
|
|
368
|
-
calculate();
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
groundSpeed.onChange = () => {
|
|
373
|
-
groundSpeedStat.sample();
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
if (slowestInput == boatSpeed) {
|
|
377
|
-
boatSpeed.onChange = () => {
|
|
378
|
-
boatSpeedStat.sample();
|
|
379
|
-
calculate();
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
boatSpeed.onChange = () => {
|
|
384
|
-
boatSpeedStat.sample();
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
isRunning = true;
|
|
389
|
-
app.setPluginStatus("Running");
|
|
390
|
-
app.debug("Running");
|
|
391
|
-
}
|
|
392
363
|
|
|
393
|
-
|
|
364
|
+
isRunning = true;
|
|
365
|
+
app.setPluginStatus("Running");
|
|
366
|
+
app.debug("Running");
|
|
367
|
+
|
|
368
|
+
|
|
394
369
|
|
|
395
|
-
|
|
396
370
|
|
|
397
371
|
|
|
398
372
|
|
|
@@ -563,7 +537,7 @@ module.exports = function (app) {
|
|
|
563
537
|
options.estimateBoatSpeed = true;
|
|
564
538
|
options.assumeCurrent = false;
|
|
565
539
|
options.estimateCurrent = false;
|
|
566
|
-
options.correctionStability =
|
|
540
|
+
options.correctionStability = 10;
|
|
567
541
|
break;
|
|
568
542
|
case 5:
|
|
569
543
|
// mature table, with current
|
|
@@ -572,7 +546,7 @@ module.exports = function (app) {
|
|
|
572
546
|
options.estimateBoatSpeed = true;
|
|
573
547
|
options.assumeCurrent = true;
|
|
574
548
|
options.estimateCurrent = true;
|
|
575
|
-
options.correctionStability =
|
|
549
|
+
options.correctionStability = 10;
|
|
576
550
|
options.currentStability = 3;
|
|
577
551
|
break;
|
|
578
552
|
case 6:
|
|
@@ -609,22 +583,22 @@ module.exports = function (app) {
|
|
|
609
583
|
lastSave = saveTable(options, corrTable);
|
|
610
584
|
}
|
|
611
585
|
|
|
612
|
-
heading =
|
|
613
|
-
attitude =
|
|
614
|
-
current =
|
|
586
|
+
heading = heading?.terminate(app);
|
|
587
|
+
attitude = attitude?.terminate(app);
|
|
588
|
+
current = current?.terminate(app);
|
|
615
589
|
currentStat = null;
|
|
616
|
-
boatSpeed =
|
|
590
|
+
boatSpeed = boatSpeed?.terminate(app);
|
|
617
591
|
boatSpeedStat = null;
|
|
618
|
-
correctedBoatSpeed =
|
|
619
|
-
boatSpeedRefGround =
|
|
620
|
-
groundSpeed =
|
|
592
|
+
correctedBoatSpeed = correctedBoatSpeed?.terminate(app);
|
|
593
|
+
boatSpeedRefGround = boatSpeedRefGround?.terminate(app);
|
|
594
|
+
groundSpeed = groundSpeed?.terminate(app);
|
|
621
595
|
groundSpeedStat = null;
|
|
622
|
-
speedCorrection =
|
|
623
|
-
residual =
|
|
596
|
+
speedCorrection = speedCorrection?.terminate(app);
|
|
597
|
+
residual = residual?.terminate(app);
|
|
624
598
|
reportFull = null;
|
|
625
599
|
reportVector = null;
|
|
626
|
-
table =
|
|
627
|
-
|
|
600
|
+
table = null;
|
|
601
|
+
app.setPluginStatus("Stopped");
|
|
628
602
|
app.debug("Stopped");
|
|
629
603
|
|
|
630
604
|
isRunning = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "speedandcurrent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.2",
|
|
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": {
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"kalman-filter": "^2.3.0",
|
|
32
|
-
"signalkutilities": "^1.
|
|
32
|
+
"signalkutilities": "^1.4.0"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/public/icon.png
CHANGED
|
Binary file
|