From 019a83b893a4d6c6f939f7162b96b188470202bf Mon Sep 17 00:00:00 2001
From: zjj <3272660260@qq.com>
Date: 星期一, 17 二月 2025 13:49:45 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/jxgtwcs' into jxgtwcs

---
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java                 |   22 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java         |  376 +++++++++++---
 zy-asrs-wcs/src/main/resources/application.yml                                           |    5 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/constant/DeviceRedisConstant.java          |    6 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java        |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonResult.java                   |   18 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java                 |    3 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java        |    1 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java                |   14 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java                   |   12 
 zy-asrs-wcs/src/main/resources/cpu.py                                                    |  151 ++++++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java                |   95 ++-
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java                    |    2 
 zy-asrs-wcs/src/main/resources/similarity.py                                             |   47 +
 zy-asrs-flow/src/pages/deviceConfig/device/index.jsx                                     |   13 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java                          |    2 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateSolution.java               |  127 +++-
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateUtils.java                  |  166 +++++-
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java                 |    2 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java              |  201 ++++---
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/Motion.java                        |    6 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java |   92 +++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java                      |   11 
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java                 |   61 ++
 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonSimilarityResult.java         |   16 
 25 files changed, 1,157 insertions(+), 295 deletions(-)

diff --git a/zy-asrs-flow/src/pages/deviceConfig/device/index.jsx b/zy-asrs-flow/src/pages/deviceConfig/device/index.jsx
index 9297c7d..88254ba 100644
--- a/zy-asrs-flow/src/pages/deviceConfig/device/index.jsx
+++ b/zy-asrs-flow/src/pages/deviceConfig/device/index.jsx
@@ -116,6 +116,19 @@
             width: 48,
         },
         {
+          title: 'ID',
+          dataIndex: 'id',
+          valueType: 'text',
+          hidden: false,
+          width: 140,
+          filterDropdown: (props) => <TextFilter
+            name='uuid'
+            {...props}
+            actionRef={actionRef}
+            setSearchParam={setSearchParam}
+          />,
+        },
+        {
             title: '缂栧彿',
             dataIndex: 'uuid',
             valueType: 'text',
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
index bfdc8e9..6f0c851 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/MainProcess.java
@@ -47,6 +47,8 @@
 
                     // 鍏ュ簱  ===>> 鍏ュ簱绔欏埌鍫嗗灈鏈虹珯锛屾牴鎹潯鐮佹壂鎻忕敓鎴愬叆搴撳伐浣滄。
                     mainService.generateInboundWrk(); // 缁勬墭
+                    mainService.palletInbound();//鍏ュ簱-鎵樼洏杩涘簱
+
                     // 瑙f瀽鍑哄簱宸ヤ綔妗�
                     mainService.analyzeOutBoundTask();
                     // 瑙f瀽鍏ュ簱宸ヤ綔妗�
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
index 5d825f1..22114d2 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/action/ShuttleAction.java
@@ -691,7 +691,7 @@
             response = shuttleThread.updateLocation(command);
         }
 
-//        News.info("鍥涘悜绌挎杞﹀懡浠や笅鍙戯紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", device.getDeviceNo(), JSON.toJSON(command));
+        News.info("鍥涘悜绌挎杞﹀懡浠や笅鍙戯紝绌挎杞﹀彿={}锛屼换鍔℃暟鎹�={}", device.getDeviceNo(), JSON.toJSON(command));
         return response;
     }
 
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java
index 54c919e..6f02b7b 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/MotionDto.java
@@ -1,6 +1,7 @@
 package com.zy.asrs.wcs.core.domain.dto;
 
 import com.zy.asrs.wcs.core.BuildSupport;
+import com.zy.asrs.wcs.rcs.entity.Device;
 import lombok.Data;
 
 /**
@@ -38,6 +39,8 @@
     //鎵ц瀹屾垚鍚庢槸鍚﹂噴鏀剧┛姊溅锛岄粯璁や笉閲婃斁  1: 閲婃斁  0: 涓嶉噴鏀�
     private Integer releaseShuttle;
 
+    private Device shuttleDevice;
+
     public static MotionDto build(BuildSupport<MotionDto> support) {
         MotionDto dto = new MotionDto();
 
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java
index e4e2b82..0c7deb5 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/domain/dto/StaDto.java
@@ -7,6 +7,8 @@
 
     private Integer staNo;
 
+    private Integer deviceStaNo;
+
     private Integer barcode;
 
     private Integer backSta;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java
index a24e153..c2a8b9e 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/BasConveyor.java
@@ -130,6 +130,18 @@
     @ApiModelProperty(value= "鎷f枡鍑哄簱绔欑偣鍒楄〃")
     private String pickOutSta;
 
+    /**
+     * 璁惧鍏ュ簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "璁惧鍏ュ簱绔欑偣鍒楄〃")
+    private String deviceInSta;
+
+    /**
+     * 璁惧鍑哄簱绔欑偣鍒楄〃
+     */
+    @ApiModelProperty(value= "璁惧鍑哄簱绔欑偣鍒楄〃")
+    private String deviceOutSta;
+
     public BasConveyor() {}
 
     public BasConveyor(Long deviceId,Integer conveyorNo,Long updateBy,Long createBy,Date createTime,Date updateTime,String memo,Integer deleted,Long hostId,String inSta,String emptyInSta,String pickInSta,String outSta,String emptyOutSta,String pickOutSta) {
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/Motion.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/Motion.java
index 0344879..a252e80 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/Motion.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/entity/Motion.java
@@ -237,6 +237,12 @@
     @ApiModelProperty(value= "鎵�灞炴満鏋�")
     private Long hostId;
 
+    /**
+     * 绉诲姩璺緞
+     */
+    @ApiModelProperty(value= "绉诲姩璺緞")
+    private String movePath;
+
     public Motion() {}
 
     public Motion(String uuid,Integer taskNo,String serialNo,String title,Integer priority,Integer sync,Long motionCtg,Long motionSts,Long deviceCtg,String device,String origin,Integer oriDrt,String target,Integer tarDrt,String dockNo,Date ioTime,Date startTime,Date endTime,Date errTime,Long errCode,String errDesc,String temp,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer deleted,Long hostId) {
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
index 6660003..e645221 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
@@ -101,8 +101,8 @@
 
             String shuttleLocNo = shuttleProtocol.getCurrentLocNo();
 
-            //鑾峰彇璺濈鐩爣浣嶇疆鏈�杩戠殑绌洪棽鍙崲灞傛彁鍗囨満
-            LiftThread liftThread = liftDispatcher.searchIdleLift(shuttleLocNo, task.getHostId(), true);
+            //鑾峰彇璺濈鐩爣浣嶇疆鏈�杩戠殑鍙崲灞傛彁鍗囨満(鍙兘涓嶇┖闂�)
+            LiftThread liftThread = liftDispatcher.searchLift(shuttleLocNo, task.getHostId(), true);
             if (liftThread == null) {
                 return motionList;
             }
@@ -158,21 +158,21 @@
             // 鍏ュ簱鐩爣灞傛湁绌挎杞�
             if (Utils.getLev(shuttleLocNo) == Utils.getLev(task.getDestLoc())) {
 
-                // 鎻愬崌鏈鸿浇璐хЩ鍔�
-                motionList.addAll(kernelService.liftMoveGoods(
-                        MotionDto.build((dto -> {
-                            dto.setLiftNo(transferLiftDevice.getId().intValue());
-                            dto.setLev(1);//鍏夋嘲1灞傛槸杈撻�佺嚎灞�
-                            dto.setStaNo(31004);//鍏ュ簱绔欑偣
-                        }))
-                        , MotionDto.build((dto -> {
-                            dto.setLiftNo(transferLiftDevice.getId().intValue());
-                            dto.setLev(Utils.getLev(task.getDestLoc()));
-                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
-                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
-                            dto.setReleaseLift(1);//鎵ц瀹屾垚鍚庨噴鏀炬彁鍗囨満
-                        }))
-                ));
+//                // 鎻愬崌鏈鸿浇璐хЩ鍔�
+//                motionList.addAll(kernelService.liftMoveGoods(
+//                        MotionDto.build((dto -> {
+//                            dto.setLiftNo(transferLiftDevice.getId().intValue());
+//                            dto.setLev(1);//鍏夋嘲1灞傛槸杈撻�佺嚎灞�
+//                            dto.setStaNo(31004);//鍏ュ簱绔欑偣
+//                        }))
+//                        , MotionDto.build((dto -> {
+//                            dto.setLiftNo(transferLiftDevice.getId().intValue());
+//                            dto.setLev(Utils.getLev(task.getDestLoc()));
+//                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
+//                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
+//                            dto.setReleaseLift(1);//鎵ц瀹屾垚鍚庨噴鏀炬彁鍗囨満
+//                        }))
+//                ));
 
                 // 绌挎杞﹁蛋琛岃嚦鎻愬崌鏈哄簱浣嶅緟鏈轰綅
                 motionList.addAll(kernelService.shuttleMove(
@@ -182,6 +182,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(standbyLocNoTo);
                         })),
                         MotionCtgType.SHUTTLE_MOVE
@@ -204,6 +205,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(destLoc);
 //                            dto.setReleaseLift(2);//鎵ц涓噴鏀炬彁鍗囨満
@@ -225,21 +227,21 @@
              */
             } else {
 
-                // 鎻愬崌鏈鸿浇璐хЩ鍔�
-                motionList.addAll(kernelService.liftMoveGoods(
-                        MotionDto.build((dto -> {
-                            dto.setLiftNo(transferLiftDevice.getId().intValue());
-                            dto.setLev(1);//鍏夋嘲1灞傛槸杈撻�佺嚎灞�
-                            dto.setStaNo(31004);//鍏ュ簱绔欑偣
-                        }))
-                        , MotionDto.build((dto -> {
-                            dto.setLiftNo(transferLiftDevice.getId().intValue());
-                            dto.setLev(Utils.getLev(task.getDestLoc()));
-                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
-                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
-                            dto.setReleaseLift(1);//鎵ц瀹屾垚鍚庨噴鏀炬彁鍗囨満
-                        }))
-                ));
+//                // 鎻愬崌鏈鸿浇璐хЩ鍔�
+//                motionList.addAll(kernelService.liftMoveGoods(
+//                        MotionDto.build((dto -> {
+//                            dto.setLiftNo(transferLiftDevice.getId().intValue());
+//                            dto.setLev(1);//鍏夋嘲1灞傛槸杈撻�佺嚎灞�
+//                            dto.setStaNo(31004);//鍏ュ簱绔欑偣
+//                        }))
+//                        , MotionDto.build((dto -> {
+//                            dto.setLiftNo(transferLiftDevice.getId().intValue());
+//                            dto.setLev(Utils.getLev(task.getDestLoc()));
+//                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
+//                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
+//                            dto.setReleaseLift(1);//鎵ц瀹屾垚鍚庨噴鏀炬彁鍗囨満
+//                        }))
+//                ));
 
                 // 绌挎杞﹁蛋琛岃嚦鎻愬崌鏈哄簱浣嶅緟鏈轰綅
                 motionList.addAll(kernelService.shuttleMove(
@@ -249,6 +251,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(standbyLocNoTo);
                         })),
@@ -289,6 +292,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(liftLocNoTo);
                         })),
@@ -341,6 +345,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(standbyLocNoFrom);
                         })),
                         MotionCtgType.SHUTTLE_MOVE_FROM_LIFT
@@ -381,6 +386,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(destLoc);
                         })),
@@ -521,6 +527,7 @@
                             })),
                             MotionDto.build((dto -> {
                                 dto.setShuttleNo(shuttleDevice.getId().intValue());
+                                dto.setShuttleDevice(shuttleDevice);
                                 dto.setLocNo(originLoc);
                             })),
                             MotionCtgType.SHUTTLE_MOVE
@@ -545,6 +552,7 @@
                             })),
                             MotionDto.build((dto -> {
                                 dto.setShuttleNo(shuttleDevice.getId().intValue());
+                                dto.setShuttleDevice(shuttleDevice);
                                 dto.setLocNo(lastPathStartLoc);
                             })),
                             MotionCtgType.SHUTTLE_TRANSPORT
