7 changed files with 179 additions and 1 deletions
@ -0,0 +1,38 @@ |
|||||
|
package com.galaxis.rcs.common.enums; |
||||
|
|
||||
|
/** |
||||
|
* 路径点与货位 / 充电器关联记录 |
||||
|
*/ |
||||
|
public enum LCCDirection { |
||||
|
/** |
||||
|
* 上方 / z负方向 / up / 北 |
||||
|
*/ |
||||
|
UP, |
||||
|
/** |
||||
|
* 下方 / z正方向 / down / 南 |
||||
|
*/ |
||||
|
DOWN, |
||||
|
|
||||
|
/** |
||||
|
* 左方 / x负方向 / left / 西 |
||||
|
*/ |
||||
|
LEFT, |
||||
|
|
||||
|
/** |
||||
|
* 右方 / x正方向 / right / 东 |
||||
|
*/ |
||||
|
RIGHT; |
||||
|
|
||||
|
public static LCCDirection fromString(String value) { |
||||
|
if (value == null) |
||||
|
throw new IllegalArgumentException("Value cannot be null"); |
||||
|
|
||||
|
for (LCCDirection type : LCCDirection.values()) { |
||||
|
if (type.toString().equalsIgnoreCase(value.trim())) { |
||||
|
return type; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
throw new IllegalArgumentException("No constant with name: " + value); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
package com.galaxis.rcs.plan.path2; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public class AGVPathPlanner { |
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
package com.galaxis.rcs.plan.path2; |
||||
|
|
||||
|
import com.galaxis.rcs.common.enums.LCCDirection; |
||||
|
import com.yvan.logisticsModel.LogisticsRuntime; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* A* 导航图 |
||||
|
*/ |
||||
|
public class NavigationGraph { |
||||
|
private final Map<String, Node> nodeMap = new HashMap<>(); |
||||
|
private final Map<String, List<String>> storeToNodes = new HashMap<>(); |
||||
|
|
||||
|
public NavigationGraph() { |
||||
|
} |
||||
|
|
||||
|
// private void initialize(LogisticsRuntime runtime) {
|
||||
|
// var items = runtime.getStaticItems();
|
||||
|
// for (Map<String, Object> item : items) {
|
||||
|
// String type = (String) item.get("t");
|
||||
|
// if ("way".equals(type)) {
|
||||
|
// float[][] tf = (float[][]) item.get("tf");
|
||||
|
// String id = (String) item.get("id");
|
||||
|
// Map<String, Object> dt = (Map<String, Object>) item.get("dt");
|
||||
|
//
|
||||
|
// // 提取坐标
|
||||
|
// float x = tf[0][0];
|
||||
|
// float z = tf[0][2]; // Z向下增长
|
||||
|
//
|
||||
|
// // 检查可旋转性
|
||||
|
// boolean rotatable = dt.containsKey("agvRotation");
|
||||
|
//
|
||||
|
// // 提取邻居节点
|
||||
|
// List<String> in = (List<String>) dt.get("in");
|
||||
|
// List<String> out = (List<String>) dt.get("out");
|
||||
|
// Set<String> neighbors = new HashSet<>();
|
||||
|
// if (in != null) neighbors.addAll(in);
|
||||
|
// if (out != null) neighbors.addAll(out);
|
||||
|
//
|
||||
|
// // 提取货位链接
|
||||
|
// List<StoreLink> storeLinks = new ArrayList<>();
|
||||
|
// List<Map<String, Object>> links = (List<Map<String, Object>>) dt.get("linkStore");
|
||||
|
// if (links != null) {
|
||||
|
// for (Map<String, Object> link : links) {
|
||||
|
// String storeId = (String) link.get("item");
|
||||
|
// int bay = (Integer) link.get("bay");
|
||||
|
// int level = (Integer) link.get("level");
|
||||
|
// int cell = (Integer) link.get("cell");
|
||||
|
// String direction = (String) link.get("direction");
|
||||
|
// storeLinks.add(new StoreLink(storeId, bay, level, cell, LCCDirection.fromString(direction)));
|
||||
|
//
|
||||
|
// // 建立货位到节点的反向映射
|
||||
|
// storeToNodes.computeIfAbsent(storeId, k -> new ArrayList<>()).add(id);
|
||||
|
// }
|
||||
|
// }
|
||||
|
//
|
||||
|
// nodeMap.put(id, new Node(id, x, z, rotatable,
|
||||
|
// new ArrayList<>(neighbors), storeLinks));
|
||||
|
// }
|
||||
|
// }
|
||||
|
//
|
||||
|
// // 2. 验证邻居双向连接
|
||||
|
// for (Node node : nodeMap.values()) {
|
||||
|
// Iterator<String> it = node.neighbors().iterator();
|
||||
|
// while (it.hasNext()) {
|
||||
|
// String neighborId = it.next();
|
||||
|
// if (!nodeMap.containsKey(neighborId)) {
|
||||
|
// it.remove(); // 移除无效邻居
|
||||
|
// }
|
||||
|
// }
|
||||
|
// }
|
||||
|
// }
|
||||
|
|
||||
|
public Node getNode(String id) { |
||||
|
return nodeMap.get(id); |
||||
|
} |
||||
|
|
||||
|
public List<String> getNodesForStore(String storeId) { |
||||
|
return storeToNodes.getOrDefault(storeId, Collections.emptyList()); |
||||
|
} |
||||
|
|
||||
|
public List<Node> getNeighbors(Node node) { |
||||
|
return node.neighbors().stream() |
||||
|
.map(nodeMap::get) |
||||
|
.filter(Objects::nonNull) |
||||
|
.toList(); |
||||
|
} |
||||
|
|
||||
|
public float distance(Node a, Node b) { |
||||
|
float dx = a.x() - b.x(); |
||||
|
float dz = a.z() - b.z(); |
||||
|
return (float) Math.sqrt(dx * dx + dz * dz); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package com.galaxis.rcs.plan.path2; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 路径节点定义 |
||||
|
* |
||||
|
* @param id 节点ID |
||||
|
* @param x 节点X坐标 |
||||
|
* @param z 节点Z坐标 |
||||
|
* @param rotatable 节点是否可旋转 |
||||
|
* @param neighbors 邻居节点ID列表 |
||||
|
*/ |
||||
|
public record Node(String id, |
||||
|
float x, |
||||
|
float z, |
||||
|
boolean rotatable, |
||||
|
List<String> neighbors, |
||||
|
List<StoreLink> storeLinks) { |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
package com.galaxis.rcs.plan.path2; |
||||
|
|
||||
|
import com.galaxis.rcs.common.enums.LCCDirection; |
||||
|
|
||||
|
public record StoreLink( |
||||
|
String storeId, int bay, int level, int cell, LCCDirection direction |
||||
|
) { |
||||
|
} |
||||
Loading…
Reference in new issue