signalk-polar-performance-plugin 0.0.19 → 0.0.21
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 +4 -0
- package/doc/BandG_polar.png +0 -0
- package/package.json +1 -1
- package/plugin/index.js +22 -14
package/README.md
CHANGED
|
@@ -15,6 +15,10 @@ The following paths are read
|
|
|
15
15
|
### Polar diagram
|
|
16
16
|
The polar diagram can be configured through CSV notation as used on [ORC sailboat data](https://jieter.github.io/orc-data/site/).
|
|
17
17
|
|
|
18
|
+
The resulting polar after processing can be seen here in the WebApp, looking something like:
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
|
|
18
22
|
### Plugin options
|
|
19
23
|
In the plugin configuration you can toggle the following options:
|
|
20
24
|
- Enable calculation/sending of beat/upwind and run/gybe/downwind angle
|
|
Binary file
|
package/package.json
CHANGED
package/plugin/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const halfPi = Math.PI / 2
|
|
1
2
|
var sourceAddress
|
|
2
3
|
|
|
3
4
|
module.exports = function (app) {
|
|
@@ -83,7 +84,6 @@ module.exports = function (app) {
|
|
|
83
84
|
|
|
84
85
|
// Global variables
|
|
85
86
|
var BSP, STW, TWA, targetTWA, TWS, HDG, port // Angles in rad, speed in m/s
|
|
86
|
-
var halfPi = Math.PI / 2
|
|
87
87
|
|
|
88
88
|
// Subscribe to paths
|
|
89
89
|
let localSubscription = {
|
|
@@ -394,6 +394,7 @@ module.exports = function (app) {
|
|
|
394
394
|
if (row[0] == 'twa/tws') {
|
|
395
395
|
// The row with TWS columns
|
|
396
396
|
// Create empty TWS objects in polar object
|
|
397
|
+
app.debug('First row with TWS columns')
|
|
397
398
|
polar = []
|
|
398
399
|
for (let index = 1; index < row.length; index++) {
|
|
399
400
|
|
|
@@ -401,20 +402,23 @@ module.exports = function (app) {
|
|
|
401
402
|
polar.push(twsObj)
|
|
402
403
|
}
|
|
403
404
|
app.debug('polar: %s', JSON.stringify(polar))
|
|
404
|
-
} else if (row
|
|
405
|
+
} else if (row.filter(i => i === '0').length > 1) {
|
|
405
406
|
app.debug('beat and run angles are included')
|
|
406
|
-
} else if (row.includes('0')) {
|
|
407
407
|
// Beat / Run angle
|
|
408
408
|
let angle = degToRad(Number(row[0]))
|
|
409
409
|
let angleName
|
|
410
410
|
let VMGName
|
|
411
|
+
app.debug('angle < halfPi %d < %d', angle, halfPi)
|
|
411
412
|
if (angle < halfPi) {
|
|
412
413
|
angleName = 'Beat angle'
|
|
413
414
|
VMGName = 'Beat VMG'
|
|
415
|
+
app.debug('cvsToPolar: row includes Beat angle: %s', row.join(';'))
|
|
414
416
|
} else {
|
|
415
417
|
angleName = 'Run angle'
|
|
416
418
|
VMGName = 'Run VMG'
|
|
419
|
+
app.debug('cvsToPolar: row includes Run angle: %s', row.join(';'))
|
|
417
420
|
}
|
|
421
|
+
|
|
418
422
|
for (let index = 0; index < row.length-1; index++) {
|
|
419
423
|
if (row[index+1] != 0) {
|
|
420
424
|
polar[index][angleName] = angle
|
|
@@ -465,16 +469,19 @@ module.exports = function (app) {
|
|
|
465
469
|
})
|
|
466
470
|
|
|
467
471
|
// Find the beat/run angle if not set yet.
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
472
|
+
for (let index = 0; index < polar.length; index++) {
|
|
473
|
+
let tws = polar[index].tws
|
|
474
|
+
app.debug('Beat angle for TWS %s is %s', msToKts(tws).toFixed(0), polar[index]['Beat angle'])
|
|
475
|
+
// app.debug(polar[index]['Beat angle'])
|
|
476
|
+
if (typeof polar[index]['Beat angle'] == 'undefined') {
|
|
477
|
+
app.debug('Finding beat angle for TWS %s')
|
|
471
478
|
let beatVMG = 0
|
|
472
479
|
let beatElement = 0
|
|
473
480
|
let runVMG = 0
|
|
474
481
|
let runElement = 0
|
|
475
482
|
|
|
476
483
|
let twaArray = polar[index].twa
|
|
477
|
-
for (let element = 0; element < twaArray.length
|
|
484
|
+
for (let element = 0; element < twaArray.length; element++) {
|
|
478
485
|
let Obj = twaArray[element]
|
|
479
486
|
if (Obj.twa < halfPi) {
|
|
480
487
|
// Beat
|
|
@@ -488,8 +495,8 @@ module.exports = function (app) {
|
|
|
488
495
|
}
|
|
489
496
|
}
|
|
490
497
|
}
|
|
491
|
-
app.debug('beatVMG for %
|
|
492
|
-
app.debug('
|
|
498
|
+
app.debug('beatVMG for %s is %s (angle %s)', msToKts(tws).toFixed(0), msToKts(twaArray[beatElement].vmg).toFixed(2), radToDeg(twaArray[beatElement].twa).toFixed(1))
|
|
499
|
+
app.debug('runVMG for %s is %s (angle %s)', msToKts(tws).toFixed(0), msToKts(twaArray[runElement].vmg).toFixed(2), radToDeg(twaArray[runElement].twa).toFixed(1))
|
|
493
500
|
polar[index]['Beat angle'] = twaArray[beatElement].twa
|
|
494
501
|
polar[index]['Beat VMG'] = twaArray[beatElement].vmg
|
|
495
502
|
polar[index]['Run angle'] = twaArray[runElement].twa
|
|
@@ -499,18 +506,19 @@ module.exports = function (app) {
|
|
|
499
506
|
}
|
|
500
507
|
|
|
501
508
|
// And now fill in some missing ends to avoid doing expensive calculations in the main loop
|
|
502
|
-
for (let index = 0; index < polar.length
|
|
509
|
+
for (let index = 0; index < polar.length; index++) {
|
|
503
510
|
// Sorted on angle, so first is lowest
|
|
504
511
|
let tws = polar[index].tws
|
|
505
512
|
let twaArray = polar[index].twa
|
|
506
513
|
let lowTBS = twaArray[0].tbs
|
|
507
514
|
let lowTWA = twaArray[0].twa
|
|
508
515
|
|
|
509
|
-
app.debug('Padding polar for %s from 0 to first given angle (%d deg, %d kts)', msToKts(tws).toFixed(0), radToDeg(lowTWA), msToKts(lowTBS))
|
|
516
|
+
// app.debug('Padding polar for %s from 0 to first given angle (%d deg, %d kts)', msToKts(tws).toFixed(0), radToDeg(lowTWA), msToKts(lowTBS))
|
|
510
517
|
|
|
511
518
|
// Now put some extra values at the beginning
|
|
512
519
|
var topArray = []
|
|
513
520
|
for (let angle = 0; angle < lowTWA; angle = angle + degToRad(5)) {
|
|
521
|
+
app.debug('Padding for angle %d (< lowTWA)', radToDeg(angle).toFixed(1), radToDeg(lowTWA).toFixed(1))
|
|
514
522
|
let tbs = (angle / lowTWA) * Math.pow(Math.cos((-1*lowTWA + angle)*2),2) * lowTBS
|
|
515
523
|
if (tbs < 0 ) { tbs = 0 }
|
|
516
524
|
let Obj = {'twa': angle, 'tbs': tbs}
|
|
@@ -546,7 +554,7 @@ module.exports = function (app) {
|
|
|
546
554
|
function getChartData () {
|
|
547
555
|
var backgroundColor = []
|
|
548
556
|
var borderColor = []
|
|
549
|
-
for (let c = 0; c <
|
|
557
|
+
for (let c = 0; c < 20; c++) {
|
|
550
558
|
let r = 0 + (c*10)
|
|
551
559
|
let g = 130 + (c*20 % 100)
|
|
552
560
|
let b = 80 + (c*30 % 120)
|
|
@@ -565,7 +573,7 @@ module.exports = function (app) {
|
|
|
565
573
|
for (let angle = 0; angle <= 180; angle += 5) {
|
|
566
574
|
data.labels.push(angle)
|
|
567
575
|
}
|
|
568
|
-
for (let index = 0; index < polar.length
|
|
576
|
+
for (let index = 0; index < polar.length; index++) {
|
|
569
577
|
// Add x axis label TWS
|
|
570
578
|
let tws = msToKts(polar[index].tws).toFixed(0)
|
|
571
579
|
let twaArray = polar[index].twa
|
|
@@ -583,7 +591,7 @@ module.exports = function (app) {
|
|
|
583
591
|
if (twaObj.twa == polar[index]['Beat angle'] || twaObj.twa == polar[index]['Run angle']) {
|
|
584
592
|
radius = 5
|
|
585
593
|
}
|
|
586
|
-
data.datasets[index].data.push({x:
|
|
594
|
+
data.datasets[index].data.push({x: Number(radToDeg(twaObj.twa).toFixed(1)), y: Number(msToKts(twaObj.tbs).toFixed(2))})
|
|
587
595
|
data.datasets[index].pointRadius.push(radius)
|
|
588
596
|
}
|
|
589
597
|
}
|