Merge remote-tracking branch 'upstream/master' into abo_waypoint_bing_datum_fix
commit
335d6af9d5
@ -0,0 +1,41 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module is a queue for deduplication of MSP requests.
|
||||||
|
* We do not want to process the same request multiple times unless response is received.
|
||||||
|
* This improves wireless handling and lower amount of data that is put on the air
|
||||||
|
*/
|
||||||
|
var mspDeduplicationQueue = function() {
|
||||||
|
|
||||||
|
let publicScope = {},
|
||||||
|
privateScope = {};
|
||||||
|
|
||||||
|
privateScope.queue = [];
|
||||||
|
|
||||||
|
publicScope.put = function(item) {
|
||||||
|
privateScope.queue.push(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.remove = function(item) {
|
||||||
|
const index = privateScope.queue.indexOf(item);
|
||||||
|
if (index > -1) {
|
||||||
|
privateScope.queue.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.check = function(item) {
|
||||||
|
return privateScope.queue.includes(item);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.flush = function() {
|
||||||
|
privateScope.queue = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.get = function() {
|
||||||
|
return privateScope.queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
return publicScope;
|
||||||
|
}();
|
||||||
|
|
||||||
|
module.exports = mspDeduplicationQueue;
|
@ -0,0 +1,39 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var mspStatistics = function() {
|
||||||
|
|
||||||
|
let publicScope = {},
|
||||||
|
privateScope = {};
|
||||||
|
|
||||||
|
privateScope.statistics = {};
|
||||||
|
|
||||||
|
|
||||||
|
publicScope.add = function(code, duration) {
|
||||||
|
if (!privateScope.statistics[code]) {
|
||||||
|
privateScope.statistics[code] = {
|
||||||
|
ctime: new Date().getTime(),
|
||||||
|
count: 0,
|
||||||
|
duration: 0,
|
||||||
|
average: 0,
|
||||||
|
callsPerSecond: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
privateScope.statistics[code].count++;
|
||||||
|
privateScope.statistics[code].duration += duration;
|
||||||
|
privateScope.statistics[code].average = privateScope.statistics[code].duration / privateScope.statistics[code].count;
|
||||||
|
privateScope.statistics[code].callsPerSecond = privateScope.statistics[code].count / ((new Date().getTime() - privateScope.statistics[code].ctime) / 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.get = function() {
|
||||||
|
return privateScope.statistics;
|
||||||
|
};
|
||||||
|
|
||||||
|
publicScope.reset = function() {
|
||||||
|
privateScope.statistics = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
return publicScope;
|
||||||
|
|
||||||
|
}();
|
||||||
|
|
||||||
|
module.exports = mspStatistics;
|
@ -1,75 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const mspQueue = require('./serial_queue');
|
|
||||||
const interval = require('./intervals');
|
|
||||||
|
|
||||||
var mspBalancedInterval = (function (mspQueue, intervalHandler) {
|
|
||||||
|
|
||||||
var publicScope = {},
|
|
||||||
privateScope = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How often balancing should be executed [Hz]
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.balancingFrequency = 0.5;
|
|
||||||
|
|
||||||
privateScope.intervals = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} name
|
|
||||||
* @param {number} requestedInterval
|
|
||||||
* @param {number} messagesInInterval
|
|
||||||
* @param {function} code
|
|
||||||
*/
|
|
||||||
publicScope.add = function (name, requestedInterval, messagesInInterval, code) {
|
|
||||||
privateScope.intervals.push({
|
|
||||||
name: name,
|
|
||||||
requestedInterval: requestedInterval,
|
|
||||||
messagesInInterval: messagesInInterval,
|
|
||||||
code: code
|
|
||||||
});
|
|
||||||
|
|
||||||
intervalHandler.add(name, code, mspQueue.getIntervalPrediction(requestedInterval, messagesInInterval));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Periodically executed balancing handler
|
|
||||||
*/
|
|
||||||
publicScope.balancer = function () {
|
|
||||||
|
|
||||||
var interval;
|
|
||||||
|
|
||||||
for (var i in privateScope.intervals) {
|
|
||||||
if (privateScope.intervals.hasOwnProperty(i)) {
|
|
||||||
interval = privateScope.intervals[i];
|
|
||||||
|
|
||||||
intervalHandler.remove(interval.name);
|
|
||||||
intervalHandler.add(
|
|
||||||
interval.name,
|
|
||||||
interval.code,
|
|
||||||
mspQueue.getIntervalPrediction(
|
|
||||||
interval.requestedInterval,
|
|
||||||
interval.messagesInInterval
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Real interval cleaning happens win interval.killAll method
|
|
||||||
* both methods have to be executed
|
|
||||||
*/
|
|
||||||
publicScope.flush = function () {
|
|
||||||
privateScope.intervals = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
setInterval(publicScope.balancer, Math.round(1000 / privateScope.balancingFrequency));
|
|
||||||
|
|
||||||
return publicScope;
|
|
||||||
})(mspQueue, interval);
|
|
||||||
|
|
||||||
module.exports = mspBalancedInterval;
|
|
@ -1,130 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
|
|
||||||
var PidController = function () {
|
|
||||||
|
|
||||||
var self = {},
|
|
||||||
privateScope = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.target = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{P: null, I: null, D: null}}
|
|
||||||
*/
|
|
||||||
privateScope.gains = {
|
|
||||||
P: null,
|
|
||||||
I: null,
|
|
||||||
D: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.Iterm = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{min: number, max: number}}
|
|
||||||
*/
|
|
||||||
privateScope.ItermLimit = {
|
|
||||||
min: -1000,
|
|
||||||
max: 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
privateScope.previousError = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {{min: number, max: number, minThreshold: number}}
|
|
||||||
*/
|
|
||||||
privateScope.output = {
|
|
||||||
min: null,
|
|
||||||
max: null,
|
|
||||||
minThreshold: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {number} value
|
|
||||||
*/
|
|
||||||
self.setTarget = function (value) {
|
|
||||||
privateScope.target = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} Pgain
|
|
||||||
* @param {number} Igain
|
|
||||||
* @param {number} Dgain
|
|
||||||
*/
|
|
||||||
self.setGains = function (Pgain, Igain, Dgain) {
|
|
||||||
privateScope.gains.P = Pgain;
|
|
||||||
privateScope.gains.I = Igain;
|
|
||||||
privateScope.gains.D = Dgain;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets min and max value for output
|
|
||||||
* @param {number} min
|
|
||||||
* @param {number} max
|
|
||||||
* @param {number} minThreshold if output is below this value, [min] is returned
|
|
||||||
*/
|
|
||||||
self.setOutput = function (min, max, minThreshold) {
|
|
||||||
privateScope.output.min = min;
|
|
||||||
privateScope.output.max = max;
|
|
||||||
privateScope.output.minThreshold = minThreshold;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets upper and lower limit for Iterm accumulator
|
|
||||||
* @param {number} min
|
|
||||||
* @param {number} max
|
|
||||||
*/
|
|
||||||
self.setItermLimit = function (min, max) {
|
|
||||||
privateScope.ItermLimit.min = min;
|
|
||||||
privateScope.ItermLimit.max = max;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes PID controller based on current value and target
|
|
||||||
* @param {number} current
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
self.run = function (current) {
|
|
||||||
var error = current - privateScope.target,
|
|
||||||
Pterm = error * privateScope.gains.P,
|
|
||||||
Dterm = (error - privateScope.previousError) * privateScope.gains.D,
|
|
||||||
output;
|
|
||||||
|
|
||||||
privateScope.previousError = error;
|
|
||||||
|
|
||||||
privateScope.Iterm += error * privateScope.gains.I;
|
|
||||||
if (privateScope.Iterm > privateScope.ItermLimit.max) {
|
|
||||||
privateScope.Iterm = privateScope.ItermLimit.max;
|
|
||||||
} else if (privateScope.Iterm < privateScope.ItermLimit.min) {
|
|
||||||
privateScope.Iterm = privateScope.ItermLimit.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = Pterm + privateScope.Iterm + Dterm;
|
|
||||||
if (output < privateScope.output.minThreshold) {
|
|
||||||
output = privateScope.output.min;
|
|
||||||
} else if (output > privateScope.output.max) {
|
|
||||||
output = privateScope.output.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
return self;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = PidController;
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue