feat: 处理轮询时地图刷新的问题

This commit is contained in:
zhanghao 2026-08-06 13:46:08 +08:00
parent 2159b7f228
commit f5b1b70274
2 changed files with 64 additions and 69 deletions

View File

@ -100,7 +100,7 @@
</div> </div>
<div class="video-container"> <div class="video-container">
<div v-if="activeMode === 'auto' || activeController === 1" class="map-container"> <div v-if="activeMode === 'auto' || activeController === 1" class="map-container">
<MapCanvas v-if="robotList.length > 0" :clearMap="true" :robotList="currentRobot" ref="mapCanvasRef" /> <MapCanvas v-if="robotList.length > 0" :robotList="currentRobot" ref="mapCanvasRef" />
</div> </div>
<div v-if="activeMode === 'artificial' && activeController === 2" class="model-container"> <div v-if="activeMode === 'artificial' && activeController === 2" class="model-container">
<UrdfViewer ref="urdfViewerRef" modelPath="/inspection/elfin10/elfin10.urdf.xacro" /> <UrdfViewer ref="urdfViewerRef" modelPath="/inspection/elfin10/elfin10.urdf.xacro" />

View File

@ -28,16 +28,11 @@ import {
import { getMapJson } from '@/api/inspection/robot' import { getMapJson } from '@/api/inspection/robot'
import { useInspectionStore } from "@/store/modules/inspection"; import { useInspectionStore } from "@/store/modules/inspection";
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { clear } from 'ace-builds/src-noconflict/ext-code_lens';
const props = defineProps({ const props = defineProps({
robotList: { robotList: {
type: Array, type: Array,
default: () => [] default: () => []
},
clearMap: {
type: Boolean,
default: false
} }
}) })
@ -78,6 +73,9 @@ const applicationState = {
let mapCanvas; // DOM let mapCanvas; // DOM
let canvasCtx; // 2D let canvasCtx; // 2D
let animationFrameId;
let mapLoadVersion = 0;
const init = () => { const init = () => {
mapCanvas = document.getElementById('map-canvas'); mapCanvas = document.getElementById('map-canvas');
canvasCtx = mapCanvas.getContext('2d'); canvasCtx = mapCanvas.getContext('2d');
@ -191,7 +189,7 @@ function renderFrame(timestamp) {
// //
if (!applicationState.isMapLoaded) { if (!applicationState.isMapLoaded) {
requestAnimationFrame(renderFrame); // animationFrameId = requestAnimationFrame(renderFrame); //
return; return;
} }
@ -241,7 +239,7 @@ function renderFrame(timestamp) {
drawMapBoundary(canvasCtx, map); drawMapBoundary(canvasCtx, map);
// //
requestAnimationFrame(renderFrame); animationFrameId = requestAnimationFrame(renderFrame);
} }
const drawAllRobots = (ctx) => { const drawAllRobots = (ctx) => {
@ -354,14 +352,25 @@ const centerCanvasView = () => {
inspectionStore.camera.centerY = (map.originY + map.maxY) / 2; inspectionStore.camera.centerY = (map.originY + map.maxY) / 2;
} }
const loadSourceMap = async () => { const getConnectedRobot = (robotList = props.robotList) => {
const connectedRobot = props.robotList.find(item => item.connectStatus == 1); return robotList.find(item => item?.connectStatus == 1)
}
const getMapIdentity = (robotList = props.robotList) => {
const robot = getConnectedRobot(robotList)
return robot ? `${robot.id ?? ''}:${robot.robotMapName ?? ''}` : ''
}
const loadSourceMap = async (connectedRobot = getConnectedRobot()) => {
if (!connectedRobot) return; if (!connectedRobot) return;
const currentLoadVersion = ++mapLoadVersion;
const res = await getMapJson({ const res = await getMapJson({
robotId: connectedRobot.id, robotId: connectedRobot.id,
mapName: connectedRobot.robotMapName mapName: connectedRobot.robotMapName
}); });
if (currentLoadVersion !== mapLoadVersion) return;
if (res.code === 200) { if (res.code === 200) {
try { try {
const rawJsonObject = JSON.parse(res.data); // JSON const rawJsonObject = JSON.parse(res.data); // JSON
@ -373,20 +382,6 @@ const loadSourceMap = async () => {
} }
}; };
/**
*
* @param id 机器人编号
* @param name 机器人名称
* @param angleRad 角度
* @param color 颜色
*/
const addRobot = (id, name,x, y, angleRad, color) => {
const map = applicationState.parsedMap;
//
const robot = new MobileRobot(id, name, x, y, angleRad, color);
applicationState.robots.push(robot);
}
const parseRobotPosition = (currentPosition) => { const parseRobotPosition = (currentPosition) => {
if (!currentPosition) return null if (!currentPosition) return null
const values = String(currentPosition).split(',').map(Number) const values = String(currentPosition).split(',').map(Number)
@ -394,60 +389,58 @@ const parseRobotPosition = (currentPosition) => {
return values return values
} }
const moveRobot = (robot, dx, dy, dtheta = 0) => { const syncRobots = (robotList) => {
robot.x += dx; const previousRobots = new Map(applicationState.robots.map(robot => [robot.id, robot]));
robot.y += dy; const nextRobots = [];
robot.angle += dtheta;
robotList.forEach(item => {
const position = parseRobotPosition(item.currentPosition)
if (!position) return
const [x, y, angle] = position
const robot = previousRobots.get(item.id)
if (robot) {
robot.name = item.robotName
robot.x = x
robot.y = y
robot.angle = angle
nextRobots.push(robot)
return
}
nextRobots.push(new MobileRobot(
item.id,
item.robotName,
x,
y,
angle,
colorList[nextRobots.length % colorList.length]
))
})
applicationState.robots = nextRobots
} }
onMounted(() => { onMounted(() => {
init() init()
if (props.robotList.length > 0) { window.addEventListener('resize', resizeCanvasToContainer);
loadSourceMap() resizeCanvasToContainer();
requestAnimationFrame(renderFrame);
window.addEventListener('resize', resizeCanvasToContainer); //
resizeCanvasToContainer(); //
setTimeout(() => {
bindEvent() bindEvent()
props.robotList.forEach(item => { syncRobots(props.robotList)
const position = parseRobotPosition(item.currentPosition) loadSourceMap()
if (!position) return animationFrameId = requestAnimationFrame(renderFrame);
const [x, y, angle] = position
addRobot(item.id, item.robotName, x, y, angle, colorList[applicationState.robots.length % colorList.length])
})
}, 300)
}
}) })
const colorList = ['#00D4FF', '#FFB300', '#00FF88', '#ff5100', '#fff', '#15ff00', '#ff00d4', '#00d4ff'] const colorList = ['#00D4FF', '#FFB300', '#00FF88', '#ff5100', '#fff', '#15ff00', '#ff00d4', '#00d4ff']
watch(() => props.robotList, //
(newVal) => { watch(() => props.robotList, syncRobots)
if (newVal.length > 0) {
if (props.clearMap) {
applicationState.robots = []
}
loadSourceMap()
const ids = applicationState.robots.map(r => r.id); //
props.robotList.forEach(item => { watch(
const position = parseRobotPosition(item.currentPosition) () => getMapIdentity(props.robotList),
if (!position) return (newIdentity, oldIdentity) => {
const [x, y, angle] = position if (newIdentity && newIdentity !== oldIdentity) loadSourceMap()
if (!ids.includes(item.id)) {
addRobot(item.id, item.robotName, x, y, angle, colorList[applicationState.robots.length % colorList.length])
} else {
applicationState.robots.forEach(robot => {
if (robot.id === item.id) {
// moveRobot(robot, parseFloat(x) - robot.x, parseFloat(y) - robot.y, parseFloat(angle) - robot.angle)
robot.x = x
robot.y = y
robot.angle = angle
}
})
}
})
}
} }
) )
@ -458,6 +451,8 @@ defineExpose({
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', resizeCanvasToContainer) window.removeEventListener('resize', resizeCanvasToContainer)
cancelAnimationFrame(animationFrameId)
mapLoadVersion += 1
canvasCtx = null canvasCtx = null
}) })
</script> </script>