@@ -559,6 +567,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(standbyLocNoTo);
                             dto.setStaNo(getStaByLev(Utils.getLev(task.getOriginLoc())));//杈撻�佺珯
@@ -583,6 +592,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(standbyLocs);
                             dto.setSync(0);//寮傛鎵ц
                             dto.setReleaseShuttle(1);//鎵ц瀹屾垚鍚庨噴鏀惧皬杞�
@@ -632,6 +642,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(standbyLocNoTo);
                         })),
@@ -672,6 +683,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(liftLocNoTo);
                         })),
@@ -724,6 +736,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(standbyLocNoFrom);
                         })),
                         MotionCtgType.SHUTTLE_MOVE_FROM_LIFT
@@ -756,6 +769,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(originLoc);
                         })),
                         MotionCtgType.SHUTTLE_MOVE
@@ -779,6 +793,7 @@
                             })),
                             MotionDto.build((dto -> {
                                 dto.setShuttleNo(shuttleDevice.getId().intValue());
+                                dto.setShuttleDevice(shuttleDevice);
                                 dto.setLocNo(lastPathStartLoc);
                             })),
                             MotionCtgType.SHUTTLE_TRANSPORT
@@ -793,6 +808,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLiftNo(transferLiftDevice.getId().intValue());
                             dto.setLocNo(standbyLocNoFrom);
                             dto.setStaNo(getStaByLev(Utils.getLev(task.getOriginLoc())));//杈撻�佺珯
@@ -817,6 +833,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(standbyLocs);
                             dto.setSync(0);//寮傛鎵ц
                             dto.setReleaseShuttle(1);//鎵ц瀹屾垚鍚庨噴鏀惧皬杞�
@@ -950,6 +967,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(chargeLocNo);
                     })),
                     MotionCtgType.SHUTTLE_MOVE
@@ -965,6 +983,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(standbyLocNoTo);
                     })),
                     MotionCtgType.SHUTTLE_MOVE
@@ -995,6 +1014,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLiftNo(transferLiftDevice.getId().intValue());
                         dto.setLocNo(liftLocNoTo);
                     })),
@@ -1047,6 +1067,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(standbyLocNoFrom);
                     })),
                     MotionCtgType.SHUTTLE_MOVE_FROM_LIFT
@@ -1068,6 +1089,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(chargeLocNo);
                     })),
                     MotionCtgType.SHUTTLE_MOVE
@@ -1136,6 +1158,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(locNo);
                     })),
                     MotionCtgType.SHUTTLE_MOVE
@@ -1190,6 +1213,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(shuttleDevice.getId().intValue());
+                            dto.setShuttleDevice(shuttleDevice);
                             dto.setLocNo(locNo);
                         })),
                         MotionCtgType.SHUTTLE_MOVE
@@ -1230,6 +1254,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLiftNo(liftDevice.getId().intValue());
                         dto.setLocNo(standbyLocNoTo);
                     })),
@@ -1270,6 +1295,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLiftNo(liftDevice.getId().intValue());
                         dto.setLocNo(liftLocNoTo);
                     })),
@@ -1322,6 +1348,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(standbyLocNoFrom);
                     })),
                     MotionCtgType.SHUTTLE_MOVE_FROM_LIFT
@@ -1353,6 +1380,7 @@
                     })),
                     MotionDto.build((dto -> {
                         dto.setShuttleNo(shuttleDevice.getId().intValue());
+                        dto.setShuttleDevice(shuttleDevice);
                         dto.setLocNo(locNo);
                     })),
                     MotionCtgType.SHUTTLE_MOVE
@@ -1408,6 +1436,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(device.getId().intValue());
+                            dto.setShuttleDevice(device);
                             dto.setLocNo(targetLoc);
                         })),
                         MotionCtgType.SHUTTLE_MOVE
@@ -1460,6 +1489,7 @@
                             })),
                             MotionDto.build((dto -> {
                                 dto.setShuttleNo(device.getId().intValue());
+                                dto.setShuttleDevice(device);
                                 dto.setLocNo(sourceLoc);
                             })),
                             MotionCtgType.SHUTTLE_MOVE
@@ -1481,6 +1511,7 @@
                         })),
                         MotionDto.build((dto -> {
                             dto.setShuttleNo(device.getId().intValue());
+                            dto.setShuttleDevice(device);
                             dto.setLocNo(targetLoc);
                         })),
                         MotionCtgType.SHUTTLE_TRANSPORT
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java
index dd37a7e..2d75205 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/KernelService.java
@@ -1,11 +1,21 @@
 package com.zy.asrs.wcs.core.kernel;
 
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zy.asrs.framework.exception.CoolException;
 import com.zy.asrs.wcs.core.domain.dto.MotionDto;
+import com.zy.asrs.wcs.core.model.NavigateNode;
 import com.zy.asrs.wcs.core.model.enums.DeviceCtgType;
 import com.zy.asrs.wcs.core.model.enums.MotionCtgType;
 import com.zy.asrs.wcs.core.entity.Motion;
+import com.zy.asrs.wcs.core.model.enums.NavigationMapType;
 import com.zy.asrs.wcs.core.service.MotionService;
 import com.zy.asrs.wcs.core.utils.LiftDispatcher;
+import com.zy.asrs.wcs.core.utils.NavigateUtils;
+import com.zy.asrs.wcs.core.utils.Utils;
+import com.zy.asrs.wcs.rcs.News;
+import com.zy.asrs.wcs.rcs.entity.Device;
+import com.zy.asrs.wcs.rcs.service.DeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -22,6 +32,10 @@
     private MotionService motionService;
     @Autowired
     private LiftDispatcher liftDispatcher;
+    @Autowired
+    private NavigateUtils navigateUtils;
+    @Autowired
+    private DeviceService deviceService;
 
     // agv -----------------------------------------------------------------------------
     @Deprecated
@@ -321,6 +335,14 @@
                 motion.setReleaseLift(target.getReleaseLift());
             }
 
+            if (motion.getOrigin() != null && motion.getTarget() != null) {
+                List<NavigateNode> nodeList = navigateUtils.calc(motion.getOrigin(), motion.getTarget(), NavigationMapType.NONE_LOCK.id, Utils.getShuttlePoints(Integer.parseInt(target.getShuttleDevice().getDeviceNo()), Utils.getLev(motion.getTarget())));
+                if (nodeList == null) {
+                    throw new CoolException(motion.getOrigin() + " dash " + motion.getTarget() + " can't find navigate path!");
+                }
+                motion.setMovePath(JSON.toJSONString(nodeList));
+            }
+
         }));
 
         return motionList;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java
index 0854719..ad64f8b 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/ShuttleCommandService.java
@@ -3,6 +3,7 @@
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zy.asrs.framework.common.Cools;
+import com.zy.asrs.framework.common.SpringUtils;
 import com.zy.asrs.framework.exception.CoolException;
 import com.zy.asrs.wcs.common.ExecuteSupport;
 import com.zy.asrs.wcs.core.action.LiftAction;
@@ -15,6 +16,7 @@
 import com.zy.asrs.wcs.core.utils.*;
 import com.zy.asrs.wcs.rcs.News;
 import com.zy.asrs.wcs.rcs.cache.SlaveConnection;
+import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant;
 import com.zy.asrs.wcs.rcs.entity.Device;
 import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType;
 import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
@@ -24,6 +26,8 @@
 import com.zy.asrs.wcs.rcs.thread.DevpThread;
 import com.zy.asrs.wcs.rcs.thread.LiftThread;
 import com.zy.asrs.wcs.rcs.thread.ShuttleThread;
+import com.zy.asrs.wcs.system.entity.Dict;
+import com.zy.asrs.wcs.system.service.DictService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -63,6 +67,10 @@
     private BasConveyorStaService basConveyorStaService;
     @Autowired
     private ShuttleDispatcher shuttleDispatcher;
+    @Autowired
+    private NavigateUtils navigateUtils;
+    @Autowired
+    private DictService dictService;
 
     // 璁$畻
     public Boolean accept(Motion motion) {
@@ -126,6 +134,11 @@
                 }
                 shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread);
                 shuttleTaskModeType = ShuttleTaskModeType.SHUTTLE_MOVE;
+
+                if (!checkSimilarityPath(motion, assignCommand)) {
+                    return false;
+                }
+
                 break;
             case SHUTTLE_TRANSPORT://绌挎杞﹁浇璐ц璧�
                 // 濡傛灉宸茬粡鍦ㄥ綋鍓嶆潯鐮佸垯杩囨护
@@ -136,6 +149,10 @@
                 }
                 shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread);
                 shuttleTaskModeType = ShuttleTaskModeType.TRANSPORT;
+
+                if (!checkSimilarityPath(motion, assignCommand)) {
+                    return false;
+                }
 
                 if (motion.getReleaseLift() == 2) {//鎵ц涓噴鏀炬彁鍗囨満
                     task.setLiftNo(0);
@@ -177,15 +194,30 @@
                 }
                 shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread);
                 shuttleTaskModeType = ShuttleTaskModeType.TRANSPORT_TO_CONVEYOR;
+
+                if (!checkSimilarityPath(motion, assignCommand)) {
+                    return false;
+                }
+
                 break;
             case SHUTTLE_MOVE_LIFT_PALLET://绌挎杞﹂《鍗囧苟绉诲姩
                 shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread);
                 shuttleTaskModeType = ShuttleTaskModeType.MOVE_PALLET_LIFT;
+
+                if (!checkSimilarityPath(motion, assignCommand)) {
+                    return false;
+                }
+
                 shuttleCommands.add(0, shuttleThread.getLiftCommand(motion.getTaskNo(), true));
                 break;
             case SHUTTLE_MOVE_DOWN_PALLET://绌挎杞︾Щ鍔ㄥ苟鎵樼洏涓嬮檷
                 shuttleCommands = this.shuttleAssignCommand(motion.getOrigin(), motion.getTarget(), NavigationMapType.DFX.id, assignCommand, shuttleThread);
                 shuttleTaskModeType = ShuttleTaskModeType.MOVE_PALLET_DOWN;
+
+                if (!checkSimilarityPath(motion, assignCommand)) {
+                    return false;
+                }
+
                 shuttleCommands.add(shuttleCommands.size(), shuttleThread.getLiftCommand(motion.getTaskNo(), false));
                 break;
             case SHUTTLE_MOVE_FROM_LIFT://鍑烘彁鍗囨満
@@ -519,7 +551,7 @@
         //鑾峰彇灏忚溅绉诲姩閫熷害
         Integer runSpeed = Optional.ofNullable(basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>().eq(BasShuttle::getDeviceId, assignCommand.getDeviceId())).getRunSpeed()).orElse(1000);
         Long hostId = shuttleThread.getDevice().getHostId();
-        List<NavigateNode> nodeList = NavigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), Utils.getLev(startLocNo)));
+        List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), Utils.getLev(startLocNo)));
         if (nodeList == null) {
             News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo);
             return null;
@@ -532,7 +564,7 @@
 
         List<ShuttleCommand> commands = new ArrayList<>();
         //鑾峰彇鍒嗘璺緞
-        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList);
+        ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
         //灏嗘瘡涓�娈佃矾寰勫垎鎴恈ommand鎸囦护
         for (ArrayList<NavigateNode> nodes : data) {
             //寮�濮嬭矾寰�
@@ -540,7 +572,7 @@
 
             //鐩爣璺緞
             NavigateNode endPath = nodes.get(nodes.size() - 1);
-            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
+            Integer allDistance = navigateUtils.getCurrentPathAllDistance(nodes);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
             //閫氳繃xy鍧愭爣灏忚溅浜岀淮鐮�
             String startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ(), hostId);
             //閫氳繃xy鍧愭爣灏忚溅浜岀淮鐮�
@@ -575,7 +607,7 @@
         //鑾峰彇灏忚溅绉诲姩閫熷害
         Integer runSpeed = Optional.ofNullable(basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>().eq(BasShuttle::getDeviceId, assignCommand.getDeviceId())).getRunSpeed()).orElse(1000);
         Long hostId = shuttleThread.getDevice().getHostId();
-        List<NavigateNode> nodeList = NavigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), Utils.getLev(startLocNo)));
+        List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), Utils.getLev(startLocNo)));
         if (nodeList == null) {
             News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo);
             return null;
