diff --git a/core/osrd-reporting/src/main/java/fr/sncf/osrd/reporting/exceptions/ErrorType.java b/core/osrd-reporting/src/main/java/fr/sncf/osrd/reporting/exceptions/ErrorType.java index c051c902ce2..1094222f612 100644 --- a/core/osrd-reporting/src/main/java/fr/sncf/osrd/reporting/exceptions/ErrorType.java +++ b/core/osrd-reporting/src/main/java/fr/sncf/osrd/reporting/exceptions/ErrorType.java @@ -92,12 +92,17 @@ public enum ErrorType { ), PathfindingGaugeError( "no_path_found:gauge", - "No path could be found after loading Gauge constraints", + "No path could be found with compatible Gauge", ErrorCause.USER ), PathfindingElectrificationError( "no_path_found:electrification", - "No path could be found after loading Electrification constraints", + "No path could be found with compatible electrification", + ErrorCause.USER + ), + PathfindingSignalisationSystemError( + "no_path_found:signalisation_system", + "No path could be found with a compatible signaling system", ErrorCause.USER ), PathfindingTimeoutError( diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/PathfindingBlocksEndpoint.kt b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/PathfindingBlocksEndpoint.kt index edf6f290f62..b0bf3436fad 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/PathfindingBlocksEndpoint.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/PathfindingBlocksEndpoint.kt @@ -5,11 +5,11 @@ import fr.sncf.osrd.api.FullInfra import fr.sncf.osrd.api.InfraManager import fr.sncf.osrd.api.pathfinding.constraints.ElectrificationConstraints import fr.sncf.osrd.api.pathfinding.constraints.LoadingGaugeConstraints +import fr.sncf.osrd.api.pathfinding.constraints.SignalingSystemConstraints +import fr.sncf.osrd.api.pathfinding.constraints.makeSignalingSystemConstraints import fr.sncf.osrd.api.pathfinding.request.PathfindingRequest import fr.sncf.osrd.api.pathfinding.request.PathfindingWaypoint -import fr.sncf.osrd.api.pathfinding.response.PathWaypointResult import fr.sncf.osrd.api.pathfinding.response.PathfindingResult -import fr.sncf.osrd.envelope_sim.TrainPhysicsIntegrator import fr.sncf.osrd.graph.* import fr.sncf.osrd.graph.Pathfinding.EdgeLocation import fr.sncf.osrd.infra.api.Direction @@ -79,6 +79,8 @@ class PathfindingBlocksEndpoint ErrorType.PathfindingGaugeError constraintErrors[ElectrificationConstraints::class.java] = ErrorType.PathfindingElectrificationError + constraintErrors[SignalingSystemConstraints::class.java] = + ErrorType.PathfindingSignalisationSystemError } } } @@ -203,8 +205,13 @@ fun runPathfinding( infra.blockInfra, infra.rawInfra, rollingStocks ) + val signalisationSystemConstraints = makeSignalingSystemConstraints( + infra.blockInfra, + infra.signalingSimulator, + rollingStocks + ) val constraints = listOf( - loadingGaugeConstraints, electrificationConstraints + loadingGaugeConstraints, electrificationConstraints, signalisationSystemConstraints ) val remainingDistanceEstimators = makeHeuristics(infra, waypoints) diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/ElectrificationConstraints.kt b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/ElectrificationConstraints.kt index ec680d1adc3..ac310674818 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/ElectrificationConstraints.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/ElectrificationConstraints.kt @@ -13,7 +13,6 @@ import fr.sncf.osrd.utils.units.Distance import fr.sncf.osrd.utils.units.Offset import java.util.stream.Collectors -@JvmRecord data class ElectrificationConstraints( val blockInfra: BlockInfra, val rawInfra: RawSignalingInfra, diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/LoadingGaugeConstraints.kt b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/LoadingGaugeConstraints.kt index 2deafdaae5b..ed175d85524 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/LoadingGaugeConstraints.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/LoadingGaugeConstraints.kt @@ -9,7 +9,6 @@ import fr.sncf.osrd.utils.DistanceRangeMap import fr.sncf.osrd.utils.units.Offset import java.util.stream.Collectors -@JvmRecord data class LoadingGaugeConstraints( val blockInfra: BlockInfra, val infra: RawSignalingInfra, diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/SignalingSystemConstraints.kt b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/SignalingSystemConstraints.kt new file mode 100644 index 00000000000..b344b02c3bd --- /dev/null +++ b/core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/SignalingSystemConstraints.kt @@ -0,0 +1,63 @@ +package fr.sncf.osrd.api.pathfinding.constraints + +import fr.sncf.osrd.graph.EdgeToRangesId +import fr.sncf.osrd.graph.Pathfinding +import fr.sncf.osrd.signaling.SignalingSimulator +import fr.sncf.osrd.sim_infra.api.* +import fr.sncf.osrd.train.RollingStock +import fr.sncf.osrd.utils.units.Offset +import fr.sncf.osrd.utils.units.meters + +data class SignalingSystemConstraints( + val blockInfra: BlockInfra, + val rollingStocksSupportedSigSystems: List> +) : EdgeToRangesId { + override fun apply(edge: BlockId): MutableCollection> { + val res = HashSet>() + for (rollingStocksigSystems in rollingStocksSupportedSigSystems) { + val edgeBlockedRanges = getBlockedRanges(edge, blockInfra, rollingStocksigSystems) + if (edgeBlockedRanges.isNotEmpty()) { + res.addAll(edgeBlockedRanges) + break // if this edge is blocked for 2 RS, we will have the same exact range (the full edge range) twice + } + } + return res + } + + /** + * Returns the sections of the given block that can't be used by the given rolling stock + */ + private fun getBlockedRanges( + edge: BlockId, + blockInfra: BlockInfra, + rollingStockSigSystems: List + ): Set> { + val blockSigSystem = blockInfra.getBlockSignalingSystem(edge) + val isRSCompatibleWithBlock = rollingStockSigSystems.contains(blockSigSystem) + if (isRSCompatibleWithBlock) { + return setOf() + } + return setOf(Pathfinding.Range( + Offset(0.meters), + blockInfra.getBlockLength(edge)) + ) + } +} + +fun makeSignalingSystemConstraints( + blockInfra: BlockInfra, + signalingSimulator: SignalingSimulator, + rollingStocks: Collection, +): SignalingSystemConstraints { + val rsSupportedSigSystems = rollingStocks.map { stock -> + stock.supportedSignalingSystems.mapNotNull { s -> try { + signalingSimulator.sigModuleManager.findSignalingSystem(s) + } catch (e: Exception) { + null + } } + } + return SignalingSystemConstraints( + blockInfra, + rsSupportedSigSystems + ) +} diff --git a/core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMPathfinding.kt b/core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMPathfinding.kt index a85f73fe0e6..ea09854080c 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMPathfinding.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMPathfinding.kt @@ -3,6 +3,7 @@ package fr.sncf.osrd.stdcm.graph import fr.sncf.osrd.api.FullInfra import fr.sncf.osrd.api.pathfinding.constraints.ElectrificationConstraints import fr.sncf.osrd.api.pathfinding.constraints.LoadingGaugeConstraints +import fr.sncf.osrd.api.pathfinding.constraints.makeSignalingSystemConstraints import fr.sncf.osrd.api.pathfinding.makeHeuristics import fr.sncf.osrd.envelope_sim.allowances.utils.AllowanceValue import fr.sncf.osrd.graph.* @@ -58,6 +59,10 @@ fun findPath( fullInfra.blockInfra, fullInfra.rawInfra, listOf(rollingStock) ) + val signalingSystemConstraints = makeSignalingSystemConstraints( + fullInfra.blockInfra, fullInfra.signalingSimulator, + listOf(rollingStock) + ) // Initialize the A* heuristic val locations = steps.stream() @@ -70,6 +75,7 @@ fun findPath( .setEdgeToLength { edge -> edge.length.cast() } .addBlockedRangeOnEdges { edge: STDCMEdge? -> convertRanges(loadingGaugeConstraints.apply(edge!!.block)) } .addBlockedRangeOnEdges { edge: STDCMEdge? -> convertRanges(electrificationConstraints.apply(edge!!.block)) } + .addBlockedRangeOnEdges { edge: STDCMEdge? -> convertRanges(signalingSystemConstraints.apply(edge!!.block)) } .setTotalCostUntilEdgeLocation { range -> totalCostUntilEdgeLocation( range, diff --git a/core/src/test/java/fr/sncf/osrd/train/TestTrains.java b/core/src/test/java/fr/sncf/osrd/train/TestTrains.java index 498a0a2c037..656a48c383e 100644 --- a/core/src/test/java/fr/sncf/osrd/train/TestTrains.java +++ b/core/src/test/java/fr/sncf/osrd/train/TestTrains.java @@ -23,6 +23,8 @@ public class TestTrains { public static final RollingStock CONSTANT_POWER_TRAIN; + public static final RollingStock TRAIN_WITHOUT_TVM; + public static final double MAX_SPEED = 300 / 3.6; private static Map createModeEffortCurves( @@ -132,7 +134,7 @@ private static Map createModeEffortCurves ); REALISTIC_FAST_TRAIN = new RollingStock( - "fast train", + "realistic fast train", 400, trainMass, 1.05, (0.65 * trainMass) / 100, ((0.008 * trainMass) / 100) * 3.6, (((0.00012 * trainMass) / 100) * 3.6) * 3.6, @@ -189,7 +191,7 @@ private static Map createModeEffortCurves ); FAST_ELECTRIC_TRAIN = new RollingStock( - "fast train", + "fast electric train", 400, trainMass, 1.05, (0.65 * trainMass) / 100, ((0.008 * trainMass) / 100) * 3.6, (((0.00012 * trainMass) / 100) * 3.6) * 3.6, @@ -225,6 +227,25 @@ private static Map createModeEffortCurves "1", new String[]{"BAL", "BAPR", "TVM300", "TVM430"} ); + + TRAIN_WITHOUT_TVM = new RollingStock( + "train without tvm", + 100, trainMass, 1.05, (0.65 * trainMass) / 100, + ((0.008 * trainMass) / 100) * 3.6, + (((0.00012 * trainMass) / 100) * 3.6) * 3.6, + 44, + 20, + 0.05, + 0.25, + 0.5, + PhysicsRollingStock.GammaType.CONST, + RJSLoadingGaugeType.G1, + createModeEffortCurves(44, CurveShape.HYPERBOLIC, + Map.of("thermal", new RollingStock.EffortCurveConditions[0])), + "thermal", + "1", + new String[]{"BAL", "BAPR"} + ); } @Test diff --git a/core/src/test/kotlin/fr/sncf/osrd/pathfinding/PathfindingSignalingTest.kt b/core/src/test/kotlin/fr/sncf/osrd/pathfinding/PathfindingSignalingTest.kt new file mode 100644 index 00000000000..8015cb37e2d --- /dev/null +++ b/core/src/test/kotlin/fr/sncf/osrd/pathfinding/PathfindingSignalingTest.kt @@ -0,0 +1,135 @@ +package fr.sncf.osrd.pathfinding + +import fr.sncf.osrd.api.pathfinding.request.PathfindingWaypoint +import fr.sncf.osrd.api.pathfinding.runPathfinding +import fr.sncf.osrd.graph.Pathfinding +import fr.sncf.osrd.railjson.schema.common.graph.EdgeDirection +import fr.sncf.osrd.reporting.exceptions.ErrorType +import fr.sncf.osrd.reporting.exceptions.OSRDError +import fr.sncf.osrd.sim_infra.api.BlockId +import fr.sncf.osrd.train.TestTrains +import fr.sncf.osrd.utils.DummyInfra +import fr.sncf.osrd.utils.units.Offset +import fr.sncf.osrd.utils.units.meters +import org.assertj.core.api.AssertionsForClassTypes +import org.assertj.core.api.Assertions as assertjAssertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import fr.sncf.osrd.sim_infra.api.Block +import org.junit.jupiter.api.BeforeEach + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class PathfindingSignalingTest { + private var infra: DummyInfra = DummyInfra() + + private fun setSigSystemIds(list: List, signalingSystemName: String) { + val id = infra.fullInfra().signalingSimulator.sigModuleManager.findSignalingSystem(signalingSystemName) + list.forEach { + infra.blockPool[it.index.toInt()].signalingSystemId = id + } + } + @BeforeEach + fun setUp() { + /* c1 + ^ \ + / v + a --> b d --> e + \ ^ + v / + c2 + */ + infra = DummyInfra() + infra.addBlock("a", "b") + infra.addBlock("b", "c1") + infra.addBlock("b", "c2") + infra.addBlock("c1", "d") + infra.addBlock("c2", "d") + infra.addBlock("d", "e") + } + + @Test + fun balTrainOnTVMBlockShouldThrow() { + setSigSystemIds(listOf(1U, 2U, 3U, 4U).map { BlockId(it) }, "TVM300") + val waypointStart = PathfindingWaypoint( + "a->b", + 0.0, + EdgeDirection.START_TO_STOP + ) + val waypointEnd = PathfindingWaypoint( + "d->e", + 100.0, + EdgeDirection.START_TO_STOP + ) + val waypoints = Array(2) { Array(1) { waypointStart } } + waypoints[1][0] = waypointEnd + + // Run a pathfinding with a non TVM train, expecting not to find any path + AssertionsForClassTypes.assertThatThrownBy { + runPathfinding( + infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM) + ) + } + .isExactlyInstanceOf(OSRDError::class.java) + .satisfies({ exception: Throwable? -> + assertjAssertions.assertThat( + (exception as OSRDError?)!!.osrdErrorType + ).isEqualTo(ErrorType.PathfindingSignalisationSystemError) + }) + } + + @Test + fun shouldFindTopPathOnBalBlocksForBalTrain() { + setSigSystemIds(listOf(2U, 4U).map { BlockId(it) }, "TVM300") + val waypointStart = PathfindingWaypoint( + "a->b", + 0.0, + EdgeDirection.START_TO_STOP + ) + val waypointEnd = PathfindingWaypoint( + "d->e", + 100.0, + EdgeDirection.START_TO_STOP + ) + val waypoints = Array(2) { Array(1) { waypointStart } } + waypoints[1][0] = waypointEnd + + val pathfindingResult = runPathfinding( + infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM) + ) + + AssertionsForClassTypes.assertThat(pathfindingResult.ranges).isEqualTo(arrayListOf( + Pathfinding.EdgeRange(BlockId(0U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(1U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(3U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(5U), Offset(0.meters), Offset(100.meters)) + )) + } + + @Test + fun shouldFindBottomPathOnBalBlocksForBalTrain() { + setSigSystemIds(listOf(1U, 3U).map { BlockId(it) }, "TVM430") + val waypointStart = PathfindingWaypoint( + "a->b", + 0.0, + EdgeDirection.START_TO_STOP + ) + val waypointEnd = PathfindingWaypoint( + "d->e", + 100.0, + EdgeDirection.START_TO_STOP + ) + val waypoints = Array(2) { Array(1) { waypointStart } } + waypoints[1][0] = waypointEnd + + val pathfindingResult = runPathfinding( + infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM) + ) + + AssertionsForClassTypes.assertThat(pathfindingResult.ranges).isEqualTo(arrayListOf( + Pathfinding.EdgeRange(BlockId(0U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(2U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(4U), Offset(0.meters), Offset(100.meters)), + Pathfinding.EdgeRange(BlockId(5U), Offset(0.meters), Offset(100.meters)) + )) + } +} diff --git a/core/src/test/kotlin/fr/sncf/osrd/pathfinding/constraints/SignalingSystemConstraintsTest.kt b/core/src/test/kotlin/fr/sncf/osrd/pathfinding/constraints/SignalingSystemConstraintsTest.kt new file mode 100644 index 00000000000..50be38b3f6c --- /dev/null +++ b/core/src/test/kotlin/fr/sncf/osrd/pathfinding/constraints/SignalingSystemConstraintsTest.kt @@ -0,0 +1,51 @@ +package fr.sncf.osrd.pathfinding.constraints + +import fr.sncf.osrd.api.pathfinding.constraints.makeSignalingSystemConstraints +import fr.sncf.osrd.graph.Pathfinding +import fr.sncf.osrd.sim_infra.api.Block +import fr.sncf.osrd.sim_infra.api.BlockId +import fr.sncf.osrd.sim_infra.api.TrackChunk +import fr.sncf.osrd.train.RollingStock +import fr.sncf.osrd.train.TestTrains +import fr.sncf.osrd.utils.DummyInfra +import fr.sncf.osrd.utils.units.Offset +import fr.sncf.osrd.utils.units.meters +import org.assertj.core.api.Assertions +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import java.util.stream.Stream + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class SignalingSystemConstraintsTest { + @ParameterizedTest + @MethodSource("testSignalingSystemArgs") + fun testSignalingSystemBlockedRanges(blockId: BlockId, rollingStock: RollingStock, expectedBlockedRanges: Collection>) { + /* + + a --> b --> c + + */ + val infra = DummyInfra() + infra.addBlock("a", "b", signalingSystemName = "BAL") + infra.addBlock("b", "c", signalingSystemName = "TVM430") + val fullInfra = infra.fullInfra() + val signalingSystemConstraints = makeSignalingSystemConstraints( + fullInfra.blockInfra, + fullInfra.signalingSimulator, + listOf(rollingStock) + ) + val blockedRanges = signalingSystemConstraints.apply(blockId) + Assertions.assertThat(blockedRanges).isEqualTo(expectedBlockedRanges) + } + + private fun testSignalingSystemArgs(): Stream { + return Stream.of( + Arguments.of(0, TestTrains.TRAIN_WITHOUT_TVM, HashSet()), + Arguments.of(1, TestTrains.TRAIN_WITHOUT_TVM, setOf(Pathfinding.Range(Offset(0.meters), Offset(100.meters)))), + Arguments.of(0, TestTrains.FAST_ELECTRIC_TRAIN, HashSet()), + Arguments.of(1, TestTrains.FAST_ELECTRIC_TRAIN, HashSet()), + ) + } +} diff --git a/core/src/test/kotlin/fr/sncf/osrd/utils/DummyInfra.kt b/core/src/test/kotlin/fr/sncf/osrd/utils/DummyInfra.kt index 5a61ced2cb5..ff94eeb987d 100644 --- a/core/src/test/kotlin/fr/sncf/osrd/utils/DummyInfra.kt +++ b/core/src/test/kotlin/fr/sncf/osrd/utils/DummyInfra.kt @@ -3,6 +3,7 @@ package fr.sncf.osrd.utils import com.google.common.collect.HashBiMap import com.google.common.collect.HashMultimap import fr.sncf.osrd.api.FullInfra +import fr.sncf.osrd.api.makeSignalingSimulator import fr.sncf.osrd.geom.LineString import fr.sncf.osrd.geom.Point import fr.sncf.osrd.sim_infra.api.* @@ -12,7 +13,9 @@ import fr.sncf.osrd.utils.units.* import kotlin.time.Duration /** This class is used to create a minimal infra to be used on unit tests, with a simple block graph. - * Ids are all interchangeable, there's one zone, one chunk, one track, one route per block. + * Ids are all interchangeable: + * there's one zone, one chunk, one track, one route, one signal per block, + * each having the same id as the block. * Block descriptor can be edited when we need to set data that isn't included in the method parameters. * Not all methods are implemented, but it can be added when relevant. */ class DummyInfra : RawInfra, BlockInfra { @@ -22,46 +25,33 @@ class DummyInfra : RawInfra, BlockInfra { private val detectorMap = HashBiMap.create() private val entryMap = HashMultimap.create() private val exitMap = HashMultimap.create() + private val signalingSimulator = makeSignalingSimulator() /** get the FullInfra */ fun fullInfra(): FullInfra { return FullInfra( this, - null, + signalingSimulator.loadSignals(this), this, - null + signalingSimulator ) } - /** Creates a block going from nodes `entry` to `exit` of length 100m, named $entry->$exit, with no max speed. */ - fun addBlock( - entry: String, - exit: String, - ): BlockId { - return addBlock(entry, exit, 100.meters) - } - - /** Creates a block going from nodes `entry` to `exit` of length `length`, named $entry->$exit */ - fun addBlock( - entry: String, - exit: String, - length: Distance - ): BlockId { - return addBlock(entry, exit, length, Double.POSITIVE_INFINITY) - } - /** Creates a block going from nodes `entry` to `exit` of length `length`, named $entry->$exit, - * with the given maximum speed. */ + * with the given maximum speed and signaling system. + * If the nodes do not exist they are created. */ fun addBlock( entry: String, exit: String, - length: Distance, - allowedSpeed: Double, + length: Distance = 100.meters, + allowedSpeed: Double = Double.POSITIVE_INFINITY, + signalingSystemName: String = "BAL" ): BlockId { val name = String.format("%s->%s", entry, exit) val entryId = detectorMap.computeIfAbsent(entry) { DirDetectorId(detectorMap.size.toUInt() * 2u) } val exitId = detectorMap.computeIfAbsent(exit) { DirDetectorId(detectorMap.size.toUInt() * 2u) } val id = BlockId(blockPool.size.toUInt()) + val signalingSystemId = getSignalingSystemIdfromName(signalingSystemName) blockPool.add( DummyBlockDescriptor( length, @@ -70,6 +60,8 @@ class DummyInfra : RawInfra, BlockInfra { exitId, allowedSpeed, 0.0, + signalingSystemId, + signalingSystemName ) ) entryMap.put(entryId, id) @@ -84,6 +76,8 @@ class DummyInfra : RawInfra, BlockInfra { val exit: DirDetectorId, val allowedSpeed: Double, var gradient: Double, + var signalingSystemId: SignalingSystemId, + var signalingSystemName: String, var voltage: String = "", var neutralSectionForward: NeutralSection? = null, var neutralSectionBackward: NeutralSection? = null, @@ -92,11 +86,11 @@ class DummyInfra : RawInfra, BlockInfra { // region inherited override fun getSignals(zonePath: ZonePathId): StaticIdxList { - TODO("Not yet implemented") + return makeIndexList(zonePath) } override fun getSignalPositions(zonePath: ZonePathId): OffsetList { - TODO("Not yet implemented") + return mutableOffsetArrayListOf(Offset(0.meters)) } override fun getSpeedLimits(route: RouteId): StaticIdxList { @@ -112,36 +106,41 @@ class DummyInfra : RawInfra, BlockInfra { } override val physicalSignals: StaticIdxSpace - get() = TODO("Not yet implemented") + get() = StaticIdxSpace(blockPool.size.toUInt()) override val logicalSignals: StaticIdxSpace - get() = TODO("Not yet implemented") + get() = StaticIdxSpace(blockPool.size.toUInt()) override fun getLogicalSignals(signal: PhysicalSignalId): StaticIdxList { - TODO("Not yet implemented") + return makeIndexList(signal) } override fun getPhysicalSignal(signal: LogicalSignalId): PhysicalSignalId { - TODO("Not yet implemented") + return convertId(signal) } - override fun getPhysicalSignalName(signal: PhysicalSignalId): String? { - TODO("Not yet implemented") + override fun getPhysicalSignalName(signal: PhysicalSignalId): String { + return "BAL" } override fun getSignalSightDistance(signal: PhysicalSignalId): Distance { - TODO("Not yet implemented") + return 400.meters } override fun getSignalingSystemId(signal: LogicalSignalId): String { - TODO("Not yet implemented") + return blockPool[signal.index].signalingSystemName + } + + private fun getSignalingSystemIdfromName(signalingSystemName: String): SignalingSystemId { + return this.signalingSimulator.sigModuleManager.findSignalingSystem(signalingSystemName) } override fun getRawSettings(signal: LogicalSignalId): Map { - TODO("Not yet implemented") + return mapOf("Nf" to "false") } override fun getNextSignalingSystemIds(signal: LogicalSignalId): List { - TODO("Not yet implemented") + val sigSystemName = blockPool[signal.index].signalingSystemName + return listOf(sigSystemName) } override val routes: StaticIdxSpace @@ -432,7 +431,7 @@ class DummyInfra : RawInfra, BlockInfra { } override fun getBlockSignalingSystem(block: BlockId): SignalingSystemId { - TODO("Not yet implemented") + return blockPool[block.index].signalingSystemId } override fun getBlocksStartingAtDetector(detector: DirDetectorId): StaticIdxList { @@ -493,5 +492,9 @@ class DummyInfra : RawInfra, BlockInfra { res.add(DirStaticIdx(StaticIdx(id.index), Direction.INCREASING)) return res } + + private fun convertId(id: StaticIdx): StaticIdx { + return StaticIdx(id.index) + } // endregion }