直播内容改成MQTT的,飞行控制、云台相机控制

main
刘妍 3 months ago
parent 8e55946a32
commit 58ae613c2b

@ -1,5 +1,15 @@
import { clientReizePublish, clientReizeSubscribe } from '@/utils/mqtt';
export const return_home_status = {
canceled: '取消或终止',
failed: '失败',
in_progress: '执行中',
ok: '执行成功',
paused: '暂停',
rejected: '拒绝',
sent: '已下发',
timeout: '超时',
};
export const eventsTopic = (data) => {
// 发送消息
clientReizePublish('thing/product/8UUXN5400A079H/events', data);

@ -29,3 +29,12 @@ export const services_replyTopic = () => {
// 订阅消息
clientSubscribe('thing/product/8UUXN5400A079H/services_reply');
};
// 无人机
export const servicesUAVTopic = (data) => {
// 发送消息
clientPublish('thing/product/1581F8HGX254V00A0BUY/services', data);
};
export const services_replyUAVTopic = () => {
// 订阅消息
clientSubscribe('thing/product/1581F8HGX254V00A0BUY/services_reply');
};

@ -40,3 +40,32 @@ export function buildShortUUID(prefix = ''): string {
unique++;
return prefix + '_' + random + unique + String(time);
}
export function uuid(len, radix) {
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [],
i;
radix = radix || chars.length;
if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
} else {
// rfc4122, version 4 form
let r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | (Math.random() * 16);
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}

@ -6,4 +6,5 @@ export { default as LivePreview } from './src/LivePreview.vue';
export { default as RemoteDebugging } from './src/RemoteDebugging.vue';
export { default as LoadControl } from './src/LoadControl.vue';
export { default as FlightControl } from './src/FlightControl.vue';
export { default as TakeOffForm } from './src/TakeOffForm.vue';
export { default as Map } from '../workplan/components/map.vue';

@ -24,10 +24,14 @@
</div>
<!-- 飞行控制 -->
<div v-if="flightControlVisible">
<FlightControl @changeFlightControl="changeFlightControl" />
<FlightControl @changeFlightControl="changeFlightControl" @clickTakeOff="clickTakeOff" />
</div>
<!-- 一键起飞表单 -->
<div v-if="takeOffFormVisible">
<TakeOffForm @changeTakeOffForm="changeTakeOffForm" />
</div>
<div class="AirportLive" v-if="airportLiveVisible" v-drag>
<AirportLive />
<AirportLive :msgData="msgData" />
</div>
<div
class="LivePreview"
@ -35,7 +39,7 @@
:style="{ bottom: airportLiveVisible ? '300px' : '20px' }"
v-drag
>
<LivePreview />
<LivePreview :msgData="msgData" />
</div>
</div>
</template>
@ -51,6 +55,7 @@
RemoteDebugging,
LoadControl,
FlightControl,
TakeOffForm,
} from './index';
import { useMessage } from '@/hooks/web/useMessage';
import { getClient, createConnection, clientSubscribe } from '@/utils/mqtt';
@ -81,6 +86,8 @@
const loadControlVisible = ref(false);
//
const flightControlVisible = ref(false);
//
const takeOffFormVisible = ref(false);
const changeAirportLive = () => {
airportLiveVisible.value = !airportLiveVisible.value;
};
@ -93,6 +100,13 @@
const changeFlightControl = () => {
flightControlVisible.value = !flightControlVisible.value;
};
const clickTakeOff = () => {
console.log('clickTakeOff');
takeOffFormVisible.value = true;
};
const changeTakeOffForm = () => {
takeOffFormVisible.value = false;
};
const msgData = ref();
const changeSelect = async (value?: any) => {
console.log(value);

@ -4,8 +4,8 @@
<div class="title">机场直播</div>
<div class="title-icon">
<RedoOutlined @click="startLiveFun" />
<a-divider type="vertical" style="border-color: #4e5778" />
<ExpandOutlined />
<!-- <a-divider type="vertical" style="border-color: #4e5778" /> -->
<!-- <ExpandOutlined /> -->
<a-divider type="vertical" style="border-color: #4e5778" />
<PoweroffOutlined @click="closeLive" />
</div>
@ -25,44 +25,116 @@
</template>
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
import { onMounted, onBeforeUnmount } from 'vue';
import { onMounted, onBeforeUnmount, watch } from 'vue';
import { startLive, endLive } from '@/api/workmanagement/airportMaintenance';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //
import { servicesTopic, services_replyTopic } from '@/utils/debugging/remote';
import { useMessage } from '@/hooks/web/useMessage';
import { buildGUID } from '@/utils/uuid';
const { createMessage } = useMessage();
const props = defineProps({
msgData: Object,
});
let player;
watch(
() => props.msgData,
(val) => {
if (val.topic == 'thing/product/8UUXN5400A079H/services_reply') {
if (val.message.method == 'live_start_push') {
console.log(val);
if (val.message.data.result == 0) {
createMessage.success('开始直播成功');
player.src('http://175.27.168.120:6012/live/2.m3u8');
} else if (val.message.data.result == 513003) {
createMessage.success('直播已开启');
player.src('http://175.27.168.120:6012/live/2.m3u8');
} else {
createMessage.error('开始直播失败');
}
} else if (val.message.method == 'live_stop_push') {
if (val.message.data.result == 0) {
createMessage.success('停止直播成功');
if (player) {
// player.dispose();
}
} else {
createMessage.error('停止直播失败');
}
}
}
},
);
const startLiveFun = () => {
const querys = {
urlType: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://221.2.83.254:1935/live/2',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
videoId: '8UUXN5400A079H/165-0-7/normal-0',
quality: 1, // 0=1=2=3=4=
bid: buildGUID(),
method: 'live_start_push',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
url_type: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://175.27.168.120:6019/live/2',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
video_id: '8UUXN5400A079H/165-0-7/normal-0',
video_quality: 1, // 0=1=2=3=4=
},
};
servicesTopic(querys);
services_replyTopic();
// const querys = {
// urlType: 1, // 0 = RTMP 1GB28181 3WebRTC 4
// url: 'rtmp://175.27.168.120:6019/live/2',
// //video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
// videoId: '8UUXN5400A079H/165-0-7/normal-0',
// quality: 1, // 0=1=2=3=4=
// };
// startLive(querys).then((res) => {
// console.log(res);
// player = TCPlayer('player-container-id', {
// width: 360,
// height: 200,
// sources: [
// {
// src: 'http://175.27.168.120:6012/live/2.m3u8', //
// },
// ],
// licenseUrl: 'http://175.27.168.120:6012/live/2.m3u8', // license license licenseUrl
// });
// });
};
const closeLive = () => {
const querys = {
bid: buildGUID(),
method: 'live_stop_push',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
video_id: '8UUXN5400A079H/165-0-7/normal-0',
},
};
startLive(querys).then((res) => {
console.log(res);
servicesTopic(querys);
// endLive({
// videoId: '8UUXN5400A079H/165-0-7/normal-0',
// }).then((res) => {
// console.log(res);
// player.dispose();
// });
};
onMounted(() => {
setTimeout(() => {
startLiveFun();
player = TCPlayer('player-container-id', {
width: 360,
height: 200,
sources: [
{
src: 'http://221.2.83.254:7005/live/2.m3u8', //
src: 'http://175.27.168.120:6012/live/2.m3u8', //
},
],
licenseUrl: 'http://221.2.83.254:7005/live/2.m3u8', // license license licenseUrl
licenseUrl: 'http://175.27.168.120:6012/live/2.m3u8', // license license licenseUrl
});
});
};
const closeLive = () => {
endLive({
videoId: '8UUXN5400A079H/165-0-7/normal-0',
}).then((res) => {
console.log(res);
player.dispose();
});
};
onMounted(() => {
// startLiveFun();
}, 1000);
});
//
onBeforeUnmount(() => {
@ -107,5 +179,11 @@
border: 1px solid #3a57e8;
}
}
.player {
height: 200px;
#player-container-id-live {
height: 100%;
}
}
}
</style>

