/** * Created by fab on 3/16/15. */ function Machine() { this.hasStock = false; this.meshes = {}; var self = this; this._buildMeshes(function(meshes){ self.meshes = meshes; _.each(_.values(meshes), function(mesh){ dmaGlobals.three.sceneAdd(mesh); }); self.setVisibility(); }); this.cell = this._makeStockCell(); this.setVisibility(false); } Machine.prototype.setVisibility = function(visible){ if (visible == null || visible === undefined) visible = dmaGlobals.assembler.isVisible(); if (visible && this.hasStock) this.cell.draw(); else this.cell.hide(); this._setMeshesVisiblity(visible); }; Machine.prototype._setMeshesVisiblity = function(visible){ _.each(_.values(this.meshes), function(mesh){ mesh.visible = visible; }); }; Machine.prototype._makeStockCell = function(){ return dmaGlobals.lattice.makeCellForLatticeType(null, dmaGlobals.lattice.get("scale")); }; Machine.prototype.updateCellType = function(){ if (this.cell) this.cell.destroy(); this.cell = this._makeStockCell(); this.setVisibility(); }; Machine.prototype.updatePartType = function(){ this.cell.destroyParts(); this.cell.draw(); this.setVisibility(); }; Machine.prototype.pickUpStock = function(){ this.hasStock = true; this.cell.draw(); }; Machine.prototype.releaseStock = function(index){ this.hasStock = false; dmaGlobals.lattice.showCellAtIndex(JSON.parse(index)); this.cell.hide(); }; Machine.prototype.pause = function(){ }; Machine.prototype.moveTo = function(x, y, z, speed, wcs, callback){ x = this._makeAbsPosition(x, wcs.x); y = this._makeAbsPosition(y, wcs.y); z = this._makeAbsPosition(z, wcs.z); this._moveTo(x, y, z, speed, wcs, callback); }; Machine.prototype._makeAbsPosition = function(target, wcs){ if (target == "" || target == null || target === undefined) return null; return parseFloat(target)+wcs; }; Machine.prototype._reorganizeSpeed = function(speed){ var newSpeed = {}; newSpeed.x = speed.xy; newSpeed.y = speed.xy; newSpeed.z = speed.z; return newSpeed; } Machine.prototype._normalizeSpeed = function(startingPos, x, y, speed){//xy moves need speed normalization var normSpeed = {}; if (x == "" || y == "") return speed; var deltaX = x-startingPos.x; var deltaY = y-startingPos.y; var totalDistance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); if (totalDistance == 0) return speed; normSpeed.x = Math.abs(deltaX/totalDistance*speed.x); normSpeed.y = Math.abs(deltaY/totalDistance*speed.y); normSpeed.z = speed.z; return normSpeed; }; Machine.prototype._animateObjects = function(objects, axis, speed, startingPos, target, callback){ var increment = speed/5;//based on 1/10th of sec if (increment == 0) { if (callback) callback(); return; } var direction = 1; if (target-startingPos < 0) direction = -1; increment = Math.max(increment, 0.00001)*direction;//need to put a min on the increment - other wise this stall out with floating pt tol var simSpeed = 50/dmaGlobals.assembler.get("simSpeed");//1/10th of sec this._incrementalMove(objects, axis, increment, startingPos, target, direction, callback, simSpeed); }; Machine.prototype._incrementalMove = function(objects, axis, increment, currentPos, target, direction, callback, simSpeed){ var self = this; setTimeout(function(){ if ((target-currentPos)*direction <= 0) { if (callback) callback(); return; } var nextPos = currentPos + increment; if (Math.abs(target-currentPos) < Math.abs(increment)) nextPos = target;//don't overshoot _.each(objects, function(object){ if (object instanceof DMACell) object.moveTo(nextPos, axis); else object.position[axis] = nextPos; }); self._incrementalMove(objects, axis, increment, nextPos, target, direction, callback, simSpeed) },simSpeed); }; /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////POST PROCESS////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// Machine.prototype.postProcess = function(data, exporter){//override in subclasses var rapidHeight = dmaGlobals.assembler.get("rapidHeight"); var safeHeight = dmaGlobals.assembler.get("safeHeight"); var wcs = dmaGlobals.assembler.get("originPosition"); var stockPosition = dmaGlobals.assembler.get("stockPosition"); var stockNum = 0;//position of stock in stock array var multStockPositions = dmaGlobals.assembler.get("multipleStockPositions"); var stockSeparation = dmaGlobals.assembler.get("stockSeparation"); var stockArraySize = dmaGlobals.assembler.get("stockArraySize"); var self = this; dmaGlobals.lattice.rasterCells(dmaGlobals.assembler._getOrder(dmaGlobals.assembler.get("camStrategy")), function(cell){ if (!cell) return; var thisStockPosition = _.clone(stockPosition); if (multStockPositions) { thisStockPosition.x += stockNum % stockArraySize.y * stockSeparation; thisStockPosition.y -= Math.floor(stockNum / stockArraySize.y) * stockSeparation; stockNum += 1; if (stockNum >= stockArraySize.x * stockArraySize.y) stockNum = 0; } data += self._postPickUpStock(exporter, thisStockPosition, rapidHeight, wcs, safeHeight); data += self._postReleaseStock(cell, exporter, rapidHeight, wcs, safeHeight); data += "\n"; }); return data; }; Machine.prototype._postPickUpStock = function(exporter, stockPosition, rapidHeight, wcs, safeHeight){ var data = ""; data += exporter.rapidXY(stockPosition.x-wcs.x, stockPosition.y-wcs.y); data += exporter.rapidZ(stockPosition.z-wcs.z+safeHeight); data += exporter.moveZ(stockPosition.z-wcs.z); data += exporter.addComment("get stock"); data += exporter.moveZ(stockPosition.z-wcs.z+safeHeight); data += exporter.rapidZ(rapidHeight); return data; }; Machine.prototype._postReleaseStock = function(cell, exporter, rapidHeight, wcs, safeHeight){ var data = ""; var cellPosition = cell.getPosition(); data += exporter.rapidXY(cellPosition.x-wcs.x, cellPosition.y-wcs.y); data += exporter.rapidZ(cellPosition.z-wcs.z+safeHeight); data += exporter.moveZ(cellPosition.z-wcs.z); data += exporter.addComment(JSON.stringify(cell.indices)); data += exporter.moveZ(cellPosition.z-wcs.z+safeHeight); data += exporter.rapidZ(rapidHeight); return data; }; /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////DEALLOCATE//////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// Machine.prototype.destroy = function(){ this.cell.destroy(); _.each(_.values(this.meshes), function(mesh){ dmaGlobals.three.sceneRemove(mesh); mesh = null; }); this.meshes = null; }; /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////SHOPBOT/////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// function Shopbot(){ Machine.call(this); } Shopbot.prototype = Object.create(Machine.prototype); Shopbot.prototype._buildMeshes = function(callback){ var meshes = {}; (new THREE.STLLoader()).load("assets/stls/shopbot/shopbotEndEffector.stl", function(geometry){ geometry.computeBoundingBox(); var unitScale = 1.5/geometry.boundingBox.max.y; geometry.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale)); geometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,0, Math.sqrt(2)/2)); var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color:0xaaaaaa, shading: THREE.FlatShading})); mesh.visible = false; meshes.endEffector = mesh; callback(meshes); }); }; Shopbot.prototype._moveTo = function(x, y, z, speed, wcs, callback){ var totalThreads = 3; function sketchyCallback(){ totalThreads -= 1; if (totalThreads > 0) return; callback(); } var startingPos = this.meshes.endEffector.position.clone(); speed = this._normalizeSpeed(startingPos, x, y, this._reorganizeSpeed(speed)); this._moveAxis(startingPos.x, x, "x", speed.x, sketchyCallback); this._moveAxis(startingPos.y, y, "y", speed.y, sketchyCallback); this._moveAxis(startingPos.z, z, "z", speed.z, sketchyCallback); }; Shopbot.prototype._moveAxis = function(startingPos, target, axis, speed, callback){ if (target == null || target === undefined) { callback(); return; } this._animateObjects([this.meshes.endEffector, this.cell], axis, speed, startingPos, target, callback); }; /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////ONE BIT/////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// function OneBitBot(){ Machine.call(this); } OneBitBot.prototype = Object.create(Machine.prototype); OneBitBot.prototype._buildMeshes = function(callback){ var meshes = []; var numMeshes = 4; function allLoaded(){ numMeshes -= 1; return numMeshes <= 0; } function geometryScale(geometry){ var unitScale = 0.05; geometry.applyMatrix(new THREE.Matrix4().makeScale(unitScale, unitScale, unitScale)); return geometry; } function meshPrep(geometry, name){ geometry.applyMatrix(new THREE.Matrix4().makeTranslation(-10-1.3919,-12.8,-1.9685)); var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color:0xaaaaaa, shading: THREE.FlatShading})); meshes[name] = mesh; if (allLoaded()) callback(meshes); } var loader = new THREE.STLLoader(); loader.load("assets/stls/oneBitBot/zAxis.STL", function(geometry){ geometryScale(geometry); geometry.applyMatrix(new THREE.Matrix4().makeTranslation(5,-2.4,-0.8)); meshPrep(geometry, "zAxis"); }); loader.load("assets/stls/oneBitBot/zDrive.STL", function(geometry){ geometryScale(geometry); geometry.applyMatrix(new THREE.Matrix4().makeTranslation(5,-2.4,0)); meshPrep(geometry, "zDrive"); }); loader.load("assets/stls/oneBitBot/yAxisMount.STL", function(geometry){ geometryScale(geometry); geometry.applyMatrix(new THREE.Matrix4().makeTranslation(5,0,0)); meshPrep(geometry, "yAxisMount"); }); loader.load("assets/stls/oneBitBot/basePlate.STL", function(geometry){ geometryScale(geometry); meshPrep(geometry, "basePlate"); }); }; OneBitBot.prototype._moveTo = function(x, y, z, speed, wcs, callback){ var totalThreads = 3; function sketchyCallback(){ totalThreads -= 1; if (totalThreads > 0) return; callback(); } var startingPos = this.meshes["basePlate"].position.clone(); speed = this._normalizeSpeed(startingPos, x, y, this._reorganizeSpeed(speed)); this._moveAxis(startingPos.x, x, "x", speed.x, sketchyCallback); this._moveAxis(startingPos.y, y, "y", speed.y, sketchyCallback); this._moveAxis(startingPos.z, z, "z", speed.z, sketchyCallback); }; OneBitBot.prototype._moveAxis = function(startingPos, target, axis, speed, callback){ if (target == null || target === undefined) { callback(); return; } this._animateObjects(_.values(this.meshes).concat(this.cell), axis, speed, startingPos, target, callback); };