Browse Source

cl2 接入amr指令

master
yuliang 6 months ago
parent
commit
53e1c0607f
  1. 5794
      doc/台湾展会项目V2.json
  2. 1
      package.json
  3. 444
      pnpm-lock.yaml
  4. 61
      src/example/example1.js
  5. 149
      src/modules/cl2/Cl23dObject.ts
  6. 81
      src/modules/cl2/Cl2Entity.ts

5794
doc/台湾展会项目V2.json

File diff suppressed because one or more lines are too long

1
package.json

@ -60,6 +60,7 @@
"split.js": "^1.6.4",
"three": "^0.177.0",
"three-csg-ts": "^3.2.0",
"mqtt": "^5.13.1",
"three-mesh-bvh": "^0.9.0",
"troika-three-text": "^0.52.4",
"tslib": "2.8.1",

444
pnpm-lock.yaml

File diff suppressed because it is too large

61
src/example/example1.js

@ -203,6 +203,9 @@ export default {
},
{
id: '1', t: 'way', v: true,
logicX: 11,
logicY: 10,
logicZ: 1,
tf: [[2.7, 0, 2.13], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['2', '38', '36'], out: ['2', '38', '36'], center: [],
@ -211,11 +214,17 @@ export default {
},
{
id: '2', t: 'way', v: true,
logicX: 11,
logicY: 11,
logicZ: 1,
tf: [[2.7, 0, 2.832], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: ['1', '3'], out: ['1', '3'], center: [] }
},
{
id: '3', t: 'way', v: true,
logicX: 11,
logicY: 13,
logicZ: 1,
tf: [[2.7, 0, 3.932], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['2', '4'], out: ['2', '4'], center: [],
@ -224,11 +233,17 @@ export default {
},
{
id: '4', t: 'way', v: true,
logicX: 11,
logicY: 15,
logicZ: 1,
tf: [[2.7, 0, 4.582], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: ['3', '5'], out: ['3', '5'], center: [] }
},
{
id: '5', t: 'way', v: true,
logicX: 11,
logicY: 16,
logicZ: 1,
tf: [[2.7, 0, 5.232], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['4', '6'], out: ['4', '6'], center: [],
@ -237,11 +252,17 @@ export default {
},
{
id: '6', t: 'way', v: true,
logicX: 11,
logicY: 17,
logicZ: 1,
tf: [[2.7, 0, 5.882], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: ['5', '7'], out: ['5', '7'], center: [] }
},
{
id: '7', t: 'way', v: true,
logicX: 11,
logicY: 18,
logicZ: 1,
tf: [[2.7, 0, 6.532], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['6', '8'], out: ['6', '8'], center: [],
@ -250,6 +271,9 @@ export default {
},
{
id: '8', t: 'way', v: true,
logicX: 11,
logicY: 20,
logicZ: 1,
tf: [[2.7, 0, 7.75], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['7', 'charger1'], out: ['7', 'charger1'], center: [],
@ -258,11 +282,17 @@ export default {
},
{
id: '17', t: 'way', v: true,
logicX: 13,
logicY: 10,
logicZ: 1,
tf: [[5.65, 0, 2.13], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: ['20'], out: ['20'], center: [] }
},
{
id: '20', t: 'way', v: true,
logicX: 13,
logicY: 12,
logicZ: 1,
tf: [[5.65, 0, 2.865], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['17', '21'], out: ['17', '21'], center: [],
@ -271,6 +301,9 @@ export default {
},
{
id: '21', t: 'way', v: true,
logicX: 13,
logicY: 13,
logicZ: 1,
tf: [[5.65, 0, 3.932], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['20', '22'], out: ['20', '22'], center: [],
@ -279,6 +312,9 @@ export default {
},
{
id: '22', t: 'way', v: true,
logicX: 13,
logicY: 14,
logicZ: 1,
tf: [[5.65, 0, 4.348], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['21', '23'], out: ['21', '23'], center: [],
@ -287,6 +323,9 @@ export default {
},
{
id: '23', t: 'way', v: true,
logicX: 13,
logicY: 16,
logicZ: 1,
tf: [[5.65, 0, 5.232], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['22', '24'], out: ['22', '24'], center: [],
@ -296,11 +335,17 @@ export default {
},
{
id: '24', t: 'way', v: true,
logicX: 13,
logicY: 17,
logicZ: 1,
tf: [[5.65, 0, 5.882], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: ['23', '25'], out: ['23', '25'], center: [] }
},
{
id: '25', t: 'way', v: true,
logicX: 13,
logicY: 18,
logicZ: 1,
tf: [[5.65, 0, 6.532], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['24', '26'], out: ['24', '26'], center: [],
@ -309,6 +354,9 @@ export default {
},
{
id: '26', t: 'way', v: true,
logicX: 13,
logicY: 19,
logicZ: 1,
tf: [[5.65, 0, 6.744], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['25', '27'], out: ['25', '27'], center: [],
@ -317,6 +365,9 @@ export default {
},
{
id: '27', t: 'way', v: true,
logicX: 13,
logicY: 20,
logicZ: 1,
tf: [[5.65, 0, 7.75], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['26', 'charger2'], out: ['26', 'charger2'], center: [],
@ -325,6 +376,9 @@ export default {
},
{
id: '36', t: 'way', v: true,
logicX: 12,
logicY: 10,
logicZ: 1,
tf: [[3.9, 0, 2.13], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['1'], out: ['1'], center: [],
@ -333,6 +387,9 @@ export default {
},
{
id: '38', t: 'way', v: true,
logicX: 10,
logicY: 10,
logicZ: 1,
tf: [[1.5, 0, 2.13], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: {
in: ['1'], out: ['1'], center: [],
@ -366,12 +423,12 @@ export default {
dt: { in: [], out: [], center: [], strokeWidth: 0.1 }
},
{
id: 'ptr1', t: 'cl2', v: true,
id: '10', t: 'cl2', v: true,
tf: [[5.65, 0, 2.13], [0, -90, 0], [1, 1, 1]],
dt: { in: [], out: [], center: [], ptrWidth: 1.5, ptrDepth: 1.5, ptrHeight: 1.98 }
},
{
id: 'clx1', t: 'clx', v: true,
id: '199', t: 'clx', v: true,
tf: [[1.5, 0, 2.13], [0, 0, 0], [1, 1, 1]],
dt: { in: [], out: [], center: [], clxWidth: 1.65, clxDepth: 1.65, clxHeight: 3.393 }
},

149
src/modules/cl2/Cl23dObject.ts

@ -3,7 +3,34 @@ import {CSG} from "three-csg-ts";
//@ts-ignore
import {mergeGeometries} from 'three/addons/utils/BufferGeometryUtils.js'
import gsap from "gsap";
// import mqtt from 'mqtt';
import mqtt from 'mqtt';
import {Euler} from "three/src/math/Euler";
export interface Cl2Task {
// 0:运输 1:接货 2:卸货 3:充电 4:提升移栽取货或卸货 5:滚筒取货或卸货(双向作业) 135:旋转货架 136:旋转车身
id: number;
content: {
SeqNo: number;
OperationType: 0 | 1 | 2 | 3 | 4 | 5 | 135 | 136;
UseBriefLocation: boolean;
StartX: number;
StartY: number;
EndX: number;
EndY: number;
EndDirection: 0 | 1 | 2 | 3 | 15;
// 0:不控制(无动作) 1:从货架上取货 2:将货物放到货架上 3:仅调整托盘高度(不进行取放货操作) 4:调整车身货物(仅供调试,RCS勿发送此命令) 5:仅调整载货台到取货高度,但是不动作 6:仅调整载货台到放货高度,但是不动作
PickMode: 0 | 1 | 2 | 3 | 4 | 5 | 6;
GoodsSlotHeight: number;
GoodsSlotDirection: 0 | 1 | 2 | 3 | 15;
GoodsId: string;
Link: {
id: string; // 实际报文没有
X: number;
Y: number;
Speed: number;
}[]
}
}
export default class Cl23dObject extends THREE.Object3D {
@ -328,36 +355,36 @@ export default class Cl23dObject extends THREE.Object3D {
groupPillar.add(ptrForkMesh)
this.add(groupPillar)
// try {
// // 安全连接配置
// const client = mqtt.connect('mqtt://127.0.0.1:9001', {
// path: '/mqtt',
// clientId: 'virtual-' + item.id,
// clean: true,
// connectTimeout: 10000,
// username: 'user',
// password: 'user',
// unixSocket: true,
// keepalive: 60,
// });
//
// // 事件绑定
// client.on('connect', () => {
// console.log('Connected');
// client.subscribe(['sensor/#', 'alerts'], { qos: 0 });
// client.publish('status', 'online', { retain: true });
// });
//
// client.on('message', (topic, msg) => {
// console.log(`[${topic}] ${msg}`);
// });
//
// client.on('error', (error) => {
// console.error('Error:', error);
// });
// } catch (e) {
// console.error(e)
// }
try {
// 安全连接配置
const client = mqtt.connect('mqtt://127.0.0.1:9001', {
path: '/mqtt',
clientId: 'virtual-' + item.id,
clean: true,
connectTimeout: 10000,
username: 'user',
password: 'user',
unixSocket: true,
keepalive: 60,
});
// 事件绑定
client.on('connect', () => {
console.log('Connected');
client.subscribe(['sensor/#', 'alerts'], { qos: 0 });
client.publish('status', 'online', { retain: true });
});
client.on('message', (topic, msg) => {
console.log(`[${topic}] ${msg}`);
});
client.on('error', (error) => {
console.error('Error:', error);
});
} catch (e) {
console.error(e)
}
}
@ -420,4 +447,64 @@ export default class Cl23dObject extends THREE.Object3D {
}
// 转
addRotation(rad: number): Promise<void> {
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
})
})
}
// 走
addTravel(pos: Vector3IF | string, speed : number = 1): Promise<void> {
const fromPos = this.position
const toPos = new THREE.Vector3(pos.x, pos.y, pos.z)
const distance = fromPos.distanceTo(toPos)
const duration = Math.max(1.0, distance / speed)
return new Promise(resolve => {
gsap.to(this.position, {
x: toPos.x,
y: toPos.y,
z: toPos.z,
duration,
ease: 'sine.inOut',
onComplete: resolve
})
})
}
getDirection(object: THREE.Object3D): 0 | 1 | 2 | 3 | 15 {
let ry = this.rotation.y
while (ry > Math.PI * 2) {
ry = ry - Math.PI * 2
}
while (ry < - Math.PI * 2) {
ry = ry + Math.PI * 2
}
if (ry < 0) {
ry = Math.PI * 2 + ry
}
if (ry >= 0 && ry < Math.PI / 2) {
return 0
}
return 0;
}
}

81
src/modules/cl2/Cl2Entity.ts

@ -3,8 +3,7 @@ import BaseEntity from '@/core/base/BaseItemEntity.ts'
import type Viewport from '@/core/engine/Viewport.ts'
import gsap from 'gsap'
import { nextTick } from 'vue'
import Cl23dObject from "@/modules/cl2/Cl23dObject";
import Cl23dObject, {type Cl2Task} from "@/modules/cl2/Cl23dObject";
/**
* CL2
*/
@ -13,6 +12,84 @@ export default class Cl2Entity extends BaseEntity {
super(viewport, id)
}
// 移动
addRobotTask(task: Cl2Task) {
if (task.id === 10010) {
let startX = task.content.StartX
let startY = task.content.StartY
if (task.content.Link?.length > 0) {
for (let i = 0; i < task.content.Link.length; i++) {
const link = task.content.Link[i];
let moveDirection: 0 | 1 | 2 | 3 | 15 = 15;
// 计算 移动方向
if (startX !== link.X && startY !== link.Y) {
throw new Error('Invalid task');
} else if (startX === link.X) {
if (startY < link.Y && link.Speed > 0 || startY > link.Y && link.Speed < 0) {
moveDirection = 3
} else {
moveDirection = 1
}
} else {
if (startX > link.X && link.Speed > 0 || startX < link.X && link.Speed < 0) {
moveDirection = 2
} else {
moveDirection = 0
}
}
this.taskQueue.add(this.createTask('ROTATION',
() => this.cl2Object.addRotation(moveDirection * Math.PI/2)
))
this.taskQueue.add(this.createTask('TRAVEL',
() => this.cl2Object.addTravel(Model.getPositionByEntityId(link.id) ,Math.abs(link.Speed/1000))
))
startX = link.X
startY = link.Y
}
}
//移动
if (task.content.OperationType === 0) {
} else if (task.content.OperationType === 1) {
} else if (task.content.OperationType === 2) {
} else if (task.content.OperationType === 3) {
} else if (task.content.OperationType === 4) {
// 取货
if (task.content.PickMode === 1) {
const gh = task.content.GoodsSlotHeight/1000
this.addArmRaise(gh)
this.addArmExtender()
// this.addArmRaise(gh + 0.1)
this.addLoad(task.content.GoodsId)
this.addArmRetractor()
this.addArmLower()
// 放货
} else if (task.content.PickMode === 2) {
this.addArmRaise(task.content.GoodsSlotHeight/1000 + 0.2)
this.addArmExtender()
this.addArmLower()
this.addUnload(task.content.GoodsId, '')
this.addArmRetractor()
}
} else if (task.content.OperationType === 5) {
} else if (task.content.OperationType === 135) {
} else if (task.content.OperationType === 136) {}
}
}
// 抬
addArmRaise(height: number) {
// super.addArmRaise(height)

Loading…
Cancel
Save