From 42c0d46b29f92c478ee923801ea4aaf0d3cbf371 Mon Sep 17 00:00:00 2001 From: Jake Read <jake.read@cba.mit.edu> Date: Wed, 30 Oct 2019 14:16:53 -0400 Subject: [PATCH] add dpi to images --- hunks/adhoc/saturn.js | 84 +++---- hunks/adhoc/tpath.js | 9 +- hunks/image/readpng.js | 84 +++++-- hunks/interface/threejs_ghost.js | 4 +- save/contexts/cuttlefish/ghost-50ms.json | 212 ++++++++++++++++++ save/contexts/cuttlefish/sat-baretest.json | 198 ++++++++++++++++ save/contexts/cuttlefish/saturn-purebare.json | 117 ++++++++++ 7 files changed, 635 insertions(+), 73 deletions(-) create mode 100644 save/contexts/cuttlefish/ghost-50ms.json create mode 100644 save/contexts/cuttlefish/sat-baretest.json create mode 100644 save/contexts/cuttlefish/saturn-purebare.json diff --git a/hunks/adhoc/saturn.js b/hunks/adhoc/saturn.js index 9412772..1c5f937 100644 --- a/hunks/adhoc/saturn.js +++ b/hunks/adhoc/saturn.js @@ -37,9 +37,9 @@ export default function Saturn() { let outy = this.output('number', 'outy') let outz = this.output('number', 'outz') let outp = this.output('array', 'posn') - let period = 0.050 // his.state('number', 'period', 50) // in ms, + let period = 0.100 // his.state('number', 'period', 50) // in ms, - let allclear = () => { + let allClear = () => { return (!outx.io() && !outy.io() && !outz.io()) } @@ -51,14 +51,17 @@ export default function Saturn() { // settings, let deviation = 0.1 // virtual radius to junction about - let accel = 10 // units/s/s + let accel = 980 // units/s/s (9.8m/s/s, 9800mm/s/s is 1G) let minSpeed = 0.01 // conspicuous, to debug for tails (indexing) // current states, - let cruise = 10 // target, (units/s) + let cruise = 200 // target, (units/s) let speed = minSpeed // currently let posUpdated = false + // we nasty, + let spmm = 200 + let jd = (speeds, debug) => { //console.log('positions', positions) let calcJunctionSpeed = (p0, p1, p2, jd) => { @@ -437,33 +440,9 @@ export default function Saturn() { return blocks } - /* - let calculateNextIncrement = () => { - // for now, straightforward: current position w/r/t positions, - // increment is this posn -> next target, at rate ... - // for simplicity, we can assume that we're always going from where we're at to the [1]th point in the positions, - let vect = [0, 0, 0] - let dist = vDist(position, positions[0]) - vect.forEach((axis, i) => { - vect[i] = (positions[0][i] - position[i]) / dist - }) - // easy increment is just this vector * rate / period - let timeSeg = [0, 0, 0] - timeSeg.forEach((axis, i) => { - timeSeg[i] = vect[i] * (cruise / period) - }) - // now, is this a step-over ? some fast-slow-math for this: - let np = vSum(position, timeSeg) - if (vDist(np, position) > vDist(position, positions[0])) { - // ts is just to get us exactly to it .. - timeSeg.forEach((axis, i) => { - timeSeg[i] = positions[0][i] - position[i] - }) - positions.shift() - } - return timeSeg - } - */ + let blockOnce = true + let blocks = [] + let posNow = [] this.loop = () => { // loading new points, @@ -482,10 +461,11 @@ export default function Saturn() { console.warn('error caught at saturn input', err) } } - //if (allclear() && positions.length > 32) { + //if (allClear() && positions.length > 32) { // first we get all move final v's by jd: // we jd, - if (positions.length > 63) { + if (positions.length > positionsBufferSize - 1 && blockOnce) { + blockOnce = false // ok, here's the lookahead routine: console.time('lookahead') // positions[] is global, speeds is generated now @@ -521,37 +501,33 @@ export default function Saturn() { console.timeLog('lookahead') console.log(`have ${ramps.length} ramps for ${positions.length} positions`) // should see about writing out motion blocks: - let blocks = blockPass(ramps, true) + blocks = blockPass(ramps, true) console.log(`have ${blocks.length} blocks for ${ramps.length} ramps`) - console.timeEnd('lookahead') // 49ms ... to write ~ 3k blocks from 145 ramps from 64 positions + console.timeEnd('lookahead') // 49ms ... to write ~ 3k blocks from 145 ramps from 64 positions // OK: I think this is it... I'll wrap the loop again to do this once, then write those blocks out at the // flowcontrol'd interval... and see how it looks. this is maybe even enough: if steppers just make these counts // of steps, distance is preserved, but some jerk every 50ms... interpolation next // run once, - throw new Error('halt') + //throw new Error('halt') } - /* - // this is our major timestep, and should happen only once-every-segment - // positions length reads @ 26, but NaN ?? - // do check ... if anything is NaN, print all positions, OK. maybe reference problem? - console.log(positions.length) - // we have items in the positions, - // we should calculate an ideal trajectory from our current position and speed - // probably recalculating the whole thing, and then send that out... - let ts = calculateNextIncrement() - //console.log('time seg\t', ts) - position = vSum(position, ts) + + if(blocks.length > 0 && allClear()){ + let bl = blocks.shift() + //console.log('block', bl) + let dist = vDist(bl[0], bl[1]) + console.log(dist.toFixed(4)) + // to gate, + outx.put(1) + outy.put(1) + outz.put(1) + // and, + posNow = vScalar(bl[0], spmm) posUpdated = true - // send 'em - outx.put(ts[0]) - outy.put(ts[1]) - outz.put(ts[2]) } + if (!outp.io() && posUpdated) { - outp.put(position) + outp.put(posNow) posUpdated = false } - */ - //} } } diff --git a/hunks/adhoc/tpath.js b/hunks/adhoc/tpath.js index 67af260..5ed840a 100644 --- a/hunks/adhoc/tpath.js +++ b/hunks/adhoc/tpath.js @@ -14,7 +14,10 @@ import { // example-path-long.js also exists... // example-path-small.js ... // example-path-sl2.js -import * as expath from '../../test_files/example-path-sl2.js' +import * as expath from '../../test_files/example-path-sl2.js' +import { vScalar } from '../../libs/smallvectors.js' + +let dpi = 600 export default function TPFCOUT(){ Hunkify(this) @@ -22,7 +25,7 @@ export default function TPFCOUT(){ // copy this in au manuel let ogpath = expath.default.arr let path = [] - let go = true + let go = false let outPosn = this.output('array', 'position') let outReset = this.state('boolean', 'reset', false) @@ -40,7 +43,7 @@ export default function TPFCOUT(){ this.loop = () => { if(path.length > 0 && go){ if(!outPosn.io()){ - outPosn.put(path.shift()) + outPosn.put(vScalar(path.shift(), 600 / 25.4)) } } } diff --git a/hunks/image/readpng.js b/hunks/image/readpng.js index bdab6a7..a1d5358 100644 --- a/hunks/image/readpng.js +++ b/hunks/image/readpng.js @@ -13,12 +13,14 @@ export default function UploadPNG() { let idealWidth = 395; // (want to pull width out of some API for this.dom - element width .. have resize..) let localImageInfo = null; let imageUpdated = false; + let localDpi = null + let dpiUpdated = false // it looks like 'RGBA' types are actually ImageData objects, // https://developer.mozilla.org/en-US/docs/Web/API/ImageData // since we will be using these in canvas-contexts, makes sense to just use these types - const imageOut = new Output("ImageData", "image", this); - this.outputs.push(imageOut); + let imageOut = this.output("ImageData", "image") + let dpiOut = this.output('number', 'dpi') // as a hack, we can use boolean state variables as a button: they have handy callbacks... const trig = new State("boolean", "release", false); @@ -26,7 +28,8 @@ export default function UploadPNG() { trig.onChange = (value) => { // I'll set this flag so that we will release image info on the next loop // if any is available, - imageUpdated = true; + imageUpdated = true + dpiUpdated = true }; // names for elements, @@ -40,16 +43,16 @@ export default function UploadPNG() { //import const png_read_handler = e => { - const reader = new FileReader(); - + const imageReader = new FileReader(); const files = e.target.files; const file = files[0]; - const img = new Image(); img.file = file; - - const loader = aImg => e => { - aImg.src = e.target.result; + const imageLoader = aImg => e => { + // binary: + let raw = e.target.result + // useful: + aImg.src = raw; aImg.onload = () => { // OK: sometimes this image is *way too big* to dump into the DOM, // so we write it into a new and virtual canvas that we won't render: @@ -61,7 +64,6 @@ export default function UploadPNG() { // great, now we can use this to pull normalized ImageData information, this is what we pass around: localImageInfo = vContext.getImageData(0, 0, aImg.width, aImg.height); imageUpdated = true; - // now we can draw something: const canvas = document.getElementById(`${canvasUid}`); // we'll want to shrink the whole thing ... or enlarge, @@ -76,8 +78,58 @@ export default function UploadPNG() { ctx.drawImage(aImg, 0, 0); }; }; - reader.onload = loader(img); - reader.readAsDataURL(file); + imageReader.onload = imageLoader(img); + imageReader.readAsDataURL(file); + // and ah data version... + const headerLoader = (event) => { + console.log('e', event.target.result) + // https://gitlab.cba.mit.edu/pub/mods/blob/master/modules/read/png + // + // get DPI + // + // 8 header + // 4 len, 4 type, data, 4 crc + // pHYs 4 ppx, 4 ppy, 1 unit: 0 ?, 1 meter + // IEND + // + var units = 0 + var ppx = 0 + var ppy = 0 + var dpi = 0 + var buf = event.target.result + var view = new DataView(buf) + var ptr = 8 + if (!((view.getUint8(1) == 80) && (view.getUint8(2) == 78) && (view.getUint8(3) == 71))) { + console.warn("error: PNG header not found") + return + } + while (1) { + var length = view.getUint32(ptr) + ptr += 4 + var type = String.fromCharCode( + view.getUint8(ptr), view.getUint8(ptr + 1), + view.getUint8(ptr + 2), view.getUint8(ptr + 3)) + ptr += 4 + if (type == "pHYs") { + ppx = view.getUint32(ptr) + ppy = view.getUint32(ptr + 4) + units = view.getUint8(ptr + 8) + } + if (type == "IEND") + break + ptr += length + 4 + } + if (units == 0) { + console.warn("no PNG units not found, assuming 72 DPI") + ppx = 72 * 1000 / 25.4 + } + localDpi = ppx * 25.4 / 1000 + dpiUpdated = true + console.log('dpi', localDpi) + } + let headerReader = new FileReader() + headerReader.onload = headerLoader + headerReader.readAsArrayBuffer(file) }; this.onload = () => { @@ -85,7 +137,7 @@ export default function UploadPNG() { $(this.dom).append(target); // to name unique DOM elements, if we want to access them later using 'get element' methods, // we can prepend the hunk's name (which is unique) - const view = html` + const view = html ` <style> #${inputItemUid} { margin: 5px; @@ -113,9 +165,13 @@ export default function UploadPNG() { this.loop = () => { // we release data if we have any, if it's been updated, and if the output is clear: if (localImageInfo && imageUpdated && !imageOut.io()) { - console.log(`${this.name} puts:`, localImageInfo); + //console.log(`${this.name} puts:`, localImageInfo); imageUpdated = false; imageOut.put(localImageInfo); } + if(localDpi && dpiUpdated && !dpiOut.io()){ + dpiUpdated = false + dpiOut.put(localDpi) + } }; } diff --git a/hunks/interface/threejs_ghost.js b/hunks/interface/threejs_ghost.js index cd38fdd..acd522d 100644 --- a/hunks/interface/threejs_ghost.js +++ b/hunks/interface/threejs_ghost.js @@ -31,8 +31,8 @@ export default function ThreeGhosts(){ let height = 1000 let lineWidth = 10 let geometry = new THREE.Geometry() - for(let i = 32; i > 0; i --){ - geometry.vertices.push(new THREE.Vector3(10*i, 10*i, 10*i)) + for(let i = 512; i > 0; i --){ + geometry.vertices.push(new THREE.Vector3(0.5*i, 0.5*i, 0.5*i)) } let updatePts = [] diff --git a/save/contexts/cuttlefish/ghost-50ms.json b/save/contexts/cuttlefish/ghost-50ms.json new file mode 100644 index 0000000..5833f31 --- /dev/null +++ b/save/contexts/cuttlefish/ghost-50ms.json @@ -0,0 +1,212 @@ +{ + "interpreterName": "cuttlefish", + "interpreterVersion": "v0.1", + "hunks": [ + { + "type": "manager", + "name": "nrol", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "1", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "view", + "name": "tlview", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "0", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/saturn", + "name": "adhoc/saturn_2", + "inputs": [ + { + "name": "posn", + "type": "array" + } + ], + "outputs": [ + { + "name": "outx", + "type": "number", + "connections": [ + { + "inHunkIndex": "4", + "inHunkInput": "0" + } + ] + }, + { + "name": "outy", + "type": "number", + "connections": [ + { + "inHunkIndex": "5", + "inHunkInput": "0" + } + ] + }, + { + "name": "outz", + "type": "number", + "connections": [ + { + "inHunkIndex": "6", + "inHunkInput": "0" + } + ] + }, + { + "name": "posn", + "type": "array", + "connections": [ + { + "inHunkIndex": "7", + "inHunkInput": "0" + }, + { + "inHunkIndex": "8", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/tpath", + "name": "adhoc/tpath_3", + "outputs": [ + { + "name": "position", + "type": "array", + "connections": [ + { + "inHunkIndex": "2", + "inHunkInput": "0" + } + ] + } + ], + "states": [ + { + "name": "reset", + "type": "boolean", + "value": "false" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_4", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_5", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_6", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "data/logger", + "name": "data/logger_7", + "inputs": [ + { + "name": "tolog", + "type": "reference" + } + ], + "states": [ + { + "name": "prefix", + "type": "string", + "value": "LOG:" + }, + { + "name": "console", + "type": "boolean", + "value": "false" + } + ] + }, + { + "type": "interface/threejs_ghost", + "name": "interface/threejs_ghost_9", + "inputs": [ + { + "name": "point", + "type": "array" + } + ] + } + ] +} \ No newline at end of file diff --git a/save/contexts/cuttlefish/sat-baretest.json b/save/contexts/cuttlefish/sat-baretest.json new file mode 100644 index 0000000..f84a645 --- /dev/null +++ b/save/contexts/cuttlefish/sat-baretest.json @@ -0,0 +1,198 @@ +{ + "interpreterName": "cuttlefish", + "interpreterVersion": "v0.1", + "hunks": [ + { + "type": "manager", + "name": "nrol", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "1", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "view", + "name": "tlview", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "0", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/saturn", + "name": "adhoc/saturn_2", + "inputs": [ + { + "name": "posn", + "type": "array" + } + ], + "outputs": [ + { + "name": "outx", + "type": "number", + "connections": [ + { + "inHunkIndex": "4", + "inHunkInput": "0" + } + ] + }, + { + "name": "outy", + "type": "number", + "connections": [ + { + "inHunkIndex": "5", + "inHunkInput": "0" + } + ] + }, + { + "name": "outz", + "type": "number", + "connections": [ + { + "inHunkIndex": "6", + "inHunkInput": "0" + } + ] + }, + { + "name": "posn", + "type": "array", + "connections": [ + { + "inHunkIndex": "7", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/tpath", + "name": "adhoc/tpath_3", + "outputs": [ + { + "name": "position", + "type": "array", + "connections": [ + { + "inHunkIndex": "2", + "inHunkInput": "0" + } + ] + } + ], + "states": [ + { + "name": "reset", + "type": "boolean", + "value": "false" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_4", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_5", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "adhoc/consumer", + "name": "adhoc/consumer_6", + "inputs": [ + { + "name": "takes", + "type": "number" + } + ], + "states": [ + { + "name": "period", + "type": "number", + "value": "50" + } + ] + }, + { + "type": "data/logger", + "name": "data/logger_7", + "inputs": [ + { + "name": "tolog", + "type": "reference" + } + ], + "states": [ + { + "name": "prefix", + "type": "string", + "value": "LOG:" + }, + { + "name": "console", + "type": "boolean", + "value": "false" + } + ] + } + ] +} \ No newline at end of file diff --git a/save/contexts/cuttlefish/saturn-purebare.json b/save/contexts/cuttlefish/saturn-purebare.json new file mode 100644 index 0000000..f9ffddf --- /dev/null +++ b/save/contexts/cuttlefish/saturn-purebare.json @@ -0,0 +1,117 @@ +{ + "interpreterName": "cuttlefish", + "interpreterVersion": "v0.1", + "hunks": [ + { + "type": "manager", + "name": "nrol", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "1", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "view", + "name": "tlview", + "inputs": [ + { + "name": "msgs", + "type": "byteArray" + } + ], + "outputs": [ + { + "name": "msgs", + "type": "byteArray", + "connections": [ + { + "inHunkIndex": "0", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/saturn", + "name": "adhoc/saturn_2", + "inputs": [ + { + "name": "posn", + "type": "array" + } + ], + "outputs": [ + { + "name": "outx", + "type": "number" + }, + { + "name": "outy", + "type": "number" + }, + { + "name": "outz", + "type": "number" + }, + { + "name": "posn", + "type": "array", + "connections": [ + { + "inHunkIndex": "4", + "inHunkInput": "0" + } + ] + } + ] + }, + { + "type": "adhoc/tpath", + "name": "adhoc/tpath_3", + "outputs": [ + { + "name": "position", + "type": "array", + "connections": [ + { + "inHunkIndex": "2", + "inHunkInput": "0" + } + ] + } + ], + "states": [ + { + "name": "reset", + "type": "boolean", + "value": "false" + } + ] + }, + { + "type": "interface/threejs_ghost", + "name": "interface/threejs_ghost_9", + "inputs": [ + { + "name": "point", + "type": "array" + } + ] + } + ] +} \ No newline at end of file -- GitLab