|
|
@@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import top.haijunit.train.domain.constant.TrainConstant;
|
|
|
import top.haijunit.train.domain.entity.SelectionEntity;
|
|
|
+import top.haijunit.train.domain.entity.SignStopEntity;
|
|
|
import top.haijunit.train.service.SelectionService;
|
|
|
import top.haijunit.train.simulation.domain.RouteItem;
|
|
|
import top.haijunit.train.simulation.domain.TrainItem;
|
|
|
@@ -12,8 +13,13 @@ import top.haijunit.train.utils.CalculatorUtil;
|
|
|
import top.haijunit.train.utils.NumberUtil;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.time.Duration;
|
|
|
import java.time.LocalTime;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.LinkedList;
|
|
|
+import java.util.OptionalInt;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.IntStream;
|
|
|
|
|
|
/**
|
|
|
* @author zhanghaijun
|
|
|
@@ -28,32 +34,77 @@ public class TrainComputerService {
|
|
|
|
|
|
|
|
|
public void run(TrainItem trainItem) {
|
|
|
+ TrainSimulationHolder.addTrainItem(this.runComputer(trainItem));
|
|
|
+ }
|
|
|
+
|
|
|
+ public TrainItem runComputer(TrainItem trainItem) {
|
|
|
+ // 进路数据
|
|
|
LinkedList<RouteItem> routeList = TrainSimulationHolder.getRouteList(trainItem.getTrainId());
|
|
|
- if (routeList == null || routeList.isEmpty()) {
|
|
|
+ // 区段数据
|
|
|
+ LinkedList<SelectionEntity> selectionAllList = routeList.stream().map(RouteItem::getSelectionList).flatMap(LinkedList::stream).collect(Collectors.toCollection(LinkedList::new));
|
|
|
+ // 停车标数据
|
|
|
+ HashMap<Long, SignStopEntity> stopSignalMap = selectionService.getStopSignalMap(selectionAllList.stream().map(SelectionEntity::getId).collect(Collectors.toCollection(LinkedList::new)));
|
|
|
+ // 当前的区段下标
|
|
|
+ OptionalInt optionIndex = IntStream.range(0, selectionAllList.size()).filter(i -> {
|
|
|
+ SelectionEntity entity = selectionAllList.get(i);
|
|
|
+ return NumberUtil.isContain(trainItem.getHeadKilometer(), entity.getStartKilometer(), entity.getEndKilometer());
|
|
|
+ }).findFirst();
|
|
|
+ if (optionIndex.isEmpty()) {
|
|
|
log.error("列车没有进路,列车位置: {},列车速度: {},列车方向: {}", trainItem.getHeadKilometer(), trainItem.getSpeed(), trainItem.getDirection());
|
|
|
- return;
|
|
|
+ return null;
|
|
|
}
|
|
|
- // 获取当前的世家
|
|
|
+ // 计算前的区段下标
|
|
|
+ int index = optionIndex.getAsInt();
|
|
|
+ // 计算后的区段下标
|
|
|
+ int currentIndex = -1;
|
|
|
+ // 获取当前的时间
|
|
|
LocalTime now = LocalTime.now();
|
|
|
- // 开始更新列车的数据:位置、速度、方向
|
|
|
// 1、距离上一个周期 列车运行的距离
|
|
|
BigDecimal decimal = trainItem.getDistance(now);
|
|
|
-
|
|
|
- // 2、计算当前时间列车的应该的位置
|
|
|
- BigDecimal kilometer = switch (trainItem.getDirection()) {
|
|
|
- case UP -> trainItem.getKilometer().subtract(decimal).abs();
|
|
|
- case DOWN -> trainItem.getKilometer().add(decimal).abs();
|
|
|
- };
|
|
|
- SelectionEntity selection = selectionService.getSelection(kilometer, trainItem.getDirection());
|
|
|
- trainItem.setHeadKilometer(now, kilometer, selection);
|
|
|
-
|
|
|
- // 更新列车运行状态
|
|
|
- RouteItem lastRoute = routeList.getLast();
|
|
|
- // MA TODO 停车标
|
|
|
- BigDecimal distanceMa = switch (trainItem.getDirection()) {
|
|
|
- case UP -> trainItem.getHeadKilometer().subtract(lastRoute.getHeadKilometer()).abs();
|
|
|
- case DOWN -> trainItem.getHeadKilometer().subtract(lastRoute.getTailKilometer()).abs();
|
|
|
- };
|
|
|
+ if (NumberUtil.isLessOrEqual(decimal, BigDecimal.ZERO) && Duration.between(trainItem.getUpdateTime(), now).getSeconds() < 3) {
|
|
|
+ // 停车状态 时间不足3S
|
|
|
+ return trainItem;
|
|
|
+ } else {
|
|
|
+ // 向前行驶计算
|
|
|
+ BigDecimal kilometer = trainItem.getHeadKilometer();
|
|
|
+ for (int i = index; i < selectionAllList.size(); i++) {
|
|
|
+ SelectionEntity entity = selectionAllList.get(i);
|
|
|
+ BigDecimal d = entity.getEndKilometer().subtract(kilometer);
|
|
|
+ if (NumberUtil.isGreaterOrEqual(d, decimal)) {
|
|
|
+ currentIndex = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ kilometer = entity.getEndKilometer();
|
|
|
+ decimal = decimal.subtract(d);
|
|
|
+ }
|
|
|
+ for (int i = index; i <= currentIndex; i++) {
|
|
|
+ SelectionEntity entity = selectionAllList.get(i);
|
|
|
+ if (stopSignalMap.containsKey(entity.getId())) {
|
|
|
+ // 期间存在停车标 立即停车
|
|
|
+ trainItem.setDirection(entity.getDirection());
|
|
|
+ trainItem.setUpdateTime(now);
|
|
|
+ trainItem.setSpeed(new BigDecimal("0.00"));
|
|
|
+ trainItem.setAcceleration(new BigDecimal("0.00"));
|
|
|
+ BigDecimal kilometerStop = entity.getStartKilometer().add(stopSignalMap.get(entity.getId()).getSelectionOff());
|
|
|
+ trainItem.setKilometer(kilometerStop);
|
|
|
+ return trainItem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SelectionEntity currentSelection = selectionAllList.get(currentIndex);
|
|
|
+ trainItem.setHeadKilometer(now, currentSelection.getStartKilometer().add(decimal), currentSelection);
|
|
|
+ }
|
|
|
+ // 计算MA
|
|
|
+ BigDecimal distanceMa = new BigDecimal("0.00");
|
|
|
+ for (int i = currentIndex; i < selectionAllList.size(); i++) {
|
|
|
+ SelectionEntity entity = selectionAllList.get(i);
|
|
|
+ if (!stopSignalMap.containsKey(entity.getId())) {
|
|
|
+ distanceMa = distanceMa.add(entity.getSelectionLength());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ SignStopEntity signStop = stopSignalMap.get(entity.getId());
|
|
|
+ distanceMa = distanceMa.add(signStop.getSelectionOff());
|
|
|
+ break;
|
|
|
+ }
|
|
|
BigDecimal distance = CalculatorUtil.distance(trainItem.getSpeed(), TrainConstant.DECELERATION_LIMIT);
|
|
|
// log.info("列车信息:列车:{},速度:{},加速度:{}, 滑行距离:{}", trainItem.getTrainId(), trainItem.getSpeed(), trainItem.getAcceleration(), distance);
|
|
|
if (NumberUtil.isLessOrEqual(distanceMa, distance)) {
|
|
|
@@ -69,6 +120,6 @@ public class TrainComputerService {
|
|
|
// 加速
|
|
|
trainItem.setAcceleration(TrainConstant.ACCELERATION_LIMIT);
|
|
|
}
|
|
|
- TrainSimulationHolder.addTrainItem(trainItem);
|
|
|
+ return trainItem;
|
|
|
}
|
|
|
}
|