Skip to content

Commit 1a5d933

Browse files
committed
Squashed commit of the following:
commit 91e7663 Author: Simon Ser <[email protected]> Date: Wed Sep 4 16:34:32 2024 +0200 core: re-order Dockerfile ADD jar stages Usually when rebuilding the core container only osrd_core.jar will be updated. Copy it last so that previous stages can benefit from the docker stage cache and be skipped. commit fe8e4b7 Author: Eloi Charpentier <[email protected]> Date: Thu Sep 5 14:23:10 2024 +0200 core: pathfinding: log a little extra info about failures commit fcd9734 Author: Egor <[email protected]> Date: Tue Jul 30 15:31:30 2024 +0200 editoast: make DbConnection type opaque Co-authored-by: Jean SIMARD <[email protected]> Co-authored-by: Léo VALAIS <[email protected]> commit d6d2ed3 Author: Simon Ser <[email protected]> Date: Thu Sep 5 09:42:44 2024 +0200 github: allow digits in module names Module names might have digits in them, e.g. "i18n" or "modelsv2". Stop forbidding these. commit 979bbdb Author: maymanaf <[email protected]> Date: Tue Sep 3 12:59:14 2024 +0200 front: add webkit browser to e2e tests commit ef82519 Author: Florian Amsallem <[email protected]> Date: Thu Sep 5 14:33:58 2024 +0200 editoast: fix signal projection cache commit 5e3ca65 Author: Youness CHRIFI ALAOUI <[email protected]> Date: Fri Aug 23 00:00:25 2024 +0200 test: adapt intagration tests commit 799b140 Author: Youness CHRIFI ALAOUI <[email protected]> Date: Thu Aug 22 03:38:25 2024 +0200 front: adapt tsv2 endpoints commit 0a2a6bb Author: Youness CHRIFI ALAOUI <[email protected]> Date: Thu Aug 22 03:31:24 2024 +0200 editoast: rename infra pathfinding input commit 541886e Author: Youness CHRIFI ALAOUI <[email protected]> Date: Thu Aug 22 02:41:58 2024 +0200 editoast: remove v2 suffix commit 0551a06 Author: Youness CHRIFI ALAOUI <[email protected]> Date: Thu Aug 22 02:41:35 2024 +0200 editoast: rename tables commit 144cf22 Author: Simon Ser <[email protected]> Date: Mon Sep 2 15:55:51 2024 +0200 front: turn on noUnusedLocals This warns when something is imported but isn't actually used. commit 05565cb Author: Simon Ser <[email protected]> Date: Thu Sep 5 13:55:26 2024 +0200 front: drop all unused React imports See previous commit. commit c94b1c9 Author: Simon Ser <[email protected]> Date: Thu Sep 5 13:52:53 2024 +0200 front: disable react/react-in-jsx-scope lint Forcing all .tsx/.jsx files to include React is cargo culting from old versions of the JSX compiler which were merely performing string substitution. Since React version 17 this isn't required anymore and the unused React imports can be dropped. commit c2b8718 Author: Eloi Charpentier <[email protected]> Date: Thu Sep 5 11:07:06 2024 +0200 core: stdcm: simplify stdcm edge builder Turns out, starting the path with a node instead of an edge can make things much easier than before commit 615f035 Author: maymanaf <[email protected]> Date: Fri Aug 30 12:06:48 2024 +0200 front: update train count check commit 19912ba Author: maymanaf <[email protected]> Date: Tue Jul 30 15:02:34 2024 +0200 front: add import trains e2e tests commit 1b14ae3 Author: SarahBellaha <[email protected]> Date: Thu Aug 22 18:15:02 2024 +0200 front: be able to select a via on the map even when pf failed
1 parent c0f03c1 commit 1a5d933

File tree

497 files changed

+3863
-3267
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

497 files changed

+3863
-3267
lines changed

.github/scripts/check-commit-titles.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ check_forbidden_chars() {
3434
}
3535

3636
check_structure() {
37-
if grep -q -E -v '^([-_.a-z]+[,:] )*[-_.a-z]+: [a-z](:[^ ]|[^:])*$'; then
37+
if grep -q -E -v '^([-_.a-z0-9]+[,:] )*[-_.a-z0-9]+: [a-z](:[^ ]|[^:])*$'; then
3838
echo 'Invalid commit title structure'
3939
fi
4040
}

