From b701db74551f19c6d30b4ffd3c316ea7cd16c044 Mon Sep 17 00:00:00 2001 From: Poovizhi99 Date: Thu, 8 May 2025 10:47:21 +0530 Subject: [PATCH 1/8] added steering for vehicle --- .../simulation/ui/vehicle/vehicleUI.tsx | 544 +++++++++++------- .../instances/animator/vehicleAnimator.tsx | 38 +- .../modules/simulation/vehicle/vehicles.tsx | 29 +- 3 files changed, 395 insertions(+), 216 deletions(-) diff --git a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx index 2a124cd..12a4b3a 100644 --- a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx +++ b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx @@ -1,232 +1,380 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef, useState } from "react"; import * as Types from "../../../../types/world/worldTypes"; import startPoint from "../../../../assets/gltf-glb/arrow_green.glb"; -import * as THREE from "three"; import startEnd from "../../../../assets/gltf-glb/arrow_red.glb"; -import { useGLTF } from '@react-three/drei'; -import { useFrame, useThree } from '@react-three/fiber'; -import { useSelectedEventSphere, useIsDragging, useIsRotating } from '../../../../store/simulation/useSimulationStore'; -import { useVehicleStore } from '../../../../store/simulation/useVehicleStore'; -import { useProductStore } from '../../../../store/simulation/useProductStore'; -import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore'; -import { upsertProductOrEventApi } from '../../../../services/simulation/UpsertProductOrEventApi'; +import { useGLTF } from "@react-three/drei"; +import { useFrame, useThree } from "@react-three/fiber"; +import { + useSelectedEventSphere, + useIsDragging, + useIsRotating, +} from "../../../../store/simulation/useSimulationStore"; +import { useVehicleStore } from "../../../../store/simulation/useVehicleStore"; +import { useProductStore } from "../../../../store/simulation/useProductStore"; +import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; +import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi"; +import { Box3, DoubleSide, Euler, Group, Mesh, Plane, Quaternion, Vector3 } from "three"; +import { position } from "html2canvas/dist/types/css/property-descriptors/position"; const VehicleUI = () => { - const { scene: startScene } = useGLTF(startPoint) as any; - const { scene: endScene } = useGLTF(startEnd) as any; - const startMarker = useRef(null); - const endMarker = useRef(null); - const prevMousePos = useRef({ x: 0, y: 0 }); - const { selectedEventSphere } = useSelectedEventSphere(); - const { selectedProduct } = useSelectedProduct(); - const { getVehicleById } = useVehicleStore(); - const { updateEvent } = useProductStore(); - const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 0, 0]); - const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 0, 0]); - const [startRotation, setStartRotation] = useState<[number, number, number]>([0, 0, 0]); - const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]); - const { isDragging, setIsDragging } = useIsDragging(); - const { isRotating, setIsRotating } = useIsRotating(); - const { raycaster } = useThree(); - const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); - const state: Types.ThreeState = useThree(); - const controls: any = state.controls; + const { scene: startScene } = useGLTF(startPoint) as any; + const { scene: endScene } = useGLTF(startEnd) as any; + const startMarker = useRef(null); + const endMarker = useRef(null); + const prevMousePos = useRef({ x: 0, y: 0 }); + const { selectedEventSphere } = useSelectedEventSphere(); + const { selectedProduct } = useSelectedProduct(); + const { getVehicleById } = useVehicleStore(); + const { updateEvent } = useProductStore(); + const [startPosition, setStartPosition] = useState<[number, number, number]>([ + 0, 1, 0, + ]); - const email = localStorage.getItem('email') - const organization = (email!.split("@")[1]).split(".")[0]; - const updateBackend = ( - productName: string, - productId: string, - organization: string, - eventData: EventsSchema - ) => { - upsertProductOrEventApi({ - productName: productName, - productId: productId, - organization: organization, - eventDatas: eventData - }) - } + const [endPosition, setEndPosition] = useState<[number, number, number]>([ + 0, 1, 0, + ]); + const [startRotation, setStartRotation] = useState<[number, number, number]>([ + 0, 0, 0, + ]); - useEffect(() => { - if (!selectedEventSphere) return; - const selectedVehicle = getVehicleById(selectedEventSphere.userData.modelUuid); + const [endRotation, setEndRotation] = useState<[number, number, number]>([ + 0, 0, 0, + ]); + const [steeringRotation, setSteeringRotation] = useState< + [number, number, number] + >([0, 0, 0]); - if (selectedVehicle?.point?.action) { - const { pickUpPoint, unLoadPoint } = selectedVehicle.point.action; + const { isDragging, setIsDragging } = useIsDragging(); + const { isRotating, setIsRotating } = useIsRotating(); + const { raycaster } = useThree(); + const [point, setPoint] = useState< + [number, number, number] + >([0, 0, 0]); + const plane = useRef(new Plane(new Vector3(0, 1, 0), 0)); + const [tubeRotation, setTubeRotation] = useState(false); + const tubeRef = useRef(null); + const outerGroup = useRef(null); + const state: Types.ThreeState = useThree(); + const controls: any = state.controls; + const [selectedVehicleData, setSelectedVechicleData] = useState< + { position: [number, number, number], rotation: [number, number, number], } + >({ position: [0, 0, 0], rotation: [0, 0, 0], }); + const CIRCLE_RADIUS = 0.8; + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; - if (pickUpPoint) { - setStartPosition([pickUpPoint.position.x, 0, pickUpPoint.position.z]); - setStartRotation([pickUpPoint.rotation.x, pickUpPoint.rotation.y, pickUpPoint.rotation.z]); + const updateBackend = ( + productName: string, + productId: string, + organization: string, + eventData: EventsSchema + ) => { + upsertProductOrEventApi({ + productName: productName, + productId: productId, + organization: organization, + eventDatas: eventData, + }); + }; + + useEffect(() => { + if (!selectedEventSphere) return; + const selectedVehicle = getVehicleById( + selectedEventSphere.userData.modelUuid + ); + + if (selectedVehicle) { + + + setSelectedVechicleData({ position: selectedVehicle.position, rotation: selectedVehicle.rotation }); + setPoint(selectedVehicle.point.position) + } + + + setTimeout(() => { + if (selectedVehicle?.point?.action) { + const { pickUpPoint, unLoadPoint, steeringAngle } = selectedVehicle.point.action; + + if (pickUpPoint && outerGroup.current) { + const worldPos = new Vector3( + pickUpPoint.position.x, + pickUpPoint.position.y, + pickUpPoint.position.z + ); + const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); + + + setStartPosition([ + localPosition.x, + selectedVehicle.point.position[1], + localPosition.z, + ]); + setStartRotation([pickUpPoint.rotation.x, pickUpPoint.rotation.y, pickUpPoint.rotation.z,]) } else { - const defaultLocal = new THREE.Vector3(0, 0, 1.5); - const defaultWorld = selectedEventSphere.localToWorld(defaultLocal); - setStartPosition([defaultWorld.x, 0, defaultWorld.z]); - setStartRotation([0, 0, 0]); + setStartPosition([0, selectedVehicle.point.position[1] + 0.1, 1.5]); + setStartRotation([0, 0, 0]); } + // end point + if (unLoadPoint && outerGroup.current) { + const worldPos = new Vector3(unLoadPoint.position.x, unLoadPoint.position.y, unLoadPoint.position.z); + const localPosition = outerGroup.current.worldToLocal(worldPos); - if (unLoadPoint) { - setEndPosition([unLoadPoint.position.x, 0, unLoadPoint.position.z]); - setEndRotation([unLoadPoint.rotation.x, unLoadPoint.rotation.y, unLoadPoint.rotation.z]); + setEndPosition([localPosition.x, selectedVehicle.point.position[1], localPosition.z]); + setEndRotation([ + unLoadPoint.rotation.x, + unLoadPoint.rotation.y, + unLoadPoint.rotation.z, + ]); } else { - const defaultLocal = new THREE.Vector3(0, 0, -1.5); - const defaultWorld = selectedEventSphere.localToWorld(defaultLocal); - setEndPosition([defaultWorld.x, 0, defaultWorld.z]); - setEndRotation([0, 0, 0]); + setEndPosition([0, selectedVehicle.point.position[1] + 0.1, -1.5]); + setEndRotation([0, 0, 0]); } - } - }, [selectedEventSphere]); - - useFrame(() => { - if (!isDragging) return; - const intersectPoint = new THREE.Vector3(); - const intersects = raycaster.ray.intersectPlane(plane.current, intersectPoint); - - if (intersects) { - if (isDragging === "start") { - setStartPosition([intersectPoint.x, 0, intersectPoint.z]); - } - if (isDragging === "end") { - setEndPosition([intersectPoint.x, 0, intersectPoint.z]); - } - } - }); - - useFrame((state) => { - if (!isRotating) return; - - const currentPointerX = state.pointer.x; - const deltaX = currentPointerX - prevMousePos.current.x; - prevMousePos.current.x = currentPointerX; - - const marker = isRotating === "start" ? startMarker.current : endMarker.current; - - if (marker) { - const rotationSpeed = 10; - if (isRotating === 'start') { - const y = startRotation[1] + deltaX * rotationSpeed; - setStartRotation([0, y, 0]); - } else { - const y = endRotation[1] + deltaX * rotationSpeed; - setEndRotation([0, y, 0]); - } - } - }); + setSteeringRotation([0, steeringAngle, 0]) + } + }, 10); - const handlePointerDown = (e: any, state: "start" | "end", rotation: "start" | "end") => { + }, [selectedEventSphere, outerGroup.current]); - if (e.object.name === "handle") { - const normalizedX = (e.clientX / window.innerWidth) * 2 - 1; - const normalizedY = -(e.clientY / window.innerHeight) * 2 + 1; - prevMousePos.current = { x: normalizedX, y: normalizedY }; - setIsRotating(rotation); - if (controls) controls.enabled = false; - setIsDragging(null); + const handlePointerDown = ( + e: any, + state: "start" | "end", + rotation: "start" | "end" + ) => { + if (e.object.name === "handle") { + const normalizedX = (e.clientX / window.innerWidth) * 2 - 1; + const normalizedY = -(e.clientY / window.innerHeight) * 2 + 1; + prevMousePos.current = { x: normalizedX, y: normalizedY }; + setIsRotating(rotation); + if (controls) controls.enabled = false; + setIsDragging(null); + } else { + setIsDragging(state); + setIsRotating(null); + if (controls) controls.enabled = false; + } + }; - } else { - setIsDragging(state); - setIsRotating(null); - if (controls) controls.enabled = false; - } - }; + const handlePointerUp = () => { + controls.enabled = true; + setIsDragging(null); + setIsRotating(null); - const handlePointerUp = () => { - controls.enabled = true; - setIsDragging(null); - setIsRotating(null); + if (selectedEventSphere?.userData.modelUuid) { + const updatedVehicle = getVehicleById( + selectedEventSphere.userData.modelUuid + ); - if (selectedEventSphere?.userData.modelUuid) { - const updatedVehicle = getVehicleById(selectedEventSphere.userData.modelUuid); + let globalStartPosition = null; + let globalEndPosition = null; - if (updatedVehicle) { - const event = updateEvent(selectedProduct.productId, selectedEventSphere.userData.modelUuid, { - point: { - ...updatedVehicle.point, - action: { - ...updatedVehicle.point?.action, - pickUpPoint: { - position: { x: startPosition[0], y: startPosition[1], z: startPosition[2], }, - rotation: { x: 0, y: startRotation[1], z: 0, }, - }, - unLoadPoint: { - position: { x: endPosition[0], y: endPosition[1], z: endPosition[2], }, - rotation: { x: 0, y: endRotation[1], z: 0, }, - }, + if (outerGroup.current && startMarker.current && endMarker.current) { + const worldPosStart = new Vector3(...startPosition); + globalStartPosition = outerGroup.current.localToWorld(worldPosStart.clone()); + const worldPosEnd = new Vector3(...endPosition); + globalEndPosition = outerGroup.current.localToWorld(worldPosEnd.clone()); + } + if (updatedVehicle && globalEndPosition && globalStartPosition) { + const event = updateEvent( + selectedProduct.productId, + selectedEventSphere.userData.modelUuid, + { + point: { + ...updatedVehicle.point, + action: { + ...updatedVehicle.point?.action, + pickUpPoint: { + position: { + x: globalStartPosition.x, + y: 0, + z: globalStartPosition.z, + }, + rotation: { x: 0, y: startRotation[1], z: 0 }, }, - }, - }) + unLoadPoint: { + position: { + x: globalEndPosition.x, + y: 0, + z: globalEndPosition.z, + }, + rotation: { x: 0, y: endRotation[1], z: 0 }, + }, + steeringAngle: steeringRotation[1] + }, + }, + } + ); - if (event) { - updateBackend( - selectedProduct.productName, - selectedProduct.productId, - organization, - event - ); - } + if (event) { + updateBackend( + selectedProduct.productName, + selectedProduct.productId, + organization, + event + ); } - } - }; + } + } + }; - useEffect(() => { - const handleGlobalPointerUp = () => { - setIsDragging(null); - setIsRotating(null); - if (controls) controls.enabled = true; - handlePointerUp(); - }; + useFrame(() => { + if (!isDragging || !plane.current || !raycaster || !outerGroup.current) return; + const intersectPoint = new Vector3(); + const intersects = raycaster.ray.intersectPlane(plane.current, intersectPoint); + if (!intersects) return; + const localPoint = outerGroup?.current.worldToLocal(intersectPoint.clone()); + if (isDragging === "start") { + if (startMarker.current) { - if (isDragging || isRotating) { - window.addEventListener("pointerup", handleGlobalPointerUp); - } + } + setStartPosition([localPoint.x, point[1], localPoint.z]); + } else if (isDragging === "end") { + setEndPosition([localPoint.x, point[1], localPoint.z]); + } + }); - return () => { - window.removeEventListener("pointerup", handleGlobalPointerUp); - }; - }, [isDragging, isRotating, startPosition, startRotation, endPosition, endRotation]); + useEffect(() => { + const handleGlobalPointerUp = () => { + setIsDragging(null); + setIsRotating(null); + setTubeRotation(false); + if (controls) controls.enabled = true; + handlePointerUp(); - return ( - startPosition.length > 0 && endPosition.length > 0 ? ( - - { - e.stopPropagation(); - handlePointerDown(e, "start", "start"); - }} - onPointerMissed={() => { - controls.enabled = true; - setIsDragging(null); - setIsRotating(null); - }} - /> + }; + + if (isDragging || isRotating || tubeRotation) { + window.addEventListener("pointerup", handleGlobalPointerUp); + } + + return () => { + window.removeEventListener("pointerup", handleGlobalPointerUp); + }; + }, [ + isDragging, isRotating, startPosition, startRotation, endPosition, endRotation, tubeRotation, steeringRotation, outerGroup.current, tubeRef.current + ]); + + + const prevSteeringY = useRef(0); + useFrame((state) => { + if (tubeRotation) { + const currentPointerX = state.pointer.x; + const deltaX = currentPointerX - prevMousePos.current.x; + prevMousePos.current.x = currentPointerX; + + const marker = tubeRef.current; + if (marker) { + const rotationSpeed = 2; + marker.rotation.y += deltaX * rotationSpeed; + setSteeringRotation([marker.rotation.x, marker.rotation.y, marker.rotation.z]); + } + } else { + prevSteeringY.current = 0; + } + }); + useFrame((state) => { + if (!isRotating) return; + const currentPointerX = state.pointer.x; + const deltaX = currentPointerX - prevMousePos.current.x; + prevMousePos.current.x = currentPointerX; + const marker = + isRotating === "start" ? startMarker.current : endMarker.current; + if (marker) { + const rotationSpeed = 10; + marker.rotation.y += deltaX * rotationSpeed; + if (isRotating === "start") { + setStartRotation([ + marker.rotation.x, + marker.rotation.y, + marker.rotation.z, + ]); + } else { + setEndRotation([ + marker.rotation.x, + marker.rotation.y, + marker.rotation.z, + ]); + } + } + }); + + return selectedVehicleData ? ( + + { + e.stopPropagation(); + setTubeRotation(true); + prevMousePos.current.x = e.pointer.x; + controls.enabled = false; + }} + onPointerMissed={() => { + controls.enabled = true; + setTubeRotation(false); + }} + onPointerUp={() => { + controls.enabled = true; + setTubeRotation(false); + }} + > + ( + + + - { - e.stopPropagation(); - handlePointerDown(e, "end", "end"); - }} - onPointerMissed={() => { - controls.enabled = true; - setIsDragging(null); - setIsRotating(null); - }} - /> - ) : null - ); -} + + + + + ) + + + {/* Start Marker */} + { + e.stopPropagation(); + handlePointerDown(e, "start", "start"); + }} + onPointerMissed={() => { + controls.enabled = true; + setIsDragging(null); + setIsRotating(null); + }} + /> + + {/* End Marker */} + { + e.stopPropagation(); + handlePointerDown(e, "end", "end"); + }} + onPointerMissed={() => { + controls.enabled = true; + setIsDragging(null); + setIsRotating(null); + }} + /> + + ) : null; +}; export default VehicleUI; diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index 460997a..62f230e 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -33,6 +33,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai let fixedInterval: number; let coveredDistance = progressRef.current; let objectRotation = (agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) as { x: number; y: number; z: number } | undefined; + const [rotatingToSteering, setRotatingToSteering] = useState(false); useEffect(() => { if (currentPhase === 'stationed-pickup' && path.length > 0) { @@ -133,18 +134,39 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai } if (progressRef.current >= totalDistance) { - if (restRotation && objectRotation) { - const targetQuaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(objectRotation.x, objectRotation.y, objectRotation.z)); - object.quaternion.slerp(targetQuaternion, delta * 2); - const angleDiff = object.quaternion.angleTo(targetQuaternion); - if (angleDiff < 0.01) { - object.rotation.set(objectRotation.x, objectRotation.y, objectRotation.z); + const restQuaternion = objectRotation ? + new THREE.Quaternion().setFromEuler(new THREE.Euler(objectRotation.x, objectRotation.y, objectRotation.z)) : + object.quaternion.clone(); + + const steeringQuaternion = new THREE.Quaternion().setFromEuler( + new THREE.Euler(objectRotation ? objectRotation.x : object.rotation.x, + agvDetail.point.action.steeringAngle, + objectRotation ? objectRotation.z : object.rotation.z) + ); + + if (restRotation) { + object.quaternion.slerp(restQuaternion, delta * 2); + const restAngleDiff = object.quaternion.angleTo(restQuaternion); + if (restAngleDiff < 0.01) { setRestingRotation(false); + setRotatingToSteering(true); + } + return; + } + else if (rotatingToSteering) { + object.quaternion.slerp(steeringQuaternion, delta * 2); + const steeringAngleDiff = object.quaternion.angleTo(steeringQuaternion); + if (steeringAngleDiff < 0.01) { + object.rotation.set( + objectRotation ? objectRotation.x : object.rotation.x, + agvDetail.point.action.steeringAngle, + objectRotation ? objectRotation.z : object.rotation.z + ); + setRotatingToSteering(false); } return; } } - if (progressRef.current >= totalDistance) { setRestingRotation(true); progressRef.current = 0; @@ -199,7 +221,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai return ( <> {currentPath.length > 0 && ( - + {currentPath.map((point, index) => ( diff --git a/app/src/modules/simulation/vehicle/vehicles.tsx b/app/src/modules/simulation/vehicle/vehicles.tsx index 68f40cf..93a275d 100644 --- a/app/src/modules/simulation/vehicle/vehicles.tsx +++ b/app/src/modules/simulation/vehicle/vehicles.tsx @@ -1,31 +1,40 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import VehicleInstances from "./instances/vehicleInstances"; import { useVehicleStore } from "../../../store/simulation/useVehicleStore"; -import { useSelectedEventData, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore"; +import { useSelectedEventSphere } from "../../../store/simulation/useSimulationStore"; import VehicleUI from "../ui/vehicle/vehicleUI"; import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; function Vehicles() { - const { vehicles } = useVehicleStore(); + const { vehicles, getVehicleById } = useVehicleStore(); const { selectedEventSphere } = useSelectedEventSphere(); - const { selectedEventData } = useSelectedEventData(); const { isPlaying } = usePlayButtonStore(); + const [isVehicleSelected, setIsVehicleSelected] = useState(false); + useEffect(() => { // console.log('vehicles: ', vehicles); }, [vehicles]) + useEffect(() => { + if (selectedEventSphere) { + const selectedVehicle = getVehicleById(selectedEventSphere.userData.modelUuid); + if (selectedVehicle) { + setIsVehicleSelected(true); + } else { + setIsVehicleSelected(false); + } + } + }, [selectedEventSphere]) + return ( <> - - - {selectedEventSphere && selectedEventData?.data.type === "vehicle" && !isPlaying && - < VehicleUI /> + {isVehicleSelected && selectedEventSphere && !isPlaying && + } - ); } -export default Vehicles; \ No newline at end of file +export default Vehicles; From d329fe3eef7a609a02482ded370536d9852379be Mon Sep 17 00:00:00 2001 From: Poovizhi99 Date: Thu, 8 May 2025 13:42:05 +0530 Subject: [PATCH 2/8] corrected steering rotation for vehicle --- .../simulation/ui/vehicle/vehicleUI.tsx | 12 +---- .../instances/animator/vehicleAnimator.tsx | 52 ++++++------------- 2 files changed, 19 insertions(+), 45 deletions(-) diff --git a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx index 12a4b3a..33ab372 100644 --- a/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx +++ b/app/src/modules/simulation/ui/vehicle/vehicleUI.tsx @@ -85,8 +85,6 @@ const VehicleUI = () => { ); if (selectedVehicle) { - - setSelectedVechicleData({ position: selectedVehicle.position, rotation: selectedVehicle.rotation }); setPoint(selectedVehicle.point.position) } @@ -105,10 +103,7 @@ const VehicleUI = () => { const localPosition = outerGroup.current.worldToLocal(worldPos.clone()); - setStartPosition([ - localPosition.x, - selectedVehicle.point.position[1], - localPosition.z, + setStartPosition([localPosition.x, selectedVehicle.point.position[1], localPosition.z, ]); setStartRotation([pickUpPoint.rotation.x, pickUpPoint.rotation.y, pickUpPoint.rotation.z,]) } else { @@ -121,10 +116,7 @@ const VehicleUI = () => { const localPosition = outerGroup.current.worldToLocal(worldPos); setEndPosition([localPosition.x, selectedVehicle.point.position[1], localPosition.z]); - setEndRotation([ - unLoadPoint.rotation.x, - unLoadPoint.rotation.y, - unLoadPoint.rotation.z, + setEndRotation([unLoadPoint.rotation.x, unLoadPoint.rotation.y, unLoadPoint.rotation.z, ]); } else { setEndPosition([0, selectedVehicle.point.position[1] + 0.1, -1.5]); diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index 696606a..61843d1 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -25,6 +25,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai const completedRef = useRef(false); const isPausedRef = useRef(false); const pauseTimeRef = useRef(null); + const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) const [progress, setProgress] = useState(0); const [restRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); @@ -32,21 +33,19 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai let startTime: number; let fixedInterval: number; let coveredDistance = progressRef.current; - let objectRotation = (agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) as { x: number; y: number; z: number } | undefined; - const [rotatingToSteering, setRotatingToSteering] = useState(false); useEffect(() => { if (currentPhase === 'stationed-pickup' && path.length > 0) { setCurrentPath(path); - objectRotation = agvDetail.point.action?.pickUpPoint?.rotation + setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation) } else if (currentPhase === 'pickup-drop' && path.length > 0) { - objectRotation = agvDetail.point.action?.unLoadPoint?.rotation + setObjectRotation(agvDetail.point.action?.unLoadPoint?.rotation) setCurrentPath(path); } else if (currentPhase === 'drop-pickup' && path.length > 0) { - objectRotation = agvDetail.point.action?.pickUpPoint?.rotation + setObjectRotation(agvDetail.point.action?.pickUpPoint?.rotation) setCurrentPath(path); } - }, [currentPhase, path]); + }, [currentPhase, path, objectRotation]); useEffect(() => { setProgress(0); @@ -125,43 +124,26 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai if (isAligned) { progressRef.current += delta * (speed * agvDetail.speed); coveredDistance = progressRef.current; - const t = (coveredDistance - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); } } + if (progressRef.current >= totalDistance) { - const restQuaternion = objectRotation ? - new THREE.Quaternion().setFromEuler(new THREE.Euler(objectRotation.x, objectRotation.y, objectRotation.z)) : - object.quaternion.clone(); - - const steeringQuaternion = new THREE.Quaternion().setFromEuler( - new THREE.Euler(objectRotation ? objectRotation.x : object.rotation.x, - agvDetail.point.action.steeringAngle, - objectRotation ? objectRotation.z : object.rotation.z) - ); - - if (restRotation) { - object.quaternion.slerp(restQuaternion, delta * 2); - const restAngleDiff = object.quaternion.angleTo(restQuaternion); - if (restAngleDiff < 0.01) { + if (restRotation && objectRotation) { + const targetEuler = new THREE.Euler( + objectRotation.x, + objectRotation.y - (agvDetail.point.action.steeringAngle), + objectRotation.z + ); + const targetQuaternion = new THREE.Quaternion().setFromEuler(targetEuler); + object.quaternion.slerp(targetQuaternion, delta * 2); + if (object.quaternion.angleTo(targetQuaternion) < 0.01) { + object.quaternion.copy(targetQuaternion); + object.rotation.copy(targetEuler); setRestingRotation(false); - setRotatingToSteering(true); - } - return; - } - else if (rotatingToSteering) { - object.quaternion.slerp(steeringQuaternion, delta * 2); - const steeringAngleDiff = object.quaternion.angleTo(steeringQuaternion); - if (steeringAngleDiff < 0.01) { - object.rotation.set( - objectRotation ? objectRotation.x : object.rotation.x, - agvDetail.point.action.steeringAngle, - objectRotation ? objectRotation.z : object.rotation.z - ); - setRotatingToSteering(false); } return; } From 19e23501a47ccb7b4c3480e754aca7f3de823830 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 8 May 2025 13:43:37 +0530 Subject: [PATCH 3/8] Implement action handlers for conveyor, robotic arm, and vehicle, including logging and material management --- .../actionHandler/useDefaultHandler.ts | 24 ++++++ .../actionHandler/useDespawnHandler.ts | 4 +- .../actions/conveyor/useConveyorActions.ts | 7 +- .../actionHandler/usePickAndPlaceHandler.ts | 41 +++++++++ .../roboticArm/useRoboticArmActions.ts | 16 ++-- .../simulation/actions/useActionHandler.ts | 4 +- .../vehicle/actionHandler/useTravelHandler.ts | 32 +++++++ .../actions/vehicle/useVehicleActions.ts | 15 ++-- .../triggers/connector/triggerConnector.tsx | 2 +- .../triggerHandler/useTriggerHandler.ts | 86 +++++++++++++++---- .../instances/instance/vehicleInstance.tsx | 11 +-- app/src/store/simulation/useVehicleStore.ts | 10 +++ 12 files changed, 207 insertions(+), 45 deletions(-) create mode 100644 app/src/modules/simulation/actions/roboticArm/actionHandler/usePickAndPlaceHandler.ts create mode 100644 app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts diff --git a/app/src/modules/simulation/actions/conveyor/actionHandler/useDefaultHandler.ts b/app/src/modules/simulation/actions/conveyor/actionHandler/useDefaultHandler.ts index e69de29..ab0a284 100644 --- a/app/src/modules/simulation/actions/conveyor/actionHandler/useDefaultHandler.ts +++ b/app/src/modules/simulation/actions/conveyor/actionHandler/useDefaultHandler.ts @@ -0,0 +1,24 @@ +import { useCallback } from "react"; +import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; + +export function useDefaultHandler() { + const { getMaterialById } = useMaterialStore(); + + const defaultLogStatus = (materialUuid: string, status: string) => { + // console.log(`${materialUuid}, ${status}`); + } + + const handleDefault = useCallback((action: ConveyorAction, materialId?: string) => { + if (!action || action.actionType !== 'default' || !materialId) return; + + const material = getMaterialById(materialId); + if (!material) return; + + defaultLogStatus(material.materialId, `performed Default action`); + + }, [getMaterialById]); + + return { + handleDefault, + }; +} \ No newline at end of file diff --git a/app/src/modules/simulation/actions/conveyor/actionHandler/useDespawnHandler.ts b/app/src/modules/simulation/actions/conveyor/actionHandler/useDespawnHandler.ts index 464629c..d72419a 100644 --- a/app/src/modules/simulation/actions/conveyor/actionHandler/useDespawnHandler.ts +++ b/app/src/modules/simulation/actions/conveyor/actionHandler/useDespawnHandler.ts @@ -2,7 +2,7 @@ import { useCallback } from "react"; import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; export function useDespawnHandler() { - const { addMaterial, getMaterialById, removeMaterial } = useMaterialStore(); + const { getMaterialById, removeMaterial } = useMaterialStore(); const deSpawnLogStatus = (materialUuid: string, status: string) => { // console.log(`${materialUuid}, ${status}`); @@ -18,7 +18,7 @@ export function useDespawnHandler() { deSpawnLogStatus(material.materialId, `Despawned`); - }, [addMaterial, getMaterialById, removeMaterial]); + }, [getMaterialById, removeMaterial]); return { handleDespawn, diff --git a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts index 43e3dc1..1772444 100644 --- a/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts +++ b/app/src/modules/simulation/actions/conveyor/useConveyorActions.ts @@ -1,17 +1,20 @@ import { useEffect, useCallback } from "react"; +import { useDefaultHandler } from "./actionHandler/useDefaultHandler"; import { useSpawnHandler } from "./actionHandler/useSpawnHandler"; import { useSwapHandler } from "./actionHandler/useSwapHandler"; import { useDelayHandler } from "./actionHandler/useDelayHandler"; import { useDespawnHandler } from "./actionHandler/useDespawnHandler"; export function useConveyorActions() { + const { handleDefault } = useDefaultHandler(); const { handleSpawn, clearCurrentSpawn } = useSpawnHandler(); const { handleSwap } = useSwapHandler(); const { handleDespawn } = useDespawnHandler(); const { handleDelay, cleanupDelay } = useDelayHandler(); - const handleDefaultAction = useCallback((action: ConveyorAction) => { - }, []); + const handleDefaultAction = useCallback((action: ConveyorAction, materialId?: string) => { + handleDefault(action, materialId); + }, [handleDefault]); const handleSpawnAction = useCallback((action: ConveyorAction) => { handleSpawn(action); diff --git a/app/src/modules/simulation/actions/roboticArm/actionHandler/usePickAndPlaceHandler.ts b/app/src/modules/simulation/actions/roboticArm/actionHandler/usePickAndPlaceHandler.ts new file mode 100644 index 0000000..2f44cfe --- /dev/null +++ b/app/src/modules/simulation/actions/roboticArm/actionHandler/usePickAndPlaceHandler.ts @@ -0,0 +1,41 @@ +import { useCallback } from "react"; +import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; +import { useArmBotStore } from "../../../../../store/simulation/useArmBotStore"; +import { useProductStore } from "../../../../../store/simulation/useProductStore"; +import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore"; + +export function usePickAndPlaceHandler() { + const { getMaterialById } = useMaterialStore(); + const { addCurrentAction } = useArmBotStore(); + const { getModelUuidByActionUuid } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); + + const pickAndPlaceLogStatus = (materialUuid: string, status: string) => { + // console.log(`${materialUuid}, ${status}`); + } + + const handlePickAndPlace = useCallback((action: RoboticArmAction, materialId?: string) => { + if (!action || action.actionType !== 'pickAndPlace' || !materialId) return; + + const material = getMaterialById(materialId); + if (!material) return; + + const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid); + + if (!modelUuid) return; + + addCurrentAction( + modelUuid, + action.actionUuid, + material.materialType, + material.materialId + ); + + pickAndPlaceLogStatus(material.materialId, `if going to be picked by armBot ${modelUuid}`); + + }, [getMaterialById, getModelUuidByActionUuid, addCurrentAction]); + + return { + handlePickAndPlace, + }; +} \ No newline at end of file diff --git a/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts b/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts index 37990db..90251d2 100644 --- a/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts +++ b/app/src/modules/simulation/actions/roboticArm/useRoboticArmActions.ts @@ -1,20 +1,24 @@ import { useEffect, useCallback } from 'react'; +import { usePickAndPlaceHandler } from './actionHandler/usePickAndPlaceHandler'; export function useRoboticArmActions() { + const { handlePickAndPlace } = usePickAndPlaceHandler(); - const handlePickAndPlace = useCallback((action: RoboticArmAction) => { - console.log(`Robotic arm pick and place`); - }, []); + const handlePickAndPlaceAction = useCallback((action: RoboticArmAction, materialId: string) => { + handlePickAndPlace(action, materialId); + }, [handlePickAndPlace]); + + const handleRoboticArmAction = useCallback((action: RoboticArmAction, materialId: string) => { + if (!action) return; - const handleRoboticArmAction = useCallback((action: RoboticArmAction) => { switch (action.actionType) { case 'pickAndPlace': - handlePickAndPlace(action); + handlePickAndPlaceAction(action, materialId); break; default: console.warn(`Unknown robotic arm action type: ${action.actionType}`); } - }, [handlePickAndPlace]); + }, [handlePickAndPlaceAction]); const cleanup = useCallback(() => { }, []); diff --git a/app/src/modules/simulation/actions/useActionHandler.ts b/app/src/modules/simulation/actions/useActionHandler.ts index 91a3c84..812ff5e 100644 --- a/app/src/modules/simulation/actions/useActionHandler.ts +++ b/app/src/modules/simulation/actions/useActionHandler.ts @@ -24,10 +24,10 @@ export function useActionHandler() { handleConveyorAction(action as ConveyorAction, materialId as string); break; case 'travel': - handleVehicleAction(action as VehicleAction); + handleVehicleAction(action as VehicleAction, materialId as string); break; case 'pickAndPlace': - handleRoboticArmAction(action as RoboticArmAction); + handleRoboticArmAction(action as RoboticArmAction, materialId as string); break; case 'process': handleMachineAction(action as MachineAction); diff --git a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts new file mode 100644 index 0000000..9b34a7d --- /dev/null +++ b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts @@ -0,0 +1,32 @@ +import { useCallback } from "react"; +import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; +import { useProductStore } from "../../../../../store/simulation/useProductStore"; +import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore"; + +export function useTravelHandler() { + const { getMaterialById } = useMaterialStore(); + const { getModelUuidByActionUuid } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); + + const travelLogStatus = (materialUuid: string, status: string) => { + console.log(`${materialUuid}, ${status}`); + } + + const handleTravel = useCallback((action: VehicleAction, materialId?: string) => { + if (!action || action.actionType !== 'travel' || !materialId) return; + + const material = getMaterialById(materialId); + if (!material) return; + + const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid); + + if (!modelUuid) return; + + travelLogStatus(material.materialId, `is triggering travel from ${modelUuid}`); + + }, [getMaterialById, getModelUuidByActionUuid]); + + return { + handleTravel, + }; +} \ No newline at end of file diff --git a/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts b/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts index 313fb5d..a54672b 100644 --- a/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts +++ b/app/src/modules/simulation/actions/vehicle/useVehicleActions.ts @@ -1,20 +1,19 @@ import { useEffect, useCallback } from 'react'; +import { useTravelHandler } from './actionHandler/useTravelHandler'; export function useVehicleActions() { + const { handleTravel } = useTravelHandler(); - const handleTravelAction = useCallback((action: VehicleAction) => { - if (!action || action.actionType !== 'travel') return; + const handleTravelAction = useCallback((action: VehicleAction, materialId: string) => { + handleTravel(action, materialId); + }, [handleTravel]); - console.log(`Vehicle travel action ${action.actionUuid}`); - - }, []); - - const handleVehicleAction = useCallback((action: VehicleAction) => { + const handleVehicleAction = useCallback((action: VehicleAction, materialId: string) => { if (!action) return; switch (action.actionType) { case 'travel': - handleTravelAction(action); + handleTravelAction(action, materialId); break; default: console.warn(`Unknown vehicle action type: ${action.actionType}`); diff --git a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx index 6afcc69..a56436f 100644 --- a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx +++ b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx @@ -50,7 +50,7 @@ function TriggerConnector() { organization: string, eventData: EventsSchema ) => { - upsertProductOrEventApi({ + const data =upsertProductOrEventApi({ productName: productName, productId: productId, organization: organization, diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts index c33e2ec..eb86062 100644 --- a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -4,12 +4,14 @@ import { useProductStore } from '../../../../store/simulation/useProductStore'; import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore'; import { useMaterialStore } from '../../../../store/simulation/useMaterialStore'; import { useArmBotStore } from '../../../../store/simulation/useArmBotStore'; +import { useVehicleStore } from '../../../../store/simulation/useVehicleStore'; export function useTriggerHandler() { const { handleAction } = useActionHandler(); const { selectedProduct } = useSelectedProduct(); const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore(); - const { addCurrentAction, getArmBotById } = useArmBotStore(); + const { getArmBotById } = useArmBotStore(); + const { getVehicleById } = useVehicleStore(); const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setEndTime } = useMaterialStore(); const handleTrigger = (trigger: TriggerSchema, action: Action, materialId: string) => { @@ -42,6 +44,44 @@ export function useTriggerHandler() { } } else if (toEvent?.type === 'vehicle') { // Transfer to Vehicle + if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + const material = getMaterialById(materialId); + if (material) { + + // Handle current action of the material + handleAction(action, materialId); + + if (material.next) { + const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid); + const vehicle = getVehicleById(trigger.triggeredAsset?.triggeredModel.modelUuid); + + setCurrentLocation(material.materialId, { + modelUuid: material.next.modelUuid, + pointUuid: material.next.pointUuid, + actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, + }); + + setNextLocation(material.materialId, null); + + if (action) { + + if (vehicle) { + + if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.currentLoad < vehicle.point.action.loadCapacity) { + + // Handle current action from vehicle + handleAction(action, materialId) + + } else { + + // Event Manager Needed + + } + } + } + } + } + } } else if (toEvent?.type === 'machine') { // Transfer to Machine @@ -51,33 +91,41 @@ export function useTriggerHandler() { if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { const material = getMaterialById(materialId); if (material) { + + // Handle current action of the material + handleAction(action, materialId); + if (material.next) { + const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid); const armBot = getArmBotById(trigger.triggeredAsset?.triggeredModel.modelUuid); - if (armBot) { - if (armBot.isActive === false && armBot.state === 'idle') { - setCurrentLocation(material.materialId, { - modelUuid: material.next.modelUuid, - pointUuid: material.next.pointUuid, - actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, - }); - setNextLocation(material.materialId, null); + setCurrentLocation(material.materialId, { + modelUuid: material.next.modelUuid, + pointUuid: material.next.pointUuid, + actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, + }); - setIsPaused(material.materialId, true); - addCurrentAction( - trigger.triggeredAsset?.triggeredModel.modelUuid, - trigger.triggeredAsset?.triggeredAction?.actionUuid, - material.materialType, - material.materialId - ); - } else { + setNextLocation(material.materialId, null); - // Event Manager Needed + if (action) { + if (armBot) { + + if (armBot.isActive === false && armBot.state === 'idle') { + + setIsPaused(material.materialId, true); + + // Handle current action from arm bot + handleAction(action, materialId) + + } else { + + // Event Manager Needed + + } } } } - handleAction(action, materialId); } } } else if (toEvent?.type === 'storageUnit') { diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 2eb9e6e..8d70dd6 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -11,7 +11,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); const vehicleRef: any = useRef(); const { isPlaying } = usePlayButtonStore(); - const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setMaterialType } = useVehicleStore(); + const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setVehicleLoad, setMaterialType } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); let isIncrememtable = useRef(true); @@ -41,6 +41,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { setCurrentPhase('stationed'); setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); + setVehicleLoad(agvDetail.modelUuid, 0); setPath([]); } @@ -54,6 +55,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { useEffect(() => { if (isPlaying) { + if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return; if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') { const toPickupPath = computePath( @@ -68,10 +70,9 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { return; } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') { - setTimeout(() => { - increment(); - }, 5000); - + // setTimeout(() => { + // increment(); + // }, 5000); if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index 63ca0d0..15f7d5d 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -17,6 +17,7 @@ interface VehiclesStore { updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void; incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void; decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void; + setVehicleLoad: (modelUuid: string, load: number) => void; setVehicleState: (modelUuid: string, newState: VehicleStatus['state']) => void; setMaterialType: (modelUuid: string, materialType: string | null) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void; @@ -107,6 +108,15 @@ export const useVehicleStore = create()( }); }, + setVehicleLoad: (modelUuid, load) => { + set((state) => { + const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); + if (vehicle) { + vehicle.currentLoad = load; + } + }); + }, + setVehicleState: (modelUuid, newState) => { set((state) => { const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); From 7cc0a83075fc8c9fa770c753ea41abc2e66dfd79 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 8 May 2025 14:00:36 +0530 Subject: [PATCH 4/8] Refactor vehicle material handling: update MaterialAnimator and VehicleInstance to use currentMaterials array, and modify useVehicleStore for material management --- .../instances/animator/materialAnimator.tsx | 2 +- .../instances/instance/vehicleInstance.tsx | 9 +++--- app/src/store/simulation/useVehicleStore.ts | 28 ++++++++++++++++--- app/src/types/simulationTypes.d.ts | 2 +- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx index 4b9eb1c..e741bba 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx @@ -40,7 +40,7 @@ const MaterialAnimator = ({ agvDetail }: MaterialAnimatorProps) => { <> ('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); let isIncrememtable = useRef(true); @@ -48,7 +47,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const increment = () => { if (isIncrememtable.current) { incrementVehicleLoad(agvDetail.modelUuid, 10); - setMaterialType(agvDetail.modelUuid, 'Material 1') + addCurrentMaterial(agvDetail.modelUuid, 'Material 1', '123'); isIncrememtable.current = false; } } @@ -74,7 +73,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { // increment(); // }, 5000); - if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) { + if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.currentMaterials.length > 0) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { const toDrop = computePath( agvDetail.point.action.pickUpPoint.position, @@ -125,7 +124,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleActive(agvDetail.modelUuid, false); setPath([]); - setMaterialType(agvDetail.modelUuid, null) + clearCurrentMaterials(agvDetail.modelUuid) vehicleStatus(agvDetail.modelUuid, 'Reached pickup point again, cycle complete'); } } diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index 455457a..83a6bbc 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -21,7 +21,9 @@ interface VehiclesStore { modelUuid: string, newState: VehicleStatus["state"] ) => void; - setMaterialType: (modelUuid: string, materialType: string | null) => void; + addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void; + setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void; + clearCurrentMaterials: (modelUuid: string) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementIdleTime: (modelUuid: string, incrementBy: number) => void; @@ -48,7 +50,7 @@ export const useVehicleStore = create()( idleTime: 0, activeTime: 0, currentLoad: 0, - materialType: null, + currentMaterials: [], distanceTraveled: 0, }); } @@ -132,11 +134,29 @@ export const useVehicleStore = create()( }); }, - setMaterialType: (modelUuid, materialType) => { + addCurrentMaterial: (modelUuid, materialType, materialId) => { set((state) => { const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); if (vehicle) { - vehicle.materialType = materialType; + vehicle.currentMaterials.push({ materialType, materialId }); + } + }); + }, + + setCurrentMaterials: (modelUuid, materials) => { + set((state) => { + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); + if (vehicle) { + vehicle.currentMaterials = materials; + } + }); + }, + + clearCurrentMaterials: (modelUuid) => { + set((state) => { + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); + if (vehicle) { + vehicle.currentMaterials = []; } }); }, diff --git a/app/src/types/simulationTypes.d.ts b/app/src/types/simulationTypes.d.ts index 04b742d..8a9f01d 100644 --- a/app/src/types/simulationTypes.d.ts +++ b/app/src/types/simulationTypes.d.ts @@ -181,7 +181,7 @@ interface VehicleStatus extends VehicleEventSchema { idleTime: number; activeTime: number; currentLoad: number; - materialType: string | null; + currentMaterials: { materialType: string; materialId: string; }[]; distanceTraveled: number; } From 7000a5942ffe6ba9cd12c42b64a01c51b4ae1e90 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 8 May 2025 14:38:38 +0530 Subject: [PATCH 5/8] Enhance vehicle material management: add removeLastMaterial function to useVehicleStore, update useTravelHandler and VehicleAnimator for improved material handling, and refine MaterialAnimator rendering logic. --- .../vehicle/actionHandler/useTravelHandler.ts | 8 +++++++- .../triggerHandler/useTriggerHandler.ts | 8 +++++--- .../instances/animator/materialAnimator.tsx | 10 ++++++---- .../instances/animator/vehicleAnimator.tsx | 8 +++++++- .../instances/instance/vehicleInstance.tsx | 13 +------------ app/src/modules/simulation/vehicle/vehicles.tsx | 3 +++ app/src/store/simulation/useVehicleStore.ts | 17 +++++++++++++++++ 7 files changed, 46 insertions(+), 21 deletions(-) diff --git a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts index 9b34a7d..90019f0 100644 --- a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts +++ b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts @@ -2,14 +2,16 @@ import { useCallback } from "react"; import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore"; +import { useVehicleStore } from "../../../../../store/simulation/useVehicleStore"; export function useTravelHandler() { const { getMaterialById } = useMaterialStore(); const { getModelUuidByActionUuid } = useProductStore(); const { selectedProduct } = useSelectedProduct(); + const { incrementVehicleLoad, addCurrentMaterial } = useVehicleStore(); const travelLogStatus = (materialUuid: string, status: string) => { - console.log(`${materialUuid}, ${status}`); + // console.log(`${materialUuid}, ${status}`); } const handleTravel = useCallback((action: VehicleAction, materialId?: string) => { @@ -22,6 +24,10 @@ export function useTravelHandler() { if (!modelUuid) return; + incrementVehicleLoad(modelUuid, 1); + console.log('material: ', material); + addCurrentMaterial(modelUuid, material.materialType, material.materialId); + travelLogStatus(material.materialId, `is triggering travel from ${modelUuid}`); }, [getMaterialById, getModelUuidByActionUuid]); diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts index eb86062..1679da6 100644 --- a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -12,7 +12,7 @@ export function useTriggerHandler() { const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore(); const { getArmBotById } = useArmBotStore(); const { getVehicleById } = useVehicleStore(); - const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setEndTime } = useMaterialStore(); + const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setIsVisible, setEndTime } = useMaterialStore(); const handleTrigger = (trigger: TriggerSchema, action: Action, materialId: string) => { @@ -69,8 +69,10 @@ export function useTriggerHandler() { if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.currentLoad < vehicle.point.action.loadCapacity) { + setIsVisible(materialId, false); + // Handle current action from vehicle - handleAction(action, materialId) + handleAction(action, materialId); } else { @@ -116,7 +118,7 @@ export function useTriggerHandler() { setIsPaused(material.materialId, true); // Handle current action from arm bot - handleAction(action, materialId) + handleAction(action, materialId); } else { diff --git a/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx index e741bba..1fd3716 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/materialAnimator.tsx @@ -38,10 +38,12 @@ const MaterialAnimator = ({ agvDetail }: MaterialAnimatorProps) => { <> {hasLoad && ( <> - + {agvDetail.currentMaterials.length > 0 && + + } = fixedInterval) { let droppedMat = droppedMaterial - 1; decrementVehicleLoad(agvDetail.modelUuid, 1); + const materialId = removeLastMaterial(agvDetail.modelUuid); + if (materialId) { + removeMaterial(materialId); + } if (droppedMat > 0) { startTime = performance.now(); requestAnimationFrame(() => step(droppedMat)); diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index cb6c7a9..9cfa130 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -10,10 +10,9 @@ import MaterialAnimator from '../animator/materialAnimator'; function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); const { isPlaying } = usePlayButtonStore(); - const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, addCurrentMaterial, clearCurrentMaterials, setVehicleLoad } = useVehicleStore(); + const { vehicles, setVehicleActive, setVehicleState, clearCurrentMaterials, setVehicleLoad } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); - let isIncrememtable = useRef(true); const computePath = useCallback( (start: any, end: any) => { @@ -44,14 +43,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { setPath([]); } - const increment = () => { - if (isIncrememtable.current) { - incrementVehicleLoad(agvDetail.modelUuid, 10); - addCurrentMaterial(agvDetail.modelUuid, 'Material 1', '123'); - isIncrememtable.current = false; - } - } - useEffect(() => { if (isPlaying) { if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return; @@ -97,8 +88,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { setVehicleState(agvDetail.modelUuid, 'running'); setVehicleActive(agvDetail.modelUuid, true); vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point'); - - isIncrememtable.current = true; } } } else { diff --git a/app/src/modules/simulation/vehicle/vehicles.tsx b/app/src/modules/simulation/vehicle/vehicles.tsx index 7757f9b..2b92403 100644 --- a/app/src/modules/simulation/vehicle/vehicles.tsx +++ b/app/src/modules/simulation/vehicle/vehicles.tsx @@ -28,10 +28,13 @@ function Vehicles() { return ( <> + + {isVehicleSelected && selectedEventSphere && !isPlaying && } + ); } diff --git a/app/src/store/simulation/useVehicleStore.ts b/app/src/store/simulation/useVehicleStore.ts index 83a6bbc..7a393de 100644 --- a/app/src/store/simulation/useVehicleStore.ts +++ b/app/src/store/simulation/useVehicleStore.ts @@ -23,6 +23,7 @@ interface VehiclesStore { ) => void; addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void; setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void; + removeLastMaterial: (modelUuid: string) => string | undefined; clearCurrentMaterials: (modelUuid: string) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementIdleTime: (modelUuid: string, incrementBy: number) => void; @@ -152,6 +153,22 @@ export const useVehicleStore = create()( }); }, + removeLastMaterial: (modelUuid) => { + let materialId: string | undefined; + set((state) => { + const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); + if (vehicle) { + if (vehicle.currentMaterials.length > 0) { + const material = vehicle.currentMaterials.pop(); + if (material) { + materialId = material.materialId + } + } + } + }); + return materialId; + }, + clearCurrentMaterials: (modelUuid) => { set((state) => { const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); From 2e19637173ee85c3dfe89f63aee965a1644a31e9 Mon Sep 17 00:00:00 2001 From: Poovizhi99 Date: Thu, 8 May 2025 14:56:21 +0530 Subject: [PATCH 6/8] changed unloading function into callback function --- .../instances/animator/vehicleAnimator.tsx | 57 +--------------- .../instances/instance/vehicleInstance.tsx | 65 ++++++++++++++++++- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index 886793d..f67e22c 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -10,12 +10,13 @@ interface VehicleAnimatorProps { path: [number, number, number][]; handleCallBack: () => void; reset: () => void; + startUnloadingProcess: () => void; currentPhase: string; agvUuid: string; agvDetail: VehicleStatus; } -function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset }: VehicleAnimatorProps) { +function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset, startUnloadingProcess }: VehicleAnimatorProps) { const { decrementVehicleLoad, getVehicleById, removeLastMaterial } = useVehicleStore(); const { removeMaterial } = useMaterialStore(); const { isPaused } = usePauseButtonStore(); @@ -25,15 +26,11 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai const progressRef = useRef(0); const movingForward = useRef(true); const completedRef = useRef(false); - const isPausedRef = useRef(false); - const pauseTimeRef = useRef(null); const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) const [progress, setProgress] = useState(0); const [restRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); - let startTime: number; - let fixedInterval: number; let coveredDistance = progressRef.current; useEffect(() => { @@ -62,12 +59,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai completedRef.current = false; movingForward.current = true; progressRef.current = 0; - startTime = 0; coveredDistance = 0; setReset(false); setRestingRotation(true); - isPausedRef.current = false; - pauseTimeRef.current = 0; const object = scene.getObjectByProperty('uuid', agvUuid); const vehicle = getVehicleById(agvDetail.modelUuid); if (object && vehicle) { @@ -77,10 +71,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai } }, [isReset, isPlaying]) - useEffect(() => { - isPausedRef.current = isPaused; - }, [isPaused]); - useFrame((_, delta) => { const object = scene.getObjectByProperty('uuid', agvUuid); if (!object || currentPath.length < 2) return; @@ -157,53 +147,12 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai setCurrentPath([]); handleCallBack(); if (currentPhase === 'pickup-drop') { - requestAnimationFrame(firstFrame); + requestAnimationFrame(startUnloadingProcess); } } }); - function firstFrame() { - const droppedMaterial = agvDetail.currentLoad; - startTime = performance.now(); - step(droppedMaterial); - } - function step(droppedMaterial: number) { - if (isPausedRef.current) { - if (!pauseTimeRef.current) { - pauseTimeRef.current = performance.now(); - } - requestAnimationFrame(() => step(droppedMaterial)); - return; - } - - if (pauseTimeRef.current) { - const pauseDuration = performance.now() - pauseTimeRef.current; - startTime += pauseDuration; - pauseTimeRef.current = null; - } - - const elapsedTime = performance.now() - startTime; - const unLoadDuration = agvDetail.point.action.unLoadDuration; - fixedInterval = ((unLoadDuration / agvDetail.currentLoad) * (1000 / speed)); - - if (elapsedTime >= fixedInterval) { - let droppedMat = droppedMaterial - 1; - decrementVehicleLoad(agvDetail.modelUuid, 1); - const materialId = removeLastMaterial(agvDetail.modelUuid); - if (materialId) { - removeMaterial(materialId); - } - if (droppedMat > 0) { - startTime = performance.now(); - requestAnimationFrame(() => step(droppedMat)); - } else { - return; - } - } else { - requestAnimationFrame(() => step(droppedMaterial)); - } - } return ( <> diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 9cfa130..28ed64b 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -3,16 +3,29 @@ import VehicleAnimator from '../animator/vehicleAnimator'; import * as THREE from 'three'; import { NavMeshQuery } from '@recast-navigation/core'; import { useNavMesh } from '../../../../../store/store'; -import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; +import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; import MaterialAnimator from '../animator/materialAnimator'; +import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); const { isPlaying } = usePlayButtonStore(); - const { vehicles, setVehicleActive, setVehicleState, clearCurrentMaterials, setVehicleLoad } = useVehicleStore(); + const { removeMaterial } = useMaterialStore(); + const { vehicles, setVehicleActive, setVehicleState, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); + const pauseTimeRef = useRef(null); + const isPausedRef = useRef(false); + let startTime: number; + let fixedInterval: number; + const { speed } = useAnimationPlaySpeed(); + const { isPaused } = usePauseButtonStore(); + + + useEffect(() => { + isPausedRef.current = isPaused; + }, [isPaused]); const computePath = useCallback( (start: any, end: any) => { @@ -41,6 +54,9 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleLoad(agvDetail.modelUuid, 0); setPath([]); + startTime = 0; + isPausedRef.current = false; + pauseTimeRef.current = 0; } useEffect(() => { @@ -118,6 +134,50 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { } } + function startUnloadingProcess() { + const droppedMaterial = agvDetail.currentLoad; + startTime = performance.now(); + handleMaterialDrop(droppedMaterial); + } + + function handleMaterialDrop(droppedMaterial: number) { + if (isPausedRef.current) { + if (!pauseTimeRef.current) { + pauseTimeRef.current = performance.now(); + } + requestAnimationFrame(() => handleMaterialDrop(droppedMaterial)); + return; + } + + if (pauseTimeRef.current) { + const pauseDuration = performance.now() - pauseTimeRef.current; + startTime += pauseDuration; + pauseTimeRef.current = null; + } + + const elapsedTime = performance.now() - startTime; + const unLoadDuration = agvDetail.point.action.unLoadDuration; + fixedInterval = ((unLoadDuration / agvDetail.currentLoad) * (1000 / speed)); + + if (elapsedTime >= fixedInterval) { + let droppedMat = droppedMaterial - 1; + decrementVehicleLoad(agvDetail.modelUuid, 1); + const materialId = removeLastMaterial(agvDetail.modelUuid); + if (materialId) { + removeMaterial(materialId); + } + if (droppedMat > 0) { + startTime = performance.now(); + requestAnimationFrame(() => handleMaterialDrop(droppedMat)); + } else { + return; + } + } else { + requestAnimationFrame(() => handleMaterialDrop(droppedMaterial)); + } + } + + return ( <> From 962215d574501516b5b17fcb8599da5cd5058369 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 8 May 2025 15:15:38 +0530 Subject: [PATCH 7/8] Refactor zone visualization components: clean up unused code and improve readability in ZoneAssets and ZoneCentreTarget. --- app/src/modules/builder/groups/zoneGroup.tsx | 2 +- .../vehicle/actionHandler/useTravelHandler.ts | 1 - .../instances/instance/materialInstance.tsx | 33 ++--------------- .../triggerHandler/useTriggerHandler.ts | 35 +++++++++++++++++++ .../modules/visualization/zone/zoneAssets.tsx | 3 +- .../visualization/zone/zoneCameraTarget.tsx | 2 -- 6 files changed, 40 insertions(+), 36 deletions(-) diff --git a/app/src/modules/builder/groups/zoneGroup.tsx b/app/src/modules/builder/groups/zoneGroup.tsx index 3bd9b8d..b0c8124 100644 --- a/app/src/modules/builder/groups/zoneGroup.tsx +++ b/app/src/modules/builder/groups/zoneGroup.tsx @@ -549,7 +549,7 @@ const ZoneGroup: React.FC = () => { const midpoint = new THREE.Vector3( (point1.x + point2.x) / 2, CONSTANTS.zoneConfig.height / 2 + - (zone.layer - 1) * CONSTANTS.zoneConfig.height, + (zone.layer - 1) * CONSTANTS.zoneConfig.height, (point1.z + point2.z) / 2 ); diff --git a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts index 90019f0..c77b518 100644 --- a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts +++ b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts @@ -25,7 +25,6 @@ export function useTravelHandler() { if (!modelUuid) return; incrementVehicleLoad(modelUuid, 1); - console.log('material: ', material); addCurrentMaterial(modelUuid, material.materialType, material.materialId); travelLogStatus(material.materialId, `is triggering travel from ${modelUuid}`); diff --git a/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx b/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx index a26109c..74bd61f 100644 --- a/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx +++ b/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx @@ -85,37 +85,10 @@ function MaterialInstance({ material }: { material: MaterialSchema }) { const callTrigger = () => { if (!material.next) return; - const fromModel = getEventByModelUuid(selectedProduct.productId, material.next.modelUuid); - if (!fromModel) return; - const fromPoint = getPointByUuid(selectedProduct.productId, fromModel.modelUuid, material.next.pointUuid); - if (!fromPoint) return; - - if (fromModel.type === 'transfer') { - const toModel = getEventByModelUuid(selectedProduct.productId, material.next.modelUuid); - if (!toModel) return; - if (toModel.type === 'transfer') { - const action = getActionByPointUuid(selectedProduct.productId, material.next.pointUuid); - if (action) { - triggerPointActions(action, material.materialId); - } - } else if (toModel?.type === 'vehicle') { - // Transfer to Vehicle - - } else if (toModel?.type === 'machine') { - // Transfer to Machine - - } else if (toModel?.type === 'roboticArm') { - // Transfer to Robotic Arm - - } else if (toModel?.type === 'storageUnit') { - // Transfer to Storage Unit - } - } else if (fromModel.type === 'vehicle') { - } else if (fromModel.type === 'machine') { - } else if (fromModel.type === 'roboticArm') { - } else if (fromModel.type === 'storageUnit') { + const action = getActionByPointUuid(selectedProduct.productId, material.next.pointUuid); + if (action) { + triggerPointActions(action, material.materialId); } - } return ( diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts index 1679da6..19652b8 100644 --- a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -199,6 +199,41 @@ export function useTriggerHandler() { } else if (toEvent?.type === 'vehicle') { // Robotic Arm to Vehicle + if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + const material = getMaterialById(materialId); + if (material) { + const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid); + const vehicle = getVehicleById(trigger.triggeredAsset?.triggeredModel.modelUuid); + + setCurrentLocation(material.materialId, { + modelUuid: trigger.triggeredAsset.triggeredModel.modelUuid, + pointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid, + actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, + }); + + setNextLocation(material.materialId, null); + + if (action) { + + if (vehicle) { + + if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.currentLoad < vehicle.point.action.loadCapacity) { + + setIsVisible(materialId, false); + + // Handle current action from vehicle + handleAction(action, materialId); + + } else { + + // Event Manager Needed + + } + } + } + + } + } } else if (toEvent?.type === 'machine') { // Robotic Arm to Machine diff --git a/app/src/modules/visualization/zone/zoneAssets.tsx b/app/src/modules/visualization/zone/zoneAssets.tsx index af8b849..309fed4 100644 --- a/app/src/modules/visualization/zone/zoneAssets.tsx +++ b/app/src/modules/visualization/zone/zoneAssets.tsx @@ -7,6 +7,7 @@ export default function ZoneAssets() { const { zoneAssetId, setZoneAssetId } = useZoneAssetId(); const { setSelectedFloorItem } = useSelectedFloorItem(); const { raycaster, controls, scene }: any = useThree(); + useEffect(() => { // console.log('zoneAssetId: ', zoneAssetId); if (!zoneAssetId) return @@ -70,8 +71,6 @@ export default function ZoneAssets() { } }, [zoneAssetId, scene, controls]) - - return ( <> diff --git a/app/src/modules/visualization/zone/zoneCameraTarget.tsx b/app/src/modules/visualization/zone/zoneCameraTarget.tsx index d1587de..c3116ef 100644 --- a/app/src/modules/visualization/zone/zoneCameraTarget.tsx +++ b/app/src/modules/visualization/zone/zoneCameraTarget.tsx @@ -13,8 +13,6 @@ export default function ZoneCentreTarget() { const { zoneTarget, setZoneTarget } = usezoneTarget(); const { Edit, setEdit } = useEditPosition(); - - useEffect(() => { if ( selectedZone.zoneViewPortTarget && From 12b12d9eb0317377fdab55fc182ea447b848c4dc Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 8 May 2025 15:20:37 +0530 Subject: [PATCH 8/8] Refactor VehicleAnimator and VehicleInstance: remove unused material handling logic and clean up code for improved readability. --- .../instances/animator/vehicleAnimator.tsx | 17 +++-------------- .../instances/instance/vehicleInstance.tsx | 10 +--------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index f67e22c..ba16302 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -4,7 +4,6 @@ import * as THREE from 'three'; import { Line } from '@react-three/drei'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; -import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; interface VehicleAnimatorProps { path: [number, number, number][]; @@ -17,8 +16,7 @@ interface VehicleAnimatorProps { } function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset, startUnloadingProcess }: VehicleAnimatorProps) { - const { decrementVehicleLoad, getVehicleById, removeLastMaterial } = useVehicleStore(); - const { removeMaterial } = useMaterialStore(); + const { getVehicleById } = useVehicleStore(); const { isPaused } = usePauseButtonStore(); const { isPlaying } = usePlayButtonStore(); const { speed } = useAnimationPlaySpeed(); @@ -27,11 +25,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai const movingForward = useRef(true); const completedRef = useRef(false); const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) - const [progress, setProgress] = useState(0); const [restRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); - let coveredDistance = progressRef.current; useEffect(() => { if (currentPhase === 'stationed-pickup' && path.length > 0) { @@ -47,7 +43,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai }, [currentPhase, path, objectRotation]); useEffect(() => { - setProgress(0); completedRef.current = false; }, [currentPath]); @@ -55,11 +50,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai if (isReset || !isPlaying) { reset(); setCurrentPath([]); - setProgress(0); completedRef.current = false; movingForward.current = true; progressRef.current = 0; - coveredDistance = 0; setReset(false); setRestingRotation(true); const object = scene.getObjectByProperty('uuid', agvUuid); @@ -89,7 +82,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai totalDistance += segmentDistance; } - while (index < distances.length && coveredDistance > accumulatedDistance + distances[index]) { + while (index < distances.length && progressRef.current > accumulatedDistance + distances[index]) { accumulatedDistance += distances[index]; index++; } @@ -115,14 +108,12 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai if (isAligned) { progressRef.current += delta * (speed * agvDetail.speed); - coveredDistance = progressRef.current; - const t = (coveredDistance - accumulatedDistance) / segmentDistance; + const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); } } - if (progressRef.current >= totalDistance) { if (restRotation && objectRotation) { const targetEuler = new THREE.Euler( @@ -152,8 +143,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai } }); - - return ( <> {currentPath.length > 0 && ( diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 28ed64b..1ef79e0 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -5,8 +5,8 @@ import { NavMeshQuery } from '@recast-navigation/core'; import { useNavMesh } from '../../../../../store/store'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; -import MaterialAnimator from '../animator/materialAnimator'; import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; +import MaterialAnimator from '../animator/materialAnimator'; function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); @@ -22,7 +22,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { speed } = useAnimationPlaySpeed(); const { isPaused } = usePauseButtonStore(); - useEffect(() => { isPausedRef.current = isPaused; }, [isPaused]); @@ -44,7 +43,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { function vehicleStatus(modelId: string, status: string) { // console.log(`${modelId} , ${status}`); - } // Function to reset everything @@ -75,11 +73,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup'); return; } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') { - - // setTimeout(() => { - // increment(); - // }, 5000); - if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.currentMaterials.length > 0) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { const toDrop = computePath( @@ -177,7 +170,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { } } - return ( <>