修改车辆动画位置更新与方向更新不同步

This commit is contained in:
GAO 2025-07-28 16:00:20 +08:00
parent e2f92ab293
commit 26fdd3742e
8 changed files with 75 additions and 33 deletions

View File

@ -8,4 +8,4 @@ VITE_APP_ENV = 'development'
VITE_APP_BASE_API = '/dev-api' VITE_APP_BASE_API = '/dev-api'
# WebSocket配置 # WebSocket配置
VITE_APP_WEBSOCKET_URL=ws://10.0.0.126:8080/collision VITE_APP_WEBSOCKET_URL=ws://10.0.0.122:8080/collision

View File

@ -5,9 +5,9 @@ VITE_APP_TITLE = 青岛机场无人驾驶车辆协同云平台
VITE_APP_ENV = 'production' VITE_APP_ENV = 'production'
# 青岛机场无人驾驶车辆协同云平台/生产环境 # 青岛机场无人驾驶车辆协同云平台/生产环境
VITE_APP_BASE_API = 'http://10.0.0.126:8080' VITE_APP_BASE_API = 'http://10.0.0.122:8080'
VITE_APP_WEBSOCKET_URL='ws://10.0.0.124:8080/collision' VITE_APP_WEBSOCKET_URL='ws://10.0.0.122:8080/collision'
# 是否在打包时开启压缩,支持 gzip 和 brotli # 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip VITE_BUILD_COMPRESS = gzip

View File

