Zhen Ye commited on
Commit
2dd0fb8
·
1 Parent(s): 2fb805f

chore(frontend): Remove unused UI sections - radar, intel summary, HEL knobs, atmosphere, and trade space

Browse files

Cleaned up frontend by removing:
- Mission Intel Summary card
- Radar/Relative Geometry sections (Tab 1 & 2)
- HEL & Director Knobs card
- Atmosphere & Maritime card
- Trade Space tab and section (Tab 3)
- Related JS imports, event handlers, and script includes

Files changed (2) hide show
  1. frontend/index.html +1 -209
  2. frontend/js/main.js +22 -61
frontend/index.html CHANGED
@@ -112,128 +112,6 @@
112
  </div>
113
  </div>
114
 
115
- <div class="card">
116
- <h2>Mission Intel Summary</h2>
117
- <div class="hint">Unbiased 2–3 sentence scene description computed from a few sampled frames + detected
118
- objects (no location inference).</div>
119
-
120
- <div class="intel">
121
- <div class="intel-top">
122
- <span class="badge"><span class="dot warn" id="intelDot"
123
- style="width:7px;height:7px;box-shadow:none"></span><span id="intelStamp">Idle</span></span>
124
- <button id="btnIntelRefresh" class="btn secondary"
125
- style="padding:8px 10px; border-radius:10px; font-weight:700">Refresh</button>
126
- </div>
127
-
128
- <div class="thumbrow" aria-label="sampled frames">
129
- <img id="intelThumb0" alt="sample frame 1" />
130
- <img id="intelThumb1" alt="sample frame 2" />
131
- <img id="intelThumb2" alt="sample frame 3" />
132
- </div>
133
-
134
- <div id="intelSummaryBox" class="intelbox">Upload a video, then click <b>Reason</b> to generate an unbiased
135
- scene summary.</div>
136
- </div>
137
- </div>
138
-
139
- <div class="card">
140
- <h2>HEL & Director Knobs</h2>
141
- <div class="grid2">
142
- <div>
143
- <label>Max output power (kW)</label>
144
- <input id="helPower" type="range" min="20" max="250" step="1" value="60" />
145
- <div class="row"><small class="mini"><span id="helPowerVal">60</span> kW</small><small class="mini">turret
146
- output</small></div>
147
- </div>
148
- <div>
149
- <label>Aperture (m)</label>
150
- <input id="helAperture" type="range" min="0.05" max="0.6" step="0.01" value="0.25" />
151
- <div class="row"><small class="mini"><span id="helApertureVal">0.25</span> m</small><small
152
- class="mini">beam director</small></div>
153
- </div>
154
- </div>
155
-
156
- <div class="grid2 mt-sm">
157
- <div>
158
- <label>Beam quality (M²)</label>
159
- <input id="helM2" type="range" min="1.1" max="4.0" step="0.1" value="1.6" />
160
- <div class="row"><small class="mini"><span id="helM2Val">1.6</span></small><small class="mini">lower is
161
- better</small></div>
162
- </div>
163
- <div>
164
- <label>Jitter (μrad RMS)</label>
165
- <input id="helJitter" type="range" min="0.5" max="15" step="0.1" value="3.2" />
166
- <div class="row"><small class="mini"><span id="helJitterVal">3.2</span></small><small
167
- class="mini">director stability</small></div>
168
- </div>
169
- </div>
170
-
171
- <div class="grid2 mt-sm">
172
- <div>
173
- <label>Mode</label>
174
- <select id="helMode">
175
- <option value="cw">CW (continuous)</option>
176
- <option value="burst">Burst (duty-limited)</option>
177
- <option value="pulse">Pulsed (peak shaping)</option>
178
- </select>
179
- </div>
180
- <div>
181
- <label>Duty cycle (%)</label>
182
- <input id="helDuty" type="range" min="10" max="100" step="1" value="85" />
183
- <div class="row"><small class="mini"><span id="helDutyVal">85</span>%</small><small class="mini">thermal /
184
- power</small></div>
185
- </div>
186
- </div>
187
- </div>
188
-
189
- <div class="card">
190
- <h2>Atmosphere & Maritime</h2>
191
- <div class="grid2">
192
- <div>
193
- <label>Visibility (km)</label>
194
- <input id="atmVis" type="range" min="1" max="30" step="1" value="16" />
195
- <div class="row"><small class="mini"><span id="atmVisVal">16</span> km</small><small
196
- class="mini">aerosol/haze</small></div>
197
- </div>
198
- <div>
199
- <label>Turbulence (Cn²)</label>
200
- <input id="atmCn2" type="range" min="1" max="10" step="1" value="5" />
201
- <div class="row"><small class="mini"><span id="atmCn2Val">5</span>/10</small><small
202
- class="mini">wavefront</small></div>
203
- </div>
204
- </div>
205
-
206
- <div class="grid2 mt-sm">
207
- <div>
208
- <label>Sea spray</label>
209
- <input id="seaSpray" type="range" min="0" max="10" step="1" value="2" />
210
- <div class="row"><small class="mini"><span id="seaSprayVal">2</span>/10</small><small class="mini">salt
211
- attenuation</small></div>
212
- </div>
213
- <div>
214
- <label>Adaptive optics</label>
215
- <input id="aoQ" type="range" min="0" max="10" step="1" value="7" />
216
- <div class="row"><small class="mini"><span id="aoQVal">7</span>/10</small><small class="mini">turbulence
217
- mitigation</small></div>
218
- </div>
219
- </div>
220
-
221
- <div class="grid2 mt-sm">
222
- <div>
223
- <label>Baseline range (m)</label>
224
- <input id="rangeBase" type="range" min="200" max="6000" step="25" value="1500" />
225
- <div class="row"><small class="mini"><span id="rangeBaseVal">1500</span> m</small><small
226
- class="mini">median target</small></div>
227
- </div>
228
- <div>
229
- <label>Update rate (Hz)</label>
230
- <input id="detHz" type="range" min="1" max="12" step="1" value="6" />
231
- <div class="row"><small class="mini"><span id="detHzVal">6</span> Hz</small><small class="mini">tab 2
232
- detection</small></div>
233
- </div>
234
- </div>
235
- </div>
236
-
237
  <div class="card">
