Commit 8f18e341 authored by Jake Read's avatar Jake Read

ready to machine demo

parent 6f4ea800
......@@ -112,6 +112,9 @@ Herein will contain a list of known problems / common errors and their fixes.
## For MW
- want that better-planner
- do axis pullout separately from stepper motor ?
- bug hunting
- dereferenced events / stepper axis vector
- multiple button calls ...
......@@ -165,6 +168,8 @@ To assemble a representation of these, we want to have a kind of 'netlist' that,
- heirarchy zoom
- architectural clarity betwixt UI and Heap
- some auto load / save currently.json file so that we can restart program w/o pain ... maybe just save on new user inputs ?
- state.setDefault('var', num) or etc / types
- perhaps all state objects like this ... still somehow state.var = // is a good operator ? don't really want state.var.set(num) and state.var.get()
- states / uis / etc - one off / one-at-a-time for updates
- i.e. all f'n update calls are to single module-global state update
- !
......
......@@ -312,6 +312,9 @@ function redrawLinks() {
while (svg.firstChild) {
svg.removeChild(svg.firstChild)
}
// draw origin
var og1 = newLine(-15,0,15,0,5, false)
var og2 = newLine(0,-15,0,15,5, false)
// find that link
var lnkPt
var nLnk = 0
......@@ -343,7 +346,7 @@ function redrawLinks() {
nLnk++
var hwPt = getRightWall(mdlRep.ui.domElem)
lnkPt.y += 5 * nLnk
var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y, 7, true)
}
}
}
......@@ -592,6 +595,10 @@ function heapSendsProgramMenu(tree) {
menuDom.id = 'programMenu'
menuDom.style.left = lastPos.x + 'px'
menuDom.style.top = lastPos.y + 'px'
var title = document.createElement('div')
title.className = 'title'
title.innerHTML = 'program menu'
menuDom.appendChild(title)
for (key in tree) {
var li = document.createElement('li')
var path = tree[key].path
......
......@@ -298,13 +298,19 @@ function getInputArrow(div) {
return pos
}
function newLine(x1, y1, x2, y2) {
function newLine(x1, y1, x2, y2, stroke, dashed) {
var ln = {}
ln.elem = document.createElementNS(svgns, 'line')
ln.elem.style.stroke = '#1a1a1a'
ln.elem.setAttribute('stroke-dasharray', '21, 7, 7, 7')
if(dashed){
ln.elem.setAttribute('stroke-dasharray', '21, 7, 7, 7')
}
ln.elem.style.fill = 'none'
ln.elem.style.strokeWidth = '6px'
if(stroke){
ln.elem.style.strokeWidth = stroke + 'px'
} else {
ln.elem.style.strokeWidth = '6px'
}
ln.x1 = x1
ln.y1 = y1
ln.x2 = x2
......
// boilerplate atkapi header
const InOut = require('../../lib/jsunit.js')
let Input = InOut.Input
let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
const serialport = require('serialport')
function ATKBridge() {
var bridge = {
description: {
name: 'ATK Hardware Bridge',
alt: 'talks over serialport',
isHardware: true
}
}
var 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', findPort)
state.portName = '---'
state.connect = Button('click to connect', openPort)
state.portStatus = 'closed' // or we hope it will be
state.terminal = 'address | key:values'
/*
------------------------------------------------------
SERIALPORT MANAGEMENT
------------------------------------------------------
*/
port = null
function findPort() {
serialport.list(function(err, ports) {
ports.forEach(function(port) {
if (port.manufacturer == 'Silicon Labs') {
console.log('found cp2102 port')
state.portName = port.comName
openPort()
}
})
})
}
bridge.init = openPort
function openPort() {
if (state.portName == '---') {
findPort()
} else {
if (port == null) {
port = new serialport(state.portName, {
baudRate: 250000
})
port.on('open', function() {
state.portStatus = 'open'
})
port.on('error', function(err) {
state.portStatus = err.message
})
port.on('data', onPortData)
}
}
}
function sendToHardware(pckt) {
if (port != null && port.writable) {
if (port.write(pckt)) {
return true
} else {
console.log('------------------ !ACHTUNG! -------------------')
console.log('------------------ !ACHTUNG! -------------------')
console.log('---------- port.write(pckt) false --------------')
// https://nodejs.org/api/stream.html#stream_event_drain
// https://serialport.io/docs/api-stream
}
return true
} else {
return false
}
}
/*
------------------------------------------------------
PACKETS TO HARDWARE
------------------------------------------------------
*/
// from software output to hardware ...
bridge.inputs = {
A: Input('headless packet', function(pckt) {
onSoftwareInput('rA', pckt)
}),
B: Input('headless packet', function(pckt) {
onSoftwareInput('rB', pckt)
}),
C: Input('headless packet', function(pckt) {
onSoftwareInput('rC', pckt)
}),
D: Input('headless packet', function(pckt) {
onSoftwareInput('rD', pckt)
}),
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)
})
}
function onSoftwareInput(key, pckt) {
// it would be responsible to check this over now, but hey
var packet = JSON.parse(JSON.stringify(pckt))
if (Array.isArray(pckt)) {
packet.unshift(255) // end delimiter
packet.unshift(254) // ptr
var route = state[key].split(',')
packet = route.concat(packet)
if (packet.length > 128) {
console.log("LARGE PACKET ALERT:", packet.length)
}
packet.unshift(packet.length + 1)
if (sendToHardware(packet)) {
console.log('PCKT OOT >>', packet.toString())
} else {
console.log('ERR: attempt to send to hardware, port not writable')
}
} else {
console.log('non-array on bridge input')
}
}
function parseTerminal(str) {
console.log('ready to parse...', str, 'as packet')
}
/*
------------------------------------------------------
PACKETS FROM HARDWARE
------------------------------------------------------
*/
// from hardware outputs to software ...
bridge.outputs = {
A: Output('headless packet'),
B: Output('headless packet'),
C: Output('headless packet'),
D: Output('headless packet'),
E: Output('headless packet'),
F: Output('headless packet'),
G: Output('headless packet')
}
bridge.pairs = {
A: {
route: state.rA,
output: bridge.outputs.A
},
B: {
route: state.rB,
output: bridge.outputs.B
},
C: {
route: state.rC,
output: bridge.outputs.C
},
D: {
route: state.rD,
output: bridge.outputs.D
},
E: {
route: state.rE,
output: bridge.outputs.E
}
}
var thisPacket = new Array()
function onPortData(data) {
// we'll make sure it's what we think it will be
// console.log("PORT DATA")
var dtArray = new Array()
if (Buffer.isBuffer(data)) {
for (var i = 0; i < data.length; i++) {
dtArray[i] = data[i]
}
} else {
console.log("ERR: port data non-buffer")
}
//console.log('DATA IN', dtArray.toString())
thisPacket = thisPacket.concat(dtArray)
if (thisPacket[0] <= 0) {
thisPacket = []
console.log('throwing packet with leading zero')
}
while (thisPacket.length >= thisPacket[0]) {
if (thisPacket.length == thisPacket[0]) {
var packetCopy = thisPacket.slice(0) // copy, deref
thisPacket = []
onPacket(packetCopy)
} else { // rare case of two packets saddling break
var fullPacket = thisPacket.slice(0, thisPacket[0])
onPacket(fullPacket)
thisPacket = thisPacket.slice(thisPacket[0])
}
}
}
function onPacket(pckt) {
var debug = false
shiftPacketPointer(pckt)
console.log('PCKT IN <<', pckt.toString(), '-----------------------')
var incomingRoute = pckt.slice(2, pckt.indexOf(255))
// flip to match outgoing
var returnRoute = new Array()
for (i in incomingRoute) {
returnRoute[i] = incomingRoute[incomingRoute.length - 1 - i]
}
var match = null
for (key in bridge.state) {
if (returnRoute.toString() === bridge.state[key].toString()) {
//console.log("FFFFFFFFFFFFFFFFFFOUND", key)
if (key.toString().charAt(0) == '_') {
// bail
} else {
//console.log(bridge.state[key])
var outKey = key.toString().charAt(1)
match = outKey
var headless = pckt.slice(pckt.indexOf(255) + 1)
//console.log('headless', headless)
bridge.outputs[outKey].emit(headless)
return true
}
}
}
if (match == null) {
console.log("PACKET RETURN AND NO KEY FOUND")
console.log(pckt)
console.log(bridge.pairs)
}
}
function shiftPacketPointer(pckt) {
var end = 0
var i = 0
while (end == 0) {
if (pckt[i] === 255) {
end = i
} else if (i >= pckt.length) {
break
}
i++
}
//array[1] = 254
for (var j = 1; j < end - 1; j++) {
pckt[j] = pckt[j + 1]
}
pckt[end - 1] = 0
// console.log('shifted', pckt)
}
return bridge
}
module.exports = ATKBridge
\ No newline at end of file
// boilerplate atkapi header
const InOut = require('../../lib/jsunit.js')
let Input = InOut.Input
let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
const PCKT = require('../../lib/packets.js')
// a constructor, a fn, a javascript mess
function Servo() {
var servo = {
// descriptions are used in UI
description: {
name: 'Breadboard Servo Signal Generator',
alt: 'servo',
isHardware: true
}
}
servo.state = State()
// alias !
var state = servo.state
state.button = Button('SEND')
state.onChange('button', onButtonPress)
state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period
state.onChange('servoVal', onButtonPress)
servo.inputs = {
packet: Input('headless packet', onPacketReturn) // makes anything into '1' event
}
servo.outputs = {
packet: Output('number')
}
function onButtonPress(evt) {
var pwm = state.servoVal
if(pwm > 100){
pwm = 100
} else if (pwm < 0){
pwm = 0
}
var microval = Math.round(7.5 * pwm)
console.log('pwm on line', microval)
var pwmpack = PCKT.pack32(microval)
pwmpack.unshift(141)
servo.outputs.packet.emit(pwmpack)
}
function onPacketReturn(evt) {
}
return servo
}
// exports
module.exports = Servo
\ No newline at end of file
// boilerplate atkapi header
const InOut = require('../../lib/jsunit.js')
let Input = InOut.Input
let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
// a constructor, a fn, a javascript mess
function Test() {
var test = {
// descriptions are used in UI
description: {
name: 'Test Packet',
alt: 'net state',
isHardware:true
}
}
test.state = State()
// alias !
var state = test.state
state.button = Button('TEST')
state.onChange('button', onButtonPress)
state.message = 'no test started'
test.inputs = {
packet: Input('headless packet', onPacketReturn),
trigger: Input('event', onButtonPress)
}
test.outputs = {
packet: Output('number')
}
function onButtonPress(evt) {
state.message = 'packet out'
var tstpck = new Array()
tstpck.push(127)
test.outputs.packet.emit(tstpck)
}
function onPacketReturn(evt) {
if (evt[0] == '127') {
state.message = 'packet return OK'
} else {
state.message = 'other packet return'
}
}
return test
}
// exports
module.exports = Test
\ No newline at end of file
......@@ -64,10 +64,6 @@ function ATKSerialLink() {
}
})
})
if(!found){
console.log('LINK ERR: no CP2102 device found, try serialport-list to make sure it is available to the system')
state.portStatus = 'no CP2102 device found'
}
}
function openSerialPort() {
......@@ -78,6 +74,7 @@ function ATKSerialLink() {
serialport = new SerialPort(state.portName, {
baudRate: 250000
})
state.portStatus = 'opening'
serialport.on('open', function() {
state.portStatus = 'open'
})
......
......@@ -59,6 +59,7 @@ function Planner() {
// i.e. one thing we can do is assert a starting value
planner.init = function(){
state.isRunning = 0
state.netState = [0, 0, 0]
}
/*
......@@ -166,6 +167,7 @@ function Planner() {
for (i in state.netState) {
state.netState[i]++
}
state.netState = state.netState
// dereference
var move = JSON.parse(JSON.stringify(mq.shift()))
console.log("MOVE FROM PLANNER", move)
......
......@@ -13,14 +13,14 @@
"isHardware": true,
"isLink": true,
"position": {
"left": 968,
"top": 347
"left": 1922,
"top": 383
}
},
"inputs": {},
"outputs": {},
"state": {
"portName": "COM10",
"portName": "COM3",
"connect": {
"type": "button",
"label": "click to find and connect"
......@@ -36,8 +36,8 @@
"path": "./modules/hardware/atkstepper.js",
"isHardware": true,
"position": {
"left": 457,
"top": 91
"left": 1427,
"top": 127
}
},
"inputs": {
......@@ -70,7 +70,7 @@
"type": "button",
"label": "test network"
},
"message": "test OK",
"message": "click above to test network",
"route": "0,3",
"rate": 2000,
"axis": "X",
......@@ -92,8 +92,8 @@
"path": "./modules/hardware/atkstepper.js",
"isHardware": true,
"position": {
"left": 456,
"top": 491
"left": 1432,
"top": 504
}
},
"inputs": {
......@@ -126,7 +126,7 @@
"type": "button",
"label": "test network"
},
"message": "test OK",
"message": "click above to test network",
"route": "0,0",
"rate": 2000,
"axis": "Y",
......@@ -148,8 +148,8 @@
"path": "./modules/hardware/atkstepper.js",
"isHardware": true,
"position": {
"left": 457,
"top": 883
"left": 1438,
"top": 871
}
},
"inputs": {
......@@ -182,7 +182,7 @@
"type": "button",
"label": "test network"
},
"message": "test OK",
"message": "click above to test network",
"route": "0,5",
"rate": 2000,
"axis": "Y",
......@@ -204,8 +204,8 @@
"path": "./modules/hardware/atkstepper.js",
"isHardware": true,
"position": {
"left": 459,
"top": 1274
"left": 1440,
"top": 1248
}
},
"inputs": {
......@@ -238,7 +238,7 @@
"type": "button",
"label": "test network"
},
"message": "test packet out",
"message": "click above to test network",
"route": "0,1",
"rate": 2000,
"axis": "Z",
......@@ -260,8 +260,8 @@
"path": "./modules/hardware/atkbreadboard.js",
"isHardware": true,
"position": {
"left": 891,
"top": 1354
"left": 1886,
"top": 1362
}
},
"inputs": {
......@@ -291,7 +291,7 @@
"type": "button",
"label": "test network"
},
"message": "test OK",
"message": "click above to test network",
"route": "0,2",
"servoButton": {
"type": "button",
......@@ -311,8 +311,8 @@
"alt": "for clicking",
"path": "./modules/ui/button.js",
"position": {
"left": -544,
"top": 337
"left": 591,
"top": 332
}
},
"inputs": {
......@@ -349,8 +349,8 @@
"alt": "for clicking",
"path": "./modules/ui/number.js",
"position": {
"left": -545,
"top": 605
"left": 586,
"top": 566
}
},
"inputs": {
......@@ -387,8 +387,8 @@
"alt": "in ... out",
"path": "./modules/util/delay.js",
"position": {
"left": -546,
"top": 499
"left": 589,
"top": 464
}
},
"inputs": {
......@@ -418,8 +418,8 @@
"alt": "movements -> acceleration planned moves",
"path": "./modules/motion/planner.js",
"position": {
"left": -31,
"top": 91
"left": 822,
"top": 1020
}
},
"inputs": {
......@@ -478,7 +478,7 @@
0,
0
],
"isRunning": 1,
"isRunning": 0,
"netWindow": 3,
"netState": [
0,
......@@ -494,8 +494,8 @@
"alt": "line of gcode -> planner recognized move",
"path": "./modules/parsing/gcode.js",
"position": {
"left": -556,
"top": 83
"left": 583,
"top": 111
}
},
"inputs": {
......@@ -531,8 +531,8 @@
"alt": "sequential txt input",
"path": "./modules/ui/multiline.js",
"position": {
"left": -1117,
"top": 89
"left": 24,
"top": 99
}
},
"inputs": {
......
{
"description": {
"name": "new program",
"counter": 5
},
"modules": {
"Serialport ATK Link-1": {
"description": {
"id": "Serialport ATK Link-1",
"name": "Serialport ATK Link",
"alt": "window into hardware world",
"path": "./modules/hardware/atkseriallink.js",
"isHardware": true,
"isLink": true,
"position": {
"left": 968,
"top": 347
}
},
"inputs": {},
"outputs": {},
"state": {
"portName": "COM10",
"connect": {
"type": "button",
"label": "click to find and connect"