Skip to content

Commit 0efa9de

Browse files
committed
core: pathfinding: filter out routes without blocks
1 parent 84486d8 commit 0efa9de

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

core/src/main/java/fr/sncf/osrd/api/pathfinding/PathfindingResultConverter.java

+30-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static fr.sncf.osrd.railjson.schema.common.graph.EdgeDirection.START_TO_STOP;
44
import static fr.sncf.osrd.railjson.schema.common.graph.EdgeDirection.STOP_TO_START;
5+
import static fr.sncf.osrd.sim_infra.utils.BlockRecoveryKt.recoverBlocks;
56
import static fr.sncf.osrd.utils.KtToJavaConverter.toIntList;
67
import static fr.sncf.osrd.utils.indexing.DirStaticIdxKt.toDirection;
78
import static fr.sncf.osrd.utils.indexing.DirStaticIdxKt.toValue;
@@ -17,13 +18,11 @@
1718
import fr.sncf.osrd.railjson.schema.infra.RJSRoutePath;
1819
import fr.sncf.osrd.railjson.schema.infra.trackranges.RJSDirectionalTrackRange;
1920
import fr.sncf.osrd.reporting.warnings.DiagnosticRecorderImpl;
20-
import fr.sncf.osrd.sim_infra.api.BlockInfra;
21-
import fr.sncf.osrd.sim_infra.api.PathProperties;
22-
import fr.sncf.osrd.sim_infra.api.RawSignalingInfra;
23-
import fr.sncf.osrd.sim_infra.api.RawSignalingInfraKt;
21+
import fr.sncf.osrd.sim_infra.api.*;
2422
import fr.sncf.osrd.utils.Direction;
2523
import fr.sncf.osrd.utils.DistanceRangeMap;
2624
import fr.sncf.osrd.utils.graph.Pathfinding;
25+
import fr.sncf.osrd.utils.indexing.MutableStaticIdxArrayList;
2726
import java.util.ArrayList;
2827
import java.util.Collection;
2928
import java.util.Comparator;
@@ -193,7 +192,7 @@ static List<RJSRoutePath> makeRoutePath(
193192
.map(Pathfinding.EdgeRange::edge)
194193
.toList();
195194
var chunkPath = chunksOnBlocks(blockInfra, blocks);
196-
var routes = chunksToRoutes(rawInfra, chunkPath);
195+
var routes = chunksToRoutes(rawInfra, blockInfra, chunkPath);
197196
var startOffset = findStartOffset(blockInfra, rawInfra, chunkPath.get(0), routes.get(0), ranges.get(0));
198197
var endOffset = findEndOffset(blockInfra, rawInfra, Iterables.getLast(chunkPath),
199198
Iterables.getLast(routes), Iterables.getLast(ranges));
@@ -347,12 +346,13 @@ private static List<Integer> chunksOnBlocks(BlockInfra blockInfra, List<Integer>
347346
/** Converts a list of dir chunks into a list of routes */
348347
public static List<Integer> chunksToRoutes(
349348
RawSignalingInfra infra,
349+
BlockInfra blockInfra,
350350
List<Integer> pathChunks
351351
) {
352352
var chunkStartIndex = 0;
353353
var res = new ArrayList<Integer>();
354354
while (chunkStartIndex < pathChunks.size()) {
355-
var route = findRoute(infra, pathChunks, chunkStartIndex, chunkStartIndex != 0);
355+
var route = findRoute(infra, blockInfra, pathChunks, chunkStartIndex, chunkStartIndex != 0);
356356
res.add(route);
357357
var chunkSetOnRoute = new HashSet<>(toIntList(infra.getChunksOnRoute(route)));
358358
while (chunkStartIndex < pathChunks.size() && chunkSetOnRoute.contains(pathChunks.get(chunkStartIndex)))
@@ -364,6 +364,7 @@ public static List<Integer> chunksToRoutes(
364364
/** Finds a valid route that follows the given path */
365365
private static int findRoute(
366366
RawSignalingInfra infra,
367+
BlockInfra blockInfra,
367368
List<Integer> chunks,
368369
int startIndex,
369370
boolean routeMustIncludeStart
@@ -374,19 +375,22 @@ private static int findRoute(
374375
routes.sort(Comparator.comparingInt(r -> -infra.getChunksOnRoute(r).getSize()));
375376

376377
for (var routeId : routes)
377-
if (routeMatchPath(infra, chunks, startIndex, routeMustIncludeStart, routeId))
378+
if (routeMatchPath(infra, blockInfra, chunks, startIndex, routeMustIncludeStart, routeId))
378379
return routeId;
379380
throw new RuntimeException("Couldn't find a route matching the given chunk list");
380381
}
381382

382383
/** Returns false if the route differs from the path */
383384
private static boolean routeMatchPath(
384385
RawSignalingInfra infra,
386+
BlockInfra blockInfra,
385387
List<Integer> chunks,
386388
int chunkIndex,
387389
boolean routeMustIncludeStart,
388390
int routeId
389391
) {
392+
if (!routeHasBlockPath(infra, blockInfra, routeId))
393+
return false; // Filter out routes that don't have block, they would cause issues later on
390394
var firstChunk = chunks.get(chunkIndex);
391395
var routeChunks = infra.getChunksOnRoute(routeId);
392396
var routeChunkIndex = 0;
@@ -408,4 +412,23 @@ private static boolean routeMatchPath(
408412
chunkIndex++;
409413
}
410414
}
415+
416+
/** Returns true if the route contains a valid block path.
417+
* </p>
418+
* This should always be true, but it can be false on infrastructures with errors in its signaling data
419+
* (such as the ones imported from poor data sources).
420+
* At this step we know that there is at least one route with a valid block path,
421+
* we just need to filter out the ones that don't. */
422+
private static boolean routeHasBlockPath(
423+
RawSignalingInfra infra,
424+
BlockInfra blockInfra,
425+
int routeId
426+
) {
427+
var routeIds = new MutableStaticIdxArrayList<Route>();
428+
routeIds.add(routeId);
429+
var blockPaths = recoverBlocks(
430+
infra, blockInfra, routeIds, null
431+
);
432+
return !blockPaths.isEmpty();
433+
}
411434
}

core/src/main/java/fr/sncf/osrd/standalone_sim/ScheduleMetadataExtractor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fun run(envelope: Envelope, trainPath: PathProperties, chunkPath: ChunkPath, sch
7878
val simulator = fullInfra.signalingSimulator
7979

8080
// get a new generation route path
81-
val routePath = toRouteIdList(chunksToRoutes(rawInfra, toIntList(chunkPath.chunks)))
81+
val routePath = toRouteIdList(chunksToRoutes(rawInfra, fullInfra.blockInfra, toIntList(chunkPath.chunks)))
8282

8383
// recover blocks from the route paths
8484
val detailedBlockPath = recoverBlockPath(simulator, fullInfra, routePath)

0 commit comments

Comments
 (0)