@@ -588,7 +620,7 @@
 
         List<ShuttleCommand> commands = new ArrayList<>();
         //鑾峰彇鍒嗘璺緞
-        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList);
+        ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
         //灏嗘瘡涓�娈佃矾寰勫垎鎴恈ommand鎸囦护
         for (ArrayList<NavigateNode> nodes : data) {
             //寮�濮嬭矾寰�
@@ -596,7 +628,7 @@
 
             //鐩爣璺緞
             NavigateNode endPath = nodes.get(nodes.size() - 1);
-            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
+            Integer allDistance = navigateUtils.getCurrentPathAllDistance(nodes);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
             //閫氳繃xy鍧愭爣灏忚溅浜岀淮鐮�
             String startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ(), hostId);
             //閫氳繃xy鍧愭爣灏忚溅浜岀淮鐮�
@@ -612,5 +644,53 @@
         return commands;
     }
 
+    private boolean checkSimilarityPath(Motion motion, ShuttleAssignCommand assignCommand) {
+        String movePath = motion.getMovePath();
+        if (Cools.isEmpty(movePath)) {
+            return false;
+        }
+
+        Double similarityRef = 0.9D;
+        Dict similarityRefDict = dictService.getOne(new LambdaQueryWrapper<Dict>()
+                .eq(Dict::getFlag, "similarityRef")
+                .eq(Dict::getStatus, 1));
+        if (similarityRefDict != null) {
+            similarityRef = Double.parseDouble(similarityRefDict.getValue());
+        }
+
+        List<NavigateNode> originPath = JSON.parseArray(movePath, NavigateNode.class);
+        List<NavigateNode> finalPath = assignCommand.getNodes();
+
+        if (finalPath == null) {
+            return false;
+        }
+
+        Double similarity = navigateUtils.similarityPath(originPath, finalPath);
+        if (similarity <= similarityRef) {
+            Object object = redisUtil.get(DeviceRedisConstant.SIMILARITY_TIMES + motion.getTaskNo());
+            if (object == null) {
+                redisUtil.set(DeviceRedisConstant.SIMILARITY_TIMES + motion.getTaskNo(), System.currentTimeMillis(), 60 * 60 * 24);
+            }else {
+                long similarityTimeoutRef = 20L;//榛樿瓒呮椂20s
+                Dict similarityTimeoutDict = dictService.getOne(new LambdaQueryWrapper<Dict>()
+                        .eq(Dict::getFlag, "similarityTimeout")
+                        .eq(Dict::getStatus, 1));
+                if (similarityTimeoutDict != null) {
+                    similarityTimeoutRef = Long.parseLong(similarityTimeoutDict.getValue());
+                }
+
+                long recordTime = Long.parseLong(object.toString());
+                if (System.currentTimeMillis() - recordTime > (60 * similarityTimeoutRef)) {
+                    //瓒呮椂锛岀洿鎺ユ斁琛�
+                    return true;
+                }
+            }
+            News.error("{} dash {} path similarity mismatch!", motion.getOrigin(), motion.getTarget());
+            return false;
+        }
+
+        return true;
+    }
+
 
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonResult.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonResult.java
new file mode 100644
index 0000000..e0abb76
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonResult.java
@@ -0,0 +1,18 @@
+package com.zy.asrs.wcs.core.model;
+
+import lombok.Data;
+
+@Data
+public class PythonResult {
+
+    private String start;
+
+    private String target;
+
+    private String path;
+
+    private Double time;
+
+    private Integer calcResult;
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonSimilarityResult.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonSimilarityResult.java
new file mode 100644
index 0000000..31c0e42
--- /dev/null
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/PythonSimilarityResult.java
@@ -0,0 +1,16 @@
+package com.zy.asrs.wcs.core.model;
+
+import lombok.Data;
+
+@Data
+public class PythonSimilarityResult {
+
+    private String firstPath;
+
+    private String secondPath;
+
+    private Double similarity;
+
+    private Integer calcResult;
+
+}
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java
index 352cb92..b1310e4 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/NavigationMapType.java
@@ -5,6 +5,7 @@
     NONE(-1, "鏃犺繃婊�"),
     DFX(1, "杩囨护搴撲綅鐘舵�丏FX"),    // 甯﹁揣璧拌
     NORMAL(2, "杩囨护搴撲綅鐘舵�乆"),   // 鏃犺揣璧拌
+    NONE_LOCK(3, "杩囨护搴撲綅鐘舵�乆锛屼笖鏃犺矾寰勯攣"),
     ;
 
     public Integer id;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
index 6a5ef93..2b00511 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
@@ -10,6 +10,8 @@
 import com.zy.asrs.framework.common.Cools;
 import com.zy.asrs.framework.common.R;
 import com.zy.asrs.framework.common.SnowflakeIdWorker;
+import com.zy.asrs.framework.exception.CoolException;
+import com.zy.asrs.wcs.core.action.LiftAction;
 import com.zy.asrs.wcs.core.domain.dto.MatDto;
 import com.zy.asrs.wcs.core.domain.dto.RedisMapDto;
 import com.zy.asrs.wcs.core.domain.dto.StaDto;
@@ -17,6 +19,8 @@
 import com.zy.asrs.wcs.core.entity.*;
 import com.zy.asrs.wcs.core.kernel.AnalyzeService;
 import com.zy.asrs.wcs.core.model.MapNode;
+import com.zy.asrs.wcs.core.model.command.LiftAssignCommand;
+import com.zy.asrs.wcs.core.model.command.LiftCommand;
 import com.zy.asrs.wcs.core.model.enums.*;
 import com.zy.asrs.wcs.core.service.*;
 import com.zy.asrs.wcs.core.utils.OpenUtils;
@@ -30,13 +34,11 @@
 import com.zy.asrs.wcs.rcs.model.command.LedCommand;
 import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType;
 import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
+import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol;
 import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol;
 import com.zy.asrs.wcs.rcs.model.protocol.StaProtocol;
 import com.zy.asrs.wcs.rcs.service.DeviceService;
-import com.zy.asrs.wcs.rcs.thread.BarcodeThread;
-import com.zy.asrs.wcs.rcs.thread.DevpThread;
-import com.zy.asrs.wcs.rcs.thread.LedThread;
-import com.zy.asrs.wcs.rcs.thread.ShuttleThread;
+import com.zy.asrs.wcs.rcs.thread.*;
 import com.zy.asrs.wcs.system.entity.Dict;
 import com.zy.asrs.wcs.system.service.DictService;
 import lombok.extern.slf4j.Slf4j;
@@ -91,6 +93,8 @@
     private ShuttleChargeStaService shuttleChargeStaService;
     @Autowired
     private OpenUtils openUtils;
+    @Autowired
+    private LiftAction liftAction;
 
     /**
      * 缁勬墭
@@ -295,6 +299,134 @@
     }
 
     /**
+     * 鍏ュ簱-鎵樼洏杩涘簱
+     */
+    public synchronized void palletInbound() {
+        try {
+            // 鏍规嵁杈撻�佺嚎plc閬嶅巻
+            List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
+                    .eq(Device::getDeviceType, DeviceCtgType.CONVEYOR.val())
+                    .eq(Device::getStatus, 1));
+            for (Device devp : list) {
+                BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getDeviceId, devp.getId()).eq(BasConveyor::getHostId, devp.getHostId()));
+                // 閬嶅巻鍏ュ簱鍙�
+                for (StaDto inSta : JSON.parseArray(basConveyor.getInSta(), StaDto.class)) {
+                    BasConveyorSta basConveyorSta = basConveyorStaService.selectBySiteNo(inSta.getDeviceStaNo().toString());
+                    if(basConveyorSta == null) {
+                        continue;
+                    }
+
+                    // 鑾峰彇鍏ュ簱绔欎俊鎭�
+                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, devp.getId().intValue());
+                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getDeviceStaNo());
+                    if (staProtocol == null) {
+                        continue;
+                    } else {
+                        staProtocol = staProtocol.clone();
+                    }
+                    int workNo = staProtocol.getWorkNo().intValue();
+
+                    // 鍒ゆ柇鏄惁婊¤冻鍏ュ簱鏉′欢
+                    if (staProtocol.isAutoing()
+                            && staProtocol.isLoading()
+                            && staProtocol.isInEnable()
+                            && (workNo >= 0)
+                            && staProtocol.isPakMk()
+                    ) {
+                        Object object = redisUtil.get(DeviceRedisConstant.LIFT_PALLET_INBOUND + workNo);
+                        if (object != null) {
+                            continue;
+                        }
+
+                        Task task = taskService.getOne(new LambdaQueryWrapper<Task>()
+                                .eq(Task::getDestSite, inSta.getDeviceStaNo())
+                                .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts)
+                                .eq(Task::getTaskNo, workNo));
+                        if (task != null) {
+                            int lev = Utils.getLev(task.getDestLoc());
+                            Integer targetSite = null;
+                            if (lev == 1) {
+                                targetSite = 31006;
+                            }else if (lev == 2) {
+                                targetSite = 31007;
+                            }else if (lev == 3) {
+                                targetSite = 31008;
+                            }
+                            if(targetSite == null) {
+                                throw new CoolException(lev + "灞傜珯鐐逛俊鎭笉瀛樺湪");
+                            }
+
+                            StaProtocol staProtocol1 = devpThread.getStation().get(targetSite);
+                            if (staProtocol1 == null) {
+                                break;
+                            }
+                            if (!staProtocol1.isAutoing()) {
+                                break;
+                            }
+                            if (staProtocol1.isLoading()) {
+                                break;
+                            }
+                            if (staProtocol1.getWorkNo().intValue() != 0) {
+                                break;
+                            }
+
+                            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, inSta.getLiftNo());
+                            if (liftThread == null) {
+                                break;
+                            }
+
+                            LiftProtocol liftProtocol = liftThread.getStatus();
+                            if (liftProtocol == null) {
+                                break;
+                            }
+
+                            if (!liftThread.isIdle()) {
+                                break;
+                            }
+
+                            if (motionService.count(new LambdaQueryWrapper<Motion>()
+                                    .eq(Motion::getDeviceCtg, DeviceCtgType.LIFT.val())
+                                    .eq(Motion::getDevice, inSta.getLiftNo())
+                                    .eq(Motion::getMotionSts, MotionStsType.EXECUTING.val())) > 0) {
+                                break;
+                            }
+
+                            //妫�娴嬫彁鍗囨満鏄惁鏈変换鍔$粦瀹�
+                            boolean liftResult = Utils.checkLiftHasBinding(liftProtocol.getLiftNo(), String.valueOf(workNo));
+                            if (liftResult) {
+                                //瀛樺湪浠诲姟锛岀姝㈡墽琛�
+                                break;
+                            }
+
+                            //姣忔鎵ц鎻愬崌鏈烘寚浠ら兘缁戝畾鎻愬崌鏈�
+                            task.setLiftNo(liftProtocol.getLiftNo());
+                            task.setUpdateTime(new Date());
+                            if (!taskService.updateById(task)) {
+                                break;
+                            }
+
+                            List<LiftCommand> command = liftThread.getPalletInOutCommand(workNo, 1, lev, inSta.getDeviceStaNo(), targetSite, LiftCommandModeType.PALLET_INOUT);
+
+                            LiftAssignCommand assignCommand = new LiftAssignCommand();
+                            assignCommand.setLiftNo(liftProtocol.getLiftNo());
+                            assignCommand.setTaskNo(workNo);
+                            assignCommand.setDeviceTaskNo(liftThread.generateDeviceTaskNo(workNo, MotionCtgType.LIFT_WITH_GOODS));
+                            assignCommand.setCommands(command);
+                            liftAction.assignWork(liftThread.getDevice(), assignCommand);
+
+                            redisUtil.set(DeviceRedisConstant.LIFT_PALLET_INBOUND + workNo, "send", 60 * 60 * 6);
+                            break;
+                        }
+
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
      * 鍒濆鍖栧疄鏃跺湴鍥�
      */
     public synchronized void initRealtimeBasMap() {
@@ -462,6 +594,7 @@
 
                 //灏嗗湴鍥炬暟鎹瓨鍏edis
                 redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(map));
