added multiple actions for storage unit , and simulation bug fix
This commit is contained in:
@@ -44,35 +44,29 @@ export function useRetrieveHandler() {
|
||||
if (!modelUuid || !pointUuid) return null;
|
||||
const currentTime = performance.now();
|
||||
|
||||
if (action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid &&
|
||||
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid
|
||||
) {
|
||||
const newMaterial: MaterialSchema = {
|
||||
materialId: materialId,
|
||||
materialName: `${materialType}-${Date.now()}`,
|
||||
materialType: materialType,
|
||||
isActive: false,
|
||||
isVisible: false,
|
||||
isPaused: false,
|
||||
isRendered: true,
|
||||
startTime: currentTime,
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
};
|
||||
const newMaterial: MaterialSchema = {
|
||||
materialId: materialId,
|
||||
materialName: `${materialType}-${Date.now()}`,
|
||||
materialType: materialType,
|
||||
isActive: false,
|
||||
isVisible: false,
|
||||
isPaused: false,
|
||||
isRendered: true,
|
||||
startTime: currentTime,
|
||||
previous: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
current: {
|
||||
modelUuid: modelUuid,
|
||||
pointUuid: pointUuid,
|
||||
actionUuid: action.actionUuid
|
||||
},
|
||||
};
|
||||
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}
|
||||
return null;
|
||||
addMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}, [addMaterial, getModelUuidByActionUuid, getPointUuidByActionUuid, selectedProduct.productUuid]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -112,12 +106,16 @@ export function useRetrieveHandler() {
|
||||
getModelUuidByActionUuid(selectedProduct.productUuid, retrieval.action.actionUuid) ?? ''
|
||||
);
|
||||
|
||||
if (!storageUnit || storageUnit.currentLoad <= 0) {
|
||||
if (!storageUnit) {
|
||||
completedActions.push(actionUuid);
|
||||
hasChanges = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (storageUnit.currentLoad <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (retrieval.action.triggers.length === 0 || !retrieval.action.triggers[0]?.triggeredAsset) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ function PillarJibAnimator({
|
||||
if (crane.currentPhase === 'init-pickup') {
|
||||
if (crane.currentMaterials.length > 0) {
|
||||
const materials = scene.getObjectsByProperty('uuid', crane.currentMaterials[0].materialId);
|
||||
console.log('materials: ', materials);
|
||||
const material = materials.find((material) => material.visible === true);
|
||||
if (material) {
|
||||
const materialWorld = new THREE.Vector3();
|
||||
|
||||
@@ -35,17 +35,15 @@ function PillarJibInstance({ crane }: { crane: CraneStatus }) {
|
||||
if (!crane.isActive && crane.currentPhase === 'init' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length) {
|
||||
setCurrentPhase(crane.modelUuid, 'init-pickup');
|
||||
} else if (crane.currentPhase === 'picking' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && !crane.isCarrying) {
|
||||
if (action.triggers.length > 0) {
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === 'operator') {
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
setIsCaryying(crane.modelUuid, true);
|
||||
setCurrentPhase(crane.modelUuid, 'pickup-drop');
|
||||
} else {
|
||||
setCurrentPhaseHuman(humanId, 'hooking');
|
||||
setHumanActive(humanId, true);
|
||||
setHumanState(humanId, 'running');
|
||||
setCurrentAnimation(humanId, 'working_standing', true, false, false);
|
||||
}
|
||||
if (humanAsset?.animationState?.current === "working_standing" && humanAsset?.animationState?.isCompleted && humanId && humanAction && humanAction.actionType === 'operator') {
|
||||
setCurrentAnimation(humanId, 'idle', true, true, true);
|
||||
setIsCaryying(crane.modelUuid, true);
|
||||
setCurrentPhase(crane.modelUuid, 'pickup-drop');
|
||||
} else {
|
||||
setCurrentPhaseHuman(humanId, 'hooking');
|
||||
setHumanActive(humanId, true);
|
||||
setHumanState(humanId, 'running');
|
||||
setCurrentAnimation(humanId, 'working_standing', true, false, false);
|
||||
}
|
||||
} else if (crane.currentPhase === 'dropping' && crane.currentMaterials.length > 0 && action.maxPickUpCount <= crane.currentMaterials.length && crane.isCarrying && human.currentPhase === 'hooking') {
|
||||
setCurrentPhaseHuman(humanId, 'loadPoint-unloadPoint');
|
||||
|
||||
@@ -126,9 +126,11 @@ function OperatorInstance({ human }: { human: HumanStatus }) {
|
||||
humanStatus(human.modelUuid, 'Started from loadPoint, heading to unloadPoint');
|
||||
}
|
||||
} else if (human.state === 'idle' && human.currentPhase === 'unhooking') {
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, false, false);
|
||||
setTimeout(() => {
|
||||
setHumanState(human.modelUuid, 'running');
|
||||
setHumanActive(human.modelUuid, true);
|
||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, false, false);
|
||||
}, 1)
|
||||
}
|
||||
} else {
|
||||
reset()
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
|
||||
|
||||
export function determineExecutionOrder(products: productsSchema): PointsScheme[] {
|
||||
export function determineExecutionOrder(products: productsSchema): Action[] {
|
||||
// Create maps for all events and points
|
||||
const eventMap = new Map<string, EventsSchema>();
|
||||
const pointMap = new Map<string, PointsScheme>();
|
||||
const allPoints: PointsScheme[] = [];
|
||||
const spawnActions: Action[] = [];
|
||||
|
||||
// First pass: collect all points
|
||||
// First pass: collect all points and identify spawn actions
|
||||
products.forEach(product => {
|
||||
product.eventDatas.forEach(event => {
|
||||
eventMap.set(event.modelUuid, event);
|
||||
@@ -15,6 +16,11 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
event.points.forEach(point => {
|
||||
pointMap.set(point.uuid, point);
|
||||
allPoints.push(point);
|
||||
|
||||
// Check for spawn actions in conveyors
|
||||
if (point.action.actionType === 'spawn') {
|
||||
spawnActions.push(point.action);
|
||||
}
|
||||
});
|
||||
} else if (event.type === 'vehicle' ||
|
||||
event.type === 'machine' ||
|
||||
@@ -25,6 +31,16 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
) {
|
||||
pointMap.set(event.point.uuid, event.point);
|
||||
allPoints.push(event.point);
|
||||
|
||||
// Check for spawn actions in storage units and other types
|
||||
if (event.type === 'storageUnit') {
|
||||
const storagePoint = event.point as StoragePointSchema;
|
||||
storagePoint.actions.forEach(action => {
|
||||
if (action.actionType === 'retrieve') {
|
||||
spawnActions.push(action);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -33,11 +49,19 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
const graph = new Map<string, string[]>();
|
||||
const reverseGraph = new Map<string, string[]>();
|
||||
const allTriggeredPoints = new Set<string>();
|
||||
const actionMap = new Map<string, Action>(); // Map point UUID to its primary action
|
||||
|
||||
allPoints.forEach(point => {
|
||||
const triggers = extractTriggersFromPoint(point);
|
||||
const dependencies: string[] = [];
|
||||
|
||||
// Store the primary action for this point
|
||||
if ('action' in point) {
|
||||
actionMap.set(point.uuid, point.action);
|
||||
} else if ('actions' in point && point.actions.length > 0) {
|
||||
actionMap.set(point.uuid, point.actions[0]); // Use first action as primary
|
||||
}
|
||||
|
||||
triggers.forEach(trigger => {
|
||||
const targetUuid = trigger.triggeredAsset?.triggeredPoint?.pointUuid;
|
||||
if (targetUuid && pointMap.has(targetUuid)) {
|
||||
@@ -58,15 +82,12 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
const rootPoints = allPoints
|
||||
.filter(point => !allTriggeredPoints.has(point.uuid))
|
||||
.filter(point => {
|
||||
// Only include roots that actually have triggers pointing FROM them
|
||||
const triggers = extractTriggersFromPoint(point);
|
||||
return triggers.some(t => t.triggeredAsset?.triggeredPoint?.pointUuid);
|
||||
});
|
||||
|
||||
// If no root points found but we have triggered points, find the earliest triggers
|
||||
if (rootPoints.length === 0 && allTriggeredPoints.size > 0) {
|
||||
// This handles cases where we have circular dependencies
|
||||
// but still want to include the triggered points
|
||||
const minTriggerCount = Math.min(
|
||||
...Array.from(allTriggeredPoints)
|
||||
.map(uuid => (graph.get(uuid) || []).length)
|
||||
@@ -105,11 +126,18 @@ export function determineExecutionOrder(products: productsSchema): PointsScheme[
|
||||
// Start processing from root points
|
||||
rootPoints.forEach(root => visit(root.uuid));
|
||||
|
||||
// Convert UUIDs back to points and filter out untriggered points
|
||||
const triggeredPoints = order
|
||||
.map(uuid => pointMap.get(uuid)!)
|
||||
.filter(point => allTriggeredPoints.has(point.uuid) ||
|
||||
rootPoints.some(root => root.uuid === point.uuid));
|
||||
// Convert UUIDs back to actions
|
||||
const triggeredActions = order
|
||||
.map(uuid => actionMap.get(uuid))
|
||||
.filter((action): action is Action => action !== undefined);
|
||||
|
||||
return triggeredPoints;
|
||||
// Combine triggered actions with ALL spawn actions
|
||||
const allExecutionActions = [...triggeredActions, ...spawnActions];
|
||||
|
||||
// Remove duplicate actions while preserving order
|
||||
const uniqueActions = allExecutionActions.filter((action, index, array) =>
|
||||
array.findIndex(a => a.actionUuid === action.actionUuid) === index
|
||||
);
|
||||
|
||||
return uniqueActions;
|
||||
}
|
||||
@@ -21,12 +21,13 @@ function Simulator() {
|
||||
if (!product) return;
|
||||
|
||||
const executionOrder = determineExecutionOrder([product]);
|
||||
executionOrder.forEach(point => {
|
||||
const action = 'actions' in point ? point.actions[0] : point.action;
|
||||
|
||||
executionOrder.forEach(action => {
|
||||
handleAction(action);
|
||||
});
|
||||
}, [products, isPlaying, isReset, selectedProduct]);
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<>
|
||||
|
||||
@@ -106,6 +106,7 @@ export function useTriggerHandler() {
|
||||
|
||||
// Handle current action using Event Manager
|
||||
addVehicleToMonitor(vehicle.modelUuid, () => {
|
||||
setIsVisible(materialId, false);
|
||||
handleAction(action, materialId);
|
||||
})
|
||||
}
|
||||
@@ -392,7 +393,7 @@ export function useTriggerHandler() {
|
||||
}
|
||||
}
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Transfer to Human
|
||||
// Transfer to Crane
|
||||
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
|
||||
const material = getMaterialById(materialId);
|
||||
if (material) {
|
||||
@@ -622,7 +623,7 @@ export function useTriggerHandler() {
|
||||
}
|
||||
}
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Vehicle to Human
|
||||
// Vehicle to Crane
|
||||
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
|
||||
const material = getMaterialById(materialId);
|
||||
if (material) {
|
||||
@@ -1801,25 +1802,25 @@ export function useTriggerHandler() {
|
||||
}
|
||||
} else if (fromEvent?.type === 'crane') {
|
||||
if (toEvent?.type === 'transfer') {
|
||||
// Crane Unit to Transfer
|
||||
// Crane to Transfer
|
||||
|
||||
} else if (toEvent?.type === 'vehicle') {
|
||||
// Crane Unit to Vehicle
|
||||
// Crane to Vehicle
|
||||
|
||||
} else if (toEvent?.type === 'machine') {
|
||||
// Crane Unit to Machine
|
||||
// Crane to Machine
|
||||
|
||||
} else if (toEvent?.type === 'roboticArm') {
|
||||
// Crane Unit to Robotic Arm
|
||||
// Crane to Robotic Arm
|
||||
|
||||
} else if (toEvent?.type === 'storageUnit') {
|
||||
// Crane Unit to Storage Unit
|
||||
// Crane to Storage Unit
|
||||
|
||||
} else if (toEvent?.type === 'human') {
|
||||
// Crane Unit to Human
|
||||
// Crane to Human
|
||||
|
||||
} else if (toEvent?.type === 'crane') {
|
||||
// Crane Unit to Human
|
||||
// Crane to Human
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,8 +378,10 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
const human = getHumanById(humanId);
|
||||
const humanAction = human?.point.actions.find((action) => action.actionUuid === humanActionId);
|
||||
if (human && human.currentAction?.actionUuid !== humanActionId && human.currentLoad < (humanAction?.loadCapacity || 0)) {
|
||||
addCurrentAction(humanId, humanActionId);
|
||||
if (human && human.currentLoad < (humanAction?.loadCapacity || 0)) {
|
||||
if (human.currentAction?.actionUuid !== humanActionId) {
|
||||
addCurrentAction(humanId, humanActionId);
|
||||
}
|
||||
setTimeout(() => {
|
||||
unloadLoop();
|
||||
}, 500)
|
||||
|
||||
Reference in New Issue
Block a user