signalk-polar-performance-plugin 0.0.14 → 0.0.15

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 +44 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-polar-performance-plugin",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
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
@@ -28,6 +28,10 @@ module.exports = function (app) {
28
28
  type: 'boolean',
29
29
  title: 'Enable sending Target TWA (performance.targetAngle)'
30
30
  },
31
+ tackTrue: {
32
+ type: 'boolean',
33
+ title: 'Enable calculating Opposite Tack True (performance.tackTrue)'
34
+ },
31
35
  optimumWindAngle: {
32
36
  type: 'boolean',
33
37
  title: 'Enable calculation of Optimum Wind Angle (difference between TWA and beat/run angle (depends on beat/run angle)'
@@ -64,7 +68,7 @@ module.exports = function (app) {
64
68
  app.debug('polar: %s', JSON.stringify(polar))
65
69
 
66
70
  // Global variables
67
- var BSP, STW, TWA, TWS, port // Angles in rad, speed in m/s
71
+ var BSP, STW, TWA, targetTWA, TWS, HDG, port // Angles in rad, speed in m/s
68
72
  var halfPi = Math.PI / 2
69
73
 
70
74
  // Subscribe to paths
@@ -93,6 +97,12 @@ module.exports = function (app) {
93
97
  policy: 'instant'
94
98
  })
95
99
  }
100
+ if (options.tackTrue == true) {
101
+ localSubscription.subscribe.push({
102
+ path: 'navigation.headingTrue',
103
+ policy: 'instant'
104
+ })
105
+ }
96
106
 
97
107
  app.subscriptionmanager.subscribe(
98
108
  localSubscription,
@@ -120,6 +130,9 @@ module.exports = function (app) {
120
130
  SOG = delta.value
121
131
  BSP = SOG
122
132
  // app.debug('speedThroughWater (STW): %d', STW)
133
+ } else if (delta.path == 'navigation.headingTrue') {
134
+ HDG = delta.value
135
+ // app.debug('heading (HDG): %d', HDG)
123
136
  } else if (delta.path == 'environment.wind.speedTrue') {
124
137
  TWS = delta.value
125
138
  // app.debug('environment.wind.speedTrue (TWS): %d', TWS)
@@ -186,6 +199,11 @@ module.exports = function (app) {
186
199
  values.push({path: 'performance.maxSpeedAngle', value: roundDec(perfObj.maxSpeedAngle)})
187
200
  metas.push({path: 'performance.maxSpeedAngle', value: {"units": "rad"}})
188
201
  }
202
+ if (options.tackTrue == true) {
203
+ if (typeof perfObj.tackTrue != 'undefined') {
204
+ values.push({path: 'performance.tackTrue', value: roundDec(perfObj.tackTrue)})
205
+ }
206
+ }
189
207
 
190
208
  app.debug('sendUpdates: %s', JSON.stringify(values))
191
209
  app.handleMessage(plugin.id, {
@@ -218,6 +236,7 @@ module.exports = function (app) {
218
236
  let beatLower = polar[indexTWS]['Beat angle']
219
237
  let beatUpper = polar[indexTWS+1]['Beat angle']
220
238
  performance.beatAngle = beatLower + ((beatUpper - beatLower) * twsGapRatio)
239
+ targetTWA = performance.beatAngle
221
240
  }
222
241
  // Calculate optimum wind angle (B&G thing)
223
242
  if (options.optimumWindAngle == true) {
@@ -239,6 +258,7 @@ module.exports = function (app) {
239
258
  let runUpper = polar[indexTWS+1]['Run angle']
240
259
  //app.debug('runLower: %s runUpper: %s', runLower, runUpper)
241
260
  performance.runAngle = runLower + ((runUpper - runLower) * twsGapRatio)
261
+ targetTWA = performance.runAngle
242
262
  }
243
263
  if (options.optimumWindAngle == true) {
244
264
  if (typeof performance.runAngle != 'undefined') {
@@ -254,6 +274,21 @@ module.exports = function (app) {
254
274
  performance.runVMG = VMGLower + ((VMGUpper - VMGLower) * twsGapRatio)
255
275
  }
256
276
  }
277
+ // Calculate opposite Tack True
278
+ // app.debug('tackTrue: port: %d HDG: %d targetTWA: %d', port, radToDeg(HDG), radToDeg(targetTWA))
279
+ if (port) {
280
+ let tackTrue = HDG - targetTWA
281
+ if (tackTrue < 0) {
282
+ tackTrue = tackTrue + (2*Math.PI)
283
+ }
284
+ performance.tackTrue = tackTrue
285
+ } else {
286
+ let tackTrue = HDG + targetTWA
287
+ if (tackTrue > (2*Math.PI)) {
288
+ tackTrue = tackTrue - (2*Math.PI)
289
+ }
290
+ performance.tackTrue = tackTrue
291
+ }
257
292
  // Calculate polar target boat speed
258
293
 
259
294
  // Interpolate Define the 4 near data points
@@ -420,9 +455,9 @@ module.exports = function (app) {
420
455
  for (let index = 0; index < polar.length-1; index++) {
421
456
  let tws = polar[index].tws
422
457
  let beatVMG = 0
423
- let beatVMGelement = 0
458
+ let beatElement = 0
424
459
  let runVMG = 0
425
- let runVMGelement = 0
460
+ let runElement = 0
426
461
 
427
462
  let twaArray = polar[index].twa
428
463
  for (let element = 0; element < twaArray.length-1; element++) {
@@ -439,12 +474,12 @@ module.exports = function (app) {
439
474
  }
440
475
  }
441
476
  }
442
- app.debug('beatVMG for %d is %d (angel %d)', tws, twaArray[beatVMGelement].vmg, twaArray[beatVMGelement].twa)
443
- app.debug(' runVMG for %d is %d (angel %d)', tws, twaArray[runVMGelement].vmg, twaArray[runVMGelement].twa)
444
- polar[index]['Beat angle'] = twaArray[beatVMGelement].twa
445
- polar[index]['Beat VMG'] = twaArray[beatVMGelement].vmg
446
- polar[index]['Run angle'] = twaArray[runVMGelement].twa
447
- polar[index]['Run VMG'] = twaArray[runVMGelement].vmg
477
+ app.debug('beatVMG for %d is %d (angel %d)', tws, twaArray[beatElement].vmg, twaArray[beatElement].twa)
478
+ app.debug(' runVMG for %d is %d (angel %d)', tws, twaArray[runElement].vmg, twaArray[runElement].twa)
479
+ polar[index]['Beat angle'] = twaArray[beatElement].twa
480
+ polar[index]['Beat VMG'] = twaArray[beatElement].vmg
481
+ polar[index]['Run angle'] = twaArray[runElement].twa
482
+ polar[index]['Run VMG'] = twaArray[runElement].vmg
448
483
  }
449
484
 
450
485
  }