From cc86e0166c21c0a689e78dfe7b64ee91c3c05140 Mon Sep 17 00:00:00 2001 From: yuliang <398780299@qq.com> Date: Mon, 23 Jun 2025 14:53:22 +0800 Subject: [PATCH] =?UTF-8?q?cl2=20=E6=8E=A5=E5=85=A5amr=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amrCommunication/AmrMessageHandler.java | 56 ++++++----- .../amrCommunication/AmrStatusAndInfo.java | 49 --------- .../galaxis/rcs/connector/cl2/Cl2Connector.java | 34 ++++--- .../rcs/connector/cl2/Cl2DeviceConnector.java | 36 +++---- .../rcs/connector/cl2/VirtualCl2Connector.java | 21 ++-- .../logisticsModel/ExecutorConnectorThread.java | 66 ------------- .../java/com/yvan/logisticsModel/ExecutorItem.java | 93 ++--------------- .../com/yvan/logisticsModel/LogisticsRuntime.java | 4 +- .../yvan/logisticsModel/PtrAgvConnectorThread.java | 65 ++++++++++++ .../java/com/yvan/logisticsModel/PtrAgvItem.java | 110 +++++++++++++++++++++ 10 files changed, 259 insertions(+), 275 deletions(-) delete mode 100644 servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrStatusAndInfo.java delete mode 100644 servo/src/main/java/com/yvan/logisticsModel/ExecutorConnectorThread.java create mode 100644 servo/src/main/java/com/yvan/logisticsModel/PtrAgvConnectorThread.java create mode 100644 servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java diff --git a/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrMessageHandler.java b/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrMessageHandler.java index 1252b1c..a38bcc0 100644 --- a/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrMessageHandler.java +++ b/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrMessageHandler.java @@ -10,6 +10,8 @@ import com.galaxis.rcs.connector.cl2.receiveEntity.base.TaskModeChangeData; import com.galaxis.rcs.connector.cl2.receiveEntity.base.TaskStatusChangeData; import com.galaxis.rcs.connector.cl2.receiveEntity.base.TaskTypeChangeData; import com.galaxis.rcs.connector.cl2.sendEntity.AmrTaskMessage; +import com.yvan.logisticsModel.LogisticsRuntimeService; +import com.yvan.logisticsModel.PtrAgvItem; import lombok.extern.slf4j.Slf4j; import org.clever.core.AppContextHolder; import org.clever.core.json.JsonWrapper; @@ -22,6 +24,8 @@ import org.springframework.stereotype.Service; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j @@ -47,17 +51,17 @@ public class AmrMessageHandler { private static final Redis redis = AppContextHolder.getBean("defaultRedis", Redis.class, true); - private static final ConcurrentHashMap agvStatusMap = new ConcurrentHashMap<>(); public static void handleAgvRobotStatusMessage(MqttMessage message) { byte[] messageData = message.getPayload(); String json = new String(messageData, StandardCharsets.UTF_8); JsonWrapper jw = new JsonWrapper(json); int id = jw.asInt("id"); - int agvId = jw.asInt("content", "VehicleId"); - if (!agvStatusMap.containsKey(agvId)) { - agvStatusMap.put(agvId, new AmrStatusAndInfo(agvId + "")); + String agvId = jw.asInt("content", "VehicleId") + ""; + + PtrAgvItem agvItem = getPtrAgvItem(agvId); + if(agvItem == null ){ + return; } - AmrStatusAndInfo agvStatusAndInfo = agvStatusMap.get(agvId); /* * 消息标识 @@ -98,10 +102,10 @@ public class AmrMessageHandler { break; case 4: AmrMessage> taskCompleted = JacksonUtils.parse(json, typeRef20011_4Message); - agvStatusAndInfo.logicX = taskCompleted.content.Info.CurLogicX; - agvStatusAndInfo.logicY = taskCompleted.content.Info.CurLogicY; + agvItem.logicX = taskCompleted.content.Info.CurLogicX; + agvItem.logicY = taskCompleted.content.Info.CurLogicY; // agvStatusAndInfo.orientation = landmarkMessage.content.CurOrientation; - agvStatusAndInfo.direction = taskCompleted.content.Info.CurDirection; + agvItem.direction = taskCompleted.content.Info.CurDirection; log.info("1-Received message: " + json); break; case 8: @@ -116,12 +120,12 @@ public class AmrMessageHandler { break; case 20020: AmrMessage landmarkMessage = JacksonUtils.parse(json, typeRef20020Message); - agvStatusAndInfo.x = landmarkMessage.content.X; - agvStatusAndInfo.y = landmarkMessage.content.Y; - agvStatusAndInfo.logicX = landmarkMessage.content.CurLogicX; - agvStatusAndInfo.logicY = landmarkMessage.content.CurLogicY; + agvItem.x = landmarkMessage.content.X; + agvItem.y = landmarkMessage.content.Y; + agvItem.logicX = landmarkMessage.content.CurLogicX; + agvItem.logicY = landmarkMessage.content.CurLogicY; // agvStatusAndInfo.orientation = landmarkMessage.content.CurOrientation; - agvStatusAndInfo.direction = landmarkMessage.content.CurDirection; + agvItem.direction = landmarkMessage.content.CurDirection; // if (landmarkMessage.content.VehicleId == 32) { log.info("2-Received message: " + json); // } @@ -131,17 +135,17 @@ public class AmrMessageHandler { break; case 20060: AmrMessage statusMessage = JacksonUtils.parse(json, typeRef20060Message); - agvStatusAndInfo.agvSOC = statusMessage.content.CurBattery.SOC; - agvStatusAndInfo.agvBatteryVoltage = statusMessage.content.CurBattery.Voltage; + agvItem.agvSOC = statusMessage.content.CurBattery.SOC; + agvItem.agvBatteryVoltage = statusMessage.content.CurBattery.Voltage; // agvStatusAndInfo.agvChargingStatus = statusMessage.content.CurBattery.ChargingStatus; - agvStatusAndInfo.agvChargingCurrent = statusMessage.content.CurBattery.ChargingCurrent; - agvStatusAndInfo.agvDischargingCurrent = statusMessage.content.CurBattery.DischargingCurrent; - agvStatusAndInfo.agvBatteryTemperature = statusMessage.content.CurBattery.Temperature; - agvStatusAndInfo.x = statusMessage.content.X; - agvStatusAndInfo.y = statusMessage.content.Y; - agvStatusAndInfo.orientation = statusMessage.content.CurOrientation; - agvStatusAndInfo.logicX = statusMessage.content.CurLogicX; - agvStatusAndInfo.logicY = statusMessage.content.CurLogicY; + agvItem.agvChargingCurrent = statusMessage.content.CurBattery.ChargingCurrent; + agvItem.agvDischargingCurrent = statusMessage.content.CurBattery.DischargingCurrent; + agvItem.agvBatteryTemperature = statusMessage.content.CurBattery.Temperature; + agvItem.x = statusMessage.content.X; + agvItem.y = statusMessage.content.Y; + agvItem.orientation = statusMessage.content.CurOrientation; + agvItem.logicX = statusMessage.content.CurLogicX; + agvItem.logicY = statusMessage.content.CurLogicY; // if (statusMessage.content.VehicleId == 32) { // log.info("Received message: " + json); // } @@ -181,8 +185,10 @@ public class AmrMessageHandler { } } - public static AmrStatusAndInfo getAmrStatusAndInfo(int vehicleId) { - return agvStatusMap.get(vehicleId); + public static PtrAgvItem getPtrAgvItem(String vehicleId) { + var runtime = LogisticsRuntimeService.findByEnvCode(1L); + var executorItem = runtime.executorItemMap.get(vehicleId); + return (PtrAgvItem) executorItem; } public static void sendCmd10010(int vehicleId, AmrTaskMessage amrTaskMessage) throws JsonProcessingException, MqttException { MqttClient mqttClient = AppContextHolder.getBean(MqttClient.class, true); diff --git a/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrStatusAndInfo.java b/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrStatusAndInfo.java deleted file mode 100644 index 51b620d..0000000 --- a/servo/src/main/java/com/galaxis/rcs/communication/amrCommunication/AmrStatusAndInfo.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.galaxis.rcs.communication.amrCommunication; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class AmrStatusAndInfo { - // agvId 车唯一标识 - public String agvId; - // agv名称 - public String agvName; - // agv类型 - public String agvType; - // agv型号 - public String agvModel; - // AMR功能型号 - public String agvFnModel; - // agv电量 - public double agvSOC; - // agv电池电压 - public double agvBatteryVoltage; - // agv充电状态 - public boolean agvChargingStatus; - // agv充电电流 - public double agvChargingCurrent; - // agv放电电流 - public double agvDischargingCurrent; - // agv电池温度 - public double agvBatteryTemperature; - // agv当前x坐标 - public double x; - // agv当前y坐标 - public double y; - // agv当前z坐标 - public double z; - // 当前所在站点的逻辑X坐标 Int32 - public int logicX; - // 当前所在站点的逻辑Y坐标 Int32 - public int logicY; - // 当前方向 UInt8 0: X轴正向 1: Y轴正向 2: X轴负向 3: Y轴负向 15: 未知方向 - public short direction; - // agv当前转动角度值 - public double orientation; - - public AmrStatusAndInfo(String agvId) { - this.agvId = agvId; - } -} diff --git a/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2Connector.java b/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2Connector.java index 080bcf6..4e9c9b9 100644 --- a/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2Connector.java +++ b/servo/src/main/java/com/galaxis/rcs/connector/cl2/Cl2Connector.java @@ -5,6 +5,7 @@ import com.galaxis.rcs.common.enums.PlanTaskType; import com.galaxis.rcs.connector.ConnectorConsumer; import com.yvan.logisticsModel.ExecutorItem; import com.yvan.logisticsModel.LogisticsRuntime; +import com.yvan.logisticsModel.PtrAgvItem; public abstract class Cl2Connector implements ConnectorConsumer { // RCS发往CL2的指令 @@ -19,21 +20,24 @@ public abstract class Cl2Connector implements ConnectorConsumer { */ @Override public void consume(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task) { + + PtrAgvItem ptrAgvItem = (PtrAgvItem) executorItem; + switch (PlanTaskType.valueOf(task.getPlanType())) { case MOVE: - robotMove(executorItem, runtime, task, task.getTargetId()); + robotMove(ptrAgvItem, runtime, task, task.getTargetId()); break; case ROTATION: - robotRotation(executorItem, runtime, task, task.getTargetRotation().floatValue()); + robotRotation(ptrAgvItem, runtime, task, task.getTargetRotation().floatValue()); break; case LOAD: - robotLoad(executorItem, runtime, task, task.getTargetId(), task.getTargetBay(), task.getTargetLevel(), task.getTargetCell()); + robotLoad(ptrAgvItem, runtime, task, task.getTargetId(), task.getTargetBay(), task.getTargetLevel(), task.getTargetCell()); break; case UNLOAD: - robotUnload(executorItem, runtime, task, task.getTargetId(), task.getTargetBay(), task.getTargetLevel(), task.getTargetCell()); + robotUnload(ptrAgvItem, runtime, task, task.getTargetId(), task.getTargetBay(), task.getTargetLevel(), task.getTargetCell()); break; case CHARGE: - robotCharger(executorItem, runtime, task, task.getTargetId()); + robotCharger(ptrAgvItem, runtime, task, task.getTargetId()); break; default: throw new IllegalArgumentException("Unknown plan type: " + task.getPlanType()); @@ -43,27 +47,27 @@ public abstract class Cl2Connector implements ConnectorConsumer { /** * 移动 robotMove * - * @param executorItem 机器人执行器 + * @param ptrAgvItem 机器人执行器 * @param runtime 物流运行时环境 * @param task 任务计划 * @param endWayPoint 终点ID, WayPointId */ - public abstract void robotMove(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String endWayPoint); + public abstract void robotMove(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String endWayPoint); /** * 旋转 robotRotate * - * @param executorItem 机器人执行器 + * @param ptrAgvItem 机器人执行器 * @param runtime 物流运行时环境 * @param task 任务计划 * @param worldRotation 转动身体到世界角度 90 度 */ - public abstract void robotRotation(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation); + public abstract void robotRotation(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation); /** * 取货 robotLoad * - * @param executorItem 机器人执行器 + * @param ptrAgvItem 机器人执行器 * @param runtime 物流运行时环境 * @param task 任务计划 * @param rackItem 货架ID @@ -71,12 +75,12 @@ public abstract class Cl2Connector implements ConnectorConsumer { * @param level 层 * @param cell 格 */ - public abstract void robotLoad(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell); + public abstract void robotLoad(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell); /** * 放货 robotUnload * - * @param executorItem 机器人执行器 + * @param ptrAgvItem 机器人执行器 * @param runtime 物流运行时环境 * @param task 任务计划 * @param rackItem 货架ID @@ -84,16 +88,16 @@ public abstract class Cl2Connector implements ConnectorConsumer { * @param level 层 * @param cell 格 */ - public abstract void robotUnload(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell); + public abstract void robotUnload(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell); /** * 充电 robotCharge * - * @param executorItem 机器人执行器 + * @param ptrAgvItem 机器人执行器 * @param runtime 物流运行时环境 * @param task 任务计划 * @param chargerItem 充电桩ID */ - public abstract void robotCharger(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem); + public abstract void robotCharger(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem); } 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 c17108c..c12f35a 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 @@ -2,12 +2,8 @@ package com.galaxis.rcs.connector.cl2; import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.galaxis.rcs.communication.amrCommunication.AmrMessageHandler; -import com.galaxis.rcs.communication.amrCommunication.AmrStatusAndInfo; import com.galaxis.rcs.connector.cl2.sendEntity.AmrTaskMessage; -import com.yvan.logisticsModel.ExecutorItem; -import com.yvan.logisticsModel.FlowItem; -import com.yvan.logisticsModel.LogisticsRuntime; -import com.yvan.logisticsModel.StaticItem; +import com.yvan.logisticsModel.*; import lombok.extern.slf4j.Slf4j; import org.clever.core.Conv; @@ -20,13 +16,9 @@ import java.math.BigDecimal; public class Cl2DeviceConnector extends Cl2Connector { @Override - public void robotMove(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String endPointId) { + public void robotMove(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String endPointId) { double speed = 1000; - // 获取车辆ID - int vehicleId = Conv.asInteger(task.getExecutorId()); - // 获取车辆当前信息 - AmrStatusAndInfo agvInfo = AmrMessageHandler.getAmrStatusAndInfo(vehicleId); // 获取目标点信息 StaticItem pointItem = runtime.getStaticItemById(endPointId); @@ -37,8 +29,8 @@ public class Cl2DeviceConnector extends Cl2Connector { message.SeqNo = 1; message.OperationType = 0; message.GoNow = true; - message.StartX = agvInfo.logicX; - message.StartY = agvInfo.logicY; + message.StartX = ptrAgvItem.logicX; + message.StartY = ptrAgvItem.logicY; message.EndX = pointItem.logicX; message.EndY = pointItem.logicY; double targetRotation = task.getTargetRotation().doubleValue(); @@ -52,14 +44,14 @@ public class Cl2DeviceConnector extends Cl2Connector { short targetDirection = (short) (Math.round(targetRotation/90) % 4); // 判断车的 速度方向 - if (agvInfo.direction == targetDirection) { + if (ptrAgvItem.direction == targetDirection) { } log.info("Cl2DeviceConnector robotMove: executorItem={}, task={}, endPointId={}", - executorItem.getId(), task.getPlanTaskId(), endPointId); + ptrAgvItem.getId(), task.getPlanTaskId(), endPointId); // 获取静态数据(货架、地标等) @@ -77,26 +69,26 @@ public class Cl2DeviceConnector extends Cl2Connector { } @Override - public void robotRotation(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation) { + public void robotRotation(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation) { log.info("Cl2DeviceConnector robotRotation: executorItem={}, task={}, worldRotation={}", - executorItem.getId(), task.getPlanTaskId(), worldRotation); + ptrAgvItem.getId(), task.getPlanTaskId(), worldRotation); } @Override - public void robotLoad(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { + public void robotLoad(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { log.info("Cl2DeviceConnector robotLoad: executorItem={}, task={}, rackItem={}, bay={}, level={}, cell={}", - executorItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); + ptrAgvItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); } @Override - public void robotUnload(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { + public void robotUnload(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { log.info("Cl2DeviceConnector robotUnload: executorItem={}, task={}, rackItem={}, bay={}, level={}, cell={}", - executorItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); + ptrAgvItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); } @Override - public void robotCharger(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem) { + public void robotCharger(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem) { log.info("Cl2DeviceConnector robotCharger: executorItem={}, task={}, chargerItem={}", - executorItem.getId(), task.getPlanTaskId(), chargerItem); + ptrAgvItem.getId(), task.getPlanTaskId(), chargerItem); } } diff --git a/servo/src/main/java/com/galaxis/rcs/connector/cl2/VirtualCl2Connector.java b/servo/src/main/java/com/galaxis/rcs/connector/cl2/VirtualCl2Connector.java index 60a5fe0..6f49601 100644 --- a/servo/src/main/java/com/galaxis/rcs/connector/cl2/VirtualCl2Connector.java +++ b/servo/src/main/java/com/galaxis/rcs/connector/cl2/VirtualCl2Connector.java @@ -3,6 +3,7 @@ package com.galaxis.rcs.connector.cl2; import com.galaxis.rcs.common.entity.RcsTaskPlan; import com.yvan.logisticsModel.ExecutorItem; import com.yvan.logisticsModel.LogisticsRuntime; +import com.yvan.logisticsModel.PtrAgvItem; import lombok.extern.slf4j.Slf4j; /** @@ -12,32 +13,32 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class VirtualCl2Connector extends Cl2Connector { @Override - public void robotMove(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String endWayPoint) { + public void robotMove(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String endWayPoint) { log.info("VirtualCl2Connector robotMove: executorItem={}, task={}, endWayPoint={}", - executorItem.getId(), task.getPlanTaskId(), endWayPoint); + ptrAgvItem.getId(), task.getPlanTaskId(), endWayPoint); } @Override - public void robotRotation(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation) { + public void robotRotation(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, float worldRotation) { log.info("VirtualCl2Connector robotRotation: executorItem={}, task={}, worldRotation={}", - executorItem.getId(), task.getPlanTaskId(), worldRotation); + ptrAgvItem.getId(), task.getPlanTaskId(), worldRotation); } @Override - public void robotLoad(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { + public void robotLoad(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { log.info("VirtualCl2Connector robotLoad: executorItem={}, task={}, rackItem={}, bay={}, level={}, cell={}", - executorItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); + ptrAgvItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); } @Override - public void robotUnload(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { + public void robotUnload(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String rackItem, int bay, int level, int cell) { log.info("VirtualCl2Connector robotUnload: executorItem={}, task={}, rackItem={}, bay={}, level={}, cell={}", - executorItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); + ptrAgvItem.getId(), task.getPlanTaskId(), rackItem, bay, level, cell); } @Override - public void robotCharger(ExecutorItem executorItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem) { + public void robotCharger(PtrAgvItem ptrAgvItem, LogisticsRuntime runtime, RcsTaskPlan task, String chargerItem) { log.info("VirtualCl2Connector robotCharger: executorItem={}, task={}, chargerItem={}", - executorItem.getId(), task.getPlanTaskId(), chargerItem); + ptrAgvItem.getId(), task.getPlanTaskId(), chargerItem); } } diff --git a/servo/src/main/java/com/yvan/logisticsModel/ExecutorConnectorThread.java b/servo/src/main/java/com/yvan/logisticsModel/ExecutorConnectorThread.java deleted file mode 100644 index ac77af8..0000000 --- a/servo/src/main/java/com/yvan/logisticsModel/ExecutorConnectorThread.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.yvan.logisticsModel; - -import com.galaxis.rcs.common.entity.RcsTaskPlan; -import com.galaxis.rcs.common.enums.PlanTaskStatus; -import com.galaxis.rcs.connector.ConnectorFactory; -import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; - -import java.util.concurrent.atomic.AtomicBoolean; - -@Slf4j -public class ExecutorConnectorThread extends Thread { - private final AtomicBoolean running = new AtomicBoolean(false); - - private final ExecutorItem executorItem; - private final LogisticsRuntime logisticsRuntime; - - public ExecutorConnectorThread(ExecutorItem executorItem, LogisticsRuntime logisticsRuntime) { - super("ExecutorConnector-" + executorItem.getId()); - this.executorItem = executorItem; - this.logisticsRuntime = logisticsRuntime; - } - - @Override - public void run() { - running.set(true); - log.info("Connector thread started for executor: {}", this.executorItem.getId()); - - try { - while (running.get()) { - // 从队列中获取任务,如果队列为空则阻塞等待 - RcsTaskPlan task = this.executorItem.planQueue.take(); - - try { - // 处理任务 - ConnectorFactory.getConnector(this.executorItem.getT()) - .consume(this.executorItem, this.logisticsRuntime, task); - - } catch (Exception e) { - log.error("Error processing task: " + task, e); - task.setPlanTaskErrorInfo(e.getMessage()); - task.setPlanTaskStatus(PlanTaskStatus.ERROR.toString()); - } - } - } catch (InterruptedException e) { - System.out.println("Connector thread interrupted for executor: " + this.executorItem.getId()); - } finally { - System.out.println("Connector thread stopped for executor: " + this.executorItem.getId()); - } - } - - /** - * 停止连接器线程 - */ - public void stopConnector() { - running.set(false); - this.interrupt(); // 中断阻塞状态 - } - - /** - * 检查连接器是否在运行 - */ - public boolean isRunning() { - return running.get(); - } -} diff --git a/servo/src/main/java/com/yvan/logisticsModel/ExecutorItem.java b/servo/src/main/java/com/yvan/logisticsModel/ExecutorItem.java index 33deee7..0eec10d 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/ExecutorItem.java +++ b/servo/src/main/java/com/yvan/logisticsModel/ExecutorItem.java @@ -13,104 +13,25 @@ import java.util.concurrent.BlockingQueue; * 物流任务执行单元(如拣货台、小车、AGV、堆垛机、人等) * 每个物流任务执行器都会有一个 Connector 线程,专门用来消费 currentPlanList 队列,变成实际的设备指令 */ -public class ExecutorItem extends BaseItem { - private final int BLOCKING_QUEUE_CAPACITY = 100; - private final LogisticsRuntime logisticsRuntime; - - /** - * 当前执行的任务规划列表 - */ - final BlockingQueue planQueue = Queues.newArrayBlockingQueue(BLOCKING_QUEUE_CAPACITY); - - /** - * 车执行完所有任务之后,停留在什么坐标点位实体上 - */ - public StaticItem planTargetItem; - - /** - * 车当前旋转角度 - */ - public Float currentRotationAngle; - - /** - * 车当前逻辑坐标位 - */ - public Vector2 currentLogicPosition; - - /** - * 车当前世界坐标位 - */ - public Vector2 currentWorldPosition; - - /** - * 计划目标坐标位, 执行完所有任务之后,车会停留在什么是世界角度 - */ - public Float planRotationAngle; - - /** - * 连接器线程 - */ - private final ExecutorConnectorThread connectorThread; +public abstract class ExecutorItem extends BaseItem { + public final LogisticsRuntime logisticsRuntime; + public boolean isMapReady = false; - /** - * 启动连接器线程 - */ - public void startConnector() { - if (!connectorThread.isRunning()) { - connectorThread.start(); - System.out.println("Connector started for executor: " + this.getId()); - } - } - - /** - * 停止连接器线程 - */ - public void stopConnector() { - connectorThread.stop(); - System.out.println("Connector stopped for executor: " + this.getId()); + public void mapReady() { + this.isMapReady = true; } public ExecutorItem(LogisticsRuntime logisticsRuntime, Map raw) { super(raw); this.logisticsRuntime = logisticsRuntime; - this.connectorThread = new ExecutorConnectorThread(this, logisticsRuntime); } - /** - * 添加任务序列到当前执行器 - */ - public void appendSequence(PlanTaskSequence sequence) { - if (sequence == null || sequence.taskList.isEmpty()) { - return; - } - - // 检查 planList 是不是全都是我的任务 - for (RcsTaskPlan plan : sequence.taskList) { - if (!plan.getExecutorId().equals(this.getId())) { - throw new RuntimeException("plan not belong executor:" + this.getId() + ", " + plan.getExecutorId()); - } - } - - LogisticsRuntime runtime = sequence.logisticsRuntime; - - if (sequence.lastWayPointId != null) { - this.planTargetItem = runtime.getStaticItemById(sequence.lastWayPointId); - } - if (sequence.lastRotationAngle != null) { - this.planRotationAngle = sequence.lastRotationAngle; - } - - planQueue.addAll(sequence.taskList); - - // TODO: 开启轮询线程,等待下一个待执行任务 - } /** * 执行器是否空闲 */ - public boolean isFree() { - return (this.planQueue.isEmpty() && this.connectorThread.isRunning()); - } + abstract public boolean isFree(); + abstract public void appendSequence(PlanTaskSequence sequence); } diff --git a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java index 3bd0d06..0ab081b 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java +++ b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java @@ -133,7 +133,7 @@ public class LogisticsRuntime { case "cl2": case "clx": - item = new ExecutorItem(this, itemObject); + item = new PtrAgvItem(this, itemObject); this.executorItemMap.put(item.getId(), (ExecutorItem) item); break; } @@ -143,7 +143,7 @@ public class LogisticsRuntime { public void start() { // 开启所有机器人的任务调度 for (ExecutorItem executorItem : executorItemMap.values()) { - executorItem.startConnector(); + executorItem.mapReady(); log.info("Executor {} started", executorItem.getId()); } diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvConnectorThread.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvConnectorThread.java new file mode 100644 index 0000000..279a0c4 --- /dev/null +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvConnectorThread.java @@ -0,0 +1,65 @@ +package com.yvan.logisticsModel; + +import com.galaxis.rcs.common.entity.RcsTaskPlan; +import com.galaxis.rcs.common.enums.PlanTaskStatus; +import com.galaxis.rcs.connector.ConnectorFactory; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicBoolean; + +@Slf4j +public class PtrAgvConnectorThread extends Thread { + private final AtomicBoolean running = new AtomicBoolean(false); + + private final PtrAgvItem executorItem; + private final LogisticsRuntime logisticsRuntime; + + public PtrAgvConnectorThread(PtrAgvItem executorItem, LogisticsRuntime logisticsRuntime) { + super("ExecutorConnector-" + executorItem.getId()); + this.executorItem = executorItem; + this.logisticsRuntime = logisticsRuntime; + } + + @Override + public void run() { + running.set(true); + log.info("Connector thread started for executor: {}", this.executorItem.getId()); + + try { + while (running.get()) { + // 从队列中获取任务,如果队列为空则阻塞等待 + RcsTaskPlan task = this.executorItem.planQueue.take(); + + try { + // 处理任务 + ConnectorFactory.getConnector(this.executorItem.getT()) + .consume(this.executorItem, this.logisticsRuntime, task); + + } catch (Exception e) { + log.error("Error processing task: " + task, e); + task.setPlanTaskErrorInfo(e.getMessage()); + task.setPlanTaskStatus(PlanTaskStatus.ERROR.toString()); + } + } + } catch (InterruptedException e) { + System.out.println("Connector thread interrupted for executor: " + this.executorItem.getId()); + } finally { + System.out.println("Connector thread stopped for executor: " + this.executorItem.getId()); + } + } + + /** + * 停止连接器线程 + */ + public void stopConnector() { + running.set(false); + this.interrupt(); // 中断阻塞状态 + } + + /** + * 检查连接器是否在运行 + */ + public boolean isRunning() { + return running.get(); + } +} diff --git a/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java new file mode 100644 index 0000000..c5a9561 --- /dev/null +++ b/servo/src/main/java/com/yvan/logisticsModel/PtrAgvItem.java @@ -0,0 +1,110 @@ +package com.yvan.logisticsModel; + +import com.galaxis.rcs.common.entity.RcsTaskPlan; +import com.galaxis.rcs.plan.PlanTaskSequence; +import com.google.common.collect.Queues; + +import java.util.Map; +import java.util.concurrent.BlockingQueue; + +public class PtrAgvItem extends ExecutorItem { + private final int BLOCKING_QUEUE_CAPACITY = 100; + + // ip + public String ip; + // agv名称 + public String agvName; + // agv类型 + public String agvType; + // agv型号 + public String agvModel; + // AMR功能型号 + public String agvFnModel; + // agv电量 + public double agvSOC; + // agv电池电压 + public double agvBatteryVoltage; + // agv充电状态 + public boolean agvChargingStatus; + // agv充电电流 + public double agvChargingCurrent; + // agv放电电流 + public double agvDischargingCurrent; + // agv电池温度 + public double agvBatteryTemperature; + // agv当前x坐标 + public double x; + // agv当前y坐标 + public double y; + // agv当前z坐标 + public double z; + // 当前所在站点的逻辑X坐标 Int32 + public int logicX; + // 当前所在站点的逻辑Y坐标 Int32 + public int logicY; + // 当前方向 UInt8 0: X轴正向 1: Y轴正向 2: X轴负向 3: Y轴负向 15: 未知方向 + public short direction; + // agv当前转动角度值 + public double orientation; + + + /** + * 当前执行的任务规划列表 + */ + final BlockingQueue planQueue = Queues.newArrayBlockingQueue(BLOCKING_QUEUE_CAPACITY); + + + /** + * 连接器线程 + */ + private final PtrAgvConnectorThread connectorThread; + /** + * 启动连接器线程 + */ + public void startConnector() { + if (!connectorThread.isRunning()) { + connectorThread.start(); + System.out.println("Connector started for executor: " + this.getId()); + } + } + + /** + * 停止连接器线程 + */ + public void stopConnector() { + connectorThread.stop(); + System.out.println("Connector stopped for executor: " + this.getId()); + } + + /** + * 添加任务序列到当前执行器 + */ + public void appendSequence(PlanTaskSequence sequence) { + if (sequence == null || sequence.taskList.isEmpty()) { + return; + } + + // 检查 planList 是不是全都是我的任务 + for (RcsTaskPlan plan : sequence.taskList) { + if (!plan.getExecutorId().equals(this.getId())) { + throw new RuntimeException("plan not belong executor:" + this.getId() + ", " + plan.getExecutorId()); + } + } + + LogisticsRuntime runtime = sequence.logisticsRuntime; + + planQueue.addAll(sequence.taskList); + + // TODO: 开启轮询线程,等待下一个待执行任务 + } + + public boolean isFree() { + return (this.planQueue.isEmpty() && this.connectorThread.isRunning()); + } + + public PtrAgvItem(LogisticsRuntime logisticsRuntime, Map raw) { + super(logisticsRuntime, raw); + this.connectorThread = new PtrAgvConnectorThread(this, logisticsRuntime); + } + +}