+                redisUtil.set(DeviceRedisConstant.BASE_MAP + lev, JSON.toJSONString(map));
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -470,86 +603,171 @@
 
     // 瑙f瀽鍏ュ簱宸ヤ綔妗�
     public synchronized void analyzeInBoundTask() {
-        for (Task task : taskService.selectWaitAnalyzeInBoundTask()) {
-            BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>().eq(BasConveyorSta::getSiteNo, task.getDestSite()));
-            if (basConveyorSta == null) {
-                continue;
-            }
-            BasConveyor basConveyor = basConveyorService.getById(basConveyorSta.getConveyorId());
-            if (basConveyor == null) {
-                continue;
-            }
-//            DeviceBarcode deviceBarcode = deviceBarcodeService.getById(basConveyorSta.getBarcodeId());
-//            if (deviceBarcode == null) {
-//                continue;
-//            }
-//            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, Integer.parseInt(deviceBarcode.getDeviceId()));
-//            if (barcodeThread == null) {
-//                continue;
-//            }
-//            if (!barcodeThread.getBarcode().equals(task.getZpallet())) {
-//                continue;
-//            }
-            if (Cools.isEmpty(basConveyorSta.getTaskNo())){
-                continue;
-            }
-            if (!basConveyorSta.getTaskNo().toString().equals(task.getTaskNo())){
-                continue;
-            }
-            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
-            if (devpThread == null) {
-                continue;
-            }
-            StaProtocol staProtocol = devpThread.getStation().get(basConveyorSta.getSiteNo());
-            if (staProtocol == null) {
-                continue;
-            }
-            if (!(staProtocol.isAutoing()
-                    && staProtocol.isLoading()
-                    && staProtocol.isInEnable())) {
-                continue;
-            }
+        try {
+            // 鏍规嵁杈撻�佺嚎plc閬嶅巻
+            List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
+                    .eq(Device::getDeviceType, DeviceCtgType.CONVEYOR.val())
+                    .eq(Device::getStatus, 1));
+            for (Device devp : list) {
+                BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getDeviceId, devp.getId()).eq(BasConveyor::getHostId, devp.getHostId()));
+                // 閬嶅巻鍏ュ簱鍙�
+                for (StaDto inSta : JSON.parseArray(basConveyor.getDeviceInSta(), StaDto.class)) {
+                    BasConveyorSta basConveyorSta = basConveyorStaService.selectBySiteNo(inSta.getStaNo().toString());
+                    if(basConveyorSta == null) {
+                        continue;
+                    }
 
-            //瑙f瀽鍓嶅垽鏂唴閮ㄧ洰鏍囧�兼槸鍚︽湁鐗� 鏈夊伐浣滃彿
-            StaProtocol staProtocolInside = devpThread.getStation().get(Utils.getStaByLev(Utils.getLev(task.getDestLoc())));
-            if (staProtocolInside == null) {
-                continue;
-            }
-            if (staProtocolInside.isLoading() || staProtocolInside.getWorkNo() !=0) {
-                continue;
-            }
+                    // 鑾峰彇鍏ュ簱绔欎俊鎭�
+                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, devp.getId().intValue());
+                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
+                    if (staProtocol == null) {
+                        continue;
+                    } else {
+                        staProtocol = staProtocol.clone();
+                    }
+                    int workNo = staProtocol.getWorkNo().intValue();
 
-            if (Cools.isEmpty(task.getShuttleNo())) {
-                //鍒嗛厤灏忚溅
-                //鎼滅储绌洪棽杞�
-                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
-                if (shuttleThread == null) {
-                    News.info("{}浠诲姟鏈壘鍒扮┖闂茬┛姊溅", task.getTaskNo());
-                    continue;
+                    // 鍒ゆ柇鏄惁婊¤冻鍏ュ簱鏉′欢
+                    if (staProtocol.isAutoing()
+                            && staProtocol.isInEnable()
+                            && (workNo >= 0)
+                            && staProtocol.isPakMk()
+                    ) {
+
+                        Task task = taskService.getOne(new LambdaQueryWrapper<Task>()
+                                .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts)
+                                .eq(Task::getTaskNo, workNo));
+                        if (task != null) {
+                            if (!Cools.isEmpty(task.getLiftNo())) {
+                                if (task.getLiftNo() > 0) {
+                                    task.setLiftNo(0);
+                                    task.setUpdateTime(new Date());
+                                    if (!taskService.updateById(task)) {
+                                        News.info("{}浠诲姟鏇存柊閲婃斁鎻愬崌鏈哄け璐�", task.getTaskNo());
+                                    }
+                                }
+                            }
+
+                            if (Cools.isEmpty(task.getShuttleNo())) {
+                                //鍒嗛厤灏忚溅
+                                //鎼滅储绌洪棽杞�
+                                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
+                                if (shuttleThread == null) {
+                                    News.info("{}浠诲姟鏈壘鍒扮┖闂茬┛姊溅", task.getTaskNo());
+                                    continue;
+                                }
+
+                                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//淇濆瓨绌挎杞﹀彿
+                                task.setUpdateTime(new Date());
+                                if (!taskService.updateById(task)) {
+                                    News.info("{}浠诲姟鏇存柊绌挎杞﹀彿澶辫触", task.getTaskNo());
+                                }
+                                continue;
+                            }
+
+                            // generate motion list
+                            List<Motion> motionList = analyzeService.generateMotion(task);
+                            if (motionList.isEmpty()) {
+                                continue;
+                            }
+                            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
+
+                            // 鏇存柊宸ヤ綔涓绘。
+                            task.setTaskSts(TaskStsType.ANALYZE_INBOUND.sts); // 宸ヤ綔鐘舵��
+                            task.setUpdateTime(new Date());
+                            if (!taskService.updateById(task)) {
+                                News.error("鏇存柊宸ヤ綔妗eけ璐ワ紒锛侊紒 [宸ヤ綔鍙凤細{}]", task.getTaskNo());
+                            }
+                            break;
+                        }
+
+                    }
                 }
-
-                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//淇濆瓨绌挎杞﹀彿
-                task.setUpdateTime(new Date());
-                if (!taskService.updateById(task)) {
-                    News.info("{}浠诲姟鏇存柊绌挎杞﹀彿澶辫触", task.getTaskNo());
-                }
-                continue;
             }
-
-            // generate motion list
-            List<Motion> motionList = analyzeService.generateMotion(task);
-            if (motionList.isEmpty()) {
-                continue;
-            }
-            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
-
-            // 鏇存柊宸ヤ綔涓绘。
-            task.setTaskSts(TaskStsType.ANALYZE_INBOUND.sts); // 宸ヤ綔鐘舵��
-            task.setUpdateTime(new Date());
-            if (!taskService.updateById(task)) {
-                News.error("鏇存柊宸ヤ綔妗eけ璐ワ紒锛侊紒 [宸ヤ綔鍙凤細{}]", task.getTaskNo());
-            }
+        } catch (Exception e) {
+            e.printStackTrace();
         }
