diff --git a/steps/index.html b/steps/index.html index c8ac40b..6acdba5 100644 --- a/steps/index.html +++ b/steps/index.html @@ -318,6 +318,8 @@ (P) Show Covariance + Show Dimensions diff --git a/steps/src/dom.js b/steps/src/dom.js index 995415c..b73451e 100644 --- a/steps/src/dom.js +++ b/steps/src/dom.js @@ -71,6 +71,7 @@ export const modalCancelBtn = document.getElementById("modal-cancel-btn"); export const toggleCloseUp = document.getElementById("toggle-close-up"); export const togglePredictedPos = document.getElementById("toggle-predicted-pos"); export const toggleCovariance = document.getElementById("toggle-covariance"); +export const toggleVehicleDimensions = document.getElementById("toggle-vehicle-dimensions"); export const modalProgressContainer = document.getElementById("modal-progress-container"); export const modalProgressBar = document.getElementById("modal-progress-bar"); export const modalProgressText = document.getElementById("modal-progress-text"); diff --git a/steps/src/drawUtils.js b/steps/src/drawUtils.js index 1840cb8..a6475a3 100644 --- a/steps/src/drawUtils.js +++ b/steps/src/drawUtils.js @@ -332,12 +332,12 @@ export function drawTrajectories(p, plotScales) { } const logs = track.historyLog.filter( - (log) => log.frameIdx <= appState.currentFrame + 1 + (log) => log.frameIdx <= appState.currentFrame ); if (logs.length < 2) continue; const lastLog = logs[logs.length - 1]; - if (appState.currentFrame + 1 - lastLog.frameIdx > MAX_TRAJECTORY_LENGTH) + if (appState.currentFrame - lastLog.frameIdx > MAX_TRAJECTORY_LENGTH) continue; const isCurrentlyStationary = lastLog.isStationary; @@ -388,34 +388,52 @@ export function drawTrajectories(p, plotScales) { } else { // MODE 2: DEFAULT TTC SCHEME (Use pre-calculated category from JSON) - // FIND the TTC category from the new timeline - let ttcCategory = null; - if (track.ttcCategoryTimeline) { - const ttcEntry = track.ttcCategoryTimeline.find( - (entry) => entry.frameIdx === lastLog.frameIdx - ); - ttcCategory = ttcEntry ? ttcEntry.ttcCategory : null; // Get the category if found - } + // 1. Check for 'risk' property (New Logic) + if (lastLog.risk !== undefined && lastLog.risk !== null) { + switch (lastLog.risk) { + case 2: // High Risk + trajectoryColor = p.color(localTtcColors.critical); // Red + break; + case 1: // Medium Risk + trajectoryColor = p.color(localTtcColors.high); // Orange + break; + case 0: // Low Risk + trajectoryColor = p.color(localTtcColors.away); // Blue + break; + default: + trajectoryColor = p.color(localTtcColors.default); // Gray + break; + } + } else { + // 2. Fallback to 'ttcCategoryTimeline' (Old Logic) + let ttcCategory = null; + if (track.ttcCategoryTimeline) { + const ttcEntry = track.ttcCategoryTimeline.find( + (entry) => entry.frameIdx === lastLog.frameIdx + ); + ttcCategory = ttcEntry ? ttcEntry.ttcCategory : null; // Get the category if found + } - switch (ttcCategory) { - case 3: - trajectoryColor = p.color(localTtcColors.critical); - break; - case 2: - trajectoryColor = p.color(localTtcColors.high); - break; - case 1: - trajectoryColor = p.color(localTtcColors.medium); - break; - case 0: - trajectoryColor = p.color(localTtcColors.low); - break; - case -1: - trajectoryColor = p.color(localTtcColors.away); - break; - default: - trajectoryColor = p.color(localTtcColors.default); - break; + switch (ttcCategory) { + case 3: + trajectoryColor = p.color(localTtcColors.critical); + break; + case 2: + trajectoryColor = p.color(localTtcColors.high); + break; + case 1: + trajectoryColor = p.color(localTtcColors.medium); + break; + case 0: + trajectoryColor = p.color(localTtcColors.low); + break; + case -1: + trajectoryColor = p.color(localTtcColors.away); + break; + default: + trajectoryColor = p.color(localTtcColors.default); + break; + } } } @@ -522,10 +540,15 @@ export function drawTrackMarkers(p, plotScales) { // Defer Text Drawing const speed = (Math.sqrt(vx * vx + vy * vy) * 3.6).toFixed(1); - let ttcText = - log.ttc !== null && isFinite(log.ttc) && log.ttc < 100 - ? `TTC: ${log.ttc.toFixed(1)}s` - : ""; + let ttcText = ""; + if ("tti" in log) { + const tti = log.tti; + if (typeof tti === "number" && isFinite(tti)) { + ttcText = `TTI: ${tti.toFixed(1)}s`; + } + } else if (log.ttc !== null && isFinite(log.ttc) && log.ttc < 100) { + ttcText = `TTC: ${log.ttc.toFixed(1)}s`; + } if (log.state !== undefined && log.state !== null) { ttcText += ttcText ? ` | st: ${log.state}` : `st: ${log.state}`; } @@ -886,6 +909,40 @@ export function drawCovarianceEllipse( } } +export function drawObjectDimensions( + p, + position, + dims, + angle, + plotScales, + isStationary +) { + try { + if (isStationary) return; + const [dimA, dimB] = dims; + const angledegrees = 90 + angle; + p.push(); + p.noFill(); + p.stroke(128, 0, 128, 150); // Purple + p.strokeWeight(1); + p.translate( + position[0] * plotScales.plotScaleX, + position[1] * plotScales.plotScaleY + ); + p.rotate(p.radians(angledegrees)); + p.rectMode(p.CENTER); + p.rect( + 0, + 0, + dimA * 2 * plotScales.plotScaleX, + dimB * 2 * plotScales.plotScaleY + ); + p.pop(); + } catch (error) { + console.error("Error in drawObjectDimensions:", error); + } +} + export function drawEgoVehicle(p, plotScales) { try { diff --git a/steps/src/p5/radarSketch.js b/steps/src/p5/radarSketch.js index 67a2eea..ff37d56 100644 --- a/steps/src/p5/radarSketch.js +++ b/steps/src/p5/radarSketch.js @@ -14,6 +14,7 @@ import { togglePredictedPos, toggleCovariance, toggleVelocity, + toggleVehicleDimensions, toggleClusterColor, } from "../dom.js"; import { @@ -26,6 +27,7 @@ import { snrColors, handleCloseUpDisplay, drawCovarianceEllipse, + drawObjectDimensions, ttcColors, drawRegionsOfInterest, drawClusterCentroids, @@ -203,15 +205,13 @@ export const radarSketch = function (p) { // } if (togglePredictedPos.checked) { for (const track of appState.vizData.tracks) { - const log = track.historyLog.find( - (log) => log.frameIdx === appState.currentFrame - ); + const log = track.historyLog.find((log) => log.frameIdx === appState.currentFrame); if ( log && log.predictedPosition && log.predictedPosition[0] !== null ) { - const pos = log.predictedPosition; + const pos = log.predictedPosition; //using predicted position from data const x = pos[0] * plotScales.plotScaleX; const y = pos[1] * plotScales.plotScaleY; @@ -230,8 +230,7 @@ export const radarSketch = function (p) { if (toggleCovariance.checked) { for (const track of appState.vizData.tracks) { const log = track.historyLog.find( - (log) => log.frameIdx === appState.currentFrame + 1 - ); + (log) => log.frameIdx === appState.currentFrame); if ( log && log.ellipseRadii && @@ -251,6 +250,29 @@ export const radarSketch = function (p) { } } } + if (toggleVehicleDimensions.checked) { + for (const track of appState.vizData.tracks) { + const log = track.historyLog.find( + (log) => log.frameIdx === appState.currentFrame); + if ( + log && + log.objectExtentRadii && + typeof log.objectExtentAngle !== "undefined" + ) { + const pos = log.correctedPosition; + if (pos && pos[0] !== null) { + drawObjectDimensions( + p, + pos, + log.objectExtentRadii, + log.objectExtentAngle, + plotScales, + log.isStationary + ); + } + } + } + } } // Draw cluster centroids if enabled diff --git a/steps/src/ui.js b/steps/src/ui.js index 7517cf8..f573255 100644 --- a/steps/src/ui.js +++ b/steps/src/ui.js @@ -18,6 +18,8 @@ import { toggleDebugOverlay, toggleDebug2Overlay, toggleCloseUp, + toggleCovariance, + toggleVehicleDimensions, snrMinInput, snrMaxInput, applySnrBtn, @@ -185,7 +187,7 @@ export function initUIEventListeners() { t.addEventListener("change", handleColorToggles); }); - [toggleVelocity, toggleEgoSpeed, toggleFrameNorm, toggleTracks, toggleDebugOverlay, toggleDebug2Overlay].forEach((t) => { + [toggleVelocity, toggleEgoSpeed, toggleFrameNorm, toggleTracks, toggleDebugOverlay, toggleDebug2Overlay, toggleCovariance, toggleVehicleDimensions].forEach((t) => { t.addEventListener("change", () => { if (appState.p5_instance) appState.p5_instance.redraw(); if (t === toggleDebugOverlay || t === toggleDebug2Overlay) {