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

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'
# 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_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
VITE_BUILD_COMPRESS = gzip

View File

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

View File

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

View File

@ -1,4 +1,5 @@
<template>
<!-- 包含航空器路由的绘制 -->
<!-- 气象监测站弹窗 -->
<WeatherStationPopup
:visible="weatherStationVisible"
@ -51,6 +52,9 @@ import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { LineString } from 'ol/geom';
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';
//
@ -89,6 +93,21 @@ const props = defineProps({
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 labelSystem = ref(null);
@ -484,7 +503,7 @@ function updateVehiclePosition(vehicleData) {
}
//
applyCurrentCategorySettings(object_id);
// applyCurrentCategorySettings(object_id);
} else {
//
if (animationSystem.value) {
@ -679,12 +698,12 @@ function parseLineStringGeometry(lineString) {
// 线
function updateAircraftRoute(flightNo, coordinates, routeType, routeStatus) {
if (!aircraftRouteSource || !props.map) return;
console.log('原始航线坐标:', coordinates);
//
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 endPoint = projectedCoords[projectedCoords.length - 1];

View File

@ -104,7 +104,7 @@
<div class="control-group">
<label>服务器地址:</label>
<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>
</div>

View File

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

View File

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