Skip to content

Commit 3ba9e61

Browse files
committed
core/api add STDCM grid margins
1 parent b304992 commit 3ba9e61

File tree

13 files changed

+87
-15
lines changed

13 files changed

+87
-15
lines changed

api/openapi.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,18 @@ components:
10461046
speed_limit_composition:
10471047
type: string
10481048
description: Train category for speed limits
1049+
margin_before:
1050+
type: number
1051+
format: double
1052+
description: |
1053+
Margin of x seconds before the train passage, which means that the path used by the train should
1054+
be free and available at least x seconds before its passage.
1055+
margin_after:
1056+
type: number
1057+
format: double
1058+
description: |
1059+
Margin of y seconds after the train passage, which means that the path used by the train should
1060+
be free and available at least y seconds after its passage.
10491061
Path:
10501062
properties:
10511063
id:

api/osrd_infra/serializers.py

+2
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,5 @@ class WaypointInputSerializer(Serializer):
173173
maximum_departure_delay = serializers.FloatField(required=False, allow_null=True)
174174
maximum_relative_run_time = serializers.FloatField(required=False, allow_null=True)
175175
speed_limit_composition = serializers.CharField(max_length=255, required=False, allow_null=True)
176+
margin_before = serializers.FloatField(required=False, allow_null=True)
177+
margin_after = serializers.FloatField(required=False, allow_null=True)

api/osrd_infra/views/stdcm.py

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ def make_stdcm_core_payload(request):
9090
"maximum_departure_delay",
9191
"maximum_relative_run_time",
9292
"speed_limit_composition",
93+
"margin_before",
94+
"margin_after"
9395
# Don't forget to add these fields to the serializer
9496
]
9597
for parameter in optional_forwarded_parameters:

core/openapi.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,18 @@ components:
557557
speed_limit_composition:
558558
type: string
559559
description: Train composition used for speed limit
560+
margin_before:
561+
type: number
562+
format: double
563+
description: |
564+
Margin of x seconds before the train passage, which means that the path used by the train should
565+
be free and available at least x seconds before its passage.
566+
margin_after:
567+
type: number
568+
format: double
569+
description: |
570+
Margin of y seconds after the train passage, which means that the path used by the train should
571+
be free and available at least y seconds after its passage.
560572
SimulationRequest:
561573
required:
562574
- infra

