-
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
8f490e7
commit edd8cb5
Showing
10 changed files
with
334 additions
and
45 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
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
63 changes: 63 additions & 0 deletions
63
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,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<List<SignalingSystemId>> | ||
) : EdgeToRangesId<Block> { | ||
override fun apply(edge: BlockId): MutableCollection<Pathfinding.Range<Block>> { | ||
val res = HashSet<Pathfinding.Range<Block>>() | ||
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<SignalingSystemId> | ||
): Set<Pathfinding.Range<Block>> { | ||
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<RollingStock>, | ||
): SignalingSystemConstraints { | ||
val rsSupportedSigSystems = rollingStocks.map { stock -> | ||
stock.supportedSignalingSystems.mapNotNull { s -> try { | ||
signalingSimulator.sigModuleManager.findSignalingSystem(s) | ||
} catch (e: Exception) { | ||
null | ||
} } | ||
} | ||
return SignalingSystemConstraints( | ||
blockInfra, | ||
rsSupportedSigSystems | ||
) | ||
} |
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 = DummyInfra() | ||
|
||
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)) | ||
)) | ||
} | ||
} |
Oops, something went wrong.