diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlockRequest.kt b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlockRequest.kt index fdee1e777be..37775959814 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlockRequest.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlockRequest.kt @@ -17,6 +17,7 @@ class PathfindingBlockRequest( val rollingStockSupportedSignalingSystems: List, @Json(name = "rolling_stock_maximum_speed") val rollingStockMaximumSpeed: Double, @Json(name = "rolling_stock_length") val rollingStockLength: Double, + @Json(name = "stop_at_next_signal") val stopAtNextSignal: Boolean, val timeout: Double?, val infra: String, @Json(name = "expected_version") val expectedVersion: String, diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlocksEndpointV2.kt b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlocksEndpointV2.kt index e8ff1d325c3..a6a2466e36d 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlocksEndpointV2.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/pathfinding/PathfindingBlocksEndpointV2.kt @@ -80,10 +80,17 @@ fun runPathfinding( ): PathfindingBlockResponse { // Parse the waypoints val waypoints = ArrayList>>() - for (step in request.pathItems) { + request.pathItems.forEachIndexed { stepIndex, step -> val allStarts = HashSet>() for (direction in Direction.entries) { - for (waypoint in step) allStarts.addAll(findWaypointBlocks(infra, waypoint, direction)) + for (waypoint in step) { + val waypointBlocks = findWaypointBlocks(infra, waypoint, direction) + if (request.stopAtNextSignal && stepIndex != 0 && stepIndex != request.pathItems.lastIndex) { + allStarts.addAll(waypointBlocks.map { moveWaypointBlockToNextSignal(request, it, infra) }) + } else { + allStarts.addAll(waypointBlocks) + } + } } waypoints.add(allStarts) } @@ -369,3 +376,27 @@ private fun getBlockOffset( String.format("getBlockOffset: Track chunk %s not in block %s", trackChunkId, blockId) ) } + +private fun moveWaypointBlockToNextSignal( + request: PathfindingBlockRequest, + waypointBlock: PathfindingEdgeLocationId, + infra: FullInfra +): PathfindingEdgeLocationId { + val nextSignalOffset = getNextSignalOffset(waypointBlock.edge, waypointBlock.offset, infra, request.rollingStockLength) + return PathfindingEdgeLocationId(waypointBlock.edge, nextSignalOffset) +} + +private fun getNextSignalOffset(blockId: BlockId, blockOffset: Offset, infra: FullInfra, rollingStockLength: Double): Offset { + val signalsPositions = infra.blockInfra.getSignalsPositions(blockId) + val blockLength = infra.blockInfra.getBlockLength(blockId).distance + val nextSignalPosition = signalsPositions.firstOrNull { it.distance > blockOffset.distance } + + val maxHeadOffset = (nextSignalPosition?.distance ?: blockLength) - 1.meters +// println("signalsPositions: $signalsPositions, blockLength: $blockLength, blockOffset: $blockOffset, nextSignalPosition: $nextSignalPosition, maxHeadOffset: $maxHeadOffset") + + // TODO: pour garder la queue sur le PR +// val minTailOffset = blockOffset.distance + rollingStockLength.meters +// val finalOffset = if (minTailOffset <= maxHeadOffset) minTailOffset else maxHeadOffset + val finalOffset = maxHeadOffset + return Offset(finalOffset) +} diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/standalone_sim/SimulationRequest.kt b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/standalone_sim/SimulationRequest.kt index af6fe7db860..5993f09147e 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/standalone_sim/SimulationRequest.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/standalone_sim/SimulationRequest.kt @@ -141,5 +141,6 @@ class SimulationPowerRestrictionItem( ) class TrainScheduleOptions( - @Json(name = "use_electrical_profiles") val useElectricalProfiles: Boolean + @Json(name = "use_electrical_profiles") val useElectricalProfiles: Boolean, +// @Json(name = "stop_at_next_signal") val stopAtNextSignal: Boolean // TODO: not sure it is used still ) diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMEndpointV2.kt b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMEndpointV2.kt index 8d3bfd5ed82..0241d7d6212 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMEndpointV2.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMEndpointV2.kt @@ -299,7 +299,7 @@ private fun parseSteps( return pathItems .map { STDCMStep( - findWaypointBlocks(infra, it.locations), + findWaypointBlocks(infra, it.locations), // TODO: isFirstOrLastWaypoint and stopAtNextSignal it.stopDuration?.seconds, it.stopDuration != null, if (it.stepTimingData != null) @@ -362,12 +362,12 @@ private fun checkForConflicts( private fun findWaypointBlocks( infra: FullInfra, - waypoints: Collection + waypoints: Collection, ): Set> { val waypointBlocks = HashSet>() for (waypoint in waypoints) { for (direction in Direction.entries) { - waypointBlocks.addAll(findWaypointBlocks(infra, waypoint, direction)) + waypointBlocks.addAll(findWaypointBlocks(infra, waypoint, direction)) // TODO: isFirstOrLastWaypoint and stopAtNextSignal } } return waypointBlocks diff --git a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMRequestV2.kt b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMRequestV2.kt index 20119098384..a4f41596e13 100644 --- a/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMRequestV2.kt +++ b/core/src/main/kotlin/fr/sncf/osrd/api/api_v2/stdcm/STDCMRequestV2.kt @@ -34,6 +34,7 @@ class STDCMRequestV2( @Json(name = "rolling_stock_supported_signaling_systems") val rollingStockSupportedSignalingSystems: List, @Json(name = "trains_requirements") val trainsRequirements: Map, + @Json(name = "stop_at_next_signal") val stopAtNextSignal: Boolean, // Simulation inputs val comfort: Comfort,