From db873c86feb24fe296cfeed9a18a7cd4e9ab15e9 Mon Sep 17 00:00:00 2001
From: Jake <jake.read@cba.mit.edu>
Date: Thu, 1 Nov 2018 23:05:19 -0400
Subject: [PATCH] after first chips

---
 README.md                |   5 +-
 load/dogbone.gcode       |  43 +++++++++++
 programs/mothercnc.js    |   4 -
 programs/servopwmtest.js |  13 ++++
 server.js                | 161 +++++++++++++++++++++++++++++++++++++--
 src/hardware/bridge.js   |  26 +++++--
 src/hardware/servo.js    |   3 +-
 src/hardware/test.js     |   3 +-
 src/motion/planner.js    |  12 +--
 src/ui/multiline.js      |  11 +--
 10 files changed, 245 insertions(+), 36 deletions(-)
 create mode 100644 load/dogbone.gcode
 create mode 100644 programs/servopwmtest.js

diff --git a/README.md b/README.md
index 13b8c2f..f7a5743 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ This project serves the developement environment / api we use to write and repre
 - wake up planner sequence, say hello
  - load program / don't during startup ?
  - flow control immediately ? 
- 
+
  - exercise to get in groove: pwm for servos & startup seq. in atkapi 
 - once we can plan gcode sequence, work towards more
  - better hardware abstraction, i.e.
@@ -40,6 +40,9 @@ This project serves the developement environment / api we use to write and repre
  - i.e. array access 
 - consistent dereferencing, type checking implementation?
 
+## Planner Bugs
+ - trapezoid linking doesn't account for speed changes properly, i.e. doesn't ramp down into next move if next move's cruise speed is less than our exit speed 
+
 ## Want
 - log() for logs-from-module tagged 
 
diff --git a/load/dogbone.gcode b/load/dogbone.gcode
new file mode 100644
index 0000000..8eada82
--- /dev/null
+++ b/load/dogbone.gcode
@@ -0,0 +1,43 @@
+G0 F25 Z5
+G0 X27.5Y111.5
+G0 Z-2
+G0 Y83.5
+G0 X14.5
+G0 Y27.5
+G0 X27.5
+G0 Y-1.5
+G0 X-1.5
+G0 Y27.5
+G0 X10.5
+G0 Y83.5
+G0 X-1.5
+G0 Y111.5
+G0 X27.5
+G0 Z-4
+G0 Y83.5
+G0 X14.5
+G0 Y27.5
+G0 X27.5
+G0 Y-1.5
+G0 X-1.5
+G0 Y27.5
+G0 X10.5
+G0 Y83.5
+G0 X-1.5
+G0 Y111.5
+G0 X27.5
+G0 Z-6
+G0 Y83.5
+G0 X14.5
+G0 Y27.5
+G0 X27.5
+G0 Y-1.5
+G0 X-1.5
+G0 Y27.5
+G0 X10.5
+G0 Y83.5
+G0 X-1.5
+G0 Y111.5
+G0 X27.5
+G0 Z10
+G0 X-40Y140
\ No newline at end of file
diff --git a/programs/mothercnc.js b/programs/mothercnc.js
index da711fd..8eb244f 100644
--- a/programs/mothercnc.js
+++ b/programs/mothercnc.js
@@ -1,5 +1,3 @@
-
-/*
 // wrap require() up, appending path used to object, and giving ID
 // use the same to load from browser 
 var term = addModule('./src/ui/terminal.js')
@@ -88,8 +86,6 @@ bridge.outputs.E.attach(t5.inputs.packet)
 
 bridge.state.rE = '0'
 
-*/
-
 bridge.init()
 
 multiline.load()
diff --git a/programs/servopwmtest.js b/programs/servopwmtest.js
new file mode 100644
index 0000000..1555687
--- /dev/null
+++ b/programs/servopwmtest.js
@@ -0,0 +1,13 @@
+var bridge = addModule('./src/hardware/bridge.js')
+bridge.init()
+var test = addModule('./src/hardware/test.js')
+var servo = addModule('./src/hardware/servo.js')
+
+test.outputs.packet.attach(bridge.inputs.B)
+bridge.outputs.B.attach(test.inputs.packet)
+
+servo.outputs.packet.attach(bridge.inputs.B)
+
+setUiPos(test, 150, 100)
+setUiPos(servo, 150, 300)
+setUiPos(bridge, 750, 150)
\ No newline at end of file
diff --git a/server.js b/server.js
index 2932c04..d56495f 100644
--- a/server.js
+++ b/server.js
@@ -122,19 +122,164 @@ PROGRAM AS API
 
 var modules = new Array()
 
