From 32c98d4855b6178554c787103dc956d161e152b3 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 19 十二月 2025 19:45:30 +0800
Subject: [PATCH] 增加了异形分析逻辑
---
src/lujing/MowingPathGenerationPage.java | 218 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 193 insertions(+), 25 deletions(-)
diff --git a/src/lujing/MowingPathGenerationPage.java b/src/lujing/MowingPathGenerationPage.java
index 4bc81b4..73a8fde 100644
--- a/src/lujing/MowingPathGenerationPage.java
+++ b/src/lujing/MowingPathGenerationPage.java
@@ -15,8 +15,14 @@
import dikuai.Dikuai;
import lujing.Lunjingguihua;
import lujing.ObstaclePathPlanner;
+import lujing.Qufenxingzhuang;
+import lujing.AoxinglujingNoObstacle;
+import lujing.YixinglujingNoObstacle;
+import lujing.AoxinglujingHaveObstacel;
+import lujing.YixinglujingHaveObstacel;
import org.locationtech.jts.geom.Coordinate;
import gecaoji.Device;
+import java.util.Locale;
/**
* 鐢熸垚鍓茶崏璺緞椤甸潰
@@ -494,8 +500,24 @@
obstacles = obstacles.replace("\r\n", " ").replace('\r', ' ').replace('\n', ' ');
}
+ // 鑾峰彇瀹夊叏璺濈
+ String safetyMarginStr = getSafetyDistanceString();
+ if (safetyMarginStr == null) {
+ // 濡傛灉娌℃湁璁剧疆瀹夊叏璺濈锛屼娇鐢ㄩ粯璁ゅ�硷細鍓茶崏瀹藉害鐨勪竴鍗� + 0.2绫�
+ double defaultSafetyDistance = widthMeters / 2.0 + 0.2;
+ safetyMarginStr = BigDecimal.valueOf(defaultSafetyDistance)
+ .setScale(3, RoundingMode.HALF_UP)
+ .stripTrailingZeros()
+ .toPlainString();
+ }
+
String mode = normalizeExistingMowingPattern(modeInput);
try {
+ // 1. 棣栧厛鍒ゆ柇鍦板潡绫诲瀷锛堝嚫褰㈣繕鏄紓褰級
+ Qufenxingzhuang shapeJudger = new Qufenxingzhuang();
+ int grassType = shapeJudger.judgeGrassType(boundary);
+ // grassType: 0=鏃犳硶鍒ゆ柇, 1=鍑稿舰, 2=寮傚舰
+
// 瑙f瀽闅滅鐗╁垪琛�
List<List<Coordinate>> obstacleList = Lunjingguihua.parseObstacles(obstacles);
if (obstacleList == null) {
@@ -505,35 +527,110 @@
// 鍒ゆ柇鏄惁鏈夋湁鏁堢殑闅滅鐗╋細鍙湁褰撹В鏋愭垚鍔熶笖鍒楄〃涓嶄负绌烘椂锛屾墠璁や负鏈夐殰纰嶇墿
boolean hasValidObstacles = !obstacleList.isEmpty();
- String generated;
+ String generated = null;
+ // 2. 鏍规嵁鍦板潡绫诲瀷鍜屾槸鍚︽湁闅滅鐗╋紝璋冪敤涓嶅悓鐨勮矾寰勭敓鎴愮被
if (!hasValidObstacles) {
- // 闅滅鐗╁潗鏍囦笉瀛樺湪鎴栦负绌烘椂锛屼娇鐢↙unjingguihua绫荤殑鏂规硶鐢熸垚璺緞
- generated = Lunjingguihua.generatePathFromStrings(
- boundary,
- obstacles != null ? obstacles : "",
- plannerWidth,
- null, // safetyDistStr锛屼娇鐢ㄩ粯璁ゅ��
- mode
- );
- } else {
- // 鏈夋湁鏁堥殰纰嶇墿鏃讹紝浣跨敤ObstaclePathPlanner澶勭悊璺緞鐢熸垚
- List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary);
- if (polygon.size() < 4) {
- if (showMessages) {
- JOptionPane.showMessageDialog(parentComponent, "澶氳竟褰㈠潗鏍囨暟閲忎笉瓒筹紝鑷冲皯闇�瑕佷笁涓偣",
- "閿欒", JOptionPane.ERROR_MESSAGE);
+ // 鏃犻殰纰嶇墿鐨勬儏鍐�
+ if (grassType == 1) {
+ // 鍑稿舰鍦板潡锛屾棤闅滅鐗� -> 璋冪敤 AoxinglujingNoObstacle
+ List<AoxinglujingNoObstacle.PathSegment> segments =
+ AoxinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr);
+ generated = formatAoxingPathSegments(segments);
+ } else if (grassType == 2) {
+ // 寮傚舰鍦板潡锛屾棤闅滅鐗� -> 璋冪敤 YixinglujingNoObstacle
+ // 娉ㄦ剰锛氬鏋滆绫昏繕娌℃湁瀹炵幇锛岃繖閲屼細鎶涘嚭寮傚父鎴栬繑鍥瀗ull
+ try {
+ // 鍋囪 YixinglujingNoObstacle 鏈夌被浼肩殑鏂规硶绛惧悕
+ // 濡傛灉绫昏繕娌℃湁瀹炵幇锛屽彲鑳介渶瑕佷娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ generated = YixinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr);
+ } catch (Exception e) {
+ // 濡傛灉绫昏繕娌℃湁瀹炵幇锛屼娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ if (showMessages) {
+ System.err.println("YixinglujingNoObstacle 灏氭湭瀹炵幇锛屼娇鐢ㄩ粯璁ゆ柟娉�: " + e.getMessage());
+ }
+ generated = Lunjingguihua.generatePathFromStrings(
+ boundary, obstacles != null ? obstacles : "", plannerWidth, safetyMarginStr, mode);
}
- return null;
+ } else {
+ // 鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ if (showMessages) {
+ JOptionPane.showMessageDialog(parentComponent, "鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁よ矾寰勭敓鎴愭柟娉�",
+ "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ }
+ generated = Lunjingguihua.generatePathFromStrings(
+ boundary, obstacles != null ? obstacles : "", plannerWidth, safetyMarginStr, mode);
}
-
- // 鏈夐殰纰嶇墿鏃朵娇鐢ㄥ壊鑽夊搴︾殑涓�鍗� + 0.05绫抽澶栧畨鍏ㄨ窛绂�
- double safetyDistance = widthMeters / 2.0 + 0.05;
-
- ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner(
- polygon, widthMeters, mode, obstacleList, safetyDistance);
- List<Lunjingguihua.PathSegment> segments = pathPlanner.generate();
- generated = Lunjingguihua.formatPathSegments(segments);
+ } else {
+ // 鏈夐殰纰嶇墿鐨勬儏鍐�
+ if (grassType == 1) {
+ // 鍑稿舰鍦板潡锛屾湁闅滅鐗� -> 璋冪敤 AoxinglujingHaveObstacel
+ try {
+ // 鍋囪 AoxinglujingHaveObstacel 鏈夌被浼肩殑鏂规硶绛惧悕
+ generated = AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr);
+ } catch (Exception e) {
+ // 濡傛灉绫昏繕娌℃湁瀹炵幇锛屼娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ if (showMessages) {
+ System.err.println("AoxinglujingHaveObstacel 灏氭湭瀹炵幇锛屼娇鐢ㄩ粯璁ゆ柟娉�: " + e.getMessage());
+ }
+ List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary);
+ if (polygon.size() < 4) {
+ if (showMessages) {
+ JOptionPane.showMessageDialog(parentComponent, "澶氳竟褰㈠潗鏍囨暟閲忎笉瓒筹紝鑷冲皯闇�瑕佷笁涓偣",
+ "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+ return null;
+ }
+ double safetyDistance = Double.parseDouble(safetyMarginStr);
+ ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner(
+ polygon, widthMeters, mode, obstacleList, safetyDistance);
+ List<Lunjingguihua.PathSegment> segments = pathPlanner.generate();
+ generated = Lunjingguihua.formatPathSegments(segments);
+ }
+ } else if (grassType == 2) {
+ // 寮傚舰鍦板潡锛屾湁闅滅鐗� -> 璋冪敤 YixinglujingHaveObstacel
+ try {
+ // 鍋囪 YixinglujingHaveObstacel 鏈夌被浼肩殑鏂规硶绛惧悕
+ generated = YixinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr);
+ } catch (Exception e) {
+ // 濡傛灉绫昏繕娌℃湁瀹炵幇锛屼娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ if (showMessages) {
+ System.err.println("YixinglujingHaveObstacel 灏氭湭瀹炵幇锛屼娇鐢ㄩ粯璁ゆ柟娉�: " + e.getMessage());
+ }
+ List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary);
+ if (polygon.size() < 4) {
+ if (showMessages) {
+ JOptionPane.showMessageDialog(parentComponent, "澶氳竟褰㈠潗鏍囨暟閲忎笉瓒筹紝鑷冲皯闇�瑕佷笁涓偣",
+ "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+ return null;
+ }
+ double safetyDistance = Double.parseDouble(safetyMarginStr);
+ ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner(
+ polygon, widthMeters, mode, obstacleList, safetyDistance);
+ List<Lunjingguihua.PathSegment> segments = pathPlanner.generate();
+ generated = Lunjingguihua.formatPathSegments(segments);
+ }
+ } else {
+ // 鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄥ師鏉ョ殑鏂规硶浣滀负鍚庡
+ if (showMessages) {
+ JOptionPane.showMessageDialog(parentComponent, "鏃犳硶鍒ゆ柇鍦板潡绫诲瀷锛屼娇鐢ㄩ粯璁よ矾寰勭敓鎴愭柟娉�",
+ "鎻愮ず", JOptionPane.WARNING_MESSAGE);
+ }
+ List<Coordinate> polygon = Lunjingguihua.parseCoordinates(boundary);
+ if (polygon.size() < 4) {
+ if (showMessages) {
+ JOptionPane.showMessageDialog(parentComponent, "澶氳竟褰㈠潗鏍囨暟閲忎笉瓒筹紝鑷冲皯闇�瑕佷笁涓偣",
+ "閿欒", JOptionPane.ERROR_MESSAGE);
+ }
+ return null;
+ }
+ double safetyDistance = Double.parseDouble(safetyMarginStr);
+ ObstaclePathPlanner pathPlanner = new ObstaclePathPlanner(
+ polygon, widthMeters, mode, obstacleList, safetyDistance);
+ List<Lunjingguihua.PathSegment> segments = pathPlanner.generate();
+ generated = Lunjingguihua.formatPathSegments(segments);
+ }
}
String trimmed = generated != null ? generated.trim() : "";
@@ -564,6 +661,77 @@
return null;
}
+ /**
+ * 鑾峰彇瀹夊叏璺濈瀛楃涓诧紙绫筹級
+ */
+ private String getSafetyDistanceString() {
+ Device device = Device.getActiveDevice();
+ if (device != null) {
+ String safetyDistanceValue = device.getMowingSafetyDistance();
+ if (safetyDistanceValue != null && !"-1".equals(safetyDistanceValue) && !safetyDistanceValue.trim().isEmpty()) {
+ try {
+ double distanceMeters = Double.parseDouble(safetyDistanceValue.trim());
+ // 濡傛灉鍊煎ぇ浜�100锛岃涓烘槸鍘樼背锛岄渶瑕佽浆鎹负绫�
+ if (distanceMeters > 100) {
+ distanceMeters = distanceMeters / 100.0;
+ }
+ return BigDecimal.valueOf(distanceMeters)
+ .setScale(3, RoundingMode.HALF_UP)
+ .stripTrailingZeros()
+ .toPlainString();
+ } catch (NumberFormatException e) {
+ // 瑙f瀽澶辫触锛岃繑鍥瀗ull锛屼娇鐢ㄩ粯璁ゅ��
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鏍煎紡鍖� 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 || !equals2D(last, segment.start)) {
+ appendPoint(sb, segment.start);
+ }
+ // 娣诲姞缁堢偣
+ appendPoint(sb, segment.end);
+ last = segment.end;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 姣旇緝涓や釜鐐规槸鍚︾浉鍚岋紙浣跨敤灏忕殑瀹瑰樊锛�
+ */
+ private boolean equals2D(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;
+ }
+
+ /**
+ * 娣诲姞鐐瑰埌瀛楃涓叉瀯寤哄櫒
+ */
+ private void appendPoint(StringBuilder sb, AoxinglujingNoObstacle.Point point) {
+ if (sb.length() > 0) {
+ sb.append(";");
+ }
+ sb.append(String.format(Locale.US, "%.6f,%.6f", point.x, point.y));
+ }
+
// ========== UI杈呭姪鏂规硶 ==========
private JTextArea createInfoTextArea(String text, boolean editable, int rows) {
--
Gitblit v1.10.0