core/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ RUN --mount=type=cache,target=/home/gradle/.gradle \
1515
#### Running stage
1616
FROM eclipse-temurin:21 AS running_env
1717

18-
COPY --from=build_env /osrd-all.jar /app/osrd_core.jar
1918
ADD 'https://dtdg.co/latest-java-tracer' /app/dd-java-agent.jar
2019
ADD 'https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar' /app/opentelemetry-javaagent.jar
20+
COPY --from=build_env /osrd-all.jar /app/osrd_core.jar
2121

2222
ARG OSRD_GIT_DESCRIBE
2323
ENV OSRD_GIT_DESCRIBE=${OSRD_GIT_DESCRIBE}

core/kt-osrd-sim-infra/src/main/kotlin/fr/sncf/osrd/sim_infra/utils/InfraUtils.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ private fun findRoute(
118118
return routeId
119119
}
120120
}
121-
val error = OSRDError(ErrorType.ScheduleMetadataExtractionFailed)
122-
error.context["reason"] = "Couldn't find a route matching the given chunk list"
123-
throw error
121+
throw OSRDError(ErrorType.MissingRouteFromChunkPath)
124122
}
125123

126124
/** Returns false if the route differs from the path */

core/osrd-reporting/src/main/java/fr/sncf/osrd/reporting/exceptions/ErrorType.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,12 @@ public enum ErrorType {
162162
InvalidSTDCMStepWithTimingData(
163163
"invalid_stdcm_step_with_timing_data",
164164
"An STDCM step with planned timing data must be a stop",
165-
ErrorCause.USER);
165+
ErrorCause.USER),
166+
MissingRouteFromChunkPath(
167+
"missing_route_from_chunk_path",
168+
"couldn't find a route matching the given chunk list",
169+
ErrorCause.INTERNAL),
170+
;
166171

167172
public final String type;
168173
public final String message;

core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlocksEndpointV2.kt

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import fr.sncf.osrd.utils.units.meters
2323
import java.time.Duration
2424
import java.time.Instant
2525
import java.util.*
26+
import org.slf4j.Logger
27+
import org.slf4j.LoggerFactory
2628
import org.takes.Request
2729
import org.takes.Response
2830
import org.takes.Take
@@ -39,7 +41,10 @@ import org.takes.rs.RsWithStatus
3941
*/
4042
class NoPathFoundException(val response: PathfindingBlockResponse) : Exception()
4143