238
  <h2>Engagement Policy</h2>
239
  <div class="grid2">
@@ -274,7 +152,6 @@
274
  <div class="tabs">
275
  <button class="tabbtn active" data-tab="frame">Tab 1 · Frame-1 Reason</button>
276
  <button class="tabbtn" data-tab="engage">Tab 2 · Video Engage</button>
277
- <button class="tabbtn" data-tab="trade">Trade Space</button>
278
  </div>
279
 
280
  <!-- ===== Tab 1 ===== -->
@@ -312,13 +189,7 @@
312
  </div>
313
  </div>
314
 
315
- <div class="panel panel-objects radar">
316
- <h3>
317
- <span>Radar / Relative Geometry</span>
318
- <span class="rightnote" id="objCount">0</span>
319
- </h3>
320
- <canvas id="frameRadar" width="600" height="260" class="full-size"></canvas>
321
- </div>
322
 
323
  <div class="panel panel-features">
324
  <h3>
@@ -413,93 +284,17 @@
413
  </div>
414
 
415
  <div class="engage-right">
416
- <div class="panel radar">
417
- <h3>
418
- <span>Radar / Relative Geometry</span>
419
- <span class="rightnote">Dynamic</span>
420
- </h3>
421
- <canvas id="radarCanvas" width="600" height="260" class="full-size"></canvas>
422
- </div>
423
-
424
  <div class="panel" style="flex:1; min-height:0">
425
  <h3>
426
  <span>Live Track Cards</span>
