<script lang="ts" setup name="AlarmList"> import ThreeMap from '@/components/ThreeMap/index.vue' // 竖轴 import type { Ref } from 'vue' import { reactive, ref } from 'vue' import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import {ctrlNav, getRouteList, setTaskMode, startTrack, targetGrid} from "@/api/home/route/route"; import useSettingsStore from "@/store/modules/settings"; import useWebsocketStore from "@/store/modules/websocket"; import {getRobotList, robotDetail} from "@/api/home/robot/robot"; import {fileUpload, saveImg} from "@/api/home/task/task"; import html2canvas from 'html2canvas' import {getDevList, hsList} from "@/api/home/tcy/tcy"; const routeId = ref('') const x = ref('**.**') const y = ref('**.**') const routeList = ref<any[]>([]) const tableData = ref<any[]>([]) const settingsStore = useSettingsStore() const websocket = useWebsocketStore() // const mapSize = ref(260) // const mapNum = ref(20) const gridHeight = ref(10) const gridWidth = ref(20) const resolution = ref(0.5) const pcdUrl = ref('') const threeMap = ref() // 组件 const drawThree = ref() // 组件 const mca = ref() // 组件 const psd = ref() // 组件 const canvas = ref() // 组件 const x1 = ref(0) const x2 = ref(4095) const x3 = ref(0) const x4 = ref(4095) const maxThreshold = ref(0) const stepLen = ref(5) const gridInputX = ref(0) const gridInputY = ref(0) const mcaData: Ref<any[]> = ref([ {name: 'mca', data: []}, {name: '', data: []} ]) const psdData: Ref<any[]> = ref([ {name: 'psd', data: []}, {name: '', data: []} ]) const robot = ref({}) let mcaobj0 = {} let mcaobj1 = {} let psdobj0 = {} let psdobj1 = {} const grid = ref({ currGridX: '***', currGridY: '***', estimateGridX: '***', estimateGridY: '***', }) // socket更新数据 const unwatch = watch(websocket, (newVal) => { if (newVal.positionData && Object.keys(newVal.positionData).length >= 1 ) { x.value = newVal.positionData.x y.value = newVal.positionData.y } else if (newVal.gridData && Object.keys(newVal.gridData).length >= 1 ) { console.log('栅格推送', newVal.gridData) grid.value = newVal.gridData } else if (newVal.alarmData && Object.keys(newVal.alarmData).length >= 1 ) { tableData.value.push(newVal.alarmData) } else if (newVal.detectorHData && Object.keys(newVal.detectorHData).length >= 1 ) { if(mcaobj0.hasOwnProperty(newVal.detectorHData.mcaX)) { mcaobj0[newVal.detectorHData.mcaX] += newVal.detectorHData.mcaY } else { mcaobj0[newVal.detectorHData.mcaX] = newVal.detectorHData.mcaY } if(mcaobj1.hasOwnProperty(newVal.detectorHData.mcaX1)) { mcaobj1[newVal.detectorHData.mcaX1] += newVal.detectorHData.mcaY1 } else { mcaobj1[newVal.detectorHData.mcaX1] = newVal.detectorHData.mcaY1 } if(psdobj0.hasOwnProperty(newVal.detectorHData.psdX)) { psdobj0[newVal.detectorHData.psdX] += newVal.detectorHData.psdY } else { psdobj0[newVal.detectorHData.psdX] = newVal.detectorHData.psdY } if(psdobj1.hasOwnProperty(newVal.detectorHData.psdX1)) { psdobj1[newVal.detectorHData.psdX1] += newVal.detectorHData.psdY1 } else { psdobj1[newVal.detectorHData.psdX1] = newVal.detectorHData.psdY1 } } }) onBeforeUnmount(() => { unwatch() clearInterval(timer); }) const currTaskId = ref('') const isOpen = ref(false) onMounted(() => { setTimeout(() => { // 查机器人列表,获得pcdUrl,mapSize,mapNum getRobotList({}).then((response) => { if(response.code === 200) { const robot = response.data.filter((item: any) => item.id === settingsStore.robot.id)[0] pcdUrl.value = window.localStorage.getItem('baseurl-robot') + '/static/finalCloud_' + robot.id + '.pcd' // mapSize.value = Number(robot.gridSize) // mapNum.value = Number(robot.gridNumber) stepLen.value = Number(robot.stepLen) maxThreshold.value = Number(robot.maxThreshold) gridHeight.value = Number(robot.gridHeight) gridWidth.value = Number(robot.gridWidth) resolution.value = Number(robot.resolution) setTimeout(() => { threeMap.value.initMap() }, 100) } }) // 查机器人的路线列表,获得routeList getRouteList({ robotId: settingsStore.robot.id }).then((response) => { routeList.value = response.data // 查机器人详情,控制按钮 robotDetail({ id: settingsStore.robot.id, }).then((res) => { if(res.code === 200) { routeId.value = res.data.currRouteId // 路线 currTaskId.value = res.data.currTaskId // 任务 } }) }) // 探测仪详情 getDevList({}).then((response) => { if(response.code === 200) { robot.value = response.data.filter((item: { robotId: any; }) => item.robotId === settingsStore.robot.id)[0] } }) }, 200) updateTimer() }) const updateTimer = () => { mcaData.value[0].data = Object.entries(mcaobj0) mcaData.value[1].data = Object.entries(mcaobj1) psdData.value[0].data = Object.entries(psdobj0) psdData.value[1].data = Object.entries(psdobj1) }; const timer = setInterval(updateTimer, 1000); function openChange(action: any) { setTaskMode({ robotId: settingsStore.robot.id, isOpen: isOpen.value? 1: 0, }).then((response) => { if (response.code === 200) { ElMessage.success('指令已下发') } }) } function startGPS(action: any) { ctrlNav({ robotId: settingsStore.robot.id, action, }).then((response) => { if (response.code === 200) { if(response.data === 1) { ElMessage.success('指令已下发') } else if(response.data === 0) { ElMessage.error('指令下发失败') } } }) } function gridSetXY() { targetGrid({ estimateGridX: gridInputX.value, estimateGridY: gridInputY.value, robotId: settingsStore.robot.id, }).then((response) => { if (response.code === 200) { ElMessage.success('自定义栅格已下发') } }) } function gridSet() { if(grid.value.estimateGridX === '***') { ElMessage.warning('请等待栅格信息') } targetGrid({ estimateGridX: grid.value.estimateGridX, estimateGridY: grid.value.estimateGridY, robotId: settingsStore.robot.id, }).then((response) => { if (response.code === 200) { ElMessage.success('栅格已下发') } }) } function startRoute(action: any) { // if(action === 1) { // // 清除缓存 // threeMap.value.clearRun() // mcaobj0 = {} // mcaobj1 = {} // psdobj0 = {} // psdobj1 = {} // } window.localStorage.setItem('isRunRoute', action.toString()) // 指令 startTrack({ robotId: settingsStore.robot.id, action, // track_name: routeList.value.filter(item => item.id === routeId.value)[0].routeName, wait: 0, isTask: 1, maxThreshold: maxThreshold.value, stepLen: stepLen.value, }).then((response) => { if (response.code === 200) { if(response.data === 1) { ElMessage.success('指令已下发') } else if(response.data === 0) { ElMessage.error('指令下发失败') } // 终止传图 if(action === 0) { nextTick(() => { let routeImg: any, mcaImg: any, psdImg: any threeMap.value.render() const promise_three = html2canvas(drawThree.value).then((res) => { routeImg = res.toDataURL('image/png') }) const promise_mca = html2canvas(mca.value).then((res) => { mcaImg = res.toDataURL('image/png') }) const promise_psd = html2canvas(psd.value).then((res) => { psdImg = res.toDataURL('image/png') }) Promise.all([promise_three, promise_mca, promise_psd]).then(() => { let params = { taskId: currTaskId.value, routeImg: routeImg, mcaImg: mcaImg, psdImg: psdImg, } saveImg(params).then((res) => { if (res.code === 200) { ElMessage.success('图片已上传') } }) // 查机器人详情,控制按钮 robotDetail({ id: settingsStore.robot.id, }).then((res) => { if(res.code === 200) { routeId.value = res.data.currRouteId // 路线 currTaskId.value = res.data.currTaskId // 任务 } }) }); }) } else { // 查机器人详情,控制按钮 robotDetail({ id: settingsStore.robot.id, }).then((res) => { if(res.code === 200) { routeId.value = res.data.currRouteId // 路线 currTaskId.value = res.data.currTaskId // 任务 } }) } } }) hs(action) } function getPic(ref: HTMLElement, param: string, message: string) { html2canvas(ref).then((res) => { const imgUrl = res.toDataURL('image/png') let params = { taskId: currTaskId.value, } console.log(imgUrl) params[param] = imgUrl saveImg(params).then((res) => { if (res.code === 200) { ElMessage.success(message + '图片已上传') } }) }) } function tableRowClassName({ row, rowIndex }) { if (rowIndex % 2 === 1) { return 'e-row' } return '' } function hs(type: any) { hsList({ detectorId: robot.value.id, type, x1: x1.value, x2: x2.value, x3: x3.value, x4: x4.value, }).then((res) => { if(res.code === 200) { ElMessage.success('指令下发成功') } }) } </script> <template> <app-container style="height: calc(100vh - 70px);overflow: hidden"> <div> <span style="font-size: 14px">初始寻源步长:<el-input-number v-model="stepLen" :precision="0" :step="1" style="width: 100px" size="small"/></span> <!-- <el-select v-model="routeId" placeholder="选择巡航路径">--> <!-- <el-option--> <!-- v-for="item in routeList"--> <!-- :key="item.id"--> <!-- :label="item.routeName"--> <!-- :value="item.id"/>--> <!-- </el-select>--> <span class="span-text">x,y坐标:{{x}},{{y}}</span> <span class="span-text">当前栅格:{{grid.currGridX}},{{grid.currGridY}}</span> <span class="span-text">规划栅格:{{grid.estimateGridX}},{{grid.estimateGridY}}</span> <div style="float: right;"> <span style="padding-top: 10px;font-size: 13px">手动控制</span> <el-switch v-model="isOpen" active-text="开" inactive-text="关" style="margin: 0 10px" @change="openChange"/> <el-button type="primary" @click="startGPS(1)" size="small">开始导航</el-button> <el-button type="primary" @click="startGPS(0)" size="small">停止导航</el-button> <el-button type="primary" @click="startRoute(1)" v-if="currTaskId === ''" size="small">执行任务</el-button> <el-button type="primary" @click="startRoute(0)" v-if="currTaskId !== ''" size="small">停止任务</el-button> <el-button type="primary" @click="gridSet()" size="small">栅格下发</el-button> </div> </div> <div style="display: flex;width: 100%;height: 77%;"> <div ref="drawThree" class="map-yx"> <three-map ref="threeMap" id="pcdcontainer-yx" :gridHeight="gridHeight" :gridWidth="gridWidth" :resolution="resolution" :pcdUrl="pcdUrl"/> </div> <div class="table-yx"> <span class="span-text" style="margin-left: 0px">自定义规划栅格 X: <el-input-number v-model="gridInputX" :precision="0" :step="1" style="width: 80px" size="small"/></span> <span class="span-text" style="margin-left: 5px">Y: <el-input-number v-model="gridInputY" :precision="0" :step="1" style="width: 80px" size="small"/></span> <el-button type="primary" @click="gridSetXY()" size="small">下发</el-button> <el-table :data="tableData" :row-class-name="tableRowClassName" size="small" style="margin-top: 10px" border> <el-table-column prop="robotName" label="设备名称" align="center" /> <el-table-column prop="discernTypeName" label="识别类型" align="center" /> <el-table-column prop="monitorVal" label="检测数值" align="center" /> </el-table> </div> </div> <canvas ref="canvas" style="display: none;"></canvas> <div style="height: 22%;display: flex;"> <div ref="mca" style="width: calc(50% - 90px);height: 100%;background-color: #000000;margin-right: 5px"> <bar-chart-vertical id="mca" width="100%" :isDataZoom="false" :data="mcaData" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" /> </div> <div ref="psd" style="width: calc(50% - 90px);height: 100%;background-color: #000000;margin-right: 10px"> <bar-chart-vertical id="psd" width="100%" :isDataZoom="false" :data="psdData" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" /> </div> <div style="width: 160px;color: #2a3746;font-family: 微软雅黑;font-size: 14px"> <div>X1:<el-input-number v-model="x1" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div> <div style="margin-top: 6px">X2:<el-input-number v-model="x2" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div> <div style="margin-top: 6px">X3:<el-input-number v-model="x3" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div> <div style="margin-top: 6px">X4:<el-input-number v-model="x4" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div> </div> </div> </app-container> </template> <style lang="scss" scoped> .map-yx { width: 70%; height: 100%; padding: 10px 0 10px 0; } .table-yx { width: 30%; height: 100%; padding-left: 10px; padding-top: 10px; } .span-text { margin: 0px 10px;font-weight: bold;letter-spacing: 1px;color: #4c4c4d; font-size: 14px; } </style> <style lang="scss" > .el-table .e-row { background: #f0f4fe; } </style>