feat: Enhance ArmBotState with connections and isActive properties
- Updated ArmBotState interface across multiple files to include connections (source and targets) and isActive properties. - Implemented logic in ProcessAnimator to check if processes are connected to active ArmBots, preventing future spawns if connected. - Adjusted animation state handling to account for active ArmBots, stopping animations and resetting states as necessary. - Refactored related functions for better clarity and maintainability.
This commit is contained in:
parent
5c24d7ca71
commit
e0082cb55a
|
@ -12,7 +12,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
|
@ -45,7 +50,8 @@ const ArmBot = ({ armBots, setArmBots, setStaticMachines }: ArmBotProps) => {
|
|||
status: "idle",
|
||||
material: "default",
|
||||
triggerId: '',
|
||||
actions: bot.points.actions
|
||||
actions: bot.points.actions,
|
||||
connections: bot.points.connections
|
||||
}));
|
||||
setArmBots(initialStates);
|
||||
}, [simulationStates]);
|
||||
|
|
|
@ -18,16 +18,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: {
|
||||
triggerId: string;
|
||||
startPoint: string;
|
||||
endPoint: string;
|
||||
}[];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
|
@ -87,6 +83,7 @@ export const ArmbotInstances: React.FC<ArmbotInstancesProps> = ({ index, armBot,
|
|||
rotation={armBot.rotation}
|
||||
processes={processes}
|
||||
armBot={armBot}
|
||||
setArmBots={setArmBots}
|
||||
setStaticMachines={setStaticMachines}
|
||||
updateArmBotStatus={updateArmBotStatus}
|
||||
/>
|
||||
|
|
|
@ -20,16 +20,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: {
|
||||
triggerId: string;
|
||||
startPoint: string;
|
||||
endPoint: string;
|
||||
}[];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
type IKAnimationControllerProps = {
|
||||
|
@ -46,6 +42,7 @@ type IKAnimationControllerProps = {
|
|||
logStatus: (status: string) => void;
|
||||
groupRef: React.RefObject<THREE.Group>;
|
||||
armBot: ArmBotState;
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
updateArmBotStatus: (status: string) => void;
|
||||
}
|
||||
|
@ -59,6 +56,7 @@ const IKAnimationController = ({
|
|||
logStatus,
|
||||
groupRef,
|
||||
armBot,
|
||||
setArmBots,
|
||||
setStaticMachines,
|
||||
updateArmBotStatus
|
||||
}: IKAnimationControllerProps) => {
|
||||
|
@ -120,30 +118,61 @@ const IKAnimationController = ({
|
|||
if (prev.selectedTrigger !== selectedTrigger) {
|
||||
logStatus(`[Arm ${uuid}] Processing new trigger: ${selectedTrigger}`);
|
||||
|
||||
|
||||
const currentProcess = process.find(p => p.triggerId === prev.selectedTrigger);
|
||||
if (currentProcess) {
|
||||
const triggerId = currentProcess.triggerId;
|
||||
|
||||
const endPoint = armBot.actions.processes.find((process) => process.triggerId === triggerId)?.endPoint;
|
||||
|
||||
// Search simulationStates for a StaticMachine that has a point matching this endPointId
|
||||
const matchedStaticMachine = simulationStates.find(
|
||||
(state) =>
|
||||
state.type === "StaticMachine" &&
|
||||
state.points?.uuid === endPoint// check for static machine with matching point uuid
|
||||
) as any;
|
||||
// Search simulationStates for a StaticMachine or Conveyor that has a point matching this endPointId
|
||||
const matchedMachine = simulationStates.find((state) => {
|
||||
if (state.type === "Conveyor") {
|
||||
// For Conveyor, points is an array
|
||||
return (state).points.some(
|
||||
(point) => point.uuid === endPoint
|
||||
);
|
||||
} else if (state.type === "StaticMachine") {
|
||||
// For StaticMachine, points is an object
|
||||
return state.points.uuid === endPoint;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (matchedStaticMachine) {
|
||||
setStaticMachines((machines) => {
|
||||
return machines.map((machine) => {
|
||||
if (machine.uuid === matchedStaticMachine.modeluuid) {
|
||||
return { ...machine, status: "running" };
|
||||
} else {
|
||||
return machine;
|
||||
}
|
||||
if (matchedMachine) {
|
||||
// Log if the end point is a conveyor
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
logStatus(`[Arm ${uuid}] Reached end point which is a conveyor (${matchedMachine.modelName})`);
|
||||
} else {
|
||||
logStatus(`[Arm ${uuid}] Reached end point which is a static machine (${matchedMachine.modelName})`);
|
||||
}
|
||||
|
||||
if (matchedMachine.type === "StaticMachine") {
|
||||
setStaticMachines((machines) => {
|
||||
return machines.map((machine) => {
|
||||
if (machine.uuid === matchedMachine.modeluuid) {
|
||||
return { ...machine, status: "running" };
|
||||
} else {
|
||||
return machine;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (matchedMachine.type === "Conveyor") {
|
||||
setArmBots((prev) =>
|
||||
prev.map((arm) => {
|
||||
if (arm.uuid === uuid) {
|
||||
return {
|
||||
...arm,
|
||||
isActive: false
|
||||
};
|
||||
}
|
||||
else {
|
||||
return arm;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,16 +23,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
actions: {
|
||||
uuid: string;
|
||||
name: string;
|
||||
speed: number;
|
||||
processes: {
|
||||
triggerId: string;
|
||||
startPoint: string;
|
||||
endPoint: string;
|
||||
}[];
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
const IkInstances = ({
|
||||
|
@ -43,6 +39,7 @@ const IkInstances = ({
|
|||
position,
|
||||
rotation,
|
||||
armBot,
|
||||
setArmBots,
|
||||
setStaticMachines,
|
||||
updateArmBotStatus
|
||||
}: {
|
||||
|
@ -53,6 +50,7 @@ const IkInstances = ({
|
|||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
armBot: ArmBotState;
|
||||
setArmBots: React.Dispatch<React.SetStateAction<ArmBotState[]>>;
|
||||
setStaticMachines: React.Dispatch<React.SetStateAction<StaticMachineState[]>>;
|
||||
updateArmBotStatus: (status: string) => void;
|
||||
}) => {
|
||||
|
@ -141,6 +139,7 @@ const IkInstances = ({
|
|||
logStatus={logStatus}
|
||||
groupRef={groupRef}
|
||||
armBot={armBot}
|
||||
setArmBots={setArmBots}
|
||||
setStaticMachines={setStaticMachines}
|
||||
updateArmBotStatus={updateArmBotStatus}
|
||||
/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useRef, useEffect, useMemo } from "react";
|
||||
import React, { useRef, useEffect, useMemo, useCallback } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import { GLTFLoader } from "three-stdlib";
|
||||
import * as THREE from "three";
|
||||
|
@ -18,9 +18,13 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface ProcessContainerProps {
|
||||
processes: ProcessData[];
|
||||
setProcesses: React.Dispatch<React.SetStateAction<any[]>>;
|
||||
|
@ -103,9 +107,33 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
|
||||
// In processAnimator.tsx - only the relevant spawn logic part that needs fixes
|
||||
|
||||
|
||||
// Add this function to ProcessAnimator component
|
||||
const isConnectedToActiveArmBot = useCallback(
|
||||
(processId: any) => {
|
||||
// Check if any active armbot is connected to this process
|
||||
return armBots.some((armbot) => {
|
||||
if (!armbot.isActive) return false;
|
||||
|
||||
// Check if this armbot is connected to the process
|
||||
return armbot.connections?.targets?.some((connection: any) => {
|
||||
// Find the process that owns this modelUUID
|
||||
const connectedProcess = processes.find((p) =>
|
||||
p.paths?.some((path) => path.modeluuid === connection.modelUUID)
|
||||
);
|
||||
return connectedProcess?.id === processId;
|
||||
});
|
||||
});
|
||||
},
|
||||
[armBots, processes]
|
||||
);
|
||||
|
||||
// In processAnimator.tsx - only the relevant spawn logic part that needs fixes
|
||||
|
||||
useFrame(() => {
|
||||
// Spawn logic frame
|
||||
const currentTime = clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
|
||||
const currentTime =
|
||||
clockRef.current.getElapsedTime() - elapsedBeforePauseRef.current;
|
||||
|
||||
setAnimationStates((prev) => {
|
||||
const newStates = { ...prev };
|
||||
|
@ -119,6 +147,14 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
return;
|
||||
}
|
||||
|
||||
if (isConnectedToActiveArmBot(process.id)) {
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
nextSpawnTime: Infinity, // Prevent future spawns
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const spawnPoint = findSpawnPoint(process);
|
||||
if (!spawnPoint || !spawnPoint.actions) return;
|
||||
|
||||
|
@ -133,7 +169,10 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
: parseFloat(spawnAction.spawnInterval as string) || 0;
|
||||
|
||||
// Check if this is a zero interval spawn and we already spawned an object
|
||||
if (spawnInterval === 0 && processState.hasSpawnedZeroIntervalObject === true) {
|
||||
if (
|
||||
spawnInterval === 0 &&
|
||||
processState.hasSpawnedZeroIntervalObject === true
|
||||
) {
|
||||
return; // Don't spawn more objects for zero interval
|
||||
}
|
||||
|
||||
|
@ -183,6 +222,29 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
const processState = newStates[process.id];
|
||||
if (!processState) return;
|
||||
|
||||
if (isConnectedToActiveArmBot(process.id)) {
|
||||
newStates[process.id] = {
|
||||
...processState,
|
||||
spawnedObjects: Object.entries(processState.spawnedObjects).reduce(
|
||||
(acc, [id, obj]) => ({
|
||||
...acc,
|
||||
[id]: {
|
||||
...obj,
|
||||
state: {
|
||||
...obj.state,
|
||||
isAnimating: false, // Stop animation
|
||||
isDelaying: false, // Clear delays
|
||||
delayComplete: false, // Reset delays
|
||||
progress: 0, // Reset progress
|
||||
},
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (processState.isProcessDelaying) {
|
||||
const effectiveDelayTime =
|
||||
processState.processDelayDuration / speedRef.current;
|
||||
|
@ -338,10 +400,13 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
|
||||
if (isLastPoint) {
|
||||
const isAgvPicking = agvRef.current.some(
|
||||
(agv: any) => agv.processId === process.id && agv.status === "picking"
|
||||
(agv: any) =>
|
||||
agv.processId === process.id && agv.status === "picking"
|
||||
);
|
||||
|
||||
const shouldHide = !currentPointData?.actions || !hasNonInheritActions(currentPointData.actions);
|
||||
const shouldHide =
|
||||
!currentPointData?.actions ||
|
||||
!hasNonInheritActions(currentPointData.actions);
|
||||
|
||||
if (shouldHide) {
|
||||
if (isAgvPicking) {
|
||||
|
@ -372,7 +437,8 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
|
||||
if (tempStackedObjectsRef.current[objectId]) {
|
||||
const isAgvPicking = agvRef.current.some(
|
||||
(agv: any) => agv.processId === process.id && agv.status === "picking"
|
||||
(agv: any) =>
|
||||
agv.processId === process.id && agv.status === "picking"
|
||||
);
|
||||
|
||||
if (isAgvPicking) {
|
||||
|
@ -391,7 +457,8 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
|
||||
if (!isLastPoint) {
|
||||
const nextPoint = path[nextPointIdx];
|
||||
const distance = path[stateRef.currentIndex].distanceTo(nextPoint);
|
||||
const distance =
|
||||
path[stateRef.currentIndex].distanceTo(nextPoint);
|
||||
const effectiveSpeed = stateRef.speed * speedRef.current;
|
||||
const movement = effectiveSpeed * delta;
|
||||
|
||||
|
@ -442,7 +509,6 @@ const ProcessAnimator: React.FC<ProcessContainerProps> = ({
|
|||
return newStates;
|
||||
});
|
||||
});
|
||||
|
||||
if (!processedProcesses || processedProcesses.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface ProcessContainerProps {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,12 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
|
|
|
@ -10,9 +10,13 @@ interface ArmBotState {
|
|||
status: string;
|
||||
material: string;
|
||||
triggerId: string;
|
||||
connections: {
|
||||
source: { modelUUID: string; pointUUID: string };
|
||||
targets: { modelUUID: string; pointUUID: string }[];
|
||||
};
|
||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[]; };
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
interface StaticMachineState {
|
||||
uuid: string;
|
||||
status: string;
|
||||
|
|
Loading…
Reference in New Issue