Implement action handlers for conveyor, robotic arm, and vehicle, including logging and material management

This commit is contained in:
2025-05-08 13:43:37 +05:30
parent 8bf48bfcfe
commit 19e23501a4
12 changed files with 207 additions and 45 deletions

View File

@@ -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,
};
}

View File

@@ -2,7 +2,7 @@ import { useCallback } from "react";
import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore"; import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore";
export function useDespawnHandler() { export function useDespawnHandler() {
const { addMaterial, getMaterialById, removeMaterial } = useMaterialStore(); const { getMaterialById, removeMaterial } = useMaterialStore();
const deSpawnLogStatus = (materialUuid: string, status: string) => { const deSpawnLogStatus = (materialUuid: string, status: string) => {
// console.log(`${materialUuid}, ${status}`); // console.log(`${materialUuid}, ${status}`);
@@ -18,7 +18,7 @@ export function useDespawnHandler() {
deSpawnLogStatus(material.materialId, `Despawned`); deSpawnLogStatus(material.materialId, `Despawned`);
}, [addMaterial, getMaterialById, removeMaterial]); }, [getMaterialById, removeMaterial]);
return { return {
handleDespawn, handleDespawn,

View File

@@ -1,17 +1,20 @@
import { useEffect, useCallback } from "react"; import { useEffect, useCallback } from "react";
import { useDefaultHandler } from "./actionHandler/useDefaultHandler";
import { useSpawnHandler } from "./actionHandler/useSpawnHandler"; import { useSpawnHandler } from "./actionHandler/useSpawnHandler";
import { useSwapHandler } from "./actionHandler/useSwapHandler"; import { useSwapHandler } from "./actionHandler/useSwapHandler";
import { useDelayHandler } from "./actionHandler/useDelayHandler"; import { useDelayHandler } from "./actionHandler/useDelayHandler";
import { useDespawnHandler } from "./actionHandler/useDespawnHandler"; import { useDespawnHandler } from "./actionHandler/useDespawnHandler";
export function useConveyorActions() { export function useConveyorActions() {
const { handleDefault } = useDefaultHandler();
const { handleSpawn, clearCurrentSpawn } = useSpawnHandler(); const { handleSpawn, clearCurrentSpawn } = useSpawnHandler();
const { handleSwap } = useSwapHandler(); const { handleSwap } = useSwapHandler();
const { handleDespawn } = useDespawnHandler(); const { handleDespawn } = useDespawnHandler();
const { handleDelay, cleanupDelay } = useDelayHandler(); 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) => { const handleSpawnAction = useCallback((action: ConveyorAction) => {
handleSpawn(action); handleSpawn(action);

View File

@@ -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,
};
}

View File

@@ -1,20 +1,24 @@
import { useEffect, useCallback } from 'react'; import { useEffect, useCallback } from 'react';
import { usePickAndPlaceHandler } from './actionHandler/usePickAndPlaceHandler';
export function useRoboticArmActions() { export function useRoboticArmActions() {
const { handlePickAndPlace } = usePickAndPlaceHandler();
const handlePickAndPlace = useCallback((action: RoboticArmAction) => { const handlePickAndPlaceAction = useCallback((action: RoboticArmAction, materialId: string) => {
console.log(`Robotic arm pick and place`); handlePickAndPlace(action, materialId);
}, []); }, [handlePickAndPlace]);
const handleRoboticArmAction = useCallback((action: RoboticArmAction, materialId: string) => {
if (!action) return;
const handleRoboticArmAction = useCallback((action: RoboticArmAction) => {
switch (action.actionType) { switch (action.actionType) {
case 'pickAndPlace': case 'pickAndPlace':
handlePickAndPlace(action); handlePickAndPlaceAction(action, materialId);
break; break;
default: default:
console.warn(`Unknown robotic arm action type: ${action.actionType}`); console.warn(`Unknown robotic arm action type: ${action.actionType}`);
} }
}, [handlePickAndPlace]); }, [handlePickAndPlaceAction]);
const cleanup = useCallback(() => { const cleanup = useCallback(() => {
}, []); }, []);

View File

@@ -24,10 +24,10 @@ export function useActionHandler() {
handleConveyorAction(action as ConveyorAction, materialId as string); handleConveyorAction(action as ConveyorAction, materialId as string);
break; break;
case 'travel': case 'travel':
handleVehicleAction(action as VehicleAction); handleVehicleAction(action as VehicleAction, materialId as string);
break; break;
case 'pickAndPlace': case 'pickAndPlace':
handleRoboticArmAction(action as RoboticArmAction); handleRoboticArmAction(action as RoboticArmAction, materialId as string);
break; break;
case 'process': case 'process':
handleMachineAction(action as MachineAction); handleMachineAction(action as MachineAction);

View File

@@ -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,
};
}

View File

@@ -1,20 +1,19 @@
import { useEffect, useCallback } from 'react'; import { useEffect, useCallback } from 'react';
import { useTravelHandler } from './actionHandler/useTravelHandler';
export function useVehicleActions() { export function useVehicleActions() {
const { handleTravel } = useTravelHandler();
const handleTravelAction = useCallback((action: VehicleAction) => { const handleTravelAction = useCallback((action: VehicleAction, materialId: string) => {
if (!action || action.actionType !== 'travel') return; handleTravel(action, materialId);
}, [handleTravel]);
console.log(`Vehicle travel action ${action.actionUuid}`); const handleVehicleAction = useCallback((action: VehicleAction, materialId: string) => {
}, []);
const handleVehicleAction = useCallback((action: VehicleAction) => {
if (!action) return; if (!action) return;
switch (action.actionType) { switch (action.actionType) {
case 'travel': case 'travel':
handleTravelAction(action); handleTravelAction(action, materialId);
break; break;
default: default:
console.warn(`Unknown vehicle action type: ${action.actionType}`); console.warn(`Unknown vehicle action type: ${action.actionType}`);

View File

@@ -50,7 +50,7 @@ function TriggerConnector() {
organization: string, organization: string,
eventData: EventsSchema eventData: EventsSchema
) => { ) => {
upsertProductOrEventApi({ const data =upsertProductOrEventApi({
productName: productName, productName: productName,
productId: productId, productId: productId,
organization: organization, organization: organization,

View File

@@ -4,12 +4,14 @@ import { useProductStore } from '../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore'; import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
import { useMaterialStore } from '../../../../store/simulation/useMaterialStore'; import { useMaterialStore } from '../../../../store/simulation/useMaterialStore';
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore'; import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
export function useTriggerHandler() { export function useTriggerHandler() {
const { handleAction } = useActionHandler(); const { handleAction } = useActionHandler();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore(); const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
const { addCurrentAction, getArmBotById } = useArmBotStore(); const { getArmBotById } = useArmBotStore();
const { getVehicleById } = useVehicleStore();
const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setEndTime } = useMaterialStore(); const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setEndTime } = useMaterialStore();
const handleTrigger = (trigger: TriggerSchema, action: Action, materialId: string) => { const handleTrigger = (trigger: TriggerSchema, action: Action, materialId: string) => {
@@ -42,6 +44,44 @@ export function useTriggerHandler() {
} }
} else if (toEvent?.type === 'vehicle') { } else if (toEvent?.type === 'vehicle') {
// Transfer to 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') { } else if (toEvent?.type === 'machine') {
// Transfer to Machine // Transfer to Machine
@@ -51,10 +91,14 @@ export function useTriggerHandler() {
if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
const material = getMaterialById(materialId); const material = getMaterialById(materialId);
if (material) { if (material) {
// Handle current action of the material
handleAction(action, materialId);
if (material.next) { if (material.next) {
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
const armBot = getArmBotById(trigger.triggeredAsset?.triggeredModel.modelUuid); const armBot = getArmBotById(trigger.triggeredAsset?.triggeredModel.modelUuid);
if (armBot) {
if (armBot.isActive === false && armBot.state === 'idle') {
setCurrentLocation(material.materialId, { setCurrentLocation(material.materialId, {
modelUuid: material.next.modelUuid, modelUuid: material.next.modelUuid,
pointUuid: material.next.pointUuid, pointUuid: material.next.pointUuid,
@@ -63,13 +107,17 @@ export function useTriggerHandler() {
setNextLocation(material.materialId, null); setNextLocation(material.materialId, null);
if (action) {
if (armBot) {
if (armBot.isActive === false && armBot.state === 'idle') {
setIsPaused(material.materialId, true); setIsPaused(material.materialId, true);
addCurrentAction(
trigger.triggeredAsset?.triggeredModel.modelUuid, // Handle current action from arm bot
trigger.triggeredAsset?.triggeredAction?.actionUuid, handleAction(action, materialId)
material.materialType,
material.materialId
);
} else { } else {
// Event Manager Needed // Event Manager Needed
@@ -77,7 +125,7 @@ export function useTriggerHandler() {
} }
} }
} }
handleAction(action, materialId); }
} }
} }
} else if (toEvent?.type === 'storageUnit') { } else if (toEvent?.type === 'storageUnit') {

View File

@@ -11,7 +11,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) {
const { navMesh } = useNavMesh(); const { navMesh } = useNavMesh();
const vehicleRef: any = useRef(); const vehicleRef: any = useRef();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setMaterialType } = useVehicleStore(); const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setVehicleLoad, setMaterialType } = useVehicleStore();
const [currentPhase, setCurrentPhase] = useState<string>('stationed'); const [currentPhase, setCurrentPhase] = useState<string>('stationed');
const [path, setPath] = useState<[number, number, number][]>([]); const [path, setPath] = useState<[number, number, number][]>([]);
let isIncrememtable = useRef<boolean>(true); let isIncrememtable = useRef<boolean>(true);
@@ -41,6 +41,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) {
setCurrentPhase('stationed'); setCurrentPhase('stationed');
setVehicleActive(agvDetail.modelUuid, false); setVehicleActive(agvDetail.modelUuid, false);
setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleState(agvDetail.modelUuid, 'idle');
setVehicleLoad(agvDetail.modelUuid, 0);
setPath([]); setPath([]);
} }
@@ -54,6 +55,7 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) {
useEffect(() => { useEffect(() => {
if (isPlaying) { if (isPlaying) {
if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return;
if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') { if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') {
const toPickupPath = computePath( const toPickupPath = computePath(
@@ -68,10 +70,9 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) {
return; return;
} else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') { } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') {
setTimeout(() => { // setTimeout(() => {
increment(); // increment();
}, 5000); // }, 5000);
if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) { if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) {
if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) {

View File

@@ -17,6 +17,7 @@ interface VehiclesStore {
updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void; updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void;
incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void; incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void;
decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void; decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void;
setVehicleLoad: (modelUuid: string, load: number) => void;
setVehicleState: (modelUuid: string, newState: VehicleStatus['state']) => void; setVehicleState: (modelUuid: string, newState: VehicleStatus['state']) => void;
setMaterialType: (modelUuid: string, materialType: string | null) => void; setMaterialType: (modelUuid: string, materialType: string | null) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void; incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
@@ -107,6 +108,15 @@ export const useVehicleStore = create<VehiclesStore>()(
}); });
}, },
setVehicleLoad: (modelUuid, load) => {
set((state) => {
const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentLoad = load;
}
});
},
setVehicleState: (modelUuid, newState) => { setVehicleState: (modelUuid, newState) => {
set((state) => { set((state) => {
const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid); const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid);