signalk-polar-performance-plugin 0.0.58 → 0.0.59

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/plugin/index.js +50 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-polar-performance-plugin",
3
- "version": "0.0.58",
3
+ "version": "0.0.59",
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
@@ -472,7 +472,7 @@ module.exports = function (app) {
472
472
  }
473
473
  // Calculate opposite Tack True
474
474
  // app.debug('tackTrue: port: %d HDG: %d targetTWA: %d', port, radToDeg(HDG), radToDeg(targetTWA))
475
- if (port) {
475
+ if (port < 0) {
476
476
  let tackTrue = HDG - targetTWA
477
477
  if (tackTrue < 0) {
478
478
  tackTrue = tackTrue + 2 * Math.PI
@@ -588,15 +588,39 @@ module.exports = function (app) {
588
588
  var polar = {}
589
589
  var beat = false
590
590
 
591
+ function upsertTwa (polarIndex, twaObj, angleDeg) {
592
+ const twaArray = polar[polarIndex].twa
593
+ const existingIndex = twaArray.findIndex(entry => entry.twa === twaObj.twa)
594
+ if (existingIndex >= 0) {
595
+ app.error(
596
+ 'Duplicate TWA %s deg for TWS %s kts, keeping last value',
597
+ angleDeg,
598
+ msToKts(polar[polarIndex].tws).toFixed(1)
599
+ )
600
+ twaArray[existingIndex] = twaObj
601
+ } else {
602
+ twaArray.push(twaObj)
603
+ }
604
+ }
605
+
591
606
  // Create array of arrays from csv
592
607
  csv.split('\n').forEach(row => {
593
- csvArray.push(row.split(';'))
608
+ const trimmedRow = row.trim()
609
+ if (!trimmedRow) {
610
+ return
611
+ }
612
+ const cells = trimmedRow.split(';').map(cell => cell.trim())
613
+ if (!cells[0]) {
614
+ return
615
+ }
616
+ csvArray.push(cells)
594
617
  })
595
618
  // app.debug('csvArray: %s', JSON.stringify(csvArray))
596
619
 
597
620
  // Populate the polar object from CSV rows
598
621
  csvArray.forEach(row => {
599
- if (row[0] == 'twa/tws') {
622
+ const rowKey = row[0].trim().toLowerCase()
623
+ if (rowKey == 'twa/tws') {
600
624
  // The row with TWS columns
601
625
  // Create empty TWS objects in polar object
602
626
  app.debug('First row with TWS columns')
@@ -609,7 +633,8 @@ module.exports = function (app) {
609
633
  } else if (row.filter(i => i === '0').length > 1) {
610
634
  app.debug('beat and run angles are included')
611
635
  // Beat / Run angle
612
- let angle = degToRad(Number(row[0]))
636
+ let angleDeg = Number(row[0])
637
+ let angle = degToRad(angleDeg)
613
638
  let angleName
614
639
  let VMGName
615
640
  app.debug('angle < halfPi %d < %d', angle, halfPi)
@@ -624,17 +649,23 @@ module.exports = function (app) {
624
649
  }
625
650
 
626
651
  for (let index = 0; index < row.length - 1; index++) {
627
- if (row[index + 1] != 0) {
652
+ if (!row[index + 1]) {
653
+ continue
654
+ }
655
+ const tbsCell = Number(row[index + 1])
656
+ if (Number.isNaN(tbsCell) || tbsCell === 0) {
657
+ continue
658
+ }
659
+ if (tbsCell != 0) {
628
660
  polar[index][angleName] = angle
629
- let tbs =
630
- ktsToMs(Number(row[index + 1])) * (options.perfAdjust || 1)
661
+ let tbs = ktsToMs(tbsCell) * (options.perfAdjust || 1)
631
662
  let vmg = tbs * Math.abs(Math.cos(angle))
632
663
  polar[index][VMGName] = roundDec(vmg)
633
664
  if (typeof polar[index]['twa'] == 'undefined') {
634
665
  polar[index]['twa'] = []
635
666
  }
636
667
  let Obj = { twa: angle, tbs: tbs, vmg: vmg }
637
- polar[index]['twa'] = polar[index]['twa'].concat(Obj)
668
+ upsertTwa(index, Obj, angleDeg)
638
669
  app.debug('Finding max speed')
639
670
  if (
640
671
  typeof polar[index]['Max speed'] == 'undefined' ||
@@ -648,17 +679,24 @@ module.exports = function (app) {
648
679
  }
649
680
  } else {
650
681
  // Normal line
651
- let angle = degToRad(Number(row[0])) // CSV deg to internal rad
682
+ let angleDeg = Number(row[0])
683
+ let angle = degToRad(angleDeg) // CSV deg to internal rad
652
684
  for (let index = 0; index < row.length - 1; index++) {
653
685
  if (typeof polar[index].twa == 'undefined') {
654
686
  polar[index].twa = []
655
687
  }
656
- let tbs =
657
- ktsToMs(Number(row[index + 1])) * (options.perfAdjust || 1)
688
+ if (!row[index + 1]) {
689
+ continue
690
+ }
691
+ const tbsCell = Number(row[index + 1])
692
+ if (Number.isNaN(tbsCell)) {
693
+ continue
694
+ }
695
+ let tbs = ktsToMs(tbsCell) * (options.perfAdjust || 1)
658
696
  let vmg = tbs * Math.abs(Math.cos(angle))
659
697
  let Obj = { twa: angle, tbs: tbs, vmg: vmg }
660
698
  // app.debug('Adding Obj: %s', JSON.stringify(Obj))
661
- polar[index]['twa'] = polar[index]['twa'].concat(Obj)
699
+ upsertTwa(index, Obj, angleDeg)
662
700
  // See if we need to set/overwrite beat/run angle
663
701
 
664
702
  // See if this a new Max speed