@ -76,7 +76,7 @@ function handleSetCategoryVisibility(type, settings) {
// EPSG:4528 // EPSG:4528
proj4.defs( proj4.defs(
"EPSG:4528", "EPSG:4528",
"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs" "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
); );
register(proj4); register(proj4);
const projection = getProjection("EPSG:4528"); const projection = getProjection("EPSG:4528");

View File

@ -86,6 +86,8 @@ function updateVehicleAnimations(deltaTime) {
if (!animData) return; if (!animData) return;
// //
//
//
ensureContinuousMovement(animData, vehicle, currentTime, deltaTime); ensureContinuousMovement(animData, vehicle, currentTime, deltaTime);
// //
@ -157,9 +159,11 @@ function updateVehicleAnimations(deltaTime) {
// //
if (props.getVehicleStyle) { if (props.getVehicleStyle) {
const currentHeading = vehicle ? vehicle.heading : 0; // const currentHeading = vehicle ? vehicle.heading : 0;
// //使heading
const currentHeading = animData.heading !== undefined ? animData.heading : (vehicle ? vehicle.heading : 0);
if (!animData.lastHeading || Math.abs(animData.lastHeading - currentHeading) > 1) { if (!animData.lastHeading || Math.abs(animData.lastHeading - currentHeading) > 5) {
feature.setStyle(props.getVehicleStyle(id, currentSpeed, currentHeading)); feature.setStyle(props.getVehicleStyle(id, currentSpeed, currentHeading));
animData.lastHeading = currentHeading; animData.lastHeading = currentHeading;
} }
@ -182,7 +186,7 @@ function updateVehiclePathHistory(id, animData, currentTime) {
} }
// 150ms // 150ms
if (!animData.lastPathRecordTime || currentTime - animData.lastPathRecordTime > 150) { if (!animData.lastPathRecordTime || currentTime - animData.lastPathRecordTime > 100) {
// //
animData.pathHistory.push({ animData.pathHistory.push({
time: currentTime, time: currentTime,
@ -209,23 +213,25 @@ function ensureContinuousMovement(animData, vehicle, currentTime, deltaTime) {
// //
if (!animData.predictionVector) { if (!animData.predictionVector) {
// 使 // 使
if (animData.pathHistory && animData.pathHistory.length >= 2) { if (animData.pathHistory && animData.pathHistory.length >= 2) {//
//
const latest = animData.pathHistory[animData.pathHistory.length - 1]; const latest = animData.pathHistory[animData.pathHistory.length - 1];
const previous = animData.pathHistory[animData.pathHistory.length - 2]; const previous = animData.pathHistory[animData.pathHistory.length - 2];
//position:[x,y]
//
const dx = latest.position[0] - previous.position[0]; const dx = latest.position[0] - previous.position[0];
const dy = latest.position[1] - previous.position[1]; const dy = latest.position[1] - previous.position[1];
const len = Math.sqrt(dx * dx + dy * dy); const len = Math.sqrt(dx * dx + dy * dy);
if (len > 0) { if (len > 0) {
// //
animData.predictionVector = [dx / len, dy / len]; animData.predictionVector = [dx / len, dy / len]; //
} else { } else {
// //
animData.predictionVector = [0, 1]; animData.predictionVector = [0, 1];
} }
} else { } else {
// //
animData.predictionVector = [0, 1]; animData.predictionVector = [0, 1];
} }
} }
@ -235,8 +241,22 @@ function ensureContinuousMovement(animData, vehicle, currentTime, deltaTime) {
animData.targetPosition = [ animData.targetPosition = [
animData.position[0] + animData.predictionVector[0] * moveDistance, animData.position[0] + animData.predictionVector[0] * moveDistance,
animData.position[1] + animData.predictionVector[1] * moveDistance animData.position[1] + animData.predictionVector[1] * moveDistance
]; ];//
// ========== ==========
if (animData.predictionVector[0] !== 0 || animData.predictionVector[1] !== 0) {
//
const moveAngle = Math.atan2(animData.predictionVector[1], animData.predictionVector[0]);
// heading
let predictedHeading = (moveAngle * 180 / Math.PI + 72) % 360; // 72
if (predictedHeading < 0) predictedHeading += 360;
// //
animData.targetHeading = predictedHeading;
//
// animData.heading = predictedHeading; //
}
// //
if (!animData.lastSpeedReduction || currentTime - animData.lastSpeedReduction > 2000) { if (!animData.lastSpeedReduction || currentTime - animData.lastSpeedReduction > 2000) {
animData.speed = Math.max(animData.speed * 0.95, MIN_SPEED); animData.speed = Math.max(animData.speed * 0.95, MIN_SPEED);
@ -246,9 +266,9 @@ function ensureContinuousMovement(animData, vehicle, currentTime, deltaTime) {
} }
// //
function predictFuturePath(animData) { function predictFuturePath(animData) {//animData
if (!animData.pathHistory || animData.pathHistory.length < 3) { if (!animData.pathHistory || animData.pathHistory.length < 3) {
return null; return null;//
} }
// //
@ -261,6 +281,7 @@ function predictFuturePath(animData) {
let totalWeight = 0; let totalWeight = 0;
// //
// 1~2
for (let i = points - 2; i >= 0; i--) { for (let i = points - 2; i >= 0; i--) {
const curr = history[i + 1]; const curr = history[i + 1];
const prev = history[i]; const prev = history[i];
@ -307,7 +328,7 @@ function predictFuturePath(animData) {
const predictionVector = [ const predictionVector = [
normalizedDx * speedFactor, normalizedDx * speedFactor,
normalizedDy * speedFactor normalizedDy * speedFactor
]; ];//
// //
const predictedPosition = [ const predictedPosition = [
@ -318,7 +339,7 @@ function predictFuturePath(animData) {
return { return {
vector: predictionVector, vector: predictionVector,
position: predictedPosition position: predictedPosition
}; };//
} }
// //
@ -344,9 +365,9 @@ function initVehicleAnimation(id, coordinates, heading, speed) {
vehicleMotionHistory.value[id] = []; vehicleMotionHistory.value[id] = [];
} }
// - // -
function updateVehicleAnimationTarget(id, coordinates, heading, speed) { function updateVehicleAnimationTarget(id, coordinates, heading, speed) {
const animData = vehicleAnimations.value[id] || {}; const animData = vehicleAnimations.value[id] || {};//ID
const now = Date.now(); const now = Date.now();
// //
@ -357,7 +378,7 @@ function updateVehicleAnimationTarget(id, coordinates, heading, speed) {
const dx = coordinates[0] - animData.position[0]; const dx = coordinates[0] - animData.position[0];
const dy = coordinates[1] - animData.position[1]; const dy = coordinates[1] - animData.position[1];
const distance = Math.sqrt(dx * dx + dy * dy); const distance = Math.sqrt(dx * dx + dy * dy);
//
if (distance > 0.0001) { if (distance > 0.0001) {
// //
predictionVector = [dx / distance, dy / distance]; predictionVector = [dx / distance, dy / distance];
@ -370,7 +391,7 @@ function updateVehicleAnimationTarget(id, coordinates, heading, speed) {
} else { } else {
animData.speedHistory.push(speed); animData.speedHistory.push(speed);
if (animData.speedHistory.length > 3) { if (animData.speedHistory.length > 3) {
animData.speedHistory.shift(); animData.speedHistory.shift();//3
} }
} }
@ -383,7 +404,8 @@ function updateVehicleAnimationTarget(id, coordinates, heading, speed) {
...animData, ...animData,
targetPosition: coordinates, targetPosition: coordinates,
targetHeading: heading, targetHeading: heading,
heading: animData.heading || heading, // heading: animData.heading || heading,
heading: animData.heading !== undefined ? animData.heading : heading,
position: animData.position || coordinates, position: animData.position || coordinates,
speed: smoothedSpeed, speed: smoothedSpeed,
lastUpdated: now, lastUpdated: now,
@ -402,10 +424,10 @@ function stopAnimationLoop() {
// //
function resetAnimations() { function resetAnimations() {
vehicleAnimations.value = {}; vehicleAnimations.value = {};//
vehicleMotionHistory.value = {}; vehicleMotionHistory.value = {};//
Object.keys(props.vehicles).forEach(id => { Object.keys(props.vehicles).forEach(id => {//props.vehiclesID
const vehicle = props.vehicles[id]; const vehicle = props.vehicles[id];
if (vehicle) { if (vehicle) {
vehicleAnimations.value[id] = { vehicleAnimations.value[id] = {

View File

@ -1,4 +1,5 @@
<template> <template>
<!-- 包含航空器路由的绘制 -->
<!-- 气象监测站弹窗 --> <!-- 气象监测站弹窗 -->
<WeatherStationPopup <WeatherStationPopup
:visible="weatherStationVisible" :visible="weatherStationVisible"
@ -51,6 +52,9 @@ import Feature from 'ol/Feature';
import Point from 'ol/geom/Point'; import Point from 'ol/geom/Point';
import { LineString } from 'ol/geom'; import { LineString } from 'ol/geom';
import { transform } from 'ol/proj'; import { transform } from 'ol/proj';
import proj4 from 'proj4';
import { register } from 'ol/proj/proj4.js';
import { get as getProj } from 'ol/proj';
import WebSocketService, { createWebSocket, resetWebSocketInstance } from '../../../utils/websocket.js'; import WebSocketService, { createWebSocket, resetWebSocketInstance } from '../../../utils/websocket.js';
// //
@ -89,6 +93,21 @@ const props = defineProps({
map: Object map: Object
}); });
// CGCS2000 / 3-degree Gauss-Kruger CM 120E (EPSG:4547)
if (typeof window !== 'undefined' && proj4) {
//
if (!proj4.defs('EPSG:4528')) {
proj4.defs(
"EPSG:4528",
"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
);
console.log('已注册 EPSG:4528 坐标系');
}
// OpenLayers
register(proj4);
}
console.log("注册EPSG:4528",getProj('EPSG:4528'));
// //
const animationSystem = ref(null); const animationSystem = ref(null);
const labelSystem = ref(null); const labelSystem = ref(null);
@ -484,7 +503,7 @@ function updateVehiclePosition(vehicleData) {
} }
// //
applyCurrentCategorySettings(object_id); // applyCurrentCategorySettings(object_id);
} else { } else {
// //
if (animationSystem.value) { if (animationSystem.value) {
@ -679,12 +698,12 @@ function parseLineStringGeometry(lineString) {
// 线 // 线
function updateAircraftRoute(flightNo, coordinates, routeType, routeStatus) { function updateAircraftRoute(flightNo, coordinates, routeType, routeStatus) {
if (!aircraftRouteSource || !props.map) return; if (!aircraftRouteSource || !props.map) return;
console.log('原始航线坐标:', coordinates);
// //
const projectedCoords = coordinates.map(coord => const projectedCoords = coordinates.map(coord =>
transform(coord, 'EPSG:4326', props.map.getView().getProjection()) transform(coord, 'EPSG:4528', props.map.getView().getProjection())
); );
console.log('处理后的坐标:', projectedCoords);
// //
const startPoint = projectedCoords[0]; const startPoint = projectedCoords[0];
const endPoint = projectedCoords[projectedCoords.length - 1]; const endPoint = projectedCoords[projectedCoords.length - 1];

View File

@ -104,7 +104,7 @@
<div class="control-group"> <div class="control-group">
<label>服务器地址:</label> <label>服务器地址:</label>
<select id="collisionServerSelect"> <select id="collisionServerSelect">
<option value="ws://10.0.0.126:8080/collision">10.0.0.126:8080/collision</option> <option value="ws://10.0.0.122:8080/collision">10.0.0.122:8080/collision</option>
</select> </select>
</div> </div>

View File

@ -334,7 +334,7 @@ watch(() => mapRef.value?.map, (newMap) => {
/* 告警统计卡片 */ /* 告警统计卡片 */
.alarm-stats-card { .alarm-stats-card {
position: absolute; position: absolute;
top: 177px; top: 23%;
left: 28px; left: 28px;
width: 246px; width: 246px;
height: 147px; height: 147px;
@ -347,6 +347,7 @@ watch(() => mapRef.value?.map, (newMap) => {
border: 0.5px solid rgba(222, 213, 213, 0.53); border: 0.5px solid rgba(222, 213, 213, 0.53);
overflow: hidden; overflow: hidden;
} }
.stats-header { .stats-header {
display: flex; display: flex;

View File

@ -32,7 +32,7 @@ export default defineConfig(({ mode, command }) => {
// https://cn.vitejs.dev/config/#server-proxy // https://cn.vitejs.dev/config/#server-proxy
'/dev-api': { '/dev-api': {
// target: 'http://10.0.0.17:8099',//昊天 // target: 'http://10.0.0.17:8099',//昊天
target: 'http://10.0.0.126:8080',//田哥 target: 'http://10.0.0.122:8080',//田哥
changeOrigin: true, changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '') rewrite: (p) => p.replace(/^\/dev-api/, '')
} }