Newer
Older
intelligentRobot / src / views / task / run / index.vue
wangxitong on 3 Sep 13 KB first commit
<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>