From 9bbea8b9b451ee74f18a3d7917c7ac135535542e Mon Sep 17 00:00:00 2001 From: yuliang <398780299@qq.com> Date: Wed, 25 Jun 2025 19:08:19 +0800 Subject: [PATCH] =?UTF-8?q?cl2=20=E5=9F=BA=E4=BA=8E=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=92=8C=E4=BB=BB=E5=8A=A1=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=88=86=E6=AD=A5=E7=94=9F=E6=88=90=E8=AE=BE=E5=A4=87=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/command-example/f1.json | 422 +++++++++++++++++++++++++++++++++++++++++ src/modules/cl2/Cl23dObject.ts | 140 ++++++++++---- 2 files changed, 526 insertions(+), 36 deletions(-) create mode 100644 doc/command-example/f1.json diff --git a/doc/command-example/f1.json b/doc/command-example/f1.json new file mode 100644 index 0000000..e6c5387 --- /dev/null +++ b/doc/command-example/f1.json @@ -0,0 +1,422 @@ +[ + { + "id": "rack1", + "t": "rack", + "v": true, + "tf": [ + [ + 1.55, + 0, + -1.5 + ], + [ + 0, + 0, + 0 + ], + [ + 2.2, + 2.8, + 1 + ] + ], + "dt": { + "rackDepth": 1, + "bottomBarHeight": 0.2, + "bottomLinkHeight": 0.2, + "topLinkDistance": 0.2, + "levelCount": 2, + "bayCount": 2, + "hideFloor": 0, + "extendColumns": 1, + "columnSpacing": 1, + "bays": [ + { + "bayWidth": 1.1, + "levelHeight": [ + 1.4, + 1.4 + ] + }, + { + "bayWidth": 1.1, + "levelHeight": [ + 1.4, + 1.4 + ] + } + ], + "center": [], + "in": [], + "out": [], + "rackWidth": 2.2, + "rackHeight": 2.8 + }, + "_rid": "_2" + }, + { + "id": "rack2", + "t": "rack", + "v": true, + "tf": [ + [ + 3.9, + 0, + -1.5 + ], + [ + 0, + 0, + 0 + ], + [ + 2.2, + 2.8, + 1 + ] + ], + "dt": { + "rackDepth": 1, + "bottomBarHeight": 0.2, + "bottomLinkHeight": 0.2, + "topLinkDistance": 0.2, + "levelCount": 2, + "bayCount": 2, + "hideFloor": 0, + "extendColumns": 1, + "columnSpacing": 1, + "bays": [ + { + "bayWidth": 1.1, + "levelHeight": [ + 1.4, + 1.4 + ] + }, + { + "bayWidth": 1.1, + "levelHeight": [ + 1.4, + 1.4 + ] + } + ], + "center": [], + "in": [], + "out": [], + "rackWidth": 2.2, + "rackHeight": 2.8 + }, + "_rid": "_3" + }, + { + "id": "1_2", + "t": "way", + "v": true, + "logicX": 1, + "logicY": 2, + "tf": [ + [ + 1, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "2_2" + ], + "out": [ + "2_2" + ], + "center": [], + "linkStore": [ + { + "item": "rack1", + "bay": 0, + "level": 0, + "cell": 0, + "direction": "up" + }, + { + "item": "rack1", + "bay": 0, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_4" + }, + { + "id": "2_2", + "t": "way", + "v": true, + "logicX": 2, + "logicY": 2, + "tf": [ + [ + 2.1, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "1_2", + "3_2" + ], + "out": [ + "1_2", + "3_2" + ], + "center": [], + "linkStore": [ + { + "item": "rack1", + "bay": 1, + "level": 0, + "cell": 0, + "direction": "up" + }, + { + "item": "rack1", + "bay": 1, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_5" + }, + { + "id": "3_2", + "t": "way", + "v": true, + "logicX": 3, + "logicY": 2, + "tf": [ + [ + 3.39, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "2_2", + "4_2" + ], + "out": [ + "2_2", + "4_2" + ], + "center": [], + "linkStore": [ + { + "item": "rack2", + "bay": 0, + "level": 0, + "cell": 0, + "direction": "up" + }, + { + "item": "rack2", + "bay": 0, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_6" + }, + { + "id": "4_2", + "t": "way", + "v": true, + "logicX": 4, + "logicY": 2, + "tf": [ + [ + 4.44, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "3_2", + "5_2" + ], + "out": [ + "3_2", + "5_2" + ], + "center": [], + "linkStore": [ + { + "item": "rack2", + "bay": 1, + "level": 0, + "cell": 0, + "direction": "up" + }, + { + "item": "rack2", + "bay": 1, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_7" + }, + { + "id": "5_2", + "t": "way", + "v": true, + "logicX": 5, + "logicY": 2, + "tf": [ + [ + 5.44, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "4_2", + "6_2" + ], + "out": [ + "4_2", + "6_2" + ], + "center": [] + }, + "_rid": "_8" + }, + { + "id": "6_2", + "t": "way", + "v": true, + "logicX": 6, + "logicY": 2, + "tf": [ + [ + 6.44, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "5_2" + ], + "out": [ + "5_2" + ], + "center": [], + "agvRotation": [ + "cl2", + "clx" + ] + }, + "_rid": "_9" + }, + { + "id": "3", + "t": "cl2", + "v": true, + "tf": [ + [ + 6.440, + 0, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 1.5, + 1.98, + 1.5 + ] + ], + "dt": { + "in": [], + "out": [], + "center": [], + "ptrWidth": 1.5, + "ptrDepth": 1.5, + "ptrHeight": 1.98 + } + } +] diff --git a/src/modules/cl2/Cl23dObject.ts b/src/modules/cl2/Cl23dObject.ts index fb76010..94d83f0 100644 --- a/src/modules/cl2/Cl23dObject.ts +++ b/src/modules/cl2/Cl23dObject.ts @@ -25,7 +25,7 @@ export interface Cl2Task { GoodsSlotDirection: 0 | 1 | 2 | 3 | 15; GoodsId: string; Link: { - id: string; // 实际报文没有 + // id: string; // 实际报文没有 X: number; Y: number; Speed: number; @@ -54,17 +54,17 @@ export default class Cl23dObject extends THREE.Object3D { const segments = 64; // 圆的分段精度 // 计算切割线与圆的交点 - const intersectY = Math.sqrt(radius*radius - lineDist*lineDist); - const startAngle = Math.asin(intersectY/radius); - const endAngle = Math.acos(intersectY/radius); + const intersectY = Math.sqrt(radius * radius - lineDist * lineDist); + const startAngle = Math.asin(intersectY / radius); + const endAngle = Math.acos(intersectY / radius); const shape = new THREE.Shape(); shape.moveTo(0, 0); // 起点在圆心 shape.absarc(0, 0, 0.8, startAngle, endAngle, false); // 从0到π绘制半圆 - shape.absarc(0, 0, 0.8, startAngle + Math.PI/2, endAngle + Math.PI/2, false); + shape.absarc(0, 0, 0.8, startAngle + Math.PI / 2, endAngle + Math.PI / 2, false); shape.absarc(0, 0, 0.8, startAngle + Math.PI, endAngle + Math.PI, false); - shape.absarc(0, 0, 0.8, startAngle + Math.PI/2 * 3, endAngle + Math.PI/2 * 3, false); + shape.absarc(0, 0, 0.8, startAngle + Math.PI / 2 * 3, endAngle + Math.PI / 2 * 3, false); shape.lineTo(-0.5, -intersectY) shape.lineTo(-0.5, -intersectY + 0.17) @@ -147,7 +147,7 @@ export default class Cl23dObject extends THREE.Object3D { shape.lineTo(-0.728 + width, -0.358 + depth - dd); shape.lineTo(-0.728 + width - dd, -0.358 + depth); shape.lineTo(-0.728 + dd, -0.358 + depth); - shape.lineTo(-0.728, -0.358 + depth - dd); + shape.lineTo(-0.728, -0.358 + depth - dd); // shape.lineTo(-0.728, -0.358 + dd); // shape.closePath() @@ -170,7 +170,6 @@ export default class Cl23dObject extends THREE.Object3D { let geometry = new THREE.ExtrudeGeometry(shape, options) - const fd = 0.03 const shapeBf = new THREE.Shape(); @@ -341,11 +340,12 @@ export default class Cl23dObject extends THREE.Object3D { private taskList: Task[] = []; private executingTask: Task[] = []; - private travelAnimation: core.Tween = null - private rotationAnimation: core.Tween = null; - private riseAnimation: core.Tween = null; - private stretchAnimation: core.Tween = null; - + private travelAnimation: core.Tween = null + private rotationAnimation: core.Tween = null; + private riseAnimation: core.Tween = null; + private stretchAnimation: core.Tween = null; + private currentAnimation: core.Tween = null; + private currentDirection: number = 15; public get cl2Entity(): Cl2Entity { @@ -357,6 +357,7 @@ export default class Cl23dObject extends THREE.Object3D { } private clock = new THREE.Clock(); + constructor(item: ItemJson, option?: RendererCudOption) { super(); console.log("time", this.clock.getElapsedTime()); @@ -428,8 +429,8 @@ export default class Cl23dObject extends THREE.Object3D { // 事件绑定 client.on('connect', () => { console.log('Connected'); - client.subscribe(['/wcs_server/' + item.id], { qos: 0 }); - client.publish('/agv_robot/status', JSON.stringify(m20020), { retain: true }); + client.subscribe(['/wcs_server/' + item.id], {qos: 0}); + client.publish('/agv_robot/status', JSON.stringify(m20020), {retain: true}); }); client.on('message', (topic, msg) => { @@ -461,19 +462,54 @@ export default class Cl23dObject extends THREE.Object3D { } } + const startTask = { + X: data.content.StartX, + Y: data.content.StartY, + Speed: 0 + } for (const item of data.content.Link) { + let moveDirection: 0 | 1 | 2 | 3 | 15 = 15; + if (startTask.X < item.X) { + if (item.Speed > 0) { + moveDirection = 0 + } else { + moveDirection = 2 + } + } + if (startTask.Y < item.Y) { + if (item.Speed > 0) { + moveDirection = 1 + } else { + moveDirection = 3 + } + } + // 添加到队列 this.taskList.push({ SeqNo: data.content.SeqNo, - OperationType: data.content.OperationType, - PickMode: data.content.PickMode, + OperationType: 0, + PickMode: 0, GoodsSlotHeight: data.content.GoodsSlotHeight, GoodsSlotDirection: data.content.GoodsSlotDirection, X: item.X, Y: item.Y, Speed: item.Speed, + Direction: moveDirection + }) + startTask.X = item.X + startTask.Y = item.Y + startTask.Speed = item.Speed + } + if (data.content.OperationType === 4 || data.content.OperationType === 5) { + this.taskList.push({ + OperationType: data.content.OperationType, + PickMode: data.content.PickMode, + GoodsSlotHeight: data.content.GoodsSlotHeight, + GoodsSlotDirection: data.content.GoodsSlotDirection, }) + } + console.log("time", this.clock.getElapsedTime()); this.executeTask() @@ -488,11 +524,16 @@ export default class Cl23dObject extends THREE.Object3D { executeTask() { + const currentTask = this.executingTask[this.executingTask.length - 1] while (this.taskList.length > 0) { const task = this.taskList.shift() - this.addTravel(task.X, task.Y, task.Speed/1000) - - this.executingTask.push(task) + if (task.OperationType === 0) { + this.addTravel(task.X, task.Y, task.Speed / 1000) + } + if ((task.Speed > 0) != (currentTask.Speed > 1) || task.Direction != currentTask.Direction) { + // 转向 + // this.addArmRotate(task.Direction) + } } @@ -535,15 +576,15 @@ export default class Cl23dObject extends THREE.Object3D { repeat: 0, ease: 'sine.inOut', onComplete: resolve, - onUpdate: function() { + onUpdate: function () { const a = this.targets()[0] - if (a.y < bh) { + if (a.y < bh) { if (pz > -1) { for (let i = 0; i < children.length; i++) { const child = children[i] child.position.y = bh - a.y } - } else if (a.y < 0 ) { + } else if (a.y < 0) { for (let i = 0; i < children.length; i++) { const child = children[i] child.position.y = 0 - a.y @@ -561,28 +602,53 @@ export default class Cl23dObject extends THREE.Object3D { // 转 - addRotation(rad: number): Promise { + addRotation(direction: number): Promise { + let rad = 0; + switch (direction) { + case 1: + rad = Math.PI / 2 * 3; + break; + case 2: + rad = Math.PI; + break; + case 3: + rad = Math.PI / 2; + break; + default: + rad = 0; + } const quat1 = new THREE.Quaternion().setFromEuler(this.rotation); const euler: Euler = new Euler(this.rotation.x, rad, this.rotation.z); const quat2 = new THREE.Quaternion().setFromEuler(euler); const angleDiff = quat1.angleTo(quat2); console.log(rad, this.rotation.y, angleDiff) const tr = this.rotation.y + angleDiff - let time = Math.abs(angleDiff) / (Math.PI/3) - const duration = angleDiff != 0 ? Math.max(0.5, time) : 0 - return new Promise(resolve => { - gsap.to(this.rotation, { - y: tr, - duration, - ease: 'none', - onComplete: resolve - }) - }) + let time = Math.abs(angleDiff) / (Math.PI / 7) + const duration = time + if (!this.rotationAnimation) { + return new Promise(resolve => { + this.rotationAnimation = gsap.to(this.rotation, { + y: tr, + duration, + ease: 'none', + onComplete: () => { + this.rotationAnimation = null + this.currentAnimation = null + resolve() + } + }) + this.currentAnimation = this.rotationAnimation + }) + } else { + this.rotationAnimation.vars.y = tr + const tt = this.rotationAnimation.duration() + this.rotationAnimation.duration(tt + duration) + } } // 走 - addTravel(logicX: number, logicY: number, speed : number = 1): Promise { + addTravel(logicX: number, logicY: number, speed: number = 1): Promise { const pos = Model.getPositionByLogicXY(logicX, logicY) @@ -599,11 +665,13 @@ export default class Cl23dObject extends THREE.Object3D { z: toPos.z, duration, ease: 'sine.inOut', - onComplete: ()=>{ + onComplete: () => { this.travelAnimation = null; + this.currentAnimation = null resolve() } }) + this.currentAnimation = this.travelAnimation }) } else { this.travelAnimation.vars.x = toPos.x