import React, { useCallback, useEffect, useState } from 'react'; import VehicleAnimator from '../animator/vehicleAnimator'; import * as THREE from 'three'; import { NavMeshQuery } from '@recast-navigation/core'; import { useNavMesh } from '../../../../../store/store'; import { usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; function VehicleInstance({ agvDetail }: any) { const { navMesh } = useNavMesh(); const { isPlaying, setIsPlaying } = usePlayButtonStore(); const { isReset } = useResetButtonStore(); const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); const computePath = useCallback( (start: any, end: any) => { try { const navMeshQuery = new NavMeshQuery(navMesh); const { path: segmentPath } = navMeshQuery.computePath(start, end); return ( segmentPath?.map(({ x, y, z }) => [x, y + 0.1, z] as [number, number, number]) || [] ); } catch { return []; } }, [navMesh] ); function vehicleStatus(modelid: string, status: string) { // console.log(`AGV ${modelid}: ${status}`); } function reset() { console.log("runs"); setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); setPath([]); setCurrentPhase('stationed') } useEffect(() => { if (isPlaying) { if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') { const toPickupPath = computePath( new THREE.Vector3(agvDetail.position[0], agvDetail.position[1], agvDetail.position[2]), agvDetail.point.action.pickUpPoint ); setPath(toPickupPath); setVehicleActive(agvDetail.modelUuid, true); setVehicleState(agvDetail.modelUuid, 'running'); setCurrentPhase('stationed-pickup'); vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup'); return; } else if ( !agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking' ) { setTimeout(() => { incrementVehicleLoad(agvDetail.modelUuid, 2); }, 5000); if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity) { const toDrop = computePath( agvDetail.point.action.pickUpPoint, agvDetail.point.action.unLoadPoint ); setPath(toDrop); setVehicleActive(agvDetail.modelUuid, true); setVehicleState(agvDetail.modelUuid, 'running'); setCurrentPhase('pickup-drop'); vehicleStatus(agvDetail.modelUuid, 'Started from pickup point, heading to drop point'); } } else if ( !agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'dropping' && agvDetail.currentLoad === 0 ) { const dropToPickup = computePath( agvDetail.point.action.unLoadPoint, agvDetail.point.action.pickUpPoint ); setPath(dropToPickup); setVehicleActive(agvDetail.modelUuid, true); setVehicleState(agvDetail.modelUuid, 'running'); setCurrentPhase('drop-pickup'); vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point'); } } }, [vehicles, currentPhase, path, isPlaying, isReset]); function handleCallBack() { if (currentPhase === 'stationed-pickup') { setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); setCurrentPhase('picking'); vehicleStatus(agvDetail.modelUuid, 'Reached pickup point, waiting for material'); setPath([]); } else if (currentPhase === 'pickup-drop') { setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); setCurrentPhase('dropping'); vehicleStatus(agvDetail.modelUuid, 'Reached drop point'); setPath([]); } else if (currentPhase === 'drop-pickup') { setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); setCurrentPhase('picking'); setPath([]); vehicleStatus(agvDetail.modelUuid, 'Reached pickup point again, cycle complete'); } } return ( <> ); } export default VehicleInstance;