From 0930bed760105b81e2e5055801bec6d6e8d57358 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 23 十二月 2025 18:40:08 +0800
Subject: [PATCH] 新增了功能
---
src/Mqttmessage/Entity/ResponseData.java | 71 +++
dikuai.properties | 8
lib/jackson-annotations-2.15.2.jar | 0
.classpath | 7
lib/jackson-databind-2.15.2.jar | 0
set.properties | 8
src/Mqttmessage/Entity/GPSData.java | 136 ++++++
src/udpdell/UDPServer.java | 19
src/Mqttmessage/Entity/BasestationData.java | 25 +
src/Mqttmessage/Entity/StatusData.java | 41 +
lib/lombok-1.18.36.jar | 0
Obstacledge.properties | 2
src/Mqttmessage/PushCallback.java | 35 +
src/Mqttmessage/Entity/PathData.java | 33 +
src/lujing/AoxinglujingNoObstacle.java | 459 +++++++--------------
src/lujing/MowingPathGenerationPage.java | 31 +
lib/jackson-core-2.15.2.jar | 0
lib/org.eclipse.paho.client.mqttv3-1.2.2.jar | 0
src/Mqttmessage/Util/DeviceMessageParser.java | 161 +++++++
src/Mqttmessage/Client.java | 119 +++++
src/Mqttmessage/Entity/HxzkPathMessage.java | 28 +
src/Mqttmessage/Entity/CoordinatePoint.java | 18
22 files changed, 878 insertions(+), 323 deletions(-)
diff --git a/.classpath b/.classpath
index c950b57..835d2ed 100644
--- a/.classpath
+++ b/.classpath
@@ -6,10 +6,15 @@
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jackson-annotations-2.15.2.jar"/>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jackson-core-2.15.2.jar"/>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jackson-databind-2.15.2.jar"/>
<classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jSerialComm-2.10.4.jar"/>
<classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/jts-core-1.19.0.jar"/>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/lombok-1.18.36.jar"/>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/MQTT-1.0-SNAPSHOT.jar"/>
+ <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/org.eclipse.paho.client.mqttv3-1.2.2.jar"/>
<classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-api-1.7.30.jar"/>
<classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/slf4j-simple-1.7.30.jar"/>
- <classpathentry kind="lib" path="E:/Users/hxzk/eclipse-workspace/GeCaoAPP/lib/MQTT-1.0-SNAPSHOT.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/Obstacledge.properties b/Obstacledge.properties
index 6fe34cc..42ee055 100644
--- a/Obstacledge.properties
+++ b/Obstacledge.properties
@@ -1,5 +1,5 @@
# 鍓茶崏鏈哄湴鍧楅殰纰嶇墿閰嶇疆鏂囦欢
-# 鐢熸垚鏃堕棿锛�2025-12-23T17:37:19.839482400
+# 鐢熸垚鏃堕棿锛�2025-12-23T18:32:39.445241900
# 鍧愭爣绯伙細WGS84锛堝害鍒嗘牸寮忥級
# ============ 鍦板潡鍩哄噯绔欓厤缃� ============
diff --git a/dikuai.properties b/dikuai.properties
index 8013c20..d6aa004 100644
--- a/dikuai.properties
+++ b/dikuai.properties
@@ -1,8 +1,8 @@
#Dikuai Properties
-#Tue Dec 23 17:37:19 CST 2025
+#Tue Dec 23 18:32:39 CST 2025
LAND1.angleThreshold=-1
LAND1.baseStationCoordinates=3949.89151752,N,11616.79267501,E
-LAND1.boundaryCoordinates=4.30,87.65;-2.36,-65.51;44.25,-66.72;49.70,-14.05;98.13,-15.87;99.34,-69.75;137.48,-67.93;134.45,90.07;4.30,87.65
+LAND1.boundaryCoordinates=-99.64,193.56;185.77,182.30;61.84,424.89;237.59,415.88;235.34,539.80;-26.03,544.31
LAND1.boundaryOriginalCoordinates=39.831522,116.279873,49.25;39.831524,116.279878,49.25;39.831525,116.279878,49.24;39.831524,116.279912,49.30;39.831524,116.279911,49.29;39.831523,116.279911,49.23;39.831521,116.279915,49.31;39.831517,116.279925,49.34;39.831514,116.279940,49.30;39.831514,116.279957,49.28;39.831516,116.279974,49.28;39.831518,116.279991,49.29;39.831521,116.280008,49.24;39.831524,116.280025,49.30;39.831526,116.280042,49.24;39.831529,116.280059,49.29;39.831529,116.280076,49.26;39.831530,116.280093,49.32;39.831531,116.280110,49.28;39.831533,116.280127,49.28;39.831535,116.280144,49.26;39.831539,116.280161,49.27;39.831544,116.280175,49.25;39.831551,116.280190,49.24;39.831558,116.280204,49.26;39.831566,116.280219,49.26;39.831574,116.280234,49.22;39.831583,116.280248,49.24;39.831591,116.280260,49.24;39.831600,116.280272,49.23;39.831608,116.280285,49.18;39.831615,116.280298,49.12;39.831618,116.280312,49.11;39.831618,116.280328,49.12;39.831615,116.280342,49.15;39.831610,116.280356,49.21;39.831602,116.280369,49.23;39.831592,116.280379,49.25;39.831581,116.280388,49.25;39.831569,116.280394,49.19;39.831559,116.280395,49.23;39.831552,116.280387,49.28;39.831547,116.280373,49.32;39.831544,116.280357,49.33;39.831541,116.280340,49.29;39.831539,116.280324,49.27;39.831536,116.280307,49.24;39.831534,116.280290,49.25;39.831531,116.280273,49.26;39.831527,116.280257,49.28;39.831522,116.280242,49.21;39.831514,116.280232,49.28;39.831504,116.280229,49.24;39.831491,116.280230,49.33;39.831478,116.280233,49.34;39.831466,116.280236,49.31;39.831454,116.280239,49.31;39.831441,116.280242,49.26;39.831429,116.280244,49.23;39.831416,116.280247,49.25;39.831402,116.280250,49.22;39.831389,116.280253,49.25;39.831376,116.280256,49.26;39.831364,116.280258,49.24;39.831351,116.280261,49.25;39.831338,116.280265,49.26;39.831324,116.280268,49.20;39.831311,116.280271,49.16;39.831298,116.280274,49.17;39.831285,116.280277,49.22;39.831271,116.280278,49.16;39.831261,116.280273,49.23
LAND1.boundaryOriginalXY=-1
LAND1.boundaryPointInterval=-1
@@ -17,9 +17,9 @@
LAND1.mowingSafetyDistance=0.53
LAND1.mowingTrack=-1
LAND1.mowingWidth=200
-LAND1.plannedPath=136.940221,-67.425155;133.930254,89.530244;4.807861,87.129352;-1.807069,-64.994176;43.773311,-66.177447;49.223902,-13.501734;98.648661,-15.359117;99.857663,-69.194695;136.940221,-67.425155;134.941682,-67.520523;131.930599,89.493063;129.930944,89.455881;132.943143,-67.615891;130.944605,-67.711259;127.931289,89.418700;125.931635,89.381519;128.946066,-67.806627;126.947527,-67.901995;123.931980,89.344337;121.932325,89.307156;124.948988,-67.997363;122.950449,-68.092732;119.932671,89.269974;117.933016,89.232793;120.951910,-68.188100;118.953371,-68.283468;115.933361,89.195611;113.933707,89.158430;116.954833,-68.378836;114.956294,-68.474204;111.934052,89.121248;109.934397,89.084067;112.957755,-68.569572;110.959216,-68.664940;107.934743,89.046886;105.935088,89.009704;108.960677,-68.760308;106.962138,-68.855677;103.935433,88.972523;101.935778,88.935341;104.963600,-68.951045;102.965061,-69.046413;99.936124,88.898160;97.936469,88.860978;100.966522,-69.141781;97.934238,-15.332269;95.936814,88.823797;93.937160,88.786615;95.932427,-15.257041;93.930617,-15.181813;91.937505,88.749434;89.937850,88.712253;91.928806,-15.106585;89.926996,-15.031357;87.938196,88.675071;85.938541,88.637890;87.925186,-14.956129;85.923375,-14.880901;83.938886,88.600708;81.939231,88.563527;83.921565,-14.805673;81.919754,-14.730445;79.939577,88.526345;77.939922,88.489164;79.917944,-14.655217;77.916134,-14.579989;75.940267,88.451983;73.940613,88.414801;75.914323,-14.504760;73.912513,-14.429532;71.940958,88.377620;69.941303,88.340438;71.910702,-14.354304;69.908892,-14.279076;67.941649,88.303257;65.941994,88.266075;67.907082,-14.203848;65.905271,-14.128620;63.942339,88.228894;61.942685,88.191712;63.903461,-14.053392;61.901651,-13.978164;59.943030,88.154531;57.943375,88.117350;59.899840,-13.902936;57.898030,-13.827708;55.943720,88.080168;53.944066,88.042987;55.896219,-13.752480;53.894409,-13.677252;51.944411,88.005805;49.944756,87.968624;51.892599,-13.602024;49.890788,-13.526796;47.945102,87.931442;45.945447,87.894261;48.098512,-24.377753;46.410911,-40.687091;43.945792,87.857079;41.946138,87.819898;44.723311,-56.996429;42.898575,-66.154738;39.946483,87.782717;37.946828,87.745535;40.897210,-66.102783;38.895846,-66.050827;35.947173,87.708354;33.947519,87.671172;36.894482,-65.998872;34.893118,-65.946916;31.947864,87.633991;29.948209,87.596809;32.891754,-65.894960;30.890390,-65.843005;27.948555,87.559628;25.948900,87.522447;28.889026,-65.791049;26.887662,-65.739094;23.949245,87.485265;21.949591,87.448084;24.886298,-65.687138;22.884934,-65.635182;19.949936,87.410902;17.950281,87.373721;20.883570,-65.583227;18.882205,-65.531271;15.950627,87.336539;13.950972,87.299358;16.880841,-65.479315;14.879477,-65.427360;11.951317,87.262176;9.951662,87.224995;12.878113,-65.375404;10.876749,-65.323449;7.952008,87.187814;5.952353,87.150632;8.875385,-65.271493;6.874021,-65.219537;4.214206,73.477072;2.826044,41.553502;4.872657,-65.167582;2.871293,-65.115626;1.437881,9.629932;0.049718,-22.293638;0.869929,-65.063671
+LAND1.plannedPath=-25.601252,543.772523;-98.992501,194.064867;184.886062,182.865285;60.950435,425.466300;237.049774,416.438391;234.819374,539.278905;-25.601252,543.772523;-23.565057,543.737388;-96.965713,193.984906;-94.938925,193.904945;-21.528862,543.702253;-19.492667,543.667118;-92.912138,193.824985;-90.885350,193.745024;-17.456472,543.631983;-15.420277,543.596848;-88.858562,193.665063;-86.831775,193.585102;-13.384082,543.561713;-11.347887,543.526578;-84.804987,193.505141;-82.778200,193.425180;-9.311692,543.491443;-7.275497,543.456308;-80.751412,193.345219;-78.724624,193.265259;-5.239302,543.421173;-3.203107,543.386038;-76.697837,193.185298;-74.671049,193.105337;-1.166912,543.350903;0.869283,543.315768;-72.644261,193.025376;-70.617474,192.945415;2.905478,543.280633;4.941673,543.245498;-68.590686,192.865454;-66.563898,192.785493;6.977868,543.210363;9.014063,543.175228;-64.537111,192.705533;-62.510323,192.625572;11.050258,543.140093;13.086453,543.104958;-60.483536,192.545611;-58.456748,192.465650;15.122648,543.069823;17.158843,543.034688;-56.429960,192.385689;-54.403173,192.305728;19.195038,542.999553;21.231233,542.964418;-52.376385,192.225767;-50.349597,192.145807;23.267428,542.929283;25.303623,542.894148;-48.322810,192.065846;-46.296022,191.985885;27.339818,542.859013;29.376013,542.823877;-44.269235,191.905924;-42.242447,191.825963;31.412208,542.788742;33.448403,542.753607;-40.215659,191.746002;-38.188872,191.666041;35.484598,542.718472;37.520793,542.683337;-36.162084,191.586081;-34.135296,191.506120;39.556988,542.648202;41.593183,542.613067;-32.108509,191.426159;-30.081721,191.346198;43.629378,542.577932;45.665573,542.542797;-28.054933,191.266237;-26.028146,191.186276;47.701768,542.507662;49.737963,542.472527;-24.001358,191.106315;-21.974571,191.026355;51.774158,542.437392;53.810353,542.402257;-19.947783,190.946394;-17.920995,190.866433;55.846548,542.367122;57.882743,542.331987;-15.894208,190.786472;-13.867420,190.706511;59.918938,542.296852;61.955133,542.261717;-11.840632,190.626550;-9.813845,190.546589;63.991328,542.226582;66.027523,542.191447;-7.787057,190.466628;-5.760269,190.386668;68.063718,542.156312;70.099913,542.121177;-3.733482,190.306707;-1.706694,190.226746;72.136108,542.086042;74.172303,542.050907;0.320093,190.146785;2.346881,190.066824;76.208498,542.015772;78.244693,541.980637;4.373669,189.986863;6.400456,189.906902;80.280888,541.945502;82.317083,541.910367;8.427244,189.826942;10.454032,189.746981;84.353278,541.875232;86.389473,541.840097;61.955917,425.414753;61.670804,424.056196;12.480819,189.667020;14.507607,189.587059;63.119317,421.220767;63.977733,425.311103;88.425668,541.804962;90.461863,541.769827;65.999549,425.207453;64.567829,418.385338;16.534394,189.507098;18.561182,189.427137;66.016342,415.549910;68.021365,425.103802;92.498058,541.734692;94.534253,541.699557;70.043181,425.000152;67.464854,412.714481;20.587970,189.347176;22.614757,189.267216;68.913367,409.879053;72.064997,424.896501;96.570448,541.664422;98.606643,541.629287;74.086814,424.792851;70.361880,407.043624;24.641545,189.187255;26.668333,189.107294;71.810392,404.208195;76.108630,424.689200;100.642838,541.594152;102.679033,541.559017;78.130446,424.585550;73.258905,401.372767;28.695120,189.027333;30.721908,188.947372;74.707417,398.537338;80.152262,424.481900;104.715228,541.523882;106.751423,541.488747;82.174078,424.378249;76.155930,395.701910;32.748696,188.867411;34.775483,188.787450;77.604442,392.866481;84.195894,424.274599;108.787618,541.453612;110.823813,541.418477;86.217710,424.170948;79.052955,390.031053;36.802271,188.707490;38.829058,188.627529;80.501468,387.195624;88.239526,424.067298;112.860008,541.383342;114.896203,541.348207;90.261342,423.963647;81.949980,384.360195;40.855846,188.547568;42.882634,188.467607;83.398493,381.524767;92.283158,423.859997;116.932398,541.313072;118.968593,541.277937;94.304974,423.756347;84.847005,378.689338;44.909421,188.387646;46.936209,188.307685;86.295518,375.853910;96.326790,423.652696;121.004788,541.242802;123.040983,541.207667;98.348606,423.549046;87.744030,373.018481;48.962997,188.227724;50.989784,188.147764;89.192543,370.183052;100.370422,423.445395;125.077177,541.172532;127.113372,541.137397;102.392238,423.341745;90.641056,367.347624;53.016572,188.067803;55.043360,187.987842;92.089568,364.512195;104.414054,423.238094;129.149567,541.102262;131.185762,541.067127;106.435870,423.134444;93.538081,361.676767;57.070147,187.907881;59.096935,187.827920;94.986593,358.841338;108.457686,423.030794;133.221957,541.031992;135.258152,540.996857;110.479502,422.927143;96.435106,356.005910;61.123722,187.747959;63.150510,187.667998;97.883618,353.170481;112.501318,422.823493;137.294347,540.961722;139.330542,540.926587;114.523134,422.719842;99.332131,350.335052;65.177298,187.588038;67.204085,187.508077;100.780644,347.499624;116.544950,422.616192;141.366737,540.891452;143.402932,540.856317;118.566766,422.512541;102.229156,344.664195;69.230873,187.428116;71.257661,187.348155;103.677669,341.828767;120.588582,422.408891;145.439127,540.821182;147.475322,540.786047;122.610398,422.305241;105.126181,338.993338;73.284448,187.268194;75.311236,187.188233;106.574694,336.157910;124.632214,422.201590;149.511517,540.750911;151.547712,540.715776;126.654030,422.097940;108.023206,333.322481;77.338023,187.108272;79.364811,187.028312;109.471719,330.487052;128.675846,421.994289;153.583907,540.680641;155.620102,540.645506;130.697662,421.890639;110.920231,327.651624;81.391599,186.948351;83.418386,186.868390;112.368744,324.816195;132.719478,421.786988;157.656297,540.610371;159.692492,540.575236;134.741294,421.683338;113.817257,321.980767;85.445174,186.788429;87.471962,186.708468;115.265769,319.145338;136.763111,421.579688;161.728687,540.540101;163.764882,540.504966;138.784927,421.476037;116.714282,316.309909;89.498749,186.628507;91.525537,186.548546;118.162794,313.474481;140.806743,421.372387;165.801077,540.469831;167.837272,540.434696;142.828559,421.268736;119.611307,310.639052;93.552325,186.468586;95.579112,186.388625;121.059819,307.803624;144.850375,421.165086;169.873467,540.399561;171.909662,540.364426;146.872191,421.061435;122.508332,304.968195;97.605900,186.308664;99.632687,186.228703;123.956845,302.132767;148.894007,420.957785;173.945857,540.329291;175.982052,540.294156;150.915823,420.854135;125.405357,299.297338;101.659475,186.148742;103.686263,186.068781;126.853870,296.461909;152.937639,420.750484;178.018247,540.259021;180.054442,540.223886;154.959455,420.646834;128.302382,293.626481;105.713050,185.988820;107.739838,185.908860;129.750895,290.791052;156.981271,420.543183;182.090637,540.188751;184.126832,540.153616;159.003087,420.439533;131.199407,287.955624;109.766626,185.828899;111.793413,185.748938;132.647920,285.120195;161.024903,420.335883;186.163027,540.118481;188.199222,540.083346;163.046719,420.232232;134.096433,282.284767;113.820201,185.668977;115.846989,185.589016;135.544945,279.449338;165.068535,420.128582;190.235417,540.048211;192.271612,540.013076;167.090351,420.024931;136.993458,276.613909;117.873776,185.509055;119.900564,185.429094;138.441970,273.778481;169.112167,419.921281;194.307807,539.977941;196.344002,539.942806;171.133983,419.817630;139.890483,270.943052;121.927351,185.349134;123.954139,185.269173;141.338995,268.107624;173.155799,419.713980;198.380197,539.907671;200.416392,539.872536;175.177615,419.610330;142.787508,265.272195;125.980927,185.189212;128.007714,185.109251;144.236021,262.436766;177.199431,419.506679;202.452587,539.837401;204.488782,539.802266;179.221247,419.403029;145.684533,259.601338;130.034502,185.029290;132.061290,184.949329;147.133046,256.765909;181.243063,419.299378;206.524977,539.767131;208.561172,539.731996;183.264879,419.195728;148.581558,253.930481;134.088077,184.869368;136.114865,184.789408;150.030071,251.095052;185.286695,419.092077;210.597367,539.696861;212.633562,539.661726;187.308511,418.988427;151.478583,248.259624;138.141652,184.709447;140.168440,184.629486;152.927096,245.424195;189.330327,418.884777;214.669757,539.626591;216.705952,539.591456;191.352143,418.781126;154.375609,242.588766;142.195228,184.549525;144.222015,184.469564;155.824121,239.753338;193.373959,418.677476;218.742147,539.556321;220.778342,539.521186;195.395775,418.573825;157.272634,236.917909;146.248803,184.389603;148.275591,184.309642;158.721146,234.082481;197.417591,418.470175;222.814537,539.486051;224.850732,539.450916;199.439408,418.366524;160.169659,231.247052;150.302378,184.229681;152.329166,184.149721;161.618171,228.411623;201.461224,418.262874;226.886927,539.415781;228.923122,539.380646;203.483040,418.159224;163.066684,225.576195;154.355954,184.069760;156.382741,183.989799;164.515197,222.740766;205.504856,418.055573;230.959317,539.345511;232.995512,539.310376;207.526672,417.951923;165.963709,219.905338;158.409529,183.909838;160.436316,183.829877;167.412222,217.069909;209.548488,417.848272;234.836343,538.344336;234.999068,529.382159;211.570304,417.744622;168.860734,214.234481;162.463104,183.749916;164.489892,183.669955;170.309247,211.399052;213.592120,417.640971;235.161793,520.419982;235.324518,511.457805;215.613936,417.537321;171.757759,208.563623;166.516679,183.589995;168.543467,183.510034;173.206272,205.728195;217.635752,417.433671;235.487243,502.495628;235.649969,493.533451;219.657568,417.330020;174.654784,202.892766;170.570255,183.430073;172.597042,183.350112;176.103297,200.057338;221.679384,417.226370;235.812694,484.571274;235.975419,475.609098;223.701200,417.122719;177.551810,197.221909;174.623830,183.270151;176.650618,183.190190;179.000322,194.386481;225.723016,417.019069;236.138144,466.646921;236.300869,457.684744;227.744832,416.915418;180.448835,191.551052;178.677405,183.110229;180.704193,183.030269;181.897347,188.715623;229.766648,416.811768;236.463594,448.722567;236.626319,439.760390;231.788464,416.708118;183.345860,185.880195;182.730980,182.950308;184.757768,182.870347;184.794372,183.044766;233.810280,416.604467;236.789045,430.798213;236.951770,421.836036;235.832096,416.500817
LAND1.returnPathCoordinates=-1
LAND1.returnPathRawCoordinates=-1
LAND1.returnPointCoordinates=-1
-LAND1.updateTime=2025-12-23 17\:37\:19
+LAND1.updateTime=2025-12-23 18\:32\:39
LAND1.userId=-1
diff --git a/lib/jackson-annotations-2.15.2.jar b/lib/jackson-annotations-2.15.2.jar
new file mode 100644
index 0000000..f8799c3
--- /dev/null
+++ b/lib/jackson-annotations-2.15.2.jar
Binary files differ
diff --git a/lib/jackson-core-2.15.2.jar b/lib/jackson-core-2.15.2.jar
new file mode 100644
index 0000000..a0e7486
--- /dev/null
+++ b/lib/jackson-core-2.15.2.jar
Binary files differ
diff --git a/lib/jackson-databind-2.15.2.jar b/lib/jackson-databind-2.15.2.jar
new file mode 100644
index 0000000..86f9a86
--- /dev/null
+++ b/lib/jackson-databind-2.15.2.jar
Binary files differ
diff --git a/lib/lombok-1.18.36.jar b/lib/lombok-1.18.36.jar
new file mode 100644
index 0000000..4341a40
--- /dev/null
+++ b/lib/lombok-1.18.36.jar
Binary files differ
diff --git a/lib/org.eclipse.paho.client.mqttv3-1.2.2.jar b/lib/org.eclipse.paho.client.mqttv3-1.2.2.jar
new file mode 100644
index 0000000..ea2d9a6
--- /dev/null
+++ b/lib/org.eclipse.paho.client.mqttv3-1.2.2.jar
Binary files differ
diff --git a/set.properties b/set.properties
index dd15b7f..7ecf537 100644
--- a/set.properties
+++ b/set.properties
@@ -1,5 +1,5 @@
#Mower Configuration Properties - Updated
-#Tue Dec 23 17:49:41 CST 2025
+#Tue Dec 23 18:35:51 CST 2025
appVersion=-1
boundaryLengthVisible=false
currentWorkLandNumber=LAND1
@@ -8,12 +8,12 @@
handheldMarkerId=1872
idleTrailDurationSeconds=60
manualBoundaryDrawingMode=false
-mapScale=0.53
+mapScale=2.83
measurementModeEnabled=false
mowerId=860
serialAutoConnect=true
serialBaudRate=115200
serialPortName=COM15
simCardNumber=-1
-viewCenterX=-76.97
-viewCenterY=8.49
+viewCenterX=-148.00
+viewCenterY=278.47
diff --git a/src/Mqttmessage/Client.java b/src/Mqttmessage/Client.java
new file mode 100644
index 0000000..90ff9f1
--- /dev/null
+++ b/src/Mqttmessage/Client.java
@@ -0,0 +1,119 @@
+package Mqttmessage;
+
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+
+/**
+ * MQTT瀹㈡埛绔伐鍏风被
+ * 鐢ㄤ簬杩炴帴MQTT鏈嶅姟鍣ㄥ苟璁㈤槄涓婚
+ */
+public class Client {
+
+ private String host;
+ private String topic;
+ private String clientId;
+ private MqttClient client;
+ private MqttConnectOptions options;
+
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param host MQTT鏈嶅姟鍣ㄥ湴鍧�锛屾牸寮忥細tcp://ip:port
+ * @param topic 璁㈤槄鐨勪富棰�
+ * @param clientId 瀹㈡埛绔疘D锛屼笉鑳介噸澶�
+ */
+ public Client(String host, String topic, String clientId) {
+
+ this.host = host;
+ this.topic = topic;
+ this.clientId = clientId;
+ this.options = new MqttConnectOptions();
+ this.options.setCleanSession(true);
+ }
+
+ /**
+ * 杩炴帴鍒癕QTT鏈嶅姟鍣�
+ * @throws MqttException 杩炴帴澶辫触鏃舵姏鍑哄紓甯�
+ */
+ public void connect() throws MqttException {
+ if (client != null && client.isConnected()) {
+ return;
+ }
+ client = new MqttClient(host, clientId);
+ client.connect(options);
+ client.setCallback(new PushCallback());
+ }
+
+ /**
+ * 璁㈤槄涓婚
+ * @param qos 鏈嶅姟璐ㄩ噺绛夌骇锛�0-2
+ * @throws MqttException 璁㈤槄澶辫触鏃舵姏鍑哄紓甯�
+ */
+ public void subscribe(int qos) throws MqttException {
+ if (client == null || !client.isConnected()) {
+ connect();
+ }
+ client.subscribe(topic, qos);
+ }
+
+ /**
+ * 璁㈤槄涓婚锛堥粯璁oS涓�2锛�
+ * @throws MqttException 璁㈤槄澶辫触鏃舵姏鍑哄紓甯�
+ */
+ public void subscribe() throws MqttException {
+ subscribe(2);
+ }
+
+ /**
+ * 鏂紑杩炴帴
+ * @throws MqttException 鏂紑杩炴帴澶辫触鏃舵姏鍑哄紓甯�
+ */
+ public void disconnect() throws MqttException {
+ if (client != null && client.isConnected()) {
+ client.disconnect();
+ }
+ }
+
+ /**
+ * 妫�鏌ユ槸鍚﹀凡杩炴帴
+ * @return true琛ㄧず宸茶繛鎺ワ紝false琛ㄧず鏈繛鎺�
+ */
+ public boolean isConnected() {
+ return client != null && client.isConnected();
+ }
+
+ /**
+ * 鑾峰彇MQTT瀹㈡埛绔疄渚�
+ * @return MqttClient瀹炰緥
+ */
+ public MqttClient getClient() {
+ return client;
+ }
+
+ /**
+ * 绀轰緥鐢ㄦ硶
+ */
+
+ public static void test() {
+ try {
+ String host = "tcp://39.99.43.227:1883";
+ String deiveID="6258";
+ String clientId = "hxzkMQTT";
+ String clientId2 = "hxzkMQTT2";
+ String topic = "mower/"+deiveID+"/gps";
+ String topic2 = "mower/"+deiveID+"/response";
+ Client mqttClient = new Client(host, topic, clientId);
+ Client mqttClient1 = new Client(host, topic2, clientId2);
+ mqttClient.connect();
+ mqttClient.subscribe();
+
+ mqttClient1.connect();
+ mqttClient1.subscribe();
+
+ // 淇濇寔绋嬪簭杩愯
+ //Thread.sleep(Long.MAX_VALUE);
+ } catch (MqttException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Mqttmessage/Entity/BasestationData.java b/src/Mqttmessage/Entity/BasestationData.java
new file mode 100644
index 0000000..058ec2c
--- /dev/null
+++ b/src/Mqttmessage/Entity/BasestationData.java
@@ -0,0 +1,25 @@
+package Mqttmessage.Entity;
+
+
+import lombok.Data;
+
+@Data
+public class BasestationData {
+
+ private String latitude_dm;
+ private String latitude_hemisphere;
+ private String longitude_dm;
+ private String longitude_hemisphere;
+ private double altitude;
+
+
+ public BasestationData(String latitude_dm, String latitude_hemisphere,
+ String longitude_dm, String longitude_hemisphere,
+ double altitude) {
+ this.latitude_dm = latitude_dm;
+ this.latitude_hemisphere = latitude_hemisphere;
+ this.longitude_dm = longitude_dm;
+ this.longitude_hemisphere = longitude_hemisphere;
+ this.altitude = altitude;
+ }
+}
diff --git a/src/Mqttmessage/Entity/CoordinatePoint.java b/src/Mqttmessage/Entity/CoordinatePoint.java
new file mode 100644
index 0000000..58d3d68
--- /dev/null
+++ b/src/Mqttmessage/Entity/CoordinatePoint.java
@@ -0,0 +1,18 @@
+package Mqttmessage.Entity;
+
+
+import lombok.Data;
+
+@Data
+public class CoordinatePoint {
+ private String x; // X鍧愭爣
+ private String y; // Y鍧愭爣
+
+ public CoordinatePoint() {
+ }
+
+ public CoordinatePoint(String x, String y) {
+ this.x = x;
+ this.y = y;
+ }
+}
diff --git a/src/Mqttmessage/Entity/GPSData.java b/src/Mqttmessage/Entity/GPSData.java
new file mode 100644
index 0000000..0b8882f
--- /dev/null
+++ b/src/Mqttmessage/Entity/GPSData.java
@@ -0,0 +1,136 @@
+package Mqttmessage.Entity;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GPSData{
+ // JSON涓殑鍘熷瀛楁
+ private String msg_id; // 娑堟伅鍞竴鏍囪瘑
+ private Long timestamp; // 鏃堕棿鎴筹紙姣锛�
+ private String device_id; // 璁惧缂栧彿
+ private String data_type; // 鏁版嵁绫诲瀷
+ private String gps_raw; // 鍘熷GPS鏁版嵁
+
+ // IMU鏁版嵁鍐呴儴绫�
+ private IMUData imu_data;
+
+ // 鐘舵�佹暟鎹紙鏂板崗璁牸寮忥級
+ private StatusInfo status;
+
+ // NMEA GGA瑙f瀽缁撴灉锛堝彲閫夛紝鏍规嵁闇�瑕佹坊鍔狅級
+ private GGAData ggaData;
+
+ /**
+ * 鑾峰彇鍘熷GPS鏁版嵁
+ * @return 鍘熷GPS鏁版嵁瀛楃涓�
+ */
+ public String getGps_raw() {
+ return gps_raw;
+ }
+
+ /**
+ * 璁剧疆鍘熷GPS鏁版嵁
+ * @param gps_raw 鍘熷GPS鏁版嵁瀛楃涓�
+ */
+ public void setGps_raw(String gps_raw) {
+ this.gps_raw = gps_raw;
+ }
+
+
+
+
+
+ /**
+ * IMU鏁版嵁鍐呴儴绫伙紙绠�鍖栫増锛屽彧鍖呭惈瑙掑害淇℃伅锛�
+ */
+ @Data
+ @NoArgsConstructor
+ public static class IMUData {
+ private Double roll; // 妯粴瑙� 瑙掑害
+ private Double pitch; // 淇话瑙� 瑙掑害
+ private Double yaw; // 鍋忚埅瑙� 瑙掑害
+
+ /**
+ * 甯﹀弬鏁扮殑鏋勯�犲嚱鏁�
+ * @param roll 妯粴瑙� 瑙掑害
+ * @param pitch 淇话瑙� 瑙掑害
+ * @param yaw 鍋忚埅瑙� 瑙掑害
+ */
+ public IMUData(Double roll, Double pitch, Double yaw) {
+ this.roll = roll;
+ this.pitch = pitch;
+ this.yaw = yaw;
+ }
+ }
+
+ /**
+ * 鐘舵�佷俊鎭唴閮ㄧ被锛堜笌StatusData涓殑StatusInfo淇濇寔涓�鑷达級
+ */
+ @Data
+ @NoArgsConstructor
+ public static class StatusInfo {
+ private Integer battery_level; // 鐢垫睜鐢甸噺鐧惧垎姣�
+ private Double battery_voltage; // 鐢垫睜鐢靛帇
+ private String operation_mode; // 鎿嶄綔妯″紡锛歮anual, auto, emergency_stop
+ private String motor_status; // 鐢垫満鐘舵�侊細stopped, running, error
+ private String blade_status; // 鍒�鐗囩姸鎬侊細stopped, rotating
+ private Integer blade_height; // 鍒�鐩橀珮搴� 鍘樼背
+ private Integer self_check_status; // 鑷鐘舵�侊細1-瀹屾垚锛�0-鏈畬鎴�
+ private Integer error_code; // 閿欒浠g爜
+ private String error_message; // 閿欒淇℃伅
+
+ /**
+ * 甯﹀弬鏁扮殑鏋勯�犲嚱鏁�
+ * @param battery_level 鐢垫睜鐢甸噺鐧惧垎姣�
+ * @param battery_voltage 鐢垫睜鐢靛帇
+ * @param operation_mode 鎿嶄綔妯″紡锛歮anual, auto, emergency_stop
+ * @param motor_status 鐢垫満鐘舵�侊細stopped, running, error
+ * @param blade_status 鍒�鐗囩姸鎬侊細stopped, rotating
+ * @param blade_height 鍒�鐩橀珮搴� 鍘樼背
+ * @param self_check_status 鑷鐘舵�侊細1-瀹屾垚锛�0-鏈畬鎴�
+ * @param error_code 閿欒浠g爜
+ * @param error_message 閿欒淇℃伅
+ */
+ public StatusInfo(Integer battery_level, Double battery_voltage, String operation_mode,
+ String motor_status, String blade_status, Integer blade_height,
+ Integer self_check_status, Integer error_code, String error_message) {
+ this.battery_level = battery_level;
+ this.battery_voltage = battery_voltage;
+ this.operation_mode = operation_mode;
+ this.motor_status = motor_status;
+ this.blade_status = blade_status;
+ this.blade_height = blade_height;
+ this.self_check_status = self_check_status;
+ this.error_code = error_code;
+ this.error_message = error_message;
+ }
+ }
+
+ /**
+ * GGA鏁版嵁瑙f瀽绫伙紙鍙�夛紝鐢ㄤ簬瀛樺偍瑙f瀽鍚庣殑GGA鏁版嵁锛�
+ */
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class GGAData {
+ private String utcTime; // UTC鏃堕棿
+ private String latitude; // 绾害锛堝師濮嬪害鍒嗘牸寮忥級
+ private String latitudeDir; // 绾害鏂瑰悜
+ private String longitude; // 缁忓害锛堝師濮嬪害鍒嗘牸寮忥級
+ private String longitudeDir;// 缁忓害鏂瑰悜
+ private Integer gpsQuality; // GPS璐ㄩ噺鎸囩ず
+ private Integer satellites; // 浣跨敤鐨勫崼鏄熸暟閲�
+ private Double hdop; // 姘村钩绮惧害鍥犲瓙
+ private Double altitude; // 娴锋嫈楂樺害
+ private String altitudeUnit;// 娴锋嫈楂樺害鍗曚綅
+ private Double geoidSep; // 澶у湴姘村噯闈㈠垎绂�
+ private String geoidSepUnit;// 澶у湴姘村噯闈㈠垎绂诲崟浣�
+ private String age; // 宸垎GPS鏁版嵁鏈熼檺
+ private String stationId; // 宸垎鍙傝�冨熀绔欐爣鍙�
+ }
+}
\ No newline at end of file
diff --git a/src/Mqttmessage/Entity/HxzkPathMessage.java b/src/Mqttmessage/Entity/HxzkPathMessage.java
new file mode 100644
index 0000000..616b3e7
--- /dev/null
+++ b/src/Mqttmessage/Entity/HxzkPathMessage.java
@@ -0,0 +1,28 @@
+package Mqttmessage.Entity;
+
+
+import lombok.Data;
+
+@Data
+public class HxzkPathMessage {
+ private String msg_id;
+ private long timestamp;
+ private String user_id;
+ private String device_id;
+ private String command;
+ private BasestationData basestation_data;
+ private PathData path_data;
+
+ public HxzkPathMessage(String msg_id, long timestamp, String user_id,
+ String device_id, String command,
+ BasestationData basestation_data, PathData path_data) {
+ this.msg_id = msg_id;
+ this.timestamp = timestamp;
+ this.user_id = user_id;
+ this.device_id = device_id;
+ this.command = command;
+ this.basestation_data = basestation_data;
+ this.path_data = path_data;
+ }
+
+}
diff --git a/src/Mqttmessage/Entity/PathData.java b/src/Mqttmessage/Entity/PathData.java
new file mode 100644
index 0000000..559247f
--- /dev/null
+++ b/src/Mqttmessage/Entity/PathData.java
@@ -0,0 +1,33 @@
+package Mqttmessage.Entity;
+
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PathData {
+
+ private String path_id;
+ private String coordinate_system;
+ private List<CoordinatePoint> boundary_points;
+ private List<CoordinatePoint> navigation_points;
+
+ private String mowing_pattern;
+ private Integer boundary_point_count; // 杈圭晫鐐规暟閲� 涓婇檺鏁伴噺1000
+ private Integer navigation_point_count; // 瀵艰埅鐐规暟閲� 涓婇檺鏁伴噺4000
+
+ public PathData(String path_id, String coordinate_system,
+ List<CoordinatePoint> boundary_points,
+ List<CoordinatePoint> navigation_points,
+ String mowing_pattern,
+ Integer boundary_point_count, Integer navigation_point_count) {
+ this.path_id = path_id;
+ this.coordinate_system = coordinate_system;
+ this.boundary_points = boundary_points;
+ this.navigation_points = navigation_points;
+ this.mowing_pattern = mowing_pattern;
+ this.boundary_point_count = boundary_point_count;
+ this.navigation_point_count = navigation_point_count;
+ }
+}
diff --git a/src/Mqttmessage/Entity/ResponseData.java b/src/Mqttmessage/Entity/ResponseData.java
new file mode 100644
index 0000000..358bb82
--- /dev/null
+++ b/src/Mqttmessage/Entity/ResponseData.java
@@ -0,0 +1,71 @@
+package Mqttmessage.Entity;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * 璁惧鍝嶅簲娑堟伅瀹炰綋绫�
+ */
+@Data
+public class ResponseData {
+
+ @JsonProperty("msg_id")
+ private String msgId;
+
+ private long timestamp;
+
+ @JsonProperty("device_id")
+ private String deviceId;
+
+ @JsonProperty("original_msg_id")
+ private String originalMsgId;
+
+ private ResponseInfo response;
+
+ // 鏋勯�犲嚱鏁�
+ public ResponseData() {
+ }
+
+ public ResponseData(String msgId, long timestamp, String deviceId, String originalMsgId, ResponseInfo response) {
+ this.msgId = msgId;
+ this.timestamp = timestamp;
+ this.deviceId = deviceId;
+ this.originalMsgId = originalMsgId;
+ this.response = response;
+ }
+
+ /**
+ * 鍝嶅簲淇℃伅鍐呴儴绫�
+ */
+ @Data
+ public static class ResponseInfo {
+ private String status;
+ private String command;
+
+ @JsonProperty("error_code")
+ private int errorCode;
+
+ @JsonProperty("error_message")
+ private String errorMessage;
+
+ @JsonProperty("additional_info")
+ private Map<String, Object> additionalInfo;
+
+ public ResponseInfo() {
+ }
+
+ public ResponseInfo(String status, String command, int errorCode, String errorMessage,
+ Map<String, Object> additionalInfo) {
+ this.status = status;
+ this.command = command;
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ this.additionalInfo = additionalInfo;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/Mqttmessage/Entity/StatusData.java b/src/Mqttmessage/Entity/StatusData.java
new file mode 100644
index 0000000..7f3d27c
--- /dev/null
+++ b/src/Mqttmessage/Entity/StatusData.java
@@ -0,0 +1,41 @@
+package Mqttmessage.Entity;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StatusData {
+ // 娑堟伅鍩烘湰淇℃伅
+ private String msg_id; // 娑堟伅鍞竴鏍囪瘑
+ private Long timestamp; // 鏃堕棿鎴�
+ private String device_id; // 璁惧缂栧彿
+ private String data_type; // 鏁版嵁绫诲瀷
+
+ // 鐘舵�佹暟鎹唴閮ㄧ被
+ private StatusInfo status;
+
+ /**
+ * 鐘舵�佷俊鎭唴閮ㄧ被
+ */
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class StatusInfo {
+ private Integer battery_level; // 鐢垫睜鐢甸噺鐧惧垎姣�
+ private Double battery_voltage; // 鐢垫睜鐢靛帇
+ private String operation_mode; // 鎿嶄綔妯″紡锛歮anual, auto, emergency_stop
+ private String motor_status; // 鐢垫満鐘舵�侊細stopped, running, error
+ private String blade_status; // 鍒�鐗囩姸鎬侊細stopped, rotating
+ private Integer blade_height; // 鍒�鐩橀珮搴� 鍘樼背
+ private Integer self_check_status; // 鑷鐘舵�侊細1-瀹屾垚锛�0-鏈畬鎴�
+ private Integer error_code; // 閿欒浠g爜
+ private String error_message; // 閿欒淇℃伅
+ private Integer signal_strength; // 淇″彿寮哄害锛堜繚鐣欏悜鍚庡吋瀹癸級
+ private String gps_fix_status; // GPS瀹氫綅鐘舵�侊細no_fix, float, fixed锛堜繚鐣欏悜鍚庡吋瀹癸級
+ private Integer satellites_tracked; // 璺熻釜鍗槦鏁伴噺锛堜繚鐣欏悜鍚庡吋瀹癸級
+ }
+}
\ No newline at end of file
diff --git a/src/Mqttmessage/PushCallback.java b/src/Mqttmessage/PushCallback.java
new file mode 100644
index 0000000..ab97989
--- /dev/null
+++ b/src/Mqttmessage/PushCallback.java
@@ -0,0 +1,35 @@
+package Mqttmessage;
+
+
+
+import Mqttmessage.Util.DeviceMessageParser;
+import Mqttmessage.Entity.GPSData;
+import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import udpdell.UDPServer;
+
+
+public class PushCallback implements MqttCallback {
+
+
+ public void connectionLost(Throwable cause) {
+ // 杩炴帴涓㈠け鍚庯紝涓�鑸湪杩欓噷闈㈣繘琛岄噸杩�
+ System.out.println("杩炴帴鏂紑锛屽彲浠ュ仛閲嶈繛");
+
+ }
+
+ public void deliveryComplete(IMqttDeliveryToken token) {
+ System.out.println("deliveryComplete---------" + token.isComplete());
+ }
+
+ public void messageArrived(String topic, MqttMessage message) throws Exception {
+ // subscribe鍚庡緱鍒扮殑娑堟伅浼氭墽琛屽埌杩欓噷闈�
+ // System.out.println(message);
+ GPSData gpsData = DeviceMessageParser.parseGPSData(new String(message.getPayload()));//瑙f瀽GNSS鏁版嵁
+ //ResponseData responseData = DeviceMessageParser.parseResponseData(new String(message.getPayload()));//瑙f瀽鍝嶅簲鏁版嵁
+ String gpsRaw = gpsData.getGps_raw();
+ UDPServer.processSerialData(gpsRaw);
+ }
+
+}
diff --git a/src/Mqttmessage/Util/DeviceMessageParser.java b/src/Mqttmessage/Util/DeviceMessageParser.java
new file mode 100644
index 0000000..d09a56d
--- /dev/null
+++ b/src/Mqttmessage/Util/DeviceMessageParser.java
@@ -0,0 +1,161 @@
+package Mqttmessage.Util;
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import Mqttmessage.Entity.GPSData;
+import Mqttmessage.Entity.ResponseData;
+
+/**
+ * 璁惧娑堟伅瑙f瀽宸ュ叿绫� - 鏀寔GPS鏁版嵁銆佺姸鎬佹暟鎹拰鍝嶅簲鏁版嵁鐨勮В鏋�
+ */
+public class DeviceMessageParser {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ static {
+ // 閰嶇疆ObjectMapper
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+
+ /**
+ * 瑙f瀽涓篏PS鏁版嵁瀵硅薄锛堟敮鎸佹柊鍗忚鏍煎紡锛屽寘鍚獹PS銆両MU鍜岀姸鎬佹暟鎹級
+ * @param jsonStr JSON瀛楃涓�
+ * @return GPSData瀵硅薄
+ * @throws JsonProcessingException 瑙f瀽寮傚父
+ */
+ public static GPSData parseGPSData(String jsonStr) throws JsonProcessingException {
+ GPSData gpsData = objectMapper.readValue(jsonStr, GPSData.class);
+
+ // 鍙�夛細瑙f瀽GGA鏁版嵁
+ /* if (gpsData.getGps_raw() != null && gpsData.getGps_raw().startsWith("$GNGGA")) {
+ GPSData.GGAData ggaData = parseGGA(gpsData.getGps_raw());
+ gpsData.setGgaData(ggaData);
+ }*/
+
+ return gpsData;
+ }
+
+
+
+ /**
+ * 瑙f瀽涓哄搷搴旀暟鎹璞�
+ * @param jsonStr JSON瀛楃涓�
+ * @return ResponseData瀵硅薄
+ * @throws JsonProcessingException 瑙f瀽寮傚父
+ */
+ public static ResponseData parseResponseData(String jsonStr) throws JsonProcessingException {
+ return objectMapper.readValue(jsonStr, ResponseData.class);
+ }
+
+ /**
+ * 瑙f瀽GGA鏍煎紡鐨凣PS鏁版嵁锛堝彲閫夊姛鑳斤級
+ * @param ggaString GGA鏍煎紡瀛楃涓�
+ * @return GGAData瀵硅薄
+ */
+ /*public static GPSData.GGAData parseGGA(String ggaString) {
+ // 绉婚櫎鍙兘鐨勬牎楠屽拰閮ㄥ垎
+ String cleanString = ggaString.split("\\*")[0];
+ String[] fields = cleanString.split(",");
+
+ if (fields.length < 15) {
+ return null;
+ }
+
+ GPSData.GGAData ggaData = new GPSData.GGAData();
+
+ try {
+ ggaData.setUtcTime(fields[1]);
+ ggaData.setLatitude(fields[2]);
+ ggaData.setLatitudeDir(fields[3]);
+ ggaData.setLongitude(fields[4]);
+ ggaData.setLongitudeDir(fields[5]);
+
+ if (!fields[6].isEmpty()) {
+ ggaData.setGpsQuality(Integer.parseInt(fields[6]));
+ }
+
+ if (!fields[7].isEmpty()) {
+ ggaData.setSatellites(Integer.parseInt(fields[7]));
+ }
+
+ if (!fields[8].isEmpty()) {
+ ggaData.setHdop(Double.parseDouble(fields[8]));
+ }
+
+ if (!fields[9].isEmpty()) {
+ ggaData.setAltitude(Double.parseDouble(fields[9]));
+ }
+
+ ggaData.setAltitudeUnit(fields[10]);
+
+ if (!fields[11].isEmpty()) {
+ ggaData.setGeoidSep(Double.parseDouble(fields[11]));
+ }
+
+ ggaData.setGeoidSepUnit(fields[12]);
+
+ if (fields.length > 13) {
+ ggaData.setAge(fields[13]);
+ }
+
+ if (fields.length > 14) {
+ ggaData.setStationId(fields[14]);
+ }
+
+ } catch (Exception e) {
+ // 瑙f瀽寮傚父锛岃繑鍥為儴鍒嗚В鏋愮殑鏁版嵁鎴杗ull
+ System.err.println("瑙f瀽GGA鏁版嵁鏃跺嚭閿�: " + e.getMessage());
+ }
+
+ return ggaData;
+ }*/
+
+ /**
+ * 灏嗘秷鎭璞¤浆鎹负JSON瀛楃涓�
+ * @param message 娑堟伅瀵硅薄锛圙PSData銆丼tatusData鎴朢esponseData锛�
+ * @return JSON瀛楃涓�
+ * @throws JsonProcessingException 杞崲寮傚父
+ */
+ public static String toJson(Object message) throws JsonProcessingException {
+ return objectMapper.writeValueAsString(message);
+ }
+
+ /**
+ * 鑾峰彇ObjectMapper瀹炰緥锛堢敤浜庨珮绾ф搷浣滐級
+ * @return ObjectMapper瀹炰緥
+ */
+ public static ObjectMapper getObjectMapper() {
+ return objectMapper;
+ }
+
+ /**
+ * 娑堟伅绫诲瀷鏋氫妇
+ */
+ public enum MessageType {
+ GPS("gps"),
+ STATUS("status"),
+ RESPONSE("response");
+
+ private final String type;
+
+ MessageType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public static MessageType fromString(String type) {
+ for (MessageType mt : MessageType.values()) {
+ if (mt.type.equalsIgnoreCase(type)) {
+ return mt;
+ }
+ }
+ throw new IllegalArgumentException("鏈煡鐨勬秷鎭被鍨�: " + type);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/lujing/AoxinglujingNoObstacle.java b/src/lujing/AoxinglujingNoObstacle.java
index 95f5f96..fe884f9 100644
--- a/src/lujing/AoxinglujingNoObstacle.java
+++ b/src/lujing/AoxinglujingNoObstacle.java
@@ -5,381 +5,236 @@
import java.util.List;
/**
- * 鏃犻殰纰嶇墿鍑稿舰鑽夊湴璺緞瑙勫垝绫� (缁堟瀬浼樺寲鐗�)
- * 鐗规�э細
- * 1. 鏈�灏忔姇褰卞搴︽柟鍚戦�夋嫨 (鏁堢巼鏈�楂橈紝杞集鏈�灏�)
- * 2. 杈圭紭杞粨浼樺厛鍒囧壊 (鏃犳瑙掕鐩�)
- * 3. 鏀寔澶栭儴浼犲叆宸插寘鍚噸鍙犵巼鐨勫搴﹀弬鏁�
+ * 鍑稿舰鑽夊湴璺緞瑙勫垝 (鍥磋竟浼樺寲鐗�)
+ * 浼樺寲閲嶇偣锛氬洿杈瑰潗鏍囧榻愭壂鎻忚捣鐐广�佸叏璺緞杩炶疮鎬�
*/
public class AoxinglujingNoObstacle {
- // 寮曞叆鏋佸皬鍊肩敤浜庢诞鐐规暟姣旇緝锛屽鐞嗗嚑浣曠簿搴﹁宸�
private static final double EPSILON = 1e-6;
- /**
- * 璺緞娈电被
- */
- public static class PathSegment {
- public Point start;
- public Point end;
- public boolean isMowing; // true涓哄壊鑽夊伐浣滄锛宖alse涓鸿繃娓℃
-
- public PathSegment(Point start, Point end, boolean isMowing) {
- this.start = start;
- this.end = end;
- this.isMowing = isMowing;
- }
-
- @Override
- public String toString() {
- return String.format("[%s -> %s, isMowing=%b]", start, end, isMowing);
- }
- }
-
- /**
- * 鍧愭爣鐐圭被
- */
public static class Point {
public double x, y;
-
- public Point(double x, double y) {
- this.x = x;
- this.y = y;
- }
-
+ public Point(double x, double y) { this.x = x; this.y = y; }
@Override
- public String toString() {
- return String.format("(%.4f, %.4f)", x, y);
+ public String toString() { return String.format("%.6f,%.6f", x, y); }
+ }
+
+ public static class PathSegment {
+ public Point start, end;
+ public boolean isMowing;
+ public PathSegment(Point start, Point end, boolean isMowing) {
+ this.start = start; this.end = end; this.isMowing = isMowing;
}
}
/**
- * 瀵瑰鍏紑鐨勯潤鎬佽皟鐢ㄦ柟娉�
- *
- * @param boundaryCoordsStr 鍦板潡杈圭晫鍧愭爣瀛楃涓� "x1,y1;x2,y2;..."
- * @param mowingWidthStr 鏈夋晥鍓茶崏瀹藉害瀛楃涓� (宸插寘鍚噸鍙犵巼)锛屽 "0.30"
- * @param safetyMarginStr 瀹夊叏杈硅窛瀛楃涓诧紝濡� "0.2"
- * @return 璺緞娈靛垪琛�
+ * 瀵瑰涓绘帴鍙�
*/
public static List<PathSegment> planPath(String boundaryCoordsStr, String mowingWidthStr, String safetyMarginStr) {
- // 1. 瑙f瀽鍙傛暟
List<Point> originalPolygon = parseCoords(boundaryCoordsStr);
- double mowingWidth;
- double safetyMargin;
+ double width = Double.parseDouble(mowingWidthStr);
+ double margin = Double.parseDouble(safetyMarginStr);
- try {
- mowingWidth = Double.parseDouble(mowingWidthStr);
- safetyMargin = Double.parseDouble(safetyMarginStr);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("鍓茶崏瀹藉害鎴栧畨鍏ㄨ竟璺濇牸寮忛敊璇�");
- }
-
- // 2. 璋冪敤鏍稿績绠楁硶
- return planPathCore(originalPolygon, mowingWidth, safetyMargin);
+ return planPathCore(originalPolygon, width, margin);
}
- /**
- * 鏍稿績绠楁硶閫昏緫
- */
- private static List<PathSegment> planPathCore(List<Point> originalPolygon, double width, double safetyMargin) {
- if (originalPolygon == null || originalPolygon.size() < 3) {
- return new ArrayList<>(); // 鎴栨姏鍑哄紓甯革紝瑙嗕笟鍔¢渶姹傝�屽畾
- }
+ private static List<PathSegment> planPathCore(List<Point> originalPolygon, double width, double margin) {
+ if (originalPolygon.size() < 3) return new ArrayList<>();
- // 纭繚澶氳竟褰㈡槸閫嗘椂閽堟柟鍚�
+ // 1. 纭繚閫嗘椂閽堝苟杩涜瀹夊叏鍐呯缉
ensureCCW(originalPolygon);
+ List<Point> workArea = shrinkPolygon(originalPolygon, margin);
+ if (workArea.size() < 3) return new ArrayList<>();
- // 1. 鏍规嵁瀹夊叏杈硅窛鍐呯缉锛屽緱鍒板疄闄呬綔涓氬尯鍩�
- List<Point> workAreaPolygon = shrinkPolygon(originalPolygon, safetyMargin);
+ // 2. 棰勮绠楁渶浼樿搴﹀拰濉厖璺緞鐨勭涓�涓偣
+ double bestAngle = findOptimalScanAngle(workArea);
+ Point firstScanStart = getFirstScanStartPoint(workArea, bestAngle, width);
- // 濡傛灉鍐呯缉鍚庡尯鍩熷け鏁堬紙濡傚湴鍧楀お灏忥級锛岃繑鍥炵┖璺緞
- if (workAreaPolygon.size() < 3) {
- return new ArrayList<>();
- }
+ // 3. 瀵归綈鍥磋竟璧风偣锛氳鍥磋竟鐨勬渶鍚庝竴涓偣鍒氬ソ杩炴帴鎵弿濉厖鐨勮捣鐐�
+ List<Point> alignedWorkArea = alignBoundaryToStart(workArea, firstScanStart);
List<PathSegment> finalPath = new ArrayList<>();
- // 2. [浼樺寲] 浼樺厛鐢熸垚杞粨璺緞 (Contour Pass)
- // 娌夸綔涓氳竟鐣岃蛋涓�鍦堬紝纭繚杈圭紭鏁撮綈涓旀棤閬楁紡
- addContourPath(workAreaPolygon, finalPath);
-
- // 3. [浼樺寲] 璁$畻鏈�浣虫壂鎻忚搴�
- // 瀵绘壘璁╁杈瑰舰鎶曞奖楂樺害鏈�灏忕殑瑙掑害锛屼粠鑰屾渶灏忓寲杞集娆℃暟
- double bestAngle = findOptimalScanAngle(workAreaPolygon);
-
- // 4. 鐢熸垚鍐呴儴寮撳瓧褰㈣矾寰�
- // 鐩存帴浣跨敤浼犲叆鐨� width (宸插寘鍚噸鍙犵巼)
- List<PathSegment> zigZagPaths = generateClippedMowingLines(workAreaPolygon, bestAngle, width);
-
- // 5. 杩炴帴杞粨璺緞鍜屽紦瀛楀舰璺緞
- if (!finalPath.isEmpty() && !zigZagPaths.isEmpty()) {
- Point contourEnd = finalPath.get(finalPath.size() - 1).end;
- Point zigzagStart = zigZagPaths.get(0).start;
-
- // 濡傛灉杞粨缁堢偣涓庡紦瀛楀舰璧风偣涓嶉噸鍚堬紝娣诲姞杩囨浮娈�
- if (distanceSq(contourEnd, zigzagStart) > EPSILON) {
- finalPath.add(new PathSegment(contourEnd, zigzagStart, false));
- }
+ // 4. 銆愮涓�闃舵銆戞坊鍔犲洿杈瑰潗鏍囪矾寰�
+ for (int i = 0; i < alignedWorkArea.size(); i++) {
+ Point p1 = alignedWorkArea.get(i);
+ Point p2 = alignedWorkArea.get((i + 1) % alignedWorkArea.size());
+ finalPath.add(new PathSegment(p1, p2, true));
}
- // 6. 鍚堝苟寮撳瓧褰㈣矾寰�
- finalPath.addAll(connectPathSegments(zigZagPaths));
+ // 5. 銆愮浜岄樁娈点�戠敓鎴愬唴閮ㄥ紦瀛楀舰璺緞
+ // 浠庡洿杈归棴鍚堢偣锛坅lignedWorkArea.get(0)锛夊紑濮嬭繛鎺�
+ Point currentPos = alignedWorkArea.get(0);
+ List<PathSegment> zigZagLines = generateZigZagPath(workArea, bestAngle, width, currentPos);
+
+ finalPath.addAll(zigZagLines);
return finalPath;
}
- // ================= 鏍稿績閫昏緫杈呭姪鏂规硶 =================
-
/**
- * 娣诲姞杞粨璺緞 (鍥寸潃澶氳竟褰㈣蛋涓�鍦�)
+ * 瀵绘壘寮撳瓧褰㈢殑绗竴鏉$嚎鐨勮捣鐐�
*/
- private static void addContourPath(List<Point> polygon, List<PathSegment> path) {
- int n = polygon.size();
- for (int i = 0; i < n; i++) {
- Point p1 = polygon.get(i);
- Point p2 = polygon.get((i + 1) % n);
- path.add(new PathSegment(p1, p2, true));
- }
- }
-
- /**
- * 瀵绘壘鏈�浼樻壂鎻忚搴� (鏈�灏忔姇褰遍珮搴︽硶)
- */
- private static double findOptimalScanAngle(List<Point> polygon) {
- double minHeight = Double.MAX_VALUE;
- double bestAngle = 0;
- int n = polygon.size();
-
- // 閬嶅巻姣忎竴鏉¤竟锛岃绠椾互璇ヨ竟涓衡�滃簳鈥濇椂锛屽杈瑰舰鐨勯珮搴�
- for (int i = 0; i < n; i++) {
- Point p1 = polygon.get(i);
- Point p2 = polygon.get((i + 1) % n);
-
- // 褰撳墠杈圭殑瑙掑害
- double currentAngle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
-
- // 璁$畻鍦ㄨ繖涓搴︿笅鐨勬姇褰遍珮搴�
- double height = calculatePolygonHeightAtAngle(polygon, currentAngle);
-
- if (height < minHeight) {
- minHeight = height;
- bestAngle = currentAngle;
- }
- }
- return bestAngle;
- }
-
- /**
- * 璁$畻澶氳竟褰㈠湪鐗瑰畾鏃嬭浆瑙掑害涓嬬殑Y杞存姇褰遍珮搴�
- */
- private static double calculatePolygonHeightAtAngle(List<Point> poly, double angle) {
+ private static Point getFirstScanStartPoint(List<Point> polygon, double angle, double width) {
+ List<Point> rotated = rotatePolygon(polygon, -angle);
double minY = Double.MAX_VALUE;
- double maxY = -Double.MAX_VALUE;
+ for (Point p : rotated) minY = Math.min(minY, p.y);
- double cos = Math.cos(-angle);
- double sin = Math.sin(-angle);
-
- for (Point p : poly) {
- // 鍙渶璁$畻鏃嬭浆鍚庣殑Y鍧愭爣
- double rotatedY = p.x * sin + p.y * cos;
- if (rotatedY < minY) minY = rotatedY;
- if (rotatedY > maxY) maxY = rotatedY;
- }
- return maxY - minY;
+ double startY = minY + width + EPSILON;
+ List<Double> xIntersections = getXIntersections(rotated, startY);
+ if (xIntersections.isEmpty()) return polygon.get(0);
+
+ Collections.sort(xIntersections);
+ return rotatePoint(new Point(xIntersections.get(0), startY), angle);
}
- private static List<PathSegment> generateClippedMowingLines(List<Point> polygon, double angle, double width) {
- List<PathSegment> segments = new ArrayList<>();
-
- // 鏃嬭浆澶氳竟褰㈣嚦姘村钩
- List<Point> rotatedPoly = rotatePolygon(polygon, -angle);
-
- double minY = Double.MAX_VALUE;
- double maxY = -Double.MAX_VALUE;
- for (Point p : rotatedPoly) {
- if (p.y < minY) minY = p.y;
- if (p.y > maxY) maxY = p.y;
- }
-
- // 璧峰鎵弿绾夸綅缃細
- // 浠� minY + width/2 寮�濮嬶紝鍥犱负涔嬪墠宸茬粡璧颁簡杞粨绾�(Contour Pass)銆�
- // 杞粨绾胯礋璐f竻鐞嗚竟缂樺尯鍩燂紝鍐呴儴濉厖绾夸繚鎸� width 鐨勯棿璺濆嵆鍙��
- // 鍔犱笂 EPSILON 闃叉娴偣鏁板垰濂借惤鍦ㄨ竟鐣屼笂瀵艰嚧鐨勫垽鏂宸�
- double currentY = minY + width / 2.0 + EPSILON;
-
- while (currentY < maxY) {
- List<Double> xIntersections = new ArrayList<>();
- int n = rotatedPoly.size();
-
- for (int i = 0; i < n; i++) {
- Point p1 = rotatedPoly.get(i);
- Point p2 = rotatedPoly.get((i + 1) % n);
-
- // 蹇界暐姘村钩绾挎
- if (Math.abs(p1.y - p2.y) < EPSILON) continue;
-
- double minP = Math.min(p1.y, p2.y);
- double maxP = Math.max(p1.y, p2.y);
-
- if (currentY >= minP && currentY < maxP) {
- double x = p1.x + (currentY - p1.y) * (p2.x - p1.x) / (p2.y - p1.y);
- xIntersections.add(x);
- }
+ /**
+ * 閲嶇粍澶氳竟褰㈤《鐐癸紝浣垮緱绱㈠紩0鐨勭偣鏈�闈犺繎濉厖璧风偣
+ */
+ private static List<Point> alignBoundaryToStart(List<Point> polygon, Point target) {
+ int bestIdx = 0;
+ double minDist = Double.MAX_VALUE;
+ for (int i = 0; i < polygon.size(); i++) {
+ double d = Math.hypot(polygon.get(i).x - target.x, polygon.get(i).y - target.y);
+ if (d < minDist) {
+ minDist = d;
+ bestIdx = i;
}
-
- Collections.sort(xIntersections);
-
- if (xIntersections.size() >= 2) {
- // 鍙栨渶宸﹀拰鏈�鍙充氦鐐�
- double xStart = xIntersections.get(0);
- double xEnd = xIntersections.get(xIntersections.size() - 1);
-
- if (xEnd - xStart > EPSILON) {
- // 鍙嶅悜鏃嬭浆鍥炲師鍧愭爣绯�
- Point rStart = rotatePoint(new Point(xStart, currentY), angle);
- Point rEnd = rotatePoint(new Point(xEnd, currentY), angle);
- segments.add(new PathSegment(rStart, rEnd, true));
- }
- }
- // 姝ヨ繘
- currentY += width;
}
-
- return segments;
+ List<Point> aligned = new ArrayList<>();
+ for (int i = 0; i < polygon.size(); i++) {
+ aligned.add(polygon.get((bestIdx + i) % polygon.size()));
+ }
+ return aligned;
}
- private static List<PathSegment> connectPathSegments(List<PathSegment> lines) {
+ private static List<PathSegment> generateZigZagPath(List<Point> polygon, double angle, double width, Point startPoint) {
List<PathSegment> result = new ArrayList<>();
- if (lines.isEmpty()) return result;
+ List<Point> rotated = rotatePolygon(polygon, -angle);
- for (int i = 0; i < lines.size(); i++) {
- PathSegment currentLine = lines.get(i);
- Point actualStart, actualEnd;
+ double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
+ for (Point p : rotated) {
+ minY = Math.min(minY, p.y);
+ maxY = Math.max(maxY, p.y);
+ }
- // 寮撳瓧褰㈣鍒掞細鍋舵暟琛屾鍚戯紝濂囨暟琛屽弽鍚�
- if (i % 2 == 0) {
- actualStart = currentLine.start;
- actualEnd = currentLine.end;
- } else {
- actualStart = currentLine.end;
- actualEnd = currentLine.start;
+ Point currentPos = startPoint;
+ boolean leftToRight = true;
+ // 璧风偣浠� minY + width 寮�濮嬶紝鍥犱负杈圭紭宸茬粡鍥磋竟鍓茶繃
+ for (double y = minY + width; y < maxY - width / 2; y += width) {
+ List<Double> xInt = getXIntersections(rotated, y);
+ if (xInt.size() < 2) continue;
+ Collections.sort(xInt);
+
+ double xStart = leftToRight ? xInt.get(0) : xInt.get(xInt.size() - 1);
+ double xEnd = leftToRight ? xInt.get(xInt.size() - 1) : xInt.get(0);
+
+ Point pS = rotatePoint(new Point(xStart, y), angle);
+ Point pE = rotatePoint(new Point(xEnd, y), angle);
+
+ // 娣诲姞杩囨浮娈� (濡傛灉鏄粠鍥磋竟鍒囨崲杩囨潵鎴栬�呮崲琛�)
+ if (Math.hypot(currentPos.x - pS.x, currentPos.y - pS.y) > 0.05) {
+ result.add(new PathSegment(currentPos, pS, false));
}
-
- // 娣诲姞杩囨浮娈�
- if (i > 0) {
- Point prevEnd = result.get(result.size() - 1).end;
- if (distanceSq(prevEnd, actualStart) > EPSILON) {
- result.add(new PathSegment(prevEnd, actualStart, false));
- }
- }
-
- result.add(new PathSegment(actualStart, actualEnd, true));
+ result.add(new PathSegment(pS, pE, true));
+ currentPos = pE;
+ leftToRight = !leftToRight;
}
return result;
}
- // ================= 鍩虹鍑犱綍宸ュ叿 =================
-
- private static List<Point> parseCoords(String s) {
- List<Point> list = new ArrayList<>();
- if (s == null || s.trim().isEmpty()) return list;
-
- String[] parts = s.split(";");
- for (String part : parts) {
- String[] xy = part.split(",");
- if (xy.length >= 2) {
- try {
- double x = Double.parseDouble(xy[0].trim());
- double y = Double.parseDouble(xy[1].trim());
- list.add(new Point(x, y));
- } catch (NumberFormatException e) {
- // 蹇界暐鏍煎紡閿欒
- }
+ private static List<Double> getXIntersections(List<Point> rotatedPoly, double y) {
+ List<Double> xIntersections = new ArrayList<>();
+ int n = rotatedPoly.size();
+ for (int i = 0; i < n; i++) {
+ Point p1 = rotatedPoly.get(i);
+ Point p2 = rotatedPoly.get((i + 1) % n);
+ if ((p1.y <= y && p2.y > y) || (p2.y <= y && p1.y > y)) {
+ double x = p1.x + (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y);
+ xIntersections.add(x);
}
}
- return list;
+ return xIntersections;
}
- private static void ensureCCW(List<Point> polygon) {
- double sum = 0;
- for (int i = 0; i < polygon.size(); i++) {
- Point p1 = polygon.get(i);
- Point p2 = polygon.get((i + 1) % polygon.size());
- sum += (p2.x - p1.x) * (p2.y + p1.y);
- }
- if (sum > 0) {
- Collections.reverse(polygon);
- }
- }
+ // --- 鍑犱綍鍩虹宸ュ叿 ---
private static List<Point> shrinkPolygon(List<Point> polygon, double margin) {
- List<Point> newPoints = new ArrayList<>();
+ List<Point> result = new ArrayList<>();
int n = polygon.size();
-
for (int i = 0; i < n; i++) {
- Point p1 = polygon.get(i);
- Point p2 = polygon.get((i + 1) % n);
- Point p0 = polygon.get((i - 1 + n) % n);
+ Point pPrev = polygon.get((i - 1 + n) % n);
+ Point pCurr = polygon.get(i);
+ Point pNext = polygon.get((i + 1) % n);
- Line line1 = offsetLine(p1, p2, margin);
- Line line0 = offsetLine(p0, p1, margin);
+ double d1x = pCurr.x - pPrev.x, d1y = pCurr.y - pPrev.y;
+ double l1 = Math.hypot(d1x, d1y);
+ double d2x = pNext.x - pCurr.x, d2y = pNext.y - pCurr.y;
+ double l2 = Math.hypot(d2x, d2y);
- Point intersection = getIntersection(line0, line1);
- if (intersection != null) {
- newPoints.add(intersection);
- }
+ double n1x = -d1y / l1, n1y = d1x / l1;
+ double n2x = -d2y / l2, n2y = d2x / l2;
+
+ double bx = n1x + n2x, by = n1y + n2y;
+ double bLen = Math.hypot(bx, by);
+ if (bLen < EPSILON) { bx = n1x; by = n1y; }
+ else { bx /= bLen; by /= bLen; }
+
+ double cosHalf = n1x * bx + n1y * by;
+ double d = margin / Math.max(cosHalf, 0.1);
+ result.add(new Point(pCurr.x + bx * d, pCurr.y + by * d));
}
- return newPoints;
+ return result;
}
- private static class Line {
- double a, b, c;
- public Line(double a, double b, double c) { this.a = a; this.b = b; this.c = c; }
+ private static double findOptimalScanAngle(List<Point> polygon) {
+ double minH = Double.MAX_VALUE;
+ double bestA = 0;
+ for (int i = 0; i < polygon.size(); i++) {
+ Point p1 = polygon.get(i), p2 = polygon.get((i + 1) % polygon.size());
+ double angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
+ double h = calculatePolygonHeightAtAngle(polygon, angle);
+ if (h < minH) { minH = h; bestA = angle; }
+ }
+ return bestA;
}
- private static Line offsetLine(Point p1, Point p2, double dist) {
- double dx = p2.x - p1.x;
- double dy = p2.y - p1.y;
- double len = Math.sqrt(dx * dx + dy * dy);
-
- if (len < EPSILON) return new Line(0, 0, 0);
-
- double nx = -dy / len;
- double ny = dx / len;
-
- // 鍚戝乏渚у钩绉伙紙鍋囪閫嗘椂閽堬級
- double newX = p1.x + nx * dist;
- double newY = p1.y + ny * dist;
-
- double a = -dy;
- double b = dx;
- double c = -a * newX - b * newY;
- return new Line(a, b, c);
- }
-
- private static Point getIntersection(Line l1, Line l2) {
- double det = l1.a * l2.b - l2.a * l1.b;
- if (Math.abs(det) < EPSILON) return null;
- double x = (l1.b * l2.c - l2.b * l1.c) / det;
- double y = (l2.a * l1.c - l1.a * l2.c) / det;
- return new Point(x, y);
+ private static double calculatePolygonHeightAtAngle(List<Point> poly, double angle) {
+ double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
+ double sin = Math.sin(-angle), cos = Math.cos(-angle);
+ for (Point p : poly) {
+ double ry = p.x * sin + p.y * cos;
+ minY = Math.min(minY, ry); maxY = Math.max(maxY, ry);
+ }
+ return maxY - minY;
}
private static Point rotatePoint(Point p, double angle) {
- double cos = Math.cos(angle);
- double sin = Math.sin(angle);
- return new Point(p.x * cos - p.y * sin, p.x * sin + p.y * cos);
+ double c = Math.cos(angle), s = Math.sin(angle);
+ return new Point(p.x * c - p.y * s, p.x * s + p.y * c);
}
private static List<Point> rotatePolygon(List<Point> poly, double angle) {
List<Point> res = new ArrayList<>();
- for (Point p : poly) {
- res.add(rotatePoint(p, angle));
- }
+ for (Point p : poly) res.add(rotatePoint(p, angle));
return res;
}
- private static double distanceSq(Point p1, Point p2) {
- return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
+ private static void ensureCCW(List<Point> poly) {
+ double s = 0;
+ for (int i = 0; i < poly.size(); i++) {
+ Point p1 = poly.get(i), p2 = poly.get((i + 1) % poly.size());
+ s += (p2.x - p1.x) * (p2.y + p1.y);
+ }
+ if (s > 0) Collections.reverse(poly);
+ }
+
+ private static List<Point> parseCoords(String s) {
+ List<Point> list = new ArrayList<>();
+ for (String p : s.split(";")) {
+ String[] xy = p.split(",");
+ if (xy.length >= 2) list.add(new Point(Double.parseDouble(xy[0]), Double.parseDouble(xy[1])));
+ }
+ return list;
}
}
\ No newline at end of file
diff --git a/src/lujing/MowingPathGenerationPage.java b/src/lujing/MowingPathGenerationPage.java
index ad0dcc4..bbbe001 100644
--- a/src/lujing/MowingPathGenerationPage.java
+++ b/src/lujing/MowingPathGenerationPage.java
@@ -125,11 +125,31 @@
// 鍦板潡杈圭晫
boundaryArea = createInfoTextArea(boundaryValue != null ? boundaryValue : "", true, 6);
- contentPanel.add(createTextAreaSection("鍦板潡杈圭晫", boundaryArea));
+ String boundaryTitle = "鍦板潡杈圭晫";
+ if (boundaryValue != null && !boundaryValue.trim().isEmpty() && !"-1".equals(boundaryValue.trim())) {
+ int boundaryCount = boundaryValue.split(";").length;
+ boundaryTitle = "鍦板潡杈圭晫 (" + boundaryCount + "鐐�)";
+ }
+ contentPanel.add(createTextAreaSection(boundaryTitle, boundaryArea));
// 闅滅鐗╁潗鏍�
obstacleArea = createInfoTextArea(obstacleValue != null ? obstacleValue : "", true, 6);
- contentPanel.add(createTextAreaSection("闅滅鐗╁潗鏍�", obstacleArea));
+ String obstacleTitle = "闅滅鐗╁潗鏍�";
+ if (obstacleValue != null && !obstacleValue.trim().isEmpty() && !"-1".equals(obstacleValue.trim())) {
+ // 闅滅鐗╁潗鏍囨牸寮忓彲鑳芥槸绌烘牸鍒嗛殧鐨勫涓殰纰嶇墿锛屾瘡涓殰纰嶇墿鐢ㄥ垎鍙峰垎闅斿潗鏍囩偣
+ // 璁$畻鎵�鏈夐殰纰嶇墿鐨勬�诲潗鏍囩偣鏁�
+ String[] obstacles = obstacleValue.trim().split("\\s+");
+ int totalObstaclePoints = 0;
+ for (String obstacle : obstacles) {
+ if (obstacle != null && !obstacle.trim().isEmpty()) {
+ totalObstaclePoints += obstacle.split(";").length;
+ }
+ }
+ if (totalObstaclePoints > 0) {
+ obstacleTitle = "闅滅鐗╁潗鏍� (" + totalObstaclePoints + "鐐�)";
+ }
+ }
+ contentPanel.add(createTextAreaSection(obstacleTitle, obstacleArea));
// 鍓茶崏瀹藉害
widthField = createInfoTextField(widthValue != null ? widthValue : "", true);
@@ -175,7 +195,12 @@
String existingPath = prepareCoordinateForEditor(dikuai.getPlannedPath());
String pathSeed = initialGeneratedPath != null ? initialGeneratedPath : existingPath;
pathArea = createInfoTextArea(pathSeed != null ? pathSeed : "", true, 10);
- contentPanel.add(createTextAreaSection("鍓茶崏璺緞鍧愭爣", pathArea));
+ String pathTitle = "鍓茶崏璺緞鍧愭爣";
+ if (pathSeed != null && !pathSeed.trim().isEmpty() && !"-1".equals(pathSeed.trim())) {
+ int pathCount = pathSeed.split(";").length;
+ pathTitle = "鍓茶崏璺緞鍧愭爣 (" + pathCount + "鐐�)";
+ }
+ contentPanel.add(createTextAreaSection(pathTitle, pathArea));
JScrollPane dialogScrollPane = new JScrollPane(contentPanel);
dialogScrollPane.setBorder(BorderFactory.createEmptyBorder());
diff --git a/src/udpdell/UDPServer.java b/src/udpdell/UDPServer.java
index b59526f..65c9ffc 100644
--- a/src/udpdell/UDPServer.java
+++ b/src/udpdell/UDPServer.java
@@ -1,4 +1,5 @@
package udpdell;
+
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
@@ -7,6 +8,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
+import Mqttmessage.Client;
import gecaoji.Device;
import zhuye.Coordinate;
@@ -35,6 +37,7 @@
thread.setDaemon(false); // 淇濇寔 JVM 鎸佺画瀛樻椿
thread.start();
serverThread = thread;
+// Client.test();
return thread;
}
@@ -83,28 +86,28 @@
}
// 妫�鏌ュ寘澶存槸鍚︽纭�
- if (!fields[0].equals("$GNGGA")) {
+ if (!fields[0].equals("$GNGGA") && !fields[0].equals("$GPGGA") && !fields[0].equals("$GBGGA")) {
System.err.println("Invalid message header: " + fields[0]);
return;
}
int sequence = incrementReceivedPacketCounter();
System.out.println("鏀跺埌浜嗗樊鍒嗘暟鎹�(" + sequence + ")锛�" + message);
-
+
// 浣跨敤Gpstoxuzuobiao澶勭悊骞惰幏鍙朮Y鍧愭爣
double[] xy = Gpstoxuzuobiao.processGNGGAToXY(message);
if (xy != null) {
// 杩欓噷鍙互灏哫Y鍧愭爣浼犻�掔粰鍏朵粬鏂规硶浣跨敤
// System.out.println("UDP GNGGA -> XY: " + xy[0] + ", " + xy[1]);
}
-
+
Coordinate.parseGNGGAToCoordinateList(message);
int count = Coordinate.coordinates.size();
System.out.println("savenum:" + count);
Device.updateFromGNGGA(message, fields[15]);
}
-
- /**澶勭悊涓插彛鎺ユ敹鍒扮殑鏁版嵁*/
+
+ /** 澶勭悊涓插彛鎺ユ敹鍒扮殑鏁版嵁 */
public static void processSerialData(String message) {
String[] fields = message.split(",");
// 妫�鏌ュ瓧娈垫暟閲忔槸鍚﹀畬鏁�
@@ -114,20 +117,20 @@
}
// 妫�鏌ュ寘澶存槸鍚︽纭�
- if (!fields[0].equals("$GNGGA")) {
+ if (!fields[0].equals("$GNGGA")&&!fields[0].equals("$GPGGA")&&!fields[0].equals("$GBGGA")) {
System.err.println("Invalid message header: " + fields[0]);
return;
}
int sequence = incrementReceivedPacketCounter();
System.out.println("鏀跺埌浜嗕覆鍙f暟鎹�(" + sequence + ")锛�" + message);
-
+
// 浣跨敤Gpstoxuzuobiao澶勭悊骞惰幏鍙朮Y鍧愭爣
double[] xy = Gpstoxuzuobiao.processGNGGAToXY(message);
if (xy != null) {
// 杩欓噷鍙互灏哫Y鍧愭爣浼犻�掔粰鍏朵粬鏂规硶浣跨敤
// System.out.println("Serial GNGGA -> XY: " + xy[0] + ", " + xy[1]);
}
-
+
Coordinate.dellchuankougngga(message);
int count = Coordinate.coordinates.size();
System.out.println("savenum:" + count);
--
Gitblit v1.10.0