import request from './common' import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers' const delayMs = (ms) => { return new Promise((resolve) => { setTimeout(() => { resolve(null) }, ms) }) } interface TeachParamsType { joint: { acceleration: number[] velocity: number[] jerk: number[] } coordinate: { acceleration: number[] velocity: number[] jerk: number[] } } const retryRequest = async (handle: any, retries: number, delay = 1000): Promise => { let retry = retries while (retry > 0) { try { const res = await handle() return res } catch (error) { retry -= 1 if (retry === 0) { throw error } } await delayMs(delay) } } class IntervalWorker { private _handle: (target: any) => Promise //执行 private _completedCallback: (res: any, target: any) => boolean //完成检测 private _timer!: any private _interval!: number private _successHandle!: (data: any) => void //数据处理回调 private _failHandle!: (data: any) => void //数据出错回调 working = false breaking = false constructor( handle: (target: any) => Promise, completedCallback: (res: any, target: any) => boolean, interval = 200 ) { this._handle = handle this._interval = interval this._completedCallback = completedCallback } setDataCallBack(successHandle: (data: any) => void, failHandle: (data: any) => void) { this._successHandle = successHandle this._failHandle = failHandle } start(target: any, repeat = true) { this.breaking = false if (this._timer) { clearTimeout(this._timer) } this._timer = setTimeout(async () => { this.working = true try { const res = await this._handle(target) if (this._successHandle) this?._successHandle(res) const completed = this._completedCallback(res, target) if (!completed && repeat && !this.breaking) { this.start(target) } else { this.working = false this.breaking = false } } catch (e) { console.error(e) if (this._failHandle) this._failHandle(e) if (!this.breaking && repeat) { this.start(target) } } }, this._interval) } startOnce(target: any) { this.start(target, false) } stop() { this.working = false this.breaking = true } } class VcControl { deviceId!: string resource!: any server: string joints: number[] = [] pose: number[] = [] exchangeWorker!: IntervalWorker movJWorker!: IntervalWorker jointMovJWorker!: IntervalWorker jogWorker!: IntervalWorker pingWorker!: IntervalWorker proxyUrl = '' mqttUrl = '' constructor(server = '') { this.server = server this.exchangeWorker = new IntervalWorker( (data: any) => request.get(`${this.proxyUrl}/protocol/exchange`), (res: any, target: any) => { return false } ) this.movJWorker = new IntervalWorker( (data: any) => request.post({ url: `${this.proxyUrl}/interface/movJ`, data }), (res: any, target: any) => { return ( Math.abs(this.pose[0] - target.pose[0]) < 1 && Math.abs(this.pose[1] - target.pose[1]) < 1 && Math.abs(this.pose[2] - target.pose[2]) < 1 ) } ) this.jointMovJWorker = new IntervalWorker( (data: any) => request.post({ url: `${this.proxyUrl}/interface/jointMovJ`, data }), (res: any, target: any) => { return ( Math.abs(this.joints[0] - target.joint[0]) < 1 && Math.abs(this.joints[1] - target.joint[1]) < 1 && Math.abs(this.joints[2] - target.joint[2]) < 1 && Math.abs(this.joints[3] - target.joint[3]) < 1 && Math.abs(this.joints[4] - target.joint[4]) < 1 && Math.abs(this.joints[5] - target.joint[5]) < 1 ) } ) this.jogWorker = new IntervalWorker( (data: any) => request.post({ url: `${this.proxyUrl}/panel/jog`, data }), (res: any, target: any) => { return false }, 300 ) } setPose(pose: any, joints: any) { this.joints = joints this.pose = pose } getUrl() { return `${location.origin}/palletizing/${this.resource.server}` } getMqttUrl() { return this.mqttUrl } //设置虚拟控制器资源 setResource(resource: any, deviceId: string) { this.resource = resource this.deviceId = deviceId this.proxyUrl = `${this.server}/palletizing/${this.resource.server}` this.mqttUrl = location.protocol == 'http:' ? `ws://${location.host}/mqtt/${this.resource.mqtt}` : `wss://${location.host}/mqtt/${this.resource.mqtt}` } //设置iframe下的控制器地址 setServerInIframe(ip: string) { this.server = `http://${ip}:22000` this.proxyUrl = this.server this.mqttUrl = `ws://${ip}:8083` } //逆解算 async inverseCal(data: any) { return request.post({ url: `${this.proxyUrl}/interface/inverseCal`, data }) } //正解算 async forwardCal(data: any) { return request.post({ url: `${this.proxyUrl}/interface/forwardCal`, data }) } //设置用户坐标系 async setUserCoordinate(data: any) { return request.post({ url: `${this.proxyUrl}/settings/coordinate/user`, data }) } //获取用户坐标系 async getUserCoordinate(data: any) { return request.get(`${this.proxyUrl}/settings/coordinate/user`) } //设置工具坐标系 async setToolCoordinate(data: any) { return request.post({ url: `${this.proxyUrl}/settings/coordinate/tool`, data }) } //获取工具坐标系 async getToolCoordinate(data: any) { return request.get(`${this.proxyUrl}/settings/coordinate/tool`) } //movJ async movJ(data: { value: boolean; pose: number[]; user: number; tool: number }) { if (!this.movJWorker.working) { this.movJWorker.start(data) } else { console.error('正在执行中, 不可重复操作') } } //停止movj stopMovJ() { this.movJWorker.stop() } //get movJ async getMoveStatus() { return request.get('/interface/movJ') } //获取关节位移 getJointMovJ() { return request.get(`${this.proxyUrl}/interface/jointMovJ`) } //设置关节位移 setJointMovJ(data: { joint: number[]; value: boolean }) { if (!this.movJWorker.working) { this.jointMovJWorker.start(data) } else { console.error('正在执行中, 不可重复操作') } } //停止关节位移 stopJointMovJ() { this.jointMovJWorker.stop() } // 周期性命令和数据交互 startExchange(successHandle: any, failHandle: any) { this.exchangeWorker.setDataCallBack(successHandle, failHandle) this.exchangeWorker.start(null) } exchangeOnce(successHandle: any) { this.exchangeWorker.setDataCallBack(successHandle, null) this.exchangeWorker.startOnce(null) } // 周期性命令和数据交互 stopExchange() { this.exchangeWorker.stop() } // 开始Jog startJog(btnType: string, BtnsIndex: number) { const data: any = { posBtns: [false, false, false, false, false, false], negBtns: [false, false, false, false, false, false] } const BtnsKey = btnType == '+' ? 'posBtns' : 'negBtns' data[BtnsKey][BtnsIndex] = true this.jogWorker.start(data) } startJogOnce(btnType: string, BtnsIndex: number) { const data: any = { posBtns: [false, false, false, false, false, false], negBtns: [false, false, false, false, false, false] } const BtnsKey = btnType == '+' ? 'posBtns' : 'negBtns' data[BtnsKey][BtnsIndex] = true this.jogWorker.startOnce(data) } // 周期性命令和数据交互 stopJog() { this.jogWorker.stop() } // 获取调试器状态 getDebuggerState() { return request.get(`${this.proxyUrl}/debugger/state`) } // 启动调试器 setDebuggerStart(projectName: string) { return retryRequest( () => request.post({ url: `${this.proxyUrl}/debugger/start`, data: { project: projectName, isDebug: false } }), 10 ) } // 停止调试器 setDebuggerStop = () => { return request.post({ url: `${this.proxyUrl}/debugger/stop`, data: {} }) } // 暂停调试器 setDebuggerSuspend = () => { return request.post({ url: `${this.proxyUrl}/debugger/suspend`, data: {} }) } // 运行 setDebuggerRun = () => { return request.post({ url: `${this.proxyUrl}/debugger/run`, data: {} }) } //清除报警 async clearAlarms() { return request.post({ url: `${this.proxyUrl}/interface/clearAlarms`, data: null }) } //设置负载 async setLoadParams(isCheck: boolean) { return request.post({ url: `${this.proxyUrl}/settings/function/loadParams`, data: { name: '', isCheck, centerX: 0.0, centerY: 0.0, centerZ: 0.0, loadValue: 0.0 } }) } //设置使能 async setEnable() { return request.post({ url: `${this.proxyUrl}/settings/controlMode`, data: { controlMode: 'enable' } }) } //配置为自动模式 async setAuto(autoManual: 'auto' | 'manual') { return request.post({ url: `${this.proxyUrl}/settings/function/autoManual`, data: { autoManual } }) } //配置速度 0 - 100 async setSpeedRatio(ratio: number) { return request.post({ url: `${this.proxyUrl}/settings/common`, data: { ratio } }) } // async setTeachParams(params: TeachParamsType) { await request.post({ url: `${this.proxyUrl}/settings/teach/joint`, data: params.joint }) return await request.post({ url: `${this.proxyUrl}/settings/teach/coordinate`, data: params.coordinate }) } async setPlaybackParams(params: TeachParamsType) { await request.post({ url: `${this.proxyUrl}/settings/playback/joint`, data: params.joint }) return await request.post({ url: `${this.proxyUrl}/settings/playback/coordinate`, data: params.coordinate }) } stopAll() { this.exchangeWorker.stop() this.jointMovJWorker.stop() this.movJWorker.stop() } //保存参数 async setPalletizingList(data: any[]) { return request.post({ url: `${this.proxyUrl}/process/palletizing/params`, data }) } //保存点动模式 async setJogMode(mode: 'jog' | 'step') { return request.post({ url: `${this.proxyUrl}/interface/jogMode`, data: { mode } }) } //设置模式 async setMode(mode: 'joint' | 'cartesian') { return request.post({ url: `${this.proxyUrl}/interface/coordinate`, data: { mode } }) } //设置刻度 async setTechInch(distance: number) { return request.post({ url: `${this.proxyUrl}/settings/teach/inch`, data: { distance } }) } //虚实轴切换 0 实轴 1虚轴 async setAxes(value: number) { return request.post({ url: `${this.proxyUrl}/debugger/simulate/axes`, data: { simulate: value } }) } //虚实轴切换 0 实轴 1虚轴 async getAxes() { return request.get(`${this.proxyUrl}/debugger/simulate/axes`) } //请求资源 async requestResource() { return request.post({ url: '/api/vcmanage/requestResource', data: {} }) } //保存工程 async saveProject(data: any) { data.sshPort = this.resource.ssh return request.post({ url: '/api/fileupload/upload', data }) } //上传视频 // async uploadVideo(data: any) { // return request.post({ url: '/api/fileupload/uploadVideo', data }) // } } const vcControl = new VcControl('') export default vcControl