Skip to content

Commit

Permalink
core, editoast: add flag to ignore speed limits
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Rolland <[email protected]>
  • Loading branch information
axrolld committed Feb 5, 2025
1 parent fd615e7 commit 31ffe44
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,5 @@ class SimulationPowerRestrictionItem(

class TrainScheduleOptions(
@Json(name = "use_electrical_profiles") val useElectricalProfiles: Boolean
@Json(name = "ignore_infra_speed_limits") val ingoreInfraSpeedLimits: Boolean
)
93 changes: 68 additions & 25 deletions core/src/main/kotlin/fr/sncf/osrd/envelope_sim_infra/MRSP.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,41 @@ fun computeMRSP(
rollingStock.getMaxSpeed(),
rollingStock.getLength(),
addRollingStockLength,
ignoreInfraSpeedLimits = false,
trainTag,
temporarySpeedLimitManager,
safetySpeedRanges,
)
}

/**
* Computes the MSRP for a rolling stock on a given path, taking into account the infrastructure speed limits.
*
* @param path corresponding path.
* @param rsMaxSpeed rolling stock max speed (m/s)
* @param rsLength length of the rolling stock (m)
* @param addRollingStockLength whether the rolling stock length should be taken into account in the
* computation.
* @param trainTag corresponding train.
* @param safetySpeedRanges Extra speed ranges, used for safety speeds. Note: rolling stock length
* is *not* added at the end of these ranges.
* @return the corresponding MRSP as an Envelope.
*/
fun computeMRSP(
path: PathProperties,
rsMaxSpeed: Double,
rsLength: Double,
addRollingStockLength: Boolean,
trainTag: String?,
temporarySpeedLimitManager: TemporarySpeedLimitManager?,
safetySpeedRanges: DistanceRangeMap<Speed>? = null,
): Envelope {
return computeMRSP(
path,
rsMaxSpeed,
rsLength,
addRollingStockLength,
ignoreInfraSpeedLimits = false,
trainTag,
temporarySpeedLimitManager,
safetySpeedRanges,
Expand All @@ -59,6 +94,8 @@ fun computeMRSP(
* @param rsLength length of the rolling stock (m)
* @param addRollingStockLength whether the rolling stock length should be taken into account in the
* computation.
* @param ignoreInfraSpeedLimits whether the speed limits coming from the infrastructure should be ignored in the
* computaion
* @param trainTag corresponding train.
* @param safetySpeedRanges Extra speed ranges, used for safety speeds. Note: rolling stock length
* is *not* added at the end of these ranges.
Expand All @@ -69,6 +106,7 @@ fun computeMRSP(
rsMaxSpeed: Double,
rsLength: Double,
addRollingStockLength: Boolean,
ignoreInfraSpeedLimits: Boolean,
trainTag: String?,
temporarySpeedLimitManager: TemporarySpeedLimitManager?,
safetySpeedRanges: DistanceRangeMap<Speed>? = null,
Expand All @@ -77,31 +115,36 @@ fun computeMRSP(
val pathLength = toMeters(path.getLength())

val offset = if (addRollingStockLength) rsLength else 0.0
val speedLimitProperties = path.getSpeedLimitProperties(trainTag, temporarySpeedLimitManager)
for (speedLimitPropertyRange in speedLimitProperties) {
// Compute where this limit is active from and to
val start = toMeters(speedLimitPropertyRange.lower)
val end = min(pathLength, offset + toMeters(speedLimitPropertyRange.upper))
val speedLimitProp = rangeMapEntryToSpeedLimitProperty(speedLimitPropertyRange)
val speed = toMetersPerSecond(speedLimitProp.speed)
val attrs =
mutableListOf<SelfTypeHolder?>(
EnvelopeProfile.CONSTANT_SPEED,
MRSPEnvelopeBuilder.LimitKind.SPEED_LIMIT
)
if (speedLimitProp.source != null) {
attrs.add(speedLimitProp.source)
}
if (attrs.any { it is UnknownTag }) attrs.add(HasMissingSpeedTag)
if (speed != 0.0) {
// Add the envelope part corresponding to the restricted speed section
builder.addPart(
EnvelopePart.generateTimes(
attrs,
doubleArrayOf(start, end),
doubleArrayOf(speed, speed)
if (ignoreInfraSpeedLimits) { // if we ignore the speed limits coming from the infrastructure
val speedLimitProperties = distanceRangeMapOf()
} // if we take into account speedlimits coming from the infrastructure
else {
val speedLimitProperties = path.getSpeedLimitProperties(trainTag, temporarySpeedLimitManager)
for (speedLimitPropertyRange in speedLimitProperties) {
// Compute where this limit is active from and to
val start = toMeters(speedLimitPropertyRange.lower)
val end = min(pathLength, offset + toMeters(speedLimitPropertyRange.upper))
val speedLimitProp = rangeMapEntryToSpeedLimitProperty(speedLimitPropertyRange)
val speed = toMetersPerSecond(speedLimitProp.speed)
val attrs =
mutableListOf<SelfTypeHolder?>(
EnvelopeProfile.CONSTANT_SPEED,
MRSPEnvelopeBuilder.LimitKind.SPEED_LIMIT
)
)
if (speedLimitProp.source != null) {
attrs.add(speedLimitProp.source)
}
if (attrs.any { it is UnknownTag }) attrs.add(HasMissingSpeedTag)
if (speed != 0.0) {
// Add the envelope part corresponding to the restricted speed section
builder.addPart(
EnvelopePart.generateTimes(
attrs,
doubleArrayOf(start, end),
doubleArrayOf(speed, speed)
)
)
}
}
}

Expand All @@ -117,7 +160,7 @@ fun computeMRSP(
)

// Add safety speeds
if (safetySpeedRanges != null) {
if (!ignoreInfraSpeedLimits && safetySpeedRanges != null) {
for (range in safetySpeedRanges) {
val speed = range.value
val newAttrs =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub struct TrainScheduleOptions {
#[derivative(Default(value = "true"))]
#[serde(default = "default_use_electrical_profiles")]
use_electrical_profiles: bool,
#[serde(Default)]
ignore_infra_speed_limits: bool,
}

fn default_use_electrical_profiles() -> bool {
Expand Down
4 changes: 4 additions & 0 deletions editoast/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11884,6 +11884,8 @@ components:
options:
type: object
properties:
ignore_infra_speed_limits:
type: boolean
use_electrical_profiles:
type: boolean
additionalProperties: false
Expand Down Expand Up @@ -11979,6 +11981,8 @@ components:
TrainScheduleOptions:
type: object
properties:
ignore_infra_speed_limits:
type: boolean
use_electrical_profiles:
type: boolean
additionalProperties: false
Expand Down
2 changes: 2 additions & 0 deletions front/src/common/api/generatedEditoastApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3254,6 +3254,7 @@ export type Margins = {
values: string[];
};
export type TrainScheduleOptions = {
ignore_infra_speed_limits?: boolean;
use_electrical_profiles?: boolean;
};
export type PathItem = PathItemLocation & {
Expand Down Expand Up @@ -3612,6 +3613,7 @@ export type TrainScheduleBase = {
values: string[];
};
options?: {
ignore_infra_speed_limits?: boolean;
use_electrical_profiles?: boolean;
};
path: (PathItemLocation & {
Expand Down
9 changes: 8 additions & 1 deletion python/osrd_schemas/osrd_schemas/train_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,19 @@ class PowerRestrictionRanges(RootModel):


class TrainScheduleOptions(BaseModel):
"""Optional arguments for the standalone simulation."""
"""Optional arguments :
- `ignore_electrical_profiles` : ignore the electrical profiles for the standalone simulation
- `ignore_infra_speed_limits` : ignore the speed limits coming from the infrastructure for the standalone simulation
"""

ignore_electrical_profiles: bool = Field(
default=False,
description="If true, the electrical profiles are ignored in the standalone simulation",
)
ignore_infra_speed_limits: bool = Field(
default=False,
description="If true, the speed limits of the infrastructure are ignored in the standalone simulation",
)


if __name__ == "__main__":
Expand Down

0 comments on commit 31ffe44

Please sign in to comment.