From f7df9057ceb536cb8e66b94554f7fa92d22592d5 Mon Sep 17 00:00:00 2001
From: Jake Read <jake.read@cba.mit.edu>
Date: Thu, 31 Oct 2019 14:26:42 -0400
Subject: [PATCH] path variety, arccos bounds catchers

---
 hunks/adhoc/saturn.js                        |  92 ++++++------
 hunks/adhoc/tpath.js                         |  25 ++--
 hunks/interface/threejs_ghost.js             |   7 +-
 save/contexts/cuttlefish/dbg-25ms-ghost.json | 140 +++++++++++++++++++
 4 files changed, 204 insertions(+), 60 deletions(-)
 create mode 100644 save/contexts/cuttlefish/dbg-25ms-ghost.json

diff --git a/hunks/adhoc/saturn.js b/hunks/adhoc/saturn.js
index 2fb0562..f13733e 100644
--- a/hunks/adhoc/saturn.js
+++ b/hunks/adhoc/saturn.js
@@ -94,28 +94,33 @@ export default function Saturn() {
   // run JD: calculate maximum allowable speeds at corners due to instantaneous turnaround limit
   let jd = (speeds, debug) => {
     //console.log('positions', positions)
-    let calcJunctionSpeed = (p0, p1, p2, jd) => {
+    let calcJunctionSpeed = (p0, p1, p2, debug) => {
       // junction speed at p1, arrival from p0 exit to p2
       let v0 = math.subtract(p1, p0)
       let v1 = math.subtract(p2, p1)
-      //console.log('for\n', v0, v1)
+      if(debug) console.log('for\n', v0, v1)
       let dotprod = math.dot(v0, v1) / (vLen(v0) * vLen(v1))
-      //console.log('dotprod', dotprod)
+      if(debug) console.log('dotprod', dotprod)
+      // block for floating pt errors that drive this term past +/- 1
+      if(dotprod < 1) dotprod = -1
+      if(dotprod > 1) dotprod = 1
       let omega = Math.PI - Math.acos(dotprod)
-      //console.log('angle between', deg(omega))
-      let r = jd / (1 / Math.cos(Math.PI / 2 - omega / 2) - 1)
-      //console.log('rad', r)
+      if(debug) console.log('angle between', deg(omega))
+      let r = deviation / (1 / Math.cos(Math.PI / 2 - omega / 2) - 1)
+      if(debug) console.log('rad', r)
       let v = Math.sqrt(accel * r)
-      //console.log('permissible', v)
+      if(debug) console.log('permissible', v)
       return v
     }
     // the ops,
     for (let m = 0; m < positions.length; m++) {
       if (m === 0) continue // noop for start: this is our current speed, should already be in speeds arr
       if (m === positions.length - 1) continue // noop for last move, nothing to junction into, exit should be minspeed
-      let jd = calcJunctionSpeed(positions[m - 1], positions[m], positions[m + 1], deviation, accel)
+      let jd = calcJunctionSpeed(positions[m - 1], positions[m], positions[m + 1])
       if (Number.isNaN(jd)) {
-        console.log(`NaN for ${m}`)
+        console.warn(`after jd, NaN for move at ${m}`, positions[m - 1], positions[m], positions[m + 1])
+        // run again w/ debug
+        calcJunctionSpeed(positions[m - 1], positions[m], positions[m + 1], true)
       }
       if (jd < speeds[m]) {
         speeds[m] = jd
@@ -274,7 +279,7 @@ export default function Saturn() {
           if (debug) console.log('/\\')
           writeTriangle(ramps, vi, vf, pi, pf)
         } else { // BEGIN TRAP SELECTIONS
-          if (true) console.log('/--\\')
+          if (debug) console.log('/--\\')
           let pa = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
           let pb = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist))
           // ok,
@@ -307,7 +312,7 @@ export default function Saturn() {
           }
         } // end TRAP SELECTIONS
       } // end BIGSWITCH
-      if(ramps.length === numRampsBefore) console.warn('zero ramps written for', pi, pf, vi, vf)
+      if (ramps.length === numRampsBefore) console.warn('zero ramps written for', pi, pf, vi, vf)
     } // end for-over-positions
     return ramps
   }
