1
1
package fr .sncf .osrd .stdcm ;
2
2
3
3
import static fr .sncf .osrd .Helpers .getExampleRollingStock ;
4
+ import static fr .sncf .osrd .api .stdcm .STDCMEndpoint .makeTrainSchedule ;
5
+ import static fr .sncf .osrd .train .TestTrains .REALISTIC_FAST_TRAIN ;
4
6
import static org .junit .jupiter .api .Assertions .assertNotNull ;
7
+ import static org .junit .jupiter .api .Assertions .assertTrue ;
5
8
9
+ import com .google .common .collect .HashMultimap ;
6
10
import fr .sncf .osrd .Helpers ;
11
+ import fr .sncf .osrd .api .FullInfra ;
7
12
import fr .sncf .osrd .railjson .parser .RJSRollingStockParser ;
13
+ import fr .sncf .osrd .standalone_sim .ScheduleMetadataExtractor ;
14
+ import fr .sncf .osrd .standalone_sim .result .ResultTrain ;
15
+ import fr .sncf .osrd .train .RollingStock ;
8
16
import fr .sncf .osrd .utils .units .Distance ;
9
17
import org .junit .jupiter .api .Test ;
10
18
import java .io .IOException ;
11
19
import java .net .URISyntaxException ;
20
+ import java .util .List ;
12
21
import java .util .Set ;
13
22
14
23
public class FullSTDCMTests {
@@ -42,9 +51,12 @@ public void testTinyInfraSmallOpening() throws IOException, URISyntaxException {
42
51
"rt.buffer_stop_b->tde.foo_b-switch_foo" , Distance .fromMeters (100 )));
43
52
var end = Set .of (Helpers .convertRouteLocation (infra ,
44
53
"rt.tde.foo_b-switch_foo->buffer_stop_c" , Distance .fromMeters (10125 )));
45
- var occupancies = STDCMHelpers .makeOccupancyFromPath (infra , start , end , 0 );
54
+ var requirements = STDCMHelpers .makeRequirementsFromPath (infra , start , end , 0 );
55
+ var occupancies = STDCMHelpers .makeOccupancyFromRequirements (infra , requirements );
46
56
double minDelay = STDCMHelpers .getMaxOccupancyLength (occupancies ); // Eventually we may need to add a % margin
47
- occupancies .putAll (STDCMHelpers .makeOccupancyFromPath (infra , start , end , minDelay * 2 ));
57
+ occupancies .putAll (STDCMHelpers .makeOccupancyFromRequirements (infra ,
58
+ STDCMHelpers .makeRequirementsFromPath (infra , start , end , minDelay * 2 )
59
+ ));
48
60
var res = new STDCMPathfindingBuilder ()
49
61
.setInfra (infra )
50
62
.setStartTime (minDelay )
@@ -53,6 +65,7 @@ public void testTinyInfraSmallOpening() throws IOException, URISyntaxException {
53
65
.setUnavailableTimes (occupancies )
54
66
.run ();
55
67
assertNotNull (res );
68
+ checkNoConflict (infra , requirements , res );
56
69
}
57
70
58
71
/** We try to fit a train in a short opening between two trains, this time on small_infra */
@@ -63,15 +76,62 @@ public void testSmallInfraSmallOpening() throws IOException, URISyntaxException
63
76
"rt.buffer_stop.3->DB0" , Distance .fromMeters (1590 )));
64
77
var end = Set .of (Helpers .convertRouteLocation (infra ,
65
78
"rt.DH2->buffer_stop.7" , Distance .fromMeters (5000 )));
66
- var occupancies = STDCMHelpers .makeOccupancyFromPath (infra , start , end , 0 );
67
- occupancies . putAll (STDCMHelpers .makeOccupancyFromPath (infra , start , end , 600 ));
79
+ var requirements = STDCMHelpers .makeRequirementsFromPath (infra , start , end , 0 );
80
+ requirements . addAll (STDCMHelpers .makeRequirementsFromPath (infra , start , end , 600 ));
68
81
var res = new STDCMPathfindingBuilder ()
69
82
.setInfra (infra )
70
83
.setStartTime (300 )
71
84
.setStartLocations (start )
72
85
.setEndLocations (end )
73
- .setUnavailableTimes (occupancies )
86
+ .setUnavailableTimes (STDCMHelpers . makeOccupancyFromRequirements ( infra , requirements ) )
74
87
.run ();
75
88
assertNotNull (res );
89
+ checkNoConflict (infra , requirements , res );
90
+ }
91
+
92
+ /** We make an opening that is just too small to fit a train,
93
+ * we check that it isn't taken and doesn't cause conflicts */
94
+ @ Test
95
+ public void testSmallInfraImpossibleOpening () throws IOException , URISyntaxException {
96
+ var infra = Helpers .fullInfraFromRJS (Helpers .getExampleInfra ("small_infra/infra.json" ));
97
+ var start = Set .of (Helpers .convertRouteLocation (infra ,
98
+ "rt.buffer_stop.3->DB0" , Distance .fromMeters (1590 )));
99
+ var end = Set .of (Helpers .convertRouteLocation (infra ,
100
+ "rt.DH2->buffer_stop.7" , Distance .fromMeters (5000 )));
101
+ var requirements = STDCMHelpers .makeRequirementsFromPath (infra , start , end , 0 );
102
+ var occupancies = STDCMHelpers .makeOccupancyFromRequirements (infra , requirements );
103
+ double minDelay = STDCMHelpers .getMaxOccupancyLength (occupancies );
104
+ occupancies .putAll (STDCMHelpers .makeOccupancyFromRequirements (infra ,
105
+ STDCMHelpers .makeRequirementsFromPath (infra , start , end , minDelay * 0.95 )
106
+ ));
107
+ var res = new STDCMPathfindingBuilder ()
108
+ .setInfra (infra )
109
+ .setStartLocations (start )
110
+ .setEndLocations (end )
111
+ .setUnavailableTimes (STDCMHelpers .makeOccupancyFromRequirements (infra , requirements ))
112
+ .run ();
113
+ assertNotNull (res );
114
+ checkNoConflict (infra , requirements , res );
115
+ }
116
+
117
+ /** Check that the result we find doesn't cause a conflict */
118
+ private void checkNoConflict (FullInfra infra , List <ResultTrain .SpacingRequirement > requirements , STDCMResult res ) {
119
+ var requirementMap = HashMultimap .<String , ResultTrain .SpacingRequirement >create ();
120
+ for (var requirement : requirements ) {
121
+ requirementMap .put (requirement .zone , requirement );
122
+ }
123
+ var newRequirements = ScheduleMetadataExtractor .run (
124
+ res .envelope (),
125
+ res .trainPath (),
126
+ makeTrainSchedule (res .envelope ().getEndPos (), REALISTIC_FAST_TRAIN ,
127
+ RollingStock .Comfort .STANDARD , res .stopResults ()),
128
+ infra
129
+ ).spacingRequirements ;
130
+ for (var requirement : newRequirements ) {
131
+ for (var existingRequirement : requirementMap .get (requirement .zone )) {
132
+ assertTrue (requirement .beginTime > existingRequirement .endTime
133
+ || requirement .endTime < existingRequirement .beginTime );
134
+ }
135
+ }
76
136
}
77
137
}
0 commit comments