427
  <span class="rightnote" id="liveStamp">—</span>
428
  </h3>
429
  <div class="list" id="trackList" style="max-height:none"></div>
430
-
431
- <!-- Radar Controls -->
432
- <div class="mt-sm" style="padding: 10px; background: rgba(0,0,0,0.2); border-radius: 6px;">
433
- <div class="row">
434
- <label class="mini">History Trails</label>
435
- <input id="radarHistoryLen" type="range" min="0" max="100" value="30" style="flex:1; margin:0 8px">
436
- <small class="mini" id="radarHistoryVal">30</small>
437
- </div>
438
- <div class="row mt-xs">
439
- <label class="mini">Future Pred</label>
440
- <input id="radarFutureLen" type="range" min="0" max="100" value="30" style="flex:1; margin:0 8px">
441
- <small class="mini" id="radarFutureVal">30</small>
442
- </div>
443
- </div>
444
  </div>
445
  </div>
446
  </div>
447
  </section>
448
 
449
- <!-- ===== Tab 3 ===== -->
450
- <section class="tab" id="tab-trade">
451
- <div class="trade-grid">
452
- <div class="panel plot">
453
- <h3>
454
- <span>Range Sensitivity · Max vs Required Power · Dwell</span>
455
- <span class="rightnote">Interactive</span>
456
- </h3>
457
- <canvas id="tradeCanvas" width="1100" height="420" class="full-size"></canvas>
458
- </div>
459
-
460
- <div class="panel">
461
- <h3>
462
- <span>Trade Controls</span>
463
- <span class="rightnote">What-if</span>
464
- </h3>
465
- <div class="hint">This plot is computed from your current HEL and atmosphere knobs. It uses the selected
466
- target’s baseline requirements (from Tab 1) as a reference curve.</div>
467
-
468
- <div class="mt-md">
469
- <label>Selected target for curve</label>
470
- <select id="tradeTarget"></select>
471
- </div>
472
-
473
- <div class="grid2 mt-sm">
474
- <div>
475
- <label>Range sweep min (m)</label>
476
- <input id="rMin" type="number" value="200" min="50" max="10000" step="50" />
477
- </div>
478
- <div>
479
- <label>Range sweep max (m)</label>
480
- <input id="rMax" type="number" value="6000" min="100" max="20000" step="50" />
481
- </div>
482
- </div>
483
-
484
- <div class="row mt-md">
485
- <label>Show P(kill)</label>
486
- <select id="showPk">
487
- <option value="on">On</option>
488
- <option value="off">Off</option>
489
- </select>
490
- </div>
491
-
492
- <div class="btnrow">
493
- <button class="btn secondary" id="btnReplot">Replot</button>
494
- <button class="btn secondary" id="btnSnap">Snapshot (log)</button>
495
- </div>
496
-
497
- <div class="hint">This tab is designed to look like a weapon trade-space console: propagation, lethality
498
- margin, and dwell inflation with range and atmosphere.</div>
499
- </div>
500
- </div>
501
- </section>
502
- </main>
503
  </div>
504
 
505
  <footer>
@@ -527,12 +322,9 @@
527
  <script src="./js/core/tracker.js"></script>
528
  <script src="./js/api/client.js"></script>
529
  <script src="./js/ui/overlays.js"></script>
530
- <script src="./js/ui/radar.js"></script>
531
  <script src="./js/ui/cards.js"></script>
532
  <script src="./js/ui/features.js"></script>
533
- <script src="./js/ui/intel.js"></script>
534
  <script src="./js/ui/cursor.js"></script>
535
- <script src="./js/ui/trade.js"></script>
536
  <script src="./data/helicopter_demo_data.js"></script>
537
  <script src="./js/core/demo.js"></script>
538
  <script src="./js/main.js"></script>
 
112
  </div>
113
  </div>
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  <div class="card">
116
  <h2>Engagement Policy</h2>
117
  <div class="grid2">
 
