From f3cd5658e6e096809decd590ef4ab18fb344840d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Fri, 14 Mar 2025 07:03:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=81=9C=E6=AD=A2=E5=96=B7=E6=B6=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/qyft/ms/app/handler/MatrixSprayState.java | 53 ++ .../qyft/ms/app/handler/impl/MatrixSprayStart.java | 549 +++++++++++---------- .../qyft/ms/app/handler/impl/MatrixSprayStop.java | 1 + 3 files changed, 337 insertions(+), 266 deletions(-) diff --git a/src/main/java/com/qyft/ms/app/handler/MatrixSprayState.java b/src/main/java/com/qyft/ms/app/handler/MatrixSprayState.java index 712a5a0..cd96cb3 100644 --- a/src/main/java/com/qyft/ms/app/handler/MatrixSprayState.java +++ b/src/main/java/com/qyft/ms/app/handler/MatrixSprayState.java @@ -4,6 +4,11 @@ package com.qyft.ms.app.handler; import lombok.Data; import org.springframework.stereotype.Component; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + @Component @Data public class MatrixSprayState { @@ -12,4 +17,52 @@ public class MatrixSprayState { */ private Double targetX = null; private Double targetY = null; + + // 用于提交任务的线程池 + private final ExecutorService executorService = Executors.newSingleThreadExecutor(); + + // 保存当前任务的 Future 对象 + private volatile Future taskFuture; + + // 停止任务的标志,volatile 保证多线程可见性 + private volatile boolean stopRequested = false; + + // 重置状态,启动任务前调用 + public void reset() { + stopRequested = false; + } + + // 请求停止任务 + public void requestStop() { + this.stopRequested = true; + } + + /** + * 启动一个异步任务,并保存其 Future 对象 + * @param task 需要异步执行的任务 + */ + public void startTask(Runnable task) { + reset(); + taskFuture = executorService.submit(task); + } + + /** + * 取消当前任务,设置停止标志并尝试调用 Future.cancel(true) + * @return 取消结果信息 + */ + public String cancelTask() { + requestStop(); + if (taskFuture != null && !taskFuture.isDone()) { + boolean cancelled = taskFuture.cancel(true); + return cancelled ? "任务停止请求已发送" : "任务取消失败"; + } + return "当前没有正在运行的任务"; + } + + /** + * 关闭线程池(如在程序退出时调用) + */ + public void shutdown() { + executorService.shutdown(); + } } diff --git a/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStart.java b/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStart.java index 59fc051..1430473 100644 --- a/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStart.java +++ b/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStart.java @@ -9,6 +9,7 @@ import com.qyft.ms.app.common.command.FrontCommandAck; import com.qyft.ms.app.common.constant.CommandStatus; import com.qyft.ms.app.common.generator.PathGenerator; import com.qyft.ms.app.handler.CommandHandler; +import com.qyft.ms.app.handler.MatrixSprayState; import com.qyft.ms.app.model.bo.CMDToDevice; import com.qyft.ms.app.model.form.CMDFormV2; import com.qyft.ms.device.client.TcpClient; @@ -16,7 +17,6 @@ import com.qyft.ms.device.handler.DeviceMessageHandler; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; @@ -34,7 +34,7 @@ import java.util.concurrent.TimeoutException; @Slf4j @Component @RequiredArgsConstructor -@Async("asyncExecutor") +//@Async("asyncExecutor") @CommandMapping("matrix_spray_start")//业务指令注解 public class MatrixSprayStart implements CommandHandler { @@ -42,6 +42,8 @@ public class MatrixSprayStart implements CommandHandler { private final DeviceMessageHandler deviceMessageHandler; + private final MatrixSprayState matrixSprayState; + /** * { * cmdName:'matrix_spray_start' @@ -62,61 +64,65 @@ public class MatrixSprayStart implements CommandHandler { */ @Override public void handle(CMDFormV2 cmdForm, ResponseBodyEmitter emitter) throws Exception { - String frontCmdId = cmdForm.getCmdId(); - String frontCmdName = cmdForm.getCmdName(); - Map param = cmdForm.getParam(); - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.RECEIVE, "后台已收到指令"), MediaType.APPLICATION_JSON);//向前端发送接收到指令 - // 1. 参数校验 - String matrixPathType = Optional.ofNullable(param.get("matrixPathType")) - .map(Object::toString) - .orElse(null); - - Double motorZHeight = Optional.ofNullable(param.get("motorZHeight")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Double gasPressure = Optional.ofNullable(param.get("gasPressure")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Double volume = Optional.ofNullable(param.get("volume")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Boolean highVoltage = Optional.ofNullable(param.get("highVoltage")) - .map(Object::toString) - .map(Boolean::parseBoolean) - .orElse(null); - - Double highVoltageValue = Optional.ofNullable(param.get("highVoltageValue")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Double spacing = Optional.ofNullable(param.get("spacing")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Double movingSpeed = Optional.ofNullable(param.get("movingSpeed")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - Double times = Optional.ofNullable(param.get("times")) - .map(Object::toString) - .map(Double::parseDouble) - .orElse(null); - - @SuppressWarnings("unchecked") - List> positionList = (List>) param.get("position"); - - - if (validate(emitter, matrixPathType, frontCmdId, frontCmdName, motorZHeight, gasPressure, volume, highVoltage, highVoltageValue, spacing, movingSpeed, times, positionList)) - return; + log.info("申请中断喷涂线程:{}", matrixSprayState.cancelTask()); + matrixSprayState.startTask(() -> { + try { + String frontCmdId = cmdForm.getCmdId(); + String frontCmdName = cmdForm.getCmdName(); + Map param = cmdForm.getParam(); + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.RECEIVE, "后台已收到指令"), MediaType.APPLICATION_JSON);//向前端发送接收到指令 + + // 1. 参数校验 + String matrixPathType = Optional.ofNullable(param.get("matrixPathType")) + .map(Object::toString) + .orElse(null); + + Double motorZHeight = Optional.ofNullable(param.get("motorZHeight")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Double gasPressure = Optional.ofNullable(param.get("gasPressure")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Double volume = Optional.ofNullable(param.get("volume")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Boolean highVoltage = Optional.ofNullable(param.get("highVoltage")) + .map(Object::toString) + .map(Boolean::parseBoolean) + .orElse(null); + + Double highVoltageValue = Optional.ofNullable(param.get("highVoltageValue")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Double spacing = Optional.ofNullable(param.get("spacing")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Double movingSpeed = Optional.ofNullable(param.get("movingSpeed")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + Double times = Optional.ofNullable(param.get("times")) + .map(Object::toString) + .map(Double::parseDouble) + .orElse(null); + + @SuppressWarnings("unchecked") + List> positionList = (List>) param.get("position"); + + + if (validate(emitter, matrixPathType, frontCmdId, frontCmdName, motorZHeight, gasPressure, volume, highVoltage, highVoltageValue, spacing, movingSpeed, times, positionList)) + return; // DeviceInstance deviceInstance = DeviceInstance.getInstance(); // MatrixSprayStatusEnum matrixSprayStatus = DeviceInstance.getInstance().getMatrixSprayStatusEnum(); @@ -126,221 +132,232 @@ public class MatrixSprayStart implements CommandHandler { // return; // } // deviceInstance.setMatrixSprayStatusEnum(MatrixSprayStatusEnum.YES);//如果没有在喷涂,设定当前状态为正在喷涂 - //三轴回到原点 先 z - CountDownLatch latch = new CountDownLatch(1); - deviceMessageHandler.setLatch(latch); - // z轴回原点 - if (originZ(emitter, frontCmdId, frontCmdName)) return; - boolean finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - // x轴回原点 - if (originX(emitter, frontCmdId, frontCmdName)) return; - // y轴回原点 - if (originY(emitter, frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.RESULT, "x轴与y轴已回到原点"), MediaType.APPLICATION_JSON); - - //设定轴移动速度 - if (motorSpeedSet(emitter, movingSpeed, frontCmdId, frontCmdName)) return; - - //2. 插入日志 - //TODO写日志 - //4.开启三通阀到喷嘴管路 - if (threeWayValveOpenSyringePipeLine(emitter, frontCmdId, frontCmdName)) return; - //7.移动到指定高度(位置) (z - height) - Double height = 101.2 - motorZHeight;//TODO 101.2是玻片高度,这个应该从数据库中获取 - latch = new CountDownLatch(1); - deviceMessageHandler.setLatch(latch); - if (moveZ(emitter, height, frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - //8.是否加电 电压 - if (highVoltage) {//加电 - if (highVoltageOpen(emitter, highVoltageValue, frontCmdId, frontCmdName)) return; - } - //9 循环position进 position:[{x1,y1,x2,y2,index}] - Double[][] slideArr = { - {18.08, 0.0}, - {45.08, 0.0}, - {72.08, 0.0}, - {99.08, 0.0} - }; - for (Map postion : positionList) { - //范围左上角 x1,y1 - Double[] upperLeft = {((Number) postion.get("x1")).doubleValue(), ((Number) postion.get("y1")).doubleValue()}; - //范围右下角 x2,y2 - Double[] lowerRight = {((Number) postion.get("x2")).doubleValue(), ((Number) postion.get("y2")).doubleValue()}; - //index 第几个玻片 - int index = (int) postion.get("index"); - //1.获取玻片的位置 - Double[] slide = slideArr[index]; - //2.玻片范围的实际位置 - Double slideCompleteUCSX = slide[0] + upperLeft[0]; - Double slideCompleteUCSY = slide[1] + upperLeft[1]; - //3.算出路径坐标list - //定义边界 - // 托盘点位 x y z - double left = slideCompleteUCSX + upperLeft[0]; - double right = slideCompleteUCSX + lowerRight[0]; - double top = slideCompleteUCSY + upperLeft[1]; - double bottom = slideCompleteUCSY + lowerRight[1]; - //移动xy到slide(玻片)的位置 - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "xy移动到玻片位置",slide), MediaType.APPLICATION_JSON); - if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; - if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "开始按照路径喷涂",slide), MediaType.APPLICATION_JSON); - if ("horizontal".equals(matrixPathType)) { //生成路径(从“左上角”往下的水平之字形) String matrixPathType = (String) param.get("matrix_path_type");//喷涂路径类型 horizontal | vertical | grid - for (int i = 0; i < times; i++) { - double topReal = top; - double bottomReal = bottom; - if (i != 0 && i % 2 == 0) {//双数喷涂 - double halfSpacing = spacing / 2; - topReal = top - halfSpacing; - bottomReal = bottom + halfSpacing; - } - List pathList = PathGenerator.generatePathPoints( - left, right, topReal, bottomReal, - spacing, - PathGenerator.MoveMode.HORIZONTAL_ZIGZAG_TOP_DOWN - ); - if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) return;//路径喷涂 - if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 - log.info("123"); - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; - if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - } + //三轴回到原点 先 z + CountDownLatch latch = new CountDownLatch(1); + deviceMessageHandler.setLatch(latch); + // z轴回原点 + if (originZ(emitter, frontCmdId, frontCmdName)) return; + boolean finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; } - } else if ("vertical".equals(matrixPathType)) { - for (int i = 0; i < times; i++) { - double leftReal = left; - double rightReal = right; - if (i != 0 && i % 2 == 0) {//双数喷涂 - double halfSpacing = spacing / 2; - leftReal = top - halfSpacing; - rightReal = bottom + halfSpacing; - } - List pathList = PathGenerator.generatePathPoints( - leftReal, rightReal, top, bottom, - spacing, - PathGenerator.MoveMode.VERTICAL_ZIGZAG_LEFT_RIGHT - ); - if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) return;//路径喷涂 - if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 - log.info("123"); - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; - if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - } + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + // x轴回原点 + if (originX(emitter, frontCmdId, frontCmdName)) return; + // y轴回原点 + if (originY(emitter, frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.RESULT, "x轴与y轴已回到原点"), MediaType.APPLICATION_JSON); + + //设定轴移动速度 + if (motorSpeedSet(emitter, movingSpeed, frontCmdId, frontCmdName)) return; + + //2. 插入日志 + //TODO写日志 + //4.开启三通阀到喷嘴管路 + if (threeWayValveOpenSyringePipeLine(emitter, frontCmdId, frontCmdName)) return; + //7.移动到指定高度(位置) (z - height) + Double height = 101.2 - motorZHeight;//TODO 101.2是玻片高度,这个应该从数据库中获取 + latch = new CountDownLatch(1); + deviceMessageHandler.setLatch(latch); + if (moveZ(emitter, height, frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; } - } else if ("grid".equals(matrixPathType)) {//横竖喷2次 - for (int i = 0; i < times; i++) { - double leftReal = left; - double rightReal = right; - double topReal = top; - double bottomReal = bottom; - if (i != 0 && i % 2 == 0) {//双数喷涂 - double halfSpacing = spacing / 2; - leftReal = top - halfSpacing; - rightReal = bottom + halfSpacing; - topReal = top - halfSpacing; - bottomReal = bottom + halfSpacing; + //8.是否加电 电压 + if (highVoltage) {//加电 + if (highVoltageOpen(emitter, highVoltageValue, frontCmdId, frontCmdName)) return; + } + //9 循环position进 position:[{x1,y1,x2,y2,index}] + Double[][] slideArr = { + {18.08, 0.0}, + {45.08, 0.0}, + {72.08, 0.0}, + {99.08, 0.0} + }; + for (Map postion : positionList) { + //范围左上角 x1,y1 + Double[] upperLeft = {((Number) postion.get("x1")).doubleValue(), ((Number) postion.get("y1")).doubleValue()}; + //范围右下角 x2,y2 + Double[] lowerRight = {((Number) postion.get("x2")).doubleValue(), ((Number) postion.get("y2")).doubleValue()}; + //index 第几个玻片 + int index = (int) postion.get("index"); + //1.获取玻片的位置 + Double[] slide = slideArr[index]; + //2.玻片范围的实际位置 + Double slideCompleteUCSX = slide[0] + upperLeft[0]; + Double slideCompleteUCSY = slide[1] + upperLeft[1]; + //3.算出路径坐标list + //定义边界 + // 托盘点位 x y z + double left = slideCompleteUCSX + upperLeft[0]; + double right = slideCompleteUCSX + lowerRight[0]; + double top = slideCompleteUCSY + upperLeft[1]; + double bottom = slideCompleteUCSY + lowerRight[1]; + //移动xy到slide(玻片)的位置 + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "xy移动到玻片位置", slide), MediaType.APPLICATION_JSON); + if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; + if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; } - List pathList = PathGenerator.generatePathPoints( - leftReal, rightReal, topReal, bottomReal, - spacing, - PathGenerator.MoveMode.VERTICAL_ZIGZAG_LEFT_RIGHT - ); - if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) return;//路径喷涂 - pathList = PathGenerator.generatePathPoints( - leftReal, rightReal, topReal, bottomReal, - spacing, - PathGenerator.MoveMode.HORIZONTAL_ZIGZAG_TOP_DOWN - ); - if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) return;//路径喷涂 - if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 - log.info("123"); - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; - if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "开始按照路径喷涂", slide), MediaType.APPLICATION_JSON); + if ("horizontal".equals(matrixPathType)) { //生成路径(从“左上角”往下的水平之字形) String matrixPathType = (String) param.get("matrix_path_type");//喷涂路径类型 horizontal | vertical | grid + for (int i = 0; i < times; i++) { + double topReal = top; + double bottomReal = bottom; + if (i != 0 && i % 2 == 0) {//双数喷涂 + double halfSpacing = spacing / 2; + topReal = top - halfSpacing; + bottomReal = bottom + halfSpacing; + } + List pathList = PathGenerator.generatePathPoints( + left, right, topReal, bottomReal, + spacing, + PathGenerator.MoveMode.HORIZONTAL_ZIGZAG_TOP_DOWN + ); + if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) + return;//路径喷涂 + if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 + log.info("123"); + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; + if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + } + } + } else if ("vertical".equals(matrixPathType)) { + for (int i = 0; i < times; i++) { + double leftReal = left; + double rightReal = right; + if (i != 0 && i % 2 == 0) {//双数喷涂 + double halfSpacing = spacing / 2; + leftReal = top - halfSpacing; + rightReal = bottom + halfSpacing; + } + List pathList = PathGenerator.generatePathPoints( + leftReal, rightReal, top, bottom, + spacing, + PathGenerator.MoveMode.VERTICAL_ZIGZAG_LEFT_RIGHT + ); + if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) + return;//路径喷涂 + if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 + log.info("123"); + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; + if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + } + } + } else if ("grid".equals(matrixPathType)) {//横竖喷2次 + for (int i = 0; i < times; i++) { + double leftReal = left; + double rightReal = right; + double topReal = top; + double bottomReal = bottom; + if (i != 0 && i % 2 == 0) {//双数喷涂 + double halfSpacing = spacing / 2; + leftReal = top - halfSpacing; + rightReal = bottom + halfSpacing; + topReal = top - halfSpacing; + bottomReal = bottom + halfSpacing; + } + List pathList = PathGenerator.generatePathPoints( + leftReal, rightReal, topReal, bottomReal, + spacing, + PathGenerator.MoveMode.VERTICAL_ZIGZAG_LEFT_RIGHT + ); + if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) + return;//路径喷涂 + pathList = PathGenerator.generatePathPoints( + leftReal, rightReal, topReal, bottomReal, + spacing, + PathGenerator.MoveMode.HORIZONTAL_ZIGZAG_TOP_DOWN + ); + if (pathSpray(emitter, frontCmdId, frontCmdName, volume, pathList, movingSpeed)) + return;//路径喷涂 + if (i + 1 != times) { //如果不是最后一次,执行完毕后回到玻片原点 + log.info("123"); + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + if (moveX(emitter, slide[0], frontCmdId, frontCmdName)) return; + if (moveY(emitter, slide[1], frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + } } } } + //10.关高压电 + if (highVoltageClose(emitter, frontCmdId, frontCmdName)) return; + //11.回到原点 motorMoveToHome 先 z + latch = new CountDownLatch(1); + deviceMessageHandler.setLatch(latch); + // z轴回原点 + if (originZ(emitter, frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + latch = new CountDownLatch(2); + deviceMessageHandler.setLatch(latch); + // x轴回原点 + if (originX(emitter, frontCmdId, frontCmdName)) return; + + // y轴回原点 + if (originY(emitter, frontCmdId, frontCmdName)) return; + finished = latch.await(5 * 60, TimeUnit.SECONDS); + if (!finished) { + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); + emitter.complete(); + return; + } + //12.结束日志 + //TODO写日志 + emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "指令执行完毕"), MediaType.APPLICATION_JSON); + } catch (Exception e) { + Thread.currentThread().interrupt(); + log.info("喷涂线程已停止"); + System.out.println("任务中断"); + } finally { + emitter.complete(); } - } - //10.关高压电 - if (highVoltageClose(emitter, frontCmdId, frontCmdName)) return; - //11.回到原点 motorMoveToHome 先 z - latch = new CountDownLatch(1); - deviceMessageHandler.setLatch(latch); - // z轴回原点 - if (originZ(emitter, frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - latch = new CountDownLatch(2); - deviceMessageHandler.setLatch(latch); - // x轴回原点 - if (originX(emitter, frontCmdId, frontCmdName)) return; - - // y轴回原点 - if (originY(emitter, frontCmdId, frontCmdName)) return; - finished = latch.await(5 * 60 , TimeUnit.SECONDS); - if (!finished) { - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); - emitter.complete(); - return; - } - //12.结束日志 - //TODO写日志 - emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.SEND, "指令执行完毕"), MediaType.APPLICATION_JSON); - emitter.complete(); + }); } @@ -488,7 +505,7 @@ public class MatrixSprayStart implements CommandHandler { //移动x与y到点位 if (moveX(emitter, p.getX(), frontCmdId, frontCmdName)) return true; if (moveY(emitter, 75.5 - p.getY(), frontCmdId, frontCmdName)) return true; - boolean finished = latch.await(5 * 60 , TimeUnit.SECONDS); + boolean finished = latch.await(5 * 60, TimeUnit.SECONDS); if (!finished) { emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.ERROR, "等待指令执行完成超时"), MediaType.APPLICATION_JSON); emitter.complete(); diff --git a/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStop.java b/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStop.java index 2b555eb..ebbfea6 100644 --- a/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStop.java +++ b/src/main/java/com/qyft/ms/app/handler/impl/MatrixSprayStop.java @@ -49,6 +49,7 @@ public class MatrixSprayStop implements CommandHandler { String frontCmdId = cmdForm.getCmdId(); String frontCmdName = cmdForm.getCmdName(); emitter.send(FrontCommandAck.backstageAck(frontCmdId, frontCmdName, CommandStatus.RECEIVE, "后台已收到指令"), MediaType.APPLICATION_JSON);//向前端发送接收到指令 + log.info("申请中断喷涂线程:{}", matrixSprayState.cancelTask()); //1.轴停止移动 CMDToDevice motorXStopCMDToDevice = DeviceCommandGenerator.motor_x_stop(); //x轴停止移动指令 CommandFuture motorXStopCMDToDeviceFuture = new CommandFuture();