From 0d8ab165c1a661570cb22ada6740b72f01f86063 Mon Sep 17 00:00:00 2001 From: amandaghassaei <amandaghassaei@gmail.com> Date: Tue, 17 Mar 2015 00:53:41 -0400 Subject: [PATCH] adding stock simulation animation --- css/main.css | 4 ++ data/users/ben.user | 2 +- js/cam/Assembler.js | 107 +++++++++++++++++++++++----------- js/cam/Machine.js | 26 +++++++++ js/cam/ShopbotExporter.js | 38 +++++++++++- js/menus/AnimationMenuView.js | 13 ++++- js/menus/AssemblerMenuView.js | 4 +- js/models/AppState.js | 3 +- js/threeViews/ThreeView.js | 12 ++-- main.html | 1 + 10 files changed, 164 insertions(+), 46 deletions(-) create mode 100644 js/cam/Machine.js diff --git a/css/main.css b/css/main.css index 1d8ce3dd..f00328c6 100644 --- a/css/main.css +++ b/css/main.css @@ -242,4 +242,8 @@ input.numberInput{ -webkit-border-radius: 6px 0 6px 6px; -moz-border-radius: 6px 0 6px 6px; border-radius: 6px 0 6px 6px; +} + +.btn-halfWidth { + width: 47%; } \ No newline at end of file diff --git a/data/users/ben.user b/data/users/ben.user index 22d80536..26696750 100644 --- a/data/users/ben.user +++ b/data/users/ben.user @@ -1 +1 @@ -{"lattice":{"units":"inches","scale":2.78388,"shouldPreserveCells":true,"cellSeparation":{"xy":0,"z":0},"cellType":"octa","connectionType":"edgeRot","partType":"beam"},"assembler":{"camStrategy":"xRaster","placementOrder":"XYZ","camProcess":"shopbot","machine":"shopbot","rapidHeight":6.9,"safeHeight":0.5,"originPosition":{"x":-1.39194,"y":1.39194,"z":0},"stockPosition":{"x":-4.713,"y":-13.321,"z":-1.303},"rapidSpeeds":{"xy":6,"z":4},"feedRate":{"xy":0.1,"z":0.1},"stockHeight":0}} \ No newline at end of file +{"lattice":{"units":"inches","scale":2.78388,"shouldPreserveCells":true,"cellSeparation":{"xy":0,"z":0},"cellType":"octa","connectionType":"edgeRot","partType":"beam"},"assembler":{"camStrategy":"xRaster","placementOrder":"XYZ","camProcess":"shopbot","machineName":"shopbot","rapidHeight":6.9,"safeHeight":0.5,"originPosition":{"x":-1.39194,"y":1.39194,"z":0},"stockPosition":{"x":-4.713,"y":-13.321,"z":-1.303},"rapidSpeeds":{"xy":6,"z":4},"feedRate":{"xy":0.1,"z":0.1},"stockHeight":0}} \ No newline at end of file diff --git a/js/cam/Assembler.js b/js/cam/Assembler.js index 60d287cf..c7339c30 100644 --- a/js/cam/Assembler.js +++ b/js/cam/Assembler.js @@ -8,8 +8,10 @@ Assembler = Backbone.Model.extend({ camStrategy: "xRaster", placementOrder: "XYZ",//used for manual strategy entry camProcess: "shopbot", - machine: "shopbot", + machineName: "shopbot", + machine: null, exporter: null, + dataOut: "", needsPostProcessing: true, editsMadeToProgram: false,//warn the user that they will override changes @@ -23,11 +25,15 @@ Assembler = Backbone.Model.extend({ stockPosition: new THREE.Vector3(20,0,0), rapidSpeeds:{xy: 3, z: 2},//rapids at clearance height - feedRate:{xy: 0.1, z: 0.1}//speed when heading towards assembly + feedRate:{xy: 0.1, z: 0.1},//speed when heading towards assembly + + simLineNumber: 1//used for stock simulation, reading through gcode }, initialize: function(options){ + this.set("machine", new Machine()); + _.bindAll(this, "postProcess"); //bind events @@ -53,6 +59,7 @@ Assembler = Backbone.Model.extend({ "change:connectionType", this._setNeedsPostProcessing); this.listenTo(options.lattice, "change:scale", this._setCAMScale); + this.listenTo(dmaGlobals.appState, "change:stockSimulationPlaying", this._stockSimulation); //init origin mesh var origin = new THREE.Mesh(new THREE.SphereGeometry(1), @@ -70,6 +77,15 @@ Assembler = Backbone.Model.extend({ this._setCAMVisibility(); }, + makeProgramEdits: function(data){ + this.set("dataOut", data, {silent:true}); + this.set("editsMadeToProgram", true, {silent: true}); + }, + +/////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////STOCK / ORIGIN///////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + _setCAMScale: function(){ var scale = dmaGlobals.lattice.get("scale")/8; this.get("origin").scale.set(scale, scale, scale); @@ -97,41 +113,41 @@ Assembler = Backbone.Model.extend({ dmaGlobals.three.render(); }, - _setNeedsPostProcessing: function(){ - this.set("needsPostProcessing", true); - }, - - makeProgramEdits: function(data){ - this.set("dataOut", data, {silent:true}); - this.set("editsMadeToProgram", true, {silent: true}); - }, - - _getExporter: function(){ - var currentExporter = this.get("exporter"); - if (this.get("camProcess") == "shopbot") { - if (currentExporter && currentExporter.constructor == ShopbotExporter){ - return currentExporter; +/////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////SIMULATION////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + _stockSimulation: function(){ + if (dmaGlobals.appState.get("stockSimulationPlaying")){ + var currentLine = this.get("simLineNumber"); + var allLines = this.get("dataOut").split("\n"); + if(currentLine<allLines.length){ + var self = this; + this.get("exporter").simulate(allLines[currentLine], this.get("machine"), function(){ + currentLine++; + self.set("simLineNumber", currentLine); + self._stockSimulation(); + }); } else { - return new ShopbotExporter(); + //finished simulation + this.set("simLineNumber", 1); + dmaGlobals.appState.set("stockSimulationPlaying", false); } - } else if (this.get("camProcess") == "gcode") { - if (currentExporter && currentExporter.constructor == GCodeExporter){ - return currentExporter; - } else { - return new GCodeExporter(); - } - } else console.warn("cam process not supported"); + } else { + this.get("machine").pause(); + } + }, - _getOrder: function(strategy){ - if (strategy == "xRaster") return "XYZ"; - if (strategy == "yRaster") return "YXZ"; - if (strategy == "manual") return this.get("placementOrder"); - console.warn("strategy not recognized"); - return ""; +/////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////POST PROCESSING//////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + _setNeedsPostProcessing: function(){ + this.set("needsPostProcessing", true); }, - postProcess: function(){ + postProcess: function(){ this.set("needsPostProcessing", false); var exporter = this._getExporter(); @@ -164,9 +180,35 @@ Assembler = Backbone.Model.extend({ this.set("dataOut", data); this.set("exporter", exporter); + this.set("simLineNumber", 1); return {data:data, exporter:exporter}; }, + _getExporter: function(){ + var currentExporter = this.get("exporter"); + if (this.get("camProcess") == "shopbot") { + if (currentExporter && currentExporter.constructor == ShopbotExporter){ + return currentExporter; + } else { + return new ShopbotExporter(); + } + } else if (this.get("camProcess") == "gcode") { + if (currentExporter && currentExporter.constructor == GCodeExporter){ + return currentExporter; + } else { + return new GCodeExporter(); + } + } else console.warn("cam process not supported"); + }, + + _getOrder: function(strategy){ + if (strategy == "xRaster") return "XYZ"; + if (strategy == "yRaster") return "YXZ"; + if (strategy == "manual") return this.get("placementOrder"); + console.warn("strategy not recognized"); + return ""; + }, + _grabStock: function(exporter, stockPosition, rapidHeight, safeHeight){ var data = ""; data += exporter.rapidXY(stockPosition.x, stockPosition.y); @@ -195,9 +237,6 @@ Assembler = Backbone.Model.extend({ return; } this.get("exporter").save(this.get("dataOut")); - }, - - destroy: function(){ } }); \ No newline at end of file diff --git a/js/cam/Machine.js b/js/cam/Machine.js new file mode 100644 index 00000000..5745d77e --- /dev/null +++ b/js/cam/Machine.js @@ -0,0 +1,26 @@ +/** + * Created by fab on 3/16/15. + */ + + +function Machine() { + var mesh = new THREE.Mesh(new THREE.BoxGeometry(2,2,2)); + dmaGlobals.three.sceneAdd(mesh); + this.mesh = mesh; +} + +Machine.prototype.pause = function(){ + +}; + +Machine.prototype.moveTo = function(x, y, z, speed, callback){ + var self = this; + setTimeout( function() { + if (x != "") self.mesh.position.x = x; + if (y != "") self.mesh.position.y = y; + if (z != "") self.mesh.position.z = z; + dmaGlobals.three.render(); + return callback(); + }, 300); + +}; \ No newline at end of file diff --git a/js/cam/ShopbotExporter.js b/js/cam/ShopbotExporter.js index bba1c191..68c756a5 100644 --- a/js/cam/ShopbotExporter.js +++ b/js/cam/ShopbotExporter.js @@ -80,4 +80,40 @@ ShopbotExporter.prototype.save = function(data){ ShopbotExporter.prototype.convertToInches = function(mm){ return mm*0.0393701; -} +}; + + +ShopbotExporter.prototype.simulate = function(line, machine, callback){ + if (line == "" || line[0] == "'" || (line[0] != "J" && line[0] != "M")) { + return callback(); + } + if (line[0] == "J"){ + return this.simulateGetPosition(line, dmaGlobals.assembler.get("rapidSpeeds"), machine, callback); + } else if (line[0] == "M"){ + return this.simulateGetPosition(line, dmaGlobals.assembler.get("feedRate"), machine, callback); + } else { + console.warn("problem parsing sbp"); + return callback(); + } +}; + +ShopbotExporter.prototype.simulateGetPosition = function(line, speed, machine, callback){ + if (line[1] == 3 || line[1] == 2) { + var data = line.split(" "); + for (var i=0;i<data.length;i++){ + var item = data[i]; + if (item[item.length-1] == ",") data[i] = item.substring(0, item.length - 1) + } + if (line[1] == 3){ + console.log(machine); + machine.moveTo(data[1], data[2], data[3], speed, callback); + } else { + machine.moveTo(data[1], data[2], "", speed, callback); + } + } else if (line[1] == "S"){ + return callback(); + } else { + console.warn("problem parsing sbp"); + return callback(); + } +}; diff --git a/js/menus/AnimationMenuView.js b/js/menus/AnimationMenuView.js index bc556eb0..3a816996 100644 --- a/js/menus/AnimationMenuView.js +++ b/js/menus/AnimationMenuView.js @@ -10,6 +10,7 @@ AnimationMenuView = Backbone.View.extend({ events: { "click #playStockSim": "_playStockSim", "click #pauseStockSim": "_pauseStockSim", + "click #resetStockSim": "_resetStockSim", "click #saveSendMenu": "_save", "click #overrideEdits": "_postProcess" }, @@ -51,6 +52,11 @@ AnimationMenuView = Backbone.View.extend({ this.model.set("stockSimulationPlaying", false); }, + _resetStockSim: function(e){ + e.preventDefault(); + dmaGlobals.assembler.set("simLineNumber", 1); + }, + render: function(){ if (this.model.get("currentTab") != "animate") return; if (dmaGlobals.assembler.get("needsPostProcessing")) dmaGlobals.assembler.postProcess(); @@ -61,7 +67,12 @@ AnimationMenuView = Backbone.View.extend({ <% if (stockSimulationPlaying){ %>\ <a href="#" id="pauseStockSim" class=" btn btn-block btn-lg btn-warning">Pause</a><br/>\ <% } else { %>\ - <a href="#" id="playStockSim" class=" btn btn-block btn-lg btn-success">Play</a><br/>\ + <% if (simLineNumber != 1){ %>\ + <a href="#" id="playStockSim" class=" btn btn-lg btn-halfWidth btn-success">Play</a>\ + <a href="#" id="resetStockSim" class=" btn btn-lg btn-halfWidth pull-right btn-default">Reset</a><br/><br/>\ + <% } else { %>\ + <a href="#" id="playStockSim" class=" btn btn-block btn-lg btn-success">Play</a><br/>\ + <% } %>\ <% } %>\ <a href="#" id="saveSendMenu" class=" btn btn-block btn-lg btn-default">Save</a><br/>\ Assembly Time: <br/><br/>\ diff --git a/js/menus/AssemblerMenuView.js b/js/menus/AssemblerMenuView.js index 31d39031..8de41830 100644 --- a/js/menus/AssemblerMenuView.js +++ b/js/menus/AssemblerMenuView.js @@ -41,7 +41,7 @@ AssemblerMenuView = Backbone.View.extend({ _selectMachine: function(e){ e.preventDefault(); - this.assembler.set("machine", $(e.target).data("type")); + this.assembler.set("machineName", $(e.target).data("type")); }, render: function(){ @@ -53,7 +53,7 @@ AssemblerMenuView = Backbone.View.extend({ template: _.template('\ Machine: \ <div class="btn-group">\ - <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allMachineTypes[machine] %><span class="caret"></span></button>\ + <button data-toggle="dropdown" class="btn dropdown-toggle" type="button"><%= allMachineTypes[machineName] %><span class="caret"></span></button>\ <ul role="menu" class="dropdown-menu">\ <% _.each(_.keys(allMachineTypes), function(key){ %>\ <li><a class="machineType" data-type="<%= key %>" href="#"><%= allMachineTypes[key] %></a></li>\ diff --git a/js/models/AppState.js b/js/models/AppState.js index e79f3967..87633b93 100644 --- a/js/models/AppState.js +++ b/js/models/AppState.js @@ -301,7 +301,7 @@ AppState = Backbone.Model.extend({ }, _getAssemblerDataToSave: function(){ - var assemblerData = _.omit(dmaGlobals.assembler.toJSON(), ["origin", "stock", "exporter", "appState", "lattice"]); + var assemblerData = _.omit(dmaGlobals.assembler.toJSON(), ["origin", "stock", "exporter", "appState", "lattice", "machine", "simLineNumber"]); if (!dmaGlobals.assembler.get("editsMadeToProgram")) assemblerData.dataOut = ""; return assemblerData; }, @@ -328,6 +328,7 @@ AppState = Backbone.Model.extend({ loadUser: function(data, isParsed){ if (!isParsed) data = JSON.parse(data); + console.log(data); this._setData(data, false); }, diff --git a/js/threeViews/ThreeView.js b/js/threeViews/ThreeView.js index 1cec6490..5a0c2cbc 100644 --- a/js/threeViews/ThreeView.js +++ b/js/threeViews/ThreeView.js @@ -26,7 +26,7 @@ ThreeView = Backbone.View.extend({ this.appState = options.appState; - _.bindAll(this, "_animate", "_mouseMoved"); + _.bindAll(this, "_mouseMoved");//"_animate" //bind events this.listenTo(this.appState, "change:deleteMode change:extrudeMode change:shift", this._setControlsEnabled); @@ -40,17 +40,17 @@ ThreeView = Backbone.View.extend({ this.$el.append(this.model.domElement);//render only once this.model.render(); - this._animate(); + //this._animate(); }, //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////CONTROLS///////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// - _animate: function(){ - requestAnimationFrame(this._animate); - this.controls.update(); - }, + //_animate: function(){ + // requestAnimationFrame(this._animate); + // this.controls.update(); + //}, _setControlsEnabled: function(){ var state = this.appState.get("deleteMode") || this.appState.get("shift") || this.appState.get("extrudeMode"); diff --git a/main.html b/main.html index 0e48077c..afb20398 100644 --- a/main.html +++ b/main.html @@ -63,6 +63,7 @@ <script src="js/models/BasePlane.js"></script> <script src="js/models/extrudeVisualizer.js"></script> <script src="js/models/AppState.js"></script> + <script src="js/cam/Machine.js"></script> <script src="js/cam/Assembler.js"></script> <script src="js/cam/ShopbotExporter.js"></script> <script src="js/cam/GCodeExporter.js"></script> -- GitLab