@ -8,38 +8,49 @@
</div>
<div class="content">
<div class="content-button">
<a-button>获取飞行器控制器</a-button>
<a-button>一键起飞</a-button>
<a-button @click="obtain"></a-button>
<a-button @click="emits('clickTakeOff')"></a-button>
<a-button>指点飞行</a-button>
<a-button>智能环绕</a-button>
<a-button>一键返航</a-button>
<!-- <a-button>智能环绕</a-button> -->
<a-button @click="returnVoyage"></a-button>
</div>
<div class="content-info">
<div class="info-item">
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
<div class="info-item-top"></div>
<div class="info-item-right"></div>
<div class="info-item-bottom"></div>
<div class="info-item-left"></div>
<div class="info-item-top" title="上升" @click="changeDRC('throttle', 'up')"></div>
<div class="info-item-right" title="右旋转" @click="changeDRC('yaw', 'up')"></div>
<div class="info-item-bottom" title="下降" @click="changeDRC('throttle', 'down')"></div>
<div class="info-item-left" title="左旋转" @click="changeDRC('yaw', 'down')"></div>
</div>
<div class="info-item">
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
<div class="info-item-top"></div>
<div class="info-item-right"></div>
<div class="info-item-bottom"></div>
<div class="info-item-left"></div>
<div class="info-item-top" title="前进" @click="changeDRC('pitch', 'up')"></div>
<div class="info-item-right" title="右移" @click="changeDRC('roll', 'up')"></div>
<div class="info-item-bottom" title="后退" @click="changeDRC('pitch', 'down')"></div>
<div class="info-item-left" title="左移" @click="changeDRC('roll', 'down')"></div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { onMounted, ref, watch, reactive } from 'vue';
import { getClient, createConnection } from '@/utils/mqtt';
import { CloseOutlined } from '@ant-design/icons-vue';
import { vDrag } from '@/utils/drag';
import { getReizeClient, createSeizeConnection, clientReizePublish } from '@/utils/mqtt';
import {
eventsTopic,
events_replyTopic,
drcDownTopic,
servicesTopic,
return_home_status,
} from '@/utils/debugging/events';
import { buildGUID } from '@/utils/uuid';
import { useMessage } from '@/hooks/web/useMessage';
const emits = defineEmits(['changeFlightControl']);
const { createMessage } = useMessage();
const emits = defineEmits(['changeFlightControl', 'clickTakeOff']);
const props = defineProps({
airportAllVal: Object,
});
@ -58,6 +69,13 @@
capacity_percent: 0,
},
});
const data = reactive({
roll: 1024,
pitch: 1024,
throttle: 1024,
yaw: 1024,
gimbal_pitch: 1024,
});
watch(
() => props.airportAllVal,
(val) => {
@ -65,6 +83,65 @@
airportVal.value = val.data;
},
);
//
const obtain = () => {
if (!getReizeClient()) {
createSeizeConnection();
}
setTimeout(() => {
//
eventsTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
eventsTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
events_replyTopic();
// //
getReizeClient().on('message', (topic, message) => {
const rs = JSON.parse(message);
console.log(rs);
//
if (rs.method === 'return_home') {
createMessage.info(return_home_status[rs.data.output.status]);
}
});
}, 1000);
};
//
const returnVoyage = () => {
servicesTopic({
bid: buildGUID(),
method: 'return_home',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
};
const changeDRC = (type, value) => {
if (value == 'up') {
data[type] = data[type] + 20;
} else {
data[type] = data[type] - 20;
}
const querys = {
seq: 1,
method: 'stick_control',
data: data,
};
drcDownTopic(querys);
};
onMounted(() => {});
</script>
<style lang="less" scoped>

@ -3,6 +3,7 @@
<div class="preview-title">
<div class="title-select">
<div class="title-select-item">
<span>镜头:</span>
<a-select
ref="select"
v-model:value="selectVal.camera"
@ -23,9 +24,9 @@
</div>
</div>
<div class="title-icon">
<RedoOutlined />
<a-divider type="vertical" style="border-color: #4e5778" />
<ExpandOutlined />
<RedoOutlined @click="startLiveFun" />
<!-- <a-divider type="vertical" style="border-color: #4e5778" /> -->
<!-- <ExpandOutlined /> -->
<a-divider type="vertical" style="border-color: #4e5778" />
<PoweroffOutlined @click="closeLive" />
</div>
@ -46,7 +47,7 @@
</template>
<script setup lang="ts">
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
import { reactive, onMounted, ref } from 'vue';
import { reactive, onMounted, ref, watch } from 'vue';
import { buildGUID } from '@/utils/uuid';
import { getClient, createConnection } from '@/utils/mqtt';
import {
@ -57,21 +58,79 @@
} from '@/api/workmanagement/airportMaintenance';
import TCPlayer from 'tcplayer.js';
import 'tcplayer.js/dist/tcplayer.min.css'; //
import { servicesUAVTopic, services_replyUAVTopic } from '@/utils/debugging/remote';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
const props = defineProps({
msgData: Object,
});
let player;
watch(
() => props.msgData,
(val) => {
if (val.topic == 'thing/product/1581F8HGX254V00A0BUY/services_reply') {
if (val.message.method == 'live_start_push') {
console.log(val);
if (val.message.data.result == 0) {
createMessage.success('开始直播成功');
player.src('http://175.27.168.120:6012/live/3.m3u8');
} else if (val.message.data.result == 513003) {
createMessage.success('直播已开启');
player.src('http://175.27.168.120:6012/live/3.m3u8');
} else {
createMessage.error('开始直播失败');
}
} else if (val.message.method == 'live_stop_push') {
if (val.message.data.result == 0) {
createMessage.success('停止直播成功');
if (player) {
// player.dispose();
}
} else {
createMessage.error('停止直播失败');
}
} else if (val.message.method == 'live_set_quality') {
if (val.message.data.result == 0) {
createMessage.success('设置清晰度成功');
player.src('http://175.27.168.120:6012/live/3.m3u8');
} else {
createMessage.error('设置清晰度失败');
}
} else if (val.message.method == 'live_lens_change') {
console.log(val);
if (val.message.data.result == 0) {
createMessage.success('设置直播镜头成功');
player.src('http://175.27.168.120:6012/live/3.m3u8');
} else {
createMessage.error('设置直播镜头失败');
}
}
}
},
);
const selectVal = reactive({
camera: 1,
camera: 'normal',
resolution: 1,
});
const optionsArr = reactive({
cameraOptions: [
{
label: '相机',
value: 0,
label: '红外',
value: 'ir',
},
{
label: '直播',
value: 1,
label: '默认',
value: 'normal',
},
{
label: '广角',
value: 'wide',
},
{
label: '变焦',
value: 'zoom',
},
],
resolutionOptions: [
@ -99,38 +158,77 @@
});
const startLiveFun = () => {
const querys = {
urlType: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://221.2.83.254:1935/live/3',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
quality: 1, // 0=1=2=3=4=
bid: buildGUID(),
method: 'live_start_push',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
url_type: 1, // 0 = RTMP 1GB28181 3WebRTC 4
url: 'rtmp://175.27.168.120:6019/live/3',
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
video_quality: 1, // 0=1=2=3=4=
},
};
startLive(querys).then((res) => {
console.log(res);
playVideo();
});
servicesUAVTopic(querys);
services_replyUAVTopic();
// const querys = {
// urlType: 1, // 0 = RTMP 1GB28181 3WebRTC 4
// // url: 'rtmp://221.2.83.254:1935/live/3',
// url: 'rtmp://175.27.168.120:6019/live/3',
// //video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
// quality: 1, // 0=1=2=3=4=
// };
// startLive(querys).then((res) => {
// console.log(res);
// playVideo();
// });
};
const resolutionChange = (val: any) => {
const querys = {
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
videoQuality: val, // 0=1=2=3=4=
bid: buildGUID(),
method: 'live_set_quality',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
video_quality: val, // 0=1=2=3=4=
},
};
setCameraVideo(querys).then((res) => {
console.log(res);
playVideo();
});
servicesUAVTopic(querys);
// const querys = {
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
// videoQuality: val, // 0=1=2=3=4=
// };
// setCameraVideo(querys).then((res) => {
// console.log(res);
// playVideo();
// });
};
const cameraChange = (val: any) => {
console.log(val);
const requestData = {
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
position: val, // 0=1=2=3=4=
camera: '99-0-0',
const querys = {
bid: buildGUID(),
method: 'live_lens_change',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
video_type: val, // 0=1=2=3=4=
},
};
exchangeCamera(requestData).then((res) => {
console.log(res);
playVideo();
});
console.log(querys);
servicesUAVTopic(querys);
// const requestData = {
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
// position: val, // 0=1=2=3=4=
// camera: '99-0-0',
// };
// exchangeCamera(requestData).then((res) => {
// console.log(res);
// playVideo();
// });
};
const data = reactive({
playedTime: 0,
@ -143,21 +241,34 @@
height: 180,
sources: [
{
src: 'http://221.2.83.254:7005/live/3.m3u8', //
src: 'http://175.27.168.120:6012/live/3.m3u8', //
},
],
licenseUrl: 'http://221.2.83.254:7005/live/3.m3u8', // license license licenseUrl
licenseUrl: 'http://175.27.168.120:6012/live/3.m3u8', // license license licenseUrl
});
};
const closeLive = () => {
endLive({
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
}).then((res) => {
console.log(res);
});
const querys = {
bid: buildGUID(),
method: 'live_stop_push',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
},
};
servicesUAVTopic(querys);
// endLive({
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
// }).then((res) => {
// console.log(res);
// });
};
onMounted(() => {
// startLiveFun();
setTimeout(() => {
startLiveFun();
playVideo();
}, 1000);
// resolutionChange(1);
});
</script>
@ -241,5 +352,11 @@
top: 100px;
z-index: 3;
}
.player {
height: 180px;
#player-container-id-live {
height: 100%;
}
}
}
</style>

