Enhance machine and robotic arm interactions: update action handling, integrate material management, and improve state management across components.
This commit is contained in:
@@ -72,6 +72,15 @@ function MachineMechanics() {
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productId,
|
||||
organization,
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleProcessTimeChange = (value: string) => {
|
||||
@@ -79,6 +88,15 @@ function MachineMechanics() {
|
||||
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||
processTime: parseFloat(value),
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productId,
|
||||
organization,
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
@@ -86,6 +104,15 @@ function MachineMechanics() {
|
||||
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||
swapMaterial: material,
|
||||
});
|
||||
|
||||
if (event) {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productId,
|
||||
organization,
|
||||
event
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
|
||||
@@ -140,11 +140,10 @@ const Simulations: React.FC = () => {
|
||||
{products.map((product, index) => (
|
||||
<div
|
||||
key={product.productId}
|
||||
className={`list-item ${
|
||||
selectedProduct.productId === product.productId
|
||||
className={`list-item ${selectedProduct.productId === product.productId
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
{/* eslint-disable-next-line */}
|
||||
<div
|
||||
|
||||
@@ -229,6 +229,6 @@ export function useSpawnHandler() {
|
||||
|
||||
return {
|
||||
handleSpawn,
|
||||
clearCurrentSpawn: clearAllSpawns
|
||||
clearAllSpawns
|
||||
};
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { useDespawnHandler } from "./actionHandler/useDespawnHandler";
|
||||
|
||||
export function useConveyorActions() {
|
||||
const { handleDefault } = useDefaultHandler();
|
||||
const { handleSpawn, clearCurrentSpawn } = useSpawnHandler();
|
||||
const { handleSpawn, clearAllSpawns } = useSpawnHandler();
|
||||
const { handleSwap } = useSwapHandler();
|
||||
const { handleDespawn } = useDespawnHandler();
|
||||
const { handleDelay, cleanupDelay } = useDelayHandler();
|
||||
@@ -57,9 +57,9 @@ export function useConveyorActions() {
|
||||
}, [handleDefaultAction, handleSpawnAction, handleSwapAction, handleDelayAction, handleDespawnAction]);
|
||||
|
||||
const cleanup = useCallback(() => {
|
||||
clearCurrentSpawn();
|
||||
clearAllSpawns();
|
||||
cleanupDelay();
|
||||
}, [clearCurrentSpawn, cleanupDelay]);
|
||||
}, [clearAllSpawns, cleanupDelay]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { useCallback } from "react";
|
||||
import { useMaterialStore } from "../../../../../store/simulation/useMaterialStore";
|
||||
import { useMachineStore } from "../../../../../store/simulation/useMachineStore";
|
||||
import { useProductStore } from "../../../../../store/simulation/useProductStore";
|
||||
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
|
||||
|
||||
export function useProcessHandler() {
|
||||
const { getMaterialById, setMaterial } = useMaterialStore();
|
||||
const { addCurrentAction } = useMachineStore();
|
||||
const { getModelUuidByActionUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
const processLogStatus = (materialUuid: string, status: string) => {
|
||||
// console.log(`${materialUuid}, ${status}`);
|
||||
}
|
||||
|
||||
const handleProcess = useCallback((action: MachineAction, materialId?: string) => {
|
||||
if (!action || action.actionType !== 'process' || !materialId) return;
|
||||
|
||||
const { swapMaterial: newMaterialType } = action;
|
||||
|
||||
const material = getMaterialById(materialId);
|
||||
if (!material) return;
|
||||
|
||||
const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid);
|
||||
|
||||
if (!modelUuid) return;
|
||||
setMaterial(material.materialId, newMaterialType);
|
||||
|
||||
addCurrentAction(modelUuid, action.actionUuid, newMaterialType, material.materialId);
|
||||
|
||||
processLogStatus(material.materialId, `Swapped to ${newMaterialType}`);
|
||||
processLogStatus(material.materialId, `starts Process action`);
|
||||
|
||||
}, [getMaterialById]);
|
||||
|
||||
return {
|
||||
handleProcess
|
||||
};
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
import { useEffect, useCallback, useRef, useState } from 'react';
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { useProcessHandler } from './actionHandler/useProcessHandler';
|
||||
|
||||
export function useMachineActions() {
|
||||
const { handleProcess } = useProcessHandler();
|
||||
|
||||
const handleProcessAction = useCallback((action: MachineAction) => {
|
||||
if (!action || action.actionType !== 'process') return;
|
||||
console.log(`Machine processing for ${action.processTime}ms`);
|
||||
}, []);
|
||||
const handleProcessAction = useCallback((action: MachineAction, materialId: string) => {
|
||||
handleProcess(action, materialId);
|
||||
}, [handleProcess]);
|
||||
|
||||
const handleMachineAction = useCallback((action: MachineAction) => {
|
||||
const handleMachineAction = useCallback((action: MachineAction, materialId: string) => {
|
||||
if (!action) return;
|
||||
|
||||
switch (action.actionType) {
|
||||
case 'process':
|
||||
handleProcessAction(action);
|
||||
handleProcessAction(action, materialId);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown machine action type: ${action.actionType}`);
|
||||
|
||||
@@ -31,7 +31,7 @@ export function usePickAndPlaceHandler() {
|
||||
material.materialId
|
||||
);
|
||||
|
||||
pickAndPlaceLogStatus(material.materialId, `if going to be picked by armBot ${modelUuid}`);
|
||||
pickAndPlaceLogStatus(material.materialId, `is going to be picked by armBot ${modelUuid}`);
|
||||
|
||||
}, [getMaterialById, getModelUuidByActionUuid, addCurrentAction]);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
usePlayButtonStore,
|
||||
useResetButtonStore,
|
||||
usePlayButtonStore,
|
||||
useResetButtonStore,
|
||||
} from "../../../store/usePlayButtonStore";
|
||||
import { useConveyorActions } from "./conveyor/useConveyorActions";
|
||||
import { useMachineActions } from "./machine/useMachineActions";
|
||||
@@ -10,75 +10,61 @@ import { useVehicleActions } from "./vehicle/useVehicleActions";
|
||||
import { useCallback, useEffect } from "react";
|
||||
|
||||
export function useActionHandler() {
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { handleConveyorAction, cleanup: cleanupConveyor } =
|
||||
useConveyorActions();
|
||||
const { handleVehicleAction, cleanup: cleanupVehicle } = useVehicleActions();
|
||||
const { handleRoboticArmAction, cleanup: cleanupRoboticArm } =
|
||||
useRoboticArmActions();
|
||||
const { handleMachineAction, cleanup: cleanupMachine } = useMachineActions();
|
||||
const { handleStorageAction, cleanup: cleanupStorage } = useStorageActions();
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { handleConveyorAction, cleanup: cleanupConveyor } = useConveyorActions();
|
||||
const { handleVehicleAction, cleanup: cleanupVehicle } = useVehicleActions();
|
||||
const { handleRoboticArmAction, cleanup: cleanupRoboticArm } = useRoboticArmActions();
|
||||
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);
|
||||
break;
|
||||
case 'store':
|
||||
handleStorageAction(action as StorageAction);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown action type: ${(action as Action).actionType}`);
|
||||
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':
|
||||
handleStorageAction(action as StorageAction);
|
||||
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);
|
||||
}
|
||||
} catch (error) {
|
||||
echo.error("Failed to handle action");
|
||||
console.error("Error handling action:", error);
|
||||
}
|
||||
},
|
||||
[
|
||||
handleConveyorAction,
|
||||
handleVehicleAction,
|
||||
handleRoboticArmAction,
|
||||
handleMachineAction,
|
||||
handleStorageAction,
|
||||
]
|
||||
);
|
||||
},
|
||||
[handleConveyorAction, handleVehicleAction, handleRoboticArmAction, handleMachineAction, handleStorageAction,]
|
||||
);
|
||||
|
||||
const cleanup = useCallback(() => {
|
||||
cleanupConveyor();
|
||||
cleanupVehicle();
|
||||
cleanupRoboticArm();
|
||||
cleanupMachine();
|
||||
cleanupStorage();
|
||||
}, [
|
||||
cleanupConveyor,
|
||||
cleanupVehicle,
|
||||
cleanupRoboticArm,
|
||||
cleanupMachine,
|
||||
cleanupStorage,
|
||||
]);
|
||||
const cleanup = useCallback(() => {
|
||||
cleanupConveyor();
|
||||
cleanupVehicle();
|
||||
cleanupRoboticArm();
|
||||
cleanupMachine();
|
||||
cleanupStorage();
|
||||
}, [cleanupConveyor, cleanupVehicle, cleanupRoboticArm, cleanupMachine, cleanupStorage,]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
cleanup();
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
cleanup();
|
||||
};
|
||||
}, [cleanup, isReset, isPlaying]);
|
||||
|
||||
return {
|
||||
handleAction,
|
||||
cleanup,
|
||||
};
|
||||
}, [cleanup, isReset, isPlaying]);
|
||||
|
||||
return {
|
||||
handleAction,
|
||||
cleanup,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useMachineStore } from '../../../../../store/simulation/useMachineStore';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
|
||||
@@ -21,22 +20,19 @@ const MachineAnimator = ({ currentPhase, handleCallBack, processingTime, machine
|
||||
const pauseTimeRef = useRef<number | null>(null);
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { removeCurrentAction } = useMachineStore();
|
||||
const { isReset, setReset } = useResetButtonStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const isPlayingRef = useRef<boolean>(false);
|
||||
const isResetRef = useRef<boolean>(false)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
isPausedRef.current = isPaused;
|
||||
}, [isPaused]);
|
||||
|
||||
useEffect(() => {
|
||||
isPlayingRef.current = isPlaying;
|
||||
}, [isPlaying]);
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isReset || !isPlaying) {
|
||||
reset();
|
||||
@@ -49,8 +45,6 @@ const MachineAnimator = ({ currentPhase, handleCallBack, processingTime, machine
|
||||
}
|
||||
}, [isReset, isPlaying])
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (currentPhase === 'processing' && !animationStarted.current && machineUuid) {
|
||||
animationStarted.current = true;
|
||||
@@ -94,8 +88,6 @@ const MachineAnimator = ({ currentPhase, handleCallBack, processingTime, machine
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useMachineStore } from '../../../../../store/simulation/useMachineStore';
|
||||
import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
import MachineAnimator from '../animator/machineAnimator';
|
||||
import { useProductStore } from '../../../../../store/simulation/useProductStore';
|
||||
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
|
||||
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
||||
|
||||
function MachineInstance({ machineDetail }: any) {
|
||||
function MachineInstance({ machineDetail }: { machineDetail: MachineStatus }) {
|
||||
const [currentPhase, setCurrentPhase] = useState<string>('idle');
|
||||
let isIncrememtable = useRef<boolean>(true);
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { machines, addCurrentAction, setMachineState, setMachineActive } = useMachineStore();
|
||||
const { machines, setMachineState, setMachineActive } = useMachineStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { getActionByUuid } = useProductStore();
|
||||
const { triggerPointActions } = useTriggerHandler();
|
||||
|
||||
const reset = () => {
|
||||
setCurrentPhase("idle");
|
||||
@@ -15,23 +21,14 @@ function MachineInstance({ machineDetail }: any) {
|
||||
setMachineActive(machineDetail.modelUuid, false);
|
||||
isIncrememtable.current = true;
|
||||
}
|
||||
const increment = () => {
|
||||
if (isIncrememtable.current) {
|
||||
addCurrentAction(machineDetail.modelUuid, "machine-action-2468-1357-8024")
|
||||
isIncrememtable.current = false;
|
||||
}
|
||||
}
|
||||
|
||||
function machineStatus(modelId: string, status: string) {
|
||||
// console.log(`${modelId} , ${status}`);
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && !machineDetail.currentAction) {
|
||||
setTimeout(() => {
|
||||
increment();
|
||||
}, 5000);
|
||||
machineStatus(machineDetail.modelUuid, 'Machine is idle and waiting for next instruction.')
|
||||
} else if (!machineDetail.isActive && machineDetail.state === "idle" && currentPhase == "idle" && machineDetail.currentAction) {
|
||||
setCurrentPhase("processing");
|
||||
@@ -49,11 +46,15 @@ function MachineInstance({ machineDetail }: any) {
|
||||
setCurrentPhase("idle")
|
||||
isIncrememtable.current = true;
|
||||
machineStatus(machineDetail.modelUuid, "Machine has completed the processing")
|
||||
|
||||
if (machineDetail.currentAction) {
|
||||
const action = getActionByUuid(selectedProduct.productId, machineDetail.currentAction.actionUuid);
|
||||
if (action && machineDetail.currentAction.materialId) {
|
||||
triggerPointActions(action, machineDetail.currentAction.materialId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log('currentPhase: ', currentPhase);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,48 +1,6 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import MachineInstances from './instances/machineInstances'
|
||||
import { useMachineStore } from '../../../store/simulation/useMachineStore'
|
||||
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore';
|
||||
|
||||
function Machine() {
|
||||
const { addMachine, addCurrentAction, removeMachine, machines } = useMachineStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
const machineSample: MachineEventSchema[] = [
|
||||
{
|
||||
modelUuid: "machine-1234-5678-9012",
|
||||
modelName: "CNC Milling Machine",
|
||||
position: [10, 0, 5],
|
||||
rotation: [0, 0, 0],
|
||||
state: "idle",
|
||||
type: "machine",
|
||||
point: {
|
||||
uuid: "machine-point-9876-5432-1098",
|
||||
position: [10, 0.5, 5.2],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: "machine-action-2468-1357-8024",
|
||||
actionName: "Metal Processing",
|
||||
actionType: "process",
|
||||
processTime: 10,
|
||||
swapMaterial: "steel",
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
removeMachine(machineSample[0].modelUuid);
|
||||
addMachine(selectedProduct.productId, machineSample[0]);
|
||||
|
||||
// addCurrentAction(machineSample[0].modelUuid, machineSample[0].point.action.actionUuid);
|
||||
}, [])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
// console.log('machines: ', machines);
|
||||
}, [machines])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getAllProductsApi } from '../../../services/simulation/getallProductsAp
|
||||
import { useVehicleStore } from '../../../store/simulation/useVehicleStore';
|
||||
import { useArmBotStore } from '../../../store/simulation/useArmBotStore';
|
||||
import { useConveyorStore } from '../../../store/simulation/useConveyorStore';
|
||||
import { useMachineStore } from '../../../store/simulation/useMachineStore';
|
||||
import { useResetButtonStore } from '../../../store/usePlayButtonStore';
|
||||
|
||||
function Products() {
|
||||
@@ -15,6 +16,7 @@ function Products() {
|
||||
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
|
||||
const { addVehicle, clearvehicles } = useVehicleStore();
|
||||
const { addArmBot, clearArmBots } = useArmBotStore();
|
||||
const { addMachine, clearMachines } = useMachineStore();
|
||||
const { addConveyor, clearConveyors } = useConveyorStore();
|
||||
const { isReset } = useResetButtonStore();
|
||||
|
||||
@@ -77,6 +79,20 @@ function Products() {
|
||||
}
|
||||
}, [selectedProduct, products, isReset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedProduct.productId) {
|
||||
const product = getProductById(selectedProduct.productId);
|
||||
if (product) {
|
||||
clearMachines();
|
||||
product.eventDatas.forEach(events => {
|
||||
if (events.type === 'machine') {
|
||||
addMachine(selectedProduct.productId, events);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, products, isReset]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
|
||||
@@ -186,12 +186,13 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
new THREE.Vector3(end[0], curveHeight, end[2]),
|
||||
new THREE.Vector3(end[0], end[1], end[2])
|
||||
];
|
||||
|
||||
|
||||
const pathSegments: [THREE.Vector3, THREE.Vector3][] = [];
|
||||
for (let i = 0; i < pathVectors.length - 1; i++) {
|
||||
pathSegments.push([pathVectors[i], pathVectors[i + 1]]);
|
||||
}
|
||||
|
||||
console.log('pathVectors: ', pathVectors.length, pathSegments.length);
|
||||
|
||||
const segmentDistances = pathSegments.map(([p1, p2]) => p1.distanceTo(p2));
|
||||
segmentDistancesRef.current = segmentDistances;
|
||||
const totalDistance = segmentDistances.reduce((sum, d) => sum + d, 0);
|
||||
@@ -209,11 +210,6 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
|
||||
if (!bone) return;
|
||||
if (isPlaying) {
|
||||
if (isReset) {
|
||||
bone.position.copy(restPosition);
|
||||
setCustomCurvePoints([]);
|
||||
ikSolver.update();
|
||||
}
|
||||
if (!isPaused && customCurvePoints && customCurvePoints.length > 0) {
|
||||
const distances = segmentDistancesRef.current;
|
||||
const totalDistance = totalDistanceRef.current;
|
||||
@@ -248,7 +244,6 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
progressRef.current = 0;
|
||||
startTimeRef.current = null;
|
||||
}
|
||||
|
||||
ikSolver.update();
|
||||
}
|
||||
} else if (!isPlaying && currentPath.length === 0) {
|
||||
@@ -257,16 +252,15 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
|
||||
setCurrentPath([]);
|
||||
setCustomCurvePoints([]);
|
||||
bone.position.copy(restPosition);
|
||||
|
||||
ikSolver.update();
|
||||
}
|
||||
ikSolver.update();
|
||||
});
|
||||
|
||||
//Helper to Visible the Circle and Curve
|
||||
return (
|
||||
<>
|
||||
{customCurvePoints && customCurvePoints?.length >= 2 && currentPath && isPlaying && (
|
||||
<mesh rotation={armBot.rotation} position={armBot.position} visible={false}>
|
||||
<mesh rotation={armBot.rotation} position={armBot.position} visible={true}>
|
||||
<Line
|
||||
points={customCurvePoints.map((p) => [p.x, p.y, p.z] as [number, number, number])}
|
||||
color="green"
|
||||
|
||||
@@ -41,6 +41,33 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
step();
|
||||
}
|
||||
|
||||
const action = getActionByUuid(selectedProduct.productId, armBot.currentAction?.actionUuid || '');
|
||||
|
||||
const handleTrigger = () => {
|
||||
if (armBot.currentAction && armBot.currentAction.materialId) {
|
||||
const material = getMaterialById(armBot.currentAction.materialId);
|
||||
if (material && material.previous && material.previous.modelUuid) {
|
||||
const model = getEventByModelUuid(selectedProduct.productId, material.previous.modelUuid);
|
||||
if (model) {
|
||||
if (model.type === 'transfer') {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
} else if (model.type === 'machine') {
|
||||
// machine specific logic
|
||||
} else if (model.type === 'vehicle') {
|
||||
decrementVehicleLoad(model.modelUuid, 1);
|
||||
removeLastMaterial(model.modelUuid);
|
||||
} else if (model.type === 'storageUnit') {
|
||||
// storage unit logic
|
||||
}
|
||||
} else {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
}
|
||||
} else {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function step() {
|
||||
if (isPausedRef.current) {
|
||||
if (!pauseTimeRef.current) {
|
||||
@@ -65,8 +92,9 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("start-to-end");
|
||||
startTime = 0
|
||||
const startPoint = armBot.point.actions[0].process.startPoint;
|
||||
const endPoint = armBot.point.actions[0].process.endPoint;
|
||||
if (!action) return;
|
||||
const startPoint = (action as RoboticArmAction).process.startPoint;
|
||||
const endPoint = (action as RoboticArmAction).process.endPoint;
|
||||
if (startPoint && endPoint) {
|
||||
let curve = createCurveBetweenTwoPoints(
|
||||
new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]),
|
||||
@@ -75,30 +103,8 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
logStatus(armBot.modelUuid, "picking the object");
|
||||
setPath(curve.points.map(point => [point.x, point.y, point.z]))
|
||||
|
||||
if (armBot.currentAction && armBot.currentAction.materialId) {
|
||||
const material = getMaterialById(armBot.currentAction.materialId)
|
||||
if (material && material.previous && material.previous.modelUuid) {
|
||||
handleTrigger();
|
||||
|
||||
const model = getEventByModelUuid(selectedProduct.productId, material.previous.modelUuid);
|
||||
|
||||
if (model) {
|
||||
if (model.type === 'transfer') {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
} else if (model.type === 'machine') {
|
||||
|
||||
} else if (model.type === 'vehicle') {
|
||||
decrementVehicleLoad(model.modelUuid, 1);
|
||||
removeLastMaterial(model.modelUuid);
|
||||
} else if (model.type === 'storageUnit') {
|
||||
|
||||
}
|
||||
} else {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
}
|
||||
} else {
|
||||
setIsVisible(armBot.currentAction.materialId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logStatus(armBot.modelUuid, "Moving armBot from start point to end position.")
|
||||
@@ -107,7 +113,8 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("end-to-rest");
|
||||
startTime = 0;
|
||||
const endPoint = armBot.point.actions[0].process.endPoint;
|
||||
if (!action) return;
|
||||
const endPoint = (action as RoboticArmAction).process.endPoint;
|
||||
if (endPoint) {
|
||||
|
||||
let curve = createCurveBetweenTwoPoints(new THREE.Vector3(endPoint[0], endPoint[1], endPoint[2]), restPosition);
|
||||
@@ -190,7 +197,8 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
setArmBotActive(armBot.modelUuid, true);
|
||||
setArmBotState(armBot.modelUuid, "running");
|
||||
setCurrentPhase("rest-to-start");
|
||||
const startPoint = armBot.point.actions[0].process.startPoint;
|
||||
if (!action) return;
|
||||
const startPoint = (action as RoboticArmAction).process.startPoint;
|
||||
if (startPoint) {
|
||||
let curve = createCurveBetweenTwoPoints(targetBones.position, new THREE.Vector3(startPoint[0], startPoint[1], startPoint[2]));
|
||||
if (curve) {
|
||||
@@ -232,6 +240,7 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
}
|
||||
|
||||
const HandleCallback = () => {
|
||||
|
||||
if (armBot.isActive && armBot.state == "running" && currentPhase == "init-to-rest") {
|
||||
logStatus(armBot.modelUuid, "Callback triggered: rest");
|
||||
setArmBotActive(armBot.modelUuid, false)
|
||||
@@ -262,6 +271,7 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
}
|
||||
}
|
||||
const logStatus = (id: string, status: string) => {
|
||||
// console.log('status: ', status);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -269,8 +279,16 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) {
|
||||
{!isReset && isPlaying && (
|
||||
<>
|
||||
<IKInstance modelUrl={armModel} setIkSolver={setIkSolver} ikSolver={ikSolver} armBot={armBot} groupRef={groupRef} />
|
||||
<RoboticArmAnimator HandleCallback={HandleCallback} restPosition={restPosition} ikSolver={ikSolver} targetBone={targetBone} armBot={armBot}
|
||||
logStatus={logStatus} path={path} currentPhase={currentPhase} />
|
||||
<RoboticArmAnimator
|
||||
HandleCallback={HandleCallback}
|
||||
restPosition={restPosition}
|
||||
ikSolver={ikSolver}
|
||||
targetBone={targetBone}
|
||||
armBot={armBot}
|
||||
logStatus={logStatus}
|
||||
path={path}
|
||||
currentPhase={currentPhase}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<MaterialAnimator ikSolver={ikSolver} armBot={armBot} currentPhase={currentPhase} />
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useSelectedProduct } from '../../../../store/simulation/useSimulationSt
|
||||
import { useMaterialStore } from '../../../../store/simulation/useMaterialStore';
|
||||
import { useArmBotStore } from '../../../../store/simulation/useArmBotStore';
|
||||
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
|
||||
import { useMachineStore } from '../../../../store/simulation/useMachineStore';
|
||||
|
||||
export function useTriggerHandler() {
|
||||
const { handleAction } = useActionHandler();
|
||||
@@ -12,6 +13,7 @@ export function useTriggerHandler() {
|
||||
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
|
||||
const { getArmBotById } = useArmBotStore();
|
||||
const { getVehicleById } = useVehicleStore();
|
||||
const { getMachineById } = useMachineStore();
|
||||
const { setCurrentLocation, setNextLocation, setPreviousLocation, getMaterialById, setIsPaused, setIsVisible, setEndTime } = useMaterialStore();
|
||||
|
||||
const handleTrigger = (trigger: TriggerSchema, action: Action, materialId?: string) => {
|
||||
@@ -252,6 +254,46 @@ export function useTriggerHandler() {
|
||||
|
||||
} else if (toEvent?.type === 'roboticArm') {
|
||||
// Machine to Robotic Arm
|
||||
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 armBot = getArmBotById(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 && armBot &&
|
||||
action.triggers[0].triggeredAsset?.triggeredModel.modelUuid &&
|
||||
action.triggers[0].triggeredAsset?.triggeredPoint?.pointUuid
|
||||
) {
|
||||
|
||||
if (armBot.isActive === false && armBot.state === 'idle') {
|
||||
|
||||
// Handle current action from arm bot
|
||||
handleAction(action, materialId);
|
||||
|
||||
} else {
|
||||
|
||||
// Event Manager Needed
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (toEvent?.type === 'storageUnit') {
|
||||
// Machine to Storage Unit
|
||||
@@ -395,6 +437,49 @@ export function useTriggerHandler() {
|
||||
} else if (toEvent?.type === 'machine') {
|
||||
// Robotic Arm to Machine
|
||||
|
||||
if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) {
|
||||
const material = getMaterialById(materialId);
|
||||
if (material) {
|
||||
|
||||
setIsPaused(material.materialId, false);
|
||||
|
||||
const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid);
|
||||
const machine = getMachineById(trigger.triggeredAsset?.triggeredModel.modelUuid);
|
||||
setNextLocation(material.materialId, null);
|
||||
|
||||
if (action) {
|
||||
|
||||
if (machine) {
|
||||
|
||||
if (machine.isActive === false && machine.state === 'idle') {
|
||||
|
||||
setIsVisible(materialId, false);
|
||||
|
||||
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,
|
||||
});
|
||||
|
||||
// Handle current action from machine
|
||||
handleAction(action, materialId);
|
||||
|
||||
} else {
|
||||
|
||||
// Event Manager Needed
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (toEvent?.type === 'roboticArm') {
|
||||
// Robotic Arm to Robotic Arm
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ export const useArmBotStore = create<ArmBotStore>()(
|
||||
actionUuid: action.actionUuid,
|
||||
actionName: action.actionName,
|
||||
materialType: materialType,
|
||||
materialId:materialId
|
||||
materialId: materialId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ interface MachineStore {
|
||||
) => void;
|
||||
clearMachines: () => void;
|
||||
|
||||
addCurrentAction: (modelUuid: string, actionUuid: string) => void;
|
||||
addCurrentAction: (modelUuid: string, actionUuid: string, materialType: string, materialId: string) => void;
|
||||
removeCurrentAction: (modelUuid: string) => void;
|
||||
|
||||
setMachineActive: (modelUuid: string, isActive: boolean) => void;
|
||||
@@ -69,16 +69,17 @@ export const useMachineStore = create<MachineStore>()(
|
||||
});
|
||||
},
|
||||
|
||||
addCurrentAction: (modelUuid) => {
|
||||
addCurrentAction: (modelUuid, actionUuid, materialType, materialId) => {
|
||||
set((state) => {
|
||||
const armBot = state.machines.find(a => a.modelUuid === modelUuid);
|
||||
if (armBot) {
|
||||
const action = armBot.point.action;
|
||||
if (action) {
|
||||
armBot.currentAction = {
|
||||
actionUuid: action.actionUuid,
|
||||
actionUuid: actionUuid,
|
||||
actionName: action.actionName,
|
||||
materialType: null
|
||||
materialType: materialType,
|
||||
materialId: materialId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
1
app/src/types/simulationTypes.d.ts
vendored
1
app/src/types/simulationTypes.d.ts
vendored
@@ -159,6 +159,7 @@ interface MachineStatus extends MachineEventSchema {
|
||||
actionUuid: string;
|
||||
actionName: string;
|
||||
materialType: string | null;
|
||||
materialId: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user