core/src/main/java/fr/sncf/osrd/api/stdcm/STDCMEndpoint.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ public Response act(Request req) throws InvalidRollingStock, InvalidSchedule {
9292
var unavailableSpace = UnavailableSpaceBuilder.computeUnavailableSpace(
9393
infra,
9494
occupancies,
95-
rollingStock
95+
rollingStock,
96+
request.marginBefore,
97+
request.marginAfter
9698
);
9799
double minRunTime = getMinRunTime(
98100
infra, rollingStock, comfort, startLocations, endLocations, request.timeStep);

core/src/main/java/fr/sncf/osrd/api/stdcm/STDCMRequest.java

+24-2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ public final class STDCMRequest {
101101
@Json(name = "speed_limit_composition")
102102
public String speedLimitComposition = null;
103103

104+
/**
105+
* Margin of x seconds before the train passage,
106+
* which means that the path used by the train should be free and available
107+
* at least x seconds before its passage.
108+
*/
109+
@Json(name = "margin_before")
110+
public double marginBefore = 0;
111+
112+
/**
113+
* Margin of y seconds after the train passage,
114+
* which means that the path used by the train should be free and available
115+
* at least y seconds after its passage.
116+
*/
117+
@Json(name = "margin_after")
118+
public double marginAfter = 0;
119+
104120
/**
105121
* Create a default STDCMRequest
106122
*/
@@ -114,7 +130,9 @@ public STDCMRequest() {
114130
null,
115131
Double.NaN,
116132
Double.NaN,
117-
null
133+
null,
134+
Double.NaN,
135+
Double.NaN
118136
);
119137
}
120138

@@ -130,7 +148,9 @@ public STDCMRequest(
130148
Collection<PathfindingWaypoint> endPoints,
131149
double startTime,
132150
double endTime,
133-
String speedLimitComposition
151+
String speedLimitComposition,
152+
double marginBefore,
153+
double marginAfter
134154
) {
135155
this.infra = infra;
136156
this.expectedVersion = expectedVersion;
@@ -141,6 +161,8 @@ public STDCMRequest(
141161
this.startTime = startTime;
142162
this.endTime = endTime;
143163
this.speedLimitComposition = speedLimitComposition;
164+
this.marginBefore = marginBefore;
165+
this.marginAfter = marginAfter;
144166
}
145167

146168
public static class RouteOccupancy {

core/src/main/java/fr/sncf/osrd/api/stdcm/UnavailableSpaceBuilder.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ public class UnavailableSpaceBuilder {
2323
public static Multimap<SignalingRoute, OccupancyBlock> computeUnavailableSpace(
2424
SignalingInfra infra,
2525
Collection<STDCMRequest.RouteOccupancy> occupancies,
26-
RollingStock rollingStock
26+
RollingStock rollingStock,
27+
double marginBefore,
28+
double marginAfter
2729
) {
2830

2931
Multimap<SignalingRoute, OccupancyBlock> res = HashMultimap.create();
@@ -35,8 +37,8 @@ public static Multimap<SignalingRoute, OccupancyBlock> computeUnavailableSpace(
3537
var startRouteNode = routeGraph.incidentNodes(currentRoute).nodeU();
3638
var endRouteNode = routeGraph.incidentNodes(currentRoute).nodeV();
3739
var length = currentRoute.getInfraRoute().getLength();
38-
var timeStart = occupancy.startOccupancyTime;
39-
var timeEnd = occupancy.endOccupancyTime;
40+
var timeStart = occupancy.startOccupancyTime - marginBefore;
41+
var timeEnd = occupancy.endOccupancyTime + marginAfter;
4042

4143
//Generating current block occupancy
4244
var block = new OccupancyBlock(timeStart, timeEnd, 0, length);

core/src/test/java/fr/sncf/osrd/api/STDCMEndpointTest.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ public void simpleEmptyTimetable() throws Exception {
3636
)),
3737
0,
3838
0,
39-
"foo"
39+
"foo",
40+
0,
41+
0
4042
));
4143

4244
var result = readBodyResponse(

core/src/test/java/fr/sncf/osrd/stdcm/STDCMHelpers.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ public static Multimap<SignalingRoute, OccupancyBlock> makeOccupancyFromPath(
5454
return UnavailableSpaceBuilder.computeUnavailableSpace(
5555
infra,
5656
occupancies,
57-
REALISTIC_FAST_TRAIN
57+
REALISTIC_FAST_TRAIN,
58+
0,
59+
0
5860
);
5961
}
6062

core/src/test/java/fr/sncf/osrd/stdcm/UnavailableSpaceBuilderTests.java

+13-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class UnavailableSpaceBuilderTests {
1616
@Test
1717
public void testNoOccupancy() throws Exception {
1818
var infra = Helpers.infraFromRJS(Helpers.getExampleInfra("tiny_infra/infra.json"));
19-
var res = computeUnavailableSpace(infra, Set.of(), REALISTIC_FAST_TRAIN);
19+
var res = computeUnavailableSpace(infra, Set.of(), REALISTIC_FAST_TRAIN, 0, 0);
2020
assertTrue(res.isEmpty());
2121
}
2222

@@ -29,7 +29,9 @@ public void testFirstRouteOccupied() {
2929
var res = computeUnavailableSpace(
3030
infra,
3131
Set.of(new STDCMRequest.RouteOccupancy("a->b", 0, 100)),
32-
REALISTIC_FAST_TRAIN
32+
REALISTIC_FAST_TRAIN,
33+
0,
34+
0
3335
);
3436
assertEquals(
3537
Set.of(
@@ -59,7 +61,9 @@ public void testSecondRouteOccupied() {
5961
var res = computeUnavailableSpace(
6062
infra,
6163
Set.of(new STDCMRequest.RouteOccupancy("b->c", 0, 100)),
62-
REALISTIC_FAST_TRAIN
64+
REALISTIC_FAST_TRAIN,
65+
0,
66+
0
6367
);
6468
assertEquals(
6569
Set.of(
@@ -96,7 +100,9 @@ public void testBranchingRoutes() {
96100
final var res = computeUnavailableSpace(
97101
infra,
98102
Set.of(new STDCMRequest.RouteOccupancy("a1->center", 0, 100)),
99-
REALISTIC_FAST_TRAIN
103+
REALISTIC_FAST_TRAIN,
104+
0,
105+
0
100106
);
101107
assertEquals(
102108
Set.of(
@@ -132,7 +138,9 @@ public void testThirdRoute() {
132138
var res = computeUnavailableSpace(
133139
infra,
134140
Set.of(new STDCMRequest.RouteOccupancy("a->b", 0, 100)),
135-
REALISTIC_FAST_TRAIN
141+
REALISTIC_FAST_TRAIN,
142+
0,
143+
0
136144
);
137145
assertEquals(
138146
Set.of(

tests/fuzzer/fuzzer.py

+2
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ def make_stdcm_payload(base_url: str, infra_id: int, path: List[Tuple[str, float
167167
"track_section": last_edge,
168168
"offset": last_offset,
169169
}],
170+
"margin_before": 0,
171+
"margin_after": 0,
170172
}
171173

172174

tests/tests/stdcm/between_trains.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ def run(*args, **kwargs):
2626
"start_time": 5000,
2727
"name": "foo",
2828
"start_points": [start],
29-
"end_points": [stop]
29+
"end_points": [stop],
30+
"margin_before": 0,
31+
"margin_after": 0
3032
}
3133
r = requests.post(base_url + f"stdcm/", json=payload)
3234
delete_timetable(base_url, timetable)

tests/tests/stdcm/empty_timetable.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ def run(*args, **kwargs):
2020
"end_points": [{
2121
"track_section": "TE0",
2222
"offset": 0
23-
}]
23+
}],
24+
"margin_before": 0,
25+
"margin_after": 0
2426
}
2527
r = requests.post(base_url + f"stdcm/", json=payload)
2628
delete_timetable(base_url, timetable)

0 commit comments

Comments
 (0)