Merge remote-tracking branch 'origin/dev-simulation/human' into main-demo
This commit is contained in:
@@ -16,7 +16,7 @@ import { getUserData } from '../../../../../functions/getUserData';
|
|||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
import { useVersionContext } from '../../../version/versionContext';
|
import { useVersionContext } from '../../../version/versionContext';
|
||||||
import { SkeletonUtils } from 'three-stdlib';
|
import { SkeletonUtils } from 'three-stdlib';
|
||||||
import { useAnimationPlaySpeed } from '../../../../../store/usePlayButtonStore';
|
import { useAnimationPlaySpeed, usePauseButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
|
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
|
||||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
const { subModule } = useSubModuleStore();
|
const { subModule } = useSubModuleStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { speed } = useAnimationPlaySpeed();
|
const { speed } = useAnimationPlaySpeed();
|
||||||
|
const { isPaused } = usePauseButtonStore();
|
||||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||||
const { removeAsset, setAnimations, resetAnimation, setAnimationComplete } = assetStore();
|
const { removeAsset, setAnimations, resetAnimation, setAnimationComplete } = assetStore();
|
||||||
const { setTop } = useTopData();
|
const { setTop } = useTopData();
|
||||||
@@ -81,7 +82,8 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
if (!ikData && asset.eventData && asset.eventData.type === 'ArmBot') {
|
if (!ikData && asset.eventData && asset.eventData.type === 'ArmBot') {
|
||||||
getAssetIksApi(asset.assetId).then((data) => {
|
getAssetIksApi(asset.assetId).then((data) => {
|
||||||
if (data.iks) {
|
if (data.iks) {
|
||||||
setIkData(data.iks);
|
const iks: IK[] = data.iks;
|
||||||
|
setIkData(iks);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -385,7 +387,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
const currentAction = actions.current[current];
|
const currentAction = actions.current[current];
|
||||||
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
||||||
|
|
||||||
if (isPlaying && currentAction) {
|
if (isPlaying && currentAction && activeModule === 'simulation' && !isPaused) {
|
||||||
blendFactor.current = 0;
|
blendFactor.current = 0;
|
||||||
|
|
||||||
currentAction.reset();
|
currentAction.reset();
|
||||||
@@ -408,7 +410,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [asset.animationState?.current, asset.animationState?.isPlaying]);
|
}, [asset.animationState?.current, asset.animationState?.isPlaying, isPaused, activeModule]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
@@ -463,7 +465,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
position={asset.position}
|
position={asset.position}
|
||||||
rotation={asset.rotation}
|
rotation={asset.rotation}
|
||||||
visible={asset.isVisible}
|
visible={asset.isVisible}
|
||||||
userData={asset}
|
userData={{ ...asset, iks: ikData }}
|
||||||
onDoubleClick={(e) => {
|
onDoubleClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!toggleView) {
|
if (!toggleView) {
|
||||||
|
|||||||
@@ -3,76 +3,97 @@ import { useFrame } from '@react-three/fiber';
|
|||||||
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore';
|
import { usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../store/usePlayButtonStore';
|
||||||
import { useSceneContext } from '../../../scene/sceneContext';
|
import { useSceneContext } from '../../../scene/sceneContext';
|
||||||
|
|
||||||
type HumanCallback = {
|
|
||||||
humanId: string;
|
|
||||||
callback: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function useHumanEventManager() {
|
export function useHumanEventManager() {
|
||||||
const { humanStore } = useSceneContext();
|
const { humanStore } = useSceneContext();
|
||||||
const { getHumanById } = humanStore();
|
const { getHumanById } = humanStore();
|
||||||
const callbacksRef = useRef<HumanCallback[]>([]);
|
|
||||||
|
const callbacksRef = useRef<Map<string, (() => void)[]>>(new Map());
|
||||||
const isMonitoringRef = useRef(false);
|
const isMonitoringRef = useRef(false);
|
||||||
|
const isCooldownRef = useRef<Map<string, boolean>>(new Map());
|
||||||
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { isPaused } = usePauseButtonStore();
|
const { isPaused } = usePauseButtonStore();
|
||||||
const { isReset } = useResetButtonStore();
|
const { isReset } = useResetButtonStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isReset) {
|
if (isReset) {
|
||||||
callbacksRef.current = [];
|
callbacksRef.current.clear();
|
||||||
|
isCooldownRef.current.clear();
|
||||||
}
|
}
|
||||||
}, [isReset])
|
}, [isReset]);
|
||||||
|
|
||||||
// Add a new human to monitor
|
|
||||||
const addHumanToMonitor = (humanId: string, callback: () => void) => {
|
const addHumanToMonitor = (humanId: string, callback: () => void) => {
|
||||||
// Avoid duplicates
|
if (!callbacksRef.current.has(humanId)) {
|
||||||
if (!callbacksRef.current.some((entry) => entry.humanId === humanId)) {
|
callbacksRef.current.set(humanId, []);
|
||||||
callbacksRef.current.push({ humanId, callback });
|
|
||||||
}
|
}
|
||||||
|
callbacksRef.current.get(humanId)!.push(callback);
|
||||||
|
|
||||||
// Start monitoring if not already running
|
|
||||||
if (!isMonitoringRef.current) {
|
if (!isMonitoringRef.current) {
|
||||||
isMonitoringRef.current = true;
|
isMonitoringRef.current = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove a human from monitoring
|
|
||||||
const removeHumanFromMonitor = (humanId: string) => {
|
const removeHumanFromMonitor = (humanId: string) => {
|
||||||
callbacksRef.current = callbacksRef.current.filter(
|
callbacksRef.current.delete(humanId);
|
||||||
(entry) => entry.humanId !== humanId
|
isCooldownRef.current.delete(humanId);
|
||||||
);
|
|
||||||
|
|
||||||
// Stop monitoring if no more humans to track
|
if (callbacksRef.current.size === 0) {
|
||||||
if (callbacksRef.current.length === 0) {
|
|
||||||
isMonitoringRef.current = false;
|
isMonitoringRef.current = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check human states every frame
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (!isMonitoringRef.current || callbacksRef.current.length === 0 || !isPlaying || isPaused) return;
|
|
||||||
|
|
||||||
callbacksRef.current.forEach(({ humanId, callback }) => {
|
if (!isMonitoringRef.current || !isPlaying || isPaused) return;
|
||||||
|
|
||||||
|
callbacksRef.current.forEach((queue, humanId) => {
|
||||||
|
if (queue.length === 0 || isCooldownRef.current.get(humanId)) return;
|
||||||
|
|
||||||
const human = getHumanById(humanId);
|
const human = getHumanById(humanId);
|
||||||
if (human?.point.action.actionType === 'worker') {
|
const actionType = human?.point.action.actionType;
|
||||||
if (human && human.isActive === false && human.state === 'idle' && human.isPicking && human.currentLoad < human.point.action.loadCapacity) {
|
|
||||||
callback();
|
let conditionMet = false;
|
||||||
removeHumanFromMonitor(humanId); // Remove after triggering
|
|
||||||
|
if (actionType === 'worker') {
|
||||||
|
conditionMet = Boolean(
|
||||||
|
human &&
|
||||||
|
human.isActive === false &&
|
||||||
|
human.state === 'idle' &&
|
||||||
|
human.isScheduled === false &&
|
||||||
|
human.currentLoad < human.point.action.loadCapacity
|
||||||
|
);
|
||||||
|
} else if (actionType === 'assembly') {
|
||||||
|
conditionMet = Boolean(
|
||||||
|
human &&
|
||||||
|
human.isActive === false &&
|
||||||
|
human.state === 'idle' &&
|
||||||
|
human.isScheduled === false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (human?.point.action.actionType === 'assembly') {
|
|
||||||
if (human && human.isActive === false && human.state === 'idle') {
|
if (conditionMet) {
|
||||||
|
const callback = queue.shift();
|
||||||
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
removeHumanFromMonitor(humanId); // Remove after triggering
|
|
||||||
|
if (queue.length === 0) {
|
||||||
|
removeHumanFromMonitor(humanId);
|
||||||
|
} else {
|
||||||
|
isCooldownRef.current.set(humanId, true);
|
||||||
|
setTimeout(() => {
|
||||||
|
isCooldownRef.current.set(humanId, false);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup on unmount
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
callbacksRef.current = [];
|
callbacksRef.current.clear();
|
||||||
isMonitoringRef.current = false;
|
isMonitoringRef.current = false;
|
||||||
|
isCooldownRef.current.clear();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
const { selectedProduct } = selectedProductStore();
|
const { selectedProduct } = selectedProductStore();
|
||||||
const { setHumanActive, setHumanState, setHumanPicking, clearCurrentMaterials, setHumanLoad, decrementHumanLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = humanStore();
|
const { setHumanActive, setHumanState, clearCurrentMaterials, setHumanLoad, setHumanScheduled, decrementHumanLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = humanStore();
|
||||||
|
|
||||||
const [currentPhase, setCurrentPhase] = useState<string>('init');
|
const [currentPhase, setCurrentPhase] = useState<string>('init');
|
||||||
const [path, setPath] = useState<[number, number, number][]>([]);
|
const [path, setPath] = useState<[number, number, number][]>([]);
|
||||||
@@ -86,8 +86,8 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
function reset() {
|
function reset() {
|
||||||
setCurrentPhase('init');
|
setCurrentPhase('init');
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
|
setHumanScheduled(human.modelUuid, false);
|
||||||
setHumanLoad(human.modelUuid, 0);
|
setHumanLoad(human.modelUuid, 0);
|
||||||
resetAnimation(human.modelUuid);
|
resetAnimation(human.modelUuid);
|
||||||
setPath([]);
|
setPath([]);
|
||||||
@@ -125,7 +125,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
if (!human.isActive && human.state === 'idle' && currentPhase === 'init') {
|
if (!human.isActive && human.state === 'idle' && currentPhase === 'init') {
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
setCurrentPhase('waiting');
|
setCurrentPhase('waiting');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Human is waiting for material in assembly');
|
humanStatus(human.modelUuid, 'Human is waiting for material in assembly');
|
||||||
@@ -134,7 +133,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false);
|
setCurrentAnimation(human.modelUuid, 'working_standing', true, true, false);
|
||||||
setHumanState(human.modelUuid, 'running');
|
setHumanState(human.modelUuid, 'running');
|
||||||
setCurrentPhase('assembling');
|
setCurrentPhase('assembling');
|
||||||
setHumanPicking(human.modelUuid, true);
|
|
||||||
setHumanActive(human.modelUuid, true);
|
setHumanActive(human.modelUuid, true);
|
||||||
|
|
||||||
processStartTimeRef.current = performance.now();
|
processStartTimeRef.current = performance.now();
|
||||||
@@ -152,8 +150,8 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
if (human.point.action.assemblyPoint && currentPhase === 'assembling') {
|
if (human.point.action.assemblyPoint && currentPhase === 'assembling') {
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
setCurrentPhase('waiting');
|
setCurrentPhase('waiting');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
|
setHumanScheduled(human.modelUuid, false);
|
||||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Human is waiting for material in assembly');
|
humanStatus(human.modelUuid, 'Human is waiting for material in assembly');
|
||||||
|
|
||||||
@@ -230,7 +228,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
setPath(toPickupPath);
|
setPath(toPickupPath);
|
||||||
setCurrentPhase('init-pickup');
|
setCurrentPhase('init-pickup');
|
||||||
setHumanState(human.modelUuid, 'running');
|
setHumanState(human.modelUuid, 'running');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanActive(human.modelUuid, true);
|
setHumanActive(human.modelUuid, true);
|
||||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Started from init, heading to pickup');
|
humanStatus(human.modelUuid, 'Started from init, heading to pickup');
|
||||||
@@ -253,8 +250,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
setPath(toDrop);
|
setPath(toDrop);
|
||||||
setCurrentPhase('pickup-drop');
|
setCurrentPhase('pickup-drop');
|
||||||
setHumanState(human.modelUuid, 'running');
|
setHumanState(human.modelUuid, 'running');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanPicking(human.modelUuid, true);
|
|
||||||
setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'walk_with_box', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Started from pickup point, heading to drop point');
|
humanStatus(human.modelUuid, 'Started from pickup point, heading to drop point');
|
||||||
}
|
}
|
||||||
@@ -278,7 +273,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
setPath(dropToPickup);
|
setPath(dropToPickup);
|
||||||
setCurrentPhase('drop-pickup');
|
setCurrentPhase('drop-pickup');
|
||||||
setHumanState(human.modelUuid, 'running');
|
setHumanState(human.modelUuid, 'running');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanActive(human.modelUuid, true);
|
setHumanActive(human.modelUuid, true);
|
||||||
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'walking', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Started from dropping point, heading to pickup point');
|
humanStatus(human.modelUuid, 'Started from dropping point, heading to pickup point');
|
||||||
@@ -295,7 +289,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
if (currentPhase === 'init-pickup') {
|
if (currentPhase === 'init-pickup') {
|
||||||
setCurrentPhase('picking');
|
setCurrentPhase('picking');
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
setHumanPicking(human.modelUuid, true);
|
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||||
humanStatus(human.modelUuid, 'Reached pickup point, waiting for material');
|
humanStatus(human.modelUuid, 'Reached pickup point, waiting for material');
|
||||||
@@ -303,7 +296,6 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
} else if (currentPhase === 'pickup-drop') {
|
} else if (currentPhase === 'pickup-drop') {
|
||||||
setCurrentPhase('dropping');
|
setCurrentPhase('dropping');
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
setHumanPicking(human.modelUuid, false);
|
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
setCurrentAnimation(human.modelUuid, 'drop', true, false, false);
|
||||||
humanStatus(human.modelUuid, 'Reached drop point');
|
humanStatus(human.modelUuid, 'Reached drop point');
|
||||||
@@ -311,8 +303,8 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
} else if (currentPhase === 'drop-pickup') {
|
} else if (currentPhase === 'drop-pickup') {
|
||||||
setCurrentPhase('picking');
|
setCurrentPhase('picking');
|
||||||
setHumanState(human.modelUuid, 'idle');
|
setHumanState(human.modelUuid, 'idle');
|
||||||
setHumanPicking(human.modelUuid, true);
|
|
||||||
setHumanActive(human.modelUuid, false);
|
setHumanActive(human.modelUuid, false);
|
||||||
|
setHumanScheduled(human.modelUuid, false);
|
||||||
setPath([]);
|
setPath([]);
|
||||||
clearCurrentMaterials(human.modelUuid);
|
clearCurrentMaterials(human.modelUuid);
|
||||||
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
setCurrentAnimation(human.modelUuid, 'idle', true, true, true);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
|
|||||||
const trySetup = () => {
|
const trySetup = () => {
|
||||||
const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid);
|
const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid);
|
||||||
|
|
||||||
if (!targetMesh) {
|
if (!targetMesh || !targetMesh.userData.iks || targetMesh.userData.iks.length < 1) {
|
||||||
retryId = setTimeout(trySetup, 100);
|
retryId = setTimeout(trySetup, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -33,34 +33,23 @@ function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
|
|||||||
if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
|
if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
|
||||||
});
|
});
|
||||||
if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
|
if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
|
||||||
const iks = [
|
|
||||||
{
|
const rawIks: IK[] = targetMesh.userData.iks;
|
||||||
target: 7,
|
const iks = rawIks.map((ik) => ({
|
||||||
effector: 6,
|
target: ik.target,
|
||||||
links: [
|
effector: ik.effector,
|
||||||
{
|
links: ik.links.map((link) => ({
|
||||||
index: 5,
|
index: link.index,
|
||||||
enabled: true,
|
enabled: link.enabled,
|
||||||
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
rotationMin: link.rotationMin ? new THREE.Vector3(...link.rotationMin) : undefined,
|
||||||
rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0),
|
rotationMax: link.rotationMax ? new THREE.Vector3(...link.rotationMax) : undefined,
|
||||||
},
|
limitation: link.limitation ? new THREE.Vector3(...link.limitation) : undefined,
|
||||||
{
|
})),
|
||||||
index: 4,
|
minDistance: ik.minDistance,
|
||||||
enabled: true,
|
maxDistance: ik.maxDistance,
|
||||||
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
maxheight: ik.maxheight,
|
||||||
rotationMax: new THREE.Vector3(0, 0, 0),
|
minheight: ik.minheight,
|
||||||
},
|
}));
|
||||||
{
|
|
||||||
index: 3,
|
|
||||||
enabled: true,
|
|
||||||
rotationMin: new THREE.Vector3(0, 0, 0),
|
|
||||||
rotationMax: new THREE.Vector3(2, 0, 0),
|
|
||||||
},
|
|
||||||
{ index: 1, enabled: true, limitation: new THREE.Vector3(0, 1, 0) },
|
|
||||||
{ index: 0, enabled: false, limitation: new THREE.Vector3(0, 0, 0) },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
|
const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
|
||||||
setIkSolver(solver);
|
setIkSolver(solver);
|
||||||
|
|||||||
@@ -171,11 +171,22 @@ const ArmBotUI = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { handlePointerDown } = useDraggableGLTF(updatePointToState);
|
const targetMesh = scene?.getObjectByProperty("uuid", selectedArmBotData?.modelUuid || '');
|
||||||
|
|
||||||
|
const { handlePointerDown } = useDraggableGLTF(
|
||||||
|
updatePointToState,
|
||||||
|
{
|
||||||
|
minDistance: targetMesh?.userData?.iks[0]?.minDistance || 1.2,
|
||||||
|
maxDistance: targetMesh?.userData?.iks[0]?.maxDistance || 2,
|
||||||
|
maxheight: targetMesh?.userData?.iks[0]?.maxheight || 0.6,
|
||||||
|
minheight: targetMesh?.userData?.iks[0]?.minheight || 1.9,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!selectedArmBotData || !Array.isArray(selectedArmBotData.point?.actions)) {
|
if (!selectedArmBotData || !Array.isArray(selectedArmBotData.point?.actions)) {
|
||||||
return null; // avoid rendering if no data yet
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{selectedArmBotData.point.actions.map((action: any) => {
|
{selectedArmBotData.point.actions.map((action: any) => {
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { ThreeEvent, useThree } from "@react-three/fiber";
|
import { ThreeEvent, useThree } from "@react-three/fiber";
|
||||||
import {
|
import { useSelectedEventData } from "../../../../store/simulation/useSimulationStore";
|
||||||
useSelectedEventData,
|
|
||||||
} from "../../../../store/simulation/useSimulationStore";
|
|
||||||
import { useProductContext } from "../../products/productContext";
|
import { useProductContext } from "../../products/productContext";
|
||||||
import { useSceneContext } from "../../../scene/sceneContext";
|
import { useSceneContext } from "../../../scene/sceneContext";
|
||||||
|
|
||||||
type OnUpdateCallback = (object: THREE.Object3D) => void;
|
type OnUpdateCallback = (object: THREE.Object3D) => void;
|
||||||
|
|
||||||
export default function useDraggableGLTF(onUpdate: OnUpdateCallback) {
|
export default function useDraggableGLTF(
|
||||||
|
onUpdate: OnUpdateCallback,
|
||||||
|
constraints: {
|
||||||
|
minDistance?: number;
|
||||||
|
maxDistance?: number;
|
||||||
|
maxheight?: number;
|
||||||
|
minheight?: number;
|
||||||
|
} = {
|
||||||
|
minDistance: 1.2,
|
||||||
|
maxDistance: 2,
|
||||||
|
minheight: 0.6,
|
||||||
|
maxheight: 1.9
|
||||||
|
}
|
||||||
|
) {
|
||||||
const { productStore } = useSceneContext();
|
const { productStore } = useSceneContext();
|
||||||
const { getEventByModelUuid } = productStore();
|
const { getEventByModelUuid } = productStore();
|
||||||
const { selectedEventData } = useSelectedEventData();
|
const { selectedEventData } = useSelectedEventData();
|
||||||
@@ -120,8 +131,10 @@ export default function useDraggableGLTF(onUpdate: OnUpdateCallback) {
|
|||||||
// CONSTRAIN MOVEMENT HERE:
|
// CONSTRAIN MOVEMENT HERE:
|
||||||
const centerX = selectedArmBot.position[0];
|
const centerX = selectedArmBot.position[0];
|
||||||
const centerZ = selectedArmBot.position[2];
|
const centerZ = selectedArmBot.position[2];
|
||||||
const minDistance = 1.2;
|
const minDistance = constraints.minDistance ?? 1.2;
|
||||||
const maxDistance = 2;
|
const maxDistance = constraints.maxDistance ?? 2;
|
||||||
|
const minHeight = constraints.minheight ?? 0.6;
|
||||||
|
const maxHeight = constraints.maxheight ?? 1.9;
|
||||||
|
|
||||||
const delta = new THREE.Vector3(targetPosition.x - centerX, 0, targetPosition.z - centerZ);
|
const delta = new THREE.Vector3(targetPosition.x - centerX, 0, targetPosition.z - centerZ);
|
||||||
|
|
||||||
@@ -169,9 +182,8 @@ export default function useDraggableGLTF(onUpdate: OnUpdateCallback) {
|
|||||||
targetPosition.x = centerX + finalLocal.x;
|
targetPosition.x = centerX + finalLocal.x;
|
||||||
targetPosition.z = centerZ + finalLocal.z;
|
targetPosition.z = centerZ + finalLocal.z;
|
||||||
|
|
||||||
|
// Clamp Y axis using variables
|
||||||
// Clamp Y axis if needed
|
targetPosition.y = Math.min(Math.max(targetPosition.y, minHeight), maxHeight);
|
||||||
targetPosition.y = Math.min(Math.max(targetPosition.y, 0.6), 1.9);
|
|
||||||
|
|
||||||
// Convert to local if parent exists
|
// Convert to local if parent exists
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export function useTriggerHandler() {
|
|||||||
const { addMachineToMonitor } = useMachineEventManager();
|
const { addMachineToMonitor } = useMachineEventManager();
|
||||||
const { addHumanToMonitor } = useHumanEventManager();
|
const { addHumanToMonitor } = useHumanEventManager();
|
||||||
const { getVehicleById } = vehicleStore();
|
const { getVehicleById } = vehicleStore();
|
||||||
const { getHumanById } = humanStore();
|
const { getHumanById, setHumanScheduled } = humanStore();
|
||||||
const { getMachineById } = machineStore();
|
const { getMachineById } = machineStore();
|
||||||
const { getStorageUnitById } = storageUnitStore();
|
const { getStorageUnitById } = storageUnitStore();
|
||||||
const { getMaterialById, setCurrentLocation, setNextLocation, setPreviousLocation, setIsPaused, setIsVisible, setEndTime } = materialStore();
|
const { getMaterialById, setCurrentLocation, setNextLocation, setPreviousLocation, setIsPaused, setIsVisible, setEndTime } = materialStore();
|
||||||
@@ -334,12 +334,14 @@ export function useTriggerHandler() {
|
|||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
}
|
}
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addVehicleToMonitor(vehicle.modelUuid,
|
addVehicleToMonitor(vehicle.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -362,12 +364,14 @@ export function useTriggerHandler() {
|
|||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
}
|
}
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addVehicleToMonitor(vehicle.modelUuid,
|
addVehicleToMonitor(vehicle.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -386,24 +390,11 @@ export function useTriggerHandler() {
|
|||||||
const human = getHumanById(trigger.triggeredAsset?.triggeredModel.modelUuid);
|
const human = getHumanById(trigger.triggeredAsset?.triggeredModel.modelUuid);
|
||||||
if (human) {
|
if (human) {
|
||||||
if (human.isActive === false && human.state === 'idle') {
|
if (human.isActive === false && human.state === 'idle') {
|
||||||
|
|
||||||
if (human && human.modelUuid === "cc62adae-7000-447b-b845-6d4910de503a") {
|
|
||||||
console.log(human);
|
|
||||||
}
|
|
||||||
const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
|
const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
|
||||||
if (conveyor) {
|
if (conveyor) {
|
||||||
if (!conveyor.isPaused) {
|
|
||||||
// Handle current action from vehicle
|
|
||||||
if (action.actionType === 'worker') {
|
|
||||||
setIsVisible(materialId, false);
|
|
||||||
}
|
|
||||||
setIsPaused(materialId, true);
|
|
||||||
handleAction(action, materialId);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addConveyorToMonitor(conveyor.modelUuid,
|
addConveyorToMonitor(conveyor.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -414,24 +405,14 @@ export function useTriggerHandler() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
addHumanToMonitor(human.modelUuid, () => {
|
addHumanToMonitor(human.modelUuid, () => {
|
||||||
const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
const conveyor = getConveyorById(action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid || '');
|
||||||
if (conveyor) {
|
if (conveyor) {
|
||||||
if (!conveyor.isPaused) {
|
|
||||||
// Handle current action from vehicle
|
|
||||||
if (action.actionType === 'worker') {
|
|
||||||
setIsVisible(materialId, false);
|
|
||||||
}
|
|
||||||
setIsPaused(materialId, true);
|
|
||||||
handleAction(action, materialId);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addConveyorToMonitor(conveyor.modelUuid,
|
addConveyorToMonitor(conveyor.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -442,7 +423,6 @@ export function useTriggerHandler() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,11 +437,13 @@ export function useTriggerHandler() {
|
|||||||
if (action.actionType === 'worker') {
|
if (action.actionType === 'worker') {
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
}
|
}
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addMachineToMonitor(machine.modelUuid,
|
addMachineToMonitor(machine.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -483,11 +465,13 @@ export function useTriggerHandler() {
|
|||||||
if (action.actionType === 'worker') {
|
if (action.actionType === 'worker') {
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
}
|
}
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addMachineToMonitor(machine.modelUuid,
|
addMachineToMonitor(machine.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -536,12 +520,14 @@ export function useTriggerHandler() {
|
|||||||
if (action.actionType === 'worker') {
|
if (action.actionType === 'worker') {
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
}
|
}
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
addHumanToMonitor(human.modelUuid,
|
addHumanToMonitor(human.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
if (action.actionType === 'worker') {
|
if (action.actionType === 'worker') {
|
||||||
@@ -711,7 +697,6 @@ export function useTriggerHandler() {
|
|||||||
|
|
||||||
setNextLocation(material.materialId, null);
|
setNextLocation(material.materialId, null);
|
||||||
|
|
||||||
|
|
||||||
if (action && human) {
|
if (action && human) {
|
||||||
|
|
||||||
if (human.isActive === false && human.state === 'idle') {
|
if (human.isActive === false && human.state === 'idle') {
|
||||||
@@ -719,10 +704,13 @@ export function useTriggerHandler() {
|
|||||||
// Handle current action from arm bot
|
// Handle current action from arm bot
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
|
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
addHumanToMonitor(human.modelUuid,
|
addHumanToMonitor(human.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
@@ -879,8 +867,10 @@ export function useTriggerHandler() {
|
|||||||
const previousModel = getEventByModelUuid(selectedProduct.productUuid, material.previous?.modelUuid || '');
|
const previousModel = getEventByModelUuid(selectedProduct.productUuid, material.previous?.modelUuid || '');
|
||||||
if (previousModel) {
|
if (previousModel) {
|
||||||
if (previousModel.type === 'transfer' && previousModel.modelUuid === model.modelUuid) {
|
if (previousModel.type === 'transfer' && previousModel.modelUuid === model.modelUuid) {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
addConveyorToMonitor(conveyor.modelUuid,
|
addConveyorToMonitor(conveyor.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
@@ -888,6 +878,7 @@ export function useTriggerHandler() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
}
|
}
|
||||||
// handleAction(action, materialId)
|
// handleAction(action, materialId)
|
||||||
@@ -898,12 +889,14 @@ export function useTriggerHandler() {
|
|||||||
if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||||
// Handle current action from vehicle
|
// Handle current action from vehicle
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addVehicleToMonitor(vehicle.modelUuid,
|
addVehicleToMonitor(vehicle.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -913,6 +906,7 @@ export function useTriggerHandler() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,8 +922,11 @@ export function useTriggerHandler() {
|
|||||||
const previousModel = getEventByModelUuid(selectedProduct.productUuid, material.previous?.modelUuid || '');
|
const previousModel = getEventByModelUuid(selectedProduct.productUuid, material.previous?.modelUuid || '');
|
||||||
if (previousModel) {
|
if (previousModel) {
|
||||||
if (previousModel.type === 'transfer' && previousModel.modelUuid === model.modelUuid) {
|
if (previousModel.type === 'transfer' && previousModel.modelUuid === model.modelUuid) {
|
||||||
|
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
addConveyorToMonitor(conveyor.modelUuid,
|
addConveyorToMonitor(conveyor.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
@@ -937,6 +934,7 @@ export function useTriggerHandler() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -946,12 +944,14 @@ export function useTriggerHandler() {
|
|||||||
if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.isPicking && vehicle.currentLoad < vehicle.point.action.loadCapacity) {
|
||||||
// Handle current action from vehicle
|
// Handle current action from vehicle
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Handle current action using Event Manager
|
// Handle current action using Event Manager
|
||||||
setIsPaused(materialId, true);
|
setIsPaused(materialId, true);
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
|
|
||||||
addVehicleToMonitor(vehicle.modelUuid,
|
addVehicleToMonitor(vehicle.modelUuid,
|
||||||
() => {
|
() => {
|
||||||
@@ -961,6 +961,7 @@ export function useTriggerHandler() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId)
|
handleAction(action, materialId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1259,7 +1260,7 @@ export function useTriggerHandler() {
|
|||||||
|
|
||||||
if (human) {
|
if (human) {
|
||||||
|
|
||||||
if (human.isActive === false && human.state === 'idle' && human.isPicking && human.currentLoad < human.point.action.loadCapacity) {
|
if (human.isActive === false && human.state === 'idle' && !human.isScheduled && human.currentLoad < human.point.action.loadCapacity) {
|
||||||
|
|
||||||
setIsVisible(materialId, false);
|
setIsVisible(materialId, false);
|
||||||
|
|
||||||
@@ -1276,6 +1277,7 @@ export function useTriggerHandler() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Handle current action from human
|
// Handle current action from human
|
||||||
|
setHumanScheduled(human.modelUuid, true);
|
||||||
handleAction(action, materialId);
|
handleAction(action, materialId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -1460,14 +1462,60 @@ export function useTriggerHandler() {
|
|||||||
actionUuid: material.current.actionUuid,
|
actionUuid: material.current.actionUuid,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setIsPaused(material.materialId, true);
|
||||||
|
setIsVisible(material.materialId, true);
|
||||||
|
|
||||||
|
const action = getActionByUuid(selectedProduct.productUuid, trigger.triggeredAsset.triggeredAction.actionUuid);
|
||||||
|
|
||||||
|
if (action && action.triggers.length > 0 &&
|
||||||
|
action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid &&
|
||||||
|
action.triggers[0]?.triggeredAsset?.triggeredAction?.actionUuid &&
|
||||||
|
action.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid) {
|
||||||
|
const model = getEventByModelUuid(selectedProduct.productUuid, action.triggers[0]?.triggeredAsset?.triggeredModel.modelUuid);
|
||||||
|
|
||||||
|
if (model?.type === 'roboticArm') {
|
||||||
|
addArmBotToMonitor(model.modelUuid, () => {
|
||||||
setNextLocation(material.materialId, {
|
setNextLocation(material.materialId, {
|
||||||
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid,
|
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid || '',
|
||||||
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid,
|
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid || '',
|
||||||
})
|
})
|
||||||
|
|
||||||
setIsPaused(material.materialId, false);
|
setIsPaused(material.materialId, false);
|
||||||
setIsVisible(material.materialId, true);
|
})
|
||||||
|
} else if (model?.type === 'vehicle') {
|
||||||
|
addVehicleToMonitor(model.modelUuid, () => {
|
||||||
|
setNextLocation(material.materialId, {
|
||||||
|
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid || '',
|
||||||
|
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid || '',
|
||||||
|
})
|
||||||
|
|
||||||
|
setIsPaused(material.materialId, false);
|
||||||
|
})
|
||||||
|
} else if (model?.type === 'transfer') {
|
||||||
|
setNextLocation(material.materialId, {
|
||||||
|
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid || '',
|
||||||
|
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid || '',
|
||||||
|
})
|
||||||
|
|
||||||
|
setIsPaused(material.materialId, false);
|
||||||
|
} else if (model?.type === 'human') {
|
||||||
|
addHumanToMonitor(model.modelUuid, () => {
|
||||||
|
setNextLocation(material.materialId, {
|
||||||
|
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid || '',
|
||||||
|
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid || '',
|
||||||
|
})
|
||||||
|
|
||||||
|
setIsPaused(material.materialId, false);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setNextLocation(material.materialId, {
|
||||||
|
modelUuid: trigger.triggeredAsset?.triggeredModel.modelUuid || '',
|
||||||
|
pointUuid: trigger.triggeredAsset?.triggeredPoint?.pointUuid || '',
|
||||||
|
})
|
||||||
|
|
||||||
|
setIsPaused(material.materialId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1510,8 +1558,31 @@ export function useTriggerHandler() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Event Manager Needed
|
setIsPaused(materialId, true);
|
||||||
|
|
||||||
|
addVehicleToMonitor(vehicle.modelUuid,
|
||||||
|
() => {
|
||||||
|
setIsPaused(materialId, false);
|
||||||
|
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 || '',
|
||||||
|
});
|
||||||
|
|
||||||
|
setNextLocation(material.materialId, null);
|
||||||
|
|
||||||
|
// Handle current action from vehicle
|
||||||
|
handleAction(action, materialId);
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { generateSoloNavMesh } from "@recast-navigation/generators";
|
|||||||
import { init as initRecastNavigation } from "@recast-navigation/core";
|
import { init as initRecastNavigation } from "@recast-navigation/core";
|
||||||
import { DebugDrawer, getPositionsAndIndices } from "@recast-navigation/three";
|
import { DebugDrawer, getPositionsAndIndices } from "@recast-navigation/three";
|
||||||
import { useSceneContext } from "../../../scene/sceneContext";
|
import { useSceneContext } from "../../../scene/sceneContext";
|
||||||
|
import { useToggleView } from "../../../../store/builder/store";
|
||||||
|
|
||||||
interface NavMeshDetailsProps {
|
interface NavMeshDetailsProps {
|
||||||
setNavMesh: (navMesh: any) => void;
|
setNavMesh: (navMesh: any) => void;
|
||||||
@@ -19,8 +20,10 @@ export default function NavMeshDetails({
|
|||||||
const { aisles } = aisleStore();
|
const { aisles } = aisleStore();
|
||||||
const { scene } = useThree();
|
const { scene } = useThree();
|
||||||
const { walls } = wallStore();
|
const { walls } = wallStore();
|
||||||
|
const { toggleView } = useToggleView();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (toggleView) return;
|
||||||
const initializeNavigation = async () => {
|
const initializeNavigation = async () => {
|
||||||
try {
|
try {
|
||||||
await initRecastNavigation();
|
await initRecastNavigation();
|
||||||
@@ -64,7 +67,7 @@ export default function NavMeshDetails({
|
|||||||
};
|
};
|
||||||
|
|
||||||
initializeNavigation();
|
initializeNavigation();
|
||||||
}, [scene, groupRef, aisles, walls]);
|
}, [scene, groupRef, aisles, walls, toggleView]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ interface HumansStore {
|
|||||||
clearHumans: () => void;
|
clearHumans: () => void;
|
||||||
|
|
||||||
setHumanActive: (modelUuid: string, isActive: boolean) => void;
|
setHumanActive: (modelUuid: string, isActive: boolean) => void;
|
||||||
setHumanPicking: (modelUuid: string, isPicking: boolean) => void;
|
setHumanScheduled: (modelUuid: string, isPicking: boolean) => void;
|
||||||
setHumanLoad: (modelUuid: string, load: number) => void;
|
setHumanLoad: (modelUuid: string, load: number) => void;
|
||||||
setHumanState: (
|
setHumanState: (
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
@@ -51,7 +51,7 @@ export const createHumanStore = () => {
|
|||||||
...event,
|
...event,
|
||||||
productUuid,
|
productUuid,
|
||||||
isActive: false,
|
isActive: false,
|
||||||
isPicking: false,
|
isScheduled: false,
|
||||||
idleTime: 0,
|
idleTime: 0,
|
||||||
activeTime: 0,
|
activeTime: 0,
|
||||||
currentLoad: 0,
|
currentLoad: 0,
|
||||||
@@ -92,11 +92,11 @@ export const createHumanStore = () => {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setHumanPicking: (modelUuid, isPicking) => {
|
setHumanScheduled: (modelUuid, isScheduled) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
const human = state.humans.find(h => h.modelUuid === modelUuid);
|
||||||
if (human) {
|
if (human) {
|
||||||
human.isPicking = isPicking;
|
human.isScheduled = isScheduled;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
22
app/src/types/simulationTypes.d.ts
vendored
22
app/src/types/simulationTypes.d.ts
vendored
@@ -224,7 +224,7 @@ interface StorageUnitStatus extends StorageEventSchema {
|
|||||||
interface HumanStatus extends HumanEventSchema {
|
interface HumanStatus extends HumanEventSchema {
|
||||||
productUuid: string;
|
productUuid: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
isPicking: boolean;
|
isScheduled: boolean;
|
||||||
idleTime: number;
|
idleTime: number;
|
||||||
activeTime: number;
|
activeTime: number;
|
||||||
currentLoad: number;
|
currentLoad: number;
|
||||||
@@ -287,3 +287,23 @@ interface MaterialHistoryEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MaterialHistorySchema = MaterialHistoryEntry[];
|
type MaterialHistorySchema = MaterialHistoryEntry[];
|
||||||
|
|
||||||
|
//IK
|
||||||
|
|
||||||
|
type Link = {
|
||||||
|
index: number;
|
||||||
|
enabled: boolean;
|
||||||
|
rotationMin?: [number, number, number];
|
||||||
|
rotationMax?: [number, number, number];
|
||||||
|
limitation?: [number, number, number];
|
||||||
|
};
|
||||||
|
|
||||||
|
type IK = {
|
||||||
|
target: number;
|
||||||
|
effector: number;
|
||||||
|
links: Link[];
|
||||||
|
minDistance?: number;
|
||||||
|
maxDistance?: number;
|
||||||
|
maxheight?: number;
|
||||||
|
minheight?: number;
|
||||||
|
} ;
|
||||||
|
|||||||
Reference in New Issue
Block a user