Commit 0967bceb authored by Jake Read's avatar Jake Read

jig modules

parent 1113cad7
......@@ -109,6 +109,7 @@ To assemble a representation of these, we want to have a kind of 'netlist' that,
## Bugs
- cannot connect input to output w/o backwards bezier
- when source has changed, opening programs that have references to that source should be carefully done ...
# The RPI
......
......@@ -189,7 +189,6 @@ function heapSendsNewModule(mdl) {
// and appends to the rep object a .ui object
// containing references to those DOM objects
function heapSendsModuleChange(data) {
console.log(data)
// data should be rep of changed module
......@@ -220,7 +219,11 @@ function heapSendsStateChange(data) {
console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
var rep = program.modules[data.id]
rep.state[data.key] = data.val
rep.ui.state[data.key].value = data.val
if (rep.state[data.key].type == 'multiline') {
rep.ui.state[data.key].value = data.val.value
} else {
rep.ui.state[data.key].value = data.val
}
}
/*
......@@ -311,9 +314,9 @@ function redrawLinks() {
}
// find that link
var lnkPt
var nLnk = 0
for(mdlName in program.modules){
if(program.modules[mdlName].description.isLink){
var nLnk = 0
for (mdlName in program.modules) {
if (program.modules[mdlName].description.isLink) {
lnkPt = getLeftWall(program.modules[mdlName].ui.domElem)
}
}
......@@ -336,8 +339,8 @@ function redrawLinks() {
}
}
}
if(mdlRep.description.isHardware && !mdlRep.description.isLink){
nLnk ++
if (mdlRep.description.isHardware && !mdlRep.description.isLink) {
nLnk++
var hwPt = getRightWall(mdlRep.ui.domElem)
lnkPt.y += 10 * nLnk
var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
......@@ -421,7 +424,7 @@ onwheel = function(evt) {
onmousedown = function(evt) {
var qr = document.querySelector(':focus')
if(qr){
if (qr) {
qr.blur()
}
var el = document.elementFromPoint(evt.pageX, evt.pageY)
......@@ -550,6 +553,10 @@ function heapSendsModuleMenu(tree) {
menuDom.id = 'moduleMenu'
menuDom.style.left = lastPos.x + 'px'
menuDom.style.top = lastPos.y + 'px'
var title = document.createElement('div')
title.className = 'title'
title.innerHTML = 'module menu'
menuDom.appendChild(title)
for (key in tree) {
var ul = document.createElement('ul')
ul.innerHTML = key.toString()
......
......@@ -166,7 +166,7 @@ function writeStateRep(container, rep, key) {
li.appendChild(document.createElement('br'))
var txtArea = document.createElement('textarea')
txtArea.rows = variable.rows
txtArea.cols = 27
txtArea.cols = 25
txtArea.value = variable.value
txtArea.addEventListener('change', function() {
rep.state[key].value = txtArea.value
......
......@@ -4,6 +4,12 @@ body {
font-size: 11px;
}
.title {
font-size: 17px;
font-weight: bold;
color: #eee;
}
.block {
width: 400px;
position: absolute;
......@@ -85,12 +91,17 @@ textarea {
ul {
list-style-type: none;
font-size: 15px;
font-weight: bold;
font-style: italic;
color: #eee;
padding: 7px 0 7px 0;
}
li {
list-style-type: none;
font-weight: normal;
font-style: none;
color: #eee;
font-size: 12px;
padding: 7px 5px 6px 5px;
......
......@@ -112,7 +112,7 @@ function MultiLine(label, rows) {
type: 'multiline',
label: label,
rows: rows,
value: ': - :'
value: ''
}
return ml
......
......@@ -27,26 +27,7 @@ programs are assemblies of modules
const Reps = require('./reps.js')
const Programs = require('./programs.js')
var program = Programs.new('hw unit test')
//var link = Programs.loadModuleFromSource(program, './modules/hardware/atkseriallink.js')
var atkbbs = Programs.loadModuleFromSource(program, './modules/hardware/atkbbs.js')
atkbbs.description.position = {
left: 10,
top: 200
}
// link.description.position = {
// left:475,
// top: 100
// }
//link.attach(atkbbs.route)
//program = Programs.open('programs/default.json')
var program = Programs.new('new program')
// UI
const View = require('./views.js')
......
......@@ -5,7 +5,8 @@ let Output = InOut.Output
let State = InOut.State
let Button = InOut.Button
// a constructor, a fn, a javascript mess
// the 'andflow' flowcontrol unit only lets events through once both have occurred ...
function AndFlow() {
var andflow = {
......@@ -18,13 +19,12 @@ function AndFlow() {
andflow.state = State()
// alias !
var state = andflow.state
var state = andflow.state
state.toggle = Button("Reset")
state.onChange('toggle', onReset)
state.toggle = Button("Reset", onReset)
// yikes
state.A = 0
state.B = 0
state.B = 0
andflow.inputs = {
reset: Input('any', onReset),
......@@ -36,22 +36,22 @@ function AndFlow() {
out: Output('any')
}
function onReset(evt){
function onReset(evt) {
state.A = 0,
state.B = 0
state.B = 0
}
function onA(input){
state.A = 1
if(state.A && state.B){
function onA(input) {
state.A = 1
if (state.A && state.B) {
andflow.outputs.out.emit(1)
onReset()
}
}
function onB(input){
function onB(input) {
state.B = 1
if(state.A && state.B){
if (state.A && state.B) {
andflow.outputs.out.emit(1)
onReset()
}
......
// 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 BBADC() {
var bbadc = {
// descriptions are used in UI
description: {
name: 'Breadboard ADC Request',
alt: 'bbadc',
isHardware: true
}
}
bbadc.state = State()
// alias !
var state = bbadc.state
state.button = Button('REQUEST CONVERSION')
state.onChange('button', onButtonPress)
state.adcVal = 0 // reports val
state.onChange('bbadcVal', onButtonPress)
bbadc.inputs = {
packet: Input('headless packet', onPacketReturn) ,
request: Input('event', onButtonPress)
}
bbadc.outputs = {
packet: Output('number')
}
function onButtonPress(evt) {
var pckt = new Array()
pckt.push(142) // request has this key
bbadc.outputs.packet.emit(pckt)
}
function onPacketReturn(evt) {
console.log('ADC RETURN', evt)
}
return bbadc
}
// exports
module.exports = BBADC
\ No newline at end of file
......@@ -9,34 +9,38 @@ const Hardware = require('../../lib/atkunit.js')
const PCKT = require('../../lib/packets.js')
// a constructor, a fn, a javascript mess
function ATKBreadBoardServo() {
function ATKBreadBoardBoard() {
// we make the module, starting from this base
// '0,1' is the route to our piece of hardware
// 'onPacket' is the function that will be called
// when data arrives from that port
var atkbbs = Hardware()
var atkbbb = Hardware()
// change the name ...
atkbbs.description.name = 'ATKBBB-Servo'
atkbbb.description.name = 'ATKBBB-Servo'
// inputs and outputs as usual
atkbbs.inputs = {
servoVal: Input('number', onServoValChange)
atkbbb.inputs = {
servoVal: Input('number', onServoValChange),
adcRequest: Input('event', onADCRequest)
}
atkbbs.outputs = {
conf: Output('event')
atkbbb.outputs = {
servoConf: Output('event'),
adcValue: Output('number')
}
// and state as well
var state = atkbbs.state
var state = atkbbb.state
state.button = Button('SEND VALUE', onServoValChange)
state.servoButton = Button('SEND VALUE', onServoValChange)
state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period
state.onChange('servoVal', onServoValChange)
state.adcButton = Button('REQUEST ADC CONVERSION', onADCRequest)
// to send things down the well, we can use
// atkbbs.route.send(packet)
// atkbbb.route.send(packet)
// where packet is a byte array
function onServoValChange(evt) {
......@@ -53,19 +57,31 @@ function ATKBreadBoardServo() {
var pwmpack = PCKT.pack32(microval)
pwmpack.unshift(141)
atkbbs.route.send(pwmpack)
atkbbb.route.send(pwmpack)
}
// to get replies to certain packets, we can
// subscribe, where 141 (here) is the 'key'
// we're looking for on the network, and the
// msg is byte array we'll get back
atkbbs.route.subscribe(141, function(msg){
console.log('logging return', msg)
atkbbb.route.subscribe(141, function(msg){
atkbbb.outputs.servoConf.emit('1')
})
function onADCRequest(evt){
var pckt = new Array()
pckt.push(142)
atkbbb.route.send(pckt)
}
atkbbb.route.subscribe(142, function(msg){
// working on this ...
console.log('ADC Request Response', msg)
atkbbb.outputs.adcValue.emit(msg)
})
return atkbbs
return atkbbb
}
// exports
module.exports = ATKBreadBoardServo
\ No newline at end of file
module.exports = ATKBreadBoardBoard
\ No newline at end of file
......@@ -8,81 +8,37 @@ let Button = InOut.Button
const MJS = require('mathjs')
const DCRT = require('../../lib/cartesian.js')
const Hardware = require('../../lib/atkunit.js')
const PCKT = require('../../lib/packets.js')
function Stepper() {
var stepper = {
description: {
name: 'ATK Network Stepper Driver',
alt: 'software representation of stepper',
isHardware: true
}
}
stepper.state = State()
var state = stepper.state
// is it shallow state?
// var state, not state :|
state.axis = 'X'
state.spu = 200 // steps per unit
state.rawMove = -10
state.makeMove = Button('test move', onRawMove)
var stepper = Hardware()
state.lead = 0
state.position = 0 // in steps
stepper.description.name = 'ATKStepper'
stepper.description.alt = 'software representation of stepper motor'
stepper.inputs = {
move: Input('move instruction', onNewInstruction),
packet: Input('headless packet', onHardwareIn),
rmtrig: Input('event', onRawMove)
}
stepper.outputs = {
ack: Output('move acknowledgement'),
q: Output('number'), // how much juice used for last move
packet: Output('headless packet')
}
function onHardwareIn(pckt) {
var debug = false
if (debug) console.log('PCKT into stepper', pckt)
var key = pckt[0]
pckt.shift()
switch (key) {
case 131:
onHardwareStepsComplete(pckt)
break
case 132:
onHardwareWaitComplete(pckt)
break
default:
console.log("STEP: pckt return w/ no recognized key")
}
}
// alias to state (from Hardware() beginnings)
var state = stepper.state
function onHardwareStepsComplete(pckt){
var stepsMade = PCKT.unPack32(pckt)
state.position += stepsMade
var unitsMade = stepsMade / state.spu
var ack = {
axis: state.axis,
increment: unitsMade
}
console.log("STEPPER ACK MOVE", state.axis)
stepper.outputs.ack.emit(ack)
}
state.axis = 'X'
state.spu = 200 // steps per unit
state.rawMove = -10
function onHardwareWaitComplete(pckt){
//var msg = PCKT.unPack32(pckt)
var ack = {
axis: state.axis,
increment: 0
}
console.log("STEPPER ACK WAIT", state.axis)
stepper.outputs.ack.emit(ack)
}
state.makeMove = Button('test move', onRawMove)
state.lead = 0
state.position = 0 // in steps
function onRawMove() {
console.log('TEST move for', state.rawMove)
......@@ -120,7 +76,7 @@ function Stepper() {
for (i in move.p1) {
if (Math.abs(move.vector[i]) > 0) {
altAxis = i
break
break
}
}
if (altAxis != null) {
......@@ -143,20 +99,20 @@ function Stepper() {
// like
/*
var move = {
p1, p2,
cruise, entry, exit,
vector,
type,
t1, d1, t2, d2, t3, d3
p1, p2,
cruise, entry, exit,
vector,
type,
t1, d1, t2, d2, t3, d3
}
*/
/*
var pckt = {
steps,
entry,
accel,
accelLen,
deccelLen
steps,
entry,
accel,
accelLen,
deccelLen
}
*/
var delta = move.p2[i] - move.p1[i]
......@@ -186,6 +142,12 @@ function Stepper() {
return aMove
}
/*
SOFTWARE -> HARDWARE ---------------------------------------------------
*/
function sendToHardware(aMove) {
// steps / unit
var spu = state.spu
......@@ -197,9 +159,9 @@ function Stepper() {
dMove.accel = watchRounding(aMove.accel * convert)
dMove.accelLen = Math.round(aMove.accelLen * convert)
dMove.deccelLen = Math.round(aMove.deccelLen * convert)
if(Math.abs(dMove.steps) < 2){
console.log("!ACHTUNG! ------------------------------------- VERY SMALL STEP MOVE")
console.log(dMove)
if (Math.abs(dMove.steps) < 2) {
console.log("!ACHTUNG! ------------------------------------- VERY SMALL STEP MOVE")
console.log(dMove)
}
console.log('------------------- DMOVE', state.axis, dMove.steps)
......@@ -220,7 +182,7 @@ function Stepper() {
packet = packet.concat(PCKT.pack32(dMove.deccelLen))
state.lead = state.lead + dMove.steps
stepper.outputs.packet.emit(packet)
stepper.route.send(packet)
}
function watchRounding(val) {
......@@ -235,6 +197,32 @@ function Stepper() {
return rounded
}
stepper.route.subscribe(131, onHardwareStepsComplete)
function onHardwareStepsComplete(pckt) {
var stepsMade = PCKT.unPack32(pckt)
state.position += stepsMade
var unitsMade = stepsMade / state.spu
var ack = {
axis: state.axis,
increment: unitsMade
}
console.log("STEPPER ACK MOVE", state.axis)
stepper.outputs.ack.emit(ack)
}
stepper.route.subscribe(132, onHardwareWaitComplete)
function onHardwareWaitComplete(pckt) {
//var msg = PCKT.unPack32(pckt)
var ack = {
axis: state.axis,
increment: 0
}
console.log("STEPPER ACK WAIT", state.axis)
stepper.outputs.ack.emit(ack)
}
return stepper
}
......
......@@ -8,6 +8,7 @@ let Button = InOut.Button
var NodeWebcam = require("node-webcam")
// C920 doesn't work with windows command line util
// this module needs love / work / a working install of opencv
var wcOptions = {
width: 1920,
......
......@@ -9,10 +9,13 @@ let Button = InOut.Button
const DCRT = require('../../lib/cartesian.js')
const MJS = require('mathjs')
// planner consumes target moves (i.e. segments having uniform speed throughout)
// and subjects them to acceleration constraints
function Planner() {
var planner = {
description: {
name: 'Lookahead Motion Planner',
name: 'Lookahead-Motion-Planner',
alt: 'movements -> acceleration planned moves'
}
}
......@@ -23,15 +26,13 @@ function Planner() {
state.axisIDs = 'X,Y,Z'
state.onChange('axisIDs', axisIDUpdate)
state.reset = Button('reset planner')
state.onChange('reset', onPlannerReset)
state.reset = Button('reset planner', onPlannerReset)
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.startStop = Button('start / stop planner', onStartStop)
state.position = [0, 0, 0]
......
......@@ -16,8 +16,7 @@ function RawMove() {
rawmove.state = State()
var state = rawmove.state
state.button = Button('SEND IT')
state.onChange('button', onMoveMake)
state.button = Button('SEND IT', onMoveMake)
state.moveSize = 1
state.speed = 35
state.axisPloy = 'Y'
......
......@@ -23,15 +23,12 @@ function MultiLineIn() {
multilinein.state = State()
// alias !
var state = multilinein.state
state.load = Button('LOAD')
state.onChange('load', onLoadFile)
state.thru = Button('WHAM')
state.previously = MultiLine('lines complete', 11) // = Multiline(rows)
state.load = Button('LOAD', onLoadFile)
state.thru = Button('WHAM', lineThru)
state.previously = MultiLine('lines complete', 11)
state.now = MultiLine('line just out', 1)
state.onChange('thru', lineThru)
state.incoming = MultiLine('future lines', 36)
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"
state.incoming.value = "G0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\n"
multilinein.inputs = {
req: Input('number', onLineRequest),
......@@ -46,7 +43,7 @@ function MultiLineIn() {
// internal funcs?
function lineThru() {
// get all as arrays, pump ?
// get all as arrays with linebreak as delimiter
var outBox = state.previously.value.split('\n')
var box = state.now.value
var inBox = state.incoming.value.split('\n')
......@@ -55,14 +52,13 @@ function MultiLineIn() {
console.log("END OF MULTILINE")
} else {
outBox.push(box)
box = inBox.shift()
state.now.value = box
state.previously.value = outBox.join('\n')
state.incoming.value = inBox.join('\n')
state.now.value= checkContent(inBox.shift())
state.previously.value = checkContent(outBox.join('\n'))
state.incoming.value = checkContent(inBox.join('\n'))
// HERE is another hack for busted state-passing system
state.now = state.now
state.previously = state.previously
state.incoming = state.incoming
if (inBox.length < 1 && box == '') {
console.log("END OF MULTILINE")
} else {
......@@ -71,6 +67,14 @@ function MultiLineIn() {
}
}
function checkContent(string){
if(typeof string == 'string'){
return string
} else {
return '-'
}
}
function onLineRequest(num) {
console.log('-------------------------- ON LINE REQ', num)
for (var i = 0; i < num; i++) {
......
......@@ -23,8 +23,7 @@ function uiNum() {
state.number = 10
state.onChange('number', onNumberDesire)
state.button = Button('WHAM')
state.onChange('button', onNumberDesire)
state.button = Button('WHAM', onNumberDesire)
uinum.inputs = {
thru: Input('any', onThruInput), // makes anything into num event
......
......@@ -20,8 +20,8 @@ function AndFlowControl() {
// alias !
var state = gate.state
state.toggle = Button("Open / Close")
state.onChange('toggle', onButtonPress)
state.toggle = Button("Open / Close", onButtonPress)
// yikes
gate.isOpen = false
state.message = 'closed'
......
{
"description": {
"name": "tstprgmem",
"counter": 3
},
"modules": {
"gate-1": {
"description": {
"id": "gate-1",
"name": "gate",
"alt": "in ... out",
"path": "./modules/util/gate.js",
"position": {
"left": 10,
"top": 30
}
},
"inputs": {
"thru": {
"accepts": "any"
}
},
"outputs": {
"out": {
"emits": "any",