Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: stdcm: account for previous margins when checking for new ones #10506

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class EngineeringAllowanceManager(private val graph: STDCMGraph) {
return ArrayList(res)
}
mutDelayNeeded += mutEdge.timeData.delayAddedToLastDeparture
mutDelayNeeded += mutEdge.engineeringAllowance?.extraDuration ?: 0.0
mutEdge = mutEdge.previousNode.previousEdge!!
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ private fun initFixedPoints(
}
var prevEdgeLength = 0.meters
for (edge in edges) {
val engineeringAllowanceLength = edge.engineeringAllowanceLength
val engineeringAllowanceLength = edge.engineeringAllowance?.length
if (engineeringAllowanceLength != null) {
val engineeringAllowanceStart = prevEdgeLength - engineeringAllowanceLength
// Edges can have overlapping engineering allowance, only the last one is relevant.
Expand Down
14 changes: 11 additions & 3 deletions core/src/main/kotlin/fr/sncf/osrd/stdcm/graph/STDCMEdge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,24 @@ data class STDCMEdge(
// How long it takes to go from the beginning to the end of the block, taking the
// standard allowance into account
val totalTime: Double,
// If this edges starts after the end of an engineering allowance, this contains its length, or
// null otherwise. Used for initial placement of fixed time points in postprocessing.
val engineeringAllowanceLength: Distance?,
// If this edges starts after the end of an engineering allowance, this contains
// some data like its length and extra time. Null if there's no engineering allowance
// ending here. Overrides any allowance spanning part of the range from previous edges.
val engineeringAllowance: EngineeringAllowanceData?,
) {
val block = infraExplorer.getCurrentBlock()

init {
assert(!isNaN(timeData.earliestReachableTime)) { "STDCM edge starts at NaN time" }
}

data class EngineeringAllowanceData(
/** How long is the allowance section. It always ends at the start of the current edge. */
val length: Distance,
/** How much extra time was added on this current allowance range. */
val extraDuration: Double,
)

/** Returns the node at the end of this edge */
fun getEdgeEnd(graph: STDCMGraph): STDCMNode {
var newWaypointIndex = waypointIndex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import fr.sncf.osrd.envelope_sim.allowances.LinearAllowance
import fr.sncf.osrd.sim_infra.api.Block
import fr.sncf.osrd.stdcm.infra_exploration.InfraExplorerWithEnvelope
import fr.sncf.osrd.stdcm.preprocessing.interfaces.BlockAvailabilityInterface
import fr.sncf.osrd.utils.units.Distance
import fr.sncf.osrd.utils.units.Distance.Companion.fromMeters
import fr.sncf.osrd.utils.units.Length
import fr.sncf.osrd.utils.units.Offset
Expand Down Expand Up @@ -161,13 +160,15 @@ internal constructor(
var departureTimeShift = delayNeeded
val needEngineeringAllowance =
delayNeeded > prevNode.timeData.maxDepartureDelayingWithoutConflict
var allowanceLength: Distance? = null
var allowanceData: STDCMEdge.EngineeringAllowanceData? = null
if (needEngineeringAllowance) {
// We can't just shift the departure time, we need an engineering allowance
// It's not computed yet, we just check that it's possible
allowanceLength =
val allowanceLength =
graph.allowanceManager.checkEngineeringAllowance(prevNode, actualStartTime)
?: return null
val extraTime = delayNeeded - prevNode.timeData.maxDepartureDelayingWithoutConflict
allowanceData = STDCMEdge.EngineeringAllowanceData(allowanceLength, extraTime)
// We still need to adapt the delay values
departureTimeShift = prevNode.timeData.maxDepartureDelayingWithoutConflict
} else {
Expand Down Expand Up @@ -217,7 +218,7 @@ internal constructor(
envelope!!.endSpeed,
Length(fromMeters(envelope!!.endPos)),
envelope!!.totalTime / standardAllowanceSpeedRatio,
allowanceLength,
allowanceData,
)
res = graph.backtrackingManager.backtrack(res!!, envelope!!)
return if (res == null || graph.delayManager.isRunTimeTooLong(res)) null else res
Expand Down
Loading