signalk-polar-performance-plugin 0.0.22 → 0.0.24

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 +56 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-polar-performance-plugin",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
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
@@ -5,6 +5,7 @@ module.exports = function (app) {
5
5
  var plugin = {}
6
6
  var unsubscribes = []
7
7
  var timers = []
8
+ var damping = {}
8
9
 
9
10
  plugin.id = 'signalk-polar-performance-plugin'
10
11
  plugin.name = 'Polar performance plugin'
@@ -49,6 +50,22 @@ module.exports = function (app) {
49
50
  type: 'boolean',
50
51
  title: 'Enable writing of maximum speed angle and boat speed for a given TWS'
51
52
  },
53
+ dampingTWA: {
54
+ type: 'number',
55
+ description: 'If data appears erratic or too sensitive, damping may be applied to amke information appear more stable. With damping set to 0, the data is presented in raw form wih no damping applied.',
56
+ title: 'True Wind Angle damping seconds',
57
+ default: 1
58
+ },
59
+ dampingTWS: {
60
+ type: 'number',
61
+ title: 'True Wind Speed damping seconds',
62
+ default: 1
63
+ },
64
+ dampingBSP: {
65
+ type: 'number',
66
+ title: 'Boat speed damping damping',
67
+ default: 1
68
+ },
52
69
  csvTable: {
53
70
  type: "string",
54
71
  title: "Copy/paste the csv content of the polar in http://jieter.github.io/orc-data/site/ style."
@@ -141,20 +158,21 @@ module.exports = function (app) {
141
158
  deltas.forEach(delta => {
142
159
  // app.debug('handleData: %s', JSON.stringify(delta))
143
160
  if (delta.path == 'navigation.speedThroughWater') {
144
- STW = delta.value
161
+ STW = applyDamping (delta.value, 'BSP', options.dampingBSP || 0)
145
162
  BSP = STW
146
163
  // app.debug('speedThroughWater (STW): %d', STW)
147
164
  } else if (delta.path == 'navigation.speedOverGround') {
148
- SOG = delta.value
165
+ SOG = applyDamping (delta.value, 'BSP', options.dampingBSP || 0)
149
166
  BSP = SOG
150
167
  // app.debug('speedThroughWater (STW): %d', STW)
151
168
  } else if (delta.path == 'navigation.headingTrue') {
152
169
  HDG = delta.value
153
170
  // app.debug('heading (HDG): %d', HDG)
154
171
  } else if (delta.path == 'environment.wind.speedTrue') {
155
- TWS = delta.value
156
- // app.debug('environment.wind.speedTrue (TWS): %d', TWS)
157
- app.debug('TWS: %d TWA: %d BSP: %d', msToKts(TWS), radToDeg(TWA)*port, msToKts(BSP))
172
+ // applyDamping (Xn, unit, a, n)
173
+ TWS = applyDamping (delta.value, 'TWS', options.dampingTWS || 0)
174
+ // app.debug('environment.wind.speedTrue (TWS): %d applyDamping: %d', delta.value, TWS)
175
+ // app.debug('TWS: %d TWA: %d BSP: %d', msToKts(TWS), radToDeg(TWA)*port, msToKts(BSP))
158
176
  sendUpdates(getPerformanceData(TWS, TWA, BSP))
159
177
  } else if (delta.path == 'environment.wind.angleTrueWater') {
160
178
  if (delta.value < 0) {
@@ -162,7 +180,8 @@ module.exports = function (app) {
162
180
  } else {
163
181
  port = 1
164
182
  }
165
- TWA = Math.abs(delta.value)
183
+ TWA = Math.abs(applyDamping (delta.value, 'TWA', options.dampingTWA || 0))
184
+ app.debug('environment.wind.angleTrueWater (TWA): %s applyDamping: %s', radToDeg(delta.value).toFixed(0), radToDeg(TWA).toFixed(0))
166
185
  }
167
186
  })
168
187
  }
@@ -210,10 +229,12 @@ module.exports = function (app) {
210
229
  if (typeof perfObj.polarSpeed != 'undefined') {
211
230
  values.push({path: 'performance.polarSpeed', value: roundDec(perfObj.polarSpeed)})
212
231
  values.push({path: 'performance.polarSpeedRatio', value: roundDec(perfObj.polarSpeedRatio)})
213
- if (options.VMG == true) {
232
+ if (typeof perfObj.velocityMadeGood != 'undefined') {
214
233
  values.push({path: 'performance.velocityMadeGood', value: roundDec(perfObj.velocityMadeGood)})
215
234
  values.push({path: 'performance.polarVelocityMadeGood', value: roundDec(perfObj.polarVelocityMadeGood)})
235
+ metas.push({path: 'performance.polarVelocityMadeGood', value: {"units": "m/s"}})
216
236
  values.push({path: 'performance.polarVelocityMadeGoodRatio', value: roundDec(perfObj.polarVelocityMadeGoodRatio)})
237
+ metas.push({path: 'performance.polarVelocityMadeGoodRatio', value: {"units": "ratio"}})
217
238
  }
218
239
  }
219
240
  if (typeof perfObj.maxSpeed != 'undefined') {
@@ -616,6 +637,27 @@ module.exports = function (app) {
616
637
  }
617
638
  return data
618
639
  }
640
+
641
+ function applyDamping (Xn, unit, RC) {
642
+ if (RC == 0) {
643
+ return Xn
644
+ } else {
645
+ if (typeof damping[unit] == 'undefined') {
646
+ // Doesn't exist yet, make obj for unit
647
+ damping[unit] = {Yn: Xn, dt: Date.now()}
648
+ }
649
+ // Calculate a
650
+ let dt = (Date.now() - damping[unit].dt)/1000
651
+ damping[unit].dt = Date.now()
652
+ let a = dt / (RC + dt)
653
+ // Yn = (1-a) * Yn-1 + a * Xn
654
+ let Yn = (1-a) * (damping[unit].Yn || Xn) + a * Xn
655
+ // Remember Yn
656
+ damping[unit].Yn = Yn
657
+ // app.debug('Unit: %s dt: %d a: %d obj: %s', unit, dt, a, JSON.stringify(damping[unit]))
658
+ return Yn
659
+ }
660
+ }
619
661
  }
620
662
 
621
663
  plugin.stop = function () {
@@ -652,6 +694,11 @@ function msToKts(ms) {
652
694
  }
653
695
 
654
696
  function roundDec (value) {
655
- value = Number(value.toFixed(3))
656
- return value
697
+ if (typeof value == 'undefined') {
698
+ return undefined
699
+ } else {
700
+ value = Number(value.toFixed(3))
701
+ return value
702
+ }
657
703
  }
704
+