uav-flight-control/src/views/map.vue

258 lines
6.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="map-container">
<mars-map :options="options" @onload="mapLoad"></mars-map>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import marsMap from "@/components/marsMap";
let options = {
scene: {
center: {
lat: 30.647679,
lng: 120.691682,
alt: 37478.2,
heading: 2.7,
pitch: -36.9,
},
showSun: false,
showMoon: false,
showSkyBox: false,
showSkyAtmosphere: false,
fog: false,
// backgroundColor: "#363635", // 天空背景色
globe: {
baseColor: "#363635", // 地球地面背景色
showGroundAtmosphere: false,
enableLighting: false,
},
clock: {
currentTime: "2023-11-01 12:00:00", // 固定光照时间
},
cameraController: {
zoomFactor: 1.5,
minimumZoomDistance: 0.1,
maximumZoomDistance: 200000,
enableCollisionDetection: false, // 允许进入地下
},
},
terrain: {
show: false,
},
basemaps: [
{
id: 2017,
pid: 10,
name: "蓝色底图",
icon: "https://data.mars3d.cn/img/thumbnail/basemap/my_blue.png",
type: "gaode",
layer: "vec",
chinaCRS: "GCJ02",
invertColor: true,
filterColor: "#015CB3",
brightness: 0.6,
contrast: 1.8,
gamma: 0.3,
hue: 1,
saturation: 0,
show: true,
},
],
};
const DIRECTION = {
UP: "w",
DOWN: "s",
LEFT: "a",
RIGHT: "d",
SPEED_UP: "q",
SPEED_DOWN: "e",
};
const keyboardMap = {
[DIRECTION.UP]: false,
[DIRECTION.DOWN]: false,
[DIRECTION.LEFT]: false,
[DIRECTION.RIGHT]: false,
[DIRECTION.SPEED_UP]: false,
[DIRECTION.SPEED_DOWN]: false,
};
let map = null;
let Cesium = {};
let mapLayer = {};
let uav = null;
const params = reactive({
lat: 31.162232,
lng: 120.734077,
altitude: 3000,
heading: 0, //当前朝向
pitch: 0, //保当前俯仰角
roll: 0, //当前翻滚角
correction: 1,
speed: 800,
gamepad: true,
});
/**
* 地图渲染完毕
* @param mapInstance 当前地图对象
*/
const mapLoad = (mapInstance) => {
map = mapInstance;
Cesium = mars3d.Cesium;
//创建marker图层
mapLayer.markerLayer = new mars3d.layer.GraphicLayer({
allowDrillPick: true, // 如果存在坐标完全相同的图标点可以打开该属性click事件通过graphics判断
});
map.addLayer(mapLayer.markerLayer);
boostrapUav();
};
/**
* 创建模型对象
*/
const initModel = () => {
uav = new mars3d.graphic.Route({
id: "uav",
name: "无人机模型",
model: {
url: "https://data.mars3d.cn/gltf/mars/wrj.glb",
scale: 5,
minimumPixelSize: 50,
runAnimations: true,
mergeOrientation: true,
},
camera: {
type: "gs",
radius: 25000,
heading: 25,
pitch: -35,
},
});
mapLayer.markerLayer.addGraphic(uav);
};
const boostrapUav = () => {
initModel();
onAddKeyboardListener();
const renderer = () => {
onAdjustParams();
onAdjustAttitude();
requestAnimationFrame(renderer);
};
renderer();
};
//开启按键监听
const onAddKeyboardListener = () => {
document.addEventListener("keydown", (e) => {
if (Object.keys(keyboardMap).includes(e.key)) {
keyboardMap[e.key] = true;
}
});
document.addEventListener("keyup", (e) => {
if (Object.keys(keyboardMap).includes(e.key)) {
keyboardMap[e.key] = false;
}
});
};
//开启飞行参数调整
const onAdjustParams = () => {
if (keyboardMap[DIRECTION.SPEED_UP]) {
params.speed += 100;
}
if (keyboardMap[DIRECTION.SPEED_DOWN]) {
if (params.speed >= 500) {
params.speed -= 100;
}
}
//机体爬升
if (keyboardMap[DIRECTION.UP] && params.pitch <= 0.3) {
params.pitch += 0.005;
if (params.pitch > 0) {
const { speed, pitch } = params;
const temp = (params.speed / 60 / 60 / 60) * 110;
//1经纬度约等于110km
params.altitude += temp * Math.sin(pitch);
}
}
//机体俯冲
if (keyboardMap[DIRECTION.DOWN] && params.pitch >= -0.3) {
params.pitch -= 0.006;
if (params.pitch < 0) {
const { speed, pitch } = params;
//1经纬度约等于110km
const temp = (params.speed / 60 / 60 / 60) * 110;
params.altitude += temp * Math.sin(pitch);
}
}
//机体左转
if (keyboardMap[DIRECTION.LEFT]) {
params.heading -= 0.115;
if (params.roll > -10) {
params.roll -= 0.115;
}
}
//机体右转
if (keyboardMap[DIRECTION.RIGHT]) {
params.heading += 0.115;
if (params.roll < 10) {
params.roll += 0.115;
}
}
const { heading, pitch, roll } = params;
const { abs, cos } = Math;
params.correction = abs(cos(heading) * cos(pitch));
if (abs(heading) < 0.001) params.heading = 0;
if (abs(roll) < 0.001) params.roll = 0;
if (abs(pitch) < 0.001) params.pitch = 0;
//方向自动回正
// if (params.heading > 0) params.heading -= 0.0025
// if (params.heading < 0) params.heading += 0.0025
if (params.roll > 0) params.roll -= 0.003;
if (params.roll < 0) params.roll += 0.003;
if (params.pitch < 0) params.pitch += 0.005;
if (params.pitch > 0) params.pitch -= 0.003;
};
// 开启飞行姿态调整/
const onAdjustAttitude = () => {
const temp = params.speed / 60 / 60 / 60 / 110;
params.lng += temp * Math.cos(params.heading);
params.lat -= temp * Math.sin(params.heading);
const { lng, lat, altitude, heading, pitch, roll } = params;
params.altitude += temp * Math.sin(pitch) * 110 * 1000 * 10;
const position = Cesium.Cartesian3.fromDegrees(lng, lat, altitude);
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
uav.model.setStyle({
heading,
pitch,
roll
});
// uav.model.orientation= orientation //【问题:这一步需要修改通过键盘左右键的时候无人机需要做相关动作,而现在这个参数只只读,现在只能更改坐标,飞机无动作】
uav.addTimePosition(position);
};
</script>
<style lang="scss" scoped>
.map-container {
height: 100%;
}
</style>