+var term = addModule('./src/ui/terminal.js')
+var multiline = addModule('./src/ui/multiline.js')
+var goButton = addModule('./src/ui/button.js')
+var numOut = addModule('./src/ui/number.js')
+var delay = addModule('./src/util/delay.js')    
+var testButton = addModule('./src/ui/button.js')
+
+var gcode = addModule('./src/parsing/gcode.js')
+var planner = addModule('./src/motion/planner.js')
+
+var servo = addModule('./src/hardware/servo.js')
+
+var xm = addModule('./src/hardware/stepper.js')
+var yma = addModule('./src/hardware/stepper.js')
+var ymb = addModule('./src/hardware/stepper.js')
+var zm = addModule('./src/hardware/stepper.js')
+
+var t1 = addModule('./src/hardware/test.js')
+var t2 = addModule('./src/hardware/test.js')
+var t3 = addModule('./src/hardware/test.js')
+var t4 = addModule('./src/hardware/test.js')
+var t5 = addModule('./src/hardware/test.js')
+//var t6 = addModule('./src/hardware/test.js')
+var t7 = addModule('./src/hardware/test.js')
+
 var bridge = addModule('./src/hardware/bridge.js')
+
+// attaching an output to an input
+term.outputs.lineOut.attach(gcode.inputs.lineIn)
+multiline.outputs.lineOut.attach(gcode.inputs.lineIn)
+gcode.outputs.instructionOut.attach(planner.inputs.instruction)
+
+goButton.outputs.whammy.attach(numOut.inputs.evt)
+numOut.outputs.out.attach(multiline.inputs.req)
+goButton.outputs.whammy.attach(delay.inputs.thru)
+delay.outputs.out.attach(planner.inputs.run)
+
+testButton.outputs.whammy.attach(t1.inputs.trigger)
+testButton.outputs.whammy.attach(t2.inputs.trigger)
+testButton.outputs.whammy.attach(t3.inputs.trigger)
+testButton.outputs.whammy.attach(t4.inputs.trigger)
+testButton.outputs.whammy.attach(t5.inputs.trigger)
+//testButton.outputs.whammy.attach(t6.inputs.trigger)
+
+
+// bi-directional hook planner / motor
+planner.outputs.moves.attach(xm.inputs.move)
+xm.outputs.ack.attach(planner.inputs.acks)
+
+planner.outputs.moves.attach(yma.inputs.move)
+yma.outputs.ack.attach(planner.inputs.acks)
+
+planner.outputs.moves.attach(ymb.inputs.move)
+//ymb.outputs.ack.attach(planner.inputs.acks)
+
+planner.outputs.moves.attach(zm.inputs.move)
+zm.outputs.ack.attach(planner.inputs.acks)
+
+planner.outputs.moveComplete.attach(multiline.inputs.req)
+
+// 0,4 is NC
+// 0,0 is YL 
+// 0,1 is Z
+// 0,2 is ATKBBB
+// 0,3 is X
+// 0,4 is NC
+// 0,5 is YR
+// 0 is Router
+
+// same motors / bridge 
+xm.state.axis = 'X'
+xm.state.spu = 100
+xm.outputs.packet.attach(bridge.inputs.A)
+bridge.outputs.A.attach(xm.inputs.packet)
+bridge.state.rA = '0,3'
+t1.outputs.packet.attach(bridge.inputs.A)
+bridge.outputs.A.attach(t1.inputs.packet)
+
+// a, or, left
+yma.state.axis = 'Y'
+yma.state.spu = 100
+yma.outputs.packet.attach(bridge.inputs.B)
+bridge.outputs.B.attach(yma.inputs.packet)
+bridge.state.rB = '0,0'
+t2.outputs.packet.attach(bridge.inputs.B)
+bridge.outputs.B.attach(t2.inputs.packet)
+
+// right 
+ymb.state.axis = 'Y'
+// should have to reverse this but did it with wires :|
+ymb.state.spu = -100
+ymb.outputs.packet.attach(bridge.inputs.C)
+bridge.outputs.C.attach(ymb.inputs.packet)
+bridge.state.rC = '0,5'
+t3.outputs.packet.attach(bridge.inputs.C)
+bridge.outputs.C.attach(t3.inputs.packet)
+
+zm.state.axis = 'Z'
+zm.state.spu = -100
+zm.outputs.packet.attach(bridge.inputs.D)
+bridge.outputs.D.attach(zm.inputs.packet)
+bridge.state.rD = '0,1'
+t4.outputs.packet.attach(bridge.inputs.D)
+bridge.outputs.D.attach(t4.inputs.packet)
+
+servo.outputs.packet.attach(bridge.inputs.E)
+servo.state.servoVal = 30
+t5.outputs.packet.attach(bridge.inputs.E)
+bridge.outputs.E.attach(t5.inputs.packet)
+bridge.state.rE = '0,2'
+
+bridge.state.rF = '0,4'
+/*
+t6.outputs.packet.attach(bridge.inputs.F)
+bridge.outputs.F.attach(t6.inputs.packet)
+//bridge.state.rF = '0'
+*/
+t7.outputs.packet.attach(bridge.inputs.G)
+bridge.outputs.G.attach(t7.inputs.packet)
+
 bridge.init()
