@ -5,26 +5,23 @@ import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainService ;
import club.joylink.rtss.simulation.cbtc.Simulation ;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository ;
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig ;
import club.joylink.rtss.simulation.cbtc.data.map.Route ;
import club.joylink.rtss.simulation.cbtc.data.map.Section ;
import club.joylink.rtss.simulation.cbtc.data.map.Signal ;
import club.joylink.rtss.simulation.cbtc.data.map.Stand ;
import club.joylink.rtss.simulation.cbtc.data.map.* ;
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan ;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan ;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath ;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo ;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Component ;
import org.springframework.util.CollectionUtils ;
import java.time.LocalDateTime ;
import java.time.LocalTime ;
import java.time.temporal.ChronoUnit ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Objects ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Component ;
import org.springframework.util.CollectionUtils ;
/ * *
* 计划车阶段处理服务
@ -32,47 +29,44 @@ import org.springframework.util.CollectionUtils;
@Slf4j
@Component
public class AtsPlanTrainStageService implements AtsStageService {
@Autowired
private AtsRealRunRecordService realRunRecordService ;
@Autowired
private AtsStandService atsStandService ;
@Autowired
private OnboardAtpApiService onboardAtpApiService ;
@Autowired
private AtsTrainService atsTrainService ;
@Autowired
private AtsRealRunRecordService realRunRecordService ;
@Autowired
private AtsStandService atsStandService ;
@Autowired
private OnboardAtpApiService onboardAtpApiService ;
@Autowired
private AtsTrainService atsTrainService ;
@Override
public void handleTransferTrackParking ( Simulation simulation , TrainInfo trainInfo ,
Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) ,
trainInfo . getTripNumber ( ) ) ;
@Override
public void handleTransferTrackParking ( Simulation simulation , TrainInfo trainInfo , Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) , trainInfo . getTripNumber ( ) ) ;
/ / List < RoutePath > routePathList = repository . queryRoutePathsByEnd ( parkSection ) ;
/ / if ( routePathList . get ( 0 ) . isRight ( ) = = trainInfo . getRight ( ) ) { / / 准备回库
/ / if ( ! parkSection . isTurnBackTrack ( ) ) { / / 针对上饶沙盘
/ / trainInfo . finishPlanPrepareInbound ( ) ;
/ / }
/ / } else 没看懂为啥有这部分逻辑 , 先注掉
if ( tripPlan . getEndSection ( ) . equals ( parkSection ) | |
tripPlan . getEndSection ( ) . getStation ( ) . equals ( parkSection . getStation ( ) ) ) {
/ / 列车到达计划终点 , 准备回库
if ( simulation . getRepository ( ) . getConfig ( ) . isHandleDepot ( ) ) {
trainInfo . finishPlanPrepareEnterDepot ( ) ;
} else {
if ( ! parkSection . isTurnBackTrack ( ) ) { / / 针对上饶沙盘
trainInfo . finishPlanPrepareInbound ( ) ;
}
}
/ / 转人工车
atsTrainService . setManualTrain ( simulation , trainInfo . getGroupNumber ( ) ) ;
} else if ( tripPlan . getStartSection ( ) . equals ( parkSection ) ) {
/ / 出库列车
if ( trainInfo . getPlanStandTrack ( ) ! = null ) {
return ;
}
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
if ( systemTime . toLocalTime ( ) . isAfter ( tripPlan . getStartTime ( ) ) ) {
if ( tripPlan . getEndSection ( ) . equals ( parkSection ) | |
tripPlan . getEndSection ( ) . getStation ( ) . equals ( parkSection . getStation ( ) ) ) {
/ / 列车到达计划终点 , 准备回库
if ( simulation . getRepository ( ) . getConfig ( ) . isHandleDepot ( ) ) {
trainInfo . finishPlanPrepareEnterDepot ( ) ;
} else {
if ( ! parkSection . isTurnBackTrack ( ) ) { / / 针对上饶沙盘
trainInfo . finishPlanPrepareInbound ( ) ;
}
}
/ / 转人工车
atsTrainService . setManualTrain ( simulation , trainInfo . getGroupNumber ( ) ) ;
} else if ( tripPlan . getStartSection ( ) . equals ( parkSection ) ) {
/ / 出库列车
if ( trainInfo . getPlanStandTrack ( ) ! = null ) {
return ;
}
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
if ( systemTime . toLocalTime ( ) . isAfter ( tripPlan . getStartTime ( ) ) ) {
/ / Integer intervalTime = repository . getIntervalTime ( ) ;
/ / LocalDateTime lastDepartTime = repository . getLastDepartTime ( ) ;
/ / if ( intervalTime ! = null & & lastDepartTime ! = null ) {
@ -80,289 +74,261 @@ public class AtsPlanTrainStageService implements AtsStageService {
/ / return ;
/ / }
/ / }
StationPlan nextPlan = tripPlan . getSecondStationPlan ( ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextPlan ) ;
StationPlan nextPlan = tripPlan . getSecondStationPlan ( ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextPlan ) ;
/ / repository . setLastDepartTime ( systemTime ) ;
}
}
}
@Override
public void handleNormalStandParking ( Simulation simulation , TrainInfo trainInfo ,
Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
MapConfig config = repository . getConfig ( ) ;
List < Stand > standList = parkSection . getStandList ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) ,
trainInfo . getTripNumber ( ) ) ;
TripPlan nextTripPlan = null ;
StationPlan stationPlan = tripPlan . queryStationPlan ( parkSection ) ;
if ( config . isStandTbStrategyIsInvalid ( ) ) {
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan )
& & tripPlan . isFrontTurnBack ( ) ) { / / 到达终点站了 , 判断站前折返还是站后折返
/ / 站前折返 , 查询下一车次计划
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
} else if ( stationPlan = = null & & tripPlan . isLastPlanStation ( parkSection . getStation ( ) ) ) {
if ( config . isAtsAutoHandleManualFrontTurnBack ( ) ) {
/ / 人工站前折返
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
}
}
if ( nextTripPlan ! = null ) { / / 站前折返 , 更新计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertEquals (
nextTripPlan . getFirstStationPlan ( ) . getSection ( ) , parkSection ,
String . format ( " 下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s] " ,
nextTripPlan . getStNumber ( ) , parkSection . getName ( ) ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan ,
nextTripPlan . getFirstStationPlan ( ) ) ;
}
} else {
if ( ! CollectionUtils . isEmpty ( standList ) ) {
Stand stand = standList . get ( 0 ) ;
switch ( stand . getTypeStrategy ( ) ) {
case NONE :
return ;
case AUTO :
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan ) ) { / / 当前计划终点站
if ( Objects . equals ( stand . isRight ( ) , trainInfo . getRight ( ) ) ) {
onboardAtpApiService . startTurnBack ( simulation , trainInfo . getGroupNumber ( ) ,
parkSection . getCode ( ) ) ;
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
if ( nextTripPlan ! = null ) { / / 站前折返 , 更新计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan ,
nextTripPlan . getSecondStationPlan ( ) ) ;
}
}
}
break ;
default :
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan )
& & tripPlan . isFrontTurnBack ( ) ) { / / 到达终点站了 , 判断站前折返还是站后折返
/ / 站前折返 , 查询下一车次计划
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
} else if ( stationPlan = = null & & tripPlan . isLastPlanStation (
parkSection . getStation ( ) ) ) {
if ( config . isAtsAutoHandleManualFrontTurnBack ( ) ) {
/ / 人工站前折返
}
}
@Override
public void handleNormalStandParking ( Simulation simulation , TrainInfo trainInfo , Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
MapConfig config = repository . getConfig ( ) ;
List < Stand > standList = parkSection . getStandList ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) , trainInfo . getTripNumber ( ) ) ;
TripPlan nextTripPlan = null ;
StationPlan stationPlan = tripPlan . queryStationPlan ( parkSection ) ;
if ( config . isStandTbStrategyIsInvalid ( ) ) {
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan ) & & tripPlan . isFrontTurnBack ( ) ) { / / 到达终点站了 , 判断站前折返还是站后折返
/ / 站前折返 , 查询下一车次计划
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
}
} else if ( stationPlan = = null & & tripPlan . isLastPlanStation ( parkSection . getStation ( ) ) ) {
if ( config . isAtsAutoHandleManualFrontTurnBack ( ) ) {
/ / 人工站前折返
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
}
}
if ( nextTripPlan ! = null ) { / / 站前折返 , 更新计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertEquals (
nextTripPlan . getFirstStationPlan ( ) . getSection ( ) , parkSection ,
String . format ( " 下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s] " ,
nextTripPlan . getStNumber ( ) , parkSection . getName ( ) ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan ,
nextTripPlan . getFirstStationPlan ( ) ) ;
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertEquals ( nextTripPlan . getFirstStationPlan ( ) . getSection ( ) , parkSection ,
String . format ( " 下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s] " , nextTripPlan . getStNumber ( ) , parkSection . getName ( ) ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan , nextTripPlan . getFirstStationPlan ( ) ) ;
}
} else {
if ( ! CollectionUtils . isEmpty ( standList ) ) {
Stand stand = standList . get ( 0 ) ;
switch ( stand . getTypeStrategy ( ) ) {
case NONE :
return ;
case AUTO :
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan ) ) { / / 当前计划终点站
if ( Objects . equals ( stand . isRight ( ) , trainInfo . getRight ( ) ) ) {
onboardAtpApiService . startTurnBack ( simulation , trainInfo . getGroupNumber ( ) , parkSection . getCode ( ) ) ;
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
if ( nextTripPlan ! = null ) { / / 站前折返 , 更新计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan , nextTripPlan . getSecondStationPlan ( ) ) ;
}
}
}
break ;
default :
if ( stationPlan ! = null & & tripPlan . isLastPlan ( stationPlan ) & & tripPlan . isFrontTurnBack ( ) ) { / / 到达终点站了 , 判断站前折返还是站后折返
/ / 站前折返 , 查询下一车次计划
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
} else if ( stationPlan = = null & & tripPlan . isLastPlanStation ( parkSection . getStation ( ) ) ) {
if ( config . isAtsAutoHandleManualFrontTurnBack ( ) ) {
/ / 人工站前折返
nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
}
}
if ( nextTripPlan ! = null ) { / / 站前折返 , 更新计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertEquals ( nextTripPlan . getFirstStationPlan ( ) . getSection ( ) , parkSection ,
String . format ( " 下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s] " , nextTripPlan . getStNumber ( ) , parkSection . getName ( ) ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan , nextTripPlan . getFirstStationPlan ( ) ) ;
}
break ;
}
}
break ;
}
}
}
}
@Override
public void ready2DepartFromNormalStand ( Simulation simulation , TrainInfo trainInfo ,
Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) ,
trainInfo . getTripNumber ( ) ) ;
StationPlan stationPlan = tripPlan . queryStationPlan ( parkSection ) ;
if ( stationPlan = = null ) {
/ / 非计划中的停靠站台轨 , 暂不处理
return ;
} else {
/ / 计划站台轨停车
if ( trainInfo . isTurnBack ( ) ) { / / 准备折返
return ;
}
if ( ! parkSection . isSamePhysical ( trainInfo . getPlanStandTrack ( ) ) ) {
/ / 已经更新过计划
return ;
}
if ( tripPlan . isLastPlan ( stationPlan ) ) {
if ( tripPlan . isBackup ( ) & & parkSection . equals ( tripPlan . getEndSection ( ) ) ) {
return ;
@Override
public void ready2DepartFromNormalStand ( Simulation simulation , TrainInfo trainInfo , Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) , trainInfo . getTripNumber ( ) ) ;
StationPlan stationPlan = tripPlan . queryStationPlan ( parkSection ) ;
if ( stationPlan = = null ) {
/ / 非计划中的停靠站台轨 , 暂不处理
return ;
} else {
/ / 计划站台轨停车
if ( trainInfo . isTurnBack ( ) ) { / / 准备折返
return ;
}
if ( ! parkSection . isSamePhysical ( trainInfo . getPlanStandTrack ( ) ) ) {
/ / 已经更新过计划
return ;
}
if ( tripPlan . isLastPlan ( stationPlan ) ) {
if ( tripPlan . isBackup ( ) & & parkSection . equals ( tripPlan . getEndSection ( ) ) ) {
return ;
}
/ / 到达终点站 , 准备折返
log . debug ( String . format ( " 列车[%s]折返初始化 " , trainInfo . getGroupNumber ( ) ) ) ;
List < RoutePath > routePaths = repository . getRoutePaths ( parkSection , tripPlan . getEndSection ( ) ) ;
Signal signal = parkSection . getSignalOf ( routePaths . get ( 0 ) . isRight ( ) ) ;
if ( signal . isMainAspect ( ) | | signal . isGuideAspect ( ) ) {
Route lockedRoute = signal . getLockedRoute ( ) ;
if ( lockedRoute ! = null & & lockedRoute . getLastRouteSection ( ) . isTurnBackTrack ( ) ) {
trainInfo . turnBackInit ( lockedRoute . getLastRouteSection ( ) ) ;
this . onboardAtpApiService . startTurnBack ( simulation , trainInfo . getGroupNumber ( ) ,
lockedRoute . getLastRouteSection ( ) . getCode ( ) ) ;
}
}
} else {
StationPlan nextStationPlan = tripPlan . queryNextStationPlan ( parkSection ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextStationPlan ) ;
}
}
/ / 到达终点站 , 准备折返
log . debug ( String . format ( " 列车[%s]折返初始化 " , trainInfo . getGroupNumber ( ) ) ) ;
List < RoutePath > routePaths = repository . getRoutePaths ( parkSection ,
tripPlan . getEndSection ( ) ) ;
Signal signal = parkSection . getSignalOf ( routePaths . get ( 0 ) . isRight ( ) ) ;
if ( signal . isMainAspect ( ) | | signal . isGuideAspect ( ) ) {
Route lockedRoute = signal . getLockedRoute ( ) ;
if ( lockedRoute ! = null & & lockedRoute . getLastRouteSection ( ) . isTurnBackTrack ( ) ) {
trainInfo . turnBackInit ( lockedRoute . getLastRouteSection ( ) ) ;
this . onboardAtpApiService . startTurnBack ( simulation , trainInfo . getGroupNumber ( ) ,
lockedRoute . getLastRouteSection ( ) . getCode ( ) ) ;
}
}
void updateTripPlan ( Simulation simulation , TrainInfo trainInfo , TripPlan nextTripPlan ) {
trainInfo . applyNewTripPlan ( nextTripPlan ) ;
this . onboardAtpApiService . updateTripPlan ( simulation , trainInfo . getGroupNumber ( ) , nextTripPlan ) ;
}
public void updateNextPlan ( Simulation simulation , TrainInfo trainInfo , TripPlan tripPlan , StationPlan nextStationPlan ) {
if ( nextStationPlan = = null ) {
log . warn ( String . format ( " 列车[%s]下一计划到站为null " , trainInfo . debugStr ( ) ) ) ;
return ;
}
} else {
StationPlan nextStationPlan = tripPlan . queryNextStationPlan ( parkSection ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextStationPlan ) ;
}
}
}
void updateTripPlan ( Simulation simulation , TrainInfo trainInfo , TripPlan nextTripPlan ) {
trainInfo . applyNewTripPlan ( nextTripPlan ) ;
this . onboardAtpApiService . updateTripPlan ( simulation , trainInfo . getGroupNumber ( ) , nextTripPlan ) ;
}
public void updateNextPlan ( Simulation simulation , TrainInfo trainInfo , TripPlan tripPlan ,
StationPlan nextStationPlan ) {
if ( nextStationPlan = = null ) {
log . warn ( String . format ( " 列车[%s]下一计划到站为null " , trainInfo . debugStr ( ) ) ) ;
return ;
}
trainInfo . updatePlanInfo ( nextStationPlan ) ;
Section nextPlanSection = nextStationPlan . getSection ( ) ;
trainInfo . updateEstimatedArriveInfo ( nextPlanSection , nextStationPlan . getArriveTime ( ) ) ;
int runTime = this . calculateRunTime ( simulation , trainInfo , tripPlan , nextStationPlan ) ;
boolean park = nextStationPlan . isPark ( ) ;
if ( tripPlan . isLastPlan ( nextStationPlan ) ) {
park = true ;
}
boolean jump = this . atsStandService . isJump ( nextPlanSection , trainInfo . getGroupNumber ( ) ) ;
if ( tripPlan . isLastPlan ( nextStationPlan ) & & jump ) {
jump = false ;
}
this . onboardAtpApiService . updateNextArriveInfo ( simulation , trainInfo . getGroupNumber ( ) ,
nextPlanSection , park , runTime , jump ) ;
}
private int calculateRunTime ( Simulation simulation , TrainInfo trainInfo ,
TripPlan tripPlan , StationPlan nextStationPlan ) {
MapConfig config = simulation . getRepository ( ) . getConfig ( ) ;
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
Section start ;
Section end = nextStationPlan . getSection ( ) ;
LocalTime startTime ;
LocalTime endTime = nextStationPlan . getArriveTime ( ) ;
List < StationPlan > planList = tripPlan . getPlanList ( ) ;
boolean turnBack = true ;
boolean outbound = false ;
startTime = tripPlan . getStartTime ( ) ;
start = tripPlan . getStartSection ( ) ;
for ( StationPlan stationPlan : planList ) {
if ( stationPlan . equals ( nextStationPlan ) ) {
break ;
}
turnBack = false ;
if ( stationPlan . getSection ( ) . isTransferTrack ( ) ) {
outbound = true ;
} else {
outbound = false ;
}
startTime = stationPlan . getLeaveTime ( ) ;
start = stationPlan . getSection ( ) ;
}
int planRunTime = ( int ) ChronoUnit . SECONDS . between ( startTime , endTime ) ;
int adjustRunTime = planRunTime ;
if ( ! turnBack & & ! outbound & & config . isAdjustOperationAutomatically ( )
& & trainInfo . isAtsAutoAdjust ( ) ) {
startTime = systemTime . toLocalTime ( ) ;
adjustRunTime = ( int ) ChronoUnit . SECONDS . between ( startTime , endTime ) ;
}
int runTime = Math . min ( adjustRunTime , planRunTime + 30 ) ;
if ( runTime < = 0 ) {
runTime = 1 ;
}
log . debug ( String . format ( " 列车[%s]站间[%s->%s]运行时间为:[%s] " , trainInfo . getGroupNumber ( ) ,
start . debugStr ( ) , end . debugStr ( ) , runTime ) ) ;
return runTime ;
}
@Override
public void handleTurnBackTrackParking ( Simulation simulation , TrainInfo trainInfo ,
Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) ,
trainInfo . getTripNumber ( ) ) ;
/ / 车次计划中的车站计划全部完成 , 并且当前折返轨与计划折返轨属于同一站 , 则认为车次计划完成
boolean completed = tripPlan . getPlanList ( ) . stream ( ) . allMatch ( StationPlan : : isFinished )
& & tripPlan . getEndSection ( ) . getStation ( ) . equals ( parkSection . getStation ( ) ) ;
if ( completed ) {
/ / 计划终端折返轨或和计划终端折返轨同站的折返轨 , 根据车次类型处理
TripPlan nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
if ( nextTripPlan = = null ) {
return ;
}
if ( tripPlan . isBackup ( ) ) {
/ / 备用车
if ( systemTime . toLocalTime ( ) . plusMinutes ( 5 ) . isAfter ( nextTripPlan . getStartTime ( ) ) ) {
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertNotEquals ( parkSection ,
nextTripPlan . getFirstStationPlan ( ) . getSection ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan ,
nextTripPlan . getFirstStationPlan ( ) ) ;
return ;
trainInfo . updatePlanInfo ( nextStationPlan ) ;
Section nextPlanSection = nextStationPlan . getSection ( ) ;
trainInfo . updateEstimatedArriveInfo ( nextPlanSection , nextStationPlan . getArriveTime ( ) ) ;
int runTime = this . calculateRunTime ( simulation , trainInfo , tripPlan , nextStationPlan ) ;
boolean park = nextStationPlan . isPark ( ) ;
if ( tripPlan . isLastPlan ( nextStationPlan ) ) {
park = true ;
}
} else if ( tripPlan . isTurnBack ( ) ) {
/ / 折返计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertNotEquals ( parkSection ,
nextTripPlan . getFirstStationPlan ( ) . getSection ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan ,
nextTripPlan . getFirstStationPlan ( ) ) ;
return ;
}
} else {
/ / 非终端折返轨 , 更新列车下一计划到达
if ( trainInfo . getPlanStandTrack ( ) ! = null ) {
return ;
}
/ / 查询停靠区段能到达的相邻的站台轨 , 取计划中包含的 , 再进行筛选 , 选出下一车站计划
List < RoutePath > routePathList = repository . queryRoutePathsByStart ( parkSection ) ;
List < StationPlan > sameDirectionList = new ArrayList < > ( ) ;
List < StationPlan > reverseDirectionList = new ArrayList < > ( ) ;
for ( RoutePath routePath : routePathList ) {
StationPlan stationPlan = tripPlan . queryStationPlan ( routePath . getEnd ( ) ) ;
boolean jump = this . atsStandService . isJump ( nextPlanSection , trainInfo . getGroupNumber ( ) ) ;
if ( tripPlan . isLastPlan ( nextStationPlan ) & & jump ) {
jump = false ;
}
this . onboardAtpApiService . updateNextArriveInfo ( simulation , trainInfo . getGroupNumber ( ) ,
nextPlanSection , park , runTime , jump ) ;
}
private int calculateRunTime ( Simulation simulation , TrainInfo trainInfo ,
TripPlan tripPlan , StationPlan nextStationPlan ) {
MapConfig config = simulation . getRepository ( ) . getConfig ( ) ;
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
Section start ;
Section end = nextStationPlan . getSection ( ) ;
LocalTime startTime ;
LocalTime endTime = nextStationPlan . getArriveTime ( ) ;
List < StationPlan > planList = tripPlan . getPlanList ( ) ;
boolean turnBack = true ;
boolean outbound = false ;
startTime = tripPlan . getStartTime ( ) ;
start = tripPlan . getStartSection ( ) ;
for ( StationPlan stationPlan : planList ) {
if ( stationPlan . equals ( nextStationPlan ) ) {
break ;
}
turnBack = false ;
if ( stationPlan . getSection ( ) . isTransferTrack ( ) ) {
outbound = true ;
} else {
outbound = false ;
}
startTime = stationPlan . getLeaveTime ( ) ;
start = stationPlan . getSection ( ) ;
}
int planRunTime = ( int ) ChronoUnit . SECONDS . between ( startTime , endTime ) ;
int adjustRunTime = planRunTime ;
if ( ! turnBack & & ! outbound & & config . isAdjustOperationAutomatically ( ) & & trainInfo . isAtsAutoAdjust ( ) ) {
startTime = systemTime . toLocalTime ( ) ;
adjustRunTime = ( int ) ChronoUnit . SECONDS . between ( startTime , endTime ) ;
}
int runTime = Math . min ( adjustRunTime , planRunTime + 30 ) ;
if ( runTime < = 0 ) {
runTime = 1 ;
}
log . debug ( String . format ( " 列车[%s]站间[%s->%s]运行时间为:[%s] " , trainInfo . getGroupNumber ( ) ,
start . debugStr ( ) , end . debugStr ( ) , runTime ) ) ;
return runTime ;
}
@Override
public void handleTurnBackTrackParking ( Simulation simulation , TrainInfo trainInfo , Section parkSection ) {
SimulationDataRepository repository = simulation . getRepository ( ) ;
LocalDateTime systemTime = simulation . getSystemTime ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) , trainInfo . getTripNumber ( ) ) ;
if ( tripPlan . getEndSection ( ) . equals ( parkSection )
/*|| tripPlan.getEndSection().getStation().equals(parkSection.getStation())*/ ) {
/ / 计划终端折返轨或和计划终端折返轨同站的折返轨 , 根据车次类型处理
TripPlan nextTripPlan = repository . queryNextTripPlanOf ( tripPlan ) ;
if ( nextTripPlan = = null ) {
return ;
}
if ( tripPlan . isBackup ( ) ) {
/ / 备用车
if ( systemTime . toLocalTime ( ) . plusMinutes ( 5 ) . isAfter ( nextTripPlan . getStartTime ( ) ) ) {
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertNotEquals ( parkSection , nextTripPlan . getFirstStationPlan ( ) . getSection ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan , nextTripPlan . getFirstStationPlan ( ) ) ;
return ;
}
} else if ( tripPlan . isTurnBack ( ) ) {
/ / 折返计划
this . updateTripPlan ( simulation , trainInfo , nextTripPlan ) ;
BusinessExceptionAssertEnum . DATA_ERROR . assertNotEquals ( parkSection , nextTripPlan . getFirstStationPlan ( ) . getSection ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , nextTripPlan , nextTripPlan . getFirstStationPlan ( ) ) ;
return ;
}
} else {
/ / 非终端折返轨 , 更新列车下一计划到达
if ( trainInfo . getPlanStandTrack ( ) ! = null ) {
return ;
}
/ / 查询停靠区段能到达的相邻的站台轨 , 取计划中包含的 , 再进行筛选 , 选出下一车站计划
List < RoutePath > routePathList = repository . queryRoutePathsByStart ( parkSection ) ;
List < StationPlan > sameDirectionList = new ArrayList < > ( ) ;
List < StationPlan > reverseDirectionList = new ArrayList < > ( ) ;
for ( RoutePath routePath : routePathList ) {
StationPlan stationPlan = tripPlan . queryStationPlan ( routePath . getEnd ( ) ) ;
if ( stationPlan ! = null ) {
if ( routePath . isRight ( ) = = tripPlan . isRight ( ) ) {
sameDirectionList . add ( stationPlan ) ;
} else {
reverseDirectionList . add ( stationPlan ) ;
}
}
}
StationPlan stationPlan = null ;
if ( sameDirectionList . size ( ) > 0 ) {
stationPlan = sameDirectionList . get ( 0 ) ;
} else if ( reverseDirectionList . size ( ) > 0 ) {
stationPlan = reverseDirectionList . get ( 0 ) ;
}
if ( stationPlan ! = null ) {
this . updateNextPlan ( simulation , trainInfo , tripPlan , stationPlan ) ;
}
}
}
@Override
public void handlePassStand ( Simulation simulation , TrainInfo trainInfo ) {
String planStandTrack = trainInfo . getPlanStandTrack ( ) ;
if ( planStandTrack = = null ) {
return ;
}
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) , trainInfo . getTripNumber ( ) ) ;
StationPlan stationPlan = tripPlan . queryStationPlan ( planStandTrack ) ;
Section section = repository . getByCode ( planStandTrack , Section . class ) ;
/ / 更新离站信息
trainInfo . updateLeaveInfo ( section , simulation . getSystemTime ( ) . toLocalTime ( ) ) ;
/ / 更新后续计划到站
if ( stationPlan ! = null ) {
if ( routePath . isRight ( ) = = tripPlan . isRight ( ) ) {
sameDirectionList . add ( stationPlan ) ;
} else {
reverseDirectionList . add ( stationPlan ) ;
}
stationPlan . finish ( ) ;
this . realRunRecordService . recordTrainRealRun ( simulation , trainInfo , stationPlan . getStation ( ) ,
stationPlan . getSection ( ) , false ) ;
StationPlan nextPlan = tripPlan . queryNextStationPlan ( stationPlan . getStation ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextPlan ) ;
}
}
StationPlan stationPlan = null ;
if ( sameDirectionList . size ( ) > 0 ) {
stationPlan = sameDirectionList . get ( 0 ) ;
} else if ( reverseDirectionList . size ( ) > 0 ) {
stationPlan = reverseDirectionList . get ( 0 ) ;
}
if ( stationPlan ! = null ) {
this . updateNextPlan ( simulation , trainInfo , tripPlan , stationPlan ) ;
}
}
}
@Override
public void handlePassStand ( Simulation simulation , TrainInfo trainInfo ) {
String planStandTrack = trainInfo . getPlanStandTrack ( ) ;
if ( planStandTrack = = null ) {
return ;
}
SimulationDataRepository repository = simulation . getRepository ( ) ;
TripPlan tripPlan = repository . getTripPlan ( trainInfo . getServiceNumber ( ) ,
trainInfo . getTripNumber ( ) ) ;
StationPlan stationPlan = tripPlan . queryStationPlan ( planStandTrack ) ;
Section section = repository . getByCode ( planStandTrack , Section . class ) ;
/ / 更新离站信息
trainInfo . updateLeaveInfo ( section , simulation . getSystemTime ( ) . toLocalTime ( ) ) ;
/ / 更新后续计划到站
if ( stationPlan ! = null ) {
stationPlan . finish ( ) ;
this . realRunRecordService . recordTrainRealRun ( simulation , trainInfo , stationPlan . getStation ( ) ,
stationPlan . getSection ( ) , false ) ;
StationPlan nextPlan = tripPlan . queryNextStationPlan ( stationPlan . getStation ( ) ) ;
this . updateNextPlan ( simulation , trainInfo , tripPlan , nextPlan ) ;
}
}
}