feat: Integrate reset functionality in ArmBot and StaticMachine components
This commit is contained in:
parent
a59aa1d61c
commit
8b7b7f589a
|
@ -4,6 +4,7 @@ import useModuleStore from "../../../store/useModuleStore";
|
||||||
import { useSimulationStates } from "../../../store/store";
|
import { useSimulationStates } from "../../../store/store";
|
||||||
import * as SimulationTypes from '../../../types/simulationTypes';
|
import * as SimulationTypes from '../../../types/simulationTypes';
|
||||||
import { ArmbotInstances } from "./ArmBotInstances";
|
import { ArmbotInstances } from "./ArmBotInstances";
|
||||||
|
import { useResetButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
|
|
||||||
interface ArmBotState {
|
interface ArmBotState {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
@ -38,6 +39,7 @@ const ArmBot = ({ armBots, setArmBots, setStaticMachines }: ArmBotProps) => {
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { scene } = useThree();
|
const { scene } = useThree();
|
||||||
const { simulationStates } = useSimulationStates();
|
const { simulationStates } = useSimulationStates();
|
||||||
|
const { isReset } = useResetButtonStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filtered = simulationStates.filter((s): s is SimulationTypes.ArmBotEventsSchema => s.type === "ArmBot");
|
const filtered = simulationStates.filter((s): s is SimulationTypes.ArmBotEventsSchema => s.type === "ArmBot");
|
||||||
|
@ -54,7 +56,7 @@ const ArmBot = ({ armBots, setArmBots, setStaticMachines }: ArmBotProps) => {
|
||||||
connections: bot.points.connections
|
connections: bot.points.connections
|
||||||
}));
|
}));
|
||||||
setArmBots(initialStates);
|
setArmBots(initialStates);
|
||||||
}, [simulationStates]);
|
}, [simulationStates, isReset]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
armBots.forEach((bot) => {
|
armBots.forEach((bot) => {
|
||||||
|
|
|
@ -31,7 +31,7 @@ interface ArmBotState {
|
||||||
|
|
||||||
type IKAnimationControllerProps = {
|
type IKAnimationControllerProps = {
|
||||||
ikSolver: any;
|
ikSolver: any;
|
||||||
process: {
|
processes: {
|
||||||
triggerId: string;
|
triggerId: string;
|
||||||
startPoint: THREE.Vector3;
|
startPoint: THREE.Vector3;
|
||||||
endPoint: THREE.Vector3;
|
endPoint: THREE.Vector3;
|
||||||
|
@ -50,7 +50,7 @@ type IKAnimationControllerProps = {
|
||||||
|
|
||||||
const IKAnimationController = ({
|
const IKAnimationController = ({
|
||||||
ikSolver,
|
ikSolver,
|
||||||
process,
|
processes,
|
||||||
selectedTrigger,
|
selectedTrigger,
|
||||||
targetBoneName,
|
targetBoneName,
|
||||||
uuid,
|
uuid,
|
||||||
|
@ -67,20 +67,10 @@ const IKAnimationController = ({
|
||||||
const [isInitializing, setIsInitializing] = useState(true);
|
const [isInitializing, setIsInitializing] = useState(true);
|
||||||
const restSpeed = 0.1;
|
const restSpeed = 0.1;
|
||||||
const restPosition = new THREE.Vector3(0, 2, 1.6);
|
const restPosition = new THREE.Vector3(0, 2, 1.6);
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();;
|
||||||
|
const statusRef = useRef("idle");
|
||||||
const { simulationStates } = useSimulationStates();
|
const { simulationStates } = useSimulationStates();
|
||||||
|
|
||||||
// Track previous states for comparison
|
|
||||||
const prevStateRef = useRef({
|
|
||||||
isInitializing: true,
|
|
||||||
needsInitialMovement: true,
|
|
||||||
selectedTrigger: "",
|
|
||||||
progress: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// Track previous status for comparison
|
|
||||||
const prevStatusRef = useRef("");
|
|
||||||
|
|
||||||
const initialCurveRef = useRef<THREE.CatmullRomCurve3 | null>(null);
|
const initialCurveRef = useRef<THREE.CatmullRomCurve3 | null>(null);
|
||||||
const initialStartPositionRef = useRef<THREE.Vector3 | null>(null);
|
const initialStartPositionRef = useRef<THREE.Vector3 | null>(null);
|
||||||
|
|
||||||
|
@ -101,91 +91,6 @@ const IKAnimationController = ({
|
||||||
}
|
}
|
||||||
}, [ikSolver]);
|
}, [ikSolver]);
|
||||||
|
|
||||||
// Log state changes
|
|
||||||
useEffect(() => {
|
|
||||||
const prev = prevStateRef.current;
|
|
||||||
|
|
||||||
if (prev.isInitializing !== isInitializing) {
|
|
||||||
if (!isInitializing) {
|
|
||||||
logStatus(`[Arm ${uuid}] Completed initialization, now at rest position`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev.needsInitialMovement !== needsInitialMovement && !needsInitialMovement) {
|
|
||||||
logStatus(`[Arm ${uuid}] Reached rest position, ready for animation`);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 (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;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update previous state
|
|
||||||
prevStateRef.current = {
|
|
||||||
isInitializing,
|
|
||||||
needsInitialMovement,
|
|
||||||
selectedTrigger,
|
|
||||||
progress
|
|
||||||
};
|
|
||||||
}, [isInitializing, needsInitialMovement, selectedTrigger, progress]);
|
|
||||||
|
|
||||||
const calculateInitialCurve = (startPosition: THREE.Vector3) => {
|
const calculateInitialCurve = (startPosition: THREE.Vector3) => {
|
||||||
const direction = new THREE.Vector3().subVectors(restPosition, startPosition);
|
const direction = new THREE.Vector3().subVectors(restPosition, startPosition);
|
||||||
|
@ -211,61 +116,56 @@ const IKAnimationController = ({
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const processedCurves = useMemo(() => {
|
const processCurves = useMemo(() => {
|
||||||
if (isPlaying)
|
if (!isPlaying) return [];
|
||||||
return process.map((p) => {
|
|
||||||
const tempLift = 0.5;
|
|
||||||
const localStart = groupRef.current?.worldToLocal(p.startPoint.clone().add(new THREE.Vector3(0, tempLift, 0)));
|
|
||||||
const localEnd = groupRef.current?.worldToLocal(p.endPoint.clone().add(new THREE.Vector3(0, tempLift, 0)));
|
|
||||||
|
|
||||||
if (localStart && localEnd) {
|
return processes.map(process => {
|
||||||
|
const localStart = groupRef.current?.worldToLocal(process.startPoint.clone());
|
||||||
|
const localEnd = groupRef.current?.worldToLocal(process.endPoint.clone());
|
||||||
|
|
||||||
const mid = new THREE.Vector3(
|
if (!localStart || !localEnd) return null;
|
||||||
(localStart.x + localEnd.x) / 1,
|
|
||||||
Math.max(localStart.y, localEnd.y) + 0.8,
|
|
||||||
(localStart.z + localEnd.z) / 0.9
|
|
||||||
);
|
|
||||||
|
|
||||||
const points = [
|
const midPoint = new THREE.Vector3(
|
||||||
restPosition.clone(),
|
(localStart.x + localEnd.x) / 2,
|
||||||
localStart.clone(),
|
Math.max(localStart.y, localEnd.y) + 1,
|
||||||
mid.clone(),
|
(localStart.z + localEnd.z) / 2
|
||||||
localEnd.clone(),
|
);
|
||||||
restPosition.clone(),
|
const restToStartCurve = new THREE.CatmullRomCurve3([
|
||||||
];
|
restPosition,
|
||||||
const curve = new THREE.CatmullRomCurve3(points);
|
new THREE.Vector3().lerpVectors(restPosition, localStart, 0.5),
|
||||||
const restToStartDist = points[0].distanceTo(points[1]);
|
localStart
|
||||||
const startToEndDist = points[1].distanceTo(points[3]);
|
]);
|
||||||
const endToRestDist = points[3].distanceTo(points[4]);
|
|
||||||
|
|
||||||
const totalDist = restToStartDist + startToEndDist + endToRestDist;
|
const processCurve = new THREE.CatmullRomCurve3([
|
||||||
const restToStartRange = [0, restToStartDist / totalDist];
|
localStart,
|
||||||
const startToEndRange = [
|
midPoint,
|
||||||
restToStartRange[1],
|
localEnd
|
||||||
restToStartRange[1] + startToEndDist / totalDist,
|
]);
|
||||||
];
|
|
||||||
const endToRestRange = [startToEndRange[1], 1];
|
|
||||||
|
|
||||||
return {
|
const endToRestCurve = new THREE.CatmullRomCurve3([
|
||||||
trigger: p.triggerId,
|
localEnd,
|
||||||
curve,
|
new THREE.Vector3().lerpVectors(localEnd, restPosition, 0.5),
|
||||||
speed: p.speed,
|
restPosition
|
||||||
restToStartRange,
|
]);
|
||||||
startToEndRange,
|
|
||||||
endToRestRange,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [process, groupRef, isPlaying]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
return {
|
||||||
console.log('processedCurves: ', processedCurves);
|
triggerId: process.triggerId,
|
||||||
}, [processedCurves])
|
restToStartCurve,
|
||||||
|
processCurve,
|
||||||
|
endToRestCurve,
|
||||||
|
speed: process.speed,
|
||||||
|
totalDistance:
|
||||||
|
restPosition.distanceTo(localStart) +
|
||||||
|
localStart.distanceTo(localEnd) +
|
||||||
|
localEnd.distanceTo(restPosition)
|
||||||
|
};
|
||||||
|
}).filter(Boolean);
|
||||||
|
}, [processes, isPlaying]);
|
||||||
|
|
||||||
const activeCurve = useMemo(() => {
|
const activeProcess = useMemo(() => {
|
||||||
if (isPlaying && processedCurves)
|
if (!selectedTrigger) return null;
|
||||||
return processedCurves.find((c) => c?.trigger === selectedTrigger);
|
return processCurves.find(p => p?.triggerId === selectedTrigger);
|
||||||
}, [processedCurves, selectedTrigger, isPlaying]);
|
}, [processCurves, selectedTrigger]);
|
||||||
|
|
||||||
// Initial movement to rest position
|
// Initial movement to rest position
|
||||||
useFrame((_, delta) => {
|
useFrame((_, delta) => {
|
||||||
|
@ -293,68 +193,128 @@ const IKAnimationController = ({
|
||||||
|
|
||||||
// Main animation loop
|
// Main animation loop
|
||||||
useFrame((_, delta) => {
|
useFrame((_, delta) => {
|
||||||
if (!ikSolver || !activeCurve || isInitializing || !isPlaying) return;
|
if (isInitializing || !isPlaying || !selectedTrigger || !activeProcess || !ikSolver) return;
|
||||||
|
|
||||||
const { curve, speed, restToStartRange, startToEndRange, endToRestRange } = activeCurve;
|
const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBoneName);
|
||||||
const targetBone = ikSolver.mesh.skeleton.bones.find(
|
if (!bone) return;
|
||||||
(b: any) => b.name === targetBoneName
|
|
||||||
);
|
|
||||||
if (!targetBone) return;
|
|
||||||
|
|
||||||
let currentSpeed = restSpeed;
|
const {
|
||||||
let currentStatus = "idle"; // Default status
|
restToStartCurve,
|
||||||
|
processCurve,
|
||||||
|
endToRestCurve,
|
||||||
|
speed,
|
||||||
|
totalDistance
|
||||||
|
} = activeProcess;
|
||||||
|
|
||||||
// Determine current phase and status
|
// Calculate current segment and progress
|
||||||
if (progress < restToStartRange[1]) {
|
const restToStartDist = restPosition.distanceTo(restToStartCurve.points[2]);
|
||||||
currentSpeed = restSpeed;
|
const processDist = processCurve.getLength();
|
||||||
currentStatus = "moving"; // Moving to start point
|
const endToRestDist = endToRestCurve.getLength();
|
||||||
} else if (progress >= startToEndRange[0] && progress < startToEndRange[1]) {
|
|
||||||
currentSpeed = speed;
|
|
||||||
currentStatus = "moving"; // Moving between points
|
|
||||||
} else if (progress >= endToRestRange[0] && progress < 1) {
|
|
||||||
currentSpeed = restSpeed;
|
|
||||||
currentStatus = "moving"; // Returning to rest
|
|
||||||
} else if (progress >= 1) {
|
|
||||||
currentStatus = "idle"; // Completed cycle
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update status when it changes
|
const restToStartEnd = restToStartDist / totalDistance;
|
||||||
if (prevStatusRef.current !== currentStatus) {
|
const processEnd = (restToStartDist + processDist) / totalDistance;
|
||||||
updateArmBotStatus(currentStatus);
|
|
||||||
prevStatusRef.current = currentStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update progress if we're not already at the end
|
setProgress(prev => {
|
||||||
if (progress < 1) {
|
let currentStatus = statusRef.current;
|
||||||
setProgress((prev) => {
|
let currentPosition: THREE.Vector3;
|
||||||
const next = prev + delta * currentSpeed;
|
const newProgress = Math.min(prev + delta * ((currentStatus === 'returning to rest') ? restSpeed : speed), 1);
|
||||||
return Math.min(next, 1); // Cap at 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update bone position based on progress
|
if (newProgress < restToStartEnd) {
|
||||||
if (progress < 1) {
|
// Moving from rest to start position
|
||||||
targetBone.position.copy(curve.getPoint(progress));
|
currentStatus = "moving to start";
|
||||||
} else {
|
const segmentProgress = newProgress / restToStartEnd;
|
||||||
targetBone.position.copy(curve.getPoint(1));
|
currentPosition = restToStartCurve.getPoint(segmentProgress);
|
||||||
}
|
} else if (newProgress < processEnd) {
|
||||||
|
// Processing - moving from start to end
|
||||||
|
currentStatus = "processing";
|
||||||
|
const segmentProgress = (newProgress - restToStartEnd) / (processEnd - restToStartEnd);
|
||||||
|
currentPosition = processCurve.getPoint(segmentProgress);
|
||||||
|
} else {
|
||||||
|
// Returning to rest position
|
||||||
|
currentStatus = "returning to rest";
|
||||||
|
const segmentProgress = (newProgress - processEnd) / (1 - processEnd);
|
||||||
|
currentPosition = endToRestCurve.getPoint(segmentProgress);
|
||||||
|
}
|
||||||
|
|
||||||
ikSolver.update();
|
// Update status if changed
|
||||||
|
if (currentStatus !== statusRef.current) {
|
||||||
|
statusRef.current = currentStatus;
|
||||||
|
// updateArmBotStatus(currentStatus);
|
||||||
|
logStatus(`[Arm ${uuid}] Status: ${currentStatus}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only trigger when the entire animation is complete (newProgress === 1)
|
||||||
|
if (newProgress === 1 && currentStatus === "returning to rest") {
|
||||||
|
updateConveyorOrStaticMachineStatus(selectedTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
bone.position.copy(currentPosition);
|
||||||
|
ikSolver.update();
|
||||||
|
return newProgress;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
const updateConveyorOrStaticMachineStatus = (selectedTrigger: string) => {
|
||||||
<>
|
const currentProcess = processes.find(p => p.triggerId === selectedTrigger);
|
||||||
{armBot.status === 'moving' && activeCurve &&
|
if (currentProcess) {
|
||||||
<MaterialInstances
|
const triggerId = currentProcess.triggerId;
|
||||||
groupRef={groupRef}
|
|
||||||
activeCurve={activeCurve}
|
const endPoint = armBot.actions.processes.find((process) => process.triggerId === triggerId)?.endPoint;
|
||||||
progress={progress}
|
|
||||||
ikSolver={ikSolver}
|
const matchedMachine = simulationStates.find((state) => {
|
||||||
targetBoneName={targetBoneName}
|
if (state.type === "Conveyor") {
|
||||||
/>
|
return (state).points.some(
|
||||||
|
(point) => point.uuid === endPoint
|
||||||
|
);
|
||||||
|
} else if (state.type === "StaticMachine") {
|
||||||
|
return state.points.uuid === endPoint;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchedMachine) {
|
||||||
|
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})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (matchedMachine.type === "StaticMachine") {
|
||||||
|
setStaticMachines((machines) => {
|
||||||
|
return machines.map((machine) => {
|
||||||
|
if (machine.uuid === matchedMachine.modeluuid) {
|
||||||
|
return { ...machine, status: "running" };
|
||||||
|
} else {
|
||||||
|
return machine;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
updateArmBotStatus('idle');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedMachine.type === "Conveyor") {
|
||||||
|
setArmBots((prev) =>
|
||||||
|
prev.map((arm) => {
|
||||||
|
if (arm.uuid === uuid) {
|
||||||
|
return {
|
||||||
|
...arm,
|
||||||
|
isActive: false,
|
||||||
|
status: "idle",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return arm;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
</>
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default IKAnimationController;
|
export default IKAnimationController;
|
|
@ -132,7 +132,7 @@ const IkInstances = ({
|
||||||
</group>
|
</group>
|
||||||
<IKAnimationController
|
<IKAnimationController
|
||||||
ikSolver={ikSolver}
|
ikSolver={ikSolver}
|
||||||
process={processes}
|
processes={processes}
|
||||||
selectedTrigger={selectedTrigger}
|
selectedTrigger={selectedTrigger}
|
||||||
targetBoneName={targetBoneName}
|
targetBoneName={targetBoneName}
|
||||||
uuid={uuid}
|
uuid={uuid}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect } from 'react'
|
||||||
import * as SimulationTypes from '../../../types/simulationTypes';
|
import * as SimulationTypes from '../../../types/simulationTypes';
|
||||||
import { useSimulationStates } from '../../../store/store';
|
import { useSimulationStates } from '../../../store/store';
|
||||||
import StaticMachineInstances from './staticMachineInstances';
|
import StaticMachineInstances from './staticMachineInstances';
|
||||||
|
import { useResetButtonStore } from '../../../store/usePlayButtonStore';
|
||||||
|
|
||||||
interface ArmBotState {
|
interface ArmBotState {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
@ -34,6 +35,7 @@ type StaticMachineProps = {
|
||||||
function StaticMachine({ setArmBots, staticMachines, setStaticMachines }: StaticMachineProps) {
|
function StaticMachine({ setArmBots, staticMachines, setStaticMachines }: StaticMachineProps) {
|
||||||
|
|
||||||
const { simulationStates } = useSimulationStates();
|
const { simulationStates } = useSimulationStates();
|
||||||
|
const { isReset } = useResetButtonStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filtered = simulationStates.filter((s): s is SimulationTypes.StaticMachineEventsSchema => s.type === "StaticMachine");
|
const filtered = simulationStates.filter((s): s is SimulationTypes.StaticMachineEventsSchema => s.type === "StaticMachine");
|
||||||
|
@ -47,7 +49,7 @@ function StaticMachine({ setArmBots, staticMachines, setStaticMachines }: Static
|
||||||
connectedArmBot: machine.points.connections.targets[0].modelUUID
|
connectedArmBot: machine.points.connections.targets[0].modelUUID
|
||||||
}));
|
}));
|
||||||
setStaticMachines(initialStates);
|
setStaticMachines(initialStates);
|
||||||
}, [simulationStates]);
|
}, [simulationStates, isReset]);
|
||||||
|
|
||||||
const updateArmBotTriggerAndMachineStatus = (armBotUuid: string, triggerId: string, machineId: string) => {
|
const updateArmBotTriggerAndMachineStatus = (armBotUuid: string, triggerId: string, machineId: string) => {
|
||||||
setArmBots((prevArmBots) => {
|
setArmBots((prevArmBots) => {
|
||||||
|
|
Loading…
Reference in New Issue