-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: add supported_signaling_systems and add signalingSystemConstrai…
…nts for the pathfinding
- Loading branch information
1 parent
30d5fe3
commit 18b7167
Showing
9 changed files
with
322 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
core/src/main/kotlin/fr/sncf/osrd/api/pathfinding/constraints/SignalingSystemConstraints.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
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 | ||
|
||
@JvmRecord | ||
data class SignalingSystemConstraints( | ||
val blockInfra: BlockInfra, | ||
val signalingSimulator: SignalingSimulator, | ||
val rollingStocks: Collection<RollingStock> | ||
) : EdgeToRangesId<Block> { | ||
override fun apply(edge: BlockId): MutableCollection<Pathfinding.Range<Block>> { | ||
val res = HashSet<Pathfinding.Range<Block>>() | ||
for (rs in rollingStocks) { | ||
res.addAll(getBlockedRanges(rs, edge, blockInfra, signalingSimulator)) | ||
} | ||
return res | ||
} | ||
|
||
companion object { | ||
/** | ||
* Returns the sections of the given block that can't be used by the given rolling stock | ||
*/ | ||
private fun getBlockedRanges( | ||
stock: RollingStock, | ||
edge: BlockId, | ||
blockInfra: BlockInfra, | ||
signalingSimulator: SignalingSimulator | ||
): Set<Pathfinding.Range<Block>> { | ||
val blockSigSystem = blockInfra.getBlockSignalingSystem(edge) | ||
val rsSupportedSigSystems = stock.SupportedSignalingSystems.map { s -> signalingSimulator.sigModuleManager.findSignalingSystem(s) } | ||
val isRSCompatibleWithBlock = rsSupportedSigSystems.any { s -> s == blockSigSystem } | ||
if (isRSCompatibleWithBlock) { | ||
return setOf() | ||
} | ||
return setOf(Pathfinding.Range( | ||
Offset(0.meters), | ||
blockInfra.getBlockLength(edge)) | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
core/src/test/kotlin/fr/sncf/osrd/pathfinding/PathfindingSignalingTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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? = null | ||
|
||
private fun setSigSystemIds(list: List<BlockId>, 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<Block>(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<Block>(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)) | ||
)) | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
core/src/test/kotlin/fr/sncf/osrd/pathfinding/constraints/SignalingSystemConstraintsTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package fr.sncf.osrd.pathfinding.constraints | ||
|
||
import fr.sncf.osrd.api.pathfinding.constraints.SignalingSystemConstraints | ||
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.BeforeAll | ||
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.io.IOException | ||
import java.net.URISyntaxException | ||
import java.util.stream.Stream | ||
|
||
@TestInstance(TestInstance.Lifecycle.PER_CLASS) | ||
class SignalingSystemConstraintsTest { | ||
private var signalingSystemConstraints: SignalingSystemConstraints? = null | ||
private var infra: DummyInfra? = null | ||
|
||
@BeforeAll | ||
@Throws(IOException::class, URISyntaxException::class) | ||
fun setUp() { | ||
/* c1 | ||
^ \ | ||
/ v | ||
a --> b d --> e | ||
\ ^ | ||
v / | ||
c2 | ||
*/ | ||
infra = DummyInfra() | ||
infra?.addBlock("a", "b", signalingSystemName = "BAL") | ||
infra?.addBlock("b", "c1", signalingSystemName = "BAL") | ||
infra?.addBlock("b", "c2", signalingSystemName = "TVM430") | ||
infra?.addBlock("c1", "d", signalingSystemName = "TVM430") | ||
infra?.addBlock("c2", "d", signalingSystemName = "BAL") | ||
infra?.addBlock("d", "e", signalingSystemName = "BAL") | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("testSignalingSystemArgs") | ||
fun testSignalingSystemBlockedRanges(blockId: BlockId, rollingStock: RollingStock, expectedBlockedRanges: Collection<Pathfinding.Range<Block>>) { | ||
val fullInfra = infra?.fullInfra(); | ||
signalingSystemConstraints = SignalingSystemConstraints( | ||
fullInfra!!.blockInfra, fullInfra.signalingSimulator, | ||
listOf(rollingStock) | ||
) | ||
val blockedRanges = signalingSystemConstraints!!.apply(blockId) | ||
Assertions.assertThat(blockedRanges).isEqualTo(expectedBlockedRanges) | ||
} | ||
|
||
private fun testSignalingSystemArgs(): Stream<Arguments> { | ||
return Stream.of( | ||
Arguments.of(1, TestTrains.TRAIN_WITHOUT_TVM, HashSet<Any>()), | ||
Arguments.of(2, TestTrains.TRAIN_WITHOUT_TVM, setOf(Pathfinding.Range<TrackChunk>(Offset(0.meters), Offset(100.meters)))), | ||
Arguments.of(1, TestTrains.FAST_ELECTRIC_TRAIN, HashSet<Any>()), | ||
Arguments.of(2, TestTrains.FAST_ELECTRIC_TRAIN, HashSet<Any>()), | ||
) | ||
} | ||
} |
Oops, something went wrong.