Browse Source

库存监视 InvUpdate, 3D 模型初始化位置变更

master
修宁 5 months ago
parent
commit
a8a8c77e7c
  1. 27
      src/core/base/BaseRenderer.ts
  2. 35
      src/core/manager/EnvManager.ts
  3. 4
      src/core/script/ModelManager.ts
  4. 4
      src/editor/widgets/server/EnvSelectConnect.vue
  5. 43
      src/modules/amr/ptr/cl2/Cl2Renderer.ts
  6. 2
      src/modules/rack/RackRenderer.ts
  7. 5
      src/types/Model.d.ts
  8. 1
      src/types/Types.d.ts

27
src/core/base/BaseRenderer.ts

@ -108,7 +108,7 @@ export default abstract class BaseRenderer {
} }
createPointForEntity(item: ItemJson, option?: RendererCudOption): Object3DLike { createPointForEntity(item: ItemJson, option?: RendererCudOption): Object3DLike {
const point = this.createPoint(item, option) let point = this.createPoint(item, option)
point.visible = ((typeof item.v !== 'undefined') ? item.v : true) point.visible = ((typeof item.v !== 'undefined') ? item.v : true)
if (item.dt.storeAt?.item) { if (item.dt.storeAt?.item) {
@ -118,7 +118,24 @@ export default abstract class BaseRenderer {
setUserDataForItem(item, point) setUserDataForItem(item, point)
this.afterCreateOrUpdatePoint(item, option, point) this.afterCreateOrUpdatePoint(item, option, point)
this.tempViewport.entityManager.appendObject(item.id, point) this.tempViewport.entityManager.appendObject(item.id, point)
if (typeof option.getParentObject3D === 'function') {
// 要求添加到指定 父对象
const parent: THREE.Object3D = option.getParentObject3D(this.tempViewport, item)
if (point instanceof MeshWrap) {
const wrap = point as MeshWrap
const mesh = wrap.manager.wrapToObject3D(wrap)
this.tempViewport.entityManager.replaceObject(item.id, mesh)
parent.add(mesh)
point = mesh
} else {
parent.add(point)
}
} else {
// 默认添加到场景中
this.appendToScene(point) this.appendToScene(point)
}
return point return point
} }
@ -155,13 +172,14 @@ export default abstract class BaseRenderer {
if (!rackRenderer) { if (!rackRenderer) {
console.error(`Cannot find renderer for rack type ${rack.t}`) console.error(`Cannot find renderer for rack type ${rack.t}`)
} }
const { position, rotation } = rackRenderer.getStorePlacement(rack, item.dt.storeAt.bay, item.dt.storeAt.level, item.dt.storeAt.cell) const { position, rotation, getParentObject3D } = rackRenderer.getStorePlacement(rack, item.dt.storeAt.bay, item.dt.storeAt.level, item.dt.storeAt.cell)
if (!position || !rotation) { if (!position || !rotation) {
console.error(`无法获取物品 ${item.id} 的存储位置`) console.error(`无法获取物品 ${item.id} 的存储位置`)
} }
option.position = position option.position = position
option.rotation = rotation option.rotation = rotation
option.getParentObject3D = getParentObject3D
} }
if (_.isArray(option?.position) && _.isArray(option?.rotation)) { if (_.isArray(option?.position) && _.isArray(option?.rotation)) {
@ -312,7 +330,10 @@ export default abstract class BaseRenderer {
* Position Rotation * Position Rotation
*/ */
getStorePlacement(storeItem: ItemJson, bay = 0, level = 0, cell = 0) getStorePlacement(storeItem: ItemJson, bay = 0, level = 0, cell = 0)
: { position: [number, number, number], rotation: [number, number, number] } { : {
position: [number, number, number], rotation: [number, number, number],
getParentObject3D?: (viewport: Viewport, parent: ItemJson) => THREE.Object3D
} {
throw new Error(' 不支持库存物品的添加. t=' + this.itemTypeName) throw new Error(' 不支持库存物品的添加. t=' + this.itemTypeName)
} }

35
src/core/manager/EnvManager.ts

@ -58,10 +58,6 @@ export default class EnvManager {
const env = worldModel.state.runState.currentEnv const env = worldModel.state.runState.currentEnv
try { try {
worldModel.backendMessageReceiver.setProjectEnv(worldModel.state.project_uuid, worldModel.state.runState.currentEnvId) worldModel.backendMessageReceiver.setProjectEnv(worldModel.state.project_uuid, worldModel.state.runState.currentEnvId)
await this.loadInvToModel()
this.stopSubscribe.push(
worldModel.backendMessageReceiver.subscribe('InvUpdate', this.onInvUpdateMessage.bind(this))
)
this.client = mqtt.connect(env.envConfig.mqtt.websocket, { this.client = mqtt.connect(env.envConfig.mqtt.websocket, {
path: '/mqtt', path: '/mqtt',
@ -75,6 +71,13 @@ export default class EnvManager {
}) })
await this.loadExecutorToModel() await this.loadExecutorToModel()
this.stopSubscribe.push(
worldModel.backendMessageReceiver.subscribe('InvUpdate', this.onInvUpdateMessage.bind(this))
)
this.stopSubscribe.push(
worldModel.backendMessageReceiver.subscribe('ServerState', this.onServerUpdateMessage.bind(this))
)
await this.loadInvToModel()
this.client.on('connect', this.onMqttConnect) this.client.on('connect', this.onMqttConnect)
this.client.on('message', this.onMqttMessage) this.client.on('message', this.onMqttMessage)
@ -87,16 +90,30 @@ export default class EnvManager {
} }
} }
/**
*
*/
onServerUpdateMessage(type: BackendTopicType, topic: string, data: ServerStatusVo) {
if (worldModel.state.runState.isRunning && worldModel.state.runState.currentEnvId === data.envId) {
// 处理服务器状态更新
if (!data.isRunning) {
// 如果服务器停止了,则断开连接
console.log(`Server stopped: ${data.envId}`)
system.msg(`Server is stopped, client disconnect!`, 'warning')
this.disconnectEnv().finally()
}
}
}
async onInvUpdateMessage(type: BackendTopicType, topic: string, body: InvUpdateVo) { async onInvUpdateMessage(type: BackendTopicType, topic: string, body: InvUpdateVo) {
console.log(`InvUpdate: ${type} ${topic}`, body)
if (!window['Model']) { if (!window['Model']) {
// 如果没有3D模型加载,则不处理库存更新 // 如果没有3D模型加载,则不处理库存更新
return return
} }
const lpnItem = Model.find(body.lpn) Model.deleteInv(body.lpn)
if (lpnItem) {
Model.deleteItem(lpnItem.id)
}
if (body.after != null) { if (body.after != null) {
// 将托盘挪到目标位置 // 将托盘挪到目标位置
@ -223,6 +240,6 @@ export default class EnvManager {
* *
*/ */
dispose(): void { dispose(): void {
this.disconnectEnv() this.disconnectEnv().finally()
} }
} }

4
src/core/script/ModelManager.ts

@ -85,6 +85,10 @@ export default class ModelManager implements IControls, Model {
return position return position
} }
deleteInv(itemId) {
this.viewport.runtimeManager.removeEntity(itemId)
}
deleteItem(itemId) { deleteItem(itemId) {
if (this.viewport.runtimeManager.has(itemId)) { if (this.viewport.runtimeManager.has(itemId)) {
// 临时执行器 // 临时执行器

4
src/editor/widgets/server/EnvSelectConnect.vue

@ -55,10 +55,10 @@ export default {
methods: { methods: {
renderIcon, renderIcon,
connectEnv() { connectEnv() {
worldModel.envManager.connectEnv() worldModel.envManager.connectEnv().finally()
}, },
disconnectEnv() { disconnectEnv() {
worldModel.envManager.disconnectEnv() worldModel.envManager.disconnectEnv().finally()
}, },
createEnv() { createEnv() {
EnvManager.createEnv(this.worldModelState.project_uuid).then(() => { EnvManager.createEnv(this.worldModelState.project_uuid).then(() => {

43
src/modules/amr/ptr/cl2/Cl2Renderer.ts

@ -1,8 +1,9 @@
import * as THREE from 'three' import * as THREE from 'three'
import BaseRenderer from '@/core/base/BaseRenderer.ts' import BaseRenderer from '@/core/base/BaseRenderer.ts'
import Constract from '@/core/Constract.ts' import Constract from '@/core/Constract.ts'
import Cl23dObject from "./Cl23dObject"; import Cl23dObject from './Cl23dObject'
import type { Object3DLike } from '@/types/ModelTypes.ts' import type { Object3DLike } from '@/types/ModelTypes.ts'
import type Viewport from '@/core/engine/Viewport.ts'
/** /**
* ptr侧叉渲染器 * ptr侧叉渲染器
@ -24,6 +25,39 @@ export default class PtrRenderer extends BaseRenderer {
} }
/** /**
* Cl2 Position Rotation
*/
getStorePlacement(storeItem: ItemJson, bay = 0, level = 0, cell = 0)
: {
position: [number, number, number], rotation: [number, number, number],
getParentObject3D?: (viewport: Viewport, parent: THREE.Object3D) => THREE.Object3D
} {
return {
position: [0, 0.2, 0],
rotation: [0, 90, 0],
getParentObject3D: this.getArmObject.bind(this)
}
}
getArmObject(viewport: Viewport, item: ItemJson): THREE.Object3D {
// 获取机械臂对象
const object = viewport.entityManager.findObjectById(item.dt.storeAt?.item)
if (!object) {
console.warn('PtrRenderer: getArmObject failed, not found Cl2:', item.dt.storeAt?.item)
return
}
const agv = object as THREE.Group
if (agv.children.length > 1) {
const pillar = agv.children[1]
if (pillar.children.length > 1) {
return pillar.children[1]
}
}
}
/**
* 使 storeWidth/storeDepth, TF无效 * 使 storeWidth/storeDepth, TF无效
*/ */
override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: THREE.Object3D) { override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: THREE.Object3D) {
@ -39,7 +73,6 @@ export default class PtrRenderer extends BaseRenderer {
) )
} }
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D { createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D {
throw new Error('not allow store line.') throw new Error('not allow store line.')
} }
@ -51,11 +84,6 @@ export default class PtrRenderer extends BaseRenderer {
createPoint(item: ItemJson, option?: RendererCudOption): THREE.Object3D { createPoint(item: ItemJson, option?: RendererCudOption): THREE.Object3D {
// 创建平面几何体 // 创建平面几何体
if (!item.dt.ptrWidth || !item.dt.ptrDepth) {
system.showErrorDialog('field ptrWidth / ptrDepth is null!')
return null
}
const group = new Cl23dObject(item, this.tempViewport, option) const group = new Cl23dObject(item, this.tempViewport, option)
group.name = PtrRenderer.POINT_NAME group.name = PtrRenderer.POINT_NAME
@ -64,7 +92,6 @@ export default class PtrRenderer extends BaseRenderer {
return group return group
} }
updatePoint(item: ItemJson, object: Object3DLike, option?: RendererCudOption): Object3DLike { updatePoint(item: ItemJson, object: Object3DLike, option?: RendererCudOption): Object3DLike {
const group: THREE.Group = object as THREE.Group const group: THREE.Group = object as THREE.Group

2
src/modules/rack/RackRenderer.ts

@ -83,7 +83,7 @@ export default class RackRenderer extends BaseRenderer {
localX += bays[bay].bayWidth / 2 // 居中 localX += bays[bay].bayWidth / 2 // 居中
let localY = 0 let localY = 0
for (let i = 0; i < level; i++) { for (let i = 0; i <= level; i++) {
localY += levelHeights[i] localY += levelHeights[i]
} }

5
src/types/Model.d.ts

@ -40,6 +40,11 @@ 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
/**
* ID
* @param itemId ID
*/
deleteInv(itemId: string): void
/** /**
* *

1
src/types/Types.d.ts

@ -63,6 +63,7 @@ interface RendererCudOption {
position?: any position?: any
//THREE.Quaternion //THREE.Quaternion
rotation?: any rotation?: any
getParentObject3D?: (viewport:any, item: ItemJson) => any
} }
/** /**

Loading…
Cancel
Save