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