Browse Source

进路触发逻辑

zhanghaijun 2 years ago
parent
commit
9b81f6ac66

+ 2 - 0
pom.xml

@@ -128,6 +128,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-resources-plugin</artifactId>
+                <version>3.2.0</version>
                 <configuration>
                     <delimiters>
                         <delimiter>${resource.delimiter}</delimiter>
@@ -155,6 +156,7 @@
                 <plugin>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-maven-plugin</artifactId>
+                    <version>${spring-boot.version}</version>
                     <configuration>
                         <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                         <layout>ZIP</layout>

+ 2 - 2
train-server/src/main/java/top/haijunit/train/listener/MessageEventListener.java

@@ -18,9 +18,9 @@ import top.haijunit.websocket.utils.WebSocketUtils;
 import java.lang.reflect.InvocationTargetException;
 
 /**
- * @author zhang
+ * @author zhanghaijun
  * @date 2023/11/23 23:13
- * @description [一句话描述该类的功能]
+ * @description websocket消息监听
  */
 @Slf4j
 @Component

+ 39 - 0
train-server/src/main/java/top/haijunit/train/listener/ReportTimeHandle.java

@@ -1,14 +1,22 @@
 package top.haijunit.train.listener;
 
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import top.haijunit.train.domain.entity.RouteEntity;
+import top.haijunit.train.simulation.RouteComputerService;
+import top.haijunit.train.simulation.TrainComputerService;
 import top.haijunit.train.simulation.TrainItem;
 import top.haijunit.train.simulation.TrainSimulationHolder;
 import top.haijunit.train.socket.CommandEnum;
 import top.haijunit.train.socket.TrainWebSocketUtils;
 
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
 /**
  * @author zhanghaijun
  * @date 2023/11/27 17:50
@@ -16,8 +24,14 @@ import top.haijunit.train.socket.TrainWebSocketUtils;
  */
 @Slf4j
 @Component