+
+//        for (Task task : taskService.selectWaitAnalyzeInBoundTask()) {
+//            BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>().eq(BasConveyorSta::getSiteNo, task.getDestSite()));
+//            if (basConveyorSta == null) {
+//                continue;
+//            }
+//            BasConveyor basConveyor = basConveyorService.getById(basConveyorSta.getConveyorId());
+//            if (basConveyor == null) {
+//                continue;
+//            }
+////            DeviceBarcode deviceBarcode = deviceBarcodeService.getById(basConveyorSta.getBarcodeId());
+////            if (deviceBarcode == null) {
+////                continue;
+////            }
+////            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, Integer.parseInt(deviceBarcode.getDeviceId()));
+////            if (barcodeThread == null) {
+////                continue;
+////            }
+////            if (!barcodeThread.getBarcode().equals(task.getZpallet())) {
+////                continue;
+////            }
+//            if (Cools.isEmpty(basConveyorSta.getTaskNo())){
+//                continue;
+//            }
+//            if (!basConveyorSta.getTaskNo().toString().equals(task.getTaskNo())){
+//                continue;
+//            }
+//            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
+//            if (devpThread == null) {
+//                continue;
+//            }
+//            StaProtocol staProtocol = devpThread.getStation().get(basConveyorSta.getSiteNo());
+//            if (staProtocol == null) {
+//                continue;
+//            }
+//            if (!(staProtocol.isAutoing()
+//                    && staProtocol.isLoading()
+//                    && staProtocol.isInEnable())) {
+//                continue;
+//            }
+//
+//            //瑙f瀽鍓嶅垽鏂唴閮ㄧ洰鏍囧�兼槸鍚︽湁鐗� 鏈夊伐浣滃彿
+//            StaProtocol staProtocolInside = devpThread.getStation().get(Utils.getStaByLev(Utils.getLev(task.getDestLoc())));
+//            if (staProtocolInside == null) {
+//                continue;
+//            }
+//            if (staProtocolInside.isLoading() || staProtocolInside.getWorkNo() !=0) {
+//                continue;
+//            }
+//
+//            if (Cools.isEmpty(task.getShuttleNo())) {
+//                //鍒嗛厤灏忚溅
+//                //鎼滅储绌洪棽杞�
+//                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
+//                if (shuttleThread == null) {
+//                    News.info("{}浠诲姟鏈壘鍒扮┖闂茬┛姊溅", task.getTaskNo());
+//                    continue;
+//                }
+//
+//                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//淇濆瓨绌挎杞﹀彿
+//                task.setUpdateTime(new Date());
+//                if (!taskService.updateById(task)) {
+//                    News.info("{}浠诲姟鏇存柊绌挎杞﹀彿澶辫触", task.getTaskNo());
+//                }
+//                continue;
+//            }
+//
+//            // generate motion list
+//            List<Motion> motionList = analyzeService.generateMotion(task);
+//            if (motionList.isEmpty()) {
+//                continue;
+//            }
+//            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
+//
+//            // 鏇存柊宸ヤ綔涓绘。
+//            task.setTaskSts(TaskStsType.ANALYZE_INBOUND.sts); // 宸ヤ綔鐘舵��
+//            task.setUpdateTime(new Date());
+//            if (!taskService.updateById(task)) {
+//                News.error("鏇存柊宸ヤ綔妗eけ璐ワ紒锛侊紒 [宸ヤ綔鍙凤細{}]", task.getTaskNo());
+//            }
+//        }
     }
 
     /**
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
index 8acafcb..87b8e84 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
@@ -6,6 +6,7 @@
 import com.zy.asrs.common.utils.HttpHandler;
 import com.zy.asrs.wcs.core.entity.*;
 import com.zy.asrs.wcs.core.model.enums.LocStsType;
+import com.zy.asrs.wcs.core.model.enums.MotionCtgType;
 import com.zy.asrs.wcs.core.model.enums.TaskStsType;
 import com.zy.asrs.wcs.core.service.*;
 import com.zy.asrs.wcs.rcs.News;
@@ -81,10 +82,12 @@
                 .eq(Task::getStatus, 1)
                 .in(Task::getTaskSts, taskSts));
         for (Task task : tasks) {
-            Motion motion = motionService.getOne(new LambdaQueryWrapper<Motion>().eq(Motion::getMotionCtg, 9).eq(Motion::getTaskNo, task.getTaskNo()));
-            List<BasConveyorSta> conveyorStas = basConveyorStaService.list(new LambdaQueryWrapper<BasConveyorSta>().in(BasConveyorSta::getTaskNo, motion.getTemp()));
-            if (!conveyorStas.isEmpty()) {
-                continue;
+            Motion motion = motionService.getOne(new LambdaQueryWrapper<Motion>().eq(Motion::getMotionCtg, MotionCtgType.LIFT_WITH_GOODS.val()).eq(Motion::getTaskNo, task.getTaskNo()));
+            if (motion != null) {
+                List<BasConveyorSta> conveyorStas = basConveyorStaService.list(new LambdaQueryWrapper<BasConveyorSta>().in(BasConveyorSta::getTaskNo, motion.getTemp()));
+                if (!conveyorStas.isEmpty()) {
+                    continue;
+                }
             }
             if (reportWms != null && reportWms.getValue().equals("true")) {
                 //鑾峰彇WMS鍦板潃
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
index 28df8f4..377f800 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
@@ -34,6 +34,63 @@
     private BasLiftService basLiftService;
     @Autowired
     private ShuttleStandbyService shuttleStandbyService;
+    @Autowired
+    private NavigateUtils navigateUtils;
+
+    /**
+     * 鏍规嵁鐩爣浣嶇疆鎼滅储鎻愬崌鏈�
+     * transfer: 鏄惁鍙崲灞�
+     */
+    public LiftThread searchLift(String locNo, Long hostId, Boolean transfer) {
+        LiftThread recentLiftThread = null;
+        Integer finalDistance = Integer.MAX_VALUE;
+        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
+                .eq(Device::getDeviceType, DeviceCtgType.LIFT.val())
+                .eq(Device::getHostId, hostId)
+                .eq(Device::getStatus, 1));
+        for (Device device : list) {
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getId().intValue());
+            if (liftThread == null) {
+                continue;
+            }
+
+            LiftProtocol liftProtocol = liftThread.getStatus();
+            if (liftProtocol == null) {
+                continue;
+            }
+
+            if (transfer) {
+                BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getLiftNo, device.getDeviceNo()).eq(BasLift::getHostId, hostId));
+                if (basLift == null) {
+                    continue;
+                }
+                if (basLift.getTransfer() != 1) {
+                    continue;//鎻愬崌鏈鸿璁剧疆鎴愪笉鍙崲灞�
+                }
+            }
+
+            ShuttleStandby standby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>()
+                    .eq(ShuttleStandby::getDeviceId, device.getId())
+                    .eq(ShuttleStandby::getDeviceLev, Utils.getLev(locNo))
+                    .eq(ShuttleStandby::getStatus, 1));
+            if (standby == null) {
+                continue;
+            }
+
+            String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), Utils.getLev(locNo));
+            List<NavigateNode> nodeList = navigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null);
+            if (nodeList == null) {
+                continue;
+            }
+            Integer originPathAllDistance = navigateUtils.getOriginPathAllDistance(nodeList);//鎬昏窛绂�
+            if (originPathAllDistance < finalDistance) {
+                finalDistance = originPathAllDistance;
+                recentLiftThread = liftThread;
+            }
+        }
+
+        return recentLiftThread;
+    }
 
     /**
      * 鏍规嵁鐩爣浣嶇疆鎼滅储绌洪棽鎻愬崌鏈�
@@ -80,11 +137,11 @@
             }
 
             String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), Utils.getLev(locNo));
-            List<NavigateNode> nodeList = NavigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null);
+            List<NavigateNode> nodeList = navigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null);
             if (nodeList == null) {
                 continue;
             }
-            Integer originPathAllDistance = NavigateUtils.getOriginPathAllDistance(nodeList);//鎬昏窛绂�
+            Integer originPathAllDistance = navigateUtils.getOriginPathAllDistance(nodeList);//鎬昏窛绂�
             if (originPathAllDistance < finalDistance) {
                 finalDistance = originPathAllDistance;
                 recentLiftThread = liftThread;
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java
index c3139be..d527847 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateMapData.java
@@ -31,6 +31,8 @@
     private LocService locService;
     @Autowired
     private DictService dictService;
+    @Autowired
+    private NavigateMapData navigateMapData;
 
     private Integer lev;//鍦板浘妤煎眰
 
@@ -54,14 +56,20 @@
      * 灏濊瘯浠巖edis鑾峰彇鏁版嵁
      */
     public int[][] getDataFromRedis(Integer mapType, List<int[]> whitePoints, List<int[]> shuttlePoints) {
+        String constantMap = DeviceRedisConstant.MAP;
+        if(mapType == NavigationMapType.NONE_LOCK.id){
+            constantMap = DeviceRedisConstant.BASE_MAP;
+        }
+
         RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
-        Object o = redisUtil.get(DeviceRedisConstant.MAP + lev);
+        Object o = redisUtil.get(constantMap + lev);
         if (o == null) {
             return null;
         }
 
         BasMapDto basMap = JSON.parseObject(o.toString(), BasMapDto.class);
-        return this.getDataFormString(basMap.getData(), mapType, whitePoints, shuttlePoints);
+        String mapData = basMap.getData();
+        return this.getDataFormString(mapData, mapType, whitePoints, shuttlePoints);
     }
 
     /**
@@ -319,7 +327,7 @@
                 ) {
                     mapNode.setValue(MapNodeType.DISABLE.id);//绂佺敤鑺傜偣
                 }
-            } else if (mapType == NavigationMapType.NORMAL.id) {
+            } else if (mapType == NavigationMapType.NORMAL.id || mapType == NavigationMapType.NONE_LOCK.id) {
                 //杩囨护搴撲綅鐘舵�乆
                 if (loc.getLocStsFlag().equals("X")) {
                     mapNode.setValue(MapNodeType.DISABLE.id);//绂佺敤鑺傜偣
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateSolution.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateSolution.java
index 679502b..0b3cf6a 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateSolution.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateSolution.java
@@ -1,13 +1,18 @@
 package com.zy.asrs.wcs.core.utils;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zy.asrs.framework.common.SpringUtils;
 import com.zy.asrs.framework.exception.CoolException;
 import com.zy.asrs.wcs.core.model.NavigateNode;
+import com.zy.asrs.wcs.core.model.PythonResult;
 import com.zy.asrs.wcs.core.model.enums.MapNodeType;
 import com.zy.asrs.wcs.system.entity.Dict;
 import com.zy.asrs.wcs.system.service.DictService;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.PriorityQueue;
@@ -52,45 +57,101 @@
     //Exist琛ㄧ敤鏉ュ瓨鏀惧凡缁忓嚭鐜拌繃鐨勭粨鐐广��
     public ArrayList<NavigateNode> Exist = new ArrayList<NavigateNode>();
 
-    public NavigateNode astarSearch(NavigateNode start, NavigateNode end) {
-        //鎶婄涓�涓紑濮嬬殑缁撶偣鍔犲叆鍒癘pen琛ㄤ腑
-        this.Open.add(start);
-        //鎶婂嚭鐜拌繃鐨勭粨鐐瑰姞鍏ュ埌Exist琛ㄤ腑
-        this.Exist.add(start);
-        //涓诲惊鐜�
-        while (Open.size() > 0) {
-            //鍙栦紭鍏堥槦鍒楅《閮ㄥ厓绱犲苟涓旀妸杩欎釜鍏冪礌浠嶰pen琛ㄤ腑鍒犻櫎
-            NavigateNode current_node = Open.poll();
-            //灏嗚繖涓粨鐐瑰姞鍏ュ埌Close琛ㄤ腑
-            Close.add(current_node);
-            //瀵瑰綋鍓嶇粨鐐硅繘琛屾墿灞曪紝寰楀埌涓�涓洓鍛ㄧ粨鐐圭殑鏁扮粍
-            ArrayList<NavigateNode> neighbour_node = extend_current_node(current_node);
-            //瀵硅繖涓粨鐐归亶鍘嗭紝鐪嬫槸鍚︽湁鐩爣缁撶偣鍑虹幇
-            for (NavigateNode node : neighbour_node) {
-                // G + H + E (瀵瑰惎鍙戝嚱鏁板鍔犲幓鎷愮偣鏂规calcNodeExtraCost)
-                int gCost = calcNodeCost(current_node, node) * calcNodeExtraCost(current_node, node, end);
-                if (node.getX() == end.getX() && node.getY() == end.getY()) {//鎵惧埌鐩爣缁撶偣灏辫繑鍥�
-                    //init_node鎿嶄綔鎶婅繖涓偦灞呯粨鐐圭殑鐖惰妭鐐硅缃负褰撳墠缁撶偣
-                    //骞朵笖璁$畻鍑篏锛� F锛� H绛夊��
-                    node.setLastDistance(gCost);
-                    node.init_node(current_node, end);
-                    return node;
-                }
+    public String astarSearch(NavigateNode start, NavigateNode end, String pythonScriptPath) {
+        String maps = JSON.toJSONString(map);
+        String startStr = start.getX() + "-" + start.getY();
+        String targetStr = end.getX() + "-" + end.getY();
 
-                //杩涜璁$畻瀵笹, F, H 绛夊��
-                node.setLastDistance(gCost);
-                node.init_node(current_node, end);
-                node.setH(calcNodeCost(node, end));
-                node.setF(node.getG() + node.getH());
-
-                Open.add(node);
-                Exist.add(node);
+        //榛樿鍦板浘姣嶈建鏂瑰悜x
+        String mapDirection = "x";
+        DictService dictService = SpringUtils.getBean(DictService.class);
+        if (dictService != null) {
+            Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>()
+                    .eq(Dict::getFlag, "direction_map")
+                    .eq(Dict::getStatus, 1));
+            if (dict != null) {
+                mapDirection = dict.getValue();
             }
         }
-        //濡傛灉閬嶅巻瀹屾墍鏈夊嚭鐜扮殑缁撶偣閮芥病鏈夋壘鍒版渶缁堢殑缁撶偣锛岃繑鍥瀗ull
+
+        ProcessBuilder processBuilder = new ProcessBuilder("python", pythonScriptPath, maps, startStr, targetStr, mapDirection);
+        processBuilder.redirectErrorStream(true);
+
+        try {
+            Process process = processBuilder.start();
+
+            // 璇诲彇Python鑴氭湰鐨勮緭鍑�
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line;
+            StringBuilder builder = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                builder.append(line);
+            }
+
+            // 绛夊緟Python鑴氭湰鎵ц瀹屾垚
+            int exitCode = process.waitFor();
+            if (exitCode != 0) {
+                System.out.println("Python script exited with error code: " + exitCode);
+                return null;
+            }
+            reader.close();
+
+            if (builder.length() <= 0) {
+                return null;
+            }
+
+            PythonResult result = JSON.parseObject(builder.toString(), PythonResult.class);
+            if (result.getCalcResult() != 200) {
+                return null;
+            }
+
+            String path = result.getPath();
+            return path;
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
         return null;
     }
 
+//    public NavigateNode astarSearch(NavigateNode start, NavigateNode end) {
+//        //鎶婄涓�涓紑濮嬬殑缁撶偣鍔犲叆鍒癘pen琛ㄤ腑
+//        this.Open.add(start);
+//        //鎶婂嚭鐜拌繃鐨勭粨鐐瑰姞鍏ュ埌Exist琛ㄤ腑
+//        this.Exist.add(start);
+//        //涓诲惊鐜�
+//        while (Open.size() > 0) {
+//            //鍙栦紭鍏堥槦鍒楅《閮ㄥ厓绱犲苟涓旀妸杩欎釜鍏冪礌浠嶰pen琛ㄤ腑鍒犻櫎
+//            NavigateNode current_node = Open.poll();
+//            //灏嗚繖涓粨鐐瑰姞鍏ュ埌Close琛ㄤ腑
+//            Close.add(current_node);
+//            //瀵瑰綋鍓嶇粨鐐硅繘琛屾墿灞曪紝寰楀埌涓�涓洓鍛ㄧ粨鐐圭殑鏁扮粍
+//            ArrayList<NavigateNode> neighbour_node = extend_current_node(current_node);
+//            //瀵硅繖涓粨鐐归亶鍘嗭紝鐪嬫槸鍚︽湁鐩爣缁撶偣鍑虹幇
+//            for (NavigateNode node : neighbour_node) {
+//                // G + H + E (瀵瑰惎鍙戝嚱鏁板鍔犲幓鎷愮偣鏂规calcNodeExtraCost)
+//                int gCost = calcNodeCost(current_node, node) * calcNodeExtraCost(current_node, node, end);
+//                if (node.getX() == end.getX() && node.getY() == end.getY()) {//鎵惧埌鐩爣缁撶偣灏辫繑鍥�
+//                    //init_node鎿嶄綔鎶婅繖涓偦灞呯粨鐐圭殑鐖惰妭鐐硅缃负褰撳墠缁撶偣
+//                    //骞朵笖璁$畻鍑篏锛� F锛� H绛夊��
+//                    node.setLastDistance(gCost);
+//                    node.init_node(current_node, end);
+//                    return node;
+//                }
+//
+//                //杩涜璁$畻瀵笹, F, H 绛夊��
+//                node.setLastDistance(gCost);
+//                node.init_node(current_node, end);
+//                node.setH(calcNodeCost(node, end));
+//                node.setF(node.getG() + node.getH());
+//
+//                Open.add(node);
+//                Exist.add(node);
+//            }
+//        }
+//        //濡傛灉閬嶅巻瀹屾墍鏈夊嚭鐜扮殑缁撶偣閮芥病鏈夋壘鍒版渶缁堢殑缁撶偣锛岃繑鍥瀗ull
+//        return null;
+//    }
+
 
     public ArrayList<NavigateNode> extend_current_node(NavigateNode current_node) {
         //榛樿鍦板浘姣嶈建鏂瑰悜x
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateUtils.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateUtils.java
index 6792085..1013656 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateUtils.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/NavigateUtils.java
@@ -1,22 +1,36 @@
 package com.zy.asrs.wcs.core.utils;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.zy.asrs.framework.common.SpringUtils;
 import com.zy.asrs.wcs.core.model.MapNode;
 import com.zy.asrs.wcs.core.model.NavigateNode;
+import com.zy.asrs.wcs.core.model.PythonSimilarityResult;
 import com.zy.asrs.wcs.core.model.enums.MapNodeType;
 import com.zy.asrs.wcs.core.model.enums.NavigationMapType;
+import com.zy.asrs.wcs.rcs.News;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
 
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
 /**
  * A*绠楁硶浣跨敤宸ュ叿
  */