@@ -319,12 +324,12 @@ export default function Saturn() {
       let vf = speeds[i + 1]
       let t = 2 * d / (vi + vf)
       if (false) console.log(`ap, ${t.toFixed(3)}`)
-      if (t < (period - 0.001)) console.warning('small link in positions check')
+      if (t < (period - 0.001)) console.warn('small link in positions check')
     }
   }
 
   let rampCheck = (ramps) => {
-    for (let i = 0; i < ramps.length; i ++) {
+    for (let i = 0; i < ramps.length; i++) {
       let r = ramps[i]
       let d = vDist(r.pi, r.pf)
       let t = 2 * d / (r.vi + r.vf)
@@ -333,14 +338,14 @@ export default function Saturn() {
       let cruiseAbsMax = cruise + 0.15 * cruise
       if (r.vi > cruiseAbsMax || r.vf > cruiseAbsMax) console.warn('troublesome ramp, high speed', r)
       // check that ramps are continuous
-      if(i < ramps.length - 2){
+      if (i < ramps.length - 2) {
         let sep = vDist(r.pf, ramps[i + 1].pi)
-        if(sep > 0.001) console.warn('troublesome ramp junction', r, ramps[i + 1])
+        if (sep > 0.001) console.warn('troublesome ramp junction', r, ramps[i + 1])
       }
     }
   }
 
-  let blockOnce = false
+  let debugRuntime = false
 
   this.loop = () => {
     // handle output to stepper, if we have any existing blocks to issue:
@@ -356,26 +361,28 @@ export default function Saturn() {
       // in which case we update p[0], or at the end of p[0], at p[1]
       let dtp = vDist(ramps[0].pf, positions[1])
       // if we're within 10^-3 of the units, clear it out
-      console.log(`at evt, dtp is ${dtp.toFixed(6)}`)
+      if(debugRuntime) console.log(`at evt, dtp is ${dtp.toFixed(6)}`)
       if (dtp < 0.001) {
+        /*
         console.log(`> complete position, had ${positions.length}`)
-        for(let i = 0; i < 10; i ++){
+        for (let i = 0; i < 10; i++) {
           console.log(`> position[${i}] ${positions[i][0].toFixed(3)}, ${positions[i][1].toFixed(3)}, ${positions[i][2].toFixed(3)}`)
         }
-        for(let i = 0; i < 10; i ++){
+        for (let i = 0; i < 10; i++) {
           console.log(`> ramps[${i}].pi ${ramps[i].pi[0].toFixed(3)},${ramps[i].pi[1].toFixed(3)},${ramps[i].pi[2].toFixed(3)}`)
           console.log(`> ramps[${i}].pf ${ramps[i].pf[0].toFixed(3)},${ramps[i].pf[1].toFixed(3)},${ramps[i].pf[2].toFixed(3)}`)
         }
+        */
         positions.shift()
         ramps.shift()
-        console.log(`> now position, have ${positions.length}`)
+        if(debugRuntime) console.log(`> complete position`)
         // have to recalculate blocks now I think?
       } else {
-        console.log(`updating p[0]`)
+        if(debugRuntime) console.log(`> updating p[0]`)
         positions[0] = ramps[0].pf
         ramps.shift()
       }
-      console.log(`${ramps.length} ramps, ${positions.length} positions`)
+      if(debugRuntime) console.log(`${ramps.length} ramps, ${positions.length} positions`)
     }
 
     if (!outp.io() && posUpdated) {
@@ -388,26 +395,23 @@ export default function Saturn() {
     // load new pts into the array,
     if (positions.length < positionsBufferSize && inpts.io()) {
       // get the new pt, adding it if it is of any appreciable distance
-      if(!blockOnce){
-        let np = inpts.get()
-        try {
-          if (vDist(np, positions[positions.length - 1]) < 0.001) {
-            // dunk on 'em
-            console.warn('zero length appendage rejected by planner')
-          } else {
-            positions.push(np) // end of queue
-            console.log(`puts new position for ${positions.length}`)
-            // THE BUSINESS:
-            // ok, here's the lookahead routine:
-          }
-        } catch (err) {
-          console.warn('error caught at saturn input', err)
+      let np = inpts.get()
+      try {
+        if (vDist(np, positions[positions.length - 1]) < 0.001) {
+          // dunk on 'em
+          console.warn('zero length appendage rejected by planner')
+        } else {
+          positions.push(np) // end of queue
+          if(debugRuntime) console.log(`puts new position for ${positions.length}`)
+          // THE BUSINESS:
+          // ok, here's the lookahead routine:
         }
+      } catch (err) {
+        console.warn('error caught at saturn input', err)
       }
 
-      if (positions.length > positionsBufferSize - 2 && !blockOnce) {
-        blockOnce = true
-        console.log('lookahead')
+      if (positions.length > positionsBufferSize - 2) {
+        if(debugRuntime) console.log('lookahead')
         // LOOKAHEAD BEGIN
         if (logTimes) console.time('lookahead')
         // positions[] is global, speeds is generated now
@@ -434,19 +438,11 @@ export default function Saturn() {
         ramps.length = 0
         ramps = rampPass(speeds)
         // is this still conn. to our head?
-        if (ramps.length > 0) console.log('new ramps', vDist(ramps[0].pi, positions[0]).toFixed(5))
+        if (ramps.length > 0 && debugRuntime) console.log('new ramps', vDist(ramps[0].pi, positions[0]).toFixed(5))
         // and a check,
         rampCheck(ramps)
         if (logTimes) console.timeLog('lookahead')
         if (logTimes) console.timeEnd('lookahead')
-        for(let i = 0; i < 20; i ++){
-          console.log(positions[i])
-        }
-        console.log(ramps[0].pi)
-        for(let i = 0; i < 30; i ++){
-          console.log(ramps[i].pf)
-        }
-        throw new Error('once')
         //console.log('new pt\t', positions.length, np)
         // LOOKAHEAD END
       }
diff --git a/hunks/adhoc/tpath.js b/hunks/adhoc/tpath.js
index 92d00b2..b0a4628 100644
--- a/hunks/adhoc/tpath.js
+++ b/hunks/adhoc/tpath.js
@@ -14,7 +14,9 @@ import {
 // example-path-long.js also exists...
 // example-path-small.js ...
 // example-path-sl2.js
-import * as expath from '../../test_files/example-path-small.js'//example-path-sl2.js'
+import * as longpath from '../../test_files/example-path-long.js'
+import * as smallpath from '../../test_files/example-path-small.js'
+import * as sl2path from '../../test_files/example-path-sl2.js'
 import { vScalar } from '../../libs/smallvectors.js'
 
 let dpi = 72
@@ -22,21 +24,24 @@ let dpi = 72
 export default function TPFCOUT(){
   Hunkify(this)
 
-  // copy this in au manuel
-  let ogpath = expath.default.arr
   let path = []
   let go = false
 
   let outPosn = this.output('array', 'position')
-  let outReset = this.state('boolean', 'reset', false)
-  outReset.onChange = (value) => {
+  let longSet = this.state('boolean', 'longpath', false)
+  longSet.onChange = (value) => {
     go = true
-    path = JSON.parse(JSON.stringify(ogpath))
+    path = JSON.parse(JSON.stringify(longpath.default.arr))
   }
-
-  this.init = () => {
-    path = JSON.parse(JSON.stringify(ogpath))
-    console.log(path)
+  let shortSet = this.state('boolean', 'shortpath', false)
+  shortSet.onChange = (value) => {
+    go = true
+    path = JSON.parse(JSON.stringify(shortpath.default.arr))
+  }
+  let sl2pathSet = this.state('boolean', 'sl2path', false)
+  sl2pathSet.onChange = (value) => {
+    go = true
+    path = JSON.parse(JSON.stringify(sl2path.default.arr))
   }
 
   // copies out, one at a time, fc pressure
diff --git a/hunks/interface/threejs_ghost.js b/hunks/interface/threejs_ghost.js
index acd522d..4563531 100644
--- a/hunks/interface/threejs_ghost.js
+++ b/hunks/interface/threejs_ghost.js
@@ -16,6 +16,8 @@ import { OrbitControls } from '../../libs/three_orbitcontrols.module.js'
 // really hacking the import here... apologies, works though!
 import { MeshLine, MeshLineMaterial } from '../../libs/three_meshline.module.js'
 
+let numSegs = 100
+
 export default function ThreeGhosts(){
   Hunkify(this)
 
@@ -31,8 +33,9 @@ export default function ThreeGhosts(){
   let height = 1000
   let lineWidth = 10
   let geometry = new THREE.Geometry()
-  for(let i = 512; i > 0; i --){
-    geometry.vertices.push(new THREE.Vector3(0.5*i, 0.5*i, 0.5*i))
+  let startSegLength = 100 / numSegs
+  for(let i = numSegs; i > 0; i --){
+    geometry.vertices.push(new THREE.Vector3(startSegLength*i, startSegLength*i, startSegLength*i))
   }
 
   let updatePts = []
diff --git a/save/contexts/cuttlefish/dbg-25ms-ghost.json b/save/contexts/cuttlefish/dbg-25ms-ghost.json
new file mode 100644
index 0000000..377bed8
--- /dev/null
+++ b/save/contexts/cuttlefish/dbg-25ms-ghost.json
@@ -0,0 +1,140 @@
+{
+  "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/tpath",
+      "name": "adhoc/tpath_2",
+      "outputs": [
+        {
+          "name": "position",
+          "type": "array",
+          "connections": [
+            {
+              "inHunkIndex": "3",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ],
+      "states": [
+        {
+          "name": "reset",
+          "type": "boolean",
+          "value": "false"
+        }
+      ]
+    },
+    {
+      "type": "adhoc/saturn",
+      "name": "adhoc/saturn_3",
+      "inputs": [
+        {
+          "name": "posn",
+          "type": "array"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "posn",
+          "type": "array",
+          "connections": [
+            {
+              "inHunkIndex": "5",
+              "inHunkInput": "0"
+            }
+          ]
+        },
+        {
+          "name": "outx",
+          "type": "number",
+          "connections": [
+            {
+              "inHunkIndex": "4",
+              "inHunkInput": "0"
+            }
+          ]
+        },
+        {
+          "name": "outy",
+          "type": "number"
+        },
+        {
+          "name": "outz",
+          "type": "number"
+        }
+      ]
+    },
+    {
+      "type": "adhoc/consumer",
+      "name": "adhoc/consumer_5",
+      "inputs": [
+        {
+          "name": "takes",
+          "type": "number"
+        }
+      ],
+      "states": [
+        {
+          "name": "period",
+          "type": "number",
+          "value": "25"
+        }
+      ]
+    },
+    {
+      "type": "interface/threejs_ghost",
+      "name": "interface/threejs_ghost_5",
+      "inputs": [
+        {
+          "name": "point",
+          "type": "array"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
-- 
GitLab