feat: Add simulation analyzer with comprehensive metric tracking and a utility for calculating minimum block size.
This commit is contained in:
@@ -4,6 +4,7 @@ export const calculateMinBlockSize = (block: Block): Size => {
|
||||
let minWidth = 100;
|
||||
let minHeight = 50;
|
||||
let stackedHeight = 0; // Track cumulative height for stacked elements
|
||||
let stackedElementCount = 0; // Track number of stacked elements for gap calculation
|
||||
|
||||
block.elements.forEach((element) => {
|
||||
if (element.positionType === "absolute") {
|
||||
@@ -17,12 +18,15 @@ export const calculateMinBlockSize = (block: Block): Size => {
|
||||
minWidth = Math.max(minWidth, (element.size?.width || 200) + 40);
|
||||
// Height: sum them up since they stack
|
||||
stackedHeight += element.size?.height || 60;
|
||||
stackedElementCount++;
|
||||
}
|
||||
});
|
||||
|
||||
// Add padding to stacked height and compare with minHeight from absolute elements
|
||||
// Add padding to stacked height and gaps between elements
|
||||
if (stackedHeight > 0) {
|
||||
minHeight = Math.max(minHeight, stackedHeight + 40);
|
||||
// Add 10px gap between each pair of stacked elements
|
||||
const gapsBetweenElements = Math.max(0, stackedElementCount - 1) * 5;
|
||||
minHeight = Math.max(minHeight, stackedHeight + gapsBetweenElements + 40);
|
||||
}
|
||||
|
||||
return { width: minWidth, height: minHeight };
|
||||
|
||||
@@ -193,6 +193,9 @@ function Analyzer() {
|
||||
// Track previous vehicle phases to detect trip completion
|
||||
const previousVehiclePhasesRef = useRef<Record<string, string>>({});
|
||||
|
||||
// Track previous crane phases to detect cycle completion
|
||||
const previousCranePhasesRef = useRef<Record<string, string>>({});
|
||||
|
||||
// Material lifecycle tracking
|
||||
const materialLifecycleRef = useRef<
|
||||
Record<
|
||||
@@ -227,6 +230,7 @@ function Analyzer() {
|
||||
previousArmBotActionsRef.current = {};
|
||||
previousHumanCountsRef.current = {};
|
||||
previousVehiclePhasesRef.current = {};
|
||||
previousCranePhasesRef.current = {};
|
||||
materialLifecycleRef.current = {};
|
||||
setAnalysis(null);
|
||||
setAnalyzing(false);
|
||||
@@ -2487,6 +2491,49 @@ function Analyzer() {
|
||||
});
|
||||
}, [vehicles, isPlaying]);
|
||||
|
||||
// Monitor Crane phase changes to track completed cycles, loads, and lifts
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
|
||||
cranes.forEach((crane) => {
|
||||
const previousPhase = previousCranePhasesRef.current[crane.modelUuid];
|
||||
const currentPhase = crane.currentPhase;
|
||||
|
||||
// Check for transition from 'pickup-drop' to 'init' (Cycle completed)
|
||||
if (previousPhase === "pickup-drop" && currentPhase === "init") {
|
||||
// Increment cycles completed
|
||||
if (!completedActionsRef.current[crane.modelUuid]) {
|
||||
completedActionsRef.current[crane.modelUuid] = 0;
|
||||
}
|
||||
completedActionsRef.current[crane.modelUuid]++;
|
||||
|
||||
// Track loads handled (number of materials carried in this cycle)
|
||||
const loadsInCycle = crane.currentMaterials?.length || 1;
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_loads`]) {
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`] += loadsInCycle;
|
||||
}
|
||||
|
||||
// Track lifts (picking phase indicates a lift operation)
|
||||
if (previousPhase !== "picking" && currentPhase === "picking") {
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_lifts`]) {
|
||||
completedActionsRef.current[`${crane.modelUuid}_lifts`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_lifts`]++;
|
||||
|
||||
// Track lift height (assuming a default lift height of 5 meters for now)
|
||||
// In a real scenario, this would be calculated from crane constraints
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_lift_height`]) {
|
||||
completedActionsRef.current[`${crane.modelUuid}_lift_height`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_lift_height`] += 5;
|
||||
}
|
||||
|
||||
previousCranePhasesRef.current[crane.modelUuid] = currentPhase;
|
||||
});
|
||||
}, [cranes, isPlaying]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user