-var test = addModule('./src/hardware/test.js')
-var servo = addModule('./src/hardware/servo.js')
 
-test.outputs.packet.attach(bridge.inputs.B)
-bridge.outputs.B.attach(test.inputs.packet)
+multiline.load('load/dogbone.gcode')
+
+// setting data w/r/t the representations they serve 
+
+setUiPos(multiline, 10, 10)
+
+setUiPos(gcode, 450, 10)
+setUiPos(term, 450, 180)
+setUiPos(goButton, 450, 300)
+setUiPos(numOut, 450, 400)
+setUiPos(delay, 450, 520)
+setUiPos(testButton, 450, 730)
+
+var plCol = 900
+
+setUiPos(t1, plCol, 730)
+setUiPos(t2, plCol, 850)
+setUiPos(t3, plCol, 970)
+setUiPos(t4, plCol, 1090)
+setUiPos(t5, plCol, 1210)
+setUiPos(t7, plCol, 1330)
+//setUiPos(t7, plCol, 1450)
+setUiPos(servo, plCol, 500)
+setUiPos(planner, plCol, 10)
+
+var hwCol = 1350
+
+setUiPos(xm, hwCol, 10)
+setUiPos(yma, hwCol, 250)
+setUiPos(ymb, hwCol, 490)
+setUiPos(zm, hwCol, 730)
 
-servo.outputs.packet.attach(bridge.inputs.B)
+setUiPos(bridge, hwCol, 970)
 
