From dc0fb19555dc01bf873361c9cb6fc22fbfc9671d Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 23 十二月 2025 17:50:13 +0800
Subject: [PATCH] 异形无障碍坐标规划优化
---
src/zhangaiwu/AddDikuai.java | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 155 insertions(+), 14 deletions(-)
diff --git a/src/zhangaiwu/AddDikuai.java b/src/zhangaiwu/AddDikuai.java
index 52de9ce..65e96d6 100644
--- a/src/zhangaiwu/AddDikuai.java
+++ b/src/zhangaiwu/AddDikuai.java
@@ -24,6 +24,9 @@
import dikuai.Gecaoanquanjuli;
import bianjie.Bianjieyouhuatoxy;
import lujing.Lunjingguihua;
+import lujing.Qufenxingzhuang;
+import lujing.AoxinglujingNoObstacle;
+import lujing.YixinglujingNoObstacle;
import set.Setsys;
import ui.UIConfig;
import zhuye.MowerLocationData;
@@ -1345,15 +1348,34 @@
showStep(2);
return;
}
- Dikuai dikuai = getOrCreatePendingDikuai();
+ // 浠庢楠�2鐨勮竟鐣屽潗鏍囨枃鏈煙鑾峰彇杈圭晫鍧愭爣
String boundaryCoords = null;
- if (dikuai != null) {
- boundaryCoords = normalizeCoordinateValue(dikuai.getBoundaryCoordinates());
+ if (boundaryXYTextArea != null) {
+ String boundaryText = boundaryXYTextArea.getText();
+ if (boundaryText != null && !boundaryText.trim().isEmpty() && !boundaryText.startsWith("ERROR")) {
+ boundaryCoords = boundaryText.trim();
+ }
}
- if (boundaryCoords == null) {
+
+ // 濡傛灉鏂囨湰鍩熶腑娌℃湁锛屽皾璇曚粠dikuaiData鑾峰彇
+ if (boundaryCoords == null || boundaryCoords.isEmpty()) {
+ boundaryCoords = normalizeCoordinateValue(dikuaiData.get("optimizedBoundaryXY"));
+ }
+
+ // 濡傛灉杩樻槸娌℃湁锛屽皾璇曚粠Dikuai瀵硅薄鑾峰彇
+ if (boundaryCoords == null || boundaryCoords.isEmpty()) {
+ Dikuai dikuai = getOrCreatePendingDikuai();
+ if (dikuai != null) {
+ boundaryCoords = normalizeCoordinateValue(dikuai.getBoundaryCoordinates());
+ }
+ }
+
+ // 濡傛灉杩樻槸娌℃湁锛屼粠dikuaiData鑾峰彇boundaryCoordinates
+ if (boundaryCoords == null || boundaryCoords.isEmpty()) {
boundaryCoords = normalizeCoordinateValue(dikuaiData.get("boundaryCoordinates"));
}
- if (boundaryCoords == null) {
+
+ if (boundaryCoords == null || boundaryCoords.isEmpty()) {
JOptionPane.showMessageDialog(this, "鏈壘鍒版湁鏁堢殑鍦板潡杈圭晫鍧愭爣锛屾棤娉曠敓鎴愯矾寰�", "鎻愮ず", JOptionPane.WARNING_MESSAGE);
dikuaiData.remove("plannedPath");
showPathGenerationMessage("鏈壘鍒版湁鏁堢殑鍦板潡杈圭晫鍧愭爣锛屾棤娉曠敓鎴愯矾寰勩��", false);
@@ -1417,19 +1439,48 @@
}
}
+ // 鏍煎紡鍖栧壊鑽夊搴﹀拰瀹夊叏璺濈锛堝崟浣嶏細绫筹紝淇濈暀3浣嶅皬鏁帮級
String widthMetersStr = String.format(Locale.US, "%.3f", widthMeters);
String safetyDistanceMetersStr = Double.isNaN(safetyDistanceMeters) ? null : String.format(Locale.US, "%.3f", safetyDistanceMeters);
- String plannerMode = resolvePlannerMode(patternDisplay);
+
+ // 濡傛灉娌℃湁瀹夊叏璺濈锛屼娇鐢ㄩ粯璁ゅ��
+ if (safetyDistanceMetersStr == null) {
+ double defaultSafetyDistance = widthMeters / 2.0 + 0.2;
+ safetyDistanceMetersStr = String.format(Locale.US, "%.3f", defaultSafetyDistance);
+ }
try {
- // 浣跨敤涓庤矾寰勮鍒掗〉闈㈢浉鍚岀殑鏂规硶锛歀unjingguihua.generatePathFromStrings
- String plannedPath = Lunjingguihua.generatePathFromStrings(
- boundaryCoords,
- obstacleCoords != null ? obstacleCoords : "",
- widthMetersStr,
- safetyDistanceMetersStr,
- plannerMode
- );
+ // 1. 璋冪敤Qufenxingzhuang涓殑judgeGrassType鏂规硶璁$畻鍦板潡杈圭晫鐨勫舰鐘�
+ Qufenxingzhuang shapeJudger = new Qufenxingzhuang();
+ int grassType = shapeJudger.judgeGrassType(boundaryCoords);
+ // grassType: 0=鏃犳硶鍒ゆ柇, 1=鍑稿舰, 2=寮傚舰
+
+ String plannedPath = null;
+
+ // 2. 鏍规嵁璁$畻鍚庣殑缁撴灉鍐冲畾璋冪敤鍝釜鏂规硶鐢熸垚鍓茶崏璺緞
+ if (grassType == 1) {
+ // 鍑稿舰鍦板潡 -> 璋冪敤AoxinglujingNoObstacle绫讳腑鐨勬柟娉�
+ List<AoxinglujingNoObstacle.PathSegment> segments =
+ AoxinglujingNoObstacle.planPath(boundaryCoords, widthMetersStr, safetyDistanceMetersStr);
+ plannedPath = formatAoxingPathSegments(segments);
+ } else if (grassType == 2) {
+ // 寮傚舰鍦板潡 -> 璋冪敤YixinglujingNoObstacle涓殑鏂规硶
+ List<YixinglujingNoObstacle.PathSegment> segments =
+ YixinglujingNoObstacle.planPath(boundaryCoords, widthMetersStr, safetyDistanceMetersStr);
+ plannedPath = formatYixingPathSegments(segments);
+ } else {
+ // 鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁ゆ柟娉曚綔涓哄悗澶�
+ JOptionPane.showMessageDialog(this, "鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁よ矾寰勭敓鎴愭柟娉�",
+ "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ String plannerMode = resolvePlannerMode(patternDisplay);
+ plannedPath = Lunjingguihua.generatePathFromStrings(
+ boundaryCoords,
+ obstacleCoords != null ? obstacleCoords : "",
+ widthMetersStr,
+ safetyDistanceMetersStr,
+ plannerMode
+ );
+ }
if (!isMeaningfulValue(plannedPath)) {
JOptionPane.showMessageDialog(this, "鐢熸垚鍓茶崏璺緞澶辫触: 鐢熸垚缁撴灉涓虹┖", "閿欒", JOptionPane.ERROR_MESSAGE);
@@ -1464,6 +1515,96 @@
}
}
+ /**
+ * 鏍煎紡鍖� AoxinglujingNoObstacle.PathSegment 鍒楄〃涓哄潗鏍囧瓧绗︿覆
+ */
+ private String formatAoxingPathSegments(List<AoxinglujingNoObstacle.PathSegment> segments) {
+ if (segments == null || segments.isEmpty()) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ AoxinglujingNoObstacle.Point last = null;
+ for (AoxinglujingNoObstacle.PathSegment segment : segments) {
+ // 鍙坊鍔犲壊鑽夊伐浣滄锛岃烦杩囪繃娓℃
+ if (segment.isMowing) {
+ // 濡傛灉璧风偣涓庝笂涓�涓粓鐐逛笉鍚岋紝娣诲姞璧风偣
+ if (last == null || !equalsAoxingPoint(last, segment.start)) {
+ appendAoxingPoint(sb, segment.start);
+ }
+ // 娣诲姞缁堢偣
+ appendAoxingPoint(sb, segment.end);
+ last = segment.end;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 鏍煎紡鍖� YixinglujingNoObstacle.PathSegment 鍒楄〃涓哄潗鏍囧瓧绗︿覆
+ */
+ private String formatYixingPathSegments(List<YixinglujingNoObstacle.PathSegment> segments) {
+ if (segments == null || segments.isEmpty()) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ YixinglujingNoObstacle.Point last = null;
+ for (YixinglujingNoObstacle.PathSegment segment : segments) {
+ // 鍙坊鍔犲壊鑽夊伐浣滄锛岃烦杩囪繃娓℃
+ if (segment.isMowing) {
+ // 濡傛灉璧风偣涓庝笂涓�涓粓鐐逛笉鍚岋紝娣诲姞璧风偣
+ if (last == null || !equalsYixingPoint(last, segment.start)) {
+ appendYixingPoint(sb, segment.start);
+ }
+ // 娣诲姞缁堢偣
+ appendYixingPoint(sb, segment.end);
+ last = segment.end;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 姣旇緝涓や釜 AoxinglujingNoObstacle.Point 鏄惁鐩稿悓锛堜娇鐢ㄥ皬鐨勫宸級
+ */
+ private boolean equalsAoxingPoint(AoxinglujingNoObstacle.Point p1, AoxinglujingNoObstacle.Point p2) {
+ if (p1 == null || p2 == null) {
+ return p1 == p2;
+ }
+ double tolerance = 1e-6;
+ return Math.abs(p1.x - p2.x) < tolerance && Math.abs(p1.y - p2.y) < tolerance;
+ }
+
+ /**
+ * 娣诲姞 AoxinglujingNoObstacle.Point 鍒板瓧绗︿覆鏋勫缓鍣�
+ */
+ private void appendAoxingPoint(StringBuilder sb, AoxinglujingNoObstacle.Point point) {
+ if (sb.length() > 0) {
+ sb.append(";");
+ }
+ sb.append(String.format(Locale.US, "%.6f,%.6f", point.x, point.y));
+ }
+
+ /**
+ * 姣旇緝涓や釜 YixinglujingNoObstacle.Point 鏄惁鐩稿悓锛堜娇鐢ㄥ皬鐨勫宸級
+ */
+ private boolean equalsYixingPoint(YixinglujingNoObstacle.Point p1, YixinglujingNoObstacle.Point p2) {
+ if (p1 == null || p2 == null) {
+ return p1 == p2;
+ }
+ double tolerance = 1e-6;
+ return Math.abs(p1.x - p2.x) < tolerance && Math.abs(p1.y - p2.y) < tolerance;
+ }
+
+ /**
+ * 娣诲姞 YixinglujingNoObstacle.Point 鍒板瓧绗︿覆鏋勫缓鍣�
+ */
+ private void appendYixingPoint(StringBuilder sb, YixinglujingNoObstacle.Point point) {
+ if (sb.length() > 0) {
+ sb.append(";");
+ }
+ sb.append(String.format(Locale.US, "%.6f,%.6f", point.x, point.y));
+ }
+
private void previewMowingPath() {
if (!hasGeneratedPath()) {
showPathGenerationMessage("璇峰厛鐢熸垚鍓茶崏璺緞鍚庡啀棰勮銆�", false);
--
Gitblit v1.10.0