Enhance vehicle handling: add picking state management, update action handling in VehicleInstance, and refine useVehicleStore for improved vehicle interactions.
This commit is contained in:
parent
e16a0a6d8b
commit
c0a7eebecb
|
@ -12,10 +12,10 @@ import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore } from "..
|
|||
export function useRetrieveHandler() {
|
||||
const { addMaterial } = useMaterialStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid } = useProductStore();
|
||||
const { getStorageUnitById, getLastMaterial } = useStorageUnitStore();
|
||||
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = useStorageUnitStore();
|
||||
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = useVehicleStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { getArmBotById, addCurrentAction } = useArmBotStore();
|
||||
const { getVehicleById } = useVehicleStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
@ -48,7 +48,7 @@ export function useRetrieveHandler() {
|
|||
isPaused: false,
|
||||
isRendered: true,
|
||||
startTime: currentTime,
|
||||
previous:{
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
|
@ -125,49 +125,94 @@ export function useRetrieveHandler() {
|
|||
if (triggeredModel.type === 'roboticArm') {
|
||||
const armBot = getArmBotById(triggeredModel.modelUuid);
|
||||
isIdle = armBot && !armBot.isActive && armBot.state === 'idle' && !armBot.currentAction || false;
|
||||
} else if (triggeredModel.type === 'vehicle') {
|
||||
const vehicle = getVehicleById(triggeredModel.modelUuid);
|
||||
isIdle = vehicle && !vehicle.isActive && vehicle.state === 'idle' || false;
|
||||
}
|
||||
|
||||
if (isIdle) {
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: true,
|
||||
lastCheckTime: currentTime
|
||||
if (isIdle) {
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: true,
|
||||
lastCheckTime: currentTime
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
);
|
||||
|
||||
if (material && triggeredModel.type === 'roboticArm') {
|
||||
addCurrentAction(
|
||||
triggeredModel.modelUuid,
|
||||
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid || '',
|
||||
material.materialType,
|
||||
material.materialId
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
);
|
||||
|
||||
if (material) {
|
||||
addCurrentAction(
|
||||
triggeredModel.modelUuid,
|
||||
retrieval.action.triggers[0].triggeredAsset.triggeredAction?.actionUuid || '',
|
||||
material.materialType,
|
||||
material.materialId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: false,
|
||||
lastCheckTime: currentTime
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
}
|
||||
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: false,
|
||||
lastCheckTime: currentTime
|
||||
} else if (triggeredModel.type === 'vehicle') {
|
||||
const vehicle = getVehicleById(triggeredModel.modelUuid);
|
||||
isIdle = vehicle && !vehicle.isActive && vehicle.state === 'idle' && vehicle.isPicking || false;
|
||||
|
||||
if (!vehicle) return;
|
||||
const loadDuration = vehicle.point.action.unLoadDuration;
|
||||
|
||||
if (isIdle) {
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: true,
|
||||
lastCheckTime: currentTime
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
|
||||
const lastMaterial = getLastMaterial(storageUnit.modelUuid);
|
||||
if (lastMaterial) {
|
||||
if (vehicle?.currentLoad < vehicle.point.action.loadCapacity) {
|
||||
const material = createNewMaterial(
|
||||
lastMaterial.materialId,
|
||||
lastMaterial.materialType,
|
||||
storageUnit.point.action
|
||||
);
|
||||
|
||||
if (material) {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1)
|
||||
incrementVehicleLoad(vehicle.modelUuid, 1);
|
||||
addCurrentMaterial(vehicle.modelUuid, material.materialType, material.materialId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setActiveRetrievals(prev => {
|
||||
const newRetrievals = new Map(prev);
|
||||
newRetrievals.set(actionUuid, {
|
||||
...retrieval,
|
||||
isProcessing: false,
|
||||
lastCheckTime: currentTime
|
||||
});
|
||||
return newRetrievals;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -18,36 +18,33 @@ export function useActionHandler() {
|
|||
const { handleMachineAction, cleanup: cleanupMachine } = useMachineActions();
|
||||
const { handleStorageAction, cleanup: cleanupStorage } = useStorageActions();
|
||||
|
||||
const handleAction = useCallback(
|
||||
(action: Action, materialId?: string) => {
|
||||
if (!action) return;
|
||||
try {
|
||||
switch (action.actionType) {
|
||||
case 'default': case 'spawn': case 'swap': case 'delay': case 'despawn':
|
||||
handleConveyorAction(action as ConveyorAction, materialId as string);
|
||||
break;
|
||||
case 'travel':
|
||||
handleVehicleAction(action as VehicleAction, materialId as string);
|
||||
break;
|
||||
case 'pickAndPlace':
|
||||
handleRoboticArmAction(action as RoboticArmAction, materialId as string);
|
||||
break;
|
||||
case 'process':
|
||||
handleMachineAction(action as MachineAction, materialId as string);
|
||||
break;
|
||||
case 'store': case 'retrieve':
|
||||
handleStorageAction(action as StorageAction, materialId as string);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown action type: ${(action as Action).actionType}`);
|
||||
}
|
||||
} catch (error) {
|
||||
echo.error("Failed to handle action");
|
||||
console.error("Error handling action:", error);
|
||||
const handleAction = useCallback((action: Action, materialId?: string) => {
|
||||
if (!action) return;
|
||||
try {
|
||||
switch (action.actionType) {
|
||||
case 'default': case 'spawn': case 'swap': case 'delay': case 'despawn':
|
||||
handleConveyorAction(action as ConveyorAction, materialId as string);
|
||||
break;
|
||||
case 'travel':
|
||||
handleVehicleAction(action as VehicleAction, materialId as string);
|
||||
break;
|
||||
case 'pickAndPlace':
|
||||
handleRoboticArmAction(action as RoboticArmAction, materialId as string);
|
||||
break;
|
||||
case 'process':
|
||||
handleMachineAction(action as MachineAction, materialId as string);
|
||||
break;
|
||||
case 'store': case 'retrieve':
|
||||
handleStorageAction(action as StorageAction, materialId as string);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown action type: ${(action as Action).actionType}`);
|
||||
}
|
||||
},
|
||||
[handleConveyorAction, handleVehicleAction, handleRoboticArmAction, handleMachineAction, handleStorageAction,]
|
||||
);
|
||||
} catch (error) {
|
||||
echo.error("Failed to handle action");
|
||||
console.error("Error handling action:", error);
|
||||
}
|
||||
}, [handleConveyorAction, handleVehicleAction, handleRoboticArmAction, handleMachineAction, handleStorageAction,]);
|
||||
|
||||
const cleanup = useCallback(() => {
|
||||
cleanupConveyor();
|
||||
|
|
|
@ -15,12 +15,12 @@ import MaterialAnimator from '../animator/materialAnimator';
|
|||
function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) {
|
||||
const { navMesh } = useNavMesh();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { removeMaterial, addMaterial } = useMaterialStore();
|
||||
const { getStorageUnitById, addCurrentMaterial, updateCurrentLoad } = useStorageUnitStore();
|
||||
const { removeMaterial } = useMaterialStore();
|
||||
const { getStorageUnitById } = useStorageUnitStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { vehicles, setVehicleActive, setVehicleState, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
|
||||
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore();
|
||||
const [currentPhase, setCurrentPhase] = useState<string>('stationed');
|
||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||
const pauseTimeRef = useRef<number | null>(null);
|
||||
|
@ -58,6 +58,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||
function reset() {
|
||||
setCurrentPhase('stationed');
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
setVehicleLoad(agvDetail.modelUuid, 0);
|
||||
setPath([]);
|
||||
|
@ -78,6 +79,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||
setPath(toPickupPath);
|
||||
setCurrentPhase('stationed-pickup');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup');
|
||||
return;
|
||||
|
@ -91,6 +93,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||
setPath(toDrop);
|
||||
setCurrentPhase('pickup-drop');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from pickup point, heading to drop point');
|
||||
}
|
||||
|
@ -104,6 +107,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||
setPath(dropToPickup);
|
||||
setCurrentPhase('drop-pickup');
|
||||
setVehicleState(agvDetail.modelUuid, 'running');
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, true);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point');
|
||||
}
|
||||
|
@ -118,18 +122,21 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
|||
if (currentPhase === 'stationed-pickup') {
|
||||
setCurrentPhase('picking');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
setVehiclePicking(agvDetail.modelUuid, true);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Reached pickup point, waiting for material');
|
||||
setPath([]);
|
||||
} else if (currentPhase === 'pickup-drop') {
|
||||
setCurrentPhase('dropping');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
setVehiclePicking(agvDetail.modelUuid, false);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
vehicleStatus(agvDetail.modelUuid, 'Reached drop point');
|
||||
setPath([]);
|
||||
} else if (currentPhase === 'drop-pickup') {
|
||||
setCurrentPhase('picking');
|
||||
setVehicleState(agvDetail.modelUuid, 'idle');
|
||||
setVehiclePicking(agvDetail.modelUuid, true);
|
||||
setVehicleActive(agvDetail.modelUuid, false);
|
||||
setPath([]);
|
||||
clearCurrentMaterials(agvDetail.modelUuid)
|
||||
|
|
|
@ -13,6 +13,7 @@ interface VehiclesStore {
|
|||
clearvehicles: () => void;
|
||||
|
||||
setVehicleActive: (modelUuid: string, isActive: boolean) => void;
|
||||
setVehiclePicking: (modelUuid: string, isPicking: boolean) => void;
|
||||
updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void;
|
||||
incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void;
|
||||
decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void;
|
||||
|
@ -46,6 +47,7 @@ export const useVehicleStore = create<VehiclesStore>()(
|
|||
...event,
|
||||
productId,
|
||||
isActive: false,
|
||||
isPicking: false,
|
||||
idleTime: 0,
|
||||
activeTime: 0,
|
||||
currentLoad: 0,
|
||||
|
@ -89,6 +91,15 @@ export const useVehicleStore = create<VehiclesStore>()(
|
|||
});
|
||||
},
|
||||
|
||||
setVehiclePicking: (modelUuid, isPicking) => {
|
||||
set((state) => {
|
||||
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
|
||||
if (vehicle) {
|
||||
vehicle.isPicking = isPicking;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updateSteeringAngle: (modelUuid, steeringAngle) => {
|
||||
set((state) => {
|
||||
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
|
||||
|
|
|
@ -180,6 +180,7 @@ interface ArmBotStatus extends RoboticArmEventSchema {
|
|||
interface VehicleStatus extends VehicleEventSchema {
|
||||
productId: string;
|
||||
isActive: boolean;
|
||||
isPicking: boolean;
|
||||
idleTime: number;
|
||||
activeTime: number;
|
||||
currentLoad: number;
|
||||
|
|
Loading…
Reference in New Issue