+@Component
 public class NavigateUtils {
 
-    public static List<NavigateNode> calc(String startPoint, String endPoint, Integer mapType, List<int[]> shuttlePoints) {
+    @Value("${pythonCalcPath}")
+    private String pythonCalcPath;
+
+    @Value("${pythonCalcSimilarity}")
+    private String pythonCalcSimilarity;
+
+    public List<NavigateNode> calc(String startPoint, String endPoint, Integer mapType, List<int[]> shuttlePoints) {
         //閫氳繃寮�濮嬬紪鍙峰拰缁撴潫缂栧彿鑾峰彇瀵瑰簲鐨剎y杞村潗鏍�
         int[] startArr = NavigatePositionConvert.positionToXY(startPoint);//寮�濮嬭妭鐐�
         int[] endArr = NavigatePositionConvert.positionToXY(endPoint);//缁撴潫鑺傜偣
@@ -36,36 +50,42 @@
         NavigateSolution solution = new NavigateSolution(mapType, lev, whiteList, shuttlePoints);
         //寮�濮嬭妭鐐癸紝涓嶇撼鍏ョ鐢ㄨ妭鐐瑰唴璁$畻
 
-        NavigateNode res_node = solution.astarSearch(start, end);
-        if (res_node == null) {
-            System.err.println("鏈壘鍒拌矾寰�");
+        String pathStr = solution.astarSearch(start, end, pythonCalcPath);
+        if (pathStr == null) {
+            News.error("{} dash {} can't find navigate path!", startPoint, endPoint);
             return null;
         }
-        ArrayList<NavigateNode> list = new ArrayList<>();
 
-        //娓叉煋
+        List<NavigateNode> list = new ArrayList<>();
+
         NavigateNode fatherNode = null;//褰撳墠寰幆涓婁竴鑺傜偣锛岀敤浜庢嫄鐐硅绠�
-        while (res_node != null) {
-            res_node.setDirection(null);
-            res_node.setIsInflectionPoint(false);
-            res_node.setZ(lev);//璁剧疆灞傞珮
+        JSONArray rows = JSON.parseArray(pathStr);
+
+        for (int i = 0; i < rows.size(); i++) {
+            Object currentObj = rows.get(i);
+
+            NavigateNode nextNode = null;
+            if ((i + 1) < rows.size()) {
+                Object object = rows.get(i + 1);
+                nextNode = pythonObjTransferNode(object, lev);
+            }
+
+            NavigateNode node = pythonObjTransferNode(currentObj, lev);
 
             //瀵绘壘鎷愮偣
-            HashMap<String, Object> result = searchInflectionPoint(res_node, fatherNode, res_node.getFather());//鍒嗗埆浼犲叆褰撳墠鑺傜偣銆佺埗鑺傜偣銆佷笅涓�鑺傜偣
+            HashMap<String, Object> result = searchInflectionPoint(node, fatherNode, nextNode);//鍒嗗埆浼犲叆褰撳墠鑺傜偣銆佺埗鑺傜偣銆佷笅涓�鑺傜偣
             //鍒ゆ柇褰撳墠鑺傜偣鏄惁涓烘嫄鐐�
             if (Boolean.parseBoolean(result.get("result").toString())) {
                 //褰撳墠涓烘嫄鐐�
-                res_node.setIsInflectionPoint(true);
+                node.setIsInflectionPoint(true);
                 //鎷愮偣鏂瑰悜
-                res_node.setDirection(result.get("direction").toString());
+                node.setDirection(result.get("direction").toString());
             }
-            list.add(res_node);
 
-            fatherNode = res_node;//鎶婂綋鍓嶈妭鐐逛繚瀛樻垚涓�涓埗鑺傜偣
-            res_node = res_node.getFather();//杩唬鎿嶄綔
+            list.add(node);
+
+            fatherNode = node;//鎶婂綋鍓嶈妭鐐逛繚瀛樻垚涓�涓埗鑺傜偣
         }
-
-        Collections.reverse(list);
 
         //灏嗘瘡涓妭鐐归噷闈㈢殑fatherNode鑷充负null(鏂逛究鍚庣画璁$畻鏃剁埗鑺傜偣杩囧瀵艰嚧鏄剧ず鐨勮妭鐐瑰お澶�)
         for (NavigateNode navigateNode : list) {
@@ -84,7 +104,7 @@
     }
 
     //鍒ゆ柇褰撳墠鑺傜偣鍒颁笅涓�涓妭鐐规槸鍚︿负鎷愮偣
-    public static HashMap<String,Object> searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) {
+    public HashMap<String,Object> searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) {
         HashMap<String, Object> map = new HashMap<>();
         map.put("result", false);//鏄惁涓烘嫄鐐癸紝true锛氭嫄鐐癸紝false锛氱洿绾�
         // 绗竴涓偣鎴栫洿绾跨偣
@@ -103,7 +123,7 @@
     /**
      * 璁$畻鏂瑰悜
      */
-    public static String calcDirection(NavigateNode currentNode, NavigateNode fatherNode) {
+    public String calcDirection(NavigateNode currentNode, NavigateNode fatherNode) {
         //鎷愮偣鏂瑰悜
         String direction = "";
         // 鏅�氭嫄鐐�
@@ -139,7 +159,7 @@
      * 鍔犺浆寮妭鐐�
      * 鑾峰彇鍒嗘璺緞锛屾瘡褰撴湁涓�涓嫄鐐瑰垯杩涜涓�娆″垎娈碉紝鏈�缁堣繑鍥炴�诲垎娈垫暟鎹�
      */
-    public static ArrayList<ArrayList<NavigateNode>> getSectionPath(List<NavigateNode> mapList) {
+    public ArrayList<ArrayList<NavigateNode>> getSectionPath(List<NavigateNode> mapList) {
         ArrayList<ArrayList<NavigateNode>> list = new ArrayList<>();
 
         ArrayList<NavigateNode> data = new ArrayList<>();
@@ -169,7 +189,7 @@
     }
 
     //鑾峰彇浠巟鐐瑰埌涓嬩竴鐐圭殑琛岃蛋璺濈
-    public static Integer getXToNextDistance(NavigateNode xNode) {
+    public Integer getXToNextDistance(NavigateNode xNode) {
         NavigateMapData mapData = SpringUtils.getBean(NavigateMapData.class);
         mapData.setLev(xNode.getZ());
         List<List<MapNode>> lists = mapData.getJsonData(NavigationMapType.NONE.id, null, null);
@@ -195,11 +215,11 @@
     /**
      * 鏍规嵁鍘熷鑺傜偣缁撴灉锛岃绠楁�昏璧拌窛绂�
      */
-    public static Integer getOriginPathAllDistance(List<NavigateNode> path) {
-        ArrayList<ArrayList<NavigateNode>> sectionPath = NavigateUtils.getSectionPath(path);
+    public Integer getOriginPathAllDistance(List<NavigateNode> path) {
+        ArrayList<ArrayList<NavigateNode>> sectionPath = getSectionPath(path);
         Integer allDistance = 0;
         for (ArrayList<NavigateNode> navigateNodes : sectionPath) {
-            Integer distance = NavigateUtils.getCurrentPathAllDistance(navigateNodes);
+            Integer distance = getCurrentPathAllDistance(navigateNodes);
             allDistance += distance;
         }
         return allDistance;
@@ -208,7 +228,7 @@
     /**
      * 鑾峰彇褰撳墠璺緞鎬昏璧拌窛绂�
      */
-    public static Integer getCurrentPathAllDistance(List<NavigateNode> path) {
+    public Integer getCurrentPathAllDistance(List<NavigateNode> path) {
         if (path.size() == 1) {
             //璺緞鍙湁涓�鏉℃暟鎹紝鍒欑洿鎺ヨ繑鍥炶璧拌窛绂�
             return path.get(0).getMoveDistance();
@@ -225,7 +245,7 @@
     /**
      * 鑾峰彇涓棿鐐瑰埌鐩爣鐐硅璧拌窛绂�
      */
-    public static Integer getMiddleToDistDistance(List<NavigateNode> path, NavigateNode middlePath) {
+    public Integer getMiddleToDistDistance(List<NavigateNode> path, NavigateNode middlePath) {
         //鏈�鍚庝竴鏉¤妭鐐逛笉璁$畻杩涜璧拌窛绂�
         NavigateNode lastPath = path.get(path.size() - 1);
         //鎬昏窛绂�
@@ -250,7 +270,7 @@
     /**
      * 妫�娴嬭矾寰勬槸鍚﹀彲鐢�(鍙蛋)
      */
-    public static boolean checkPathIsAvailable(List<NavigateNode> path, Integer shuttleNo, Integer lev) {
+    public boolean checkPathIsAvailable(List<NavigateNode> path, Integer shuttleNo, Integer lev) {
         NavigateSolution solution = new NavigateSolution(NavigationMapType.DFX.id, lev, null, Utils.getShuttlePoints(shuttleNo, lev));//鑾峰彇鏃犵櫧鍚嶅崟鍦板浘(璇ュ湴鍥惧寘鍚皬杞﹀潗鏍�)
         int[][] map = solution.map;
         for (NavigateNode node : path) {
@@ -262,19 +282,83 @@
         return true;
     }
 
-    public static void main(String[] args) {
-        //璁$畻璺緞
-        List<NavigateNode> calc = calc("1000901", "1800201", NavigationMapType.NONE.id, null);
-        System.out.println(calc);
-        System.out.println("------------------------");
-//        List<NavigateNode> calc = calc("0501401", "0201801", "out");
-        //灏嗚矾寰勫垎鍓叉垚澶氭
-        ArrayList<ArrayList<NavigateNode>> data = getSectionPath(calc);
-        for (ArrayList<NavigateNode> list : data) {
-            Integer currentPathAllDistance = getCurrentPathAllDistance(list);//璁$畻褰撳墠璺緞鎬昏窛绂�
-            System.out.println(currentPathAllDistance);
-            System.out.println(list);
+    private NavigateNode pythonObjTransferNode(Object obj, Integer z) {
+        List<Integer> pathData = JSON.parseArray(obj.toString(), Integer.class);
+        Integer x = pathData.get(0);
+        Integer y = pathData.get(1);
+
+        NavigateNode node = new NavigateNode(x, y);
+        node.setDirection(null);
+        node.setIsInflectionPoint(false);
+        node.setZ(z);
+        return node;
+    }
+
+    public Double similarityPath(List<NavigateNode> firstPath, List<NavigateNode> secondPath) {
+        try {
+            List<int[]> first = new ArrayList<>();
+            for (NavigateNode node : firstPath) {
+                first.add(new int[]{node.getX(), node.getY()});
+            }
+
+            List<int[]> second = new ArrayList<>();
+            for (NavigateNode node : secondPath) {
+                second.add(new int[]{node.getX(), node.getY()});
+            }
+
+            ProcessBuilder processBuilder = new ProcessBuilder("python", pythonCalcSimilarity, JSON.toJSONString(first), JSON.toJSONString(second));
+            processBuilder.redirectErrorStream(true);
+
+            Process process = processBuilder.start();
+
+            // 璇诲彇Python鑴氭湰鐨勮緭鍑�
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line;
+            StringBuilder builder = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                builder.append(line);
+            }
+
+            // 绛夊緟Python鑴氭湰鎵ц瀹屾垚
+            int exitCode = process.waitFor();
+            if (exitCode != 0) {
+                System.out.println("Python script exited with error code: " + exitCode);
+                return null;
+            }
+            reader.close();
+
+            if (builder.length() <= 0) {
+                return null;
+            }
+
+            PythonSimilarityResult result = JSON.parseObject(builder.toString(), PythonSimilarityResult.class);
+            if (result.getCalcResult() != 200) {
+                return 0D;
+            }
+
+            Double similarity = result.getSimilarity();
+            return similarity;
+        } catch (Exception e) {
+            e.printStackTrace();
         }
+        return 0D;
+    }
+
+    public static void main(String[] args) {
+//        //璁$畻璺緞
+//        List<NavigateNode> calc = calc("1000901", "1800201", NavigationMapType.NONE.id, null);
+//        System.out.println(calc);
+//        System.out.println("------------------------");
+////        List<NavigateNode> calc = calc("0501401", "0201801", "out");
+//        //灏嗚矾寰勫垎鍓叉垚澶氭
+//        ArrayList<ArrayList<NavigateNode>> data = getSectionPath(calc);
+//        for (ArrayList<NavigateNode> list : data) {
+//            Integer currentPathAllDistance = getCurrentPathAllDistance(list);//璁$畻褰撳墠璺緞鎬昏窛绂�
+//            System.out.println(currentPathAllDistance);
+//            System.out.println(list);
+//        }
+
+        System.loadLibrary("example");
 
     }
 
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
index 2f10b29..3f8a667 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
@@ -56,6 +56,8 @@
     private ShuttleStandbyService shuttleStandbyService;
     @Autowired
     private DictService dictService;
+    @Autowired
+    private NavigateUtils navigateUtils;
 
     public synchronized ShuttleThread searchIdleShuttle(Task task) {
         String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc();
@@ -68,7 +70,7 @@
         //鑾峰彇鍚屽眰灏忚溅
         List<Device> currentLevDevices = new ArrayList<>();
         //鑾峰彇璺ㄥ眰灏忚溅
-        List<Device> diffLevDevices = new ArrayList<>();
+        HashMap<Integer,List<Device>> diffLevDeviceMap = new HashMap<>();
         for (Device device : list) {
             //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
             ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
@@ -77,10 +79,18 @@
                 continue;
             }
 
-            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) == lev) {
+            int shuttleLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
+            if (shuttleLev == lev) {
                 currentLevDevices.add(device);
             }else {
-                diffLevDevices.add(device);
+                List<Device> devices = null;
+                if(diffLevDeviceMap.containsKey(shuttleLev)) {
+                    devices = diffLevDeviceMap.get(shuttleLev);
+                }else {
+                    devices = new ArrayList<>();
+                }
+                devices.add(device);
+                diffLevDeviceMap.put(shuttleLev, devices);
             }
         }
         //鎼滅储鍚屽眰
@@ -88,7 +98,7 @@
 
         //鍚屽眰娌℃湁鎼滅储鍒板悎閫傚皬杞︼紝璺ㄦゼ灞傛悳绱�
         if(resThread == null) {
-            resThread = this.searchDiffLevShuttle(diffLevDevices, locNo, task);
+            resThread = this.searchDiffLevShuttle(diffLevDeviceMap, locNo, task);
         }
 
         return resThread;
@@ -144,7 +154,7 @@
 
             // 鍚屾ゼ灞傜洿鎺ヨ绠楀埌鐩爣搴撲綅
             //褰撳墠绌挎杞︾嚎绋嬪埌褰撳墠杞﹀瓙鎵�鍦ㄦゼ灞傜殑鐩爣搴撲綅璺濈
-            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
+            List<NavigateNode> currentShuttlePath = navigateUtils.calc(
                     currentLocNo
                     , locNo
                     , NavigationMapType.NORMAL.id
@@ -154,7 +164,7 @@
                 continue;
             }
 
-            Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
+            Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
 
             // 鎸傝浇浠诲姟鏉冮噸
             List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null);
@@ -171,102 +181,109 @@
         return resThread;
     }
 
-    private synchronized ShuttleThread searchDiffLevShuttle(List<Device> devices, String locNo, Task task) {
+    private synchronized ShuttleThread searchDiffLevShuttle(HashMap<Integer,List<Device>> devicesMap, String locNo, Task task) {
         ShuttleThread resThread = null;
         Integer finalDistance = ShuttleDispatcher.INF;
 
         //妫�娴嬬洰鏍囨ゼ灞傝溅鏁伴噺鏄惁灏忎簬鍏佽鐨勬渶澶ф暟閲�
         boolean checkDispatchMaxNum = checkDispatchMaxNum(Utils.getLev(locNo), task.getHostId());
 
-        for (Device device : devices) {
-            if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) {
-                continue;
-            }
-            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
-            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
-            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
-            if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
-                continue;
-            }
+        for (Map.Entry<Integer, List<Device>> entry : devicesMap.entrySet()) {
+            Integer lev = entry.getKey();
+            List<Device> devices = entry.getValue();
+            for (Device device : devices) {
+                if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) {
+                    continue;
+                }
+                //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+                ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
+                ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+                if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
+                    continue;
+                }
 
-            if (!shuttleThread.isIdle()) {
-                continue;
-            }
+                if (!shuttleThread.isIdle()) {
+                    continue;
+                }
 
-            BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>()
-                    .eq(BasShuttle::getShuttleNo, device.getDeviceNo())
-                    .eq(BasShuttle::getHostId, device.getHostId()));
-            if (basShuttle == null) {
-                continue;//灏忚溅鍩虹鏁版嵁涓嶅瓨鍦�
-            }
+                BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>()
+                        .eq(BasShuttle::getShuttleNo, device.getDeviceNo())
+                        .eq(BasShuttle::getHostId, device.getHostId()));
+                if (basShuttle == null) {
+                    continue;//灏忚溅鍩虹鏁版嵁涓嶅瓨鍦�
+                }
 
-            if (!Cools.isEmpty(basShuttle.getDisableLev())) {
-                List<Integer> disableLev = JSON.parseArray(basShuttle.getDisableLev(), Integer.class);
-                //妫�鏌ュ皬杞︽槸鍚︾鐢ㄨ妤煎眰
-                if (disableLev.contains(Utils.getLev(locNo))) {
-                    continue;//灏忚溅绂佺敤璇ユゼ灞傝烦杩囪杞�
+                if (!Cools.isEmpty(basShuttle.getDisableLev())) {
+                    List<Integer> disableLev = JSON.parseArray(basShuttle.getDisableLev(), Integer.class);
+                    //妫�鏌ュ皬杞︽槸鍚︾鐢ㄨ妤煎眰
+                    if (disableLev.contains(Utils.getLev(locNo))) {
+                        continue;//灏忚溅绂佺敤璇ユゼ灞傝烦杩囪杞�
+                    }
+                }
+
+                //妫�娴嬫槸鍚﹀瓨鍦ㄥ厖鐢典换鍔�
+                Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo()));
+                if (taskCharge != null) {
+                    continue;
+                }
+
+                // 鏈夋病鏈夎鍏朵粬浠诲姟璋冨害
+                int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//灏忚溅褰撳墠灞傞珮
+                String currentLocNo = shuttleProtocol.getCurrentLocNo();//灏忚溅褰撳墠搴撲綅鍙�
+
+                if (!checkDispatchMaxNum) {
+                    News.info("{}浠诲姟锛寋}灞傦紝宸茬粡杈惧埌褰撳墠妤煎眰璋冨害杞﹁締鏈�澶у��", task.getTaskNo(), Utils.getLev(locNo));
+                    continue;
+                }
+
+                //鑾峰彇璺濈灏忚溅浣嶇疆鏈�杩戠殑绌洪棽鍙崲灞傛彁鍗囨満
+                LiftThread liftThread = liftDispatcher.searchIdleLift(currentLocNo, task.getHostId(), true);
+                if (liftThread == null) {
+                    continue;
+                }
+                Device recentTransferLift = liftThread.getDevice();
+
+                //鑾峰彇灏忚溅妤煎眰鎻愬崌鏈哄緟鏈轰綅
+                ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>()
+                        .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId())
+                        .eq(ShuttleStandby::getDeviceLev, currentLev)
+                        .eq(ShuttleStandby::getStatus, 1));
+                String targetLocNo = shuttleStandby.getDeviceLoc();
+
+                //褰撳墠绌挎杞︾嚎绋嬪埌褰撳墠杞﹀瓙鎵�鍦ㄦゼ灞傜殑鎻愬崌鏈哄緟鏈轰綅璺濈
+                List<NavigateNode> currentShuttlePath = navigateUtils.calc(
+                        currentLocNo
+                        , targetLocNo
+                        , NavigationMapType.NORMAL.id
+                        , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev)
+                );//鎼滅储绌洪棽绌挎杞︼紝浣跨敤姝e父閫氶亾鍦板浘
+                if (currentShuttlePath == null) {
+                    continue;
+                }
+
+                Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
+
+                // 涓嶅悓妤煎眰鏉冮噸
+                if (currentLev != Utils.getLev(locNo)) {
+                    currDistance += WEIGHT;
+                }
+
+                // 鎸傝浇浠诲姟鏉冮噸
+                List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null);
+                if (!Cools.isEmpty(tasks)) {
+                    currDistance += tasks.size() * WEIGHT;
+                }
+
+                if (currDistance < finalDistance) {
+                    finalDistance = currDistance;
+                    resThread = shuttleThread;
                 }
             }
 
-            //妫�娴嬫槸鍚﹀瓨鍦ㄥ厖鐢典换鍔�
-            Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo()));
-            if (taskCharge != null) {
-                continue;
-            }
-
-            // 鏈夋病鏈夎鍏朵粬浠诲姟璋冨害
-            int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//灏忚溅褰撳墠灞傞珮
-            String currentLocNo = shuttleProtocol.getCurrentLocNo();//灏忚溅褰撳墠搴撲綅鍙�
-
-            if (!checkDispatchMaxNum) {
-                News.info("{}浠诲姟锛寋}灞傦紝宸茬粡杈惧埌褰撳墠妤煎眰璋冨害杞﹁締鏈�澶у��", task.getTaskNo(), Utils.getLev(locNo));
-                continue;
-            }
-
-            //鑾峰彇璺濈灏忚溅浣嶇疆鏈�杩戠殑绌洪棽鍙崲灞傛彁鍗囨満
-            LiftThread liftThread = liftDispatcher.searchIdleLift(currentLocNo, task.getHostId(), true);
-            if (liftThread == null) {
-                continue;
-            }
-            Device recentTransferLift = liftThread.getDevice();
-
-            //鑾峰彇灏忚溅妤煎眰鎻愬崌鏈哄緟鏈轰綅
-            ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>()
-                    .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId())
-                    .eq(ShuttleStandby::getDeviceLev, currentLev)
-                    .eq(ShuttleStandby::getStatus, 1));
-            String targetLocNo = shuttleStandby.getDeviceLoc();
-
-            //褰撳墠绌挎杞︾嚎绋嬪埌褰撳墠杞﹀瓙鎵�鍦ㄦゼ灞傜殑鎻愬崌鏈哄緟鏈轰綅璺濈
-            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
-                    currentLocNo
-                    , targetLocNo
-                    , NavigationMapType.NORMAL.id
-                    , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev)
-            );//鎼滅储绌洪棽绌挎杞︼紝浣跨敤姝e父閫氶亾鍦板浘
-            if (currentShuttlePath == null) {
-                continue;
-            }
-
-            Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
-
-            // 涓嶅悓妤煎眰鏉冮噸
-            if (currentLev != Utils.getLev(locNo)) {
-                currDistance += WEIGHT;
-            }
-
-            // 鎸傝浇浠诲姟鏉冮噸
-            List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null);
-            if (!Cools.isEmpty(tasks)) {
-                currDistance += tasks.size() * WEIGHT;
-            }
-
-            if (currDistance < finalDistance) {
-                finalDistance = currDistance;
-                resThread = shuttleThread;
+            if (resThread != null) {
+                break;
             }
         }
-
         return resThread;
     }
 
@@ -401,7 +418,7 @@
         String recentLoc = null;
         for (String loc : locNos) {
             //褰撳墠绌挎杞﹀埌閬胯浣嶈绠�
-            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
+            List<NavigateNode> currentShuttlePath = navigateUtils.calc(
                     currentLocNo
                     , loc
                     , NavigationMapType.NORMAL.id
@@ -411,7 +428,7 @@
                 continue;
             }
 
-            Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
+            Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//璁$畻褰撳墠璺緞琛岃蛋鎬昏窛绂�
             if (currDistance < finalDistance) {
                 finalDistance = currDistance;
                 recentLoc = loc;
@@ -521,13 +538,13 @@
     //鍒嗘瀽鍑哄簱璺緞寰呮満搴撲綅
     public String analyzeOutPathWaitLoc(String startLoc, String targetLoc, Device shuttleDevice) {
         //璁$畻璺緞骞跺垎瑙f垚涓ゆ鍔ㄤ綔
-        List<NavigateNode> nodeList = NavigateUtils.calc(startLoc, targetLoc, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(startLoc)));
+        List<NavigateNode> nodeList = navigateUtils.calc(startLoc, targetLoc, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(startLoc)));
         if (nodeList == null) {
             News.error("{} dash {} can't find navigate path!", startLoc, targetLoc);
             return null;
         }
         //鑾峰彇鍒嗘璺緞
-        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList);
+        ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
         if (data.size() <= 1) {
             return startLoc;//涓ょ偣涔嬮棿鍙湁涓�娈佃矾寰勶紝鍦ㄨ捣鐐逛綅缃瓑寰�
         }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/constant/DeviceRedisConstant.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/constant/DeviceRedisConstant.java
index 327a493..13c6f65 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/constant/DeviceRedisConstant.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/constant/DeviceRedisConstant.java
@@ -15,8 +15,14 @@
 
     public static final String MAP = "realtimeBasMap_";
 
+    public static final String BASE_MAP = "BaseMap_";
+
     public static final String LOCK_PATH = "mapLockPath_";
 
     public static final String COMMAND_TMP = "command_tmp_";
 
+    public static final String SIMILARITY_TIMES = "similarity_times_";
+
+    public static final String LIFT_PALLET_INBOUND = "lift_pallet_inbound_";
+
 }
diff --git a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java
index 58c11a3..aa74579 100644
--- a/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java
+++ b/zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/SurayShuttleThread.java
@@ -244,6 +244,7 @@
     public synchronized CommandResponse movePath(List<NavigateNode> nodes, Integer taskNo) {
         CommandResponse response = new CommandResponse(false);
         try {
+            NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
             //榛樿鍦板浘姣嶈建鏂瑰悜x
             String mapDirection = "x";
             DictService dictService = SpringUtils.getBean(DictService.class);
@@ -264,7 +265,7 @@
 
             ArrayList<HashMap<String, Object>> modes = new ArrayList<>();
             //鑾峰彇鍒嗘璺緞
-            ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodes);
+            ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodes);
             for (int idx = 0; idx < data.size(); idx++) {
                 ArrayList<NavigateNode> sectionNodes = data.get(idx);
                 boolean isRemoveFooterNode = false;//鏄惁鍓旈櫎灏捐妭鐐�
diff --git a/zy-asrs-wcs/src/main/resources/application.yml b/zy-asrs-wcs/src/main/resources/application.yml
index 268e372..c1b6fec 100644
--- a/zy-asrs-wcs/src/main/resources/application.yml
+++ b/zy-asrs-wcs/src/main/resources/application.yml
@@ -61,4 +61,7 @@
   pwd: xltys1995
 
 config:
-  token-key: KUHSMcYQ4lePt3r6bckz0P13cBJyoonYqInThvQlUnbsFCIcCcZZAbWZ6UNFztYNYPhGdy6eyb8WdIz8FU2Cz396TyTJk3NI2rtXMHBOehRb4WWJ4MdYVVg2oWPyqRQ2
\ No newline at end of file
+  token-key: KUHSMcYQ4lePt3r6bckz0P13cBJyoonYqInThvQlUnbsFCIcCcZZAbWZ6UNFztYNYPhGdy6eyb8WdIz8FU2Cz396TyTJk3NI2rtXMHBOehRb4WWJ4MdYVVg2oWPyqRQ2
+
+pythonCalcPath: D:\\path\\cpu.py
+pythonCalcSimilarity: D:\\path\\similarity.py
\ No newline at end of file
diff --git a/zy-asrs-wcs/src/main/resources/cpu.py b/zy-asrs-wcs/src/main/resources/cpu.py
new file mode 100644
index 0000000..28dd54a
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/cpu.py
@@ -0,0 +1,151 @@
+import json
+
+import numpy as np
+import time
+import heapq
+import sys
+import ast
+
+startTime = time.perf_counter()
+
+# 鍒涘缓涓�涓畝鍗曠殑缃戞牸锛�0 涓洪�氳锛�1 涓洪殰纰�
+# grid = np.array([
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [1, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 1, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 1, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 1, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 1, 0, 3, 0, 0, 3, 0],
+#   [0, 0, 0, 0, 0, 3, 0, 0, 3, 0]
+# ])
+# grid = np.array([[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1], [-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, 3, 3, 3, 3, 3, 3, 3, -1], [-1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 4, -1, 0, 0, 0, -1, 0, 0, 0, -1], [-1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 4, -1, 0, 0, 0, -1, 0, 0, 0, -1], [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, -1], [-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1], [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1], [-1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1], [-1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1], [-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1], [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 4, -1, -1, -1, -1], [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 4, 4, -1, -1, -1]])
+
+# A* 绠楁硶瀹炵幇
+def heuristic(a, b):
+    # 浣跨敤鏇煎搱椤胯窛绂讳綔涓哄惎鍙戝紡浼拌
+    return abs(a[0] - b[0]) + abs(a[1] - b[1])
+
+def astar_search(grid, start, goal, mapDirection):
+    rows, cols = grid.shape
+    start = (start // cols, start % cols)
+    goal = (goal // cols, goal % cols)
+
+    open_set = []
+    heapq.heappush(open_set, (0, start))
+
+    came_from = {}
+    g_score = {start: 0}
+    f_score = {start: heuristic(start, goal)}
+
+    while open_set:
+        current = heapq.heappop(open_set)[1]
+
+        if current == goal:
+            return reconstruct_path(came_from, current)
+
+        # 纭畾褰撳墠鑺傜偣鍊�
+        current_value = grid[current[0], current[1]]
+
+        neighbors = findNebor(current, current_value, mapDirection)
+
+        for neighbor in neighbors:
+            # 妫�鏌ラ偦灞呮槸鍚﹀湪缃戞牸鍐呬笖閫氳
+            if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < cols:
+                if grid[neighbor] <= -1:
+                    continue
+
+                if grid[neighbor] in [66]:
+                    continue
+
+                tentative_g_score = g_score[current] + 1
+
+                if neighbor not in g_score or tentative_g_score < g_score[neighbor]:
+                    came_from[neighbor] = current
+                    g_score[neighbor] = tentative_g_score
+                    f_score[neighbor] = tentative_g_score + heuristic(neighbor, goal)
+
+                    if neighbor not in [i[1] for i in open_set]:
+                        heapq.heappush(open_set, (f_score[neighbor], neighbor))
+
+    return []
+
+def reconstruct_path(came_from, current):
+    total_path = [current]
+    while current in came_from:
+        current = came_from[current]
+        total_path.append(current)
+    return total_path[::-1]  # 鍙嶈浆璺緞
+
+def findNebor(current,current_value, direction):
+    neighbors = []
+
+    if direction == "x":
+        if current_value == 3:
+            neighbors = [(current[0] + 1, current[1]), (current[0] - 1, current[1])]
+
+        if current_value == 0 or current_value == 3 or current_value == 5 or current_value == 6 or current_value == 67:
+            neighbors.append((current[0], current[1] + 1))
+            neighbors.append((current[0], current[1] - 1))
+    else:
+        if current_value == 3:
+            neighbors = [(current[0], current[1] + 1), (current[0], current[1] - 1)]
+
+        if current_value == 0 or current_value == 3 or current_value == 5 or current_value == 6 or current_value == 67:
+            neighbors.append((current[0] + 1, current[1]))
+            neighbors.append((current[0] - 1, current[1]))
+    return neighbors
+
+maps = sys.argv[1]
+start_str = sys.argv[2]
+goal_str = sys.argv[3]
+mapDirection = sys.argv[4]
+
+maps = ast.literal_eval(maps)
+grid = np.array(maps)
+# print(type(maps))
+# print(start_str)
+# print(goal_str)
+
+start_coords = (int(start_str.split('-')[0]), int(start_str.split('-')[1]))
+goal_coords = (int(goal_str.split('-')[0]), int(goal_str.split('-')[1]))
+
+
+# print(start_coords, goal_coords)
+# # 瀹氫箟璧风偣鍜岀粓鐐圭殑鍧愭爣
+# start_coords = (1, 1)  # 璧风偣鍧愭爣 (琛�, 鍒�)
+# goal_coords = (11, 6)    # 缁堢偣鍧愭爣 (琛�, 鍒�)
+
+# 灏嗗潗鏍囪浆鎹负涓�缁寸储寮�
+start = start_coords[0] * grid.shape[1] + start_coords[1]
+goal = goal_coords[0] * grid.shape[1] + goal_coords[1]
+
+try:
+    # 鑾峰彇璺緞
+    path_coordinates = astar_search(grid, start, goal, mapDirection)
+except:
+    path_coordinates = []
+
+end = time.perf_counter()
+# print("鏈�鐭矾寰勫潗鏍�:", path_coordinates)
+# print('绋嬪簭杩愯鏃堕棿涓�: %s Seconds' % (end - startTime))
+
+calcResult = 200
+if(len(path_coordinates) == 0):
+    calcResult = 500
+
+result = {
+    "start": start_str,
+    "target": goal_str,
+    "path": json.dumps(path_coordinates),
+    "time": (end - startTime),
+    "calcResult": calcResult
+}
+
+print(result)
\ No newline at end of file
diff --git a/zy-asrs-wcs/src/main/resources/similarity.py b/zy-asrs-wcs/src/main/resources/similarity.py
new file mode 100644
index 0000000..69b6a8f
--- /dev/null
+++ b/zy-asrs-wcs/src/main/resources/similarity.py
@@ -0,0 +1,47 @@
+import json
+import sys
+
+
+def calculate_similarity(path1, path2):
+    # 灏嗚矾寰勮浆鎹负闆嗗悎
+    set1 = set(path1)
+    set2 = set(path2)
+
+    # 璁$畻閲嶅彔鑺傜偣
+    overlap = len(set1.intersection(set2))
+
+    # 璁$畻鎬昏妭鐐�
+    total_nodes = len(set1.union(set2))
+
+    # 璁$畻鐩镐技搴�
+    similarity = overlap / total_nodes if total_nodes > 0 else 0
+
+    return similarity
+
+path_a_str = sys.argv[1]
+path_b_str = sys.argv[2]
+
+path_a = json.loads(path_a_str)
+path_a = [(int(x[0]), int(x[1])) for x in path_a]
+
+path_b = json.loads(path_b_str)
+path_b = [(int(x[0]), int(x[1])) for x in path_b]
+
+# # 绀轰緥璺緞
+# path_a = [(1, 1), (1, 2), (1, 3), (1, 4), (2, 4), (3, 4), (4, 4), (5, 4), (6, 4), (7, 4), (8, 4), (9, 4), (10, 4), (10, 5), (10, 6), (11, 6)]
+# path_b = [(1, 1), (1, 2), (1, 3), (1, 4), (2, 4), (3, 4), (4, 4), (5, 4), (6, 4), (7, 4), (8, 4), (9, 4), (10, 4), (10, 5), (10, 6), (11, 6)]
+
+
+# 璁$畻鐩镐技搴�
+similarity_score = calculate_similarity(path_a, path_b)
+
+calcResult = 200
+
+result = {
+    "firstPath": json.dumps(path_a),
+    "secondPath": json.dumps(path_b),
+    "similarity": similarity_score,
+    "calcResult": calcResult
+}
+
+print(result)
\ No newline at end of file

--
Gitblit v1.9.1