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