Skip to content

Commit

Permalink
core: stdcm: fallback to linear envelope
Browse files Browse the repository at this point in the history
  • Loading branch information
eckter committed Oct 16, 2023
1 parent 7c02b7b commit feafb8b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,6 @@ public enum ErrorType {
"invalid envelope, envelope parts are not contiguous",
ErrorCause.USER
),
NoCompatibleEnvelopeFound(
"no_compatible_envelope",
"Couldn't find an envelope that wouldn't cause a conflict",
ErrorCause.USER
),
SignalingError(
"signaling_error",
"Unknown signaling system: $sigSystem",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import static fr.sncf.osrd.envelope_sim.TrainPhysicsIntegrator.POSITION_EPSILON;

import fr.sncf.osrd.envelope_sim.EnvelopeSimContext;
import fr.sncf.osrd.envelope_sim.EnvelopeSimPath;
import fr.sncf.osrd.envelope.Envelope;
import fr.sncf.osrd.envelope_sim.allowances.LinearAllowance;
import fr.sncf.osrd.envelope_sim.allowances.MarecoAllowance;
import fr.sncf.osrd.envelope_sim.allowances.utils.AllowanceRange;
import fr.sncf.osrd.envelope_sim.allowances.utils.AllowanceValue;
import fr.sncf.osrd.reporting.exceptions.ErrorType;
import fr.sncf.osrd.reporting.exceptions.OSRDError;
import fr.sncf.osrd.standalone_sim.EnvelopeStopWrapper;
import fr.sncf.osrd.stdcm.preprocessing.interfaces.BlockAvailabilityInterface;
import fr.sncf.osrd.train.RollingStock;
Expand Down Expand Up @@ -40,28 +40,40 @@ static Envelope applyAllowance(
double departureTime,
List<TrainStop> stops
) {
if (standardAllowance == null)
return envelope; // This isn't just an optimization, it avoids float inaccuracies
if (standardAllowance == null
|| standardAllowance.getAllowanceTime(envelope.getTotalTime(), envelope.getTotalDistance()) < 1e-5)
return envelope; // This isn't just an optimization, it avoids float inaccuracies and possible errors
var rangeTransitions = initRangeTransitions(stops);
var context = EnvelopeSimContextBuilder.build(rollingStock, envelopeSimPath, timeStep, comfort);
for (int i = 0; i < 10; i++) {
var newEnvelope = applyAllowanceWithTransitions(
envelope,
standardAllowance,
envelopeSimPath,
rollingStock,
timeStep,
comfort,
rangeTransitions
rangeTransitions,
context
);
var conflictOffset = findConflictOffsets(
newEnvelope, blockAvailability, ranges, departureTime, stops);
if (conflictOffset < 0)
return newEnvelope;
assert !rangeTransitions.contains(conflictOffset) : "conflict offset is already on a range transition";
if (rangeTransitions.contains(conflictOffset))
break; // Error case, we exit and fallback to the linear envelope
logger.info("Conflict in new envelope at offset {}, splitting mareco ranges", conflictOffset);
rangeTransitions.add(conflictOffset);
}
throw new OSRDError(ErrorType.NoCompatibleEnvelopeFound);
logger.info("Failed to compute a mareco standard allowance, fallback to linear allowance");
return makeFallbackEnvelope(envelope, standardAllowance, context);
}

/** Creates an envelope with a linear allowance. To be used in case we fail to compute a mareco envelope */
private static Envelope makeFallbackEnvelope(
Envelope envelope,
AllowanceValue standardAllowance,
EnvelopeSimContext context
) {
return new LinearAllowance(0, envelope.getEndPos(), 0, List.of(
new AllowanceRange(0, envelope.getEndPos(), standardAllowance)
)).apply(envelope, context);
}

/** Initiates the range transitions with one transition on each stop */
Expand Down Expand Up @@ -108,21 +120,16 @@ private static long findConflictOffsets(
private static Envelope applyAllowanceWithTransitions(
Envelope envelope,
AllowanceValue standardAllowance,
EnvelopeSimPath envelopeSimPath,
RollingStock rollingStock,
double timeStep,
RollingStock.Comfort comfort,
NavigableSet<Long> rangeTransitions
) {
NavigableSet<Long> rangeTransitions,
EnvelopeSimContext context) {

var allowance = new MarecoAllowance(
0,
envelope.getEndPos(),
1,
makeAllowanceRanges(standardAllowance, envelope.getEndPos(), rangeTransitions)
);
return allowance.apply(envelope,
EnvelopeSimContextBuilder.build(rollingStock, envelopeSimPath, timeStep, comfort));
return allowance.apply(envelope, context);
}

/** Create the list of `AllowanceRange`, with the given transitions */
Expand Down

0 comments on commit feafb8b

Please sign in to comment.