152
  <div class="tabs">
153
  <button class="tabbtn active" data-tab="frame">Tab 1 · Frame-1 Reason</button>
154
  <button class="tabbtn" data-tab="engage">Tab 2 · Video Engage</button>
 
155
  </div>
156
 
157
  <!-- ===== Tab 1 ===== -->
 
189
  </div>
190
  </div>
191
 
192
+
 
 
 
 
 
 
193
 
194
  <div class="panel panel-features">
195
  <h3>
 
284
  </div>
285
 
286
  <div class="engage-right">
 
 
 
 
 
 
 
 
287
  <div class="panel" style="flex:1; min-height:0">
288
  <h3>
289
  <span>Live Track Cards</span>
290
  <span class="rightnote" id="liveStamp">—</span>
291
  </h3>
292
  <div class="list" id="trackList" style="max-height:none"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  </div>
294
  </div>
295
  </div>
296
  </section>
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  </div>
299
 
300
  <footer>
 
322
  <script src="./js/core/tracker.js"></script>
323
  <script src="./js/api/client.js"></script>
324
  <script src="./js/ui/overlays.js"></script>
 
325
  <script src="./js/ui/cards.js"></script>
326
  <script src="./js/ui/features.js"></script>
 
327
  <script src="./js/ui/cursor.js"></script>
 
328
  <script src="./data/helicopter_demo_data.js"></script>
329
  <script src="./js/core/demo.js"></script>
330
  <script src="./js/main.js"></script>
frontend/js/main.js CHANGED
@@ -12,12 +12,9 @@ document.addEventListener("DOMContentLoaded", () => {
12
  const { load: loadDemo, getFrameData: getDemoFrameData, enable: enableDemo } = APP.core.demo;
13
 
14
  // UI Renderers
15
- const { renderFrameRadar, renderLiveRadar } = APP.ui.radar;
16
  const { renderFrameOverlay, renderEngageOverlay } = APP.ui.overlays;
17
  const { renderFrameTrackList } = APP.ui.cards;
18
  const { renderFeatures } = APP.ui.features;
19
- const { renderTrade, populateTradeTarget, snapshotTrade } = APP.ui.trade;
20
- const { computeIntelSummary, resetIntelUI, renderMissionContext } = APP.ui.intel;
21
  const { tickAgentCursor, moveCursorToRect } = APP.ui.cursor;
22
  const { matchAndUpdateTracks, predictTracks } = APP.core.tracker;
23
  const { defaultAimpoint } = APP.core.physics;
@@ -36,9 +33,6 @@ document.addEventListener("DOMContentLoaded", () => {
36
  const btnReset = $("#btnReset");
37
  const btnPause = $("#btnPause");
38
  const btnToggleSidebar = $("#btnToggleSidebar");
39
- const btnIntelRefresh = $("#btnIntelRefresh");
40
- const btnReplot = $("#btnReplot");
41
- const btnSnap = $("#btnSnap");
42
 
43
  const detectorSelect = $("#detectorSelect");
44
  const missionText = $("#missionText");
@@ -66,7 +60,6 @@ document.addEventListener("DOMContentLoaded", () => {
66
 
67
  // Initial UI sync
68
  syncKnobDisplays();
69
- renderMissionContext();
70
  setHfStatus("idle");
71
 
72
  // Start main loop
@@ -150,7 +143,7 @@ document.addEventListener("DOMContentLoaded", () => {
150
  if (!state.hasReasoned) return;
151
  await recomputeHEL();
152
  renderFrameOverlay();
153
- renderTrade();
154
  log("HEL parameters recomputed.", "g");
155
  });
156
  }
@@ -163,7 +156,7 @@ document.addEventListener("DOMContentLoaded", () => {
163
  renderFrameTrackList();
164
  renderFrameOverlay();
165
  renderFeatures(null);
166
- renderTrade();
167
  log("Detections cleared.", "t");
168
  });
169
  }
@@ -200,8 +193,6 @@ document.addEventListener("DOMContentLoaded", () => {
200
  state.tracker.running = false;
201
  state.tracker.nextId = 1;
202
  renderFrameTrackList();
203
- renderFrameRadar();
204
- renderLiveRadar();
205
  log("Engage reset.", "t");
206
  });
207
  }
@@ -218,47 +209,28 @@ document.addEventListener("DOMContentLoaded", () => {
218
  }
219
  });
220
  }
 
221
 
222
- // Intel refresh
223
- if (btnIntelRefresh) {
224
- btnIntelRefresh.addEventListener("click", async () => {
225
- if (!state.videoLoaded) return;
226
- log("Refreshing mission intel summary...", "t");
227
- await computeIntelSummary();
228
- });
229
- }
230
 
231
- // Trade space controls
232
- if (btnReplot) {
233
- btnReplot.addEventListener("click", renderTrade);
234
- }
235
- if (btnSnap) {
236
- btnSnap.addEventListener("click", snapshotTrade);
237
- }
238
- const tradeTarget = $("#tradeTarget");
239
- if (tradeTarget) {
240
- tradeTarget.addEventListener("change", renderTrade);
241
- }
242
 
243
- // Track selection event
244
- document.addEventListener("track-selected", (e) => {
245
- state.selectedId = e.detail.id;
246
- state.tracker.selectedTrackId = e.detail.id;
247
- renderFrameTrackList();
248
- renderFrameOverlay();
249
- const det = state.detections.find(d => d.id === state.selectedId);
250
- renderFeatures(det);
 
 
 
 
 
 
 
 
 
251
  });
252
-
253
- // Cursor mode toggle
254
- if (cursorMode) {
255
- cursorMode.addEventListener("change", () => {
256
- state.ui.cursorMode = cursorMode.value;
257
- if (state.ui.cursorMode === "off" && APP.ui.cursor.setCursorVisible) {
258
- APP.ui.cursor.setCursorVisible(false);
259
- }
260
- });
261
- }
262
  }
