@@ -80,7 +80,7 @@ fun addBrakingCurvesAtEOAs(
80
80
)
81
81
assert (
82
82
indicationCurveSvl.beginSpeed <= maxSpeedEnvelope &&
83
- indicationCurveSvl.endSpeed >= releaseSpeed
83
+ indicationCurveSvl.endSpeed >= nationalReleaseSpeed
84
84
)
85
85
builder.addPart(indicationCurveSvl)
86
86
envelopeWithEoaBrakingCurves = builder.build()
@@ -252,8 +252,8 @@ private fun computeSvlIndicationCurve(
252
252
if (fullIndicationCurveSvl.beginPos >= targetPosition) return null
253
253
val fullIndCurveSvlWithMaintain: Envelope
254
254
val releaseSpeedPosition =
255
- if (fullIndicationCurveSvl.maxSpeed >= releaseSpeed )
256
- fullIndicationCurveSvl.interpolatePosition(releaseSpeed )
255
+ if (fullIndicationCurveSvl.maxSpeed >= nationalReleaseSpeed )
256
+ fullIndicationCurveSvl.interpolatePosition(nationalReleaseSpeed )
257
257
else fullIndicationCurveSvl.beginPos
258
258
if (releaseSpeedPosition >= targetPosition) {
259
259
fullIndCurveSvlWithMaintain =
@@ -265,7 +265,7 @@ private fun computeSvlIndicationCurve(
265
265
EnvelopePart .generateTimes(
266
266
listOf (EnvelopeProfile .CONSTANT_SPEED ),
267
267
doubleArrayOf(releaseSpeedPosition, targetPosition),
268
- doubleArrayOf(releaseSpeed, releaseSpeed )
268
+ doubleArrayOf(nationalReleaseSpeed, nationalReleaseSpeed )
269
269
)
270
270
fullIndCurveSvlWithMaintain =
271
271
if (releaseSpeedPosition == fullIndicationCurveSvl.beginPos) {
@@ -276,7 +276,7 @@ private fun computeSvlIndicationCurve(
276
276
fullIndicationCurveSvl.beginPos,
277
277
fullIndicationCurveSvl.beginSpeed,
278
278
releaseSpeedPosition,
279
- releaseSpeed
279
+ nationalReleaseSpeed
280
280
),
281
281
maintainReleaseSpeedCurve
282
282
)
@@ -477,7 +477,6 @@ private fun keepBrakingCurveUnderOverlay(
477
477
mergedArray + currentArray.drop(1 ).toDoubleArray()
478
478
}
479
479
val timeDeltas = fullBrakingCurve.flatMap { it.cloneTimes().asList() }
480
- val nbPoints = positions.size
481
480
482
481
val partBuilder = EnvelopePartBuilder ()
483
482
partBuilder.setAttr(EnvelopeProfile .BRAKING )
@@ -487,23 +486,33 @@ private fun keepBrakingCurveUnderOverlay(
487
486
PositionConstraint (max(beginPos, fullBrakingCurve.beginPos), overlay.endPos),
488
487
EnvelopeConstraint (overlay, EnvelopePartConstraintType .CEILING )
489
488
)
490
- // Find the last point of the braking curve which is located below the overlay envelope, and
491
- // init the overlay builder there.
492
- var lastIndex = nbPoints - 1
489
+ val lastIndex = getIndexOfLastPointBeneathOverlay(positions, speeds, overlay)
490
+ // To create a braking curve with overlay builder, we need at least 2 positions.
491
+ if (lastIndex <= 0 ) return null
492
+ overlayBuilder.initEnvelopePart(positions[lastIndex], speeds[lastIndex], - 1.0 )
493
+ for (i in lastIndex - 1 downTo 0 ) {
494
+ if (! overlayBuilder.addStep(positions[i], speeds[i], timeDeltas[i])) break
495
+ }
496
+ return partBuilder.build()
497
+ }
498
+
499
+ /* * Find the index of the last point which is located beneath the overlay envelope, -1 if none exist. */
500
+ private fun getIndexOfLastPointBeneathOverlay (
501
+ positions : DoubleArray ,
502
+ speeds : DoubleArray ,
503
+ overlay : Envelope
504
+ ): Int {
505
+ var lastIndex = positions.size - 1
493
506
while (
507
+ lastIndex >= 0 &&
494
508
speeds[lastIndex] >
495
509
overlay
496
510
.get(overlay.findRightDir(positions[lastIndex], - 1.0 ))
497
511
.interpolateSpeed(positions[lastIndex])
498
512
) {
499
513
lastIndex--
500
- if (lastIndex == 0 ) return null
501
- }
502
- overlayBuilder.initEnvelopePart(positions[lastIndex], speeds[lastIndex], - 1.0 )
503
- for (i in lastIndex - 1 downTo 0 ) {
504
- if (! overlayBuilder.addStep(positions[i], speeds[i], timeDeltas[i])) break
505
514
}
506
- return partBuilder.build()
515
+ return lastIndex
507
516
}
508
517
509
518
private data class BecParams (val dBec : Double , val vBec : Double , val speed : Double ) {
0 commit comments