From 2abd8e08f2148331e14bf1332e05f5d6302f82de Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Tue, 15 Apr 2025 20:27:56 +0800
Subject: [PATCH] feat: 当前任务详情35%
---
src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel.vue | 299 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 261 insertions(+), 38 deletions(-)
diff --git a/src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel.vue b/src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel.vue
index a7f0956..5ef46bc 100644
--- a/src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel.vue
+++ b/src/views/TaskManage/TaskIntermediateContent/CurrentTaskDetails/ControlPanel.vue
@@ -1,32 +1,124 @@
<template>
<div class="pointControl">
+ <div class="manualControl"></div>
+
<div class="direction">
- <div class="blackBg directionUp">
- <el-button type="primary" @click="control">控制</el-button>
- <el-button type="primary" @click="cancelControl">取消控制</el-button>
- <el-button type="primary" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @mouseup="onMouseUp">q</el-button>
+ <div class="boxTitle">
+ 飞
+ <br />
+ 行
+ <br />
+ 控
+ <br />
+ 制
+ <br />
+ 器
</div>
- <div class="blackBg directionDown"></div>
+ <div class="btnGroup">
+ <div class="btnGroupT">
+ <div class="btnItem" v-for="item in list1">
+ <el-icon class="btnIcon">
+ <component :is="item.icon" />
+ </el-icon>
+ <div class="btn" @mousedown="onMouseDown(item.key)" @mouseup="onMouseUp">{{ item.text }}</div>
+ </div>
+ </div>
+ <div class="btnGroupB">
+ <div class="btnItem" v-for="item in list2">
+ <div class="btn" @mousedown="onMouseDown(item.key)" @mouseup="onMouseUp">{{ item.text }}</div>
+ <el-icon class="btnIcon">
+ <component :is="item.icon" />
+ </el-icon>
+ </div>
+ </div>
+ </div>
+
+ <div class="speed">
+ <el-icon class="btnIcon">
+ <Plus />
+ </el-icon>
+ <div>5<br>m/s</div>
+ <el-icon class="btnIcon">
+ <Minus />
+ </el-icon>
+ </div>
+
+
+ <div class="upAndDown">
+ <div class="btnGroupT">
+ <div class="btnItem">
+ <el-icon class="btnIcon">
+ <Top />
+ </el-icon>
+ <div class="btn" @mousedown="onMouseDown(KeyCode.ARROW_UP)" @mouseup="onMouseUp">C</div>
+ </div>
+ </div>
+ <div class="btnGroupT">
+ <div class="btnItem">
+ <div class="btn" @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @mouseup="onMouseUp">Z</div>
+ <el-icon class="btnIcon">
+ <Bottom />
+ </el-icon>
+ </div>
+ </div>
+ </div>
+
</div>
- <ControlComPass />
+ <div class="compass">
+ <ControlComPass />
+ </div>
+
+ <div class="ptzControl">
+ <div>
+ 云
+ <br />
+ 台
+ <br />
+ 控
+ <br />
+ 制
+ </div>
+ <div></div>
+ </div>
</div>
</template>
<script setup>
import ControlComPass from './ControlComPass/ControlComPass.vue'
-import {
- KeyCode,
- useManualControl,
-} from '@/hooks/controlDrone/useManualControl'
-import { useMqtt } from '@/hooks/controlDrone/useMqtt'
-import { useConnectDrone } from '@/hooks/controlDrone/useConnectDrone'
-import { droneController, exitController, postDrcExit } from '@/api/drc'
+import { KeyCode, useManualControl } from '@/hooks/controlDrone/useManualControl'
+import { droneController, exitController, postDrc, postDrcExit } from '@/api/drc'
import { ElMessage } from 'element-plus'
import { useStore } from 'vuex'
+import { UranusMqtt } from '@/mqtt'
+import {
+ ArrowDown,
+ ArrowLeft,
+ ArrowRight,
+ ArrowUp,
+ Bottom, Minus,
+ Plus,
+ RefreshLeft,
+ RefreshRight,
+} from '@element-plus/icons-vue'
const deviceOsdInfo = inject('deviceOsdInfo')
const taskDetails = inject('taskDetails')
+const store = useStore()
+const workspace_id = computed(() => taskDetails.value.way_lines[0].workspace_id)
+const dock_sn = computed(() => taskDetails.value.device_sns[0])
+const list1 = [
+ { key: KeyCode.KEY_Q, text: 'Q', icon: RefreshLeft },
+ { key: KeyCode.KEY_W, text: 'W', icon: ArrowUp },
+ { key: KeyCode.KEY_E, text: 'E', icon: RefreshRight },
+]
+const list2 = [
+ { key: KeyCode.KEY_A, text: 'A', icon: ArrowLeft },
+ { key: KeyCode.KEY_S, text: 'S', icon: ArrowDown },
+ { key: KeyCode.KEY_D, text: 'D', icon: ArrowRight },
+]
+let mqttState = null
+const client_id = ref('')
const deviceTopicInfo = ref({
sn: deviceOsdInfo.value?.data?.sn,
@@ -36,29 +128,21 @@
const flightController = ref(false)
console.log('控制面板')
-// 连接无人机mqtt 成功获得有效控制
-useConnectDrone()
-
-// 订阅消息
-useMqtt(deviceTopicInfo.value)
-
-// 使用手动控制
-const { handleKeyup, handleEmergencyStop, resetControlState } = useManualControl(
- deviceTopicInfo.value,
- flightController
-)
+// 控制对象
+let manualControl = {}
function onMouseDown(type) {
- console.log('anxia')
- handleKeyup(type)
+ manualControl?.handleKeyup(type)
}
-const store = useStore()
-const clientId = computed(() => store.state.common.clientId)
-const dock_sn = computed(() => taskDetails.value.device_sns[0])
+function onMouseUp() {
+ console.log('弹起')
+ manualControl?.resetControlState()
+}
+// 取消手动控制
function cancelControl() {
- exitController({ client_id: clientId.value, dock_sn:dock_sn.value })
+ exitController({ client_id: client_id.value, dock_sn: dock_sn.value })
.then(res => {
flightController.value = false
deviceTopicInfo.value.subTopic = ''
@@ -68,11 +152,11 @@
.catch(e => {})
}
-// 控制
+// 手动控制
function control() {
- if (!clientId.value) return ElMessage.error('无人机不在空中,不能进入指挥飞行模式。')
+ if (!client_id.value) return ElMessage.error('无人机不在空中,不能进入指挥飞行模式。')
if (!dock_sn.value) return ElMessage.error('系统错误,未获取到dock_sn')
- droneController({ client_id: clientId.value, dock_sn:dock_sn.value }).then(res => {
+ droneController({ client_id: client_id.value, dock_sn: dock_sn.value }).then(res => {
flightController.value = true
const { data } = res.data
if (data.sub && data.sub?.length > 0) {
@@ -85,10 +169,35 @@
})
}
-function onMouseUp() {
- console.log('弹起')
- resetControlState()
+// 创建连接
+const createConnect = async () => {
+ const result = await postDrc({}, workspace_id.value)
+ if (result?.code === 0) {
+ const { address, client_id: clientId, username, password, expire_time } = result.data
+ mqttState = new UranusMqtt(address, { clientId, username, password })
+ mqttState?.initMqtt()
+ client_id.value = clientId
+ }
}
+
+// 销毁连接
+const destroyConnect = () => {
+ if (mqttState) {
+ mqttState?.destroyed()
+ mqttState = null
+ client_id.value = ''
+ }
+}
+
+onMounted(async () => {
+ await createConnect()
+ // 使用控制
+ manualControl = useManualControl(mqttState, deviceTopicInfo.value, flightController)
+})
+
+onBeforeUnmount(() => {
+ destroyConnect()
+})
</script>
<style scoped lang="scss">
@@ -97,19 +206,133 @@
align-items: center;
}
+
.pointControl {
position: absolute;
bottom: 0;
right: 0;
width: 1540px;
height: 217px;
- background: rgba(255, 255, 255, 0.3);
+ background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
+ backdrop-filter: blur(5px);
border-radius: 40px 0px 40px 40px;
display: flex;
justify-content: center;
- align-items: flex-end;
+ align-items: center;
color: white;
gap: 0 10px;
pointer-events: all;
+
+ .direction {
+ width: 476px;
+ height: 188px;
+ background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
+ border-radius: 40px 40px 40px 40px;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ .boxTitle{
+ font-family: Segoe UI, Segoe UI;
+ font-weight: 400;
+ font-size: 14px;
+ color: #D2E8FA;
+ }
+
+ .btnGroup {
+ display: flex;
+ flex-direction: column;
+ gap: 10px 0;
+ .btnGroupT,
+ .btnGroupB {
+ width: 238px;
+ height: 73px;
+ }
+ }
+ .upAndDown{
+ display: flex;
+ flex-direction: column;
+ gap: 10px 0;
+ .btnGroupT,
+ .btnGroupB {
+ width: 58px;
+ height: 73px;
+ }
+ }
+ .speed{
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+ width: 58px;
+ height: 155px;
+ background: #37393F;
+ box-shadow: 2px 4px 6px 0px rgba(0,13,26,0.42);
+ border-radius: 8px 8px 8px 8px;
+ text-align: center;
+ padding: 5px 0;
+ .btnIcon{
+ font-size: 20px;
+ }
+ }
+
+ }
+
+ .manualControl {
+ width: 188px;
+ height: 188px;
+ background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
+ border-radius: 40px 40px 40px 40px;
+ }
+
+ .ptzControl {
+ width: 406px;
+ height: 188px;
+ background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
+ border-radius: 40px 40px 40px 40px;
+ }
+
+ .compass {
+ width: 356px;
+ height: 188px;
+ background: rgba(157, 173, 189, 0.11);
+ background: rgb(0, 0, 0, 0.4); /* 半透明背景 */
+ border-radius: 40px 40px 40px 40px;
+ }
+
+
+ .btnGroupT,
+ .btnGroupB {
+ background: #37393f;
+ box-shadow: 2px 4px 6px 0px rgba(0, 13, 26, 0.42);
+ border-radius: 8px 8px 8px 8px;
+ display: flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+ gap: 0 45px;
+
+ .btnItem {
+ .btnIcon {
+ font-size: 20px;
+
+ &:first-child {
+ margin-bottom: 5px;
+ }
+ }
+
+ .btn {
+ width: 35px;
+ height: 35px;
+ background: #222324;
+ line-height: 35px;
+ border-radius: 5px;
+ cursor: pointer;
+
+ &:first-child {
+ margin-bottom: 5px;
+ }
+ }
+ }
+ }
}
</style>
--
Gitblit v1.9.3