@ -1,37 +1,12 @@
import * as THREE from 'three'
import * as THREE from 'three'
import { CSG } from 'three-csg-ts'
import { CSG } from 'three-csg-ts'
//@ts-ignore
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js'
import gsap from 'gsap'
import gsap from 'gsap'
import mqtt from 'mqtt'
import mqtt from 'mqtt'
import { Euler } from 'three/src/math/Euler'
import { Euler } from 'three/src/math/Euler'
import Cl2Entity from '@/modules/cl2/Cl2Entity'
import Cl2Entity from '@/modules/cl2/Cl2Entity'
import Cl23DGraphics from "@/modules/cl2/Cl23DGraphics"
import { AmrErrorCode , AmrMsg , AmrMsg10010 , AmrMsg20020 , AmrMsg20149 , AmrMsg20250 , type LogicDirection } from "@/core/manager/amr/AmrMessageDefine" ;
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 ;
} [ ]
}
}
interface Task {
interface Task {
SeqNo : number ;
SeqNo : number ;
@ -46,293 +21,6 @@ interface Task {
export default class Cl23dObject extends THREE . Object3D {
export default class Cl23dObject extends THREE . Object3D {
// 创建ptr的底座
private static createPtrPedestal ( ) : THREE . BufferGeometry {
// 参数配置
const radius = 0.8 // 圆半径
const lineDist = 0.75 // 切割线距离圆心距离
const segments = 64 // 圆的分段精度
// 计算切割线与圆的交点
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 , endAngle + Math . PI , 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 )
shape . lineTo ( 0.75 , - intersectY + 0.17 )
shape . lineTo ( 0.75 , intersectY - 0.17 )
shape . lineTo ( - 0.5 , intersectY - 0.17 )
shape . lineTo ( - 0.5 , intersectY )
shape . closePath ( ) // 闭合路径
// 拉伸轨迹线
const curve = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 0.02 , 0 ) , new THREE . Vector3 ( 0 , 0.22 , 0 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
// 挤出几何图形 参数
const options = {
steps : 1 ,
bevelEnabled : false ,
extrudePath : curve // 设置挤出轨迹
}
// 创建挤出几何体
const geometry = new THREE . ExtrudeGeometry ( shape , options )
const material = new THREE . MeshBasicMaterial ( { color : 0xffdddbca } )
const mesh = new THREE . Mesh ( geometry , material )
mesh . updateMatrix ( )
// 倒角
const shapeD = new THREE . Shape ( )
shapeD . moveTo ( - 0.02 , - 0.02 )
shapeD . lineTo ( 0.02 , 0.02 )
shapeD . lineTo ( - 0.02 , 0.02 )
shapeD . closePath ( )
const curveD = new THREE . EllipseCurve (
0 , 0 , radius , radius , 0 , Math . PI * 2 , false , 0
)
// 生成拉伸路径点
const pointsD = curveD . getPoints ( segments ) . map ( p = >
new THREE . Vector3 ( p . x , 0.20 , p . y )
)
// 3. 挤出成型
const optionsD = {
steps : segments ,
bevelEnabled : false ,
// bevelSegments: 0.01,
extrudePath : new THREE . CatmullRomCurve3 ( pointsD )
}
const geometryD = new THREE . ExtrudeGeometry ( shapeD , optionsD )
const meshD = new THREE . Mesh ( geometryD , material )
meshD . updateMatrix ( )
// 布尔运算
const result = CSG . subtract ( mesh , meshD )
return result . geometry
}
// 创建ptr的立柱
private static createPtrPillar ( ) : THREE . BufferGeometry {
// 606.5
const width = 0.245
const depth = 0.716
const dd = 0.05
const shape = new THREE . Shape ( )
shape . moveTo ( - 0.728 , - 0.358 + dd )
shape . lineTo ( - 0.728 + dd , - 0.358 )
shape . lineTo ( - 0.728 + width - dd , - 0.358 )
shape . lineTo ( - 0.728 + width , - 0.358 + dd )
shape . lineTo ( - 0.728 + width , - 0.28 )
shape . lineTo ( - 0.728 + width - 0.08 , - 0.28 )
shape . lineTo ( - 0.728 + width - 0.08 , 0.28 )
shape . lineTo ( - 0.728 + width , 0.28 )
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 + dd);
// shape.closePath()
// 拉伸轨迹线
const curve = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 0.22 , 0 ) , new THREE . Vector3 ( 0 , 1.872 , 0 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
// 挤出几何图形 参数
const options = {
steps : 1 ,
bevelSegments : 0.05 ,
bevelEnabled : true ,
extrudePath : curve // 设置挤出轨迹
}
// 创建挤出几何体
let geometry = new THREE . ExtrudeGeometry ( shape , options )
const fd = 0.03
const shapeBf = new THREE . Shape ( )
shapeBf . moveTo ( - 0.728 + width - 0.08 , - 0.28 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , - 0.28 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , - 0.25 )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , - 0.25 )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 , - 0.25 + fd )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 , - 0.14 - fd )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , - 0.14 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , - 0.14 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , 0.14 )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , 0.14 )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 , 0.14 + fd )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 , 0.25 - fd )
shapeBf . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , 0.25 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , 0.25 )
shapeBf . lineTo ( - 0.728 + width + 0.02 , 0.28 )
shapeBf . lineTo ( - 0.728 + width - 0.08 , 0.28 )
shapeBf . closePath ( )
// 拉伸轨迹线
const curveBf = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 0.02 , 0 ) , new THREE . Vector3 ( 0 , 0.06 , 0 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
// 挤出几何图形 参数
const optionsBf = {
steps : 1 ,
bevelSegments : 0.05 ,
bevelEnabled : true ,
extrudePath : curveBf // 设置挤出轨迹
}
// 创建挤出几何体
const geometryBf = new THREE . ExtrudeGeometry ( shapeBf , optionsBf )
geometry = mergeGeometries ( [ geometry , geometryBf ] )
const material = new THREE . MeshBasicMaterial ( { color : 0xffdddbca } )
const mesh = new THREE . Mesh ( geometry , material )
const shapeD = new THREE . Shape ( )
shapeD . moveTo ( - 0.3 , - 0.25 )
shapeD . lineTo ( - 0.3 , 0.25 )
shapeD . lineTo ( 0.3 , 0.25 )
shapeD . lineTo ( 0.3 , - 0.25 )
shapeD . closePath ( )
const curveD = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 1.45 , - 1 ) , new THREE . Vector3 ( 0 , 1.45 , 1 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
const optionsD = {
steps : 1 ,
bevelSegments : 0.05 ,
bevelEnabled : true ,
extrudePath : curveD // 设置挤出轨迹
}
const geometryD = new THREE . ExtrudeGeometry ( shapeD , optionsD )
const meshD = new THREE . Mesh ( geometryD , material )
mesh . updateMatrix ( )
meshD . updateMatrix ( )
const result = CSG . subtract ( mesh , meshD )
return result . geometry
}
// 创建ptr的立柱
private static createPtrFork ( ) : THREE . BufferGeometry {
// 606.5
const width = 0.245
const depth = 0.716
const dd = 0.05
const fd = 0.03
const shape = new THREE . Shape ( )
shape . moveTo ( - 0.728 + width - 0.08 , - 0.28 )
shape . lineTo ( - 0.728 + width + 0.02 , - 0.28 )
shape . lineTo ( - 0.728 + width + 0.02 , - 0.27 )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , - 0.27 )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 , - 0.27 + fd )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 , - 0.12 - fd )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , - 0.12 )
shape . lineTo ( - 0.728 + width + 0.02 , - 0.12 )
shape . lineTo ( - 0.728 + width + 0.02 , 0.12 )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , 0.12 )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 , 0.12 + fd )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 , 0.27 - fd )
shape . lineTo ( - 0.728 + width + 0.02 + 1.130 - fd , 0.27 )
shape . lineTo ( - 0.728 + width + 0.02 , 0.27 )
shape . lineTo ( - 0.728 + width + 0.02 , 0.28 )
shape . lineTo ( - 0.728 + width - 0.08 , 0.28 )
shape . closePath ( )
// 拉伸轨迹线
const curve = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 0.02 , 0 ) , new THREE . Vector3 ( 0 , 0.482 , 0 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
// 挤出几何图形 参数
const options = {
steps : 1 ,
bevelSegments : 0.05 ,
bevelEnabled : true ,
extrudePath : curve // 设置挤出轨迹
}
// 创建挤出几何体
const geometry = new THREE . ExtrudeGeometry ( shape , options )
const material = new THREE . MeshBasicMaterial ( { color : 0xffdddbca } )
const mesh = new THREE . Mesh ( geometry , material )
mesh . updateMatrix ( )
const shapeD = new THREE . Shape ( )
shapeD . moveTo ( - 0.728 + width + 0.02 , - 0.3 )
shapeD . lineTo ( - 0.728 + width + 0.02 + 1.2 , - 0.3 )
shapeD . lineTo ( - 0.728 + width + 0.02 + 1.2 , 0.3 )
shapeD . lineTo ( - 0.728 + width + 0.02 , 0.3 )
shape . closePath ( )
// 拉伸轨迹线
const curveD = new THREE . CatmullRomCurve3 (
[ new THREE . Vector3 ( 0 , 0.07 , 0 ) , new THREE . Vector3 ( 0 , 0.482 , 0 ) ] ,
false , // 闭合曲线
'catmullrom' ,
0
)
// 挤出几何图形 参数
const optionsD = {
steps : 1 ,
bevelSegments : 0.05 ,
bevelEnabled : true ,
extrudePath : curveD // 设置挤出轨迹
}
// 创建挤出几何体
const geometryD = new THREE . ExtrudeGeometry ( shapeD , optionsD )
const meshD = new THREE . Mesh ( geometryD , material )
meshD . updateMatrix ( )
// 布尔运算
const result = CSG . subtract ( mesh , meshD )
return result . geometry
}
private static ptrPedestalGeometry : THREE.BufferGeometry = null
private static ptrPillarGeometry : THREE.BufferGeometry = null
private static ptrForkGeometry : THREE.BufferGeometry = null
private item : ItemJson
private item : ItemJson
private _cl2Entity : Cl2Entity = null
private _cl2Entity : Cl2Entity = null
@ -345,8 +33,11 @@ export default class Cl23dObject extends THREE.Object3D {
private riseAnimation : core.Tween = null
private riseAnimation : core.Tween = null
private stretchAnimation : core.Tween = null
private stretchAnimation : core.Tween = null
private currentAnimation : core.Tween = null
private currentAnimation : core.Tween = null
private currentDirection : number = 15
private currentDirection : LogicDirection = 15
private bootTime : number = 0
private seqNoName : string = ""
public get cl2Entity ( ) : Cl2Entity {
public get cl2Entity ( ) : Cl2Entity {
if ( ! this . _cl2Entity ) {
if ( ! this . _cl2Entity ) {
@ -362,26 +53,26 @@ export default class Cl23dObject extends THREE.Object3D {
super ( )
super ( )
console . log ( 'time' , this . clock . getElapsedTime ( ) )
console . log ( 'time' , this . clock . getElapsedTime ( ) )
this . item = item
this . item = item
if ( ! Cl23dObject . ptrPedestalGeometry ) {
if ( ! Cl23DGraphics . ptrPedestalGeometry ) {
Cl23dObject . ptrPedestalGeometry = Cl23dObject . createPtrPedestal ( )
Cl23DGraphics . ptrPedestalGeometry = Cl23DGraphics . createPtrPedestal ( )
}
}
const ptrPedestalGeometry = Cl23dObject . ptrPedestalGeometry
const ptrPedestalGeometry = Cl23DGraphics . ptrPedestalGeometry
const ptrPedestalMaterial = new THREE . MeshPhongMaterial ( { color : 0xffdddbca } )
const ptrPedestalMaterial = new THREE . MeshPhongMaterial ( { color : 0xffdddbca } )
const ptrPedestalMesh = new THREE . Mesh ( ptrPedestalGeometry , ptrPedestalMaterial )
const ptrPedestalMesh = new THREE . Mesh ( ptrPedestalGeometry , ptrPedestalMaterial )
ptrPedestalMesh . name = 'ptrPedestal'
ptrPedestalMesh . name = 'ptrPedestal'
if ( ! Cl23dObject . ptrPillarGeometry ) {
if ( ! Cl23DGraphics . ptrPillarGeometry ) {
Cl23dObject . ptrPillarGeometry = Cl23dObject . createPtrPillar ( )
Cl23DGraphics . ptrPillarGeometry = Cl23DGraphics . createPtrPillar ( )
}
}
const ptrPillarGeometry = Cl23dObject . ptrPillarGeometry
const ptrPillarGeometry = Cl23DGraphics . ptrPillarGeometry
const ptrPillarMaterial = new THREE . MeshPhongMaterial ( { color : 0xff6c6956 } )
const ptrPillarMaterial = new THREE . MeshPhongMaterial ( { color : 0xff6c6956 } )
const ptrPillarMesh = new THREE . Mesh ( ptrPillarGeometry , ptrPillarMaterial )
const ptrPillarMesh = new THREE . Mesh ( ptrPillarGeometry , ptrPillarMaterial )
if ( ! Cl23dObject . ptrForkGeometry ) {
if ( ! Cl23DGraphics . ptrForkGeometry ) {
Cl23dObject . ptrForkGeometry = Cl23dObject . createPtrFork ( )
Cl23DGraphics . ptrForkGeometry = Cl23DGraphics . createPtrFork ( )
}
}
const ptrForkGeometry = Cl23dObject . ptrForkGeometry
const ptrForkGeometry = Cl23DGraphics . ptrForkGeometry
const ptrForkMaterial = new THREE . MeshPhongMaterial ( { color : 0xff444444 } )
const ptrForkMaterial = new THREE . MeshPhongMaterial ( { color : 0xff444444 } )
const ptrForkMesh = new THREE . Mesh ( ptrForkGeometry , ptrForkMaterial )
const ptrForkMesh = new THREE . Mesh ( ptrForkGeometry , ptrForkMaterial )
ptrForkMesh . name = 'ptrFork'
ptrForkMesh . name = 'ptrFork'
@ -393,48 +84,82 @@ export default class Cl23dObject extends THREE.Object3D {
groupPillar . add ( ptrForkMesh )
groupPillar . add ( ptrForkMesh )
this . add ( groupPillar )
this . add ( groupPillar )
try {
this . seqNoName = 'CL2' + this . cl2Entity . id
// 安全连接配置
// 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
// })
const client = {
on() {
}
}
// debugger
/ *
// 事件绑定
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 . on ( 'message' , ( topic , msg ) = > {
}
console . log ( ` [ ${ topic } ] ${ msg } ` )
const a : Cl2Task = JSON . parse ( msg . toString ( ) )
this . handleMessage ( a )
} )
private AGVModel = "CYBER-LIFT-A_V1.0"
private AGVFnModel = "FITBOTS-CYBER-LIFT-1000_V1.0"
client . on ( 'error' , ( error ) = > {
console . error ( 'Error:' , error )
// 开机
} )
boot() {
* /
this . bootTime = Date . now ( ) ;
} catch ( e ) {
this . computeLogicDirection ( ) ;
console . error ( e )
this . subscribeMessage ( '/wcs_server/' + this . cl2Entity . id )
setTimeout ( ( ) = > {
this . send20149 ( )
// 检查当前所在位置和方向 根据车当前所在的xz坐标获取地标
setTimeout ( ( ) = > {
this . sendCurrentPositionAndDirection ( )
} , 1000 )
} , 2000 )
}
// 关机
shutdown() {
}
// 主程序启动上报
send20149() {
const content = new AmrMsg20149 ( )
content . AGVModel = this . AGVModel
content . AGVFnModel = this . AGVFnModel
// 电量
content . Battery = 100
content . CreateMonoTime = Date . now ( ) - this . bootTime
content . VehicleId = parseInt ( this . cl2Entity . id )
const m20149 = new AmrMsg < AmrMsg20149 > ( content )
this . sendMessage ( m20149 )
}
// 上报当前位姿,地标和方向
sendCurrentPositionAndDirection() {
const pointItem = Model . getItemByXYZ ( this . position . x , this . position . y , this . position . z )
if ( ! pointItem || ! pointItem . logicX || ! pointItem . logicY ) {
// 当前车辆所在位置未找到
const content = new AmrMsg20250 ( )
content . Duration = 0
content . ErrCode = 5
content . ErrCodeName = AmrErrorCode [ 5 ] . ErrCodeName
content . ErrEvtType = 1
content . ErrLevel = 14
content . ErrLifecycle = 2
content . CreateMonoTime = Date . now ( ) - this . bootTime
content . VehicleId = parseInt ( this . cl2Entity . id )
const m20250 = new AmrMsg < AmrMsg20250 > ( content )
this . sendMessage ( m20250 )
} else {
// 发送正常地标信息
const content = new AmrMsg20020 ( )
content . CurDirection = this . currentDirection
content . CurLogicX = pointItem . logicX
content . CurLogicY = pointItem . logicY
content . CurX = pointItem . logicX
content . CurY = pointItem . logicY
content . CreateMonoTime = Date . now ( ) - this . bootTime
content . VehicleId = parseInt ( this . cl2Entity . id )
const m20020 = new AmrMsg < AmrMsg20020 > ( content )
this . sendMessage ( m20020 )
}
}
}
}
subscribeMessage ( topic : string ) {
this . cl2Entity . viewport . envManager . client . subscribe ( topic , { qos : 0 } )
}
sendMessage ( msg : AmrMsg < any > ) {
this . cl2Entity . viewport . envManager . client . publish ( '/agv_robot/status' , JSON . stringify ( msg ) )
}
/*==========消息处理============*/
/*==========消息处理============*/
@ -463,7 +188,7 @@ export default class Cl23dObject extends THREE.Object3D {
client . publish ( '/agv_robot/status' , JSON . stringify ( m20020 ) , { retain : true } )
client . publish ( '/agv_robot/status' , JSON . stringify ( m20020 ) , { retain : true } )
}
}
handleMessage ( data : Cl2Task ) {
handleMessage ( data : AmrMsg < AmrMsg10010 > ) {
return
return
if ( data . id === 10010 ) {
if ( data . id === 10010 ) {
@ -535,6 +260,32 @@ export default class Cl23dObject extends THREE.Object3D {
}
}
}
}
// 计算逻辑方向
computeLogicDirection() {
let ra = this . rotation . y
while ( ra > Math . PI * 2 ) {
ra -= Math . PI * 2
}
while ( ra < 0 ) {
ra += Math . PI * 2
}
const ddra = Math . PI / 8
if ( ra >= ddra * 7 || ra < ddra ) {
this . currentDirection = 0 ;
} else if ( ra >= ddra && ra < ddra * 3 ) {
this . currentDirection = 3 ;
} else if ( ra >= ddra * 3 && ra < ddra * 5 ) {
this . currentDirection = 2 ;
} else if ( ra >= ddra * 5 && ra < ddra * 7 ) {
this . currentDirection = 1 ;
} else {
this . currentDirection = 15 ;
}
}
executeTask() {
executeTask() {
if ( this . currentAnimation ) {
if ( this . currentAnimation ) {
@ -720,3 +471,5 @@ export default class Cl23dObject extends THREE.Object3D {
// }, 2000)
// }, 2000)
}
}