From 658bdc3e3cb251e7c49aaf1f03300d976804b85a Mon Sep 17 00:00:00 2001 From: luoyifan Date: Mon, 30 Jun 2025 20:49:28 +0800 Subject: [PATCH] =?UTF-8?q?Charger=20=E5=85=85=E7=94=B5API=20=E5=B7=B2?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/f1.json | 562 ++++++++++++++++++--- .../com/galaxis/rcs/plan/PlanTaskSequence.java | 9 + .../com/galaxis/rcs/plan/path/PtrPathPlanner.java | 44 +- .../com/galaxis/rcs/plan/task/ChargerTask.java | 3 +- .../com/yvan/logisticsModel/LogisticsRuntime.java | 50 +- .../yvan/workbench/controller/RcsController.java | 16 +- .../test/java/com/yvan/workbench/CodegenTest.java | 6 +- 7 files changed, 608 insertions(+), 82 deletions(-) diff --git a/examples/f1.json b/examples/f1.json index fcf20fd..0d15afb 100644 --- a/examples/f1.json +++ b/examples/f1.json @@ -16,7 +16,7 @@ ], [ 2.2, - 2.8, + 1.211, 1 ] ], @@ -34,23 +34,25 @@ { "bayWidth": 1.1, "levelHeight": [ - 1.4, - 1.4 - ] + 0.001, + 1.21 + ], + "topHeight": 2 }, { "bayWidth": 1.1, "levelHeight": [ - 1.4, - 1.4 - ] + 0.001, + 1.21 + ], + "topHeight": 2 } ], "center": [], "in": [], "out": [], "rackWidth": 2.2, - "rackHeight": 2.8 + "rackHeight": 1.211 }, "_rid": "_2" }, @@ -71,7 +73,7 @@ ], [ 2.2, - 2.8, + 2.186, 1 ] ], @@ -89,28 +91,59 @@ { "bayWidth": 1.1, "levelHeight": [ - 1.4, - 1.4 - ] + 0.001, + 2.185 + ], + "topHeight": 2 }, { "bayWidth": 1.1, "levelHeight": [ - 1.4, - 1.4 - ] + 0.001, + 2.185 + ], + "topHeight": 2 } ], "center": [], "in": [], "out": [], "rackWidth": 2.2, - "rackHeight": 2.8 + "rackHeight": 2.186 }, "_rid": "_3" }, { - "id": "1_2", + "id": "105_105", + "t": "gstore", + "v": true, + "tf": [ + [ + 4.44, + 0, + 1.5 + ], + [ + 0, + 0, + 0 + ], + [ + 1, + 0.01, + 1.2 + ] + ], + "dt": { + "in": [], + "out": [], + "center": [], + "strokeWidth": 0.1 + }, + "_rid": "_4" + }, + { + "id": "6_4", "t": "way", "v": true, "logicX": 1, @@ -134,10 +167,10 @@ ], "dt": { "in": [ - "2_2" + "7_4" ], "out": [ - "2_2" + "7_4" ], "center": [], "linkStore": [ @@ -157,10 +190,10 @@ } ] }, - "_rid": "_4" + "_rid": "_5" }, { - "id": "2_2", + "id": "7_4", "t": "way", "v": true, "logicX": 2, @@ -184,12 +217,12 @@ ], "dt": { "in": [ - "1_2", - "3_2" + "6_4", + "8_4" ], "out": [ - "1_2", - "3_2" + "6_4", + "8_4" ], "center": [], "linkStore": [ @@ -209,10 +242,10 @@ } ] }, - "_rid": "_5" + "_rid": "_6" }, { - "id": "3_2", + "id": "8_4", "t": "way", "v": true, "logicX": 3, @@ -236,12 +269,12 @@ ], "dt": { "in": [ - "2_2", - "4_2" + "7_4", + "9_4" ], "out": [ - "2_2", - "4_2" + "7_4", + "9_4" ], "center": [], "linkStore": [ @@ -261,10 +294,10 @@ } ] }, - "_rid": "_6" + "_rid": "_7" }, { - "id": "4_2", + "id": "9_4", "t": "way", "v": true, "logicX": 4, @@ -288,12 +321,12 @@ ], "dt": { "in": [ - "3_2", - "5_2" + "8_4", + "10_4" ], "out": [ - "3_2", - "5_2" + "8_4", + "10_4" ], "center": [], "linkStore": [ @@ -310,13 +343,20 @@ "level": 1, "cell": 0, "direction": "up" + }, + { + "item": "105_105", + "bay": 0, + "level": 0, + "cell": 0, + "direction": "down" } ] }, - "_rid": "_7" + "_rid": "_8" }, { - "id": "5_2", + "id": "10_4", "t": "way", "v": true, "logicX": 5, @@ -340,19 +380,19 @@ ], "dt": { "in": [ - "4_2", - "6_2" + "9_4", + "11_4" ], "out": [ - "4_2", - "6_2" + "9_4", + "11_4" ], "center": [] }, - "_rid": "_8" + "_rid": "_9" }, { - "id": "6_2", + "id": "11_4", "t": "way", "v": true, "logicX": 6, @@ -376,10 +416,12 @@ ], "dt": { "in": [ - "5_2" + "10_4", + "charger1" ], "out": [ - "5_2" + "10_4", + "charger1" ], "center": [], "agvRotation": [ @@ -387,16 +429,61 @@ "clx" ] }, - "_rid": "_9" + "_rid": "_10" }, { - "id": "3", - "t": "cl2", + "id": "5_4", + "t": "way", "v": true, + "logicX": 5, + "logicY": 4, "tf": [ [ - 6.440, + -0.29, + 0.01, + 0 + ], + [ 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "4_4" + ], + "out": [ + "4_4" + ], + "center": [], + "linkStore": [ + { + "item": "rack3", + "bay": 1, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_11" + }, + { + "id": "4_4", + "t": "way", + "v": true, + "logicX": 4, + "logicY": 4, + "tf": [ + [ + -1.39, + 0.01, 0 ], [ @@ -405,18 +492,377 @@ 0 ], [ - 1.5, - 1.98, - 1.5 + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "5_4", + "3_4" + ], + "out": [ + "5_4", + "3_4" + ], + "center": [], + "linkStore": [ + { + "item": "rack3", + "bay": 0, + "level": 1, + "cell": 0, + "direction": "up" + } + ] + }, + "_rid": "_12" + }, + { + "id": "3_4", + "t": "way", + "v": true, + "logicX": 3, + "logicY": 4, + "tf": [ + [ + -2.34, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "4_4", + "2_4" + ], + "out": [ + "4_4", + "2_4" + ], + "center": [] + }, + "_rid": "_13" + }, + { + "id": "2_4", + "t": "way", + "v": true, + "logicX": 2, + "logicY": 4, + "tf": [ + [ + -3.34, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "1_4", + "3_4" + ], + "out": [ + "1_4", + "3_4" + ], + "center": [] + }, + "_rid": "_14" + }, + { + "id": "1_4", + "t": "way", + "v": true, + "logicX": 1, + "logicY": 4, + "tf": [ + [ + -4.34, + 0.01, + 0 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "2_4", + "1_3" + ], + "out": [ + "2_4", + "1_3" + ], + "center": [], + "agvRotation": [ + "cl2", + "clx" + ] + }, + "_rid": "_15" + }, + { + "id": "1_3", + "t": "way", + "v": true, + "logicX": 1, + "logicY": 3, + "tf": [ + [ + -4.34, + 0.01, + -1 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "1_4", + "1_2" + ], + "out": [ + "1_4", + "1_2" + ], + "center": [], + "linkStore": [ + { + "item": "108_108", + "bay": 0, + "level": 0, + "cell": 0, + "direction": "left" + } + ] + }, + "_rid": "_16" + }, + { + "id": "1_2", + "t": "way", + "v": true, + "logicX": 1, + "logicY": 2, + "tf": [ + [ + -4.34, + 0.01, + -2 + ], + [ + 0, + 0, + 0 + ], + [ + 0.25, + 0.1, + 0.25 + ] + ], + "dt": { + "in": [ + "1_3", + "charger2" + ], + "out": [ + "1_3", + "charger2" + ], + "center": [] + }, + "_rid": "_17" + }, + { + "id": "charger2", + "t": "charger", + "v": true, + "tf": [ + [ + -4.34, + 0.01, + -2.4 + ], + [ + 0, + 180, + 0 + ], + [ + 0.6, + 1, + 0.3 + ] + ], + "dt": { + "in": [ + "1_2" + ], + "out": [ + "1_2" + ], + "center": [], + "isCharger": true, + "chargerPortDirection": "down" + }, + "_rid": "_18" + }, + { + "id": "charger1", + "t": "charger", + "v": true, + "tf": [ + [ + 6.84, + 0.01, + 0 + ], + [ + 0, + 90, + 0 + ], + [ + 0.6, + 1, + 0.3 + ] + ], + "dt": { + "in": [ + "11_4" + ], + "out": [ + "11_4" + ], + "center": [], + "chargerPortDirection": "left" + }, + "_rid": "_19" + }, + { + "id": "rack3", + "t": "rack", + "v": true, + "tf": [ + [ + -0.82, + 0, + -1.5 + ], + [ + 0, + 0, + 0 + ], + [ + 2.2, + 2.186, + 1 + ] + ], + "dt": { + "rackDepth": 1, + "bottomBarHeight": 0.2, + "bottomLinkHeight": 0.2, + "topLinkDistance": 0.2, + "levelCount": 2, + "bayCount": 2, + "hideFloor": 0, + "extendColumns": 1, + "columnSpacing": 1, + "bays": [ + { + "bayWidth": 1.1, + "levelHeight": [ + 0.001, + 2.185 + ], + "topHeight": 2 + }, + { + "bayWidth": 1.1, + "levelHeight": [ + 0.001, + 2.185 + ], + "topHeight": 2 + } + ], + "center": [], + "in": [], + "out": [], + "rackWidth": 2.2, + "rackHeight": 2.186 + }, + "_rid": "_20" + }, + { + "id": "108_108", + "t": "gstore", + "v": true, + "tf": [ + [ + -6, + 0, + -1 + ], + [ + 0, + -90, + 0 + ], + [ + 1, + 0.01, + 1.2 ] ], "dt": { "in": [], "out": [], "center": [], - "ptrWidth": 1.5, - "ptrDepth": 1.5, - "ptrHeight": 1.98 - } + "strokeWidth": 0.1 + }, + "_rid": "_21" } ] diff --git a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java index e17c822..b26a8cb 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/PlanTaskSequence.java @@ -74,6 +74,12 @@ public class PlanTaskSequence { return task; } + public RcsTaskPlan addChargerBackward(String chargerId) { + RcsTaskPlan task = this.createTaskPlanEntity(PlanTaskType.CHARGE.toString()); + task.setTargetId(chargerId); + return task; + } + // 添加旋转动作 public RcsTaskPlan addRotationTo(float rotationAngle) { RcsTaskPlan task = this.createTaskPlanEntity(PlanTaskType.ROTATION.toString()); @@ -129,6 +135,9 @@ public class PlanTaskSequence { case MOVE_BACKWARD: taskStr = "MOVE_BACKWARD " + task.getTargetId(); break; + case CHARGE: + taskStr = "CHARGE " + task.getTargetId(); + break; case LOAD: taskStr = "LOAD " + task.getTargetId() + "_" + task.getTargetBay() + "_" + task.getTargetLevel() + "_" + task.getTargetCell(); break; diff --git a/servo/src/main/java/com/galaxis/rcs/plan/path/PtrPathPlanner.java b/servo/src/main/java/com/galaxis/rcs/plan/path/PtrPathPlanner.java index 0508c57..17f2cb4 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/path/PtrPathPlanner.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/path/PtrPathPlanner.java @@ -3,6 +3,9 @@ package com.galaxis.rcs.plan.path; import com.galaxis.rcs.common.enums.LCCDirection; import com.galaxis.rcs.plan.PlanTaskSequence; import com.galaxis.rcs.plan.task.*; +import com.google.common.base.Strings; +import com.yvan.logisticsModel.StaticItem; +import org.clever.core.Conv; import java.util.List; @@ -17,8 +20,47 @@ public class PtrPathPlanner { this.astar = new AStarPathPlanner(graph); } - public void planChargerTask(PlanTaskSequence planSequence, String id, LCCDirection fromDirection, ChargerTask chargerTask) { + public void planChargerTask(PlanTaskSequence plan, String startNodeId, LCCDirection startDirection, ChargerTask chargerTask) { + /* + { + "id": "charger1", + "t": "way", + "dt": { + "in": [ + "11_4" + ], + "out": [ + "11_4" + ], + "center": [], + "chargerPortDirection": "left" + }, + } + */ + // 获取充电器的 in:[] 第一个值作为移动目标, chargerPortDirection 作为目标方向 + StaticItem chargerPoint = plan.logisticsRuntime.getStaticItemById(chargerTask.chargerPointId()); + if (chargerPoint == null) { + throw new RuntimeException("Charger point not found for id: " + chargerTask.chargerPointId()); + } + List inList = (List) chargerPoint.dt.get("in"); + if (inList == null || inList.isEmpty()) { + throw new RuntimeException("Charger point 'in' list is empty for id: " + chargerTask.chargerPointId()); + } + String chargerPortDirection = Conv.asString(chargerPoint.dt.get("chargerPortDirection")); + if (Strings.isNullOrEmpty(chargerPortDirection)) { + throw new RuntimeException("Charger point 'chargerPortDirection' is empty for id: " + chargerTask.chargerPointId()); + } + LCCDirection chargerDirection = LCCDirection.fromString(chargerPortDirection); + Node node = this.graph.getNodeById(inList.get(0)); + if (node == null) { + throw new RuntimeException("Charger point 'dt.in[0]', Node not found, id: " + inList.get(0)); + } + + List toPath = astar.findPath(startNodeId, startDirection, node.id(), chargerDirection); + generateMoves(plan, toPath); + plan.addChargerBackward(chargerTask.chargerPointId()); + plan.addFinish(); } public void planMoveTask(PlanTaskSequence plan, String startNodeId, LCCDirection startDirection, MoveTask moveTask) { diff --git a/servo/src/main/java/com/galaxis/rcs/plan/task/ChargerTask.java b/servo/src/main/java/com/galaxis/rcs/plan/task/ChargerTask.java index ca5a008..e008e1a 100644 --- a/servo/src/main/java/com/galaxis/rcs/plan/task/ChargerTask.java +++ b/servo/src/main/java/com/galaxis/rcs/plan/task/ChargerTask.java @@ -4,6 +4,5 @@ import com.galaxis.rcs.common.enums.LCCDirection; public record ChargerTask( String agv, - String targetWayPointId, - LCCDirection targetDirection) { + String chargerPointId) { } diff --git a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java index 7ee40f4..5c88674 100644 --- a/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java +++ b/servo/src/main/java/com/yvan/logisticsModel/LogisticsRuntime.java @@ -1,8 +1,10 @@ package com.yvan.logisticsModel; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.galaxis.rcs.common.enums.LCCDirection; import com.galaxis.rcs.connector.cl2.Cl2Item; import com.galaxis.rcs.plan.path.NavigationGraph; +import com.galaxis.rcs.plan.path.PathUtils; import com.galaxis.rcs.plan.path.PtrPathPlanner; import com.galaxis.rcs.ptr.AgvEventManager; import com.galaxis.rcs.ptr.AmrMessageHandler; @@ -154,6 +156,7 @@ public class LogisticsRuntime { case "way": case "gstore": case "rack": + case "charger": item = new StaticItem(this, itemObject); floor.itemMap.put(item.getId(), (StaticItem) item); break; @@ -185,6 +188,7 @@ public class LogisticsRuntime { .fetch(); for (var item : list) { + // 车的属性 String payload = Conv.asString(item.get("virtual_executor_payload")); /** * { @@ -199,13 +203,47 @@ public class LogisticsRuntime { * } */ JsonWrapper jwPayload = new JsonWrapper(payload); - if ("cl2".equals(jwPayload.asStr("t"))) { - var eitem = new Cl2Item(this, (Map) jwPayload.getInnerMap()); - this.executorItemMap.put(eitem.getId(), eitem); - } else if ("clx".equals(jwPayload.asStr("t"))) { - var eitem = new Cl2Item(this, (Map) jwPayload.getInnerMap()); - this.executorItemMap.put(eitem.getId(), eitem); + switch (jwPayload.asStr("t")) { + case "cl2": + case "clx": + // 处理 CL2 或 CLX 类型的执行器 + // 车所在的标记位置,及方向 11_4:RIGHT + if (Conv.asString(item.get("virtual_location_at")).contains(":")) { + String[] parts = Conv.asString(item.get("virtual_location_at")).split(":"); + if (parts.length == 2) { + String wayPointId = parts[0]; + String direction = parts[1]; + var eitem = new Cl2Item(this, (Map) jwPayload.getInnerMap()); + + // 找到地标位置 + StaticItem staticItem = this.getStaticItemById(wayPointId); + if (staticItem != null) { + eitem.logicX = staticItem.logicX; + eitem.logicY = staticItem.logicY; + eitem.direction = PathUtils.convertDirectionToPtrDiretion(LCCDirection.fromString(direction)); + this.executorItemMap.put(eitem.getId(), eitem); + + } else { + log.warn("Static item not found for wayPointId: {}", wayPointId); + continue; // 跳过未找到的地标 + } + + + } else { + log.warn("Invalid virtual_location_at format: {}, id:{}", item.get("virtual_location_at"), item.get("id")); + continue; + } + + } else { + log.warn("Invalid virtual_location_at is null, id:{}", item.get("id")); + continue; + } + + break; + default: + log.warn("Unknown executor type: {}", jwPayload.asStr("t")); + continue; // 跳过未知类型 } } } diff --git a/servo/src/main/java/com/yvan/workbench/controller/RcsController.java b/servo/src/main/java/com/yvan/workbench/controller/RcsController.java index 9cde244..b5542f6 100644 --- a/servo/src/main/java/com/yvan/workbench/controller/RcsController.java +++ b/servo/src/main/java/com/yvan/workbench/controller/RcsController.java @@ -28,24 +28,20 @@ public class RcsController { } RcsCommonParam ps = (RcsCommonParam) ret; - String targetWayPointId = Conv.asString(params.get("targetWayPointId")); - if (Strings.isNullOrEmpty(targetWayPointId)) { - return Model.newFail("targetWayPointId Must not be empty"); - } - String targetDirection = Conv.asString(params.get("targetDirection")); - if (Strings.isNullOrEmpty(targetDirection)) { - targetDirection = ps.fromDirection.toString(); + String chargerId = Conv.asString(params.get("chargerId")); + if (Strings.isNullOrEmpty(chargerId)) { + return Model.newFail("chargerId Must not be empty"); } - StaticItem toItem = ps.runtime.getStaticItemById(targetWayPointId); + StaticItem toItem = ps.runtime.getStaticItemById(chargerId); if (toItem == null) { return Model.newFail("target wayPoint not found!"); } - ps.bizTask.setTaskTo(targetWayPointId); + ps.bizTask.setTaskTo(chargerId); ChargerTask chargerTask = new ChargerTask( - ps.agvId, ps.bizTask.getTaskTo(), LCCDirection.fromString(targetDirection, ps.fromDirection) + ps.agvId, ps.bizTask.getTaskTo() ); ps.runtime.pathPlannerMap.get(ps.agv.getT()) diff --git a/servo/src/test/java/com/yvan/workbench/CodegenTest.java b/servo/src/test/java/com/yvan/workbench/CodegenTest.java index 7e6db41..25dace3 100644 --- a/servo/src/test/java/com/yvan/workbench/CodegenTest.java +++ b/servo/src/test/java/com/yvan/workbench/CodegenTest.java @@ -29,11 +29,7 @@ public class CodegenTest { // .addTable("rcs_task_biz") // .addTable("rcs_task_device") // .addTable("rcs_task_plan"); - .addTable("lcc_bas_container") - .addTable("lcc_bas_executor") - .addTable("lcc_bas_location") - .addTable("lcc_inv_lpn") - .addTable("lcc_inv_ledger"); + .addTable("lcc_bas_location"); CodegenUtils.genCode(jdbc, config); log.info("-->"); jdbc.close();