@ -21,10 +21,22 @@
</div>
<div class="direction-controller">
<img src="@/assets/images/flightoperation/direction_controller.png" alt="" />
<div class="direction-controller-top" @click="changeDrc('top')"></div>
<div class="direction-controller-right" @click="changeDrc('right')"></div>
<div class="direction-controller-bottom" @click="changeDrc('bottom')"></div>
<div class="direction-controller-left" @click="changeDrc('left')"></div>
<div class="direction-controller-top" title="前进" @click="changeDrc('pitch', 'top')"></div>
<div
class="direction-controller-right"
title="右移"
@click="changeDrc('roll', 'right')"
></div>
<div
class="direction-controller-bottom"
title="后退"
@click="changeDrc('pitch', 'bottom')"
></div>
<div
class="direction-controller-left"
title="左移"
@click="changeDrc('roll', 'left')"
></div>
</div>
</div>
</div>
@ -73,25 +85,30 @@
);
const obtain = () => {
//
eventsTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
eventsTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
events_replyTopic();
if (!getReizeClient()) {
createSeizeConnection();
}
setTimeout(() => {
//
eventsTopic({
bid: buildGUID(),
method: 'flight_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {},
});
//
eventsTopic({
bid: buildGUID(),
method: 'payload_authority_grab',
tid: buildGUID(),
timestamp: new Date().getTime(),
data: {
payload_index: '99-0-0',
},
});
events_replyTopic();
}, 1000);
};
//
const singleShot = () => {
@ -107,15 +124,11 @@
});
};
//
const changeDrc = (val) => {
if (val == 'top') {
drcVal.pitch = drcVal.pitch + 20;
} else if (val == 'bottom') {
drcVal.pitch = drcVal.pitch - 20;
} else if (val == 'left') {
drcVal.roll = drcVal.roll - 20;
} else if (val == 'right') {
drcVal.roll = drcVal.roll + 20;
const changeDrc = (type, val) => {
if (val == 'up') {
drcVal[type] = drcVal[type] + 20;
} else {
drcVal[type] = drcVal[type] - 20;
}
const querys = {
seq: 1,
@ -125,7 +138,6 @@
drcDownTopic(querys);
};
onMounted(() => {
// createSeizeConnection();
// //
// getReizeClient().on('message', (topic, message) => {
// const rs = JSON.parse(message);

@ -0,0 +1,289 @@
<template>
<div class="takeoff-information">
<div class="title"
>一键起飞
<div @click="emits('changeTakeOffForm')">
<CloseOutlined />
</div>
</div>
<div class="content">
<div class="content-edit">
目标点纬度
<div>
<a-input v-model:value="data.target_latitude" readonly />
</div>
</div>
<div class="content-edit">
目标点经度
<div>
<a-input v-model:value="data.target_longitude" readonly />
</div>
</div>
<div class="content-edit">
目标点高度
<div>
<a-input v-model:value="data.target_height" />
</div>
</div>
<div class="content-edit">
安全起飞高度
<div>
<a-input v-model:value="data.security_takeoff_height" />
</div>
</div>
<div class="content-edit">
返航模式
<div>
<a-select v-model:value="data.rth_mode" :options="rth_modeOptions" />
</div>
</div>
<div class="content-edit">
返航高度
<div>
<a-input v-model:value="data.rth_altitude" />
</div>
</div>
<div class="content-edit">
遥控器失控动作
<div>
<a-select v-model:value="data.rc_lost_action" :options="rc_lost_actionOptions" />
</div>
</div>
<div class="content-edit">
指点飞行失控动作
<div>
<a-select
v-model:value="data.commander_mode_lost_action"
:options="commander_mode_lost_actionOptions"
/>
</div>
</div>
<div class="content-edit">
指点飞行模式
<div>
<a-select
v-model:value="data.commander_flight_mode"
:options="commander_flight_modeOptions"
/>
</div>
</div>
<div class="content-edit">
指点飞行高度
<div>
<a-input v-model:value="data.commander_flight_height" />
</div>
</div>
<div class="content-button">
<a-button
type="primary"
style="background: #0a99eb; width: 40%"
@click="emits('changeTakeOffForm')"
>关闭</a-button
>
<a-button type="primary" style="background: #3a57e8; width: 40%" @click="takeOff"
>起飞</a-button
>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import { CopyOutlined, EditOutlined } from '@ant-design/icons-vue';
import { timestampToFormattedDate } from '@/utils/index';
import { buildGUID, uuid } from '@/utils/uuid';
import { servicesTopic, services_replyTopic } from '@/utils/debugging/events';
import { vDrag } from '@/utils/drag';
import { CloseOutlined } from '@ant-design/icons-vue';
const emits = defineEmits(['changeTakeOffForm']);
const props = defineProps({
msgData: Object,
});
const data = reactive({
flight_id: uuid(14, 14),
target_latitude: 35.134615,
target_longitude: 118.296676,
target_height: 115,
security_takeoff_height: 100,
rth_altitude: 115,
rth_mode: 1,
max_speed: 10,
commander_flight_mode: 1,
rc_lost_action: 2,
commander_mode_lost_action: 1,
commander_flight_height: 115.0,
flight_safety_advance_check: 1,
simulate_mission: {
is_enable: 1, // {"0":"","1":""}
latitude: 35.143567, //
longitude: 118.305623, //
},
});
const uavInformation = ref({
sub_device: {
//
device_online_status: 0,
},
drone_battery_maintenance_info: {
//
capacity_percent: 0,
},
wireless_link: {
// Dongle
dongle_number: 0,
sdr_quality: 0,
'4g_quality': 0,
'4g_uav_quality': 0,
'4g_gnd_quality': 0,
remain_upload: 0,
sdr_link_state: 0,
sdr_freq_band: 0,
},
});
const time = ref(timestampToFormattedDate(new Date().getTime()));
const rth_modeOptions = ref([
{ label: '智能高度', value: 0 },
{ label: '设定高度', value: 1 },
]);
const rc_lost_actionOptions = ref([
{ label: '悬停', value: 0 },
{ label: '着陆(降落)', value: 1 },
{ label: '返航', value: 2 },
]);
const commander_mode_lost_actionOptions = ref([
{ label: '继续执行指点飞行任务', value: 0 },
{ label: '退出指点飞行任务,执行普通失控行为', value: 1 },
]);
const commander_flight_modeOptions = ref([
{ label: '智能高度飞行', value: 0 },
{ label: '设定高度飞行', value: 1 },
]);
watch(
() => props.msgData,
(val) => {
if (val.topic == 'thing/product/8UUXN5400A079H/osd') {
if (
val.message.data.sub_device ||
val.message.data.drone_battery_maintenance_info ||
val.message.data.wireless_link
) {
// console.log(val);
uavInformation.value = val.message.data;
time.value = timestampToFormattedDate(val.message.timestamp);
}
}
},
);
const takeOff = () => {
const querys = {
bid: buildGUID(),
data: data,
tid: buildGUID(),
timestamp: new Date().getTime(),
method: 'takeoff_to_point',
};
console.log(querys);
// servicesTopic(querys);
setTimeout(() => {
emits('changeTakeOffForm');
}, 1000);
};
</script>
<style lang="less" scoped>
.takeoff-information {
position: absolute;
top: 120px;
left: 300px;
z-index: 999;
width: 460px;
padding: 10px;
background: #0d0e15;
margin: 10px 0 0 10px;
box-shadow:
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
border-radius: 6px;
backdrop-filter: blur(3px);
color: #fff;
.title {
width: 100%;
padding: 10px 0;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
border-bottom: 1px solid #4e5778;
display: flex;
justify-content: space-between;
align-items: center;
span {
cursor: pointer;
}
}
.content-title {
font-size: 14px;
padding: 10px 0;
span {
font-size: 12px;
}
}
.content-item {
display: flex;
align-items: center;
border-bottom: 1px solid #4e5778;
padding: 10px 0;
.item-div {
width: 49%;
img {
width: 20px;
}
}
}
.content-button {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.content-edit {
display: flex;
align-items: center;
justify-content: space-between;
// border: 1px solid #4e5778;
margin-top: 10px;
padding: 2px 10px;
border-radius: 4px;
font-size: 12px;
input {
background: none;
width: 260px;
text-align: right;
color: #fff;
font-size: 12px;
}
::v-deep .ant-input-number,
.ant-input-number-group-wrapper {
background: none;
width: 260px !important;
text-align: right;
color: #fff;
font-size: 12px;
}
::v-deep .ant-input-number-group-wrapper {
input {
background: none;
width: 260px !important;
text-align: right;
color: #fff;
font-size: 12px;
}
}
::v-deep .ant-select-selector {
background: none;
width: 260px;
text-align: right;
color: #fff;
font-size: 12px;
}
}
}
</style>
Loading…
Cancel
Save