Refactor material handling: update loadCapacity to 1 in multiple components, enhance storage unit actions, and implement new store handler logic for improved material management

This commit is contained in:
2025-05-10 12:24:29 +05:30
parent cf513d3ba6
commit 3703dc629d
11 changed files with 200 additions and 30 deletions

View File

@@ -204,7 +204,7 @@ function processLoadedModel(
actionName: "Action 1", actionName: "Action 1",
actionType: "travel", actionType: "travel",
unLoadDuration: 5, unLoadDuration: 5,
loadCapacity: 10, loadCapacity: 1,
steeringAngle: 0, steeringAngle: 0,
pickUpPoint: null, pickUpPoint: null,
unLoadPoint: null, unLoadPoint: null,

View File

@@ -265,7 +265,7 @@ async function handleModelLoad(
actionName: "Action 1", actionName: "Action 1",
actionType: "travel", actionType: "travel",
unLoadDuration: 5, unLoadDuration: 5,
loadCapacity: 10, loadCapacity: 1,
steeringAngle: 0, steeringAngle: 0,
pickUpPoint: null, pickUpPoint: null,
unLoadPoint: null, unLoadPoint: null,

View File

@@ -209,7 +209,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
actionName: "Action 1", actionName: "Action 1",
actionType: "travel", actionType: "travel",
unLoadDuration: 5, unLoadDuration: 5,
loadCapacity: 10, loadCapacity: 1,
steeringAngle: 0, steeringAngle: 0,
pickUpPoint: null, pickUpPoint: null,
unLoadPoint: null, unLoadPoint: null,

View File

@@ -186,7 +186,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
actionName: "Action 1", actionName: "Action 1",
actionType: "travel", actionType: "travel",
unLoadDuration: 5, unLoadDuration: 5,
loadCapacity: 10, loadCapacity: 1,
steeringAngle: 0, steeringAngle: 0,
pickUpPoint: null, pickUpPoint: null,
unLoadPoint: null, unLoadPoint: null,

View File

@@ -0,0 +1,38 @@
import { useCallback } from "react";
import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore";
import { useStorageUnitStore } from "../../../../../store/simulation/useStorageUnitStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
export function useStoreHandler() {
const { getMaterialById, removeMaterial } = useMaterialStore();
const { addCurrentMaterial, updateCurrentLoad } = useStorageUnitStore();
const { getModelUuidByActionUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const storeLogStatus = (materialUuid: string, status: string) => {
// console.log(`${materialUuid}, ${status}`);
}
const handleStore = useCallback((action: StorageAction, materialId?: string) => {
if (!action || action.actionType !== 'store' || !materialId) return;
const material = getMaterialById(materialId);
if (!material) return;
const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid);
if (!modelUuid) return;
removeMaterial(material.materialId);
addCurrentMaterial(modelUuid, material.materialType, material.materialId);
updateCurrentLoad(modelUuid, 1);
storeLogStatus(material.materialId, `performed Store action`);
}, [getMaterialById]);
return {
handleStore,
};
}

View File

@@ -1,16 +1,19 @@
import { useEffect, useCallback, useRef, useState } from 'react'; import { useEffect, useCallback } from 'react';
import { useStoreHandler } from './actionHandler/useStoreHandler';
export function useStorageActions() { export function useStorageActions() {
const handleStoreAction = useCallback((action: StorageAction) => { const { handleStore } = useStoreHandler();
if (!action || action.actionType !== 'store') return;
}, []);
const handleStorageAction = useCallback((action: StorageAction) => { const handleStoreAction = useCallback((action: StorageAction, materialId: string) => {
handleStore(action, materialId);
}, [handleStore]);
const handleStorageAction = useCallback((action: StorageAction, materialId: string) => {
if (!action) return; if (!action) return;
switch (action.actionType) { switch (action.actionType) {
case 'store': case 'store':
handleStoreAction(action); handleStoreAction(action, materialId);
break; break;
default: default:
console.warn(`Unknown storage action type: ${action.actionType}`); console.warn(`Unknown storage action type: ${action.actionType}`);

View File

@@ -36,7 +36,7 @@ export function useActionHandler() {
handleMachineAction(action as MachineAction, materialId as string); handleMachineAction(action as MachineAction, materialId as string);
break; break;
case 'store': case 'store':
handleStorageAction(action as StorageAction); handleStorageAction(action as StorageAction, materialId as string);
break; break;
default: default:
console.warn(`Unknown action type: ${(action as Action).actionType}`); console.warn(`Unknown action type: ${(action as Action).actionType}`);

View File

@@ -6,6 +6,7 @@ import { useMaterialStore } from '../../../../store/simulation/useMaterialStore'
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore'; import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore'; import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
import { useMachineStore } from '../../../../store/simulation/useMachineStore'; import { useMachineStore } from '../../../../store/simulation/useMachineStore';
import { useStorageUnitStore } from '../../../../store/simulation/useStorageUnitStore';
export function useTriggerHandler() { export function useTriggerHandler() {
const { handleAction } = useActionHandler(); const { handleAction } = useActionHandler();
@@ -14,6 +15,7 @@ export function useTriggerHandler() {
const { getArmBotById } = useArmBotStore(); const { getArmBotById } = useArmBotStore();
const { getVehicleById } = useVehicleStore(); const { getVehicleById } = useVehicleStore();
const { getMachineById } = useMachineStore(); const { getMachineById } = useMachineStore();
const { getStorageUnitById } = useStorageUnitStore();
const { setCurrentLocation, setNextLocation, setPreviousLocation, getMaterialById, setIsPaused, setIsVisible, setEndTime } = useMaterialStore(); const { setCurrentLocation, setNextLocation, setPreviousLocation, getMaterialById, setIsPaused, setIsVisible, setEndTime } = useMaterialStore();
const handleTrigger = (trigger: TriggerSchema, action: Action, materialId?: string) => { const handleTrigger = (trigger: TriggerSchema, action: Action, materialId?: string) => {
@@ -219,10 +221,7 @@ export function useTriggerHandler() {
setIsVisible(materialId, false); setIsVisible(materialId, false);
if (action && armBot && if (action && armBot) {
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid
) {
if (armBot.isActive === false && armBot.state === 'idle') { if (armBot.isActive === false && armBot.state === 'idle') {
@@ -240,7 +239,43 @@ export function useTriggerHandler() {
} else if (toEvent?.type === 'storageUnit') { } else if (toEvent?.type === 'storageUnit') {
// Vehicle to Storage Unit // Vehicle to Storage Unit
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
const material = getMaterialById(materialId);
if (material) {
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
const storageUnit = getStorageUnitById(trigger.triggeredAsset?.triggeredModel.modelUuid);
setPreviousLocation(material.materialId, {
modelUuid: material.current.modelUuid,
pointUuid: material.current.pointUuid,
actionUuid: material.current.actionUuid,
})
setCurrentLocation(material.materialId, {
modelUuid: trigger.triggeredAsset.triggeredModel.modelUuid,
pointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid,
});
setNextLocation(material.materialId, null);
setIsVisible(materialId, false);
if (action && storageUnit) {
if (storageUnit.currentLoad < storageUnit.point.action.storageCapacity) {
// Handle current action from vehicle
handleAction(action, materialId);
} else {
// Event Manager Needed
}
}
}
}
} }
} else if (fromEvent?.type === 'machine') { } else if (fromEvent?.type === 'machine') {
if (toEvent?.type === 'transfer') { if (toEvent?.type === 'transfer') {
@@ -276,10 +311,7 @@ export function useTriggerHandler() {
setIsVisible(materialId, false); setIsVisible(materialId, false);
if (action && armBot && if (action && armBot) {
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid
) {
if (armBot.isActive === false && armBot.state === 'idle') { if (armBot.isActive === false && armBot.state === 'idle') {

View File

@@ -73,6 +73,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
const distances = []; const distances = [];
let accumulatedDistance = 0; let accumulatedDistance = 0;
let index = 0; let index = 0;
const rotationSpeed = 1;
for (let i = 0; i < currentPath.length - 1; i++) { for (let i = 0; i < currentPath.length - 1; i++) {
const start = new THREE.Vector3(...currentPath[i]); const start = new THREE.Vector3(...currentPath[i]);
@@ -95,14 +96,13 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
const currentDirection = new THREE.Vector3().subVectors(end, start).normalize(); const currentDirection = new THREE.Vector3().subVectors(end, start).normalize();
const targetAngle = Math.atan2(currentDirection.x, currentDirection.z); const targetAngle = Math.atan2(currentDirection.x, currentDirection.z);
const rotationSpeed = speed;
const currentAngle = object.rotation.y; const currentAngle = object.rotation.y;
let angleDifference = targetAngle - currentAngle; let angleDifference = targetAngle - currentAngle;
if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI; if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI;
if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI; if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI;
const maxRotationStep = rotationSpeed * delta; const maxRotationStep = (rotationSpeed * speed * agvDetail.speed) * delta;
object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep); object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep);
const isAligned = Math.abs(angleDifference) < 0.01; const isAligned = Math.abs(angleDifference) < 0.01;
@@ -122,7 +122,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
objectRotation.z objectRotation.z
); );
const targetQuaternion = new THREE.Quaternion().setFromEuler(targetEuler); const targetQuaternion = new THREE.Quaternion().setFromEuler(targetEuler);
object.quaternion.slerp(targetQuaternion, delta * 2); object.quaternion.slerp(targetQuaternion, delta * (rotationSpeed * speed * agvDetail.speed));
if (object.quaternion.angleTo(targetQuaternion) < 0.01) { if (object.quaternion.angleTo(targetQuaternion) < 0.01) {
object.quaternion.copy(targetQuaternion); object.quaternion.copy(targetQuaternion);
object.rotation.copy(targetEuler); object.rotation.copy(targetEuler);

View File

@@ -5,6 +5,7 @@ import { NavMeshQuery } from '@recast-navigation/core';
import { useNavMesh } from '../../../../../store/store'; import { useNavMesh } from '../../../../../store/store';
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore';
import { useStorageUnitStore } from '../../../../../store/simulation/useStorageUnitStore';
import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
@@ -14,7 +15,8 @@ import MaterialAnimator from '../animator/materialAnimator';
function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) { function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) {
const { navMesh } = useNavMesh(); const { navMesh } = useNavMesh();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { removeMaterial } = useMaterialStore(); const { removeMaterial, addMaterial } = useMaterialStore();
const { getStorageUnitById, addCurrentMaterial, updateCurrentLoad } = useStorageUnitStore();
const { triggerPointActions } = useTriggerHandler(); const { triggerPointActions } = useTriggerHandler();
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore(); const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
@@ -154,7 +156,10 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
handleMaterialDropToArmBot(action); handleMaterialDropToArmBot(action);
} }
} else if (model.type === 'storageUnit') { } else if (model.type === 'storageUnit') {
// const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid);
if (action) {
handleMaterialDropToStorageUnit(action);
}
} }
} else { } else {
const droppedMaterial = agvDetail.currentLoad; const droppedMaterial = agvDetail.currentLoad;
@@ -168,6 +173,98 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
} }
} }
function handleMaterialDropToStorageUnit(action: Action) {
if (action.triggers.length > 0 && action.triggers[0].triggeredAsset?.triggeredModel.modelUuid) {
const storageUnit = getStorageUnitById(action.triggers[0].triggeredAsset?.triggeredModel.modelUuid);
if (storageUnit) {
if (storageUnit.point.action.actionType === 'spawn') {
// const newMaterial: MaterialSchema = {
// materialId: THREE.MathUtils.generateUUID(),
// materialName: `${storageUnit.point.action.materialType}-${Date.now()}`,
// materialType: storageUnit.point.action.materialType || 'Default material',
// isActive: false,
// isVisible: true,
// isPaused: false,
// isRendered: true,
// startTime: performance.now(),
// current: {
// modelUuid: storageUnit.modelUuid,
// pointUuid: storageUnit.point.uuid,
// actionUuid: storageUnit.point.action.actionUuid
// },
// };
} else if (storageUnit.point.action.actionType === 'store') {
handleMaterialDropToStorage(
agvDetail.modelUuid,
agvDetail.currentLoad,
agvDetail.point.action.unLoadDuration,
storageUnit.modelUuid,
storageUnit.point.action.storageCapacity,
agvDetail.point.action
);
}
}
}
}
function handleMaterialDropToStorage(
vehicleId: string,
vehicleCurrentLoad: number,
unLoadDuration: number,
storageUnitId: string,
storageMaxCapacity: number,
action: VehicleAction
) {
startTime = performance.now();
const fixedInterval = ((unLoadDuration / vehicleCurrentLoad) * (1000 / speed));
const unloadLoop = () => {
if (isPausedRef.current) {
pauseTimeRef.current ??= performance.now();
requestAnimationFrame(unloadLoop);
return;
}
if (pauseTimeRef.current) {
const pauseDuration = performance.now() - pauseTimeRef.current;
startTime += pauseDuration;
pauseTimeRef.current = null;
}
const elapsedTime = performance.now() - startTime;
const storageUnit = getStorageUnitById(storageUnitId);
if (elapsedTime >= fixedInterval) {
if (storageUnit && agvDetail &&
storageUnit.currentLoad < storageMaxCapacity &&
vehicleCurrentLoad > 0) {
decrementVehicleLoad(vehicleId, 1);
vehicleCurrentLoad -= 1;
const material = removeLastMaterial(vehicleId);
if (material) {
triggerPointActions(action, material.materialId);
}
if (vehicleCurrentLoad > 0 && storageUnit.currentLoad < storageMaxCapacity) {
startTime = performance.now();
requestAnimationFrame(unloadLoop);
}
}
} else {
requestAnimationFrame(unloadLoop);
}
};
const storageUnit = getStorageUnitById(storageUnitId);
if (storageUnit && vehicleCurrentLoad > 0 && storageUnit?.currentLoad < storageMaxCapacity) {
unloadLoop();
}
}
function handleMaterialDropToConveyor(action: Action) { function handleMaterialDropToConveyor(action: Action) {
if (agvDetail.currentLoad > 1) { if (agvDetail.currentLoad > 1) {
// //
@@ -206,9 +303,9 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
if (elapsedTime >= fixedInterval) { if (elapsedTime >= fixedInterval) {
let droppedMat = droppedMaterial - 1; let droppedMat = droppedMaterial - 1;
decrementVehicleLoad(agvDetail.modelUuid, 1); decrementVehicleLoad(agvDetail.modelUuid, 1);
const materialId = removeLastMaterial(agvDetail.modelUuid); const material = removeLastMaterial(agvDetail.modelUuid);
if (materialId) { if (material) {
removeMaterial(materialId); removeMaterial(material.materialId);
} }
if (droppedMat > 0) { if (droppedMat > 0) {
startTime = performance.now(); startTime = performance.now();

View File

@@ -23,7 +23,7 @@ interface VehiclesStore {
) => void; ) => void;
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void; addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void; setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void;
removeLastMaterial: (modelUuid: string) => string | undefined; removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
clearCurrentMaterials: (modelUuid: string) => void; clearCurrentMaterials: (modelUuid: string) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void; incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
@@ -153,14 +153,14 @@ export const useVehicleStore = create<VehiclesStore>()(
}, },
removeLastMaterial: (modelUuid) => { removeLastMaterial: (modelUuid) => {
let materialId: string | undefined; let materialId: { materialId: string; materialType: string; } | undefined;
set((state) => { set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid); const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) { if (vehicle) {
if (vehicle.currentMaterials.length > 0) { if (vehicle.currentMaterials.length > 0) {
const material = vehicle.currentMaterials.pop(); const material = vehicle.currentMaterials.pop();
if (material) { if (material) {
materialId = material.materialId materialId = { materialId: material.materialId, materialType: material.materialType };
} }
} }
} }