Browse Source

仿真环境启动

master
修宁 6 months ago
parent
commit
993784c1f6
  1. 2
      src/components/yvTable/YvTable.vue
  2. 5
      src/core/engine/Viewport.ts
  3. 50
      src/core/manager/EntityManager.ts
  4. 233
      src/core/manager/EnvManager.ts
  5. 67
      src/core/manager/RunManager.ts
  6. 14
      src/core/manager/RuntimeManager.ts
  7. 2
      src/core/manager/WorldModel.ts
  8. 22
      src/core/script/ModelManager.ts
  9. 30
      src/editor/ModelMain.vue
  10. 75
      src/editor/OpenProject.vue
  11. 4
      src/editor/menus/FileMenu.ts
  12. 52
      src/modules/cl2/Cl23dObject.ts
  13. 11
      src/types/LCC.d.ts
  14. 11
      src/types/Model.d.ts

2
src/components/yvTable/YvTable.vue

@ -287,9 +287,7 @@ export default {
}) })
_.forEach(insertRows, (row, index) => { _.forEach(insertRows, (row, index) => {
if (!row._rid) {
row._rid = _.uniqueId('_') row._rid = _.uniqueId('_')
}
}) })
sel.add = _.cloneDeep(insertRows) sel.add = _.cloneDeep(insertRows)
if (sel.add.length > 0 || sel.update.length > 0 || sel.remove.length > 0) { if (sel.add.length > 0 || sel.update.length > 0 || sel.remove.length > 0) {

5
src/core/engine/Viewport.ts

@ -26,6 +26,7 @@ import ItemFindManager from '@/core/manager/ItemFindManager.ts'
import { MapControls } from 'three/examples/jsm/controls/MapControls' import { MapControls } from 'three/examples/jsm/controls/MapControls'
import ModelManager from '@/core/script/ModelManager.ts' import ModelManager from '@/core/script/ModelManager.ts'
import RuntimeManager from '@/core/manager/RuntimeManager.ts' import RuntimeManager from '@/core/manager/RuntimeManager.ts'
import EnvManager from '@/core/manager/EnvManager.ts'
/** /**
* *
@ -50,6 +51,7 @@ export default class Viewport {
interactionManager = new InteractionManager() interactionManager = new InteractionManager()
modelManager = new ModelManager() modelManager = new ModelManager()
runtimeManager = new RuntimeManager() runtimeManager = new RuntimeManager()
envManager = new EnvManager()
// 状态管理器 // 状态管理器
stateManager: StateManager stateManager: StateManager
@ -63,7 +65,8 @@ export default class Viewport {
markRaw(this.itemFindManager), markRaw(this.itemFindManager),
markRaw(this.interactionManager), markRaw(this.interactionManager),
markRaw(this.modelManager), markRaw(this.modelManager),
markRaw(this.runtimeManager) markRaw(this.runtimeManager),
markRaw(this.envManager)
] ]
// 对象实例管理器 moduleName -> InstanceMeshManager // 对象实例管理器 moduleName -> InstanceMeshManager

50
src/core/manager/EntityManager.ts

@ -101,6 +101,54 @@ export default class EntityManager {
this.lineDiffs.delete.clear() this.lineDiffs.delete.clear()
} }
deleteEntityOnlyRuntime(id: string) {
const entity = this.___entityMap.get(id)
if (entity) {
this.viewport.itemFindManager.remove(id)
const renderer = getRenderer(entity.t)
if (renderer) {
renderer.tempViewport = this.viewport
renderer.deletePoint(id, { isRuntime: true })
this.___entityMap.delete(id)
renderer.tempViewport = null
}
}
}
/**
* , StateManager Link
*/
createOrUpdateEntityOnlyRuntime(entity: ItemJson) {
if (!entity?.id) {
throw new Error('Entity must have an id')
}
const originEntity = this.___entityMap.get(entity.id)
const renderer = getRenderer(entity.t)
if (!renderer) {
throw new Error(`Renderer for type ${entity.t} not found`)
}
this.viewport.itemFindManager.addOrUpdate(entity)
this.___entityMap.set(entity.id, entity)
const option = {
isRuntime: true,
originEntity: _.cloneDeep(originEntity)
} as RendererCudOption
renderer.tempViewport = this.viewport
if (typeof originEntity === 'undefined') {
renderer.createPointForEntity(entity, option)
} else {
renderer.updatePointForEntity(entity, option)
}
renderer.tempViewport = null
}
/** /**
* , center[] / in[] / out[] , * , center[] / in[] / out[] ,
*/ */
@ -510,6 +558,7 @@ export default class EntityManager {
} }
let item: ItemJson | undefined = undefined let item: ItemJson | undefined = undefined
this.___entityMap.forEach((value) => { this.___entityMap.forEach((value) => {
//@ts-ignore
if (value.logicX === logicX && value.logicY === logicY) { if (value.logicX === logicX && value.logicY === logicY) {
item = value item = value
return return
@ -521,6 +570,7 @@ export default class EntityManager {
findItemByLogicXYZ(x: number, y: number, z: number): ItemJson | undefined { findItemByLogicXYZ(x: number, y: number, z: number): ItemJson | undefined {
let item: ItemJson | undefined = undefined let item: ItemJson | undefined = undefined
this.___entityMap.forEach((value) => { this.___entityMap.forEach((value) => {
//@ts-ignore
if (value.tf[0][0] === x && /*value.tf[0][1] === y &&*/ value.tf[0][2] === z && value.logicX) { if (value.tf[0][0] === x && /*value.tf[0][1] === y &&*/ value.tf[0][2] === z && value.logicX) {
item = value item = value
return return

233
src/core/manager/EnvManager.ts

@ -0,0 +1,233 @@
import type Viewport from '@/core/engine/Viewport.ts'
import { worldModel } from '@/core/manager/WorldModel.ts'
import mqtt, { type IConnackPacket, type IPublishPacket } from 'mqtt'
import type { Cl2Task } from '@/modules/cl2/Cl23dObject.ts'
import type { ErrorWithReasonCode } from 'mqtt/src/lib/shared.ts'
import type Cl23dObject from '@/modules/cl2/Cl23dObject.ts'
import { Request } from '@ease-forge/shared'
export default class EnvManager {
private viewport: Viewport
private client: mqtt.MqttClient = null
init(viewport: Viewport): void {
this.viewport = viewport
}
// 从后台读取所有车
async loadExecutors() {
const res = await Request.request.post('/api/workbench/EnvController@getAllExecutor', {
projectUuid: worldModel.state.project_uuid,
catalogCode: worldModel.state.catalogCode,
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)
const wayPointId = row.virtual_location_at
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])
Model.createExecutor(item)
}
}
// 从后台读取所有库存
async loadInv() {
const res = await Request.request.post('/api/workbench/EnvController@getAllInv', {
projectUuid: worldModel.state.project_uuid,
catalogCode: worldModel.state.catalogCode,
envId: worldModel.state.runState.currentEnvId
})
for (const row of res.data) {
const bay = row.bay
const cell = row.cell // : 0
const level = row.level // : 0
const loc_code = row.loc_code // : "rack1_0_0_0"
const lpn = row.lpn // : "LPN1"
const rack = row.rack // : "rack1"
const container_type = row.container_type // : "pallet"
Model.createInv(container_type, lpn, rack, bay, level, cell)
}
}
appendExecutor(id) {
const obj = this.viewport.entityManager.findObjectById(id)
const item = this.viewport.entityManager.findItemById(id)
if (item.t == 'cl2' && obj.userData.t === 'cl2') {
debugger
const cl2 = obj as Cl23dObject
cl2.onMqttConnect(item, this.client)
// this.client.subscribe(['/wcs_server/' + cl2.id], { qos: 0 })
// this.client.publish('/agv_robot/status', JSON.stringify(m20020), { retain: true })
}
}
onMqttConnect = (packet: IConnackPacket) => {
console.log('Connected')
}
onMqttMessage = (topic: string, payload: Buffer, packet: IPublishPacket) => {
console.log(`[${topic}] ${msg}`)
debugger
const a: Cl2Task = JSON.parse(msg.toString())
this.handleMessage(a)
}
onMqttError = (error: Error | ErrorWithReasonCode) => {
console.error('Error:', error)
}
async start(env: EnvInfo) {
if (!env) {
system.showErrorDialog('Environment is not specified, cannot start EnvManager.')
return
}
if (!worldModel.state.isOpened) {
system.showErrorDialog('WorldModel is not opened, cannot start EnvManager.')
return
}
if (!this.viewport) {
system.showErrorDialog('Viewport is not initialized, cannot start EnvManager.')
return
}
if (!worldModel.state.runState.currentEnvId) {
system.showErrorDialog('Current environment ID is not set, cannot start EnvManager.')
return
}
if (worldModel.state.runState.isRunning) {
system.showErrorDialog('EnvManager is already running, cannot start again.')
return
}
const payload = env.env_payload
const brokerUrl = payload?.mqtt?.websocket
const username = payload?.mqtt?.username
const password = payload?.mqtt?.password
if (!brokerUrl || !username || !password) {
system.showErrorDialog('MQTT broker URL, username, or password is not set in the environment payload.')
return
}
this.stop()
system.showLoading()
worldModel.state.runState.isLoading = true
worldModel.state.runState.currentEnv = Object.freeze(env)
try {
await this.loadExecutors()
await this.loadInv()
this.client = mqtt.connect(brokerUrl, {
path: '/mqtt',
clientId: system.createUUID(),
clean: true,
connectTimeout: 300,
username,
password,
unixSocket: true,
keepalive: 60
})
this.client.on('connect', this.onMqttConnect)
this.client.on('message', this.onMqttMessage)
this.client.on('error', this.onMqttError)
worldModel.state.runState.isRunning = true
} finally {
system.clearLoading()
worldModel.state.runState.isLoading = false
}
}
async stop() {
system.showLoading()
try {
if (worldModel.state.runState.isRunning) {
worldModel.state.runState.isRunning = false
}
worldModel.state.runState.currentEnv = null
if (this.client) {
this.client.removeAllListeners()
this.client.end()
this.client = null
}
this.clearExecutors()
this.clearInv()
this.viewport.runtimeManager.clear()
} finally {
system.clearLoading()
worldModel.state.runState.isLoading = false
}
}
clearInv() {
}
clearExecutors() {
}
static CURRENT_ALL_ENV: EnvInfo[]
/**
*
* @param worldId ID
* @param envName
* @param isVirtual
*/
static async createEnv(worldId: string, envName: string, isVirtual: boolean) {
throw new Error('Method not implemented.')
}
/**
*
*/
static async getAllEnv(worldId: string): Promise<ServerResponse<EnvInfo[]>> {
// system.invokeServer('')
if (!worldId) {
return Promise.resolve({ success: true, data: [], msg: '' })
}
const res = await Request.request.post('/api/workbench/EnvController@getAllEnv', {
worldId: worldId
})
if (res.success) {
EnvManager.CURRENT_ALL_ENV = res.data
for (const env of res.data) {
// payload 转换为 json 数据
if (env.env_payload) {
try {
env.env_payload = JSON.parse(env.env_payload)
} catch (e) {
console.error('解析环境负载失败:', e)
env.env_payload = {}
}
}
}
return res
}
EnvManager.CURRENT_ALL_ENV = []
return res
}
/**
*
*/
dispose(): void {
this.viewport = null
this.stop()
}
}

67
src/core/manager/RunManager.ts

@ -1,67 +0,0 @@
import { Request } from '@ease-forge/shared'
/**
*
*/
class RunManager {
// 是否正在运行
isRunning: boolean = false
/**
*
*/
async getAllEnv(worldId: string): Promise<ServerResponse<EnvInfo[]>> {
// system.invokeServer('')
if (!worldId) {
return Promise.resolve({ success: true, data: [], msg: '' })
}
const res = await Request.request.post('/api/workbench/EnvController@getAllEnv', {
worldId: worldId
})
for (const env of res.data) {
// payload 转换为 json 数据
if (env.env_payload) {
try {
env.env_payload = JSON.parse(env.env_payload)
} catch (e) {
console.error('解析环境负载失败:', e)
env.env_payload = {}
}
}
}
return res
}
/**
*
* @param worldId ID
* @param envName
* @param isVirtual
*/
async createEnv(worldId: string, envName: string, isVirtual: boolean) {
throw new Error('Method not implemented.')
}
/**
*
*/
async run(timeRate: number, envId: number) {
if (this.isRunning) {
await this.stop()
}
// 启动 websocket 监听等等
}
/**
*
*/
async stop() {
// 停止 websocket 监听等等
}
}
const runManager = new RunManager()
export default runManager

14
src/core/manager/RuntimeManager.ts

@ -5,6 +5,8 @@ import type Viewport from '@/core/engine/Viewport.ts'
*/ */
export default class RuntimeManager { export default class RuntimeManager {
private viewport: Viewport private viewport: Viewport
private readonly tmpExecutors = new Set<string>
// 货架ID -> 托盘ID
private readonly storeRackMap = new Map<string, Set<string>>() private readonly storeRackMap = new Map<string, Set<string>>()
init(viewport: Viewport): void { init(viewport: Viewport): void {
@ -58,11 +60,21 @@ export default class RuntimeManager {
* *
*/ */
clear() { clear() {
for (const id of this.tmpExecutors) {
this.viewport.entityManager.deleteEntityOnlyRuntime(id)
}
this.tmpExecutors.clear()
this.storeRackMap.clear() this.storeRackMap.clear()
} }
dispose(): void { dispose(): void {
this.viewport = null this.viewport = null
this.storeRackMap.clear() this.clear()
}
addEntity(item: ItemJson) {
this.tmpExecutors.add(item.id)
this.viewport.entityManager.createOrUpdateEntityOnlyRuntime(item)
} }
} }

2
src/core/manager/WorldModel.ts

@ -26,6 +26,7 @@ export interface WorldModelState {
isRunning: boolean, isRunning: boolean,
isVirtual: boolean, isVirtual: boolean,
timeRate: number, timeRate: number,
currentEnv: EnvInfo
} }
} }
@ -218,6 +219,7 @@ export default class WorldModel {
const items = _.cloneDeep(floor.items) const items = _.cloneDeep(floor.items)
delete floor.items delete floor.items
console.log("floor", floor); console.log("floor", floor);
//@ts-ignore
const vdata: VData = { const vdata: VData = {
items: items as ItemJson[], items: items as ItemJson[],
infos: floor, infos: floor,

22
src/core/script/ModelManager.ts

@ -94,11 +94,26 @@ export default class ModelManager implements IControls, Model {
}) })
} }
createInv(boxType: ContainerT, lpn: string, rack: string, bay?: number, level?: number, cell?: number): void { createExecutor(item: ItemJson): void {
this.viewport.runtimeManager.addEntity(item)
}
createInv(boxType: ContainerT, lpn: string, rack: string, bay?: number, level?: number, cell?: number): void {
const scale = getRenderer(boxType).defaultScale const scale = getRenderer(boxType).defaultScale
this.viewport.runtimeManager.addEntity({
id: lpn,
t: boxType as string,
tf: [[-5000, -1, 0], [0, 0, 0], [scale.x, scale.y, scale.z]],
v: true,
dt: {
in: [], out: [], center: [],
storeAt: { item: rack, bay, level, cell }
}
})
this.viewport.stateManager.update(({ getEntity, putEntity, addEntity }) => { // 这一段代码不要删除,他是用向正式环境提交数据用的
/*
this.viewport.stateManager.update(({ getEntity, putEntity, addEntity }) => {
debugger debugger
const item = getEntity(lpn) const item = getEntity(lpn)
if (item) { if (item) {
@ -124,7 +139,8 @@ export default class ModelManager implements IControls, Model {
} }
}) })
} }
}) })
*/
} }
getPositionByLogicXY(logicX: number, logicY: number): THREE.Vector3 { getPositionByLogicXY(logicX: number, logicY: number): THREE.Vector3 {

30
src/editor/ModelMain.vue

@ -31,11 +31,13 @@
<el-button :icon="renderIcon('Play')" type="primary" <el-button :icon="renderIcon('Play')" type="primary"
v-if="!worldModelState.runState.isRunning" v-if="!worldModelState.runState.isRunning"
:disabled="!worldModelState.runState.currentEnvId" :disabled="!worldModelState.runState.currentEnvId"
:loading="worldModelState.runState.isLoading">启动 :loading="worldModelState.runState.isLoading"
@click="startEnv">启动仿真
</el-button> </el-button>
<el-button :icon="renderIcon('Stop')" type="danger" plain <el-button :icon="renderIcon('Stop')" type="danger" plain
v-if="worldModelState.runState.isRunning" v-if="worldModelState.runState.isRunning"
:loading="worldModelState.runState.isLoading">停止 :loading="worldModelState.runState.isLoading"
@click="stopEnv">停止仿真
</el-button> </el-button>
</div> </div>
</div> </div>
@ -150,9 +152,8 @@ import CatalogDefine from './CatalogDefine.vue'
import Logo from '@/assets/images/logo.png' import Logo from '@/assets/images/logo.png'
import './ModelMain.less' import './ModelMain.less'
import EventBus from '@/runtime/EventBus.js' import EventBus from '@/runtime/EventBus.js'
import { useRouter } from 'vue-router'
import { worldModel } from '@/core/manager/WorldModel.ts' import { worldModel } from '@/core/manager/WorldModel.ts'
import runManager from '@/core/manager/RunManager.js' import EnvManager from '@/core/manager/EnvManager.js'
export default { export default {
components: { Model2DEditor, Model3DViewer, Split, SplitArea, CatalogDefine }, components: { Model2DEditor, Model3DViewer, Split, SplitArea, CatalogDefine },
@ -269,15 +270,16 @@ export default {
}, },
watch: { watch: {
'worldModelState.isOpened': { 'worldModelState.isOpened': {
handler(newVal) { handler() {
if (newVal.isOpened) { if (this.worldModelState.isOpened) {
this.reloadEnvList() this.reloadEnvList()
} }
} }
}, },
'worldModelState.project_uuid': { 'worldModelState.project_uuid': {
handler(newVal) { immediate: true,
if (newVal.isOpened) { handler() {
if (this.worldModelState.isOpened) {
this.reloadEnvList() this.reloadEnvList()
} }
} }
@ -299,8 +301,18 @@ export default {
methods: { methods: {
renderIcon, renderIcon,
getWidgetBySide, getWidgetBySide,
startEnv() {
const env = this.envList.find(env => env.env_id === this.worldModelState.runState.currentEnvId)
if (env) {
this.currentViewport.envManager.start(env)
}
},
stopEnv() {
this.currentViewport.envManager.stop()
},
reloadEnvList() { reloadEnvList() {
runManager.getAllEnv(this.worldModelState.project_uuid).then(res => { EnvManager.getAllEnv(this.worldModelState.project_uuid)
.then(res => {
this.envList = res.data this.envList = res.data
}) })
}, },

75
src/editor/OpenProject.vue

@ -1,31 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, useTemplateRef } from "vue"; import { onMounted, reactive, useTemplateRef } from 'vue'
import { AgGridVue } from "ag-grid-vue3"; import { AgGridVue } from 'ag-grid-vue3'
import { ElButton } from "element-plus"; import { ElButton } from 'element-plus'
import { type GridOptions } from "ag-grid-enterprise"; import { type GridOptions } from 'ag-grid-enterprise'
import { type GridApi, type GridReadyEvent } from "ag-grid-community"; import { type GridApi, type GridReadyEvent } from 'ag-grid-community'
import { Request } from "@ease-forge/shared"; import { Request } from '@ease-forge/shared'
import { localeText as localeTextCn } from "../components/yvTable/yv-aggrid-cn.locale"; import { localeText as localeTextCn } from '../components/yvTable/yv-aggrid-cn.locale'
import "ag-grid-community/styles/ag-grid.css"; import 'ag-grid-community/styles/ag-grid.css'
import "ag-grid-community/styles/ag-theme-alpine.css"; import 'ag-grid-community/styles/ag-theme-alpine.css'
defineOptions({ defineOptions({
name: 'OpenProject', name: 'OpenProject'
}); })
// //
const emit = defineEmits<{ const emit = defineEmits<{
"cancel": []; 'cancel': [];
"open": [row: any]; 'open': [row: any];
"add": [expose: OpenProjectExpose]; 'add': [expose: OpenProjectExpose];
}>(); }>()
// Props // Props
interface OpenProjectProps { interface OpenProjectProps {
} }
// props // props
const props = withDefaults(defineProps<OpenProjectProps>(), {}); const props = withDefaults(defineProps<OpenProjectProps>(), {})
// State // State
interface OpenProjectState { interface OpenProjectState {
@ -33,7 +33,7 @@ interface OpenProjectState {
} }
// state // state
const state = reactive<OpenProjectState>({}); const state = reactive<OpenProjectState>({})
// Data // Data
interface OpenProjectData { interface OpenProjectData {
@ -48,42 +48,39 @@ const data: OpenProjectData = {
// suppressNoRowsOverlay: true, // suppressNoRowsOverlay: true,
// suppressLoadingOverlay: true, // suppressLoadingOverlay: true,
// //
rowSelection: "single", rowSelection: 'single',
columnDefs: [ columnDefs: [
{ field: 'id', headerName: 'id', editable: false, hide: true }, { field: 'id', headerName: 'id', editable: false },
{ field: 'projectUuid', headerName: '项目编号', editable: false }, { field: 'projectUuid', headerName: '项目编号', editable: false },
{ field: 'projectLabel', headerName: '项目标题', editable: false }, { field: 'projectLabel', headerName: '项目标题', editable: false },
{ field: 'projectVersion', headerName: '项目版本', editable: false }, { field: 'projectVersion', headerName: '项目版本', editable: false },
{ field: 'server', headerName: '所在服务器', editable: false },
{ field: 'directoryData', headerName: '目录数据', editable: false },
{ field: 'otherData', headerName: '其他数据', editable: false },
{ field: 'createAt', headerName: '创建时间', editable: false }, { field: 'createAt', headerName: '创建时间', editable: false },
{ field: 'createBy', headerName: '创建人', editable: false }, { field: 'createBy', headerName: '创建人', editable: false },
{ field: 'updateAt', headerName: '最后更新时间', editable: false }, { field: 'updateAt', headerName: '最后更新时间', editable: false },
{ field: 'updateBy', headerName: '更新人', editable: false }, { field: 'updateBy', headerName: '更新人', editable: false }
], ],
onGridReady(event: GridReadyEvent) { onGridReady(event: GridReadyEvent) {
data.api = event.api data.api = event.api
}, }
}, }
}; }
const grid = useTemplateRef<InstanceType<typeof AgGridVue>>("gridRef"); const grid = useTemplateRef<InstanceType<typeof AgGridVue>>('gridRef')
onMounted(loadData); onMounted(loadData)
function loadData() { function loadData() {
Request.request.post("/api/workbench/LccModelManager@projectList").then(res => { Request.request.post('/api/workbench/LccModelManager@projectList').then(res => {
state.grid1Data = res.records; state.grid1Data = res.records
}); })
} }
function open() { function open() {
const row = data.api?.getSelectedRows()?.[0]; const row = data.api?.getSelectedRows()?.[0]
if (!row) return; if (!row) return
emit("open", row); emit('open', row)
} }
function add() { function add() {
emit("add", expose); emit('add', expose)
} }
interface OpenProjectExpose { interface OpenProjectExpose {
@ -95,14 +92,14 @@ interface OpenProjectExpose {
const expose: OpenProjectExpose = { const expose: OpenProjectExpose = {
state, state,
data, data,
loadData, loadData
}; }
// //
defineExpose(expose); defineExpose(expose)
export type { export type {
OpenProjectProps, OpenProjectProps,
OpenProjectState, OpenProjectState
} }
</script> </script>

4
src/editor/menus/FileMenu.ts

@ -109,7 +109,7 @@ export default defineMenu((menus) => {
} }
}), { }), {
title: '打开项目', title: '打开项目',
width: 1500, width: 600,
height: 500, height: 500,
showClose: true, showClose: true,
showMax: true, showMax: true,
@ -142,6 +142,8 @@ export default defineMenu((menus) => {
envId: 1, envId: 1,
otherData: JSON.stringify(worldModel.state.worldData) otherData: JSON.stringify(worldModel.state.worldData)
}) })
system.msg('保存成功', 'success')
} finally { } finally {
system.clearLoading() system.clearLoading()
} }

52
src/modules/cl2/Cl23dObject.ts

@ -409,28 +409,10 @@ export default class Cl23dObject extends THREE.Object3D {
on() { on() {
} }
} }
debugger
const m20020 = { /*
'content': { // 事件绑定
'CreateMonoTime': 233701185,
'CreateTime': 1750638957541,
'CurDirection': 0,
'CurLogicX': 6,
'CurLogicY': 2,
'CurOrientation': -3.1375624383367926,
'CurX': 6,
'CurY': 2,
'MarkerType': 1,
'SendTime': 1750638957541,
'SeqNo': 11,
'VehicleId': 3,
'X': 2652.477598132277,
'Y': 3944.4427159671854
},
'id': 20020
}
// 事件绑定
client.on('connect', () => { client.on('connect', () => {
console.log('Connected') console.log('Connected')
client.subscribe(['/wcs_server/' + item.id], { qos: 0 }) client.subscribe(['/wcs_server/' + item.id], { qos: 0 })
@ -447,6 +429,7 @@ export default class Cl23dObject extends THREE.Object3D {
client.on('error', (error) => { client.on('error', (error) => {
console.error('Error:', error) console.error('Error:', error)
}) })
*/
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
@ -455,8 +438,33 @@ export default class Cl23dObject extends THREE.Object3D {
/*==========消息处理============*/ /*==========消息处理============*/
onMqttConnect(item: ItemJson, client: mqtt.MqttClient) {
const m20020 = {
'content': {
'CreateMonoTime': 233701185,
'CreateTime': 1750638957541,
'CurDirection': 0,
'CurLogicX': 6,
'CurLogicY': 2,
'CurOrientation': -3.1375624383367926,
'CurX': 6,
'CurY': 2,
'MarkerType': 1,
'SendTime': 1750638957541,
'SeqNo': 11,
'VehicleId': 3,
'X': 2652.477598132277,
'Y': 3944.4427159671854
},
'id': 20020
}
client.subscribe(['/wcs_server/' + item.id], { qos: 0 })
client.publish('/agv_robot/status', JSON.stringify(m20020), { retain: true })
}
handleMessage(data: Cl2Task) { handleMessage(data: Cl2Task) {
return; return
if (data.id === 10010) { if (data.id === 10010) {
if (this.taskList.length <= 0) { if (this.taskList.length <= 0) {

11
src/types/LCC.d.ts

@ -11,17 +11,6 @@ declare interface LCC {
loadFloor(projectUUID: string, catalogCode: string, envId: string): Promise<ServerResponse<boolean>> loadFloor(projectUUID: string, catalogCode: string, envId: string): Promise<ServerResponse<boolean>>
/** /**
*
* @param boxType
* @param lpn
* @param rack ID
* @param bay ,
* @param level ,
* @param cell ,
*/
createInv(boxType: ContainerT, lpn: string, rack: string, bay: number = 0, level: number = 0, cell: number = 0): void
/**
* *
* @param lpn * @param lpn
* @param rack ID * @param rack ID

11
src/types/Model.d.ts

@ -30,7 +30,7 @@ declare interface Model {
/** /**
* *
* @param boxType * @param boxType
* @param lpn * @param lpn
* @param rack ID * @param rack ID
@ -40,6 +40,13 @@ declare interface Model {
*/ */
createInv(boxType: ContainerT, lpn: string, rack: string, bay: number = 0, level: number = 0, cell: number = 0): void createInv(boxType: ContainerT, lpn: string, rack: string, bay: number = 0, level: number = 0, cell: number = 0): void
/**
*
* @param item Json
*/
createExecutor(item: ItemJson): void
/** /**
* *
*/ */
@ -205,7 +212,7 @@ declare function msg(str: string, type: MSG_TYPE = 1): void
* *
*/ */
interface EnvInfo { interface EnvInfo {
env_id: string env_id: number
world_id: string world_id: string
env_name: string env_name: string
is_virtual: boolean is_virtual: boolean

Loading…
Cancel
Save