263
 
264
  function setupKnobListeners() {
@@ -270,7 +242,7 @@ document.addEventListener("DOMContentLoaded", () => {
270
  if (state.hasReasoned) {
271
  recomputeHEL();
272
  renderFrameOverlay();
273
- renderTrade();
274
  }
275
  });
276
  });
@@ -327,13 +299,8 @@ document.addEventListener("DOMContentLoaded", () => {
327
  if (tab) tab.classList.add("active");
328
 
329
  // Tab-specific actions
330
- if (btn.dataset.tab === "trade") {
331
- populateTradeTarget();
332
- renderTrade();
333
- }
334
  if (btn.dataset.tab === "engage") {
335
  resizeOverlays();
336
- renderLiveRadar();
337
  }
338
  });
339
  });
@@ -367,7 +334,7 @@ document.addEventListener("DOMContentLoaded", () => {
367
  renderFrameTrackList();
368
  renderFrameOverlay();
369
  renderFeatures(null);
370
- renderTrade();
371
 
372
  setStatus("warn", "REASONING · Running perception pipeline");
373
 
@@ -500,10 +467,6 @@ document.addEventListener("DOMContentLoaded", () => {
500
 
501
  // Seed tracks for Tab 2
502
  seedTracksFromTab1();
503
- renderFrameRadar();
504
-
505
- // Generate intel summary (async)
506
- computeIntelSummary();
507
  }).catch(err => {
508
  log(`Polling error: ${err.message}`, "e");
509
  stopStreamingMode();
@@ -760,8 +723,6 @@ document.addEventListener("DOMContentLoaded", () => {
760
  } // End if(running)
761
 
762
  // Render UI
763
- if (renderFrameRadar) renderFrameRadar();
764
- if (renderLiveRadar) renderLiveRadar();
765
  if (renderFrameOverlay) renderFrameOverlay();
766
  if (renderEngageOverlay) renderEngageOverlay();
767
  if (tickAgentCursor) tickAgentCursor();
 
12
  const { load: loadDemo, getFrameData: getDemoFrameData, enable: enableDemo } = APP.core.demo;
13
 
14
  // UI Renderers
 
15
  const { renderFrameOverlay, renderEngageOverlay } = APP.ui.overlays;
16
  const { renderFrameTrackList } = APP.ui.cards;
17
  const { renderFeatures } = APP.ui.features;
 
 
18
  const { tickAgentCursor, moveCursorToRect } = APP.ui.cursor;
19
  const { matchAndUpdateTracks, predictTracks } = APP.core.tracker;
20
  const { defaultAimpoint } = APP.core.physics;
 
33
  const btnReset = $("#btnReset");
34
  const btnPause = $("#btnPause");
35
  const btnToggleSidebar = $("#btnToggleSidebar");
 
 
 
36
 
37
  const detectorSelect = $("#detectorSelect");
38
  const missionText = $("#missionText");
 
60
 
61
  // Initial UI sync
62
  syncKnobDisplays();
 
63
  setHfStatus("idle");
64
 
65
  // Start main loop
 
143
  if (!state.hasReasoned) return;
144
  await recomputeHEL();
145
  renderFrameOverlay();
146
+
147
  log("HEL parameters recomputed.", "g");
148
  });
149
  }
 
156
  renderFrameTrackList();
157
  renderFrameOverlay();
158
  renderFeatures(null);
159
+
160
  log("Detections cleared.", "t");
161
  });
