Files
overwatch/debug2.js
2026-09-30 23:49:38 +00:00

58 lines
3.2 KiB
JavaScript

const fs = require('fs');
const html = fs.readFileSync('defense_sim.html', 'utf8');
const script = html.match(/<script>([\s\S]*?)<\/script>/)[1];
function extractFn(src, name) {
const re = new RegExp('function ' + name + '\\(', 'g');
const m = re.exec(src);
if (!m) return null;
let i = m.index, depth = 0, start = src.indexOf('{', i);
for (let j = start; j < src.length; j++) {
if (src[j] === '{') depth++;
else if (src[j] === '}') { depth--; if (depth === 0) return src.slice(i, j + 1); }
}
return null;
}
const fns = ['targetTrajectory','detectFromRadars','estimatePosition3D','estimateTrajectory','computeInterceptPoint','perpDistToLine','gaussianNoise','kmToPixels'];
eval(fns.map(n => extractFn(script, n)).filter(Boolean).join('\n'));
const MEASUREMENT_ERROR = 20.0, IR_ERROR = 3.0, SCALE = 10;
// Single prop-drone trial, fixed geometry for reproducibility
const P = { startDist:15, speed:30, cruiseMin:200, cruiseMax:200, descentStart:3, terminalAlt:0 };
const numRadars=8, numDrones=24, radarRange=20, droneSpeed=100, irRange=5, cityRadius=10, droneLine=8, dt=0.5;
const startAngle = Math.PI/3; // fixed
const startPos = [P.startDist*Math.cos(startAngle), P.startDist*Math.sin(startAngle)];
const targetAngle = Math.PI/3; // straight radial approach
const targetDist = 2;
const targetPos = [targetDist*Math.cos(targetAngle), targetDist*Math.sin(targetAngle)];
const cruiseAlt = 200;
const trajectory = targetTrajectory(startPos, targetPos, cruiseAlt, P.speed, P.descentStart, P.terminalAlt);
const radarPositions = [];
for (let i=0;i<numRadars;i++){const a=2*Math.PI*i/numRadars,d=cityRadius+2;radarPositions.push([d*Math.cos(a),d*Math.sin(a),0]);}
let time=0, detectionTime=null, observations=[];
function getTruePos(t){let b=trajectory[0],bd=1e18;for(const p of trajectory){const d=Math.abs(p.t-t);if(d<bd){bd=d;b=p;}}return b;}
for (let step=0; step<20 && detectionTime===null; step++) {
time += dt;
const tp = getTruePos(time);
const pos = [tp.x, tp.y, tp.z/1000];
const detections = detectFromRadars(pos, radarPositions, radarRange, gaussianNoise);
if (detections.length>0) observations.push({x:pos[0],y:pos[1],z:pos[2]*1000,t:time});
if (observations.length>=3) {
detectionTime = time;
const posEst = estimatePosition3D(detections, radarPositions);
if (posEst) observations[observations.length-1] = {x:posEst[0]/1000,y:posEst[1]/1000,z:posEst[2],t:time};
console.log(`=== detection at t=${time.toFixed(1)}s, ${observations.length} observations ===`);
console.log('true target pos (km):', pos.map(v=>v.toFixed(3)));
if (posEst) console.log('posEst (km):', posEst.map(v=>v.toFixed(3)));
console.log('observations (x km, y km, z m, t s):');
for (const o of observations) console.log(' ', o.x.toFixed(4), o.y.toFixed(4), o.z.toFixed(2), o.t.toFixed(1));
const traj = estimateTrajectory(observations);
const velMs = [traj.vel[0]*1000, traj.vel[1]*1000, traj.vel[2]];
console.log('vel (raw):', traj.vel.map(v=>v.toExponential(3)));
console.log('velMs:', velMs.map(v=>v.toFixed(2)));
console.log('speedEst:', Math.sqrt(velMs[0]**2+velMs[1]**2+velMs[2]**2).toFixed(1), 'R2:', traj.r2.toFixed(3));
break;
}
}