diff --git a/README.md b/README.md index 13b8c2f082072fbe215b0b3aa7e417ff2b8512d0..f7a574324ed06dc9e8b44b82f147e1e2c24d6dad 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 0000000000000000000000000000000000000000..8eada8236f36aefc55308843150274ba79dfa562 --- /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 da711fdbfae40fd2640704d00699b98ccade1345..8eb244f54f201c480244474096e01dcecb173a5a 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 0000000000000000000000000000000000000000..155568723c512b16e5be57db1634aec3f5026e4a --- /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 2932c04091264709df611fa67bcd28b4a807df80..d56495f9b4911e171bb96a6056dabf53ff4980f2 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 ff3af69fe7e904395236ddf560b2e45770af8672..192e24e916e44e6546b7ad5b3f00559f1f7ff1bf 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 c20e34f8d5fa2728f2a292cc72a10db954879e71..aafcb6cddb413bf69cb10db1de370b2872cda5eb 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 7be7a80842f87ac2224753971687b0382df01f5b..a75fd6d83abf49de00998acfa360b7e0b5f44b6f 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 1d019a98d29474deccba498f2ab1cae88c324dd7..ef2526724cd699c2be964cc4f5e9b9dec8f96d65 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 c0f925399749fc11c6ac15ff7b5dfb512fc446bd..4083ab7d1eba198c38acfb2b222145f7bcd897ef 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