Skip to content

Commit

Permalink
core, editoast: allow to customize pathfinding timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
shenriotpro committed Feb 9, 2024
1 parent 56e19c8 commit b4a0802
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 43 deletions.
4 changes: 4 additions & 0 deletions core/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,10 @@ components:
offset: 138.32
rolling_stocks:
$ref: "#/components/schemas/RollingStock"
timeout:
type: number
nullable: true
format: double
STDCMRequest:
properties:
infra:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ public int run() {
var results = new HashMap<String, StandaloneSimResult>();
for (var trainScheduleGroup : input.trainScheduleGroups) {
logger.info("Running simulation for schedule group: {}", trainScheduleGroup.id);
var rawPathfindingResult = runPathfinding(infra, trainScheduleGroup.waypoints, rollingStocks.values());
var rawPathfindingResult =
runPathfinding(infra, trainScheduleGroup.waypoints, rollingStocks.values(), null);
var pathfindingResult = convertPathfindingResult(
infra.blockInfra(), infra.rawInfra(), rawPathfindingResult, diagnosticRecorder);
var routePath = pathfindingResult.routePaths.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class PathfindingBlocksEndpoint(private val infraManager: InfraManager) : Take {
RJSRollingStockParser.parse(rjsRollingStock)
}
.toList()
val path = runPathfinding(infra, reqWaypoints, rollingStocks)
val timeout = request.timeout
val path = runPathfinding(infra, reqWaypoints, rollingStocks, timeout)
val res = convertPathfindingResult(infra.blockInfra, infra.rawInfra, path, recorder)
validatePathfindingResult(res, reqWaypoints, infra.rawInfra)
RsJson(RsWithBody(PathfindingResult.adapterResult.toJson(res)))
Expand Down Expand Up @@ -200,7 +201,8 @@ private fun isWaypointOnTrack(
fun runPathfinding(
infra: FullInfra,
reqWaypoints: Array<Array<PathfindingWaypoint>>,
rollingStocks: Collection<RollingStock>?
rollingStocks: Collection<RollingStock>?,
timeout: Double?
): PathfindingResultId<Block> {
// Parse the waypoints
val waypoints = ArrayList<Collection<PathfindingEdgeLocationId<Block>>>()
Expand All @@ -222,7 +224,7 @@ fun runPathfinding(
val remainingDistanceEstimators = makeHeuristics(infra, waypoints)

// Compute the paths from the entry waypoint to the exit waypoint
return computePaths(infra, waypoints, constraints, remainingDistanceEstimators)
return computePaths(infra, waypoints, constraints, remainingDistanceEstimators, timeout)
}

/** Initialize the heuristics */
Expand Down Expand Up @@ -267,10 +269,12 @@ private fun computePaths(
infra: FullInfra,
waypoints: ArrayList<Collection<PathfindingEdgeLocationId<Block>>>,
constraints: List<EdgeToRangesId<Block>>,
remainingDistanceEstimators: List<AStarHeuristicId<Block>>
remainingDistanceEstimators: List<AStarHeuristicId<Block>>,
timeout: Double?
): PathfindingResultId<Block> {
val pathFound =
Pathfinding(GraphAdapter(infra.blockInfra, infra.rawInfra))
.setTimeout(timeout)
.setEdgeToLength { block: BlockId -> infra.blockInfra.getBlockLength(block) }
.setRemainingDistanceEstimator(remainingDistanceEstimators)
.addBlockedRangeOnEdges(constraints)
Expand All @@ -289,6 +293,7 @@ private fun computePaths(
if (possiblePathWithoutErrorNoConstraints != null) {
for (currentConstraint in constraints) {
Pathfinding(GraphAdapter(infra.blockInfra, infra.rawInfra))
.setTimeout(timeout)
.setEdgeToLength { block: BlockId -> infra.blockInfra.getBlockLength(block) }
.addBlockedRangeOnEdges(currentConstraint)
.setRemainingDistanceEstimator(remainingDistanceEstimators)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class PathfindingRequest
/** expectedVersion The expected infrastructure version */
@Json(name = "expected_version") var expectedVersion: String,
/** List of rolling stocks that must be able to use this path */
@Json(name = "rolling_stocks") var rollingStocks: List<RJSRollingStock>
@Json(name = "rolling_stocks") var rollingStocks: List<RJSRollingStock>,
var timeout: Double?
) {

companion object {
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/kotlin/fr/sncf/osrd/graph/Pathfinding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ class Pathfinding<NodeT : Any, EdgeT : Any, OffsetType>(
}

/** Sets the pathfinding's timeout */
fun setTimeout(timeout: Double): Pathfinding<NodeT, EdgeT, OffsetType> {
this.timeout = timeout
fun setTimeout(timeout: Double?): Pathfinding<NodeT, EdgeT, OffsetType> {
if (timeout != null) this.timeout = timeout
return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,14 +650,14 @@ class PathfindingTests {
}

@ParameterizedTest
@CsvSource("0, true", "10, false")
fun pathfindingTimesOut(timeout: Long, timesOut: Boolean) {
@CsvSource("0, true", "10, false", ", false")
fun pathfindingTimesOut(timeout: Long?, timesOut: Boolean) {
val builder = SimpleGraphBuilder()
builder.makeNodes(2)
builder.makeEdge(0, 1, 100.meters)
val g = builder.build()
val pathfinding =
Pathfinding(g).setEdgeToLength { edge -> edge.length }.setTimeout(timeout.toDouble())
Pathfinding(g).setEdgeToLength { edge -> edge.length }.setTimeout(timeout?.toDouble())
if (!timesOut) {
val res =
pathfinding.runPathfindingEdgesOnly(listOf(listOf(builder.getEdgeLocation("0-1"))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ class PathfindingElectrificationTest : ApiTest() {

// Run a pathfinding with a non-electric train
val normalPath =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.REALISTIC_FAST_TRAIN))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.REALISTIC_FAST_TRAIN),
null
)
Assertions.assertNotNull(normalPath)
assert(TestTrains.FAST_ELECTRIC_TRAIN.modeNames.contains("25000V"))
for (block in infra.blockPool) block.voltage = "25000V"
Expand All @@ -60,7 +65,12 @@ class PathfindingElectrificationTest : ApiTest() {

// Run another pathfinding with an electric train
val electricPath =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.FAST_ELECTRIC_TRAIN))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.FAST_ELECTRIC_TRAIN),
null
)
Assertions.assertNotNull(electricPath)

// We check that the path is different, we need to avoid the non-electrified track
Expand All @@ -80,7 +90,12 @@ class PathfindingElectrificationTest : ApiTest() {
for (block in infra.blockPool) block.voltage = ""
val exception =
Assertions.assertThrows(OSRDError::class.java) {
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.FAST_ELECTRIC_TRAIN))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.FAST_ELECTRIC_TRAIN),
null
)
}
Assertions.assertEquals(exception.osrdErrorType, ErrorType.PathfindingElectrificationError)
}
Expand All @@ -103,7 +118,12 @@ class PathfindingElectrificationTest : ApiTest() {

// Run a pathfinding with a non-electric train
val normalPath =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.REALISTIC_FAST_TRAIN))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.REALISTIC_FAST_TRAIN),
null
)
Assertions.assertNotNull(normalPath)
assert(TestTrains.FAST_ELECTRIC_TRAIN.modeNames.contains("25000V"))
for (block in infra.blockPool) block.voltage = "25000V"
Expand All @@ -126,15 +146,21 @@ class PathfindingElectrificationTest : ApiTest() {
) {
// Run another pathfinding with an electric train
val electricPath =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.FAST_ELECTRIC_TRAIN))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.FAST_ELECTRIC_TRAIN),
null
)
Assertions.assertNotNull(electricPath)
} else {
val exception =
Assertions.assertThrows(OSRDError::class.java) {
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.FAST_ELECTRIC_TRAIN)
listOf(TestTrains.FAST_ELECTRIC_TRAIN),
null
)
}
Assertions.assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ class PathfindingSignalingTest {

// 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))
runPathfinding(
infra.fullInfra(),
waypoints,
listOf(TestTrains.TRAIN_WITHOUT_TVM),
null
)
}
.isExactlyInstanceOf(OSRDError::class.java)
.satisfies({ exception: Throwable? ->
Expand All @@ -80,7 +85,7 @@ class PathfindingSignalingTest {
waypoints[1][0] = waypointEnd

val pathfindingResult =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM))
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM), null)

AssertionsForClassTypes.assertThat(pathfindingResult.ranges)
.isEqualTo(
Expand All @@ -102,7 +107,7 @@ class PathfindingSignalingTest {
waypoints[1][0] = waypointEnd

val pathfindingResult =
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM))
runPathfinding(infra.fullInfra(), waypoints, listOf(TestTrains.TRAIN_WITHOUT_TVM), null)

AssertionsForClassTypes.assertThat(pathfindingResult.ranges)
.isEqualTo(
Expand Down
Loading

0 comments on commit b4a0802

Please sign in to comment.