-setUiPos(test, 150, 100)
-setUiPos(servo, 150, 300)
-setUiPos(bridge, 750, 150)
+// setting ui elements / state 
+planner.state.isRunning = 0
 
 function setUiPos(module, left, top){
     if(module.ui == null){
diff --git a/src/hardware/bridge.js b/src/hardware/bridge.js
index ff3af69..192e24e 100644
--- a/src/hardware/bridge.js
+++ b/src/hardware/bridge.js
@@ -18,13 +18,15 @@ function ATKBridge() {
     }
 
     var state = State()
-    bridge.state = state 
+    bridge.state = state
 
     state.rA = '0,0'
     state.rB = '0,1'
     state.rC = '0,2'
     state.rD = '0,3'
     state.rE = '0,4'
+    state.rF = '0,5'
+    state.rG = '0'
 
     state.findPort = Button('click to find atk port')
     state.portName = '---'
@@ -80,8 +82,8 @@ function ATKBridge() {
 
     function sendToHardware(pckt) {
         if (port != null && port.writable) {
-            if(port.write(pckt)){
-                return true 
+            if (port.write(pckt)) {
+                return true
             } else {
                 console.log('------------------ !ACHTUNG! -------------------')
                 console.log('------------------ !ACHTUNG! -------------------')
@@ -117,6 +119,12 @@ function ATKBridge() {
         }),
         E: Input('headless packet', function(pckt) {
             onSoftwareInput('rE', pckt)
+        }),
+        F: Input('headless packet', function(pckt) {
+            onSoftwareInput('rF', pckt)
+        }),
+        G: Input('headless packet', function(pckt) {
+            onSoftwareInput('rG', pckt)
         })
     }
 
@@ -174,7 +182,9 @@ function ATKBridge() {
         B: Output('headless packet'),
         C: Output('headless packet'),
         D: Output('headless packet'),
-        E: Output('headless packet')
+        E: Output('headless packet'),
+        F: Output('headless packet'),
+        G: Output('headless packet')
     }
 
     bridge.pairs = {
@@ -250,7 +260,7 @@ function ATKBridge() {
         for (key in bridge.state) {
             if (returnRoute.toString() === bridge.state[key].toString()) {
                 //console.log("FFFFFFFFFFFFFFFFFFOUND", key)
-                if(key.toString().charAt(0) == '_'){
+                if (key.toString().charAt(0) == '_') {
                     // bail
                 } else {
                     //console.log(bridge.state[key])
@@ -259,11 +269,11 @@ function ATKBridge() {
                     var headless = pckt.slice(pckt.indexOf(255) + 1)
                     //console.log('headless', headless)
                     bridge.outputs[outKey].emit(headless)
-                    return true 
-                } 
+                    return true
+                }
             }
         }
-        if(match == null){
+        if (match == null) {
             console.log("PACKET RETURN AND NO KEY FOUND")
             console.log(pckt)
             console.log(bridge.pairs)
diff --git a/src/hardware/servo.js b/src/hardware/servo.js
index c20e34f..aafcb6c 100644
--- a/src/hardware/servo.js
+++ b/src/hardware/servo.js
@@ -14,7 +14,8 @@ function Servo() {
         // descriptions are used in UI
         description: {
             name: 'Breadboard Servo Signal Generator',
-            alt: 'servo'
+            alt: 'servo',
+            isHardware: true
         }
     }
 
diff --git a/src/hardware/test.js b/src/hardware/test.js
index 7be7a80..a75fd6d 100644
--- a/src/hardware/test.js
+++ b/src/hardware/test.js
@@ -25,7 +25,8 @@ function Test() {
     state.message = 'no test started'
 
     test.inputs = {
-        packet: Input('headless packet', onPacketReturn) // makes anything into '1' event
+        packet: Input('headless packet', onPacketReturn), 
+        trigger: Input('event', onButtonPress)
     }
 
     test.outputs = {
diff --git a/src/motion/planner.js b/src/motion/planner.js
index 1d019a9..ef25267 100644
--- a/src/motion/planner.js
+++ b/src/motion/planner.js
@@ -20,27 +20,27 @@ function Planner() {
     planner.state = State()
     var state = planner.state // reference pass attempt?
 
-    state.axisIDs = 'X,Y'
+    state.axisIDs = 'X,Y,Z'
     state.onChange('axisIDs', axisIDUpdate)
 
     state.reset = Button('reset planner')
     state.onChange('reset', onPlannerReset)
 
-    state.accel = 100 // units/s/s
-    state.jd = 0.5 // units to arc about
-    state.minSpeed = 10 // units/s
+    state.accel = 200 // units/s/s
+    state.jd = 0.1 // units to arc about
+    state.minSpeed = 1 // units/s
 
     state.startStop = Button('start / stop planner')
     state.onChange('startStop', onStartStop)
 
-    state.position = [0, 0]
+    state.position = [0, 0, 0]
 
     // should be grn / red button ... 
     state.isRunning = 1
     state.onChange('isRunning', netStateRefresh)
 
     state.netWindow = 3
-    state.netState = [0, 0]
+    state.netState = [0, 0, 0]
 
     planner.inputs = {
         instruction: Input('move instruction', onNewInstruction),
diff --git a/src/ui/multiline.js b/src/ui/multiline.js
index c0f9253..4083ab7 100644
--- a/src/ui/multiline.js
+++ b/src/ui/multiline.js
@@ -31,10 +31,7 @@ function MultiLineIn() {
     state.onChange('thru', lineThru)
 
     state.incoming = MultiLine('future lines', 36)
-    state.incoming.value = "G0 Z5.0000 F100\nG0 X87.7230Y8.0230\nG1 Z0.0000 F50\nG1 X0.9540Y126.8930\nG0 Z5.0000\nG0 X0.9540Y126.8930\nG1 Z0.0000\nG1 X29.2600Y54.1250\nG1 X87.6220Y8.0230\nG1 X87.7230Y8.0230\nG0 Z5.0000\nG0 X87.7230Y8.0230\nG1 Z0.0000\nG1 X87.7320Y8.0230\nG1 X91.6956Y21.1580\nG0 Z5.0000\nG0 X91.6956Y21.1580\nG1 Z0.0000\nG1 X123.4990Y126.5606\nG0 Z5.0000\n"
-    /*
-        G0 F50 X100\nG0 Y100\nG0 X0\nG0 Z5\nG0 X10Y10\nG0 X0Y20\nG0 X0Y0Z0"
-        */
+    state.incoming.value = "G0 F50 X10Y10Z10\n G0 X20Y20Z0\n G0 X0\n G0 Y10\n G0 F50 X10Y10Z10\n G0 X20Y20Z0\n G0 X0\n G0 Y10\n G0 F50 X10Y10Z10\n G0 X20Y20Z0\n G0 X0\n G0 Y10\n G0 F50 X10Y10Z10\n G0 X20Y20Z0\n G0 X0\n G0 Y10\n"
 
     multilinein.inputs = {
         req: Input('number', onLineRequest),
@@ -81,10 +78,10 @@ function MultiLineIn() {
         }
     }
 
-    function onLoadFile() {
-        console.log('!!!!!!')
-        fs.readFile('load/updown.gcode', 'utf8', (err, data) => {
+    function onLoadFile(path) {
+        fs.readFile(path, 'utf8', (err, data) => {
             if (err) throw err;
+            console.log('Loading:')
             console.log(data);
             state.incoming.value = data
             state.incoming = state.incoming
-- 
GitLab