162
  }
 
193
  state.tracker.running = false;
194
  state.tracker.nextId = 1;
195
  renderFrameTrackList();
 
 
196
  log("Engage reset.", "t");
197
  });
198
  }
 
209
  }
210
  });
211
  }
212
+ }
213
 
 
 
 
 
 
 
 
 
214
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
+ // Track selection event
217
+ document.addEventListener("track-selected", (e) => {
218
+ state.selectedId = e.detail.id;
219
+ state.tracker.selectedTrackId = e.detail.id;
220
+ renderFrameTrackList();
221
+ renderFrameOverlay();
222
+ const det = state.detections.find(d => d.id === state.selectedId);
223
+ renderFeatures(det);
224
+ });
225
+
226
+ // Cursor mode toggle
227
+ if (cursorMode) {
228
+ cursorMode.addEventListener("change", () => {
229
+ state.ui.cursorMode = cursorMode.value;
230
+ if (state.ui.cursorMode === "off" && APP.ui.cursor.setCursorVisible) {
231
+ APP.ui.cursor.setCursorVisible(false);
232
+ }
233
  });
 
 
 
 
 
 
 
 
 
 
234
  }
235
 
236
  function setupKnobListeners() {
 
242
  if (state.hasReasoned) {
243
  recomputeHEL();
244
  renderFrameOverlay();
245
+
246
  }
247
  });
248
  });
 
299
  if (tab) tab.classList.add("active");
300
 
301
  // Tab-specific actions
 
 
 
 
302
  if (btn.dataset.tab === "engage") {
303
  resizeOverlays();
 
304
  }
305
  });
306
  });
 
334
  renderFrameTrackList();
335
  renderFrameOverlay();
336
  renderFeatures(null);
337
+
338
 
339
  setStatus("warn", "REASONING · Running perception pipeline");
340
 
 
467
 
468
  // Seed tracks for Tab 2
469
  seedTracksFromTab1();
 
 
 
 
470
  }).catch(err => {
471
  log(`Polling error: ${err.message}`, "e");
472
  stopStreamingMode();
 
723
  } // End if(running)
724
 
725
  // Render UI
 
 
726
  if (renderFrameOverlay) renderFrameOverlay();
727
  if (renderEngageOverlay) renderEngageOverlay();
728
  if (tickAgentCursor) tickAgentCursor();