From a98f3fa379f9d40ab8e4d126a13bf7b2fd9033d4 Mon Sep 17 00:00:00 2001 From: Darko Lukic Date: Mon, 5 Dec 2016 23:07:33 +0100 Subject: [PATCH] Implement mechanism to validate if driver is implemented correctly --- src/drivers/DriverManager.js | 14 +++-- src/drivers/laser/LaserDriver.js | 8 ++- src/drivers/modbus/ModbusDriverSimulator.js | 8 ++- src/drivers/motion/MotionDriver.js | 2 - src/drivers/motion/MotionDriverSimulator.js | 8 ++- src/types/BaseDriver.js | 15 ------ src/types/PositionDriver.js | 15 ------ src/types/TerrainDriver.js | 11 ---- src/types/TunedAngle.js | 59 +++++++++++++++++++++ src/utils/DriverChecker.js | 47 ++++++++++++++++ strategies/default/InitTask.js | 25 +-------- 11 files changed, 137 insertions(+), 75 deletions(-) delete mode 100644 src/types/BaseDriver.js delete mode 100644 src/types/PositionDriver.js delete mode 100644 src/types/TerrainDriver.js create mode 100644 src/types/TunedAngle.js create mode 100644 src/utils/DriverChecker.js diff --git a/src/drivers/DriverManager.js b/src/drivers/DriverManager.js index 16a6089..220b468 100644 --- a/src/drivers/DriverManager.js +++ b/src/drivers/DriverManager.js @@ -1,4 +1,5 @@ /** @namespace drivers */ +const DriverChecker = Mep.require('utils/DriverChecker'); const TAG = 'DriverManager'; @@ -62,7 +63,7 @@ class DriverManager { let load = moduleConfig.load; let classPath = moduleConfig.class; - // Do not initialize if `init field == false` + // Do not initialize if `load field == false` if (load != false) { let ModuleClass = Mep.require(classPath); @@ -72,14 +73,21 @@ class DriverManager { } if (typeof ModuleClass === 'function') { + let driverInstance; + let loadedWithoutErrors = true; try { - let driverInstance = new ModuleClass(driverIdentifier, moduleConfig); + driverInstance = new ModuleClass(driverIdentifier, moduleConfig); this.drivers[driverIdentifier] = driverInstance; Mep.Log.debug(TAG, 'Driver `' + driverIdentifier + '` loaded'); - } catch (error) { + loadedWithoutErrors = false; this.putDriverOutOfOrder(driverIdentifier, error); } + + // Test if all methods are OK + if (loadedWithoutErrors === true) { + DriverChecker.check(driverInstance); + } } else { diff --git a/src/drivers/laser/LaserDriver.js b/src/drivers/laser/LaserDriver.js index d680ea2..cbd1417 100644 --- a/src/drivers/laser/LaserDriver.js +++ b/src/drivers/laser/LaserDriver.js @@ -1,6 +1,6 @@ /** @namespace drivers.laser */ -const TerrainDriver = Mep.require('types/TerrainDriver'); +const EventEmitter = require('events'); const Point = Mep.require('types/Point'); const Polygon = Mep.require('types/Polygon'); @@ -13,7 +13,7 @@ const TAG = 'LaserDriver'; * @author Darko Lukic * @fires LaserDriver#terrain */ -class LaserDriver extends TerrainDriver { +class LaserDriver extends EventEmitter { /** * Make instance of LaserDriver. * @@ -119,6 +119,10 @@ class LaserDriver extends TerrainDriver { static dependencies() { return ['ModbusDriver']; } + + getGroups() { + return ['terrain']; + } } module.exports = LaserDriver; \ No newline at end of file diff --git a/src/drivers/modbus/ModbusDriverSimulator.js b/src/drivers/modbus/ModbusDriverSimulator.js index b3708c0..69a3a9b 100644 --- a/src/drivers/modbus/ModbusDriverSimulator.js +++ b/src/drivers/modbus/ModbusDriverSimulator.js @@ -1,8 +1,8 @@ -const BaseDriver = Mep.require('types/BaseDriver'); +const EventEmitter = require('events'); const TAG = 'ModbusDriverSimulator'; -class ModbusDriverSimulator extends BaseDriver { +class ModbusDriverSimulator extends EventEmitter { constructor(name, config) { super(); @@ -12,6 +12,10 @@ class ModbusDriverSimulator extends BaseDriver { registerCoilReading(slaveAddress, functionAddress) { } + + getGroups() { + return []; + } } module.exports = ModbusDriverSimulator; \ No newline at end of file diff --git a/src/drivers/motion/MotionDriver.js b/src/drivers/motion/MotionDriver.js index dc5445c..0f28aa4 100644 --- a/src/drivers/motion/MotionDriver.js +++ b/src/drivers/motion/MotionDriver.js @@ -1,10 +1,8 @@ const MotionDriverBinder = require('bindings')('motion').MotionDriverBinder; const Point = Mep.require('types/Point'); -const PositionDriver = Mep.require('types/PositionDriver'); const Constants = require('./Constants'); const Util = require('util'); const EventEmitter = require('events'); -//const mixin = require('es6-mixin').mixin; Util.inherits(MotionDriverBinder, EventEmitter); diff --git a/src/drivers/motion/MotionDriverSimulator.js b/src/drivers/motion/MotionDriverSimulator.js index a82b95c..39db033 100644 --- a/src/drivers/motion/MotionDriverSimulator.js +++ b/src/drivers/motion/MotionDriverSimulator.js @@ -1,6 +1,6 @@ const WebSocketClient = Mep.require('utils/WebSocketClient'); const Point = Mep.require('types/Point'); -const PositionDriver = Mep.require('types/PositionDriver'); +const EventEmitter = require('events'); const TAG = 'MotionDriverSimulator'; @@ -32,7 +32,7 @@ const TAG = 'MotionDriverSimulator'; * } * */ -class MotionDriverSimulator extends PositionDriver { +class MotionDriverSimulator extends EventEmitter { constructor(name, config) { super(); @@ -117,6 +117,10 @@ class MotionDriverSimulator extends PositionDriver { params: params })); } + + getGroups() { + return ['position']; + } } module.exports = MotionDriverSimulator; \ No newline at end of file diff --git a/src/types/BaseDriver.js b/src/types/BaseDriver.js deleted file mode 100644 index ff694a7..0000000 --- a/src/types/BaseDriver.js +++ /dev/null @@ -1,15 +0,0 @@ -const EventEmitter = require('events').EventEmitter; - -class BaseDriver extends EventEmitter { - constructor() { - super(); - - this.groups = []; - } - - getGroups() { - return this.groups; - } -} - -module.exports = BaseDriver; diff --git a/src/types/PositionDriver.js b/src/types/PositionDriver.js deleted file mode 100644 index fceb331..0000000 --- a/src/types/PositionDriver.js +++ /dev/null @@ -1,15 +0,0 @@ -const BaseDriver = require('./BaseDriver'); - -class PositionDriver extends BaseDriver { - constructor() { - super(); - - if (typeof this.getPosition !== 'function') { - throw new TypeError("Must override getPosition()"); - } - - this.groups.push('position'); - } -} - -module.exports = PositionDriver; diff --git a/src/types/TerrainDriver.js b/src/types/TerrainDriver.js deleted file mode 100644 index cfdac0e..0000000 --- a/src/types/TerrainDriver.js +++ /dev/null @@ -1,11 +0,0 @@ -const BaseDriver = require('./BaseDriver'); - -class TerrainDriver extends BaseDriver { - constructor() { - super(); - - this.groups.push('terrain'); - } -} - -module.exports = TerrainDriver; \ No newline at end of file diff --git a/src/types/TunedAngle.js b/src/types/TunedAngle.js new file mode 100644 index 0000000..c4f5ea8 --- /dev/null +++ b/src/types/TunedAngle.js @@ -0,0 +1,59 @@ +/** @namespace types */ + +const TAG = 'TunedAngle'; + +/** + * Tunable angle. Angle is chosen depends on table name in configuration. + * + * @author Darko Lukic + * @memberof types + * @example + * new TunePoint( + * 150, 129, + * [151, 129, 'table_1'], + * [148, 128, 'table_2'] + * ); + */ +class TunedAngle { + /** + * Add multiple Points, add Points for each table. It must has + * at least one Point which will be used as default. Other Points + * must have tag! + * + * @param defaultX {integer} - Default point X coordinate + */ + constructor(defaultAngle) { + // If there are table dependent points + for (let i = 1; i < arguments.length; i++) { + + // Check if the argument is valid + if (typeof arguments[i][0] === 'undefined' || + typeof arguments[i][1] === 'undefined') { + + Mep.Log.warn(TAG, 'Invalid arguments'); + continue; + } + + // Check if table name matches + if (Mep.Config.get('table') == arguments[i][1]) { + this.point = arguments[i][0]; + } + } + + // Otherwise use default point + if (typeof this.point === 'undefined') { + this.angle = defaultAngle; + } + } + + /** + * Get angle depending on the chosen table in configuration. + * + * @returns {number} - Point + */ + getAngle() { + return this.angle; + } +} + +module.exports = TunedAngle; diff --git a/src/utils/DriverChecker.js b/src/utils/DriverChecker.js new file mode 100644 index 0000000..cad5477 --- /dev/null +++ b/src/utils/DriverChecker.js @@ -0,0 +1,47 @@ +/** + * A goal of the class is to check if drivers are correctly implemented. + * + * @author Darko Lukic + * @memberOf utils + */ + +class DriverChecker { + static check(driver) { + let groups; + if (typeof driver.getGroups === 'function') { + groups = driver.getGroups(); + } else { + throw TypeError(driver.constructor.name + ' doesn\'t have member getGroups()'); + } + + for (let group of groups) { + switch (group) { + case 'position': + DriverChecker._checkPosition(driver); + break; + + case 'terrain': + DriverChecker._checkTerrain(driver); + break; + } + } + } + + static _checkPosition(driver) { + let driverClassName = driver.constructor.name; + + // Check getPosition() + if (typeof driver.getPosition !== 'function') { + throw TypeError(driverClassName + ' requires method getPosition()'); + } + if (driver.getPosition().constructor.name !== 'Point') { + throw TypeError('Method '+ driverClassName +'.getPosition() must return Point'); + } + } + + static _checkTerrain(driver) { + + } +} + +module.exports = DriverChecker; diff --git a/strategies/default/InitTask.js b/strategies/default/InitTask.js index 1c7b2d3..a8a4933 100644 --- a/strategies/default/InitTask.js +++ b/strategies/default/InitTask.js @@ -9,30 +9,9 @@ class InitTask extends Task { // Wait WebSocketClient to connect to WebSocketServer await Delay(200); - await position.set(new TunedPoint(1100, 0), { speed: 130 }); - await position.set(new TunedPoint(-1300, 0)); - - - if (false) { - await position.set(new TunedPoint(-1100, 0), { speed: 40 }); - await position.arc(new Point(-1300, 100), 30, 1); - await position.arc(new Point(-1300, 100), 60, 1); - } - - if (false) { - await position.set(new TunedPoint(-1200, 0), { speed: 40 }); - await position.set(new TunedPoint(-735, -850), { pathfinding: true }); - await position.set(new TunedPoint(765, -850), { pathfinding: true }); - await position.set(new TunedPoint(-1200, 0), { pathfinding: true }); - } - - //await position.set(new TunedPoint(-1300, 0)); - // Let's move around - //await position.set(new TunedPoint(-735, -850), { pathfinding: true }); - //await position.set(new TunedPoint(765, -850), { pathfinding: true }); - //await position.set(new TunedPoint(-1200, 400), { pathfinding: true }); - //await position.set(new TunedPoint(-170, 820), { pathfinding: true }); + await position.set(new TunedPoint(1100, 0), {speed: 130}); + await position.set(new TunedPoint(-1300, 0)); } }