forked from drone/command-center-dashboard

罗广辉
2025-04-17 8f436e8f6ff26083e5f5c07b39eb1581772a32b7
feat: 无人机控制调整
8 files modified
88 ■■■■■ changed files
src/api/drc.js 4 ●●●● patch | view | raw | blame | history
src/api/payload.js 3 ●●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue 40 ●●●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/CurrentTaskDetails.vue 21 ●●●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/TaskDetailsLeft.vue 1 ●●●● patch | view | raw | blame | history
src/const/drc.js 1 ●●●● patch | view | raw | blame | history
src/hooks/controlDrone/useManualControl.js 16 ●●●● patch | view | raw | blame | history
src/websocket/index.js 2 ●●●●● patch | view | raw | blame | history
src/api/drc.js
@@ -44,7 +44,7 @@
// 一键返航
export async function returnHome(sn) {
  return request({
    url: `/dp/home/${sn}/drc/returnHome`,
    url: `/drone-device-core/dp/home/${sn}/drc/returnHome`,
    method: 'post',
  })
}
@@ -52,7 +52,7 @@
// 取消返航
export async function returnHomeCancel(sn) {
  return request({
    url: `/dp/home/${sn}/drc/returnHomeCancel`,
    url: `/drone-device-core/dp/home/${sn}/drc/returnHomeCancel`,
    method: 'post',
  })
}
src/api/payload.js
@@ -23,10 +23,11 @@
    return await request.post(`${API_PREFIX}/devices/${sn}/payload/commands`, body, config)
}
// 拍照和录像
export async function callPhotoAndVideoCmd(sn, type) {
  return await request({
    url:`/droneAirport/liveStreamApi/${sn}/payload/photoAndVideoCmd/${type}`,
    url:`/drone-device-core/droneAirport/liveStreamApi/${sn}/payload/photoAndVideoCmd/${type}`,
    method:'get',
  })
}
src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -147,9 +147,19 @@
const deviceOsdInfo = inject('deviceOsdInfo')
const taskDetails = inject('taskDetails')
const dockSn = inject('dockSn')
const droneSn = inject('droneSn')
const store = useStore()
let mqttState = null
const client_id = ref('')
const valueTime = ref('00:00:00')
let timer = null
let totalSeconds = 0
const workspace_id = computed(() => taskDetails?.value?.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 },
@@ -162,6 +172,7 @@
]
const speed = ref(5)
provide('speed',speed)
const list5 = [
    { name: '上', style: { top: '-70%' }, imgStyle: { top: '20%', left: '50%' } },
@@ -183,21 +194,15 @@
    ],
]
let mqttState = null
const client_id = ref('')
const valueTime = ref('00:00:00')
let timer = null
let totalSeconds = 0
const deviceTopicInfo = ref({
    sn: deviceOsdInfo.value?.data?.sn,
    pubTopic: '',
    subTopic: '',
})
const flightController = ref(false)
// 控制对象
let manualControl = {}
const sn = computed(() => deviceOsdInfo?.value?.data?.sn)
const isAutoControl = inject('isAutoControl')
const timeStart = () => {
@@ -222,7 +227,7 @@
// 按下操作
function onMouseDown(type) {
    manualControl?.handleKeyup(type, { sn: sn.value, speed: speed.value })
    manualControl?.handleKeyup(type)
}
// 弹起操作
@@ -232,7 +237,7 @@
// 取消手动控制
function cancelControl() {
    exitController({ client_id: client_id.value, dock_sn: dock_sn.value })
    exitController({ client_id: client_id.value, dock_sn: dockSn.value })
        .then(res => {
            flightController.value = false
            deviceTopicInfo.value.subTopic = ''
@@ -245,8 +250,8 @@
// 手动控制
function control() {
    if (!client_id.value) return ElMessage.error('无人机不在空中,不能进入指挥飞行模式。')
    if (!dock_sn.value) return ElMessage.error('系统错误,未获取到dock_sn')
    droneController({ client_id: client_id.value, dock_sn: dock_sn.value }).then(res => {
    if (!dockSn.value) return ElMessage.error('系统错误,未获取到dock_sn')
    droneController({ client_id: client_id.value, dock_sn: dockSn.value }).then(res => {
        flightController.value = true
        const { data } = res.data
        if (data.sub && data.sub?.length > 0) {
@@ -262,14 +267,14 @@
// 返航
function onBackDock() {
    returnHome(dock_sn.value).then(res => {
    returnHome(dockSn?.value).then(res => {
        ElMessage.success('返航操作成功')
    })
}
// 取消返航
function cancelBackDock() {
    returnHomeCancel({ client_id: this.clientId, dock_sn: this.sn }).then(res => {
    returnHomeCancel(dockSn?.value).then(res => {
        ElMessage.success('取消返航成功')
    })
}
@@ -303,13 +308,18 @@
    }
}
const paramsRef = computed(()=>({
    droneSn:droneSn.value,
    speed:speed.value,
}))
watch(
    () => workspace_id.value,
    async () => {
        if (workspace_id.value) {
            await createConnect()
            // 使用控制
            manualControl = useManualControl(mqttState, deviceTopicInfo.value, flightController)
            manualControl = useManualControl(mqttState, deviceTopicInfo.value, flightController,paramsRef)
        }
    }
)
src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -18,8 +18,8 @@
            <TaskDetailsRight v-if="isAutoControl" />
            <template v-else>
                <TaskDetailsHead />
                <TaskDetailsLeft />
            </template>
            <TaskDetailsLeft />
            <!--    控制面板,里面有方法需要立即执行,不可用v-if        -->
@@ -59,8 +59,12 @@
const deviceOsdInfo = ref({})
provide('taskDetails', taskDetails)
provide('deviceOsdInfo', deviceOsdInfo)
provide('dockSn', taskDetails?.value?.device_sns?.[0])
provide('droneSn', deviceOsdInfo?.value?.data?.sn)
const dockSn = computed(() => taskDetails?.value?.device_sns?.[0])
const droneSn = computed(() => deviceOsdInfo?.value?.data?.sn)
provide('dockSn', dockSn)
provide('droneSn', droneSn)
// 机巢直播
@@ -81,6 +85,7 @@
// 无人机直播画质切换
const changeLineQuality = async () => {
    if (droneLiveUrl.value) return droneLiveUrl.value
    const res = await liveStart(droneSn, lineQuality.value)
    droneLiveUrl.value = res.data.data.rtcs_url
    return droneLiveUrl.value
@@ -115,7 +120,7 @@
    switch (payload.biz_code) {
        case EBizCode.DeviceOsd: {
            deviceOsdInfo.value = payload
            // console.log(deviceOsdInfo.value,'osd信息')
            console.log(deviceOsdInfo.value,'device_osd信息')
            setCurrentLiveUrl()
            break
        }
@@ -141,10 +146,6 @@
    }
)
const removeEvent = () => {
    connectWs?.close()
    deviceOsdInfo.value = {}
}
onMounted(() => {
    getTaskDetails()
@@ -152,8 +153,10 @@
})
onBeforeUnmount(() => {
    connectWs?.close()
    deviceOsdInfo.value = {}
    connectWs = null
    EventBus.off('CurrentTaskDetails-timeStop', changeLineQuality)
    removeEvent()
})
</script>
src/components/CurrentTaskDetails/TaskDetailsLeft.vue
@@ -59,6 +59,7 @@
    const type = isRecording.value ? 'video_stop' : 'video_start'
    const msg = isRecording.value ? '停止录像' : '开始录像'
    const emitType = isRecording.value ? 'controlPanel-timeStop' : 'controlPanel-timeStart'
    callPhotoAndVideoCmd(droneSn.value, type).then(res => {
        ElMessage.success(msg)
        EventBus.emit(emitType)
src/const/drc.js
@@ -1,6 +1,7 @@
export const DRC_METHOD = {
    HEART_BEAT: 'heart_beat',
    DRONE_CONTROL: 'drone_control', // 飞行控制-虚拟摇杆
    DRONE_CONTROL2: 'stick_control', // 2代及以上飞行控制-摇杆
    DRONE_EMERGENCY_STOP: 'drone_emergency_stop', // 急停
    OSD_INFO_PUSH: 'osd_info_push', // 高频osd信息上报
    HSI_INFO_PUSH: 'hsi_info_push', // 避障信息上报
src/hooks/controlDrone/useManualControl.js
@@ -34,15 +34,15 @@
        KEY_M: 'KeyM',
    }
export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController) {
export function useManualControl(mqttState,deviceTopicInfo, isCurrentFlightController,paramsRef) {
    const activeCodeKey = ref(null)
    let genPortOne = true //是一代机场
    const mqttHooks = useMqtt(mqttState,deviceTopicInfo)
    let seq = 0
    function handlePublish(params) {
        const body = {
            method: DRC_METHOD.DRONE_CONTROL,
            method: genPortOne ? DRC_METHOD.DRONE_CONTROL : DRC_METHOD.DRONE_CONTROL2,
            data: params,
        }
        handleClearInterval()
@@ -54,18 +54,18 @@
        }, 50)
    }
    function handleKeyup(keyCode,params) {
        const {sn,speed} = params
        let genPortOne = false //是一代机场
    function handleKeyup(keyCode) {
        const  {droneSn,speed} =  paramsRef.value
        if (!deviceTopicInfo.pubTopic) {
            ElMessage.error('请确保已经建立DRC链路')
            return
        }
        if (sn === '4TADKCM0010016' || sn === 'BA0BA1C3D38157A49E1B16574FA474F7') {
        if (droneSn.value === '4TADKCM0010016' || droneSn.value === 'BA0BA1C3D38157A49E1B16574FA474F7') {
            genPortOne = true
        }
        const SPEED = genPortOne ? (speed || 5) : 500 //  check
        const SPEED = genPortOne ? (speed.value || 5) : 500 //  check
        const HEIGHT = genPortOne ? 5 : 500; //  check
        const W_SPEED = genPortOne ? 20 : 500 // 机头角速度
src/websocket/index.js
@@ -67,7 +67,9 @@
    }
    close() {
        console.log('socket关闭')
        this._socket?.close()
        this._socket = null
    }
}