38 changed files with 1018 additions and 165 deletions
@ -0,0 +1,30 @@ |
|||||
|
package com.galaxis.rcs.common.entity; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* (lcc_env_info) |
||||
|
*/ |
||||
|
@Data |
||||
|
public class LccEnvInfo implements Serializable { |
||||
|
/** 环境ID */ |
||||
|
private Long envId; |
||||
|
/** 世界地图ID */ |
||||
|
private String worldId; |
||||
|
/** 环境名称 */ |
||||
|
private String envName; |
||||
|
/** 是否虚拟环境 */ |
||||
|
private Boolean isVirtual; |
||||
|
/** 环境负载信息 */ |
||||
|
private String envPayload; |
||||
|
/** 创建时间 */ |
||||
|
private Date createAt; |
||||
|
/** 创建人 */ |
||||
|
private String createBy; |
||||
|
/** 更新时间 */ |
||||
|
private Date updateAt; |
||||
|
/** 更新人 */ |
||||
|
private String updateBy; |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
package com.galaxis.rcs.common.enums; |
||||
|
|
||||
|
public enum BizTaskStatus { |
||||
|
/** |
||||
|
* 待调度 |
||||
|
*/ |
||||
|
WAITING_FOR_DISPATCH, |
||||
|
|
||||
|
/** |
||||
|
* 设备执行中 |
||||
|
*/ |
||||
|
DEVICE_EXECUTING, |
||||
|
|
||||
|
/** |
||||
|
* 暂停执行 |
||||
|
*/ |
||||
|
PAUSED, |
||||
|
|
||||
|
/** |
||||
|
* 调度异常 |
||||
|
*/ |
||||
|
DISPATCH_ERROR, |
||||
|
|
||||
|
/** |
||||
|
* 规划异常 |
||||
|
*/ |
||||
|
PLANNING_ERROR, |
||||
|
|
||||
|
/** |
||||
|
* 设备执行异常 |
||||
|
*/ |
||||
|
DEVICE_ERROR; |
||||
|
|
||||
|
public static BizTaskStatus fromString(String value) { |
||||
|
if (value == null) |
||||
|
throw new IllegalArgumentException("Value cannot be null"); |
||||
|
|
||||
|
for (BizTaskStatus type : BizTaskStatus.values()) { |
||||
|
if (type.toString().equalsIgnoreCase(value.trim())) { |
||||
|
return type; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
throw new IllegalArgumentException("No constant with name: " + value); |
||||
|
} |
||||
|
} |
||||
@ -1,5 +1,18 @@ |
|||||
package com.galaxis.rcs.common.enums; |
package com.galaxis.rcs.common.enums; |
||||
|
|
||||
public enum BizTaskType { |
public enum BizTaskType { |
||||
CARRY, // 搬运任务
|
CARRY; // 搬运任务
|
||||
|
|
||||
|
public static BizTaskType fromString(String value) { |
||||
|
if (value == null) |
||||
|
throw new IllegalArgumentException("Value cannot be null"); |
||||
|
|
||||
|
for (BizTaskType type : BizTaskType.values()) { |
||||
|
if (type.toString().equalsIgnoreCase(value.trim())) { |
||||
|
return type; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
throw new IllegalArgumentException("No constant with name: " + value); |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,26 @@ |
|||||
|
package com.galaxis.rcs.common.enums; |
||||
|
|
||||
|
/** |
||||
|
* 表示货位 与 路标点, 在世界坐标中的相对位置关系 |
||||
|
*/ |
||||
|
public enum OperationSide { |
||||
|
/** |
||||
|
* 货位在路标点的上方 |
||||
|
*/ |
||||
|
TOP, |
||||
|
|
||||
|
/** |
||||
|
* 货位在路标点的下方 |
||||
|
*/ |
||||
|
BOTTOM, |
||||
|
|
||||
|
/** |
||||
|
* 货位在路标点的左侧 |
||||
|
*/ |
||||
|
LEFT, |
||||
|
|
||||
|
/** |
||||
|
* 货位在路标点的右侧 |
||||
|
*/ |
||||
|
RIGHT |
||||
|
} |
||||
@ -0,0 +1,74 @@ |
|||||
|
package com.galaxis.rcs.common.query; |
||||
|
|
||||
|
import static com.querydsl.core.types.PathMetadataFactory.*; |
||||
|
import com.querydsl.core.types.dsl.*; |
||||
|
import com.querydsl.core.types.*; |
||||
|
import com.querydsl.sql.*; |
||||
|
import java.sql.Types; |
||||
|
import com.galaxis.rcs.common.entity.LccEnvInfo; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* (lcc_env_info) |
||||
|
*/ |
||||
|
@SuppressWarnings("ALL") |
||||
|
public class QLccEnvInfo extends RelationalPathBase<LccEnvInfo> { |
||||
|
/** lcc_env_info表 */ |
||||
|
public static final QLccEnvInfo lccEnvInfo = new QLccEnvInfo("lcc_env_info"); |
||||
|
|
||||
|
/** 环境ID */ |
||||
|
public final NumberPath<Long> envId = createNumber("envId", Long.class); |
||||
|
/** 世界地图ID */ |
||||
|
public final StringPath worldId = createString("worldId"); |
||||
|
/** 环境名称 */ |
||||
|
public final StringPath envName = createString("envName"); |
||||
|
/** 是否虚拟环境 */ |
||||
|
public final BooleanPath isVirtual = createBoolean("isVirtual"); |
||||
|
/** 环境负载信息 */ |
||||
|
public final StringPath envPayload = createString("envPayload"); |
||||
|
/** 创建时间 */ |
||||
|
public final DateTimePath<Date> createAt = createDateTime("createAt", Date.class); |
||||
|
/** 创建人 */ |
||||
|
public final StringPath createBy = createString("createBy"); |
||||
|
/** 更新时间 */ |
||||
|
public final DateTimePath<Date> updateAt = createDateTime("updateAt", Date.class); |
||||
|
/** 更新人 */ |
||||
|
public final StringPath updateBy = createString("updateBy"); |
||||
|
|
||||
|
public QLccEnvInfo(String variable) { |
||||
|
super(LccEnvInfo.class, forVariable(variable), "rcs2_tw_zhanghui", "lcc_env_info"); |
||||
|
addMetadata(); |
||||
|
} |
||||
|
|
||||
|
public QLccEnvInfo(String variable, String schema, String table) { |
||||
|
super(LccEnvInfo.class, forVariable(variable), schema, table); |
||||
|
addMetadata(); |
||||
|
} |
||||
|
|
||||
|
public QLccEnvInfo(String variable, String schema) { |
||||
|
super(LccEnvInfo.class, forVariable(variable), schema, "lcc_env_info"); |
||||
|
addMetadata(); |
||||
|
} |
||||
|
|
||||
|
public QLccEnvInfo(Path<? extends LccEnvInfo> path) { |
||||
|
super(path.getType(), path.getMetadata(), "rcs2_tw_zhanghui", "lcc_env_info"); |
||||
|
addMetadata(); |
||||
|
} |
||||
|
|
||||
|
public QLccEnvInfo(PathMetadata metadata) { |
||||
|
super(LccEnvInfo.class, metadata, "rcs2_tw_zhanghui", "lcc_env_info"); |
||||
|
addMetadata(); |
||||
|
} |
||||
|
|
||||
|
private void addMetadata() { |
||||
|
addMetadata(envId, ColumnMetadata.named("env_id").withIndex(1).ofType(Types.BIGINT).withSize(19)); |
||||
|
addMetadata(worldId, ColumnMetadata.named("world_id").withIndex(2).ofType(Types.VARCHAR).withSize(50)); |
||||
|
addMetadata(envName, ColumnMetadata.named("env_name").withIndex(3).ofType(Types.VARCHAR).withSize(50)); |
||||
|
addMetadata(isVirtual, ColumnMetadata.named("is_virtual").withIndex(4).ofType(Types.BIT).withSize(3)); |
||||
|
addMetadata(envPayload, ColumnMetadata.named("env_payload").withIndex(5).ofType(Types.VARCHAR).withSize(3000)); |
||||
|
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(6).ofType(Types.TIMESTAMP)); |
||||
|
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(7).ofType(Types.VARCHAR).withSize(50)); |
||||
|
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(8).ofType(Types.TIMESTAMP)); |
||||
|
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(9).ofType(Types.VARCHAR).withSize(50)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
/** |
||||
|
* A*路径节点状态 |
||||
|
*/ |
||||
|
public record AStarNodeState( |
||||
|
String nodeId, // 当前节点ID
|
||||
|
int direction, // 当前方向 (0,90,180,270)
|
||||
|
float gCost, // 实际代价
|
||||
|
float hCost, // 启发式代价
|
||||
|
AStarNodeState parent // 父节点
|
||||
|
) implements Comparable<AStarNodeState> { |
||||
|
|
||||
|
// 状态唯一标识
|
||||
|
public String stateKey() { |
||||
|
return nodeId + ":" + direction; |
||||
|
} |
||||
|
|
||||
|
// 总代价
|
||||
|
public float fCost() { |
||||
|
return gCost + hCost; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int compareTo(AStarNodeState other) { |
||||
|
return Float.compare(this.fCost(), other.fCost()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,122 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* A*路径规划器 |
||||
|
*/ |
||||
|
public class AStarPathPlanner { |
||||
|
private final NavigationGraph graph; |
||||
|
|
||||
|
public AStarPathPlanner(NavigationGraph graph) { |
||||
|
this.graph = graph; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 规划路径 |
||||
|
* |
||||
|
* @param startNodeId 起始节点ID |
||||
|
* @param startDirection 起始方向 |
||||
|
* @param endNodeId 目标节点ID |
||||
|
* @param endDirection 目标方向 |
||||
|
* @return 路径节点序列 (包含方向信息) |
||||
|
*/ |
||||
|
public List<AStarNodeState> planPath(String startNodeId, int startDirection, String endNodeId, int endDirection) { |
||||
|
// 开放集 (优先队列)
|
||||
|
PriorityQueue<AStarNodeState> openSet = new PriorityQueue<>(); |
||||
|
|
||||
|
// 状态管理
|
||||
|
Map<String, Float> gScoreMap = new HashMap<>(); |
||||
|
Map<String, AStarNodeState> cameFrom = new HashMap<>(); |
||||
|
|
||||
|
// 初始化起点
|
||||
|
AStarNodeState start = new AStarNodeState( |
||||
|
startNodeId, |
||||
|
startDirection, |
||||
|
0, |
||||
|
graph.heuristicCost(startNodeId, endNodeId), |
||||
|
null |
||||
|
); |
||||
|
|
||||
|
openSet.add(start); |
||||
|
gScoreMap.put(start.stateKey(), 0.0f); |
||||
|
|
||||
|
while (!openSet.isEmpty()) { |
||||
|
AStarNodeState current = openSet.poll(); |
||||
|
|
||||
|
// 到达目标状态
|
||||
|
if (current.nodeId().equals(endNodeId) && |
||||
|
current.direction() == endDirection) { |
||||
|
return reconstructPath(cameFrom, current); |
||||
|
} |
||||
|
|
||||
|
// 处理移动操作 (到相邻节点)
|
||||
|
for (NavigationNode neighbor : graph.getAdjacentNodes(current.nodeId())) { |
||||
|
PathSegment segment = graph.getPathSegment(current.nodeId(), neighbor.id()); |
||||
|
if (segment == null) continue; |
||||
|
|
||||
|
float moveCost = segment.distance(); |
||||
|
float tentativeGCost = current.gCost() + moveCost; |
||||
|
String neighborKey = neighbor.id() + ":" + current.direction(); |
||||
|
|
||||
|
// 发现更好路径
|
||||
|
if (tentativeGCost < gScoreMap.getOrDefault(neighborKey, Float.MAX_VALUE)) { |
||||
|
AStarNodeState neighborState = new AStarNodeState( |
||||
|
neighbor.id(), |
||||
|
current.direction(), |
||||
|
tentativeGCost, |
||||
|
graph.heuristicCost(neighbor.id(), endNodeId), |
||||
|
current |
||||
|
); |
||||
|
|
||||
|
cameFrom.put(neighborKey, current); |
||||
|
gScoreMap.put(neighborKey, tentativeGCost); |
||||
|
openSet.add(neighborState); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 处理旋转操作 (当前节点可旋转时)
|
||||
|
NavigationNode currentNode = graph.nodes.get(current.nodeId()); |
||||
|
if (currentNode != null && currentNode.rotatable()) { |
||||
|
for (int rotation : new int[]{90, -90}) { |
||||
|
int newDirection = (current.direction() + rotation + 360) % 360; |
||||
|
float rotateCost = 1.0f; // 旋转代价
|
||||
|
float tentativeGCost = current.gCost() + rotateCost; |
||||
|
String rotatedKey = current.nodeId() + ":" + newDirection; |
||||
|
|
||||
|
// 发现更好路径
|
||||
|
if (tentativeGCost < gScoreMap.getOrDefault(rotatedKey, Float.MAX_VALUE)) { |
||||
|
AStarNodeState rotatedState = new AStarNodeState( |
||||
|
current.nodeId(), |
||||
|
newDirection, |
||||
|
tentativeGCost, |
||||
|
current.hCost(), // 旋转不改变位置,启发值不变
|
||||
|
current |
||||
|
); |
||||
|
|
||||
|
cameFrom.put(rotatedKey, current); |
||||
|
gScoreMap.put(rotatedKey, tentativeGCost); |
||||
|
openSet.add(rotatedState); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return Collections.emptyList(); // 未找到路径
|
||||
|
} |
||||
|
|
||||
|
private List<AStarNodeState> reconstructPath( |
||||
|
Map<String, AStarNodeState> cameFrom, |
||||
|
AStarNodeState endState |
||||
|
) { |
||||
|
LinkedList<AStarNodeState> path = new LinkedList<>(); |
||||
|
AStarNodeState current = endState; |
||||
|
|
||||
|
while (current != null) { |
||||
|
path.addFirst(current); |
||||
|
current = cameFrom.get(current.stateKey()); |
||||
|
} |
||||
|
|
||||
|
return path; |
||||
|
} |
||||
|
} |
||||
@ -1,4 +0,0 @@ |
|||||
package com.galaxis.rcs.plan.path; |
|
||||
|
|
||||
public class ChargerPoint { |
|
||||
} |
|
||||
@ -0,0 +1,95 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
import com.galaxis.rcs.common.enums.OperationSide; |
||||
|
import com.yvan.logisticsModel.LogisticsRuntime; |
||||
|
import org.clever.core.Conv; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class GraphInitializer { |
||||
|
|
||||
|
public NavigationGraph initializeGraph(LogisticsRuntime runtime, String agvType, List<Map<String, Object>> jsonData) { |
||||
|
if (runtime.executorGraphMap.containsKey(agvType)) { |
||||
|
return runtime.executorGraphMap.get(agvType); |
||||
|
} |
||||
|
NavigationGraph graph = new NavigationGraph(); |
||||
|
runtime.executorGraphMap.put(agvType, graph); |
||||
|
|
||||
|
// 第一步:创建所有节点
|
||||
|
for (Map<String, Object> nodeData : jsonData) { |
||||
|
String id = (String) nodeData.get("id"); |
||||
|
|
||||
|
// 判断是否是 way 类型才创建 NavigationNode
|
||||
|
if (!"way".equals(nodeData.get("t"))) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
List<List<Float>> tf = (List<List<Float>>) nodeData.get("tf"); |
||||
|
float x = tf.get(0).get(0); |
||||
|
float z = tf.get(0).get(2); |
||||
|
|
||||
|
// 检查是否为可旋转点
|
||||
|
Map<String, Object> dt = (Map<String, Object>) nodeData.get("dt"); |
||||
|
boolean rotatable = false; |
||||
|
if (dt.containsKey("agvRotation")) { |
||||
|
rotatable = true; |
||||
|
} |
||||
|
|
||||
|
// 添加节点
|
||||
|
graph.addNode(new NavigationNode(id, x, z, rotatable)); |
||||
|
} |
||||
|
|
||||
|
// 第二步:添加路径连接
|
||||
|
for (Map<String, Object> nodeData : jsonData) { |
||||
|
if (!"way".equals(nodeData.get("t"))) continue; |
||||
|
|
||||
|
String id = (String) nodeData.get("id"); |
||||
|
Map<String, Object> dt = (Map<String, Object>) nodeData.get("dt"); |
||||
|
|
||||
|
List<String> outEdges = (List<String>) dt.get("out"); |
||||
|
if (outEdges != null) { |
||||
|
for (String neighborId : outEdges) { |
||||
|
if (graph.nodes.containsKey(id) && graph.nodes.containsKey(neighborId)) { |
||||
|
NavigationNode from = graph.nodes.get(id); |
||||
|
NavigationNode to = graph.nodes.get(neighborId); |
||||
|
graph.addBidirectionalPath(from, to); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 第三步:添加操作点 OperationPoint
|
||||
|
for (Map<String, Object> nodeData : jsonData) { |
||||
|
if (!"way".equals(nodeData.get("t"))) continue; |
||||
|
|
||||
|
String nodeId = (String) nodeData.get("id"); |
||||
|
Map<String, Object> dt = (Map<String, Object>) nodeData.get("dt"); |
||||
|
|
||||
|
if (dt.containsKey("linkStore")) { |
||||
|
List<Map<String, Object>> linkStores = (List<Map<String, Object>>) dt.get("linkStore"); |
||||
|
for (Map<String, Object> store : linkStores) { |
||||
|
String targetId = (String) store.get("item"); |
||||
|
Integer bay = Conv.asInteger(store.get("bay")); |
||||
|
Integer level = Conv.asInteger(store.get("level")); |
||||
|
Integer cell = Conv.asInteger(store.get("cell")); |
||||
|
|
||||
|
// 根据位置确定方位(这里假设固定为 TOP,可根据 tf 中的方向判断更精确)
|
||||
|
OperationSide side = OperationSide.TOP; |
||||
|
|
||||
|
OperationPoint point = new OperationPoint( |
||||
|
graph.nodes.get(nodeId), |
||||
|
targetId, |
||||
|
side, |
||||
|
bay, |
||||
|
level, |
||||
|
cell |
||||
|
); |
||||
|
graph.addOperationPoint(point); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return graph; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
import java.util.*; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
|
||||
|
/** |
||||
|
* 导航图管理器 |
||||
|
*/ |
||||
|
public class NavigationGraph { |
||||
|
final Map<String, NavigationNode> nodes = new ConcurrentHashMap<>(); |
||||
|
final Map<String, OperationPoint> operationPoints = new ConcurrentHashMap<>(); |
||||
|
final Map<String, PathSegment> pathSegments = new ConcurrentHashMap<>(); |
||||
|
final Map<String, List<NavigationNode>> adjacencyList = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
// 添加节点
|
||||
|
public void addNode(NavigationNode node) { |
||||
|
nodes.put(node.id(), node); |
||||
|
adjacencyList.put(node.id(), new ArrayList<>()); |
||||
|
} |
||||
|
|
||||
|
// 添加双向路径
|
||||
|
public void addBidirectionalPath(NavigationNode a, NavigationNode b) { |
||||
|
float distance = a.distanceTo(b); |
||||
|
pathSegments.put(a.id() + "->" + b.id(), new PathSegment(a, b, distance)); |
||||
|
pathSegments.put(b.id() + "->" + a.id(), new PathSegment(b, a, distance)); |
||||
|
|
||||
|
adjacencyList.get(a.id()).add(b); |
||||
|
adjacencyList.get(b.id()).add(a); |
||||
|
} |
||||
|
|
||||
|
// 添加操作点
|
||||
|
public void addOperationPoint(OperationPoint point) { |
||||
|
operationPoints.put(point.locationKey(), point); |
||||
|
} |
||||
|
|
||||
|
// 查找操作点
|
||||
|
public OperationPoint findOperationPoint(String locationKey) { |
||||
|
return operationPoints.get(locationKey); |
||||
|
} |
||||
|
|
||||
|
// 获取路径段
|
||||
|
public PathSegment getPathSegment(String startId, String endId) { |
||||
|
return pathSegments.get(startId + "->" + endId); |
||||
|
} |
||||
|
|
||||
|
// 获取相邻节点
|
||||
|
public List<NavigationNode> getAdjacentNodes(String nodeId) { |
||||
|
return adjacencyList.getOrDefault(nodeId, Collections.emptyList()); |
||||
|
} |
||||
|
|
||||
|
// 获取最近的旋转点
|
||||
|
public NavigationNode findNearestRotationPoint(String startId) { |
||||
|
NavigationNode start = nodes.get(startId); |
||||
|
if (start == null) return null; |
||||
|
|
||||
|
return nodes.values().parallelStream() |
||||
|
.filter(NavigationNode::rotatable) |
||||
|
.min(Comparator.comparing(start::distanceTo)) |
||||
|
.orElse(null); |
||||
|
} |
||||
|
|
||||
|
// 计算启发式代价 (使用欧几里得距离)
|
||||
|
public float heuristicCost(String fromId, String toId) { |
||||
|
NavigationNode from = nodes.get(fromId); |
||||
|
NavigationNode to = nodes.get(toId); |
||||
|
if (from == null || to == null) return Float.MAX_VALUE; |
||||
|
return from.distanceTo(to); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
import org.clever.core.Conv; |
||||
|
|
||||
|
/** |
||||
|
* 路标节点(地图中的顶点) |
||||
|
*/ |
||||
|
public record NavigationNode( |
||||
|
String id, // 节点ID (如 "20", "charger1")
|
||||
|
float x, // 向右增长
|
||||
|
float z, // 向下增长 (y无效)
|
||||
|
boolean rotatable // 是否为可旋转位
|
||||
|
) implements Comparable<NavigationNode> { |
||||
|
// 计算到另一个节点的欧几里得距离
|
||||
|
public float distanceTo(NavigationNode other) { |
||||
|
float dx = this.x - other.x; |
||||
|
float dz = this.z - other.z; |
||||
|
return Conv.asFloat(Math.sqrt(dx * dx + dz * dz)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int compareTo(NavigationNode other) { |
||||
|
return this.id.compareTo(other.id); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
import com.galaxis.rcs.common.enums.OperationSide; |
||||
|
|
||||
|
/** |
||||
|
* 操作位置(取货/放货/充电点) |
||||
|
*/ |
||||
|
public record OperationPoint( |
||||
|
NavigationNode node, // 关联的路标节点
|
||||
|
String targetId, // 货位ID (如 "54") 或货架ID (如 "rack1")
|
||||
|
OperationSide side, // 方位
|
||||
|
Integer bay, // 列 (货架时非空)
|
||||
|
Integer level, // 层 (货架时非空)
|
||||
|
Integer cell // 格 (货架时非空)
|
||||
|
) { |
||||
|
// 计算操作所需方向
|
||||
|
public int requiredDirection() { |
||||
|
return switch (side) { |
||||
|
case LEFT -> 90; |
||||
|
case RIGHT -> 270; |
||||
|
case TOP -> 0; |
||||
|
case BOTTOM -> 180; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
// 位置唯一标识
|
||||
|
public String locationKey() { |
||||
|
if (bay == null || level == null || cell == null) { |
||||
|
return targetId; // 地堆货位
|
||||
|
} |
||||
|
return targetId + "-" + bay + "-" + level + "-" + cell; |
||||
|
} |
||||
|
} |
||||
@ -1,7 +0,0 @@ |
|||||
package com.galaxis.rcs.plan.path; |
|
||||
|
|
||||
/** |
|
||||
* 物流任务路径信息管理类 |
|
||||
*/ |
|
||||
public class PathInfoManager { |
|
||||
} |
|
||||
@ -0,0 +1,15 @@ |
|||||
|
package com.galaxis.rcs.plan.path; |
||||
|
|
||||
|
/** |
||||
|
* 路径段(节点之间的连接) |
||||
|
*/ |
||||
|
public record PathSegment( |
||||
|
NavigationNode start, // 起点节点
|
||||
|
NavigationNode end, // 终点节点
|
||||
|
float distance // 路径距离
|
||||
|
) { |
||||
|
// 路径唯一标识
|
||||
|
public String key() { |
||||
|
return start.id() + "->" + end.id(); |
||||
|
} |
||||
|
} |
||||
@ -1,4 +0,0 @@ |
|||||
package com.galaxis.rcs.plan.path; |
|
||||
|
|
||||
public class Point { |
|
||||
} |
|
||||
@ -1,4 +0,0 @@ |
|||||
package com.galaxis.rcs.plan.path; |
|
||||
|
|
||||
public class StorePoint { |
|
||||
} |
|
||||
@ -1,4 +0,0 @@ |
|||||
package com.galaxis.rcs.plan.path; |
|
||||
|
|
||||
public class WayPoint { |
|
||||
} |
|
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.yvan.workbench.controller; |
||||
|
|
||||
|
import com.yvan.workbench.model.entity.Model; |
||||
|
import org.clever.core.Conv; |
||||
|
import org.clever.core.json.JsonWrapper; |
||||
|
import org.clever.data.jdbc.DaoFactory; |
||||
|
import org.clever.data.jdbc.QueryDSL; |
||||
|
import org.clever.data.jdbc.querydsl.utils.QueryDslUtils; |
||||
|
import org.clever.web.mvc.annotation.RequestBody; |
||||
|
import org.springframework.data.redis.core.query.QueryUtils; |
||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
|
||||
|
import java.util.LinkedHashMap; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import static com.galaxis.rcs.common.query.QLccEnvInfo.lccEnvInfo; |
||||
|
|
||||
|
public class EnvController { |
||||
|
static final QueryDSL queryDSL = DaoFactory.getQueryDSL(); |
||||
|
|
||||
|
@ResponseBody |
||||
|
public static Model<List<LinkedHashMap<String, Object>>> getAllEnv(@RequestBody Map<String, Object> params) { |
||||
|
var list = queryDSL.select(QueryDslUtils.linkedMap(lccEnvInfo)) |
||||
|
.from(lccEnvInfo) |
||||
|
.where(lccEnvInfo.worldId.eq(Conv.asString(params.get("worldId")))) |
||||
|
.fetch(); |
||||
|
|
||||
|
return Model.newSuccess(list); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
package com.yvan.workbench.model.entity; |
||||
|
|
||||
|
public class Model<T> implements java.io.Serializable { |
||||
|
private boolean success = false; |
||||
|
private T data; |
||||
|
private String msg = ""; |
||||
|
|
||||
|
public static <T> Model<T> newSuccess(T data) { |
||||
|
return new Model<T>().setData(data).setSuccess(true).setMsg("操作成功"); |
||||
|
} |
||||
|
|
||||
|
public T getData() { |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
public Model<T> setData(T data) { |
||||
|
this.data = data; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public String getMsg() { |
||||
|
return msg; |
||||
|
} |
||||
|
|
||||
|
public Model<T> setMsg(String msg) { |
||||
|
this.msg = msg; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public boolean isSuccess() { |
||||
|
return success; |
||||
|
} |
||||
|
|
||||
|
public Model<T> setSuccess(boolean success) { |
||||
|
this.success = success; |
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue