fix(playback): 增强回放WebSocket钩子,确保首次接收AMR数据后初始化机器人图元
This commit is contained in:
parent
4a45782d5e
commit
8e7f00ec50
@ -44,7 +44,10 @@ export interface UsePlaybackWebSocketReturn {
|
|||||||
changeSpeed: (speed: number) => void; // Placeholder for speed control
|
changeSpeed: (speed: number) => void; // Placeholder for speed control
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | undefined>): UsePlaybackWebSocketReturn {
|
export function usePlaybackWebSocket(
|
||||||
|
editorService: ShallowRef<EditorService | undefined>,
|
||||||
|
onFirstAmrData?: () => void,
|
||||||
|
): UsePlaybackWebSocketReturn {
|
||||||
const client = shallowRef<WebSocket | null>(null);
|
const client = shallowRef<WebSocket | null>(null);
|
||||||
const isConnected = ref(false);
|
const isConnected = ref(false);
|
||||||
const isPlaying = ref(false);
|
const isPlaying = ref(false);
|
||||||
@ -54,6 +57,7 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
|
|||||||
const currentSceneId = ref<string | null>(null);
|
const currentSceneId = ref<string | null>(null);
|
||||||
const sceneJson = ref<string | null>(null);
|
const sceneJson = ref<string | null>(null);
|
||||||
const locationData = ref<any[]>([]); // 新增:库位数据的响应式引用
|
const locationData = ref<any[]>([]); // 新增:库位数据的响应式引用
|
||||||
|
let hasReceivedAmrData = false; // 新增:用于确保 onFirstAmrData 只调用一次的标志
|
||||||
|
|
||||||
const { calculateCenterPoint, jumpToPosition } = useViewState();
|
const { calculateCenterPoint, jumpToPosition } = useViewState();
|
||||||
|
|
||||||
@ -104,6 +108,11 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
|
|||||||
(msg.data as RobotRealtimeInfo[]).forEach((robot) => {
|
(msg.data as RobotRealtimeInfo[]).forEach((robot) => {
|
||||||
latestRobotData.set(robot.id, robot);
|
latestRobotData.set(robot.id, robot);
|
||||||
});
|
});
|
||||||
|
// [关键修复] 仅在第一次收到AMR数据时触发回调
|
||||||
|
if (!hasReceivedAmrData) {
|
||||||
|
hasReceivedAmrData = true;
|
||||||
|
onFirstAmrData?.();
|
||||||
|
}
|
||||||
} else if (msg.type === 'LOCATION') {
|
} else if (msg.type === 'LOCATION') {
|
||||||
// 新增:处理库位数据
|
// 新增:处理库位数据
|
||||||
locationData.value = msg.data;
|
locationData.value = msg.data;
|
||||||
|
|||||||
@ -107,7 +107,10 @@ const leftSiderEl = shallowRef<HTMLElement>();
|
|||||||
const isPlaybackControllerVisible = ref<boolean>(true);
|
const isPlaybackControllerVisible = ref<boolean>(true);
|
||||||
const selectedDate = ref<Dayjs>();
|
const selectedDate = ref<Dayjs>();
|
||||||
|
|
||||||
const playback = usePlaybackWebSocket(editor);
|
const playback = usePlaybackWebSocket(editor, async () => {
|
||||||
|
// [关键修复] 只有在收到第一帧机器人数据后才初始化机器人图元
|
||||||
|
await editor.value?.initRobots();
|
||||||
|
});
|
||||||
|
|
||||||
watch(mode, async (newMode) => {
|
watch(mode, async (newMode) => {
|
||||||
if (newMode === 'live') {
|
if (newMode === 'live') {
|
||||||
@ -125,8 +128,8 @@ watch(mode, async (newMode) => {
|
|||||||
watch(playback.sceneJson, async (newJson) => {
|
watch(playback.sceneJson, async (newJson) => {
|
||||||
if (newJson) {
|
if (newJson) {
|
||||||
await editor.value?.load(newJson);
|
await editor.value?.load(newJson);
|
||||||
// [关键修复] 场景加载后,立即重新初始化机器人
|
// [移除] 不再需要在这里初始化机器人,交由 onFirstAmrData 回调处理
|
||||||
await editor.value?.initRobots();
|
// await editor.value?.initRobots();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -205,8 +208,8 @@ watch(playback.currentTime, (newTimestamp) => {
|
|||||||
watch(playback.sceneJson, async (newJson) => {
|
watch(playback.sceneJson, async (newJson) => {
|
||||||
if (newJson) {
|
if (newJson) {
|
||||||
await editor.value?.load(newJson);
|
await editor.value?.load(newJson);
|
||||||
// [关键修复] 场景加载后,立即重新初始化机器人
|
// [移除] 不再需要在这里初始化机器人,交由 onFirstAmrData 回调处理
|
||||||
await editor.value?.initRobots();
|
// await editor.value?.initRobots();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -258,7 +261,7 @@ const readScene = async () => {
|
|||||||
* 采用 requestAnimationFrame 优化高频数据渲染,确保动画流畅且不阻塞UI线程。
|
* 采用 requestAnimationFrame 优化高频数据渲染,确保动画流畅且不阻塞UI线程。
|
||||||
*/
|
*/
|
||||||
const monitorScene = async () => {
|
const monitorScene = async () => {
|
||||||
console.log(current.value?.id);
|
console.log('[实时模式] 开始监控场景, current:', current.value?.id);
|
||||||
client.value?.close();
|
client.value?.close();
|
||||||
// 根据路由路径是否是真实场景监控决定使用哪个监控接口
|
// 根据路由路径是否是真实场景监控决定使用哪个监控接口
|
||||||
const sidWithFloor = isMultiFloor.value ? `${props.sid}/${currentFloorIndex.value + 1}` : props.sid;
|
const sidWithFloor = isMultiFloor.value ? `${props.sid}/${currentFloorIndex.value + 1}` : props.sid;
|
||||||
@ -278,6 +281,7 @@ const monitorScene = async () => {
|
|||||||
* @param updates 需要更新的机器人数据数组
|
* @param updates 需要更新的机器人数据数组
|
||||||
*/
|
*/
|
||||||
const batchUpdateRobots = (updates: Array<{ id: string; data: RobotRealtimeInfo }>) => {
|
const batchUpdateRobots = (updates: Array<{ id: string; data: RobotRealtimeInfo }>) => {
|
||||||
|
console.log('[实时模式] batchUpdateRobots 被调用,更新数量:', updates.length);
|
||||||
if (!editor.value || updates.length === 0) return;
|
if (!editor.value || updates.length === 0) return;
|
||||||
|
|
||||||
// 用于收集所有图元(pen)的更新数据
|
// 用于收集所有图元(pen)的更新数据
|
||||||
@ -299,6 +303,7 @@ const monitorScene = async () => {
|
|||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
// 1. 更新机器人缓存的业务数据
|
// 1. 更新机器人缓存的业务数据
|
||||||
|
console.log('[实时模式] 更新机器人业务数据:', id, { x, y, active, angle });
|
||||||
editor.value?.updateRobot(id, {
|
editor.value?.updateRobot(id, {
|
||||||
...rest,
|
...rest,
|
||||||
isCharging: isCharging as any,
|
isCharging: isCharging as any,
|
||||||
@ -338,6 +343,7 @@ const monitorScene = async () => {
|
|||||||
penUpdatePayload.y = y - 60;
|
penUpdatePayload.y = y - 60;
|
||||||
penUpdatePayload.visible = true;
|
penUpdatePayload.visible = true;
|
||||||
penUpdatePayload.locked = LockState.None;
|
penUpdatePayload.locked = LockState.None;
|
||||||
|
console.log('[实时模式] 设置机器人可见性:', id, { x: x - 60, y: y - 60, visible: true });
|
||||||
}
|
}
|
||||||
if (angle != null) {
|
if (angle != null) {
|
||||||
penUpdatePayload.rotate = -angle + 180;
|
penUpdatePayload.rotate = -angle + 180;
|
||||||
@ -423,6 +429,7 @@ const monitorScene = async () => {
|
|||||||
*/
|
*/
|
||||||
ws.onmessage = (e) => {
|
ws.onmessage = (e) => {
|
||||||
const data = JSON.parse(e.data || '{}');
|
const data = JSON.parse(e.data || '{}');
|
||||||
|
console.log('[实时模式] 收到WebSocket数据:', data);
|
||||||
|
|
||||||
// 判断数据类型:type=99为自动门点,其他为机器人
|
// 判断数据类型:type=99为自动门点,其他为机器人
|
||||||
if (data.type === 99) {
|
if (data.type === 99) {
|
||||||
@ -431,6 +438,7 @@ const monitorScene = async () => {
|
|||||||
} else {
|
} else {
|
||||||
// 机器人数据处理
|
// 机器人数据处理
|
||||||
const robotData = data as RobotRealtimeInfo;
|
const robotData = data as RobotRealtimeInfo;
|
||||||
|
console.log('[实时模式] 收到机器人数据:', robotData.id, { x: robotData.x, y: robotData.y, active: robotData.active });
|
||||||
latestRobotData.set(robotData.id, robotData);
|
latestRobotData.set(robotData.id, robotData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -541,9 +549,14 @@ onMounted(() => {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
console.log('Current route in movement-supervision.vue:', window.location.href);
|
console.log('Current route in movement-supervision.vue:', window.location.href);
|
||||||
if (mode.value === 'live') {
|
if (mode.value === 'live') {
|
||||||
|
console.log('[实时模式] 初始化实时模式');
|
||||||
await readScene();
|
await readScene();
|
||||||
|
// [关键修复] 实时模式下需要显式初始化机器人
|
||||||
|
console.log('[实时模式] 初始化机器人图元');
|
||||||
|
await editor.value?.initRobots();
|
||||||
await monitorScene();
|
await monitorScene();
|
||||||
} else {
|
} else {
|
||||||
|
console.log('[回放模式] 初始化回放模式');
|
||||||
playback.connect(props.sid);
|
playback.connect(props.sid);
|
||||||
// [调试代码] 自动设置回放日期和时间
|
// [调试代码] 自动设置回放日期和时间
|
||||||
const debugDate = dayjs('2025-09-28 09:00:00');
|
const debugDate = dayjs('2025-09-28 09:00:00');
|
||||||
@ -551,7 +564,8 @@ onMounted(async () => {
|
|||||||
playback.seek(debugDate.valueOf());
|
playback.seek(debugDate.valueOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
await editor.value?.initRobots();
|
// [移除] 不再需要在这里初始化机器人,交由 onFirstAmrData 回调处理
|
||||||
|
// await editor.value?.initRobots();
|
||||||
|
|
||||||
storageLocationService.value?.startMonitoring({ interval: 1 });
|
storageLocationService.value?.startMonitoring({ interval: 1 });
|
||||||
// 自动保存和恢复视图状态
|
// 自动保存和恢复视图状态
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user