import { DRC_METHOD } from '@/const/drc.js' import { useMqtt } from '@/hooks/controlDrone/useMqtt' import { ElMessage } from 'element-plus' import { postPayloadCommands, ptzControlApi } from '@/api/payload' import { throttle } from 'lodash' let myInterval export const KeyCode = { KEY_W: 'KeyW', KEY_A: 'KeyA', KEY_S: 'KeyS', KEY_D: 'KeyD', KEY_Q: 'KeyQ', KEY_E: 'KeyE', KEY_J: 'KeyJ', KEY_K: 'KeyK', KEY_L: 'KeyL', KEY_X: 'KeyX', KEY_Z: 'KeyZ', KEY_C: 'KeyC', KEY_I: 'KeyI', KEY_O: 'KeyO', ARROW_UP: 'ArrowUp', ARROW_DOWN: 'ArrowDown', ARROW_LEFT: 'ArrowLeft', ARROW_RIGHT: 'ArrowRight', NUMPAD_SUBTRACT: 'NumpadSubtract', NUMPAD_ADD: 'NumpadAdd', // 提升速度 KEY_EQUAL: 'Equal', KEY_MINUS: 'Minus', // 录音 KEY_N: 'KeyN', KEY_M: 'KeyM', } export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController,paramsRef) { let activeCodeKey = null let genPortOne = true //是一代机场 let mqttHooks = useMqtt(mqttState,deviceTopicInfo) let seq = 0 const keysPressed = [ {key: 'KeyQ', value: false}, {key: 'KeyW', value: false}, {key: 'KeyE', value: false}, {key: 'KeyA', value: false}, {key: 'KeyS', value: false}, {key: 'KeyD', value: false}, ] function handlePublish(params) { const body = { method: genPortOne ? DRC_METHOD.DRONE_CONTROL : DRC_METHOD.DRONE_CONTROL2, data: params, } handleClearInterval() myInterval = setInterval(() => { body.data.seq = seq++ seq++ window.console.log('keyCode>>>>', activeCodeKey, body) mqttHooks?.publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 0 }) }, 50) } function handleKeyup(keyCode) { const {droneSn,speed} = paramsRef.value if (!deviceTopicInfo.pubTopic) { ElMessage.error('请确保已经建立DRC链路') return } if (droneSn.value === '4TADKCM0010016' || droneSn.value === 'BA0BA1C3D38157A49E1B16574FA474F7') { genPortOne = true } const SPEED = genPortOne ? (speed.value || 5) : 500 // check const HEIGHT = genPortOne ? 5 : 500; // check const W_SPEED = genPortOne ? 20 : 500 // 机头角速度 let arrList = [] if (genPortOne) { arrList = [ { Key: 'KeyQ', category: 'w', value: -W_SPEED },{ Key: 'KeyW',category: 'x', value: SPEED }, { Key: 'KeyE', category: 'w', value: W_SPEED},{ Key: 'KeyA', category: 'y', value: -SPEED}, { Key: 'KeyS', category: 'x', value: -SPEED},{ Key: 'KeyD', category: 'y', value: SPEED} ] } else { arrList = [ { Key: 'KeyQ', category: 'yaw', value: 1024-W_SPEED },{ Key: 'KeyW',category: 'pitch', value: 1024+SPEED }, { Key: 'KeyE', category: 'yaw', value: 1024+W_SPEED},{ Key: 'KeyA', category: 'roll', value: 1024-SPEED}, { Key: 'KeyS', category: 'pitch', value: 1024-SPEED},{ Key: 'KeyD', category: 'roll', value: 1024+SPEED} ] } let resultObj = [] let resultArr = [] // 遍历被选中得数组 if (keyCode === 'assemblyKeys') { keysPressed.map(key => { if (key.value) { let result = arrList.filter(item =>item.Key===key.key) resultObj.push(result[0]) } }) // 相同属性值进行计算 resultArr = resultObj.reduce((acc, item) => { // 如果累加器中已经有这个 category,则累加 value if (acc[item.category]) { // acc[item.category] += item.value; acc[item.category] = genPortOne ? 0 : 1024; } else { // 否则,初始化这个 category 的 value acc[item.category] = item.value; } return acc; }, {}); } seq = 0 switch (keyCode) { case 'assemblyKeys': // 针对Q W E A S D 组合键 if (activeCodeKey === keyCode) return handlePublish(resultArr) activeCodeKey = keyCode break case 'KeyQ': if (activeCodeKey === keyCode) return let objQ = { yaw: 1024-W_SPEED } if (genPortOne) {objQ = {w: -W_SPEED}} handlePublish(objQ) activeCodeKey = keyCode break case 'KeyW': if (activeCodeKey === keyCode) return let objW = { pitch: 1024+SPEED } if (genPortOne) {objW = {x: SPEED}} handlePublish(objW) activeCodeKey = keyCode break case 'KeyE': if (activeCodeKey === keyCode) return let objE = { yaw: 1024+W_SPEED } if (genPortOne) {objE = {w: W_SPEED}} handlePublish(objE) activeCodeKey = keyCode break case 'KeyA': if (activeCodeKey === keyCode) return let objA = { roll: 1024-SPEED } if (genPortOne) {objA = {y: -SPEED}} handlePublish(objA) activeCodeKey = keyCode break case 'KeyS': if (activeCodeKey === keyCode) return let objS = { pitch: 1024-SPEED } if (genPortOne) {objS = {x: -SPEED}} handlePublish(objS) activeCodeKey = keyCode break case 'KeyD': if (activeCodeKey === keyCode) return let objD = { roll: 1024+SPEED } if (genPortOne) {objD = {y: SPEED}} handlePublish(objD) activeCodeKey = keyCode break case 'KeyZ': if (activeCodeKey === keyCode) return let objZ = { throttle: 1024-HEIGHT } if (genPortOne) {objZ = {h: -HEIGHT}} handlePublish(objZ) activeCodeKey = keyCode break // case 'ArrowDown': case 'KeyC': if (activeCodeKey === keyCode) return let objC = { throttle: 1024+HEIGHT } if (genPortOne) {objC = {h: HEIGHT}} handlePublish(objC) activeCodeKey = keyCode break case 'ArrowUp': if (activeCodeKey === keyCode) return clearInterval(myInterval) ptzControl('up') myInterval = setInterval(()=>ptzControl('up'), 200) activeCodeKey = keyCode break case 'ArrowDown': if (activeCodeKey === keyCode) return clearInterval(myInterval) ptzControl('down') myInterval = setInterval(()=>ptzControl('down'), 200) activeCodeKey = keyCode break case 'ArrowLeft': if (activeCodeKey === keyCode) return clearInterval(myInterval) ptzControl('left') myInterval = setInterval(()=>ptzControl('left'), 200) activeCodeKey = keyCode break case 'ArrowRight': if (activeCodeKey === keyCode) return clearInterval(myInterval) ptzControl('right') myInterval = setInterval(()=>ptzControl('right'), 200) activeCodeKey = keyCode break default: break } } // 云台上下左右 function ptzControl(key) { const {dockSn} = paramsRef.value ptzControlApi(key, { sn: dockSn }).then(res => { }) } const handlePayloadTurn = (params) => { handleClearInterval() if (!this.myInterval) { postPayloadCommands(this.sn, params) } this.myInterval = setInterval(() => { postPayloadCommands(this.sn, params) }, 500) } function handleClearInterval() { clearInterval(myInterval) myInterval = undefined } function resetControlState() { keysPressed.map(item => item.value = false) activeCodeKey = null seq = 0 handleClearInterval() } function onKeyup() { resetControlState() } function onKeydown(e) { e.preventDefault() keysPressed.forEach(item => { if(e.code === item.key) item.value = true }) let result = keysPressed.filter(item=>item.value===true) if (result && result.length >= 2) { handleKeyup('assemblyKeys') } else { handleKeyup(e.code) } } function startKeyboardManualControl() { window.addEventListener('keydown', onKeydown) window.addEventListener('keyup', onKeyup) } function closeKeyboardManualControl() { resetControlState() window.removeEventListener('keydown', onKeydown) window.removeEventListener('keyup', onKeyup) } watch( () => isCurrentFlightController.value, val => { if (val && deviceTopicInfo.pubTopic) { startKeyboardManualControl() } else { closeKeyboardManualControl() } }, { immediate: true } ) onUnmounted(() => { deviceTopicInfo.subTopic = '' deviceTopicInfo.pubTopic = '' mqttHooks = null closeKeyboardManualControl() }) function handleEmergencyStop() { if (!deviceTopicInfo.pubTopic) { ElMessage.error('请确保已经建立DRC链路') return } const body = { method: DRC_METHOD.DRONE_EMERGENCY_STOP, data: {}, } resetControlState() window.console.log('handleEmergencyStop>>>>', deviceTopicInfo.pubTopic, body) mqttHooks?.publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 1 }) } return { activeCodeKey, handleKeyup, handleEmergencyStop, resetControlState, } }