44+
val pathfindingLogger: Logger = LoggerFactory.getLogger("Pathfinding")
45+
4246
class PathfindingBlocksEndpointV2(private val infraManager: InfraManager) : Take {
47+
4348
override fun act(req: Request): Response {
4449
val recorder = DiagnosticRecorderImpl(false)
4550
return try {
@@ -50,13 +55,16 @@ class PathfindingBlocksEndpointV2(private val infraManager: InfraManager) : Take
5055
// Load infra
5156
val infra = infraManager.getInfra(request.infra, request.expectedVersion, recorder)
5257
val res = runPathfinding(infra, request)
58+
pathfindingLogger.info("success")
5359
RsJson(RsWithBody(pathfindingResponseAdapter.toJson(res)))
5460
} catch (error: NoPathFoundException) {
61+
pathfindingLogger.info("no path found")
5562
RsJson(RsWithBody(pathfindingResponseAdapter.toJson(error.response)))
5663
} catch (error: OSRDError) {
5764
if (!error.osrdErrorType.isCacheable) {
5865
ExceptionHandler.handle(error)
5966
} else {
67+
pathfindingLogger.info("pathfinding failed: ${error.message}")
6068
val response = PathfindingFailed(error)
6169
RsJson(RsWithBody(pathfindingResponseAdapter.toJson(response)))
6270
}
@@ -154,8 +162,10 @@ private fun computePaths(
154162
.addBlockedRangeOnEdges(constraints)
155163
.runPathfinding(waypoints)
156164
if (pathFound != null) {
165+
pathfindingLogger.info("path found in block graph, start postprocessing")
157166
return pathFound
158167
}
168+
pathfindingLogger.info("no path found, identifying issues")
159169

160170
// Handling errors
161171
// Check if pathfinding failed due to incompatible constraints

core/src/main/kotlin/fr/sncf/osrd/graph/Pathfinding.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.sncf.osrd.graph
22

33
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
4+
import fr.sncf.osrd.api.api_v2.pathfinding.pathfindingLogger
45
import fr.sncf.osrd.api.pathfinding.constraints.ConstraintCombiner
56
import fr.sncf.osrd.reporting.exceptions.ErrorType
67
import fr.sncf.osrd.reporting.exceptions.OSRDError
@@ -11,6 +12,7 @@ import java.time.Duration
1112
import java.time.Instant
1213
import java.util.*
1314
import java.util.stream.Collectors
15+
import kotlin.math.max
1416

1517
@SuppressFBWarnings(
1618
value = ["FE_FLOATING_POINT_EQUALITY"],
@@ -184,15 +186,23 @@ class Pathfinding<NodeT : Any, EdgeT : Any, OffsetType>(
184186
val startRange = EdgeRange(location.edge, location.offset, location.offset)
185187
registerStep(startRange, null, 0.0, 0, listOf(location))
186188
}
189+
var maxReachedTarget = 0
187190
val start = Instant.now()
188191
while (true) {
189192
if (Duration.between(start, Instant.now()).toSeconds() >= timeout)
190193
throw OSRDError(ErrorType.PathfindingTimeoutError)
191-
val step = queue.poll() ?: return null
194+
val step = queue.poll()
195+
if (step == null) {
196+
pathfindingLogger.info(
197+
"pathfinding failed, # reached waypoints = $maxReachedTarget/${targetsOnEdges.size}"
198+
)
199+
return null
200+
}
192201
val endNode = graph.getEdgeEnd(step.range.edge)
193202
if (seen.getOrDefault(step.range, -1) >= step.nReachedTargets) {
194203
continue
195204
}
205+
maxReachedTarget = max(step.nReachedTargets, maxReachedTarget)
196206
seen[step.range] = step.nReachedTargets
197207
if (hasReachedEnd(targetsOnEdges.size, step)) return buildResult(step)
198208
// Check if the next target is reached in this step, only if the step doesn't already

core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/BacktrackingManager.kt

+1-7
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class BacktrackingManager(private val graph: STDCMGraph) {
3939
// Create the new edge
4040
val newNode = newPreviousEdge.getEdgeEnd(graph)
4141
return STDCMEdgeBuilder.fromNode(graph, newNode, edge.infraExplorer)
42-
.setStartOffset(edge.envelopeStartOffset)
4342
.setEnvelope(envelope)
4443
.findEdgeSameNextOccupancy(edge.timeNextOccupancy)
4544
}
@@ -78,13 +77,8 @@ class BacktrackingManager(private val graph: STDCMGraph) {
7877
graph
7978
)
8079
val prevNode = old.previousNode
81-
return STDCMEdgeBuilder(old.infraExplorer, graph, prevNode)
82-
.setStartTime(old.timeStart - old.addedDelay)
83-
.setStartOffset(old.envelopeStartOffset)
84-
.setPrevMaximumAddedDelay(old.maximumAddedDelayAfter + old.addedDelay)
85-
.setPrevAddedDelay(old.totalDepartureTimeShift - old.addedDelay)
80+
return STDCMEdgeBuilder.fromNode(graph, prevNode, old.infraExplorer)
8681
.setEnvelope(newEnvelope)
87-
.setWaypointIndex(old.waypointIndex)
8882
.findEdgeSameNextOccupancy(old.timeNextOccupancy)
8983
}
9084
}

core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMEdgeBuilder.kt

+21-90
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import fr.sncf.osrd.utils.units.meters
1515
import kotlin.math.min
1616

1717
/** This class handles the creation of new edges, handling the many optional parameters. */
18+
@ConsistentCopyVisibility
1819
data class STDCMEdgeBuilder
1920
internal constructor(
2021
/** Instance used to explore the infra, contains the underlying edge */
@@ -23,26 +24,8 @@ internal constructor(
2324
private val graph: STDCMGraph,
2425
/** Previous node, used to compute the final path */
2526
private var prevNode: STDCMNode,
26-
/** Start time of the edge */
27-
private var startTime: Double = 0.0,
28-
29-
/** Start speed, ignored if envelope is specified */
30-
private var startSpeed: Double = 0.0,
31-
3227
/** Start offset on the given block */
3328
private var startOffset: Offset<Block> = Offset(0.meters),
34-
35-
/**
36-
* Maximum delay we can add on any of the previous edges by shifting the departure time, without
37-
* causing a conflict
38-
*/
39-
private var prevMaximumAddedDelay: Double = 0.0,
40-
41-
/**
42-
* Sum of all the delay that has been added in the previous edges by shifting the departure time
43-
*/
44-
private var prevAddedDelay: Double = 0.0,
45-
4629
/** Envelope to use on the edge, if unspecified we try to go at maximum allowed speed */
4730
private var envelope: Envelope? = null,
4831

@@ -51,46 +34,7 @@ internal constructor(
5134
* for the resource generator caches. This is the instance that must be used for next edges
5235
*/
5336
private var explorerWithNewEnvelope: InfraExplorerWithEnvelope? = null,
54-
55-
/** Index of the last waypoint passed by the train */
56-
private var waypointIndex: Int = 0
5737
) {
58-
// region SETTERS
59-
/** Sets the start time of the edge */
60-
fun setStartTime(startTime: Double): STDCMEdgeBuilder {
61-
this.startTime = startTime
62-
return this
63-
}
64-
65-
/** Sets the start speed, ignored if the envelope has been specified */
66-
fun setStartSpeed(startSpeed: Double): STDCMEdgeBuilder {
67-
this.startSpeed = startSpeed
68-
return this
69-
}
70-
71-
/** Start offset on the given block */
72-
fun setStartOffset(startOffset: Offset<Block>): STDCMEdgeBuilder {
73-
this.startOffset = startOffset
74-
return this
75-
}
76-
77-
/**
78-
* Sets the maximum delay we can add on any of the previous edges by shifting the departure time
79-
*/
80-
fun setPrevMaximumAddedDelay(prevMaximumAddedDelay: Double): STDCMEdgeBuilder {
81-
this.prevMaximumAddedDelay = prevMaximumAddedDelay
82-
return this
83-
}
84-
85-
/**
86-
* Sets the sum of all the delay that has been added in the previous edges by shifting the
87-
* departure time
88-
*/
89-
fun setPrevAddedDelay(prevAddedDelay: Double): STDCMEdgeBuilder {
90-
this.prevAddedDelay = prevAddedDelay
91-
return this
92-
}
93-
9438
/**
9539
* Sets the envelope to use on the edge, if unspecified we try to go at maximum allowed speed
9640
*/
@@ -99,16 +43,6 @@ internal constructor(
9943
return this
10044
}
10145

102-
/**
103-
* Sets the waypoint index on the new edge (i.e. the index of the last waypoint passed by the
104-
* train)
105-
*/
106-
fun setWaypointIndex(waypointIndex: Int): STDCMEdgeBuilder {
107-
this.waypointIndex = waypointIndex
108-
return this
109-
}
110-
// endregion SETTERS
111-
// region BUILDERS
11246
/**
11347
* Creates all edges that can be accessed on the given block, using all the parameters
11448
* specified.
@@ -143,12 +77,10 @@ internal constructor(
14377
val delay =
14478
getDelaysPerOpening()
14579
.stream()
146-
.filter { x: Double -> startTime + x <= timeNextOccupancy }
80+
.filter { x: Double -> prevNode.time + x <= timeNextOccupancy }
14781
.max { obj: Double, anotherDouble: Double? -> obj.compareTo(anotherDouble!!) }
14882
return delay.map { delayNeeded: Double -> makeSingleEdge(delayNeeded) }.orElse(null)
14983
}
150-
// endregion BUILDERS
151-
// region UTILITIES
15284
/** Returns the envelope to be used for the new edges */
15385
private fun getEnvelope(): Envelope? {
15486
if (envelope == null)
@@ -162,13 +94,13 @@ internal constructor(
16294
infraExplorer,
16395
BlockSimulationParameters(
16496
infraExplorer.getCurrentBlock(),
165-
startSpeed,
97+
prevNode.speed,
16698
startOffset,
16799
getStopOnBlock(
168100
graph,
169101
infraExplorer.getCurrentBlock(),
170102
startOffset,
171-
waypointIndex
103+
prevNode.waypointIndex
172104
)
173105
)
174106
)
@@ -213,7 +145,7 @@ internal constructor(
213145
private fun getDelaysPerOpening(): Set<Double> {
214146
return graph.delayManager.minimumDelaysPerOpening(
215147
getExplorerWithNewEnvelope()!!,
216-
startTime,
148+
prevNode.time,
217149
envelope!!,
218150
startOffset,
219151
)
@@ -222,33 +154,37 @@ internal constructor(
222154
/** Returns the stop duration at the end of the edge being built, or null if there's no stop */
223155
private fun getEndStopDuration(): Double? {
224156
val endAtStop =
225-
getStopOnBlock(graph, infraExplorer.getCurrentBlock(), startOffset, waypointIndex) !=
226-
null
157+
getStopOnBlock(
158+
graph,
159+
infraExplorer.getCurrentBlock(),
160+
startOffset,
161+
prevNode.waypointIndex
162+
) != null
227163
if (!endAtStop) return null
228-
return graph.getFirstStopAfterIndex(waypointIndex)!!.duration!!
164+
return graph.getFirstStopAfterIndex(prevNode.waypointIndex)!!.duration!!
229165
}
230166

231167
/** Creates a single STDCM edge, adding the given amount of delay */
232168
private fun makeSingleEdge(delayNeeded: Double): STDCMEdge? {
233169
if (java.lang.Double.isInfinite(delayNeeded)) return null
234-
val actualStartTime = startTime + delayNeeded
170+
val actualStartTime = prevNode.time + delayNeeded
235171

236172
var maximumDelay = 0.0
237173
var departureTimeShift = delayNeeded
238-
if (delayNeeded > prevMaximumAddedDelay) {
174+
if (delayNeeded > prevNode.maximumAddedDelay) {
239175
// We can't just shift the departure time, we need an engineering allowance
240176
// It's not computed yet, we just check that it's possible
241177
if (!graph.allowanceManager.checkEngineeringAllowance(prevNode, actualStartTime))
242178
return null
243179
// We still need to adapt the delay values
244-
departureTimeShift = prevMaximumAddedDelay
180+
departureTimeShift = prevNode.maximumAddedDelay
245181
} else {
246182
maximumDelay =
247183
min(
248-
prevMaximumAddedDelay - delayNeeded,
184+
prevNode.maximumAddedDelay - delayNeeded,
249185
graph.delayManager.findMaximumAddedDelay(
250186
getExplorerWithNewEnvelope()!!,
251-
startTime + delayNeeded,
187+
prevNode.time + delayNeeded,
252188
startOffset,
253189
envelope!!,
254190
)
@@ -266,14 +202,14 @@ internal constructor(
266202
departureTimeShift,
267203
graph.delayManager.findNextOccupancy(
268204
getExplorerWithNewEnvelope()!!,
269-
startTime + delayNeeded,
205+
prevNode.time + delayNeeded,
270206
startOffset,
271207
envelope!!,
272208
),
273-
prevAddedDelay + departureTimeShift,
209+
prevNode.totalPrevAddedDelay + departureTimeShift,
274210
prevNode,
275211
startOffset,
276-
waypointIndex,
212+
prevNode.waypointIndex,
277213
endAtStop,
278214
envelope!!.beginSpeed,
279215
envelope!!.endSpeed,
@@ -293,7 +229,7 @@ internal constructor(
293229
return true
294230
node = prevEdge.previousNode
295231
}
296-
} // endregion UTILITIES
232+
}
297233

298234
companion object {
299235
fun fromNode(
@@ -305,12 +241,7 @@ internal constructor(
305241
if (node.locationOnEdge != null) {
306242
builder.startOffset = node.locationOnEdge
307243
}
308-
builder.startTime = node.time
309-
builder.startSpeed = node.speed
310-
builder.prevMaximumAddedDelay = node.maximumAddedDelay
311-
builder.prevAddedDelay = node.totalPrevAddedDelay
312244
builder.prevNode = node
313-
builder.waypointIndex = node.waypointIndex
314245
return builder
315246
}
316247
}

0 commit comments

Comments
 (0)