From 0885beb81ca32e30e996e7bc009bc951ecc62a2a Mon Sep 17 00:00:00 2001 From: Jake Read <jake.read@cba.mit.edu> Date: Wed, 30 Oct 2019 09:31:06 -0400 Subject: [PATCH] near refactor for periods --- hunks/adhoc/saturn.js | 238 ++++++++++++++++++++++++++++-------------- 1 file changed, 160 insertions(+), 78 deletions(-) diff --git a/hunks/adhoc/saturn.js b/hunks/adhoc/saturn.js index 22cc0bb..524ad12 100644 --- a/hunks/adhoc/saturn.js +++ b/hunks/adhoc/saturn.js @@ -112,8 +112,8 @@ export default function Saturn() { // to calculate the maximum entrance, given our exit, to make within one period of time: // let t = 2 * d / (speeds[i] + speeds[i + 1]) // current t ... - // v2, where t = period - let maxEntranceByPeriod = period / (2 * d) - speeds[i] + // v2, where t = period (1.5 is a safety factor for later rounding) + let maxEntranceByPeriod = (period * 1.5) / (2 * d) - speeds[i] // set the entrance speed to the min of JD or our Max Entrance, but no lower than the minspeed let max = Math.max(minSpeed, Math.min(speeds[i], maxEntranceByAccel, maxEntranceByPeriod)) @@ -166,9 +166,8 @@ export default function Saturn() { if (debug) console.log(`entrance speed is ${vi}`) if (debug) console.log(`exit speed is ${vf}`) if (debug) console.log(`d is ${d}, maxEntry ${maxEntry}, maxExit ${maxExit}`) - // big switch - if (maxExit <= vf) { - if (debug) console.log(`/`) + // these are common and useful: + let writeUpTick = () => { ramps.push({ vi: vi, vf: vf, @@ -176,9 +175,8 @@ export default function Saturn() { pi: pi, pf: pf }) - if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) - } else if (maxEntry <= vi) { - if (debug) console.log('\\') + } + let writeDownTick = () => { ramps.push({ vi: vi, vf: vf, @@ -186,8 +184,20 @@ export default function Saturn() { pi: pi, pf: pf }) + } + // big switch + if (maxExit <= vf) { + // the all-up and all-down segments should always be clear: + // since we already swept for these cases in the revpass + if (debug) console.log(`/`) + writeUpTick() + if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + } else if (maxEntry <= vi) { + if (debug) console.log('\\') + writeDownTick() if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) } else if (vi === cruise && vf === cruise) { + // similarely, since we're not segmenting cruise any farther, it should also be OK if (debug) console.log('--') ramps.push({ vi: vi, @@ -201,100 +211,172 @@ export default function Saturn() { if (debug) console.log('--\\') let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel) let pInter = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist)) - // seg1 - ramps.push({ - vi: vi, - vf: cruise, - t: (d - dcDist) / cruise, - pi: pi, - pf: pInter - }) - if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) - // seg 2, - ramps.push({ - vi: cruise, - vf: vf, - t: (cruise - vf) / accel, - pi: pInter, - pf: pf - }) - if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) - } else if (vf === cruise) { - if (debug) console.log('/--') - let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel) - let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist)) - // seg1 - ramps.push({ - vi: vi, - vf: cruise, - t: (cruise - vi) / accel, - pi: pi, - pf: pInter - }) - if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) - // seg2 - ramps.push({ - vi: cruise, - vf: vf, - t: (d - acDist) / cruise, - pi: pInter, - pf: pf - }) - if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) - } else { - let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel) - let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel) - if (acDist + dcDist < d) { - if (debug) console.log('/--\\') - let pa = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist)) - let pb = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist)) - // 3 segs + // now, we need to tune accel / cruise phases so that neither t is < 1 period + let tSeg1 = (d - dcDist) / cruise + let tSeg2 = (cruise - vf) / accel + if(tSeg1 < period || tSeg2 < period){ + // hopeless, write downtick + // there are other options here: adjust one to suit other, but we're not here for it + // and in these cases, the small segments, being small, can just get washed into a big ramp, ok + writeDownTick() + } else { + // and if we can't do that, we backtrack to '\\' type + // seg1 ramps.push({ vi: vi, vf: cruise, - t: (cruise - vi) / accel, + t: tSeg1, pi: pi, - pf: pa - }) - if (ramps[ramps.length - 1].t < period) console.warn('trouble seg1/3', ramps[ramps.length - 1]) - ramps.push({ - vi: cruise, - vf: cruise, - t: (d - acDist - dcDist) / cruise, - pi: pa, - pf: pb + pf: pInter }) - if (ramps[ramps.length - 1].t < period) console.warn('trouble seg2/3', ramps[ramps.length - 1]) + if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + // seg 2, ramps.push({ vi: cruise, vf: vf, - t: (cruise - vf) / accel, - pi: pb, + t: tSeg2, + pi: pInter, pf: pf }) - if (ramps[ramps.length - 1].t < period) console.warn('trouble seg3/3', ramps[ramps.length - 1]) + if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + } + } else if (vf === cruise) { + if (debug) console.log('/--') + let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel) + let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist)) + // I feel the same about this as I did above + let tSeg1 = (cruise - vi) / accel + let tSeg2 = (d - acDist) / cruise + if(tSeg1 < period || tSeg2 < period){ + writeDownTick() } else { - if (debug) console.log('/\\') - let vPeak = Math.sqrt(((2 * accel * d + Math.pow(vi, 2) + Math.pow(vf, 2)) / 2)) - let acDist = (Math.pow(vPeak, 2) - Math.pow(vi, 2)) / (2 * accel) - let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist)) + // seg1 ramps.push({ vi: vi, - vf: vPeak, - t: (vPeak - vi) / accel, + vf: cruise, + t: tSeg1, pi: pi, pf: pInter }) if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + // seg2 ramps.push({ - vi: vPeak, + vi: cruise, vf: vf, - t: (vPeak - vf) / accel, + t: tSeg2, pi: pInter, pf: pf }) if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) } + } else { + let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel) + let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel) + let writeTriangle = () => { + if (debug) console.log('/\\') + let vPeak = Math.sqrt(((2 * accel * d + Math.pow(vi, 2) + Math.pow(vf, 2)) / 2)) + let acDist = (Math.pow(vPeak, 2) - Math.pow(vi, 2)) / (2 * accel) + let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist)) + // finally, we have to check here if either / or side is too small, then default to smallticks + let tSeg1 = (vPeak - vi) / accel + let tSeg2 = (vPeak - vf) / accel + if(tSeg1 < period || tSeg2 < period){ + // bail hard, + if(vf > vi){ + writeUpTick() + } else { + writeDownTick() + } + } else { + ramps.push({ + vi: vi, + vf: vPeak, + t: tSeg1, + pi: pi, + pf: pInter + }) + if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + ramps.push({ + vi: vPeak, + vf: vf, + t: tSeg2, + pi: pInter, + pf: pf + }) + if (ramps[ramps.length - 1].t < period) console.warn('RampPass generates too-short ramp:', ramps[ramps.length - 1]) + } + } + if (acDist + dcDist < d) { + 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, + let tSeg1 = (cruise - vi) / accel + let tSeg2 = (d - acDist - dcDist) / cruise + let tSeg3 = (cruise - vf) / accel + if(tSeg2 < period){ + // for this case, contencating into a triangle is fine... it will be within ~ 50ms of extra accel time: not much + writeTriangle() + } else if (tSeg1 < period && tSeg3 < period){ + // contencate to slow-up or slow-down + if(vf > vi){ + writeUpTick() + } else { + writeDownTick() + } + } else if (tSeg1 < period){ + // write slow-triangle up to pb, + // HERE + // and last seg. as normal + ramps.push({ + vi: cruise, + vf: vf, + t: tSeg3, + pi: pb, + pf: pf + }) + } else if (tSeg3 < period){ + // write first seg as normal, + ramps.push({ + vi: vi, + vf: cruise, + t: tSeg1, + pi: pi, + pf: pa + }) + // second as slow-loss from pa -> vf + // HERE + } else { + // 3 segs + ramps.push({ + vi: vi, + vf: cruise, + t: tSeg1, + pi: pi, + pf: pa + }) + if (ramps[ramps.length - 1].t < period) console.warn('trouble seg1/3', ramps[ramps.length - 1]) + ramps.push({ + vi: cruise, + vf: cruise, + t: tSeg2, + pi: pa, + pf: pb + }) + if (ramps[ramps.length - 1].t < period) console.warn('trouble seg2/3', ramps[ramps.length - 1]) + ramps.push({ + vi: cruise, + vf: vf, + t: tSeg3, + pi: pb, + pf: pf + }) + if (ramps[ramps.length - 1].t < period) console.warn('trouble seg3/3', ramps[ramps.length - 1]) + } + } else { + // the actual triangle case + writeTriangle() + } } // end BIGSWITCH } // end for-over-positions return ramps -- GitLab