From 4e0240929d0b10ca5d1ceb5888c84b5f35365def Mon Sep 17 00:00:00 2001 From: Poovizhi99 Date: Wed, 14 May 2025 10:16:30 +0530 Subject: [PATCH] added active time with play,pause,reset and based on speed for vehicle --- .../instances/instance/vehicleInstance.tsx | 95 ++++++++++++++++--- app/src/store/simulation/useVehicleStore.ts | 11 +++ .../components/marketPlace/marketPlace.scss | 1 + 3 files changed, 94 insertions(+), 13 deletions(-) diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index d054a10..4e9a298 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -11,10 +11,7 @@ import { useProductStore } from '../../../../../store/simulation/useProductStore import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import MaterialAnimator from '../animator/materialAnimator'; -type Timer = { - start: number | null; - active: boolean; -}; + function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) { const { navMesh } = useNavMesh(); const { isPlaying } = usePlayButtonStore(); @@ -23,20 +20,33 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) const { triggerPointActions } = useTriggerHandler(); const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore(); const { selectedProduct } = useSelectedProduct(); - const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore(); + const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = useVehicleStore(); + const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); const pauseTimeRef = useRef(null); + const idleTimeRef = useRef(0); + const activeTimeRef = useRef(0); const isPausedRef = useRef(false); + const isSpeedRef = useRef(0); let startTime: number; let fixedInterval: number; const { speed } = useAnimationPlaySpeed(); const { isPaused } = usePauseButtonStore(); + const previousTimeRef = useRef(null); // Tracks the last frame time + const isActiveRef = useRef(agvDetail.isActive); // Tracks the previous isActive state + const animationFrameIdRef = useRef(null); // Tracks the animation frame ID + + useEffect(() => { isPausedRef.current = isPaused; }, [isPaused]); + useEffect(() => { + isSpeedRef.current = speed; + }, [speed]); + const computePath = useCallback( (start: any, end: any) => { try { @@ -54,7 +64,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) ); function vehicleStatus(modelId: string, status: string) { - // + // console.log(`${modelId} , ${status}`); } // Function to reset everything @@ -68,6 +78,14 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) startTime = 0; isPausedRef.current = false; pauseTimeRef.current = 0; + resetTime(agvDetail.modelUuid) + activeTimeRef.current = 0 + idleTimeRef.current = 0 + previousTimeRef.current = null + if (animationFrameIdRef.current !== null) { + cancelAnimationFrame(animationFrameIdRef.current) + animationFrameIdRef.current = null + } } useEffect(() => { @@ -115,12 +133,60 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point'); } } - } else { + } + else { reset() } // eslint-disable-next-line react-hooks/exhaustive-deps }, [vehicles, currentPhase, path, isPlaying]); + + function animate(currentTime: number) { + if (previousTimeRef.current === null) { + previousTimeRef.current = currentTime; + } + + const deltaTime = (currentTime - previousTimeRef.current) / 1000; + previousTimeRef.current = currentTime; + + if (agvDetail.isActive) { + if (!isPausedRef.current) { + activeTimeRef.current += deltaTime * isSpeedRef.current; + } + } else { + if (!isPausedRef.current) { + idleTimeRef.current += deltaTime * isSpeedRef.current; // Scale idle time by speed + } + } + animationFrameIdRef.current = requestAnimationFrame(animate); + } + + useEffect(() => { + if (!isPlaying) return + if (!agvDetail.isActive) { + const roundedActiveTime = Math.round(activeTimeRef.current); + // console.log('Final Active Time:', roundedActiveTime, 'seconds'); + incrementActiveTime(agvDetail.modelUuid, roundedActiveTime); + activeTimeRef.current = 0; + } else { + const roundedIdleTime = Math.round(idleTimeRef.current); + // console.log('Final Idle Time:', roundedIdleTime, 'seconds'); + incrementIdleTime(agvDetail.modelUuid, roundedIdleTime); + idleTimeRef.current = 0; + } + + if (animationFrameIdRef.current === null) { + animationFrameIdRef.current = requestAnimationFrame(animate); + } + + return () => { + if (animationFrameIdRef.current !== null) { + cancelAnimationFrame(animationFrameIdRef.current); + animationFrameIdRef.current = null; + } + }; + }, [agvDetail]); + function handleCallBack() { if (currentPhase === 'stationed-pickup') { setCurrentPhase('picking'); @@ -147,9 +213,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) } } - - - function startUnloadingProcess() { if (agvDetail.point.action.triggers.length > 0) { const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid); @@ -213,7 +276,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) action: VehicleAction ) { startTime = performance.now(); - const fixedInterval = ((unLoadDuration / vehicleCurrentLoad) * (1000 / speed)); + const fixedInterval = ((unLoadDuration / vehicleCurrentLoad) * (1000 / isSpeedRef.current)); const unloadLoop = () => { if (isPausedRef.current) { @@ -295,7 +358,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) const elapsedTime = performance.now() - startTime; const unLoadDuration = agvDetail.point.action.unLoadDuration; - fixedInterval = ((unLoadDuration / agvDetail.currentLoad) * (1000 / speed)); + fixedInterval = ((unLoadDuration / agvDetail.currentLoad) * (1000 / isSpeedRef.current)); if (elapsedTime >= fixedInterval) { let droppedMat = droppedMaterial - 1; @@ -331,4 +394,10 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) ); } -export default VehicleInstance; \ No newline at end of file +export default VehicleInstance; + + + + + + diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index e69c233..13b4b0a 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -28,6 +28,7 @@ interface VehiclesStore { clearCurrentMaterials: (modelUuid: string) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementIdleTime: (modelUuid: string, incrementBy: number) => void; + resetTime: (modelUuid: string) => void; getVehicleById: (modelUuid: string) => VehicleStatus | undefined; getVehiclesByProduct: (productId: string) => VehicleStatus[]; @@ -206,6 +207,16 @@ export const useVehicleStore = create()( }); }, + resetTime: (modelUuid) => { + set((state) => { + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); + if (vehicle) { + vehicle.activeTime = 0; + vehicle.idleTime = 0; + } + }); + }, + getVehicleById: (modelUuid) => { return get().vehicles.find((v) => v.modelUuid === modelUuid); }, diff --git a/app/src/styles/components/marketPlace/marketPlace.scss b/app/src/styles/components/marketPlace/marketPlace.scss index b4237f2..fa667a4 100644 --- a/app/src/styles/components/marketPlace/marketPlace.scss +++ b/app/src/styles/components/marketPlace/marketPlace.scss @@ -312,6 +312,7 @@ width: 100%; height: 100%; background: var(--background-color); + backdrop-filter: blur(16px); display: flex; gap: 12px; overflow: hidden;