+@RequiredArgsConstructor
 public class ReportTimeHandle {
 
+    private final RouteComputerService routeComputerService;
+    private final TrainComputerService trainComputerService;
+
+    /** 定时发送列车位置数据 */
+    @Async
     @Scheduled(fixedRate = 50)
     public void sendTrainPositionList() {
         for (TrainItem trainItem : TrainSimulationHolder.getTrainItem()) {
@@ -25,8 +39,33 @@ public class ReportTimeHandle {
         }
     }
 
+    /** 定时发送进路占用数据 */
+    // @Async
+    // @Scheduled(fixedRate = 50)
+    public void sendRouterStatus() {
+        Map<Long, LinkedList<RouteEntity>> routeMap = TrainSimulationHolder.getRouteMap();
+        TrainWebSocketUtils.sendMessage(CommandEnum.ROUTE_STATUS, new HashMap<>(routeMap));
+    }
+
     @Async
     public void sendTrainPosition(TrainItem train) {
         TrainWebSocketUtils.sendMessage(CommandEnum.TRAIN, train);
     }
+
+    /** 定时计算进路 */
+    @Async
+    @Scheduled(fixedRate = 10000)
+    public void runRouteCompute() {
+        for (TrainItem trainItem : TrainSimulationHolder.getTrainItem()) {
+            routeComputerService.run(trainItem);
+        }
+    }
+
+    public void runTrainCompute() {
+        for (TrainItem trainItem : TrainSimulationHolder.getTrainItem()) {
+            trainComputerService.run(trainItem);
+        }
+    }
+
+
 }

+ 2 - 2
train-server/src/main/java/top/haijunit/train/listener/TrainApplication.java

@@ -15,7 +15,7 @@ import java.util.List;
 /**
  * @author zhanghaijun
  * @date 2023/11/27 17:02
- * @description [一句话描述该类的功能]
+ * @description 项目启动初始化列车信息
  */
 @Slf4j
 @Component
@@ -25,7 +25,7 @@ public class TrainApplication implements ApplicationRunner {
     private final TrainRepository trainRepository;
 
     @Override
-    public void run(ApplicationArguments args) throws Exception {
+    public void run(ApplicationArguments args) {
         List<TrainEntity> list = trainRepository.findAll();
         for (TrainEntity train : list) {
             TrainItem trainItem = new TrainItem(train.getId(), train.getName(), train.getTrainLength(), train.getInitKilometer(), train.getInitDirection());

+ 82 - 0
train-server/src/main/java/top/haijunit/train/simulation/RouteComputerService.java

@@ -0,0 +1,82 @@
+package top.haijunit.train.simulation;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import top.haijunit.train.domain.constant.RouteStatusEnum;
+import top.haijunit.train.domain.constant.SignalStateEnum;
+import top.haijunit.train.domain.entity.RouteEntity;
+import top.haijunit.train.service.RouteService;
+import top.haijunit.train.service.SwitchService;
+
+import java.math.BigDecimal;
+import java.util.LinkedList;
+
+/**
+ * @author zhanghaijun
+ * @date 2023/11/27 17:54
+ * @description 进路计算
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class RouteComputerService {
+
+    private final SwitchService switchService;
+    private final RouteService routeService;
+
+    @Async
+    public void run(TrainItem train) {
+        // 占用、 列车 车头 过了信号灯 变成红色
+        // 列车 车尾离开 进路 型号等 空闲状态
+        //
+        LinkedList<RouteEntity> list = routeCompute(train);
+        // TODO 释放车尾已过的进路
+
+        // 更新进路共享数据
+        TrainSimulationHolder.addRouteList(train.getId(), list);
+    }
+
+    public LinkedList<RouteEntity> routeCompute(TrainItem train) {
+        LinkedList<RouteEntity> routeList = TrainSimulationHolder.getRouteList(train.getId());
+        // 1、是否触发进路计算
+        // 2、寻找下一跳进路
+        // 3、下一条进路是否为空闲
+        // 4、下一条进路是否包括道岔,道岔状态是否正确
+        // 5、将下一条进路状态置为锁定状态
+        // 6、释放车尾已过的进路
+        // TODO 假设向前走100米
+        BigDecimal nextPrePosition = train.getKilometer().add(new BigDecimal(100));
+        RouteEntity routeTrigger = routeService.isTrigger(train.getKilometer(), nextPrePosition);
+        if (null == routeTrigger) {
+            // 没有触发进路
+            return routeList;
+        }
+        // 找到下一个进路
+        RouteEntity nextRoute = routeService.getNextRoute(routeTrigger.getId());
+        if (null == nextRoute) {
+            // 没有找到下一个进路
+            return routeList;
+        }
+        // a)检查进路当前是否为出清/空闲状态,否则返回触发失败;
+        if (!TrainSimulationHolder.isRouteIdle(nextRoute.getId())) {
+            // 下一跳进路为非出清状态
+            return routeList;
+        }
+        if (!routeTrigger.getSwitchList().isEmpty()) {
+            // b)检查进路中道岔状态是否与进路要求的状态一致
+            boolean changed = switchService.changeSwitchState(routeTrigger.getSwitchMap());
+            if (changed) {
+                // TODo 切换道岔需要时间
+                return routeList;
+            }
+        }
+        // c)出清(如果包括道岔,道岔已就位),将进路至于锁闭状态
+        nextRoute.setRouteStatus(RouteStatusEnum.LOCK);
+        // d)将进路的信号状态置为红色
+        nextRoute.setSignalState(String.valueOf(SignalStateEnum.RED_YELLOW.getCode()));
+        routeList.addLast(nextRoute);
+        return routeList;
+    }
+}

+ 5 - 53
train-server/src/main/java/top/haijunit/train/simulation/TrainComputerService.java

@@ -2,69 +2,21 @@ package top.haijunit.train.simulation;
 
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import top.haijunit.train.domain.constant.RouteStatusEnum;
-import top.haijunit.train.domain.constant.SignalStateEnum;
-import top.haijunit.train.domain.entity.RouteEntity;
-import top.haijunit.train.service.RouteService;
-import top.haijunit.train.service.SwitchService;
-
-import java.math.BigDecimal;
-import java.util.LinkedList;
 
 /**
  * @author zhanghaijun
- * @date 2023/11/27 17:54
- * @description [一句话描述该类的功能]
+ * @date 2023/11/29 22:08
+ * @description 列车位置计算
  */
 @Slf4j
 @Service
 @RequiredArgsConstructor
 public class TrainComputerService {
 
-    private final SwitchService switchService;
-    private final RouteService routeService;
-
-    public void routeCompute(TrainItem train) {
-        LinkedList<RouteEntity> routeList = TrainSimulationHolder.getRouteList(train.getId());
-        // 1、是否触发进路计算
-        // 2、寻找下一跳进路
-        // 3、下一条进路是否为空闲
-        // 4、下一条进路是否包括道岔,道岔状态是否正确
-        // 5、将下一条进路状态置为锁定状态
-        // 6、释放车尾已过的进路
-        // TODO 假设向前走100米
-        BigDecimal nextPrePosition = train.getKilometer().add(new BigDecimal(100));
-        RouteEntity routeTrigger = routeService.isTrigger(train.getKilometer(), nextPrePosition);
-        if (null == routeTrigger) {
-            // 没有触发进路
-            return;
-        }
-        // 找到下一个进路
-        RouteEntity nextRoute = routeService.getNextRoute(routeTrigger.getId());
-        if (null == nextRoute) {
-            // 没有找到下一个进路
-            return;
-        }
-        // a)检查进路当前是否为出清/空闲状态,否则返回触发失败;
-        if (!TrainSimulationHolder.isRouteIdle(nextRoute.getId())) {
-            // 下一跳进路为非出清状态
-            return;
-        }
-        if (!routeTrigger.getSwitchList().isEmpty()) {
-            // b)检查进路中道岔状态是否与进路要求的状态一致
-            boolean changed = switchService.changeSwitchState(routeTrigger.getSwitchMap());
-            if (changed) {
-                // TODo 切换道岔需要时间
-                return;
-            }
-        }
-        // c)出清(如果包括道岔,道岔已就位),将进路至于锁闭状态
-        nextRoute.setRouteStatus(RouteStatusEnum.LOCK);
-        // d)将进路的信号状态置为红色
-        nextRoute.setSignalState(String.valueOf(SignalStateEnum.RED_YELLOW.getCode()));
-        routeList.addLast(nextRoute);
-        // TODO 释放车尾已过的进路
+    @Async
+    public void run(TrainItem trainItem) {
 
     }
 }

+ 4 - 0
train-server/src/main/java/top/haijunit/train/simulation/TrainSimulationHolder.java

@@ -43,6 +43,10 @@ public class TrainSimulationHolder {
         return TRAVEL_ROUTE_MAP.getOrDefault(trainId, new LinkedList<>());
     }
 
+    public static Map<Long, LinkedList<RouteEntity>> getRouteMap() {
+        return TRAVEL_ROUTE_MAP;
+    }
+
     public static boolean isRouteIdle(Long routeId) {
         for (Map.Entry<Long, LinkedList<RouteEntity>> entry : TRAVEL_ROUTE_MAP.entrySet()) {
             return entry.getValue().stream().noneMatch(item -> item.getId().equals(routeId) && !item.getRouteStatus().equals(RouteStatusEnum.IDLE));

+ 1 - 0
train-server/src/main/java/top/haijunit/train/socket/CommandEnum.java

@@ -20,6 +20,7 @@ public enum CommandEnum {
     TRAIN(10101, "列车状态信息", null),
     ROAD_SIGNAL(10102, "信号机状态信息", null),
     ROAD_SWITCH(10103, "道岔状态信息", null),
+    ROUTE_STATUS(10104, "进路状态信息", null),
     PLATFORM_PRESSING_STOP(20104, "站台紧急停车操作指令", SocketDevice.Platform.class),
     // AFC设备
     AFC_GATE_MACHINE(10201, "AFC闸机信息", null),