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 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
+ ![](https://raw.githubusercontent.com/htool/signalk-polar-performance-plugin/main/doc/BandG_polar.png)
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-polar-performance-plugin",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "A plugin that calculates performance information based on a (CSV) polar diagram.",
5
5
  "main": "plugin/index.js",
6
6
  "scripts": {
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[0] == '0') {
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
- if (typeof polar[0].beatAngle == 'undefined') {
469
- for (let index = 0; index < polar.length-1; index++) {
470
- let tws = polar[index].tws
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-1; element++) {
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 %d is %d (angel %d)', tws, twaArray[beatElement].vmg, twaArray[beatElement].twa)
492
- app.debug(' runVMG for %d is %d (angel %d)', tws, twaArray[runElement].vmg, twaArray[runElement].twa)
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-1; index++) {
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 < 8; 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 -1; index++) {
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: Math.round(radToDeg(twaObj.twa)), y: Number(msToKts(twaObj.tbs).toFixed(2))})
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
  }