Browse Source

连接到已带状态的服务器

master
修宁 5 months ago
parent
commit
b40017dac4
  1. 43
      src/core/manager/EnvManager.ts
  2. 94
      src/core/script/LCCScript.ts
  3. 3
      src/core/script/ModelManager.ts
  4. 24
      src/editor/widgets/monitor/MonitorView.vue
  5. 10
      src/types/LCC.d.ts

43
src/core/manager/EnvManager.ts

@ -70,7 +70,7 @@ export default class EnvManager {
keepalive: 60
})
await LCC.loadExecutor()
await this.loadExecutorToModel()
this.client.on('connect', this.onMqttConnect)
this.client.on('message', this.onMqttMessage)
@ -83,6 +83,47 @@ export default class EnvManager {
}
}
// 加载执行器到3D视图上
async loadExecutorToModel() {
if (!window['Model']) {
return
}
const deviceRes = await LCC.queryDeviceInfoList()
if (!deviceRes.success) {
return
}
const deviceList: AgvStatusVo[] = deviceRes.data || []
for (const agvState of deviceList) {
const agvItem = Model.find(agvState.id)
if (!agvItem) {
// 还没加载到地图
const item = JSON.parse(agvState.virtualExecutorPayload)
const pos = Model.getPositionByLogicXY(agvState.logicX, agvState.logicY)
if (pos) {
item.tf[0] = [pos.x, pos.y, agvState.z]
}
switch (_.toLower(agvState.direction)) {
// right=0/left=180/up=90/down=-90
case 'right':
item.tf[1][1] = 0 // 右侧
break
case 'left':
item.tf[1][1] = 180 // 左侧
break
case 'down':
item.tf[1][1] = -90 // 下方
break
case 'up':
item.tf[1][1] = 90 // 上方
break
}
Model.createExecutor(item)
}
}
}
async disconnectEnv() {
system.showLoading()
try {

94
src/core/script/LCCScript.ts

@ -90,59 +90,59 @@ export default class LCCScript implements LCC {
})
}
queryDeviceInfoList(): Promise<ServerResponse<DeviceVo[]>> {
queryDeviceInfoList(): Promise<ServerResponse<AgvStatusVo[]>> {
return Request.request.post('/api/workbench/LccController@queryDeviceInfoList', {
projectUUID: worldModel.state.project_uuid,
envId: worldModel.state.runState.currentEnvId
})
}
// 从后台读取所有车
async loadExecutor(): Promise<ExecutorVo> {
const res = await Request.request.post('/api/workbench/LccController@loadExecutor', {
projectUuid: worldModel.state.project_uuid,
envId: worldModel.state.runState.currentEnvId
})
for (const row of res.data) {
const executor_id = row.executor_id
const payload = JSON.parse(row.virtual_executor_payload)
// 车所在的标记位置,及方向 11_4:RIGHT
const [wayPointId, direction] = _.split(row.virtual_location_at, ':')
if (window['Model']) {
const point = Model.find(wayPointId)
if (!point) {
console.error(`Waypoint with ID ${wayPointId} not found for executor ${executor_id}.`)
continue
}
const item = _.cloneDeep(payload)
item.id = executor_id
item.tf[0] = _.cloneDeep(point.tf[0])
switch (_.toLower(direction)) {
// right=0/left=180/up=90/down=-90
case 'right':
item.tf[1][1] = 0 // 右侧
break
case 'left':
item.tf[1][1] = 180 // 左侧
break
case 'down':
item.tf[1][1] = -90 // 下方
break
case 'up':
item.tf[1][1] = 90 // 上方
break
}
if (row.virtual_floor_code === worldModel.state.catalogCode) {
Model.createExecutor(item)
}
}
}
return res.data
}
// // 从后台读取所有车
// async loadExecutor(): Promise<ExecutorVo> {
// const res = await Request.request.post('/api/workbench/LccController@loadExecutor', {
// projectUuid: worldModel.state.project_uuid,
// envId: worldModel.state.runState.currentEnvId
// })
//
// for (const row of res.data) {
// const executor_id = row.executor_id
// const payload = JSON.parse(row.virtual_executor_payload)
// // 车所在的标记位置,及方向 11_4:RIGHT
// const [wayPointId, direction] = _.split(row.virtual_location_at, ':')
//
// if (window['Model']) {
// const point = Model.find(wayPointId)
// if (!point) {
// console.error(`Waypoint with ID ${wayPointId} not found for executor ${executor_id}.`)
// continue
// }
//
// const item = _.cloneDeep(payload)
// item.id = executor_id
// item.tf[0] = _.cloneDeep(point.tf[0])
// switch (_.toLower(direction)) {
// // right=0/left=180/up=90/down=-90
// case 'right':
// item.tf[1][1] = 0 // 右侧
// break
// case 'left':
// item.tf[1][1] = 180 // 左侧
// break
// case 'down':
// item.tf[1][1] = -90 // 下方
// break
// case 'up':
// item.tf[1][1] = 90 // 上方
// break
// }
// if (row.virtual_floor_code === worldModel.state.catalogCode) {
// Model.createExecutor(item)
// }
// }
// }
//
// return res.data
// }
/**
*

3
src/core/script/ModelManager.ts

@ -142,6 +142,9 @@ this.viewport.stateManager.update(({ getEntity, putEntity, addEntity }) => {
getPositionByLogicXY(logicX: number, logicY: number): THREE.Vector3 {
const item = this.viewport.entityManager.findItemByLogicXY(logicX, logicY)
if (!item) {
return null
}
const matrix = getMatrixFromTf(item.tf)
const position = new THREE.Vector3()
matrix.decompose(position, new THREE.Quaternion(), new THREE.Vector3())

24
src/editor/widgets/monitor/MonitorView.vue

@ -1,11 +1,15 @@
<template>
<div class="title">
设备监控
<el-button size="small" :icon="renderIcon('Refresh')" @click="refreshData"
style="margin-left: 5px;"
/>
<el-input v-model="searchKeyword" size="small" style="width: 240px" placeholder="Search">
<template #prefix>
<component :is="renderIcon('element Search')"></component>
</template>
</el-input>
<span class="close" @click="closeMe">
<component :is="renderIcon('element Close')" />
</span>
@ -76,7 +80,7 @@ export default {
stopSubscribe: [],
/**
* 设备列表数据
* @type {Array< Partial< DeviceVo>>}
* @type {Array<Partial<AgvStatusVo>>}
*/
deviceList: []
}
@ -100,7 +104,7 @@ export default {
* 获取任务进度百分比
*/
getTaskProcessPercent(deviceInfo) {
if (deviceInfo == null || deviceInfo.taskTotalCount === 0) {
if (deviceInfo == null || !deviceInfo.taskTotalCount || !deviceInfo.taskCompleted) {
return 0
}
return Math.round((deviceInfo.taskCompleted / deviceInfo.taskTotalCount) * 100)
@ -133,7 +137,6 @@ export default {
* @type {DeviceStatusFn}
*/
onDeviceStatusMessage(type, topic, body) {
console.log(this, topic, body)
const deviceInfo = _.find(this.deviceList, device => device.id === body.id)
if (!deviceInfo) {
return
@ -141,12 +144,7 @@ export default {
_.assign(deviceInfo, body)
},
async subscribe() {
this.deviceList = []
const res = await LCC.queryDeviceInfoList()
if (!res.success) {
return
}
this.deviceList = res.data
await this.refreshData()
//
this.stopSubscribe.push(
@ -156,6 +154,14 @@ export default {
worldModel.backendMessageReceiver.subscribe('DeviceStatus', this.onDeviceStatusMessage.bind(this))
)
},
async refreshData(){
this.deviceList = []
const res = await LCC.queryDeviceInfoList()
if (!res.success) {
return
}
this.deviceList = res.data
},
undescribe() {
//
for (const stopFn of this.stopSubscribe) {

10
src/types/LCC.d.ts

@ -21,7 +21,7 @@ declare interface LCC {
/**
* Model
*/
loadExecutor(): Promise<ExecutorVo>
// loadExecutor(): Promise<ExecutorVo>
/**
*
@ -32,7 +32,7 @@ declare interface LCC {
/**
*
*/
queryDeviceInfoList(): Promise<ServerResponse<DeviceVo[]>>
queryDeviceInfoList(): Promise<ServerResponse<AgvStatusVo[]>>
/**
*
@ -73,7 +73,7 @@ type BackendTopicType = 'ServerState' | 'ClientState' | 'TaskUpdate' | 'InvUpdat
type DeviceAliveFn = (type: BackendTopicType, topic: string, body: DeviceAliveVo) => void
type DeviceStatusFn = (type: BackendTopicType, topic: string, body: DeviceVo) => void
type DeviceStatusFn = (type: BackendTopicType, topic: string, body: AgvStatusVo) => void
type ServerStateFn = (type: BackendTopicType, topic: string, body: ServerStatusVo) => void
@ -112,7 +112,7 @@ interface DeviceAliveVo {
online: boolean
}
interface DeviceVo {
interface AgvStatusVo {
// 设备 ID
id: string
// 设备类型
@ -165,6 +165,8 @@ interface DeviceVo {
bizTaskTo: string
// 搬运托盘号
bizLpn: string
virtualLocationAt: string; // 车所在的标记位置,及方向 11_4:RIGHT
virtualExecutorPayload: string; // 车的虚拟执行器负载
}
/**

Loading…
Cancel
Save