Commit 15d18531 authored by Jake Read's avatar Jake Read
Browse files

mud printer

parent 3555f19e
......@@ -15,6 +15,8 @@
- SVG export
- ...
298
# To install and run mods locally
You need to first install [node.js](https://docs.npmjs.com/getting-started/installing-node).
......
......@@ -13,7 +13,7 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./files.html'>files.html</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./index.html'>index.html</a><br>
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./js/atkserialserver.js'>atkserialserver.js</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./js/atkbridge.js'>atkbridge.js</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./js/deviceserver.js'>deviceserver.js</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./js/echoserver.js'>echoserver.js</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./js/files.js'>files.js</a><br>
......@@ -106,7 +106,10 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/motors/stepper'>stepper</a><br>
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;network</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/network/atkbridge'>atkbridge</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/pot'>pot</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/profile'>profile</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/reset'>reset</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/hardware/test'>test</a><br>
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/image/boundingbox'>boundingbox</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/image/color%20separation'>color separation</a><br>
......@@ -148,8 +151,9 @@
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;motion</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/gcodeParser'>gcodeParser</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/machineController'>machineController</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/moveInstructionQue'>moveInstructionQue</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/neilParser'>neilParser</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/planner'>planner</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/planner-ye-olden'>planner-ye-olden</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/segments'>segments</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/textBlockIn'>textBlockIn</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./modules/motion/textLineIn'>textLineIn</a><br>
......@@ -1684,7 +1688,6 @@
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./node_modules/xtend/package.json'>package.json</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./node_modules/xtend/README.md'>README.md</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./node_modules/xtend/test.js'>test.js</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./planner-pre'>planner-pre</a><br>
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;programs</i><br>
<i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frep</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='./programs/frep/gears'>gears</a><br>
......
......@@ -21,7 +21,7 @@ if (process.argv.length < 4 && process.argv[2] != 'default') {
} else if (process.argv[2] === 'default' || process.argv.length < 3) {
client_address = '::ffff:127.0.0.1'
server_port = '6789'
com_port = 'COM8'
com_port = 'COM3'
} else {
client_address = process.argv[2]
server_port = process.argv[3]
......
//
// hardware reset command
//
// Neil Gershenfeld and Jake Read
// (c) Massachusetts Institute of Technology 2018
//
// This work may be reproduced, modified, distributed, performed, and
// displayed for any purpose, but must acknowledge the mods
// project. Copyright is retained and must be preserved. The work is
// provided as is; no warranty is provided, and users accept all
// liability.
//
// closure
//
(function() {
// globals
var mod = {}
// name
var name = 'test'
var init = function() {
//
}
var inputs = {
//
}
var outputs = {
test: {
type: 'packet',
label: 'headless packet out',
event: function() {
var test = [127]
mods.output(mod, 'test', test)
}
}
}
var interface = function(div) {
mod.div = div
mod.resetButton = make_button_input(div, 'send')
mod.resetButton.addEventListener('click', function() {
outputs.test.event()
})
}
/*
UI helpers
*/
function make_text_input(div, name, size) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(name + ': '))
var input = document.createElement('input')
input.type = 'text'
input.size = size
div.appendChild(input)
return input
}
function make_button_input(div, text) {
div.appendChild(document.createElement('br'))
var button = document.createElement('button')
button.style.padding = mods.ui.padding
button.style.margin = 1
button.appendChild(document.createTextNode(text))
div.appendChild(button)
return button
}
function make_checkbox_input(div, prefix) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(prefix + ': '))
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
div.appendChild(checkbox)
return checkbox
}
function make_text_display(div, prefix) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(prefix + ': '))
var span = document.createElement('span')
span.innerHTML = ''
div.appendChild(span)
return span
}
return ({
mod: mod,
name: name,
init: init,
inputs: inputs,
outputs: outputs,
interface: interface
})
}())
\ No newline at end of file
......@@ -77,7 +77,10 @@ module_label('   motors')
module_menu('      stepper','modules/hardware/motors/stepper')
module_label('   network')
module_menu('      atkbridge','modules/hardware/network/atkbridge')
module_menu('   pot','modules/hardware/pot')
module_menu('   profile','modules/hardware/profile')
module_menu('   reset','modules/hardware/reset')
module_menu('   test','modules/hardware/test')
module_label('image')
module_menu('   boundingbox','modules/image/boundingbox')
module_menu('   color separation','modules/image/color%20separation')
......@@ -118,8 +121,9 @@ module_menu('   move','modules/module/move')
module_label('motion')
module_menu('   gcodeParser','modules/motion/gcodeParser')
module_menu('   machineController','modules/motion/machineController')
module_menu('   moveInstructionQue','modules/motion/moveInstructionQue')
module_menu('   neilParser','modules/motion/neilParser')
module_menu('   planner','modules/motion/planner')
module_menu('   planner-ye-olden','modules/motion/planner-ye-olden')
module_menu('   segments','modules/motion/segments')
module_menu('   textBlockIn','modules/motion/textBlockIn')
module_menu('   textLineIn','modules/motion/textLineIn')
......
......@@ -92,7 +92,7 @@ turns lines of text into objects for machine controller
}
// loop to find position vals, check for feed update
for (key in keyvals) {
if (key.match('[A-CX-Z]')) {
if (key.match('[A-EX-Z]')) {
output.position[key] = keyvals[key]
} else if (key.match('[F]')){
if(mod.codeMode.value == 'G0'){
......
......@@ -107,6 +107,16 @@ dishes gcodes -> planner, spindle codes -> spindle
jog('Y', -parseFloat(mod.jogStepSizeIn.value))
})
mod.jogYPButton = make_button_input(div, 'z+')
mod.jogYPButton.addEventListener('click', function(evt) {
jog('Z', parseFloat(mod.jogStepSizeIn.value))
})
mod.jogYMButton = make_button_input(div, 'z-')
mod.jogYMButton.addEventListener('click', function(evt) {
jog('Z', -parseFloat(mod.jogStepSizeIn.value))
})
// sequence begin, stop
mod.startSequenceButton = make_button_input(div, 'start sequence')
......
//
// generic line input
//
// Neil Gershenfeld and Jake Read
// (c) Massachusetts Institute of Technology 2018
//
// This work may be reproduced, modified, distributed, performed, and
// displayed for any purpose, but must acknowledge the mods
// project. Copyright is retained and must be preserved. The work is
// provided as is; no warranty is provided, and users accept all
// liability.
//
// closure
//
(function() {
//
// module globals
//
var mod = {}
//
// name
//
var name = 'move instruction queue'
//
// initialization
//
var init = function() {
}
//
// inputs
//
var inputs = {
lineRequest: {
type: 'number',
label: 'line request',
event: function(evt) {
sendLine()
}
},
instructions: {
type: 'objects',
label: 'move instructions',
event: function(evt){
newInstructions(evt.detail)
}
}
}
//
// outputs
//
var outputs = {
instruction: {
type: 'object',
label: 'instruction',
event: function(instr) {
mods.output(mod, 'instruction', instr)
}
}
}
//
// interface
//
var interface = function(div) {
mod.div = div
//
// inputs
//
mod.lineCountDisplay = make_text_display(div, 'current line')
mod.resetCurrentLine = make_button_input(div, 'reset lines')
mod.resetCurrentLine.addEventListener('click', function(){
mod.lineCountDisplay.innerHTML = '0'
currentLine = 0
})
mod.sendOneLine = make_button_input(div, 'send a line')
mod.sendOneLine.addEventListener('click', function(){
sendLine()
})
}
var currentLine = 0
var moveArray = []
function newInstructions(instructions){
moveArray = instructions
}
function sendLine() {
var moveOut = moveArray[currentLine]
currentLine++
if (currentLine > moveArray.length) {
currentLine = moveArray.length
} else {
outputs.instruction.event(moveOut)
}
mod.lineCountDisplay.innerHTML = currentLine.toString()
}
/*
UI helpers
*/
function make_text_input(div, name, size) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(name + ': '))
var input = document.createElement('input')
input.type = 'text'
input.size = size
div.appendChild(input)
return input
}
function makeTextArea(div, name, width, height) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(name + ': '))
div.appendChild(document.createElement('br'))
var textArea = document.createElement('textarea')
textArea.setAttribute('cols', width)
textArea.setAttribute('rows', height)
textArea.type = 'textarea'
div.appendChild(textArea)
return textArea
}
function make_button_input(div, text) {
div.appendChild(document.createElement('br'))
var button = document.createElement('button')
button.style.padding = mods.ui.padding
button.style.margin = 1
button.appendChild(document.createTextNode(text))
div.appendChild(button)
return button
}
function make_checkbox_input(div, prefix) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(prefix + ': '))
var checkbox = document.createElement('input')
checkbox.type = 'checkbox'
div.appendChild(checkbox)
return checkbox
}
function make_text_display(div, prefix) {
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode(prefix + ': '))
var span = document.createElement('span')
span.innerHTML = ''
div.appendChild(span)
return span
}
//
// return values
//
return ({
mod: mod,
name: name,
init: init,
inputs: inputs,
outputs: outputs,
interface: interface
})
}())
\ No newline at end of file
......@@ -48,9 +48,9 @@ motors
var init = function() {
mod.accelIn.value = '500'
mod.junctionDeviationIn.value = '1'
mod.minSpeedIn.value = '4'
mod.minSpeedIn.value = '12'
mod.axisIdentifiers.value = 'X,Y'
mod.axisIdentifiers.value = 'X,Y,Z'
resetNetwork()
mod.netWindowIn.value = '12'
......@@ -211,13 +211,18 @@ motors
*/
if(ok){
var opening = packetWindowSize - axisNetCounters[0]
var newrequest = true
if(opening > moveQue.length){
opening = moveQue.length
newrequest = false
}
for(var i = 0; i < opening; i++){
//console.log('sending', i)
sendMove()
outputs.moveComplete.event()
if(newrequest){
outputs.moveComplete.event()
}
}
}
}
......
//
// converts toolpath objects into segments for accel planning
//
// Neil Gershenfeld and Jake Read
// (c) Massachusetts Institute of Technology 2018
//
// This work may be reproduced, modified, distributed, performed, and
// displayed for any purpose, but must acknowledge the mods
// project. Copyright is retained and must be preserved. The work is
// provided as is; no warranty is provided, and users accept all
// liability.
/*
eats objects like
var move = {
position: {
X: float
Y: float
Z: float
A: float
}
rate: float
}
*/
//
// closure
//
(function() {
//
// module globals
//
var mod = {}
//
// name
//
var name = 'motion planner'
//
// initialization
//
var init = function() {
mod.accel_in.value = '25'
mod.junction_deviation_in.value = '0.5'
mod.current_block_in.value = '0'
mod.current_window_size_in.value = '0'
mod.window = 0
mod.packets_awaiting_reply = 0
}
//
// inputs
var twoCount = 0
//
var inputs = {
segments: {
type: 'objects',
label: 'segments',
event: function(evt) {
mod.segments = JSON.parse(JSON.stringify(evt.detail)) // dereference pls
// console.log('segments to planner: ', mod.segments)
runQueue()
}
},
next: {
type: 'event',
label: 'call for next block',
event: function(evt) {
twoCount++
if (twoCount > 1) {
mod.packets_awaiting_reply--;
if (mod.packets_awaiting_reply < mod.window) {
sendBlock()
}
twoCount = 0
}
}
}
}
//
// outputs
//
var outputs = {
nextblock: {
type: 'object',
label: 'next block',
event: function() {
//mods.output(mod, 'segments', null)
}
}
}
//
// interface
//
var interface = function(div) {
mod.div = div
//
// inputs
//
// settings
mod.accel_in = make_text_input(div, 'acceleration, mm/s/s', 12)
mod.junction_deviation_in = make_text_input(div, 'junction deviation, mm', 12)
//
// request to do the business
//
mod.parse_button = make_button_input(div, 'parse')
mod.parse_button.addEventListener('click', function() {
runQueue()
})
// current block
mod.current_block_in = make_text_input(div, 'next block to send', 12)
mod.current_window_size_in = make_text_input(div, 'current window size', 12)
//
// send a block
//
mod.send_button = make_button_input(div, 'send next block')
mod.send_button.addEventListener('click', function() {
sendBlock()
})
mod.open_window_button = make_button_input(div, 'open transmit window')
mod.open_window_button.addEventListener('click', function() {
console.log('opening window')
if (mod.window < 2) {
mod.window = 3
} else {
mod.window++
}
mod.current_window_size_in.value = mod.window.toString()
mod.packets_awaiting_reply = 0
while (mod.packets_awaiting_reply < mod.window) {
sendBlock()
}
})
mod.close_window_button = make_button_input(div, 'close transmit window')
mod.close_window_button.addEventListener('click', function() {
mod.window = 0;
mod.current_window_size_in.value = mod.window.toString()
})
}
function cartesianDistance(p1, p2) {
// takes p1, p2 to be arrays of same length
// computes cartesian distance
var sum = 0
for (var i = 0; i < p1.length; i++) {
sum += Math.pow((p1[i] - p2[i]), 2)
}
return Math.sqrt(sum)
}
function cartesianLength(v) {
// length of vector
var sum = 0
for (var i = 0; i < v.length; i++) {
sum += Math.pow(v[i], 2)
}
return Math.sqrt(sum)
}
function addMatrix(a, b, c) {
// c = a + b
a.forEach(function(item, index) {
c[index] = b[index] + a[index]
})
}
function subtractMatrix(a, b, c) {
// c = a - b
b.forEach(function(item, index) {
c[index] = a[index] - b[index]
})
}
function multiplyMatrix(a, scalar, b) {
// b = a * scalar
a.forEach(function(item, index) {
b[index] = a[index] * scalar
})
}
function multiply2dMatrix(a, scalar, b) {
// b = a * scalar
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < a[i].length; j++) {
b[i][j] = a[i][j] * scalar;
}
}
}
function divideMatrix(a, scalar, b) {
// b = a / scalar
for (var i = 0; i < a.length; i++) {
b[i] = a[i] / scalar
}
}
function unitVector(p1, p2) {
// returns new array, is unit vector of p2-p1
var unit = new Array()
subtractMatrix(p2, p1, unit)
var length = cartesianLength(unit)
divideMatrix(unit, length, unit)
return unit
}
function dotProduct(a, b) {
// returns a dot b
var sum = 0;
for (var i = 0; i < a.length; i++) {
sum += a[i] * b[i]
}
return sum
}
function toFixedMatrix(a, digits) {
var rounded = new Array()
for (var i = 0; i < a.length; i++) {
rounded[i] = a[i].toFixed(digits)
}