From e66ff8a4c51185c353e6d33ab76fdf01283aab77 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 10:26:04 +0800 Subject: [PATCH 01/16] =?UTF-8?q?client-id=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/galaxis/rcs/RCSService.java | 4 ++ .../com/galaxis/rcs/ptr/AmrMessageHandler.java | 8 +-- .../java/com/galaxis/rcs/ptr/PtrMqttClient.java | 60 +++++++++++++++++++--- .../java/com/yvan/logisticsEnv/EnvPayload.java | 1 - .../java/com/yvan/logisticsEnv/EnvStartParam.java | 2 + .../com/yvan/logisticsModel/LogisticsRuntime.java | 2 +- 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/RCSService.java b/servo/src/main/java/com/galaxis/rcs/RCSService.java index c66103a..8ae56f4 100644 --- a/servo/src/main/java/com/galaxis/rcs/RCSService.java +++ b/servo/src/main/java/com/galaxis/rcs/RCSService.java @@ -28,6 +28,8 @@ import org.clever.data.jdbc.DaoFactory; import org.clever.data.jdbc.QueryDSL; import org.clever.data.jdbc.querydsl.utils.QueryDslUtils; +import java.lang.management.ManagementFactory; +import java.net.InetAddress; import java.util.Map; import static com.galaxis.rcs.common.query.QLccEnvInfo.lccEnvInfo; @@ -52,6 +54,7 @@ public class RCSService { * 加载所有自动启动的环境和楼层数据 * 并启动对应的环境 */ + @SneakyThrows private void createAutoStartEnv() { QueryDSL queryDSL = DaoFactory.getQueryDSL(); var list = queryDSL.select(QueryDslUtils.linkedMap( @@ -98,6 +101,7 @@ public class RCSService { param.setTimeRate(1); param.setVirtual(false); param.setEnvPayload(envPayload); + param.setClientId(InetAddress.getLocalHost().getHostName()); runtime.start(param); } diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java index 5e24bee..8d3842b 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java @@ -68,7 +68,7 @@ public class AmrMessageHandler { private static final Redis redis = AppContextHolder.getBean("defaultRedis", Redis.class, true); public final LogisticsRuntime runtime; - public volatile PtrMqttClient ptrMqttClient; + private volatile PtrMqttClient ptrMqttClient; public int getNewSeqNo() { String redisKey = "lcc:rcs:" + runtime.projectUUID + ":" + runtime.envId + ":seqNo"; @@ -84,8 +84,8 @@ public class AmrMessageHandler { this.runtime = runtime; } - public void start(EnvPayload.MqttConfig mqttConfig) { - this.ptrMqttClient = new PtrMqttClient(this, mqttConfig); + public void start(EnvPayload.MqttConfig mqttConfig, String clientId) { + this.ptrMqttClient = new PtrMqttClient(this, mqttConfig, clientId); } public void stop() { @@ -209,7 +209,7 @@ public class AmrMessageHandler { BannerUtils.printConfig(log, "MQTT 发送报文 [" + id + "] RcsMessageType." + RcsMessageType.fromValue(id) + " - " + RcsMessageType.fromValue(id).description, ar); } - ptrMqttClient.client.publish(topic, payload.getBytes(StandardCharsets.UTF_8), 0, false); + ptrMqttClient.publish(topic, payload); } /** diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java index cea8883..ed49e01 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java @@ -12,14 +12,16 @@ import org.eclipse.paho.mqttv5.common.MqttException; import org.eclipse.paho.mqttv5.common.MqttMessage; import org.eclipse.paho.mqttv5.common.packet.MqttProperties; +import java.nio.charset.StandardCharsets; + @Slf4j public class PtrMqttClient implements MqttCallback { public final AmrMessageHandler amrMessageHandler; public final EnvPayload.MqttConfig mqttConfig; - public final MqttClient client; + private final MqttClient client; @SneakyThrows - public PtrMqttClient(AmrMessageHandler handler, EnvPayload.MqttConfig mqttConfig) { + public PtrMqttClient(AmrMessageHandler handler, EnvPayload.MqttConfig mqttConfig, String clientId) { this.amrMessageHandler = handler; this.mqttConfig = mqttConfig; @@ -27,17 +29,56 @@ public class PtrMqttClient implements MqttCallback { String username = mqttConfig.getUsername(); String password = mqttConfig.getPassword(); - client = new MqttClient(brokerUrl, mqttConfig.getClientId()); + client = new MqttClient(brokerUrl, clientId); + MqttConnectionOptions options = new MqttConnectionOptions(); + options.setServerURIs(new String[]{brokerUrl}); + options.setAutomaticReconnect(true); + options.setUserName(username); + options.setPassword(password.getBytes()); + options.setConnectionTimeout(10); + options.setKeepAliveInterval(20); + client.setCallback(this); + client.connect(options); + client.subscribe("/agv_robot/status", 0); + } + + @SneakyThrows + public void publish(String topic, String payload) { + this.client.publish(topic, payload.getBytes(StandardCharsets.UTF_8), 0, false); + } + + @SneakyThrows + public static void main(String[] args) { + String brokerUrl = "tcp://10.10.203.239:1885"; + String clientId = "yvan-rcs-dev"; + String topic = "test/topic"; + String content = "Hello from Java"; + String username = "admin"; + String password = "admin"; + int qos = 0; + + MqttClient client = new MqttClient(brokerUrl, clientId); MqttConnectionOptions options = new MqttConnectionOptions(); options.setServerURIs(new String[]{brokerUrl}); - options.setAutomaticReconnect(true); // 启用自动重连 + options.setAutomaticReconnect(true); options.setUserName(username); options.setPassword(password.getBytes()); + options.setConnectionTimeout(10); + options.setKeepAliveInterval(20); + System.out.println("Connecting to broker..."); client.connect(options); - client.subscribe("/agv_robot/status", 0); + System.out.println("Connected"); + + System.out.println("Publishing message..."); + long start = System.currentTimeMillis(); + client.publish(topic, content.getBytes(), qos, false); + System.out.println("Published in " + (System.currentTimeMillis() - start) + " ms"); + + client.disconnect(); + System.out.println("Disconnected"); } @Override @@ -81,10 +122,13 @@ public class PtrMqttClient implements MqttCallback { @SneakyThrows public void stop() { - if (client.isConnected()) { + if (client != null && client.isConnected()) { client.disconnect(); + client.close(); + log.info("MQTT client disconnected and closed."); + } else { + log.warn("MQTT client is not connected, no action taken."); } - client.close(); - log.info("MQTT client stopped"); } + } diff --git a/servo/src/main/java/com/yvan/logisticsEnv/EnvPayload.java b/servo/src/main/java/com/yvan/logisticsEnv/EnvPayload.java index c5b8fea..2692634 100644 --- a/servo/src/main/java/com/yvan/logisticsEnv/EnvPayload.java +++ b/servo/src/main/java/com/yvan/logisticsEnv/EnvPayload.java @@ -12,7 +12,6 @@ public class EnvPayload implements Serializable { @Data public static class MqttConfig { private String brokerUrl; - private String clientId; private String username; private String password; } diff --git a/servo/src/main/java/com/yvan/logisticsEnv/EnvStartParam.java b/servo/src/main/java/com/yvan/logisticsEnv/EnvStartParam.java index f984317..b9ed166 100644 --- a/servo/src/main/java/com/yvan/logisticsEnv/EnvStartParam.java +++ b/servo/src/main/java/com/yvan/logisticsEnv/EnvStartParam.java @@ -10,6 +10,8 @@ import lombok.Setter; @Setter public class EnvStartParam { + public String clientId; + /** * 是否虚拟仿真环境 */ diff --git a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java index 7fdbee6..6694ba4 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java +++ b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java @@ -176,7 +176,7 @@ public class LogisticsRuntime { this.logisticsEnv.start(param); // 启动 MQTT 监听 - this.amrMessageHandler.start(param.getEnvPayload().getMqtt()); + this.amrMessageHandler.start(param.getEnvPayload().getMqtt(), param.clientId); // 开启所有机器人的任务处理 Set executorTypes = Sets.newHashSet(); From 80ab9daff29e99b861c4d3389444d847aba3d69a Mon Sep 17 00:00:00 2001 From: luoyifan Date: Fri, 27 Jun 2025 10:46:24 +0800 Subject: [PATCH 02/16] =?UTF-8?q?Client=20ID=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/galaxis/rcs/ptr/PtrMqttClient.java | 33 ++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java index ed49e01..084def4 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java @@ -1,35 +1,35 @@ package com.galaxis.rcs.ptr; -import com.google.common.base.Splitter; import com.yvan.logisticsEnv.EnvPayload; -import com.yvan.logisticsModel.LogisticsRuntime; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.clever.core.BannerUtils; -import org.clever.core.json.JsonWrapper; import org.eclipse.paho.mqttv5.client.*; import org.eclipse.paho.mqttv5.common.MqttException; import org.eclipse.paho.mqttv5.common.MqttMessage; import org.eclipse.paho.mqttv5.common.packet.MqttProperties; +import java.net.InetAddress; import java.nio.charset.StandardCharsets; +import java.util.concurrent.CountDownLatch; @Slf4j public class PtrMqttClient implements MqttCallback { public final AmrMessageHandler amrMessageHandler; public final EnvPayload.MqttConfig mqttConfig; private final MqttClient client; + private CountDownLatch connectLatch = new CountDownLatch(1); @SneakyThrows public PtrMqttClient(AmrMessageHandler handler, EnvPayload.MqttConfig mqttConfig, String clientId) { this.amrMessageHandler = handler; this.mqttConfig = mqttConfig; - String brokerUrl = mqttConfig.getBrokerUrl(); - String username = mqttConfig.getUsername(); - String password = mqttConfig.getPassword(); + String brokerUrl = mqttConfig.getBrokerUrl(); // "tcp://10.10.203.239:1885" + String username = mqttConfig.getUsername(); // admin + String password = mqttConfig.getPassword(); // admin - client = new MqttClient(brokerUrl, clientId); + client = new MqttClient(brokerUrl, clientId); // String clientId = "LUOYIFAN-PC" MqttConnectionOptions options = new MqttConnectionOptions(); options.setServerURIs(new String[]{brokerUrl}); options.setAutomaticReconnect(true); @@ -40,20 +40,29 @@ public class PtrMqttClient implements MqttCallback { client.setCallback(this); + BannerUtils.printConfig(log, "MQTT 开启监听", new String[]{ + "brokerUrl: " + brokerUrl, + "userName: " + username, + "clientId: " + clientId, + "topic: /agv_robot/status"}); + client.connect(options); + connectLatch.await(); client.subscribe("/agv_robot/status", 0); } @SneakyThrows public void publish(String topic, String payload) { + // 这个一发送就阻塞 this.client.publish(topic, payload.getBytes(StandardCharsets.UTF_8), 0, false); } @SneakyThrows public static void main(String[] args) { + // 这个测试是好的 String brokerUrl = "tcp://10.10.203.239:1885"; - String clientId = "yvan-rcs-dev"; - String topic = "test/topic"; + String clientId = InetAddress.getLocalHost().getHostName(); // LUOYIFAN-PC + String topic = "/agv_robot/status"; String content = "Hello from Java"; String username = "admin"; String password = "admin"; @@ -74,7 +83,7 @@ public class PtrMqttClient implements MqttCallback { System.out.println("Publishing message..."); long start = System.currentTimeMillis(); - client.publish(topic, content.getBytes(), qos, false); + client.publish(topic, content.getBytes(), qos, false); // 这个发送是好的 System.out.println("Published in " + (System.currentTimeMillis() - start) + " ms"); client.disconnect(); @@ -113,7 +122,9 @@ public class PtrMqttClient implements MqttCallback { @Override public void connectComplete(boolean reconnect, String serverURI) { - BannerUtils.printConfig(log, "MQTT 开启监听", new String[]{serverURI + " topic: /agv_robot/status"}); + // BannerUtils.printConfig(log, "MQTT 开启监听", new String[]{serverURI + " topic: /agv_robot/status"}); + log.info("MQTT client connected to server: {}", serverURI); + connectLatch.countDown(); // 放行 } @Override From dd4e27d0d0e2db1ca316d021b8b475c9bb6a1db3 Mon Sep 17 00:00:00 2001 From: luoyifan Date: Fri, 27 Jun 2025 11:34:34 +0800 Subject: [PATCH 03/16] =?UTF-8?q?clientForSend=20=E5=92=8C=20subscribe=20?= =?UTF-8?q?=E6=98=AF=E4=B8=A4=E5=A5=97=20MQTT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/galaxis/rcs/ptr/AmrMessageHandler.java | 5 +- .../java/com/galaxis/rcs/ptr/PtrMqttClient.java | 76 +++++++++++----------- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java index 8d3842b..2777562 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java @@ -19,6 +19,7 @@ import org.clever.core.BannerUtils; import org.clever.core.json.JsonWrapper; import org.clever.core.mapper.BeanCopyUtils; import org.clever.data.redis.Redis; +import org.clever.data.redis.RedisAdmin; import org.eclipse.paho.mqttv5.client.MqttClient; import org.eclipse.paho.mqttv5.common.MqttException; import org.eclipse.paho.mqttv5.common.MqttMessage; @@ -65,7 +66,7 @@ public class AmrMessageHandler { private static final TypeReference> typeRef20250Message = new TypeReference>() { }; - private static final Redis redis = AppContextHolder.getBean("defaultRedis", Redis.class, true); + private static final Redis redis = RedisAdmin.getRedis(); public final LogisticsRuntime runtime; private volatile PtrMqttClient ptrMqttClient; @@ -162,7 +163,7 @@ public class AmrMessageHandler { break; case AMR_HEARTBEAT: AmrMessage heartbeatMessage = JacksonUtils.parse(json, typeRef20100Message); - sendCmdHeartBeat(heartbeatMessage.content.VehicleId + ""); + // sendCmdHeartBeat(heartbeatMessage.content.VehicleId + ""); handleHeartbeatMessage(agvItem, heartbeatMessage.content); break; case AMR_BOOT: diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java index 084def4..bf43cb4 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/PtrMqttClient.java @@ -17,77 +17,74 @@ import java.util.concurrent.CountDownLatch; public class PtrMqttClient implements MqttCallback { public final AmrMessageHandler amrMessageHandler; public final EnvPayload.MqttConfig mqttConfig; + private final MqttClient clientForSend; private final MqttClient client; + private final String clientId; private CountDownLatch connectLatch = new CountDownLatch(1); + @SneakyThrows public PtrMqttClient(AmrMessageHandler handler, EnvPayload.MqttConfig mqttConfig, String clientId) { this.amrMessageHandler = handler; this.mqttConfig = mqttConfig; + this.clientId = clientId; String brokerUrl = mqttConfig.getBrokerUrl(); // "tcp://10.10.203.239:1885" String username = mqttConfig.getUsername(); // admin String password = mqttConfig.getPassword(); // admin + clientForSend = new MqttClient(brokerUrl, clientId + "_send"); // String clientId = "LUOYIFAN-PC_send" client = new MqttClient(brokerUrl, clientId); // String clientId = "LUOYIFAN-PC" MqttConnectionOptions options = new MqttConnectionOptions(); options.setServerURIs(new String[]{brokerUrl}); options.setAutomaticReconnect(true); options.setUserName(username); options.setPassword(password.getBytes()); - options.setConnectionTimeout(10); + options.setConnectionTimeout(1); options.setKeepAliveInterval(20); + options.setExecutorServiceTimeout(1); client.setCallback(this); + client.connect(options); - BannerUtils.printConfig(log, "MQTT 开启监听", new String[]{ + clientForSend.connect(options); + connectLatch.await(); + + BannerUtils.printConfig(log, "MQTT 开启监听成功", new String[]{ "brokerUrl: " + brokerUrl, "userName: " + username, "clientId: " + clientId, "topic: /agv_robot/status"}); - client.connect(options); - connectLatch.await(); client.subscribe("/agv_robot/status", 0); } @SneakyThrows - public void publish(String topic, String payload) { - // 这个一发送就阻塞 - this.client.publish(topic, payload.getBytes(StandardCharsets.UTF_8), 0, false); + public void publish(String topic, String payloadString) { + MqttMessage message = new MqttMessage(payloadString.getBytes(StandardCharsets.UTF_8)); + message.setQos(0); + message.setRetained(false); + + if (this.clientForSend.isConnected()) { + this.clientForSend.publish(topic, message); + } else { + throw new RuntimeException("MQTT client is not connected, cannot publish message."); + } + log.info("Message published to topic {}: finish", topic); } @SneakyThrows public static void main(String[] args) { - // 这个测试是好的 - String brokerUrl = "tcp://10.10.203.239:1885"; - String clientId = InetAddress.getLocalHost().getHostName(); // LUOYIFAN-PC - String topic = "/agv_robot/status"; - String content = "Hello from Java"; - String username = "admin"; - String password = "admin"; - int qos = 0; - - MqttClient client = new MqttClient(brokerUrl, clientId); - MqttConnectionOptions options = new MqttConnectionOptions(); - options.setServerURIs(new String[]{brokerUrl}); - options.setAutomaticReconnect(true); - options.setUserName(username); - options.setPassword(password.getBytes()); - options.setConnectionTimeout(10); - options.setKeepAliveInterval(20); - - System.out.println("Connecting to broker..."); - client.connect(options); - System.out.println("Connected"); - - System.out.println("Publishing message..."); - long start = System.currentTimeMillis(); - client.publish(topic, content.getBytes(), qos, false); // 这个发送是好的 - System.out.println("Published in " + (System.currentTimeMillis() - start) + " ms"); - - client.disconnect(); - System.out.println("Disconnected"); + var config = new EnvPayload.MqttConfig(); + config.setBrokerUrl("tcp://10.10.203.239:1885"); + config.setUsername("admin"); + config.setPassword("admin"); + + PtrMqttClient mqttClient = new PtrMqttClient(null, config, "LUOYIFAN-PC"); + for (int i = 0; i < 100; i++) { + mqttClient.publish("/agv_robot/status", "Hello from Java " + i); + } + log.info("Message published successfully."); } @Override @@ -105,7 +102,11 @@ public class PtrMqttClient implements MqttCallback { switch (topic) { case "/agv_robot/status": try { - amrMessageHandler.handleAgvRobotStatusMessage(message); + if (this.amrMessageHandler == null) { + log.info("amrMessageHandler is null, skipping message handling {}", new String(message.getPayload(), StandardCharsets.UTF_8)); + return; + } + this.amrMessageHandler.handleAgvRobotStatusMessage(message); } catch (Exception e) { log.error("amrMessageHandler.handleAgvRobotStatusMessage 异常", e); @@ -118,6 +119,7 @@ public class PtrMqttClient implements MqttCallback { @Override public void deliveryComplete(IMqttToken token) { + log.info("Message delivery complete: {}", token); } @Override From 88f60b97bd68d67201cbeb56a70295951d3c5d6b Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 14:53:59 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/galaxis/rcs/plan/PlanTaskSequence.java | 43 +++++++++++++++- .../java/com/yvan/logisticsModel/PtrAgvItem.java | 57 ++++++++++++---------- 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index 5b8beb3..c637c70 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -5,8 +5,14 @@ import com.galaxis.rcs.common.entity.RcsTaskBiz; import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.galaxis.rcs.common.enums.PlanTaskStatus; import com.galaxis.rcs.common.enums.PlanTaskType; +import com.galaxis.rcs.ptr.ArmMessageType; +import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.yvan.logisticsModel.LogisticsRuntime; +import com.yvan.logisticsModel.PtrAgvDeviceTask; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.clever.core.BannerUtils; import org.clever.core.id.SnowFlake; import org.clever.core.json.JsonWrapper; @@ -15,6 +21,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +@Slf4j public class PlanTaskSequence { @JsonIgnore public static final SnowFlake snowFlake = new SnowFlake(); @@ -27,7 +34,6 @@ public class PlanTaskSequence { public String lastWayPointId; public Float lastRotationAngle = null; - public boolean isFinished = false; public String lastLoadLpn = ""; public PlanTaskSequence(String executorId, LogisticsRuntime logisticsRuntime, RcsTaskBiz bizTask, String createBy) { @@ -103,7 +109,6 @@ public class PlanTaskSequence { // 添加完成动作 public RcsTaskPlan addFinish() { RcsTaskPlan task = this.createTaskPlanEntity(PlanTaskType.FINISH.toString()); - this.isFinished = true; return task; } @@ -145,4 +150,38 @@ public class PlanTaskSequence { jw.set("items", list); return jw.getInnerMap(); } + + /** + * 是不是所有的任务都完成了 + */ + public boolean isAllCompleted() { + boolean isAllComplete = true; + for (RcsTaskPlan task : taskList) { + if (!PlanTaskStatus.FINISHED.toString().equals(task.getPlanTaskStatus())) { + isAllComplete = false; + break; + } + } + return isAllComplete; + } + + public RcsTaskPlan getByPlanTaskId(Long planTaskId) { + for (RcsTaskPlan task : taskList) { + if (task.getPlanTaskId().equals(planTaskId)) { + return task; + } + } + return null; + } + + @SneakyThrows + public void savePlanTask(RcsTaskPlan planTask) { + //TODO: 保存数据库 + var jw = new JsonWrapper(planTask); + var list = Splitter.on("\n").splitToList(jw.toString()); + String[] ar = new String[list.size()]; + list.toArray(ar); + // log.info("3-Received message: " + json); + BannerUtils.printConfig(log, "保存业务任务 planTask", ar); + } } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 149c42f..76b8d84 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.galaxis.rcs.common.enums.AgvEventType; import com.galaxis.rcs.common.enums.LCCDirection; +import com.galaxis.rcs.common.enums.PlanTaskStatus; import com.galaxis.rcs.common.enums.PlanTaskType; import com.galaxis.rcs.connector.cl2.Cl2DeviceConnector; import com.galaxis.rcs.plan.PlanTaskSequence; @@ -17,6 +18,7 @@ import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; import com.google.common.collect.Queues; +import com.yvan.logisticsMonitor.task.PlanTask; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.clever.core.json.JsonWrapper; @@ -221,7 +223,19 @@ public abstract class PtrAgvItem extends ExecutorItem { public boolean isFree() { // return (this.logisticsRuntime.isRunning() && this.deviceTaskQueue.isEmpty() && this.connectorThread.isRunning()); - return this.runtime.isRunning() && planTaskSequence == null && deviceTaskQueue.isEmpty() && !isPaused; + if (!this.runtime.isRunning()) { + return false; + } + if (planTaskSequence != null && !planTaskSequence.isAllCompleted()) { + return false; + } + if (!deviceTaskQueue.isEmpty()) { + return false; + } + if (this.isPaused) { + return false; + } + return true; } public void updatePosition(int logicX, int logicY, short direction) { @@ -268,9 +282,26 @@ public abstract class PtrAgvItem extends ExecutorItem { if (task.seqNo == seqNo) { task.taskGroupStatus = messageStatus; if (task.x == x && task.y == y) { + // 标记任务已完成, 4=完成 task.taskStatus = 4; } + + if (messageStatus == 4) { + fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); + RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); + planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); + planTaskSequence.savePlanTask(planTask); + if (planTaskSequence.isAllCompleted()) { + fireEvent(AgvEventType.PLAN_COMPLETE, this); + planTaskSequence = null; + } + + } else { + log.error("messageStatus unkown messageStatus={}", messageStatus); + } + } + // TODO: 3是什么? if (task.taskGroupStatus < 3 /*|| task.taskStatus < 4*/) { needCompute = false; } @@ -278,32 +309,8 @@ public abstract class PtrAgvItem extends ExecutorItem { if (needCompute) { LockSupport.unpark(connectorThread); } - - // 如果是任务完成事件 - if (messageStatus == 4) { - fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, this.connectorThread.__currentTask); - - if (isTaskSequenceComplete()) { - fireEvent(AgvEventType.PLAN_COMPLETE, this); - planTaskSequence = null; - } - } } - /** - * 检查当前任务序列是否完成 - */ - public boolean isTaskSequenceComplete() { - if (planTaskSequence == null) { - return false; - } - for (PtrAgvDeviceTask task : runningDeviceTaskList) { - if (task.taskGroupStatus < 3 /*|| task.taskStatus < 4*/) { - return false; - } - } - return true; - } public void updateRedisStatus() { String statusKey = getRedisKey("status"); From cdb9d471ad03d089f0209a07d6807bd618975c86 Mon Sep 17 00:00:00 2001 From: luoyifan Date: Fri, 27 Jun 2025 15:55:54 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E4=BB=8E=20updatePosition=20=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E4=BB=BB=E5=8A=A1=E5=AE=8C=E6=88=90=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/galaxis/rcs/ptr/AmrMessageHandler.java | 1 + .../com/yvan/logisticsModel/PtrAgvDeviceTask.java | 2 + .../java/com/yvan/logisticsModel/PtrAgvItem.java | 87 ++++++++++++++-------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java index 2777562..19ba758 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java @@ -426,6 +426,7 @@ public class AmrMessageHandler { // 这是源逻辑,CurLogicX / CurLogicY / CurDirection 需要到 PtrAgvItem 中更新, 因为要触发事件 agvItem.x = message.X; agvItem.y = message.Y; + agvItem.orientation = message.CurOrientation; agvItem.updatePosition(message.CurLogicX, message.CurLogicY, message.CurDirection); } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvDeviceTask.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvDeviceTask.java index 0eb806f..79a93ac 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvDeviceTask.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvDeviceTask.java @@ -38,4 +38,6 @@ public class PtrAgvDeviceTask { // 是否最后任务 public boolean isLastTask = false; + public int checkLogicX; + public int checkLogicY; } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 76b8d84..883e3af 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -261,6 +261,47 @@ public abstract class PtrAgvItem extends ExecutorItem { fireEvent(AgvEventType.DIRECTION_CHANGED, this, oldDirection, direction); } + + // 从 runningDeviceTaskList 里面,找到完成到什么阶段 + // 比如 (1,2) -> (2,2) -> (3,2) , 如果 updatePosition=3,2 ,那么前2个任务都要完成 + int finishTargetIndex = -1; + for (int i = 0; i < runningDeviceTaskList.size(); i++) { + PtrAgvDeviceTask task = runningDeviceTaskList.get(i); + if (task.checkLogicX == logicX && task.checkLogicY == logicY) { + finishTargetIndex = i; + break; + } + } + + boolean needCompute = false; + + if (finishTargetIndex > 0) { + needCompute = true; + // 标记前面的任务都完成了 + for (int i = 0; i < finishTargetIndex; i++) { + PtrAgvDeviceTask task = runningDeviceTaskList.get(i); + + task.taskStatus = 4; // 标记为完成 + task.taskGroupStatus = 4; // 标记为任务组完成 + fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); + + // 更新计划任务 + RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); + if (planTask != null) { + planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); + planTaskSequence.savePlanTask(planTask); + } + } + + if (planTaskSequence.isAllCompleted()) { + fireEvent(AgvEventType.PLAN_COMPLETE, this); + planTaskSequence = null; + } + } + + if (needCompute) { + LockSupport.unpark(connectorThread); + } } /** @@ -277,38 +318,7 @@ public abstract class PtrAgvItem extends ExecutorItem { return; } - boolean needCompute = true; - for (PtrAgvDeviceTask task : runningDeviceTaskList) { - if (task.seqNo == seqNo) { - task.taskGroupStatus = messageStatus; - if (task.x == x && task.y == y) { - // 标记任务已完成, 4=完成 - task.taskStatus = 4; - } - - if (messageStatus == 4) { - fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); - RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); - planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); - planTaskSequence.savePlanTask(planTask); - if (planTaskSequence.isAllCompleted()) { - fireEvent(AgvEventType.PLAN_COMPLETE, this); - planTaskSequence = null; - } - - } else { - log.error("messageStatus unkown messageStatus={}", messageStatus); - } - - } - // TODO: 3是什么? - if (task.taskGroupStatus < 3 /*|| task.taskStatus < 4*/) { - needCompute = false; - } - } - if (needCompute) { - LockSupport.unpark(connectorThread); - } + // 任务完成逻辑,在地标检查里 } @@ -458,6 +468,9 @@ public abstract class PtrAgvItem extends ExecutorItem { deviceTask.endPoint = pointItem; deviceTask.bizTaskId = plan.getBizTaskId(); deviceTask.planTaskId = plan.getPlanTaskId(); + // 行走任务完成后,检查用的字段 + deviceTask.checkLogicX = pointItem.logicX; + deviceTask.checkLogicY = pointItem.logicY; deviceTaskList.add(deviceTask); // 设置新的起点 startPoint = pointItem; @@ -633,6 +646,16 @@ public abstract class PtrAgvItem extends ExecutorItem { }; } + public short getAmrDirection(LCCDirection lccDirection) { + return switch (lccDirection) { + case RIGHT -> 0; + case DOWN -> 1; + case LEFT -> 2; + case UP -> 3; + default -> -1; // 未知方向 + }; + } + private String getRedisKey(String type) { return String.format("lcc:%s:%s:rcs:%s_%s", runtime.projectUUID, runtime.envId, type, this.getId()); From c2cc08cf5ff526c156334f70badbda7ef6ca42b1 Mon Sep 17 00:00:00 2001 From: yuliang <398780299@qq.com> Date: Fri, 27 Jun 2025 16:05:58 +0800 Subject: [PATCH 06/16] =?UTF-8?q?cl2=20=E5=9F=BA=E4=BA=8E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=8A=B6=E6=80=81=E5=92=8C=E4=BB=BB=E5=8A=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=86=E6=AD=A5=E7=94=9F=E6=88=90=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/galaxis/rcs/ptr/AmrTaskMode.java | 78 ++++++++++++++++++++++ .../java/com/yvan/logisticsModel/PtrAgvItem.java | 8 +-- 2 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java new file mode 100644 index 0000000..a740f5c --- /dev/null +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java @@ -0,0 +1,78 @@ +package com.galaxis.rcs.ptr; + +import com.google.common.collect.Maps; + +import java.util.Collections; +import java.util.Map; + +/** + * AMR 任务模式 + */ +public enum AmrTaskMode { + /** + * 空闲模式 + */ + AMR_FREE_MODE(0, "空闲模式"), + /** + * 初始化模式 + */ + AMR_INIT_MODE(1, "初始化模式"), + /** + * 任务模式 + */ + AMR_TASK_MODE(2, "任务模式"), + /** + * 单动作模式 + */ + AMR_SINGLE_ACTION_MODE(3, "单动作模式"), + /** + * 手动模式 + */ + AMR_MANUAL_MODE(4, "手动模式"), + /** + * 遥控器模式 + */ + AMR_HANDSET_MODE(5, "遥控器模式"), + /** + * 充电模式 + */ + AMR_CHARGE_MODE(6, "充电模式"), + /** + * 任务被中断模式 + */ + AMR_TASK_INTERRUPT_MODE (7, "任务被中断模式"), + /** + * 自定义模式 + */ + AMR_CUSTOMIZE_MODE(8, "自定义模式"); + + // 枚举值映射 + private static final Map VALUE_MAP; + + static { + Map map = Maps.newHashMap(); + for (AmrTaskMode message : values()) { + map.put(message.value, message); + } + VALUE_MAP = Collections.unmodifiableMap(map); + } + + public final int value; + public final String description; + + AmrTaskMode(int value, String description) { + this.value = value; + this.description = description; + } + + /** + * 从整数值获取对应的枚举 + * + * @param value 整数值 + * @return 对应的枚举,如果找不到则返回 null + */ + public static AmrTaskMode fromValue(int value) { + return VALUE_MAP.get(value); + } + +} diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 883e3af..82d9fa0 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -8,10 +8,7 @@ import com.galaxis.rcs.common.enums.PlanTaskStatus; import com.galaxis.rcs.common.enums.PlanTaskType; import com.galaxis.rcs.connector.cl2.Cl2DeviceConnector; import com.galaxis.rcs.plan.PlanTaskSequence; -import com.galaxis.rcs.ptr.AgvEventListener; -import com.galaxis.rcs.ptr.AmrMessageHandler; -import com.galaxis.rcs.ptr.ControlMode; -import com.galaxis.rcs.ptr.PosDirection; +import com.galaxis.rcs.ptr.*; import com.galaxis.rcs.ptr.receiveEntity.AmrHeartbeatMessage; import com.galaxis.rcs.ptr.receiveEntity.base.CurBatteryData; import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; @@ -65,6 +62,9 @@ public abstract class PtrAgvItem extends ExecutorItem { // agv当前转动角度值 public double orientation; + // 任务模式 + public AmrTaskMode taskMode; + private volatile boolean isManualMode = false; private volatile boolean isPaused = false; private volatile PosDirection lastPausedPosition; From 265b10136d8986955828f67cb194b6c04ca01167 Mon Sep 17 00:00:00 2001 From: luoyifan Date: Fri, 27 Jun 2025 16:08:04 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/galaxis/rcs/connector/cl2/Cl2DeviceConnector.java | 9 ++++----- servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java | 5 +---- servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 3 +++ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2DeviceConnector.java b/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2DeviceConnector.java index 789b6ff..6a29965 100644 --- a/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2DeviceConnector.java +++ b/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2DeviceConnector.java @@ -27,11 +27,10 @@ public class Cl2DeviceConnector { } public void sendTask(String vehicleId, RcsTaskMessage rcsTaskMessage) throws MqttException, JsonProcessingException { - var list = Splitter.on("\n").splitToList(JsonWrapper.toJsonPretty(rcsTaskMessage)); - String[] ar = new String[list.size()]; - list.toArray(ar); - BannerUtils.printConfig(log, "CL2 发送报文", ar); - + // var list = Splitter.on("\n").splitToList(JsonWrapper.toJsonPretty(rcsTaskMessage)); + // String[] ar = new String[list.size()]; + // list.toArray(ar); + // BannerUtils.printConfig(log, "CL2 发送报文", ar); amrMessageHandler.sendCmdTask(vehicleId, rcsTaskMessage); } diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java index 19ba758..ac9f9e2 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java @@ -14,18 +14,15 @@ import com.yvan.logisticsModel.LogisticsRuntime; import com.yvan.logisticsModel.PtrAgvItem; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.clever.core.AppContextHolder; import org.clever.core.BannerUtils; import org.clever.core.json.JsonWrapper; import org.clever.core.mapper.BeanCopyUtils; import org.clever.data.redis.Redis; import org.clever.data.redis.RedisAdmin; -import org.eclipse.paho.mqttv5.client.MqttClient; import org.eclipse.paho.mqttv5.common.MqttException; import org.eclipse.paho.mqttv5.common.MqttMessage; import java.nio.charset.StandardCharsets; -import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.Executors; @@ -230,7 +227,7 @@ public class AmrMessageHandler { baseMessage.content = rcsTaskMessage; String json = JacksonUtils.toJson(baseMessage); - log.info("sendCmd10010: {}", json); + // log.info("sendCmd10010: {}", json); // log.debug("Sending task to {}: {}", vehicleId, json); publish("/wcs_server/" + vehicleId, json, baseMessage.id); diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 883e3af..4bfed89 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -321,6 +321,9 @@ public abstract class PtrAgvItem extends ExecutorItem { // 任务完成逻辑,在地标检查里 } + public void updateTaskMode(int taskMode) { + + } public void updateRedisStatus() { String statusKey = getRedisKey("status"); From 735faee1151a2784088261c3316a95d3386a1c43 Mon Sep 17 00:00:00 2001 From: yuliang <398780299@qq.com> Date: Fri, 27 Jun 2025 16:10:59 +0800 Subject: [PATCH 08/16] =?UTF-8?q?cl2=20=E5=9F=BA=E4=BA=8E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=8A=B6=E6=80=81=E5=92=8C=E4=BB=BB=E5=8A=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=86=E6=AD=A5=E7=94=9F=E6=88=90=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java | 1 + servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java index ac9f9e2..7d1611a 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrMessageHandler.java @@ -478,6 +478,7 @@ public class AmrMessageHandler { AmrMessage> taskModeChange = JacksonUtils.parse(json, typeRef20011_1Message); AmrTaskStatusMessage modeMessage = taskModeChange.content; agvItem.updateDeviceTaskStatus((int) modeMessage.SeqNo, 0, 0, modeMessage.EventId); + agvItem.updateTaskMode(modeMessage.Info.TaskMode); break; case 4: AmrMessage> taskCompleted = JacksonUtils.parse(json, typeRef20011_4Message); diff --git a/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java b/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java index a740f5c..8ade272 100644 --- a/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java +++ b/servo/src/main/java/com/galaxis/rcs/ptr/AmrTaskMode.java @@ -44,7 +44,11 @@ public enum AmrTaskMode { /** * 自定义模式 */ - AMR_CUSTOMIZE_MODE(8, "自定义模式"); + AMR_CUSTOMIZE_MODE(8, "自定义模式"), + /** + * 主程序退出(关机或关服务)时会进入这个模式 + */ + AMR_SHUTDOWN_MODE(8, "主程序退出"); // 枚举值映射 private static final Map VALUE_MAP; From 03f30916338cbf98c146621367e11aa5a57f9fd5 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:22:50 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/galaxis/rcs/plan/PlanTaskSequence.java | 14 +++++++++----- .../src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index c637c70..9888c7c 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -5,11 +5,9 @@ import com.galaxis.rcs.common.entity.RcsTaskBiz; import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.galaxis.rcs.common.enums.PlanTaskStatus; import com.galaxis.rcs.common.enums.PlanTaskType; -import com.galaxis.rcs.ptr.ArmMessageType; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.yvan.logisticsModel.LogisticsRuntime; -import com.yvan.logisticsModel.PtrAgvDeviceTask; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.clever.core.BannerUtils; @@ -157,9 +155,11 @@ public class PlanTaskSequence { public boolean isAllCompleted() { boolean isAllComplete = true; for (RcsTaskPlan task : taskList) { - if (!PlanTaskStatus.FINISHED.toString().equals(task.getPlanTaskStatus())) { - isAllComplete = false; - break; + if (PlanTaskType.valueOf(task.getPlanType()) != PlanTaskType.FINISH) { + if (!PlanTaskStatus.FINISHED.toString().equals(task.getPlanTaskStatus())) { + isAllComplete = false; + break; + } } } return isAllComplete; @@ -178,9 +178,13 @@ public class PlanTaskSequence { public void savePlanTask(RcsTaskPlan planTask) { //TODO: 保存数据库 var jw = new JsonWrapper(planTask); + jw.set("isAllCompleted", this.isAllCompleted()); + var list = Splitter.on("\n").splitToList(jw.toString()); String[] ar = new String[list.size()]; list.toArray(ar); + + // log.info("3-Received message: " + json); BannerUtils.printConfig(log, "保存业务任务 planTask", ar); } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index dcd4f28..2326091 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -15,7 +15,6 @@ import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; import com.google.common.collect.Queues; -import com.yvan.logisticsMonitor.task.PlanTask; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.clever.core.json.JsonWrapper; From 76618d9607c2ef1d411ff035176db9f8f83db481 Mon Sep 17 00:00:00 2001 From: yuliang <398780299@qq.com> Date: Fri, 27 Jun 2025 16:31:45 +0800 Subject: [PATCH 10/16] =?UTF-8?q?cl2=20=E5=9F=BA=E4=BA=8E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=8A=B6=E6=80=81=E5=92=8C=E4=BB=BB=E5=8A=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=88=86=E6=AD=A5=E7=94=9F=E6=88=90=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 2326091..310fc3c 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -274,10 +274,10 @@ public abstract class PtrAgvItem extends ExecutorItem { boolean needCompute = false; - if (finishTargetIndex > 0) { + if (finishTargetIndex >= 0) { needCompute = true; // 标记前面的任务都完成了 - for (int i = 0; i < finishTargetIndex; i++) { + for (int i = 0; i <= finishTargetIndex; i++) { PtrAgvDeviceTask task = runningDeviceTaskList.get(i); task.taskStatus = 4; // 标记为完成 From a6b4ba0730abc46e7079bdca780ee8f748c96eea Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:34:42 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/galaxis/rcs/plan/PlanTaskSequence.java | 4 ++ .../java/com/yvan/logisticsModel/PtrAgvItem.java | 58 +++++++++++----------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index 9888c7c..9a80d9c 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -188,4 +188,8 @@ public class PlanTaskSequence { // log.info("3-Received message: " + json); BannerUtils.printConfig(log, "保存业务任务 planTask", ar); } + + public boolean isEmpty() { + return this.taskList.isEmpty(); + } } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 2326091..7049a31 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -261,40 +261,42 @@ public abstract class PtrAgvItem extends ExecutorItem { oldDirection, direction); } + boolean needCompute = false; // 从 runningDeviceTaskList 里面,找到完成到什么阶段 // 比如 (1,2) -> (2,2) -> (3,2) , 如果 updatePosition=3,2 ,那么前2个任务都要完成 - int finishTargetIndex = -1; - for (int i = 0; i < runningDeviceTaskList.size(); i++) { - PtrAgvDeviceTask task = runningDeviceTaskList.get(i); - if (task.checkLogicX == logicX && task.checkLogicY == logicY) { - finishTargetIndex = i; - break; - } - } - - boolean needCompute = false; - - if (finishTargetIndex > 0) { - needCompute = true; - // 标记前面的任务都完成了 - for (int i = 0; i < finishTargetIndex; i++) { + if (this.runningDeviceTaskList != null && !this.runningDeviceTaskList.isEmpty() && + this.planTaskSequence != null && !this.planTaskSequence.isEmpty()) { + int finishTargetIndex = -1; + for (int i = 0; i < runningDeviceTaskList.size(); i++) { PtrAgvDeviceTask task = runningDeviceTaskList.get(i); - - task.taskStatus = 4; // 标记为完成 - task.taskGroupStatus = 4; // 标记为任务组完成 - fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); - - // 更新计划任务 - RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); - if (planTask != null) { - planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); - planTaskSequence.savePlanTask(planTask); + if (task.checkLogicX == logicX && task.checkLogicY == logicY) { + finishTargetIndex = i; + break; } } - if (planTaskSequence.isAllCompleted()) { - fireEvent(AgvEventType.PLAN_COMPLETE, this); - planTaskSequence = null; + if (finishTargetIndex > 0) { + needCompute = true; + // 标记前面的任务都完成了 + for (int i = 0; i < finishTargetIndex; i++) { + PtrAgvDeviceTask task = runningDeviceTaskList.get(i); + + task.taskStatus = 4; // 标记为完成 + task.taskGroupStatus = 4; // 标记为任务组完成 + fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); + + // 更新计划任务 + RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); + if (planTask != null) { + planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); + planTaskSequence.savePlanTask(planTask); + } + } + + if (planTaskSequence.isAllCompleted()) { + fireEvent(AgvEventType.PLAN_COMPLETE, this); + planTaskSequence = null; + } } } From 8ae5a82a1aa8fd9f92d2dfe0e32261e5ce67ebe7 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:36:44 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 48c193d..5a291cb 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -262,10 +262,12 @@ public abstract class PtrAgvItem extends ExecutorItem { } boolean needCompute = false; + // 从 runningDeviceTaskList 里面,找到完成到什么阶段 // 比如 (1,2) -> (2,2) -> (3,2) , 如果 updatePosition=3,2 ,那么前2个任务都要完成 if (this.runningDeviceTaskList != null && !this.runningDeviceTaskList.isEmpty() && this.planTaskSequence != null && !this.planTaskSequence.isEmpty()) { + int finishTargetIndex = -1; for (int i = 0; i < runningDeviceTaskList.size(); i++) { PtrAgvDeviceTask task = runningDeviceTaskList.get(i); @@ -275,8 +277,6 @@ public abstract class PtrAgvItem extends ExecutorItem { } } - boolean needCompute = false; - if (finishTargetIndex >= 0) { needCompute = true; // 标记前面的任务都完成了 From 227eb9e6e4f0a96da1c977a8a357ee8813259957 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:48:30 +0800 Subject: [PATCH 13/16] =?UTF-8?q?updatePosition=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/yvan/logisticsModel/PtrAgvItem.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 5a291cb..927871b 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -17,6 +17,7 @@ import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; import com.google.common.collect.Queues; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.clever.core.BannerUtils; import org.clever.core.json.JsonWrapper; import org.clever.data.redis.Redis; import org.clever.data.redis.RedisAdmin; @@ -261,6 +262,12 @@ public abstract class PtrAgvItem extends ExecutorItem { oldDirection, direction); } + BannerUtils.printConfig(log, "updatePosition", new String[]{ + "logicX: " + logicX, + "logicY: " + logicY, + "direction: " + direction + }); + boolean needCompute = false; // 从 runningDeviceTaskList 里面,找到完成到什么阶段 @@ -277,11 +284,11 @@ public abstract class PtrAgvItem extends ExecutorItem { } } - if (finishTargetIndex >= 0) { - needCompute = true; - // 标记前面的任务都完成了 - for (int i = 0; i <= finishTargetIndex; i++) { - PtrAgvDeviceTask task = runningDeviceTaskList.get(i); + if (finishTargetIndex >= 0) { + needCompute = true; + // 标记前面的任务都完成了 + for (int i = 0; i <= finishTargetIndex; i++) { + PtrAgvDeviceTask task = runningDeviceTaskList.get(i); task.taskStatus = 4; // 标记为完成 task.taskGroupStatus = 4; // 标记为任务组完成 From 8e65cf48bea4bf1b64438770ed5c93a105b2e91b Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:53:23 +0800 Subject: [PATCH 14/16] =?UTF-8?q?updatePosition=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java | 4 ++++ servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index 9a80d9c..f1b720c 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -192,4 +192,8 @@ public class PlanTaskSequence { public boolean isEmpty() { return this.taskList.isEmpty(); } + + public int size() { + return this.taskList.size(); + } } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 927871b..1853ee4 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -265,7 +265,9 @@ public abstract class PtrAgvItem extends ExecutorItem { BannerUtils.printConfig(log, "updatePosition", new String[]{ "logicX: " + logicX, "logicY: " + logicY, - "direction: " + direction + "direction: " + direction, + "runningDeviceSize" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), + "planTaskSize" + (this.planTaskSequence == null ? "null" : this.planTaskSequence.size()) }); boolean needCompute = false; From eeb44903f9d3e734057c74c7d04db2ecf8cc80f7 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 16:53:51 +0800 Subject: [PATCH 15/16] =?UTF-8?q?updatePosition=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index 1853ee4..ba66134 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -266,8 +266,8 @@ public abstract class PtrAgvItem extends ExecutorItem { "logicX: " + logicX, "logicY: " + logicY, "direction: " + direction, - "runningDeviceSize" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), - "planTaskSize" + (this.planTaskSequence == null ? "null" : this.planTaskSequence.size()) + "runningDeviceSize:" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), + "planTaskSize:" + (this.planTaskSequence == null ? "null" : this.planTaskSequence.size()) }); boolean needCompute = false; From d024f793acbccea4cb6d951a222a2703d871f848 Mon Sep 17 00:00:00 2001 From: yvan Date: Fri, 27 Jun 2025 17:00:45 +0800 Subject: [PATCH 16/16] =?UTF-8?q?updatePosition=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/galaxis/rcs/plan/PlanTaskSequence.java | 1 + .../java/com/yvan/logisticsModel/PtrAgvItem.java | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index f1b720c..e17c822 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -142,6 +142,7 @@ public class PlanTaskSequence { taskStr = "FINISH"; break; } + taskStr = taskStr + " STATE:" + task.getPlanTaskStatus(); list.add(taskStr); } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java index ba66134..98354aa 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -14,6 +14,7 @@ import com.galaxis.rcs.ptr.receiveEntity.base.CurBatteryData; import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; +import com.google.common.base.Joiner; import com.google.common.collect.Queues; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -262,22 +263,14 @@ public abstract class PtrAgvItem extends ExecutorItem { oldDirection, direction); } - BannerUtils.printConfig(log, "updatePosition", new String[]{ - "logicX: " + logicX, - "logicY: " + logicY, - "direction: " + direction, - "runningDeviceSize:" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), - "planTaskSize:" + (this.planTaskSequence == null ? "null" : this.planTaskSequence.size()) - }); - boolean needCompute = false; // 从 runningDeviceTaskList 里面,找到完成到什么阶段 // 比如 (1,2) -> (2,2) -> (3,2) , 如果 updatePosition=3,2 ,那么前2个任务都要完成 + int finishTargetIndex = -1; if (this.runningDeviceTaskList != null && !this.runningDeviceTaskList.isEmpty() && this.planTaskSequence != null && !this.planTaskSequence.isEmpty()) { - int finishTargetIndex = -1; for (int i = 0; i < runningDeviceTaskList.size(); i++) { PtrAgvDeviceTask task = runningDeviceTaskList.get(i); if (task.checkLogicX == logicX && task.checkLogicY == logicY) { @@ -311,6 +304,17 @@ public abstract class PtrAgvItem extends ExecutorItem { } } + BannerUtils.printConfig(log, "updatePosition", new String[]{ + "logicX: " + logicX, + "logicY: " + logicY, + "direction: " + direction, + "finishTargetIndex: " + finishTargetIndex, + "runningDeviceSize:" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), + "planTask:" + (this.planTaskSequence == null ? "null" : + ("\n" + Joiner.on("\n").join((List) this.planTaskSequence.toPrettyMap().get("items"))) + ) + }); + if (needCompute) { LockSupport.unpark(connectorThread); }