From 877b2519157cea762b1e63e9c57c09614216d684 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 24 七月 2025 19:27:46 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java | 17
src/main/java/com/zy/core/model/command/ShuttleCommand.java | 15
src/main/java/com/zy/common/utils/NavigateMapUtils.java | 5
src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java | 3
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java | 10
src/main/java/com/zy/common/model/NavigateNode.java | 1
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java | 13
src/main/java/com/zy/core/thread/ShuttleThread.java | 2
src/main/java/com/zy/common/utils/NavigateUtils.java | 24
src/main/java/com/zy/core/cache/MessageQueue.java | 25
src/main/java/com/zy/core/thread/TrafficControlThread.java | 30 +
src/main/java/com/zy/core/utils/TrafficControlUtils.java | 81 +++
src/main/java/com/zy/common/utils/NavigatePositionConvert.java | 6
src/main/java/com/zy/core/ServerBootstrap.java | 12
src/main/java/com/zy/core/model/TrafficControlDataModel.java | 19
src/main/java/com/zy/asrs/controller/ShuttleController.java | 4
src/main/java/com/zy/core/action/ShuttleAction.java | 584 ++++++++++++++++----
src/main/java/com/zy/core/enums/SlaveType.java | 1
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java | 575 +++++++++++++++++++++
src/main/java/com/zy/core/enums/RedisKeyType.java | 6
src/main/java/com/zy/common/utils/NavigateMapData.java | 125 ++++
src/main/java/com/zy/common/model/enums/NavigationMapType.java | 5
22 files changed, 1,416 insertions(+), 147 deletions(-)
diff --git a/src/main/java/com/zy/asrs/controller/ShuttleController.java b/src/main/java/com/zy/asrs/controller/ShuttleController.java
index f7bdebb..0f41a90 100644
--- a/src/main/java/com/zy/asrs/controller/ShuttleController.java
+++ b/src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -35,6 +35,7 @@
import com.zy.core.model.param.ShuttleMoveLocParam;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.thread.ShuttleThread;
+import com.zy.core.thread.TrafficControlThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -346,6 +347,9 @@
assignCommand.setCommands(commands);
} else if (shuttleTaskModeType == ShuttleTaskModeType.RESET) {
//澶嶄綅
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ trafficControlThread.cancelTrafficControl(shuttleProtocol.getShuttleNo(), shuttleProtocol.getTaskNo());
+
shuttleThread.setSyncTaskNo(0);//宸ヤ綔鍙锋竻绌�
shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);//浠诲姟鐘舵��-绌洪棽
shuttleThread.setPakMk(true);//浣滀笟鏍囪澶嶄綅
diff --git a/src/main/java/com/zy/common/model/NavigateNode.java b/src/main/java/com/zy/common/model/NavigateNode.java
index c1e1a70..4ebf6d6 100644
--- a/src/main/java/com/zy/common/model/NavigateNode.java
+++ b/src/main/java/com/zy/common/model/NavigateNode.java
@@ -22,6 +22,7 @@
private Integer moveDistance;//琛岃蛋璺濈
private Integer nodeValue;//鑺傜偣鏁版嵁
private Boolean linePartAllowGo = false;//鐩寸嚎娈甸儴鍒嗭紝鍏佽鐩存帴琛岃蛋
+ private Long linePartFlag;//鐩寸嚎娈垫暟鎹爣璇�
public NavigateNode(int x, int y) {
this.x = x;
diff --git a/src/main/java/com/zy/common/model/enums/NavigationMapType.java b/src/main/java/com/zy/common/model/enums/NavigationMapType.java
index 4556a94..fb83272 100644
--- a/src/main/java/com/zy/common/model/enums/NavigationMapType.java
+++ b/src/main/java/com/zy/common/model/enums/NavigationMapType.java
@@ -11,6 +11,7 @@
SHUTTLE(3, "鍦板浘鎼哄甫灏忚溅"),
LIFT(4, "鍦板浘鎼哄甫鎻愬崌鏈�"),
PATH_LOCK(5, "璺緞閿�"),
+ TRAFFIC_CONTROL(6, "浜ら�氱鍒�"),
;
public Integer id;
@@ -46,11 +47,11 @@
}
public static List<NavigationMapType> getDfxWithDevice() {
- return getMapTypes(DFX, SHUTTLE, LIFT, PATH_LOCK);
+ return getMapTypes(DFX, SHUTTLE, LIFT, PATH_LOCK, TRAFFIC_CONTROL);
}
public static List<NavigationMapType> getNormalWithDevice() {
- return getMapTypes(NORMAL, SHUTTLE, LIFT, PATH_LOCK);
+ return getMapTypes(NORMAL, SHUTTLE, LIFT, PATH_LOCK, TRAFFIC_CONTROL);
}
public static List<NavigationMapType> getMapTypes(NavigationMapType... types) {
diff --git a/src/main/java/com/zy/common/utils/NavigateMapData.java b/src/main/java/com/zy/common/utils/NavigateMapData.java
index 3df92d7..8deec59 100644
--- a/src/main/java/com/zy/common/utils/NavigateMapData.java
+++ b/src/main/java/com/zy/common/utils/NavigateMapData.java
@@ -3,6 +3,8 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.SpringUtils;
+import com.core.exception.CoolException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.entity.LocMast;
@@ -11,16 +13,24 @@
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.MapNode;
+import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.MapNodeType;
import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.ShuttleCommandModeType;
import com.zy.core.enums.SlaveType;
+import com.zy.core.model.TrafficControlDataModel;
+import com.zy.core.model.command.ShuttleAssignCommand;
+import com.zy.core.model.command.ShuttleCommand;
+import com.zy.core.model.command.ShuttleRedisCommand;
import com.zy.core.model.protocol.ForkLiftStaProtocol;
import com.zy.core.thread.ForkLiftThread;
+import com.zy.core.thread.TrafficControlThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -38,6 +48,8 @@
private DeviceConfigService deviceConfigService;
@Autowired
private BasMapService basMapService;
+ @Autowired
+ private ObjectMapper objectMapper;
public int[][] getData(Integer lev, List<NavigationMapType> mapTypes, List<int[]> whitePoints, List<int[]> shuttlePoints) {
try {
@@ -188,6 +200,11 @@
if(mapType.equals(NavigationMapType.PATH_LOCK)) {
//鍔犺浇璺緞閿�
lists = loadPathLock(lists, lev);
+ }
+
+ if(mapType.equals(NavigationMapType.TRAFFIC_CONTROL)) {
+ //鍔犺浇浜ら�氱鍒�
+ lists = loadTrafficControl(lists, lev);
}
}
@@ -396,4 +413,112 @@
return lists;
}
+ //鍔犺浇浜ら�氱鍒�
+ public List<List<MapNode>> loadTrafficControl(List<List<MapNode>> lists, Integer lev) {
+ try {
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ if (trafficControlThread == null) {
+ throw new CoolException("init traffic control thread error");
+ }
+
+ List<TrafficControlDataModel> trafficList = trafficControlThread.getAllTrafficControl();
+ for (TrafficControlDataModel trafficControlDataModel : trafficList) {
+ List<NavigateNode> totalNodeList = trafficControlDataModel.getTotalNodeList();
+ NavigateNode startNode = totalNodeList.get(0);
+ if (startNode.getZ() != lev) {
+ continue;
+ }
+
+ for (NavigateNode node : totalNodeList) {
+ int row = node.getX();
+ int bay = node.getY();
+
+ List<MapNode> list = lists.get(row);
+ MapNode mapNode = list.get(bay);
+
+ //鑺傜偣璁剧疆鎴怐isable
+ mapNode.setValue(MapNodeType.DISABLE.id);
+
+ //鏇存柊list
+ list.set(bay, mapNode);
+ lists.set(row, list);
+ }
+ }
+
+// HashMap<String, Integer> deviceMap = trafficControlThread.getDeviceMap();
+// if(deviceMap == null) {
+// throw new CoolException("get traffic control device map error");
+// }
+//
+// for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
+// String key = entry.getKey();
+// Integer shuttleNo = entry.getValue();
+// if (shuttleNo <= 0) {
+// continue;
+// }
+//
+// Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + shuttleNo);
+// if (object == null) {
+// continue;
+// }
+//
+// int taskNo = Integer.parseInt(String.valueOf(object));
+//
+// Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + taskNo);
+// if (obj == null) {
+// continue;
+// }
+//
+// ShuttleRedisCommand redisCommand = null;
+// try {
+// redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
+// } catch (IOException e) {
+// throw new RuntimeException(e);
+// }
+//
+// if (redisCommand == null) {
+// continue;
+// }
+//
+// ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
+// List<ShuttleCommand> commands = assignCommand.getCommands();
+//
+// List<NavigateNode> controlLocList = new ArrayList<>();
+// for (ShuttleCommand command : commands) {
+// if (command.getComplete()) {
+// continue;
+// }
+//
+// if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
+// List<NavigateNode> nodes = command.getNodes();
+// for (NavigateNode node : nodes) {
+// if(!controlLocList.contains(node)) {
+// controlLocList.add(node);
+// }
+// }
+// }
+// }
+//
+// for (NavigateNode node : controlLocList) {
+// int row = node.getX();
+// int bay = node.getY();
+//
+// List<MapNode> list = lists.get(row);
+// MapNode mapNode = list.get(bay);
+//
+// //鑺傜偣璁剧疆鎴怐isable
+// mapNode.setValue(MapNodeType.DISABLE.id);
+//
+// //鏇存柊list
+// list.set(bay, mapNode);
+// lists.set(row, list);
+// }
+//
+// }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return lists;
+ }
+
}
diff --git a/src/main/java/com/zy/common/utils/NavigateMapUtils.java b/src/main/java/com/zy/common/utils/NavigateMapUtils.java
index 733f56c..8b043c4 100644
--- a/src/main/java/com/zy/common/utils/NavigateMapUtils.java
+++ b/src/main/java/com/zy/common/utils/NavigateMapUtils.java
@@ -58,7 +58,10 @@
//鍒ゆ柇鑺傜偣鏄惁琚攣瀹�
if(lockMap.containsKey(key)) {
- return false;
+ Integer deviceNo = (Integer) lockMap.get(key);
+ if (!shuttleNo.equals(deviceNo)) {//绛夊緟閿佸畾鐨勮妭鐐瑰凡琚綋鍓嶅皬杞﹂攣瀹氾紝璁ゅ畾閿佸畾鎴愬姛
+ return false;
+ }
}
tmpMap.put(key, shuttleNo);
diff --git a/src/main/java/com/zy/common/utils/NavigatePositionConvert.java b/src/main/java/com/zy/common/utils/NavigatePositionConvert.java
index 76a2bfd..ac71260 100644
--- a/src/main/java/com/zy/common/utils/NavigatePositionConvert.java
+++ b/src/main/java/com/zy/common/utils/NavigatePositionConvert.java
@@ -100,4 +100,10 @@
return new int[]{col, row};
}
+ public static boolean equalsNode(NavigateNode node1, NavigateNode node2) {
+ if(node1.getX() == node2.getX() && node1.getY() == node2.getY() && node1.getZ() == node2.getZ()) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/zy/common/utils/NavigateUtils.java b/src/main/java/com/zy/common/utils/NavigateUtils.java
index dd88872..d49b64b 100644
--- a/src/main/java/com/zy/common/utils/NavigateUtils.java
+++ b/src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -2,6 +2,8 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.MapNode;
@@ -10,6 +12,8 @@
import com.zy.core.News;
import com.zy.core.enums.MapNodeType;
import com.zy.core.model.PythonSimilarityResult;
+import com.zy.system.entity.Config;
+import com.zy.system.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -30,6 +34,10 @@
private String pythonCalcSimilarity;
@Autowired
private NavigateMapData navigateMapData;
+ @Autowired
+ private SnowflakeIdWorker snowflakeIdWorker;
+ @Autowired
+ private ConfigService configService;
public List<NavigateNode> calc(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites) {
return calcJava(startPoint, endPoint, mapTypes, shuttlePoints, whites);
@@ -315,15 +323,23 @@
//灏嗘渶鍚庝竴娈垫暟鎹坊鍔犺繘鍏�
list.add(data);
+ //鍒嗘璺緞-澶勭悊瓒呴暱鐩寸嚎娈佃矾寰�
List<List<NavigateNode>> paths = getSectionPathToSplitOverLength(list);
return paths;
}
//鍒嗘璺緞-澶勭悊瓒呴暱鐩寸嚎娈佃矾寰�
public List<List<NavigateNode>> getSectionPathToSplitOverLength(List<List<NavigateNode>> list) {
+ int overLength = 9;//榛樿9鑺�
+ Config shuttleMoveOverLengthConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "shuttleMoveOverLength"));
+ if (shuttleMoveOverLengthConfig != null) {
+ overLength = Integer.parseInt(shuttleMoveOverLengthConfig.getValue());
+ }
+
List<List<NavigateNode>> paths = new ArrayList<>();
- int overLength = 9;
for (List<NavigateNode> nodes : list) {
+ long nextId = snowflakeIdWorker.nextId();
+
if (nodes.size() > overLength) {
List<NavigateNode> copy = JSON.parseArray(JSON.toJSONString(nodes), NavigateNode.class);
List<NavigateNode> tmp = new ArrayList<>();
@@ -337,10 +353,12 @@
if (lastNode == null) {
NavigateNode startNode = tmp.get(0);
startNode.setLinePartAllowGo(true);//鐩寸嚎娈佃秴闀块儴鍒嗗厑璁哥洿鎺ヨ璧�
+ startNode.setLinePartFlag(nextId);//鐩寸嚎娈垫暟鎹爣璇�
tmp.set(0, startNode);
}
NavigateNode targetNode = tmp.get(tmp.size() - 1);
targetNode.setLinePartAllowGo(true);//鐩寸嚎娈佃秴闀块儴鍒嗗厑璁哥洿鎺ヨ璧�
+ targetNode.setLinePartFlag(nextId);//鐩寸嚎娈垫暟鎹爣璇�
if (lastNode != null) {
tmp.add(0, lastNode);
}
@@ -357,6 +375,10 @@
paths.add(tmp);
}
}else {
+ NavigateNode startNode = nodes.get(0);
+ startNode.setLinePartAllowGo(true);//鐩寸嚎娈佃秴闀块儴鍒嗗厑璁哥洿鎺ヨ璧�
+ startNode.setLinePartFlag(nextId);//鐩寸嚎娈垫暟鎹爣璇�
+ nodes.set(0, startNode);
paths.add(nodes);
}
}
diff --git a/src/main/java/com/zy/common/utils/ShuttleOperaUtils.java b/src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
index 171640f..33739d4 100644
--- a/src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
+++ b/src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -116,12 +116,15 @@
assignCommand.setNodes(allNode);//褰撳墠浠诲姟鎵�鍗犵敤鐨勮妭鐐筶ist
- boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(startLocNo), shuttleNo, lockNode, true);//閿佸畾璺緞
- if (!result) {
- News.error("{} dash {} can't lock path!", startLocNo, endLocNo);
- shuttleThread.offerSystemMsg("{} dash {} can't lock path!", startLocNo, endLocNo);
- return null;//璺緞閿佸畾澶辫触
+ //灏忚溅绉诲姩杩炵画涓嬪彂鎸囦护
+ boolean shuttleMoveCommandsContinuously = false;
+ Config shuttleMoveCommandsContinuouslyConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "shuttleMoveCommandsContinuously"));
+ if (shuttleMoveCommandsContinuouslyConfig != null) {
+ if (shuttleMoveCommandsContinuouslyConfig.getValue().equals("Y")) {
+ shuttleMoveCommandsContinuously = true;
+ }
}
+ assignCommand.setShuttleMoveCommandsContinuously(shuttleMoveCommandsContinuously);
return commands;
}
diff --git a/src/main/java/com/zy/core/ServerBootstrap.java b/src/main/java/com/zy/core/ServerBootstrap.java
index 003d514..6af478e 100644
--- a/src/main/java/com/zy/core/ServerBootstrap.java
+++ b/src/main/java/com/zy/core/ServerBootstrap.java
@@ -11,7 +11,9 @@
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
+import com.zy.core.thread.TrafficControlThread;
import com.zy.core.thread.impl.NyShuttleThread;
+import com.zy.core.thread.impl.TrafficControlImplThread;
import com.zy.core.thread.impl.ZyForkLiftThread;
import com.zy.core.utils.DeviceMsgUtils;
import lombok.extern.slf4j.Slf4j;
@@ -61,14 +63,16 @@
List<DeviceConfig> forkLiftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
.eq("device_type", String.valueOf(SlaveType.ForkLift)));
for (DeviceConfig forkLift : forkLiftList) {
- MessageQueue.init(SlaveType.ForkLift, forkLift);
+ MessageQueue.init(SlaveType.ForkLift, forkLift.getDeviceNo());
}
// 鍒濆鍖栧洓鍚戠┛姊溅mq
List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
.eq("device_type", String.valueOf(SlaveType.Shuttle)));
for (DeviceConfig shuttle : shuttleList) {
- MessageQueue.init(SlaveType.Shuttle, shuttle);
+ MessageQueue.init(SlaveType.Shuttle, shuttle.getDeviceNo());
}
+
+ MessageQueue.init(SlaveType.TrafficControl, 1);
}
private void initThread(){
@@ -128,6 +132,10 @@
//璁惧鍒濆鍖栧畬姣�
deviceMsgUtils.sendDeviceConfig(JSON.toJSONString(allDevices));
deviceMsgUtils.sendFakeDeviceConfig(JSON.toJSONString(fakeDevices));
+
+ TrafficControlThread trafficControlThread = new TrafficControlImplThread(redisUtil);
+ new Thread(trafficControlThread).start();
+ SlaveConnection.put(SlaveType.TrafficControl, 1, trafficControlThread);
}
diff --git a/src/main/java/com/zy/core/action/ShuttleAction.java b/src/main/java/com/zy/core/action/ShuttleAction.java
index 1bfe527..393d2cb 100644
--- a/src/main/java/com/zy/core/action/ShuttleAction.java
+++ b/src/main/java/com/zy/core/action/ShuttleAction.java
@@ -13,31 +13,30 @@
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.Utils;
-import com.zy.common.ExecuteSupport;
import com.zy.common.model.NavigateNode;
import com.zy.common.service.CommonService;
import com.zy.common.utils.NavigateMapUtils;
+import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.dispatcher.ShuttleDispatchUtils;
import com.zy.core.enums.*;
import com.zy.core.model.CommandResponse;
+import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.ShuttleRedisCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.thread.ShuttleThread;
+import com.zy.core.thread.TrafficControlThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
@Component
public class ShuttleAction {
@@ -65,6 +64,17 @@
ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
if (shuttleThread == null) {
return false;
+ }
+
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ if(trafficControlThread == null){
+ return false;
+ }
+
+ //娓呯┖涓嬪彂绱㈠紩
+ Set<String> keys = redisUtil.searchKeys(RedisKeyType.SHUTTLE_SEND_COMMAND_INDEX.key + shuttleNo);
+ for (String key : keys) {
+ redisUtil.del(key);
}
ShuttleRedisCommand redisCommand = new ShuttleRedisCommand();
@@ -113,139 +123,69 @@
return false;
}
- List<ShuttleCommand> commands = redisCommand.getAssignCommand().getCommands();
- if (commands.isEmpty()) {
+ //妫�娴嬪懡浠�
+ int checked = checkCommand(redisCommand, shuttleNo);
+ if (checked == 0) {
return false;
}
ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
- int commandStep = redisCommand.getCommandStep();
-
- Integer mode = -1;
- if(commandStep < commands.size()) {
- //鍙栧嚭鍛戒护
- ShuttleCommand currentCommand = commands.get(commandStep);
- mode = currentCommand.getMode();
- }
-
- //鍒ゆ柇璁惧鏄惁绌洪棽
- Integer finalMode = mode;
- if (!shuttleThread.isDeviceIdle(new ExecuteSupport() {
- @Override
- public Boolean judgement() {
- if (ShuttleCommandModeType.CHARGE_CLOSE.id.equals(finalMode)) {//鍏抽棴鍏呯數
- return false;//涓嶉渶瑕佸垽鏂姸鎬�
- }
- return true;//闇�瑕佸垽鏂姸鎬�
- }
- })) {
+ List<ShuttleCommand> commands = assignCommand.getCommands();
+ if (commands.isEmpty()) {
return false;
}
- // 瀹岀粨涓婁竴鏉″懡浠�
- boolean updateCommand = false;
- if (commandStep != 0) {
- ShuttleCommand command = commands.get(commandStep - 1);
- if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
- // 姝e父绉诲姩
- if (command.getTargetLocNo().equals(shuttleProtocol.getCurrentLocNo())) {
- command.setComplete(true);
- updateCommand = true;
- //瑙i攣閿佸畾璺緞锛屼笂涓�鏉¤矾寰�
- List<NavigateNode> nodes = null;
- try {
- String nodesStr = objectMapper.writeValueAsString(command.getNodes());
- nodes = objectMapper.readValue(nodesStr, new TypeReference<List<NavigateNode>>() {
- });
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- if (nodes != null) {
- NavigateNode targetNode = assignCommand.getNodes().get(assignCommand.getNodes().size() - 1);//鏈�缁堣妭鐐�
- NavigateNode node = nodes.get(nodes.size() - 1);
- if (!(targetNode.getX() == node.getX() && targetNode.getY() == node.getY())) {
- nodes.remove(nodes.size() - 1);//鍓旈櫎灏捐妭鐐�
- }
- boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(shuttleProtocol.getCurrentLocNo()), shuttleProtocol.getShuttleNo(), nodes, false);//瑙i攣璺緞
- if (!result) {
- return false;//瑙i攣澶辫触
- }
- }
- }
- } else if (command.getMode() == ShuttleCommandModeType.PALLET_LIFT.id) {
- // 鎵樼洏椤跺崌
- //鍒ゆ柇鏄惁椤跺崌鍒颁綅
- if (shuttleProtocol.getHasLift()) {
- command.setComplete(true);
- updateCommand = true;
-// //鍒ゆ柇鏄惁鏈夌墿
-// if (shuttleProtocol.getHasPallet()) {
-// command.setComplete(true);
-// }
- }
- } else if (command.getMode() == ShuttleCommandModeType.PALLET_DOWN.id) {
- // 鎵樼洏涓嬮檷鍛戒护
- // 鍒ゆ柇鏄惁涓嬮檷鍒颁綅
- if (!shuttleProtocol.getHasLift()) {
- command.setComplete(true);
- updateCommand = true;
- }
- } else if (command.getMode() == ShuttleCommandModeType.CHARGE_OPEN.id) {
- // 鍏呯數寮�
- //鍒ゆ柇灏忚溅鍏呯數鐘舵��
- if (shuttleProtocol.getHasCharge()) {
- command.setComplete(true);
- updateCommand = true;
- }
- }else {
- command.setComplete(true);//鍏朵粬鍛戒护榛樿璁や负瀹屾垚
- updateCommand = true;
- }
-
- if(updateCommand) {
- // 鏇存柊redis鏁版嵁
- redisUtil.set(RedisKeyType.SHUTTLE_WORK_FLAG.key + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect));
- }
-
- if (!command.getComplete()) {
- return false;
- }
-
- //鍒ゆ柇鏄惁涓烘渶鍚庝竴鏉″懡浠や笖鍛戒护鎵ц瀹屾垚锛屾姏鍑虹瓑寰呯‘璁ょ姸鎬�
- ShuttleCommand endCommand = commands.get(commands.size() - 1);
- if (endCommand.getComplete()) {
- News.info("鍥涘悜绌挎杞︿换鍔℃墽琛屼笅鍙戝畬鎴愮瓑寰呮墽琛岀粨鏉燂紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(commands));
-
- // 绯荤粺浠诲姟
- if (assignCommand.getAuto()) {
- if (!assignCommand.getCharge()) {
- //瀵逛富绾跨▼鎶涘嚭绛夊緟纭鐘舵�亀aiting
- shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
- }else {
- shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
- }
- News.info("鍥涘悜绌挎杞︿换鍔℃墽琛屼笅鍙戝畬鎴愮瓑寰呮墽琛岀粨鏉燂紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
-
- // 鎵嬪姩浠诲姟
- } else {
- //鎵嬪姩妯″紡涓嶆姏鍑虹瓑寰呯姸鎬侊紝鐩存帴澶嶄綅绌洪棽鐘舵��
- shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
- //浠诲姟鍙锋竻闆�
- shuttleThread.setSyncTaskNo(0);
- //鏍囪澶嶄綅
- shuttleThread.setPakMk(true);
- News.info("鍥涘悜绌挎杞︽墜鍔ㄤ换鍔℃墽琛屽畬鎴愶紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
- }
-
- //鍒犻櫎redis
- redisUtil.del(RedisKeyType.SHUTTLE_WORK_FLAG.key + redisCommand.getWrkNo());
- return false;//绂佹鍐嶄笅鍙戝懡浠�
- }
+ int commandStep = redisCommand.getCommandStep();
+ if(commandStep >= commands.size()){
+ return false;
}
//鍙栧嚭鍛戒护
- ShuttleCommand command = commands.get(commandStep);
+ ShuttleCommand command = null;
+ if (checked == 1) {
+ //闈炶繛缁寚浠わ紝闇�瑕佹娴嬩笂涓�鏉℃寚浠ゆ槸鍚﹀畬鎴�
+ if (commandStep > 0) {
+ ShuttleCommand lastCommand = commands.get(commandStep - 1);
+ if (!lastCommand.getComplete()) {
+ return false;//鎸囦护鏈畬鎴�
+ }
+ }
+
+ command = commands.get(commandStep);
+ } else if (checked == 2) {
+ //杩炵画鎸囦护鐩存帴鍙栨暟鎹�
+ command = commands.get(commandStep);
+ }
+
+ if(command == null){
+ return false;
+ }
+
+ //绉诲姩鍛戒护锛岄攣瀹氳矾寰�
+ if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
+ List<NavigateNode> nodes = JSON.parseArray(JSON.toJSONString(command.getNodes()), NavigateNode.class);
+ //鐢宠绠″埗
+ boolean apply = applyTrafficControl(commands, nodes, shuttleNo, taskNo);
+ if(!apply){
+ return false;//鐢宠澶辫触
+ }
+// //妫�娴嬭矾寰勬槸鍚﹀啿绐�
+// int conflict = searchShuttlePathConflict(nodes, shuttleNo);
+// if(conflict == 2){
+// return false;//妫�娴嬪悗鏈夊啿绐�
+// }
+
+ if (checked == 2) {
+ nodes.remove(0);
+ }
+
+ boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(command.getTargetLocNo()), shuttleNo, nodes, true);//閿佸畾璺緞
+ if (!result) {
+ News.error("{} device can't lock path!", shuttleNo);
+ shuttleThread.offerSystemMsg("{} device can't lock path!", shuttleNo);
+ return false;//璺緞閿佸畾澶辫触
+ }
+ }
// 涓嬪彂鍛戒护
CommandResponse response = write(command, shuttleNo);
@@ -273,14 +213,400 @@
}
shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WORKING);
- commandStep++;
+
+ //瀛樺偍涓嬪彂鎸囦护绱㈠紩
+ redisUtil.set(RedisKeyType.SHUTTLE_SEND_COMMAND_INDEX.key + shuttleNo + "_" + taskNo + "_" + commandStep, commandStep);
+
+ commandStep += 1;
//鏇存柊redis鏁版嵁
redisCommand.setCommandStep(commandStep);
+
//浠诲姟鏁版嵁淇濆瓨鍒皉edis
redisUtil.set(RedisKeyType.SHUTTLE_WORK_FLAG.key + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
return true;
}
+ /**
+ * 妫�娴嬪懡浠�
+ * 0:鏈�氳繃 1:閫氳繃 2:閫氳繃涓斿彲鎻愬墠涓嬪彂鎸囦护
+ */
+ private int checkCommand(ShuttleRedisCommand redisCommand, Integer shuttleNo) {
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ if(trafficControlThread == null){
+ return 0;
+ }
+
+ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+ if (shuttleThread == null) {
+ return 0;
+ }
+
+ ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+ if (shuttleProtocol == null) {
+ return 0;
+ }
+
+ int commandStep = redisCommand.getCommandStep();
+ if (commandStep == 0) {
+ return 1;//绗竴鏉″懡浠ゆ棤闇�妫�娴�
+ }
+
+ ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
+ List<ShuttleCommand> commands = assignCommand.getCommands();
+ if (commands.isEmpty()) {
+ return 0;
+ }
+
+ //涓婁竴鏉℃寚浠�
+ String searchKey = RedisKeyType.SHUTTLE_SEND_COMMAND_INDEX.key + shuttleNo + "_" + redisCommand.getWrkNo() + "_";
+ Set<String> keys = redisUtil.searchKeys(searchKey);
+ TreeSet<Integer> treeSet = new TreeSet<>();
+ for (String key : keys) {
+ String[] split = key.split(searchKey);
+ treeSet.add(Integer.parseInt(split[1]));
+ }
+ if (treeSet.isEmpty()) {
+ return 1;
+ }
+
+ String firstKey = searchKey + treeSet.first();
+ Integer lastCommandIdx = (Integer) redisUtil.get(firstKey);
+ ShuttleCommand lastCommand = commands.get(lastCommandIdx);
+ if (!lastCommand.getComplete()) {
+ //妫�娴嬫洿鏂板懡浠ゅ畬鎴�
+ boolean checked = updateCommandComplete(lastCommandIdx, commands, shuttleNo);
+ if (checked) {
+ //鍒犻櫎绱㈠紩
+ redisUtil.del(firstKey);
+
+ // 鏇存柊redis鏁版嵁
+ redisUtil.set(RedisKeyType.SHUTTLE_WORK_FLAG.key + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect));
+ }else {
+ //灏忚溅绉诲姩杩炵画涓嬪彂鎸囦护
+ if (assignCommand.getShuttleMoveCommandsContinuously()) {
+ if (treeSet.size() <= 1) {
+ if(commandStep >= commands.size()) {
+ return 0;
+ }
+
+ //绉诲姩鎸囦护
+ if(lastCommand.getMode() != ShuttleCommandModeType.MOVE.id) {
+ return 0;
+ }
+
+ List<NavigateNode> nodes = lastCommand.getNodes();
+ NavigateNode startNode = nodes.get(0);
+ if (!startNode.getLinePartAllowGo()) {//鐩寸嚎娈甸儴鍒嗭紝鍏佽鐩存帴琛岃蛋
+ return 0;
+ }
+
+ //鐩寸嚎娈垫暟鎹爣璇�
+ Long linePartFlag = startNode.getLinePartFlag();
+
+ //鍙栨寚浠�
+ ShuttleCommand currentCommand = commands.get(commandStep);
+ if(currentCommand.getMode() != ShuttleCommandModeType.MOVE.id) {
+ return 0;
+ }
+
+ List<NavigateNode> currentNodes = currentCommand.getNodes();
+ NavigateNode currentStartNode = currentNodes.get(0);
+ if(!currentStartNode.getLinePartAllowGo()) {//鐩寸嚎娈甸儴鍒嗭紝鍏佽鐩存帴琛岃蛋
+ return 0;
+ }
+
+ if(currentStartNode.getLinePartFlag().equals(linePartFlag)) {
+ //鏁版嵁鏍囪瘑涓�鑷�
+ return 2;//鍏佽灏忚溅绉诲姩杩炵画涓嬪彂鎸囦护
+ }
+
+ }
+ }
+
+ return 0;
+ }
+ }
+
+ //鍒ゆ柇鏄惁涓烘渶鍚庝竴鏉″懡浠や笖鍛戒护鎵ц瀹屾垚锛屾姏鍑虹瓑寰呯‘璁ょ姸鎬�
+ ShuttleCommand endCommand = commands.get(commands.size() - 1);
+ if (endCommand.getComplete()) {
+ News.info("鍥涘悜绌挎杞︿换鍔℃墽琛屼笅鍙戝畬鎴愮瓑寰呮墽琛岀粨鏉燂紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(commands));
+
+ // 绯荤粺浠诲姟
+ if (assignCommand.getAuto()) {
+ if (!assignCommand.getCharge()) {
+ //瀵逛富绾跨▼鎶涘嚭绛夊緟纭鐘舵�亀aiting
+ shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
+ } else {
+ shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
+ }
+ News.info("鍥涘悜绌挎杞︿换鍔℃墽琛屼笅鍙戝畬鎴愮瓑寰呮墽琛岀粨鏉燂紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(endCommand));
+
+ // 鎵嬪姩浠诲姟
+ } else {
+ //鎵嬪姩妯″紡涓嶆姏鍑虹瓑寰呯姸鎬侊紝鐩存帴澶嶄綅绌洪棽鐘舵��
+ shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
+ //浠诲姟鍙锋竻闆�
+ shuttleThread.setSyncTaskNo(0);
+ //鏍囪澶嶄綅
+ shuttleThread.setPakMk(true);
+ News.info("鍥涘悜绌挎杞︽墜鍔ㄤ换鍔℃墽琛屽畬鎴愶紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(endCommand));
+ }
+
+ //鐢宠鍙栨秷绠″埗
+ trafficControlThread.cancelTrafficControl(shuttleNo, shuttleProtocol.getTaskNo());
+ //鍒犻櫎redis
+ redisUtil.del(RedisKeyType.SHUTTLE_WORK_FLAG.key + redisCommand.getWrkNo());
+ return 0;//绂佹鍐嶄笅鍙戝懡浠�
+ }
+
+ return 1;
+ }
+
+ //妫�娴嬫洿鏂板懡浠ゅ畬鎴�
+ private boolean updateCommandComplete(Integer commandIdx, List<ShuttleCommand> commands, Integer shuttleNo) {
+ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+ if (shuttleThread == null) {
+ return false;
+ }
+
+ ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+ if (shuttleProtocol == null) {
+ return false;
+ }
+
+ //鍒ゆ柇璁惧鏄惁绌洪棽
+ boolean deviceIdle = shuttleThread.isDeviceIdle();
+
+ ShuttleCommand command = commands.get(commandIdx);
+ if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
+ // 姝e父绉诲姩
+ List<String> targetPoints = new ArrayList<>();
+
+ //瑙i攣閿佸畾璺緞锛屼笂涓�鏉¤矾寰�
+ List<NavigateNode> nodes = null;
+ try {
+ String nodesStr = objectMapper.writeValueAsString(command.getNodes());
+ nodes = objectMapper.readValue(nodesStr, new TypeReference<List<NavigateNode>>() {
+ });
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ NavigateNode startNode = nodes.get(0);
+ Long linePartFlag = startNode.getLinePartFlag();
+
+ NavigateNode targetNode = nodes.get(nodes.size() - 1);
+ targetPoints.add(targetNode.getX() + "-" + targetNode.getY());
+
+ for (int i = commandIdx + 1; i < commands.size(); i++) {
+ ShuttleCommand nextCommand = commands.get(i);
+ if (nextCommand.getMode() == ShuttleCommandModeType.MOVE.id) {
+ List<NavigateNode> nextCommandNodes = nextCommand.getNodes();
+ NavigateNode nextStartNode = nextCommandNodes.get(0);
+ Long nextLinePartFlag = nextStartNode.getLinePartFlag();
+ if(nextLinePartFlag.equals(linePartFlag)) {
+ for (NavigateNode node : nextCommandNodes) {
+ String key = node.getX() + "-" + node.getY();
+ if(!targetPoints.contains(key)) {
+ targetPoints.add(key);
+ }
+ }
+ }
+ }
+ }
+
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ if (trafficControlThread == null) {
+ return false;
+ }
+
+ TrafficControlDataModel trafficControlDataModel = trafficControlThread.queryTrafficControl(shuttleNo);
+ if (trafficControlDataModel != null) {
+ //鏈夌鍒朵俊鎭紝杩涜妫�娴�
+ if (!trafficControlDataModel.getTaskNo().equals(shuttleProtocol.getTaskNo())) {
+ return false;//浠诲姟涓嶄竴鑷�
+ }
+
+ //妫�娴嬫槸鍚﹀埌缁堢偣
+ List<NavigateNode> totalNodeList = trafficControlDataModel.getTotalNodeList();
+ NavigateNode trafficTargetNode = totalNodeList.get(totalNodeList.size() - 1);
+ String trafficTargetLoc = Utils.getLocNo(trafficTargetNode.getX(), trafficTargetNode.getY(), trafficTargetNode.getZ());
+
+ //鍒ゆ柇灏忚溅鏄惁鍒扮粓鐐�
+ if(shuttleProtocol.getCurrentLocNo().equals(trafficTargetLoc)) {
+ //涓婃姤浜ょ
+ trafficControlThread.trafficReport(command.getNodesDeepCopy(), shuttleNo, shuttleProtocol.getTaskNo());
+ }
+ }
+
+ String currentLocNo = shuttleProtocol.getCurrentLocNo();
+ if (targetPoints.contains(Utils.getRow(currentLocNo) + "-" + Utils.getBay(currentLocNo))) {
+ command.setComplete(true);
+ boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(shuttleProtocol.getCurrentLocNo()), shuttleProtocol.getShuttleNo(), nodes, false);//瑙i攣璺緞
+ if (!result) {
+ return false;//瑙i攣澶辫触
+ }
+ }else {
+ return false;
+ }
+ } else if (command.getMode() == ShuttleCommandModeType.PALLET_LIFT.id) {
+ // 鎵樼洏椤跺崌
+ if (!deviceIdle) {
+ return false;//璁惧涓嶇┖闂�
+ }
+
+ //鍒ゆ柇鏄惁椤跺崌鍒颁綅
+ if (shuttleProtocol.getHasLift()) {
+ command.setComplete(true);
+// //鍒ゆ柇鏄惁鏈夌墿
+// if (shuttleProtocol.getHasPallet()) {
+// command.setComplete(true);
+// }
+ }else {
+ return false;
+ }
+ } else if (command.getMode() == ShuttleCommandModeType.PALLET_DOWN.id) {
+ // 鎵樼洏涓嬮檷鍛戒护
+ if (!deviceIdle) {
+ return false;//璁惧涓嶇┖闂�
+ }
+
+ // 鍒ゆ柇鏄惁涓嬮檷鍒颁綅
+ if (!shuttleProtocol.getHasLift()) {
+ command.setComplete(true);
+ }else {
+ return false;
+ }
+ } else if (command.getMode() == ShuttleCommandModeType.CHARGE_OPEN.id) {
+ // 鍏呯數寮�
+ //鍒ゆ柇灏忚溅鍏呯數鐘舵��
+ if (shuttleProtocol.getHasCharge()) {
+ command.setComplete(true);
+ }else {
+ return false;
+ }
+ } else if (command.getMode() == ShuttleCommandModeType.CHARGE_CLOSE.id) {
+ //鍏抽棴鍏呯數
+ command.setComplete(true);
+ } else {
+ command.setComplete(true);//鍏朵粬鍛戒护榛樿璁や负瀹屾垚
+ }
+
+ return true;
+ }
+
+ //鐢宠绠″埗
+ public boolean applyTrafficControl(List<ShuttleCommand> commands, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
+ TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+ if (trafficControlThread == null) {
+ return false;
+ }
+
+ NavigateNode startNode = nodeList.get(0);
+ Long linePartFlag = startNode.getLinePartFlag();
+
+ List<NavigateNode> totalNodeList = new ArrayList<>();
+ for (ShuttleCommand command : commands) {
+ if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
+ NavigateNode node = command.getNodes().get(0);
+ Long nodeLinePartFlag = node.getLinePartFlag();
+ if (nodeLinePartFlag.equals(linePartFlag)) {
+ List<NavigateNode> deepCopy = command.getNodesDeepCopy();
+ if (deepCopy != null) {
+ totalNodeList.addAll(deepCopy);
+ }
+ }
+ }
+ }
+ return trafficControlThread.applyTrafficControl(totalNodeList, nodeList, shuttleNo, taskNo);
+ }
+
+// /**
+// * 鎼滅储灏忚溅璺緞鏄惁瀛樺湪鍐茬獊
+// * 0:鏈娴� 1:妫�娴嬫棤鍐茬獊 2:妫�娴嬫湁鍐茬獊
+// */
+// public int searchShuttlePathConflict(List<NavigateNode> nodeList, Integer shuttleNo) {
+// ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+// if (shuttleThread == null) {
+// return 0;
+// }
+//
+// ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+// if (shuttleProtocol == null) {
+// return 0;
+// }
+//
+// int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
+//
+// TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
+// if (trafficControlThread == null) {
+// return 2;
+// }
+// HashMap<String, List<Integer>> nodeMap = trafficControlThread.getNodesMapByLev(lev);
+// if (nodeMap == null || nodeMap.isEmpty()) {
+// return 2;
+// }
+//
+// List<String> conflictLocList = new ArrayList<>();
+// for (NavigateNode node : nodeList) {
+// String locNo = Utils.getLocNo(node.getX(), node.getY(), lev);
+// if(!nodeMap.containsKey(locNo)) {
+// return 2;
+// }
+//
+// List<Integer> shuttleNos = nodeMap.get(locNo);
+// if (shuttleNos.size() > 1) {
+// //璺緞瀛樺湪澶氳溅锛屽啿绐�
+// conflictLocList.add(locNo);
+// }
+// }
+//
+// if (conflictLocList.isEmpty()) {
+// //鏃犲啿绐侊紝瑙i櫎浜ら�氱鍒�
+// shuttleThread.setTrafficControl(false, null);
+// return 1;//妫�娴嬪悗鏃犲啿绐�
+// }
+//
+// //璺緞瀛樺湪鍐茬獊锛屾娴嬪彲鎵ц杞﹁締鏄惁涓哄綋鍓嶅皬杞�
+// //涓婃姤灏忚溅鐘舵��-浜ら�氱鍒朵腑
+// shuttleThread.setTrafficControl(true, nodeList);
+//
+// HashMap<String, Integer> deviceMap = trafficControlThread.getDeviceMap();
+// if(deviceMap == null) {
+// return 2;
+// }
+//
+// boolean detected = false;
+//// for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
+//// List<String> mainList = JSON.parseArray(entry.getKey(), String.class);
+//// Integer device = entry.getValue();
+//// if(result) {
+//// //鍒ゆ柇绠″埗杞﹁締鏄惁鍖归厤
+//// if(shuttleNo.equals(device)) {
+//// detected = true;
+//// break;
+//// }
+//// }
+//// }
+//
+// for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
+// String key = entry.getKey();
+// Integer value = entry.getValue();
+// if(shuttleNo.equals(value)) {
+// //鍒ゆ柇绠″埗杞﹁締鏄惁鍖归厤
+// detected = true;
+// break;
+// }
+// }
+//
+// if (detected) {
+// return 1;//妫�娴嬪悗鏃犲啿绐侊紝浜ら�氱鍒跺凡鍏佽姝ゅ皬杞﹁繍琛�
+// }
+//
+// return 2;//妫�娴嬪悗鏈夊啿绐�
+// }
+
//婕旂ず妯″紡
public synchronized void demo(Integer shuttleNo) {
ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
diff --git a/src/main/java/com/zy/core/cache/MessageQueue.java b/src/main/java/com/zy/core/cache/MessageQueue.java
index 4037c4a..9788407 100644
--- a/src/main/java/com/zy/core/cache/MessageQueue.java
+++ b/src/main/java/com/zy/core/cache/MessageQueue.java
@@ -1,6 +1,5 @@
package com.zy.core.cache;
-import com.zy.asrs.entity.DeviceConfig;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.Task;
@@ -22,23 +21,28 @@
private static final Map<Integer, ConcurrentLinkedQueue<Task>> FORK_LIFT_EXCHANGE = new ConcurrentHashMap<>();
//璐у弶鎻愬崌鏈篗aster mq浜ゆ崲鏈�
private static final Map<Integer, ConcurrentLinkedQueue<Task>> FORK_LIFT_MASTER_EXCHANGE = new ConcurrentHashMap<>();
+ //Traffic Control mq浜ゆ崲鏈�
+ private static final Map<Integer, ConcurrentLinkedQueue<Task>> TRAFFIC_CONTROL_EXCHANGE = new ConcurrentHashMap<>();
/**
* mq 浜ゆ崲鏈哄垵濮嬪寲
*/
- public static void init(SlaveType type, DeviceConfig deviceConfig) {
+ public static void init(SlaveType type, Integer id) {
switch (type) {
case Shuttle:
- SHUTTLE_EXCHANGE.put(deviceConfig.getDeviceNo(), new ConcurrentLinkedQueue<>());
+ SHUTTLE_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
break;
case ForkLift:
- FORK_LIFT_EXCHANGE.put(deviceConfig.getDeviceNo(), new ConcurrentLinkedQueue<>());
+ FORK_LIFT_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
break;
case ForkLiftMaster:
- FORK_LIFT_MASTER_EXCHANGE.put(deviceConfig.getDeviceNo(), new ConcurrentLinkedQueue<>());
+ FORK_LIFT_MASTER_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
break;
case Lift:
- LIFT_EXCHANGE.put(deviceConfig.getDeviceNo(), new ConcurrentLinkedQueue<>());
+ LIFT_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
+ break;
+ case TrafficControl:
+ TRAFFIC_CONTROL_EXCHANGE.put(id, new ConcurrentLinkedQueue<>());
break;
default:
break;
@@ -59,6 +63,8 @@
return FORK_LIFT_MASTER_EXCHANGE.get(id).offer(task);
case Lift:
return LIFT_EXCHANGE.get(id).offer(task);
+ case TrafficControl:
+ return TRAFFIC_CONTROL_EXCHANGE.get(id).offer(task);
default:
return false;
}
@@ -78,6 +84,8 @@
return FORK_LIFT_MASTER_EXCHANGE.get(id).poll();
case Lift:
return LIFT_EXCHANGE.get(id).poll();
+ case TrafficControl:
+ return TRAFFIC_CONTROL_EXCHANGE.get(id).poll();
default:
return null;
}
@@ -96,6 +104,8 @@
return FORK_LIFT_MASTER_EXCHANGE.get(id).peek();
case Lift:
return LIFT_EXCHANGE.get(id).peek();
+ case TrafficControl:
+ return TRAFFIC_CONTROL_EXCHANGE.get(id).peek();
default:
return null;
}
@@ -115,6 +125,9 @@
case Lift:
LIFT_EXCHANGE.get(id).clear();
break;
+ case TrafficControl:
+ TRAFFIC_CONTROL_EXCHANGE.get(id).clear();
+ break;
default:
break;
}
diff --git a/src/main/java/com/zy/core/enums/RedisKeyType.java b/src/main/java/com/zy/core/enums/RedisKeyType.java
index da700bd..d6e6650 100644
--- a/src/main/java/com/zy/core/enums/RedisKeyType.java
+++ b/src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -14,6 +14,12 @@
FORK_LIFT_PUT_COMPLETE("fork_lift_put_complete_"),
OUT_TASK_PREVIEW_DISPATCH_FORKLIFT("out_task_preview_dispatch_forklift_"),
+ //灏忚溅涓嬪彂鎸囦护绱㈠紩
+ SHUTTLE_SEND_COMMAND_INDEX("shuttle_send_command_index_"),
+
+ //浠诲姟鍫靛鍙敤璁惧鍦板浘
+ TASK_BLOCK_ENABLE_DEVICE_MAP("task_block_enable_device_map"),
+
//鍦板浘閿佸畾鑺傜偣
LOCK_MAP_NODES("lock_map_nodes_"),
diff --git a/src/main/java/com/zy/core/enums/SlaveType.java b/src/main/java/com/zy/core/enums/SlaveType.java
index 4b65625..0412a07 100644
--- a/src/main/java/com/zy/core/enums/SlaveType.java
+++ b/src/main/java/com/zy/core/enums/SlaveType.java
@@ -6,6 +6,7 @@
Lift,
ForkLift,
ForkLiftMaster,
+ TrafficControl,
;
public static SlaveType findInstance(String s){
diff --git a/src/main/java/com/zy/core/model/TrafficControlDataModel.java b/src/main/java/com/zy/core/model/TrafficControlDataModel.java
new file mode 100644
index 0000000..b73396f
--- /dev/null
+++ b/src/main/java/com/zy/core/model/TrafficControlDataModel.java
@@ -0,0 +1,19 @@
+package com.zy.core.model;
+
+import com.zy.common.model.NavigateNode;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class TrafficControlDataModel {
+
+ private Integer shuttleNo;
+
+ private Integer taskNo;
+
+ private List<NavigateNode> nodeList;
+
+ private List<NavigateNode> totalNodeList;
+
+}
diff --git a/src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java b/src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java
index a64f1c4..841ec12 100644
--- a/src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java
+++ b/src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java
@@ -77,6 +77,9 @@
*/
private List<NavigateNode> nodes;
+ //灏忚溅绉诲姩杩炵画涓嬪彂鎸囦护
+ private Boolean shuttleMoveCommandsContinuously;
+
public List<NavigateNode> getNodesDeepCopy() {
if (this.nodes == null) {
return null;
diff --git a/src/main/java/com/zy/core/model/command/ShuttleCommand.java b/src/main/java/com/zy/core/model/command/ShuttleCommand.java
index a0c8b22..8e420f9 100644
--- a/src/main/java/com/zy/core/model/command/ShuttleCommand.java
+++ b/src/main/java/com/zy/core/model/command/ShuttleCommand.java
@@ -3,6 +3,8 @@
import com.zy.common.model.NavigateNode;
import com.zy.core.enums.ShuttleCommandModeType;
import lombok.Data;
+
+import java.util.ArrayList;
import java.util.List;
/**
@@ -50,7 +52,18 @@
if (this.mode == null) {
return null;
}
-
return ShuttleCommandModeType.get(this.mode).desc;
}
+
+ public List<NavigateNode> getNodesDeepCopy() {
+ if (this.nodes == null) {
+ return null;
+ }
+ List<NavigateNode> navigateNodes = new ArrayList<>();
+ for (NavigateNode node : nodes) {
+ navigateNodes.add(node.clone());
+ }
+ return navigateNodes;
+ }
+
}
diff --git a/src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java b/src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
index a4bf8e0..c4db647 100644
--- a/src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
+++ b/src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
@@ -6,6 +6,7 @@
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.service.BasShuttleErrService;
import com.zy.asrs.service.LocMastService;
+import com.zy.common.model.NavigateNode;
import com.zy.common.utils.RedisUtil;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.ShuttleProtocolStatusType;
@@ -13,6 +14,7 @@
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
+import java.util.List;
/**
* 鍥涘悜绌挎杞�
@@ -184,6 +186,11 @@
private Long lastOnlineTime = System.currentTimeMillis();
/**
+ * 灏忚溅绌洪棽鏃堕棿
+ */
+ private Long idleTime = System.currentTimeMillis();
+
+ /**
* 鎵╁睍瀛楁
*/
private Object extend;
@@ -193,6 +200,16 @@
*/
private String systemMsg;
+ /**
+ * 浜ら�氱鍒�
+ */
+ private Boolean trafficControl = false;
+
+ /**
+ * 浜ら�氱鍒禢odes
+ */
+ private List<NavigateNode> trafficControlNodes = null;
+
public String getProtocolStatus$() {
if (this.protocolStatusType == null) {
return "";
diff --git a/src/main/java/com/zy/core/thread/ShuttleThread.java b/src/main/java/com/zy/core/thread/ShuttleThread.java
index a1444cc..aaa63c0 100644
--- a/src/main/java/com/zy/core/thread/ShuttleThread.java
+++ b/src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -70,6 +70,8 @@
boolean offerSystemMsg(String format, Object... arguments);
+ boolean setTrafficControl(boolean enable, List<NavigateNode> nodeList);
+
void updateDeviceDataLogTime(long time);
JSONObject parseStatusToMsg(ShuttleProtocol shuttleProtocol);
diff --git a/src/main/java/com/zy/core/thread/TrafficControlThread.java b/src/main/java/com/zy/core/thread/TrafficControlThread.java
new file mode 100644
index 0000000..ea0411a
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/TrafficControlThread.java
@@ -0,0 +1,30 @@
+package com.zy.core.thread;
+
+
+import com.zy.common.model.NavigateNode;
+import com.zy.core.ThreadHandler;
+import com.zy.core.model.TrafficControlDataModel;
+
+import java.util.HashMap;
+import java.util.List;
+
+public interface TrafficControlThread extends ThreadHandler {
+
+// boolean getDetecting();
+//
+// void updateDetect();
+//
+// boolean addNodes(Integer shuttleNo, Integer taskNo, List<NavigateNode> nodeList);
+//
+// boolean removeNodes(Integer shuttleNo, Integer taskNo);
+
+ boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo);
+
+ boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo);
+
+ boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo);
+
+ TrafficControlDataModel queryTrafficControl(Integer shuttleNo);
+
+ List<TrafficControlDataModel> getAllTrafficControl();
+}
diff --git a/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java b/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
index 05d895e..2542703 100644
--- a/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
+++ b/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -752,6 +752,9 @@
@Override
public synchronized boolean setProtocolStatus(ShuttleProtocolStatusType status) {
+ if (status.equals(ShuttleProtocolStatusType.IDLE)) {
+ this.shuttleProtocol.setIdleTime(System.currentTimeMillis());
+ }
this.shuttleProtocol.setProtocolStatus(status);
return true;
}
@@ -821,6 +824,13 @@
}
@Override
+ public boolean setTrafficControl(boolean enable, List<NavigateNode> nodeList) {
+ shuttleProtocol.setTrafficControl(enable);
+ shuttleProtocol.setTrafficControlNodes(nodeList);
+ return true;
+ }
+
+ @Override
public void updateDeviceDataLogTime(long time) {
shuttleProtocol.setDeviceDataLog(time);
}
diff --git a/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java b/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
new file mode 100644
index 0000000..40379eb
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -0,0 +1,575 @@
+package com.zy.core.thread.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.core.common.SpringUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.model.NavigateNode;
+import com.zy.common.model.enums.NavigationMapType;
+import com.zy.common.utils.NavigatePositionConvert;
+import com.zy.common.utils.NavigateUtils;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.News;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.model.TrafficControlDataModel;
+import com.zy.core.model.command.ShuttleAssignCommand;
+import com.zy.core.model.command.ShuttleRedisCommand;
+import com.zy.core.model.protocol.ShuttleProtocol;
+import com.zy.core.thread.ShuttleThread;
+import com.zy.core.thread.TrafficControlThread;
+import com.zy.core.utils.TrafficControlUtils;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.function.Function;
+
+public class TrafficControlImplThread implements TrafficControlThread {
+
+ private RedisUtil redisUtil;
+ private boolean detecting = false;
+ private boolean updateDetect = false;
+ private Long detectTime = System.currentTimeMillis();
+ private HashMap<String, Integer> deviceMap = null;
+ private HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = null;
+ private HashMap<String, List<NavigateNode>> taskNodesMap = new HashMap<>();
+ private List<TrafficControlDataModel> trafficControlDataList = new ArrayList<>();
+
+ public TrafficControlImplThread(RedisUtil redisUtil) {
+ this.redisUtil = redisUtil;
+ }
+
+ @Override
+ public void run() {
+// List<Integer> shuttleNoList = new ArrayList<>();
+// while (true) {
+// try {
+// DeviceConfigService deviceConfigService = null;
+// try {
+// deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
+// }catch (Exception e){}
+//
+// if(deviceConfigService == null){
+// continue;
+// }
+//
+// if(shuttleNoList.isEmpty()){
+// List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+// .eq("device_type", String.valueOf(SlaveType.Shuttle)));
+// for (DeviceConfig deviceConfig : shuttleList) {
+// shuttleNoList.add(deviceConfig.getDeviceNo());
+// }
+// }
+//
+// if((updateDetect) || ((System.currentTimeMillis() - detectTime) > 1000 * 2)) {
+// detect(shuttleNoList);
+// }
+// }catch (Exception e){
+// e.printStackTrace();
+// }
+// }
+
+ }
+
+ public synchronized void detect(List<Integer> shuttleNoList) {
+ detecting = true;
+ updateDetect = false;
+ ObjectMapper objectMapper = null;
+ try {
+ objectMapper = SpringUtils.getBean(ObjectMapper.class);
+ }catch (Exception e){}
+
+ if(objectMapper == null){
+ return;
+ }
+
+ HashMap<String, List<NavigateNode>> tmpTaskNodesMap = new HashMap<>();
+ for (Integer shuttleNo : shuttleNoList) {
+ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+ if (shuttleThread == null) {
+ continue;
+ }
+
+ ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+ if (shuttleProtocol == null) {
+ continue;
+ }
+
+ if (shuttleProtocol.getTaskNo() == 0) {
+ continue;
+ }
+
+ if (shuttleProtocol.getCurrentLocNo() == null) {
+ continue;
+ }
+
+ int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
+
+ Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo());
+ if (obj == null) {
+ continue;
+ }
+
+ ShuttleRedisCommand redisCommand = null;
+ try {
+ redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ if (redisCommand == null) {
+ continue;
+ }
+
+ ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
+ if (assignCommand == null) {
+ continue;
+ }
+
+ List<NavigateNode> nodeList = assignCommand.getNodesDeepCopy();
+ if (nodeList == null || nodeList.isEmpty()) {
+ continue;
+ }
+
+ tmpTaskNodesMap.put(shuttleProtocol.getTaskNo() + "-" + shuttleNo, nodeList);
+ }
+ this.taskNodesMap = tmpTaskNodesMap;
+ HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = calcNodeList();
+
+ HashMap<Integer, HashMap<String, List<Integer>>> levBlockMap = new HashMap<>();
+ //杩囨护涓嶉渶瑕佺鍒惰妭鐐�
+ for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levNodesMap.entrySet()) {
+ Integer lev = entry.getKey();
+ HashMap<String, List<Integer>> value = entry.getValue();
+
+ HashMap<String, List<Integer>> blockMap = new HashMap<>();
+ for (Map.Entry<String, List<Integer>> listEntry : value.entrySet()) {
+ String locNo = listEntry.getKey();
+ List<Integer> shuttleNos = listEntry.getValue();
+ if (shuttleNos.size() <= 1) {
+ continue;
+ }
+ blockMap.put(locNo, shuttleNos);
+ }
+
+ levBlockMap.put(lev, blockMap);
+ }
+
+ //璁$畻鍫靛鑼冨洿
+ List<List<String>> allLocList = new ArrayList<>();
+ List<List<Integer>> allDeviceNodes = new ArrayList<>();
+ for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levBlockMap.entrySet()) {
+ Integer lev = entry.getKey();
+ HashMap<String, List<Integer>> nodes = entry.getValue();
+
+ Set<String> sets = new HashSet<>();
+ for (Map.Entry<String, List<Integer>> val : nodes.entrySet()) {
+ String locNo = val.getKey();
+ sets.add(locNo);
+ }
+
+ List<List<String>> locList = TrafficControlUtils.groupNodes(sets);
+ List<List<Integer>> deviceNodes = new ArrayList<>();
+
+ //get devices
+ for (List<String> list : locList) {
+ List<List<Integer>> tmpDeviceNodes = new ArrayList<>();
+ for (String loc : list) {
+ List<Integer> shuttleNos = nodes.get(loc);
+ if(!tmpDeviceNodes.contains(shuttleNos)) {
+ tmpDeviceNodes.add(shuttleNos);
+ }
+ }
+ //鑺傜偣骞堕泦-鑾峰彇鍫靛璁惧缂栧彿
+ List<List<Integer>> deviceList = mergeConnectedComponents(tmpDeviceNodes);
+ deviceNodes.addAll(deviceList);
+ }
+
+ allLocList.addAll(locList);
+ allDeviceNodes.addAll(deviceNodes);
+ }
+
+ System.out.println(JSON.toJSONString(allLocList));
+ System.out.println(JSON.toJSONString(allDeviceNodes));
+// //鍒嗛厤鍫靛鑺傜偣鍙墽琛岃澶�
+// findDeviceByBlockList(allLocList, allDeviceNodes);
+
+ detecting = false;
+ detectTime = System.currentTimeMillis();
+
+ //鍙戝竷鍫靛鑺傜偣鍙敤璁惧缂栧彿
+ redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
+ }
+
+ //鍒嗛厤鍫靛鑺傜偣鍙墽琛岃澶�
+ public void findDeviceByBlockList(List<List<String>> allLocList, List<List<Integer>> blockNodes) {
+ HashMap<String, Integer> map = new HashMap<>();
+ if (deviceMap == null) {
+ Object object = redisUtil.get(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key);
+ if (object != null) {
+ map = (HashMap<String, Integer>) object;
+ }
+ } else {
+ map = deviceMap;
+ }
+
+ HashMap<String, Integer> newMap = new HashMap<>();
+
+ for (int i = 0; i < blockNodes.size(); i++) {
+ List<Integer> blockNode = blockNodes.get(i);
+ List<String> locs = allLocList.get(i);
+
+ String key = JSON.toJSONString(locs);
+
+ Integer value = -1;
+ if (map.containsKey(key)) {
+ value = map.get(key);
+ map.remove(key);
+
+ if (value > 0) {
+ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, value);
+ if (shuttleThread == null) {
+ continue;
+ }
+
+ ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+ if (shuttleProtocol == null) {
+ continue;
+ }
+
+ if (shuttleProtocol.getTaskNo() == 0) {
+ value = searchDevice(locs, blockNode, newMap);
+ }
+
+ if (!shuttleProtocol.getTrafficControl()) {
+ value = searchDevice(locs, blockNode, newMap);
+ }
+ }else {
+ value = searchDevice(locs, blockNode, newMap);
+ }
+ } else {
+ value = searchDevice(locs, blockNode, newMap);
+ }
+ newMap.put(key, value);
+ }
+
+ deviceMap = newMap;
+ //鍙戝竷鍫靛鑺傜偣鍙敤璁惧缂栧彿
+ redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, newMap);
+ }
+
+ public Integer searchDevice(List<String> locs, List<Integer> blockNode, HashMap<String, Integer> deviceMap) {
+ NavigateUtils navigateUtils = null;
+ try {
+ navigateUtils = SpringUtils.getBean(NavigateUtils.class);
+ }catch (Exception e){}
+
+ if(navigateUtils == null){
+ return -1;
+ }
+
+ Integer value = -1;
+ for (Integer shuttleNo : blockNode) {
+ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+ if (shuttleThread == null) {
+ continue;
+ }
+
+ ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+ if (shuttleProtocol == null) {
+ continue;
+ }
+
+ if (!shuttleThread.isDeviceIdle()) {
+ continue;
+ }
+
+ if (shuttleProtocol.getTaskNo() == 0) {
+ continue;
+ }
+
+ if (!shuttleProtocol.getTrafficControl()) {
+ continue;//灏忚溅鏈敵璇蜂氦閫氱鍒�
+ }
+
+ //妫�娴嬪皬杞︽槸鍚﹀凡缁忓垎閰�
+ if (deviceMap.containsValue(shuttleNo)) {
+ continue;
+ }
+
+ List<NavigateNode> trafficControlNodes = shuttleProtocol.getTrafficControlNodes();
+ List<String> trafficControlLocs = new ArrayList<>();
+ for (NavigateNode node : trafficControlNodes) {
+ trafficControlLocs.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
+ }
+
+ //妫�娴嬪綋鍓嶅皬杞﹁妭鐐规槸鍚﹀尮閰嶄氦閫氱鍒惰妭鐐�
+ boolean result = false;
+ for (String loc : locs) {
+ if (trafficControlLocs.contains(loc)) {
+ result = true;
+ break;
+ }
+ }
+
+ if (!result) {
+ continue;
+ }
+
+ //check path
+ String currentLocNo = shuttleProtocol.getCurrentLocNo();
+ for (String loc : locs) {
+ if (loc.equals(currentLocNo)) {
+ continue;
+ }
+ List<NavigateNode> nodeList = navigateUtils.calc(currentLocNo, loc, NavigationMapType.getNormalWithDevice(), Utils.getShuttlePoints(shuttleNo, Utils.getLev(loc)), null);
+ if (nodeList == null) {
+ break;
+ }
+ }
+
+ value = shuttleNo;
+ break;
+ }
+
+ return value;
+ }
+
+ //鑺傜偣骞堕泦
+ public List<List<Integer>> mergeConnectedComponents(List<List<Integer>> lists) {
+ // 1. 鏀堕泦鎵�鏈夊敮涓�鍏冪礌
+ Set<Integer> allElements = new HashSet<>();
+ for (List<Integer> list : lists) {
+ allElements.addAll(list);
+ }
+
+ // 2. 鍒濆鍖栧苟鏌ラ泦
+ Map<Integer, Integer> parent = new HashMap<>();
+ for (Integer element : allElements) {
+ parent.put(element, element);
+ }
+
+ // 3. 瀹氫箟鏌ユ壘鏍硅妭鐐圭殑鍑芥暟锛堝甫璺緞鍘嬬缉锛�
+ Function<Integer, Integer> find = x -> {
+ int root = x;
+ while (parent.get(root) != root) {
+ root = parent.get(root);
+ }
+ // 璺緞鍘嬬缉
+ int current = x;
+ while (parent.get(current) != root) {
+ int next = parent.get(current);
+ parent.put(current, root);
+ current = next;
+ }
+ return root;
+ };
+
+ // 4. 閬嶅巻姣忎釜鍒楄〃骞跺悎骞跺厓绱�
+ for (List<Integer> list : lists) {
+ if (list.isEmpty()) continue;
+ int first = list.get(0);
+ for (int i = 1; i < list.size(); i++) {
+ int a = first;
+ int b = list.get(i);
+ int rootA = find.apply(a);
+ int rootB = find.apply(b);
+ if (rootA != rootB) {
+ parent.put(rootB, rootA); // 鍚堝苟闆嗗悎
+ }
+ }
+ }
+
+ // 5. 鎸夋牴鑺傜偣鍒嗙粍
+ Map<Integer, Set<Integer>> components = new HashMap<>();
+ for (Integer element : allElements) {
+ int root = find.apply(element);
+ components.computeIfAbsent(root, k -> new TreeSet<>()).add(element);
+ }
+
+ // 6. 杞崲涓烘湁搴忓垪琛�
+ List<List<Integer>> result = new ArrayList<>();
+ for (Set<Integer> set : components.values()) {
+ result.add(new ArrayList<>(set));
+ }
+
+ return result;
+ }
+
+ private HashMap<Integer, HashMap<String, List<Integer>>> calcNodeList() {
+ HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = new HashMap<>();
+ for (Map.Entry<String, List<NavigateNode>> entry : taskNodesMap.entrySet()) {
+ String key = entry.getKey();
+ String[] split = key.split("-");
+ Integer taskNo = Integer.parseInt(split[0]);
+ Integer shuttleNo = Integer.parseInt(split[1]);
+
+ List<NavigateNode> nodeList = entry.getValue();
+ NavigateNode node1 = nodeList.get(0);
+ int lev = node1.getZ();
+
+ HashMap<String, List<Integer>> nodeMap = new HashMap<>();
+ if(levNodesMap.containsKey(lev)) {
+ nodeMap = levNodesMap.get(lev);
+ }
+
+ for (NavigateNode node : nodeList) {
+ String locNo = Utils.getLocNo(node.getX(), node.getY(), lev);
+ List<Integer> shuttleNos = new ArrayList<>();
+ if (nodeMap.containsKey(locNo)) {
+ shuttleNos = nodeMap.get(locNo);
+ }
+
+ if (!shuttleNos.contains(shuttleNo)) {
+ shuttleNos.add(shuttleNo);
+ }
+ nodeMap.put(locNo, shuttleNos);
+ }
+ levNodesMap.put(lev, nodeMap);
+ }
+ this.levNodesMap = levNodesMap;
+ return levNodesMap;
+ }
+
+ @Override
+ public synchronized boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
+ //鍙戝竷鍫靛鑺傜偣鍙敤璁惧缂栧彿
+ redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
+ //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+ for (int i = 0; i < trafficControlDataList.size(); i++) {
+ TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
+ if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
+ //瀛樺湪绠″埗
+ if(!controlDataModel.getTaskNo().equals(taskNo)) {
+ return false;
+ }
+
+ //浠诲姟鎬绘暟閲忎笉涓�鑷�
+ if (totalNodeList.size() != controlDataModel.getTotalNodeList().size()) {
+ return false;
+ }
+
+ int startIdx = 0;
+ int targetIdx = totalNodeList.size() - 1;
+ NavigateNode applyStartNode = totalNodeList.get(startIdx);
+ NavigateNode applyTargetNode = totalNodeList.get(targetIdx);
+
+ NavigateNode controlStartNode = controlDataModel.getTotalNodeList().get(startIdx);
+ NavigateNode controlTargetNode = controlDataModel.getTotalNodeList().get(targetIdx);
+
+ //璧风偣涓嶅悓
+ if(!NavigatePositionConvert.equalsNode(applyStartNode, controlStartNode)) {
+ return false;
+ }
+
+ //缁堢偣涓嶅悓
+ if(!NavigatePositionConvert.equalsNode(applyTargetNode, controlTargetNode)) {
+ return false;
+ }
+
+ News.info("traffic running {},{}", shuttleNo, taskNo);
+ return true;//宸茬粡绠″埗鍏佽鎵ц
+ }
+ }
+
+ NavigateNode startNode = totalNodeList.get(0);
+ List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ());
+
+ List<String> shuttleLocList = new ArrayList<>();
+ for (int[] shuttlePoint : shuttlePoints) {
+ String locNo = Utils.getLocNo(shuttlePoint[0], shuttlePoint[1], startNode.getZ());
+ shuttleLocList.add(locNo);
+ }
+
+ for (NavigateNode node : totalNodeList) {
+ String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
+ if(shuttleLocList.contains(locNo)) {
+ return false;//node has shuttle
+ }
+ }
+
+ //妫�娴嬭妭鐐规槸鍚﹁浣跨敤
+ for (TrafficControlDataModel controlDataModel : trafficControlDataList) {
+ List<NavigateNode> list = controlDataModel.getTotalNodeList();
+ for (NavigateNode node1 : list) {
+ for (NavigateNode node2 : totalNodeList) {
+ if (NavigatePositionConvert.equalsNode(node1, node2)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ //浜ょ鎺ユ敹
+ TrafficControlDataModel model = new TrafficControlDataModel();
+ model.setShuttleNo(shuttleNo);
+ model.setTaskNo(taskNo);
+ model.setNodeList(nodeList);
+ model.setTotalNodeList(totalNodeList);
+ trafficControlDataList.add(model);
+ News.info("receipt traffic {},{}", shuttleNo, taskNo);
+ return true;
+ }
+
+ @Override
+ public boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
+ //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+ for (int i = 0; i < trafficControlDataList.size(); i++) {
+ TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
+ if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
+ if(controlDataModel.getTaskNo().equals(taskNo)) {
+ List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
+ totalNodeList.removeAll(nodeList);
+ controlDataModel.setTotalNodeList(totalNodeList);
+ trafficControlDataList.set(i, controlDataModel);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public synchronized boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo) {
+ //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+ for (int i = 0; i < trafficControlDataList.size(); i++) {
+ TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
+ if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
+ if(controlDataModel.getTaskNo().equals(taskNo)) {
+ trafficControlDataList.remove(i);//鍙栨秷绠″埗
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) {
+ //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+ for (int i = 0; i < trafficControlDataList.size(); i++) {
+ TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
+ if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
+ return controlDataModel;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<TrafficControlDataModel> getAllTrafficControl() {
+ return trafficControlDataList;
+ }
+
+ @Override
+ public boolean connect() {
+ return false;
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+}
diff --git a/src/main/java/com/zy/core/utils/TrafficControlUtils.java b/src/main/java/com/zy/core/utils/TrafficControlUtils.java
new file mode 100644
index 0000000..d67e225
--- /dev/null
+++ b/src/main/java/com/zy/core/utils/TrafficControlUtils.java
@@ -0,0 +1,81 @@
+package com.zy.core.utils;
+
+import java.util.*;
+
+public class TrafficControlUtils {
+
+ public static List<List<String>> groupNodes(Collection<String> keys) {
+ // 1. 鎸変綅缃仛绫伙細Map<浣嶇疆閿�, 鑺傜偣鍒楄〃>
+ Map<String, List<String>> clusterMap = new HashMap<>();
+ for (String key : keys) {
+ String rowStr = key.substring(0, 2);
+ String colStr = key.substring(2, 5);
+ String posKey = rowStr + "_" + colStr; // 浣嶇疆閿牸寮�: "RR_CCC"
+ clusterMap.computeIfAbsent(posKey, k -> new ArrayList<>()).add(key);
+ }
+
+ // 2. 鍒濆鍖栧苟鏌ラ泦
+ Map<String, String> parentMap = new HashMap<>();
+ Map<String, Integer> rankMap = new HashMap<>();
+ for (String posKey : clusterMap.keySet()) {
+ parentMap.put(posKey, posKey); // 鍒濆鐖惰妭鐐规寚鍚戣嚜宸�
+ rankMap.put(posKey, 0);
+ }
+
+ // 3. 閬嶅巻鎵�鏈変綅缃敭锛屽悎骞剁浉閭荤皣
+ for (String posKey : clusterMap.keySet()) {
+ String[] parts = posKey.split("_");
+ int row = Integer.parseInt(parts[0]);
+ int col = Integer.parseInt(parts[1]);
+
+ // 妫�鏌ュ洓涓柟鍚戯細宸︺�佸彸銆佷笂銆佷笅
+ int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // {dRow, dCol}
+ for (int[] dir : directions) {
+ int newRow = row + dir[0];
+ int newCol = col + dir[1];
+ String neighborKey = String.format("%02d_%03d", newRow, newCol);
+
+ if (parentMap.containsKey(neighborKey)) {
+ union(posKey, neighborKey, parentMap, rankMap);
+ }
+ }
+ }
+
+ // 4. 鐢熸垚鍒嗙粍缁撴灉
+ Map<String, List<String>> groupMap = new HashMap<>();
+ for (String posKey : clusterMap.keySet()) {
+ String root = find(posKey, parentMap);
+ groupMap.computeIfAbsent(root, k -> new ArrayList<>())
+ .addAll(clusterMap.get(posKey));
+ }
+
+ return new ArrayList<>(groupMap.values());
+ }
+
+ // 骞舵煡闆嗭細鏌ユ壘鏍硅妭鐐癸紙甯﹁矾寰勫帇缂╋級
+ private static String find(String x, Map<String, String> parentMap) {
+ if (!parentMap.get(x).equals(x)) {
+ parentMap.put(x, find(parentMap.get(x), parentMap));
+ }
+ return parentMap.get(x);
+ }
+
+ // 骞舵煡闆嗭細鎸夌З鍚堝苟
+ private static void union(String x, String y, Map<String, String> parentMap, Map<String, Integer> rankMap) {
+ String rootX = find(x, parentMap);
+ String rootY = find(y, parentMap);
+ if (rootX.equals(rootY)) return;
+
+ int rankX = rankMap.get(rootX);
+ int rankY = rankMap.get(rootY);
+ if (rankX < rankY) {
+ parentMap.put(rootX, rootY);
+ } else if (rankX > rankY) {
+ parentMap.put(rootY, rootX);
+ } else {
+ parentMap.put(rootY, rootX);
+ rankMap.put(rootX, rankX + 1);
+ }
+ }
+
+}
--
Gitblit v1.9.1