diff --git a/scenario_runner/srunner/examples/CatalogExample.xosc b/scenario_runner/srunner/examples/CatalogExample.xosc new file mode 100644 index 0000000..78614a5 --- /dev/null +++ b/scenario_runner/srunner/examples/CatalogExample.xosc @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/ChangeLane.xml b/scenario_runner/srunner/examples/ChangeLane.xml new file mode 100644 index 0000000..d7f7760 --- /dev/null +++ b/scenario_runner/srunner/examples/ChangeLane.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/ChangingWeather.xosc b/scenario_runner/srunner/examples/ChangingWeather.xosc new file mode 100644 index 0000000..c4cc314 --- /dev/null +++ b/scenario_runner/srunner/examples/ChangingWeather.xosc @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/ControlLoss.xml b/scenario_runner/srunner/examples/ControlLoss.xml new file mode 100644 index 0000000..032b3fc --- /dev/null +++ b/scenario_runner/srunner/examples/ControlLoss.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/CutIn.xml b/scenario_runner/srunner/examples/CutIn.xml new file mode 100644 index 0000000..1c249d7 --- /dev/null +++ b/scenario_runner/srunner/examples/CutIn.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/CyclistCrossing.xosc b/scenario_runner/srunner/examples/CyclistCrossing.xosc new file mode 100644 index 0000000..15e5243 --- /dev/null +++ b/scenario_runner/srunner/examples/CyclistCrossing.xosc @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/FollowLeadingVehicle.xml b/scenario_runner/srunner/examples/FollowLeadingVehicle.xml new file mode 100644 index 0000000..c74a802 --- /dev/null +++ b/scenario_runner/srunner/examples/FollowLeadingVehicle.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/FollowLeadingVehicle.xosc b/scenario_runner/srunner/examples/FollowLeadingVehicle.xosc new file mode 100644 index 0000000..c203820 --- /dev/null +++ b/scenario_runner/srunner/examples/FollowLeadingVehicle.xosc @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/FreeRide.xml b/scenario_runner/srunner/examples/FreeRide.xml new file mode 100644 index 0000000..9ad20fa --- /dev/null +++ b/scenario_runner/srunner/examples/FreeRide.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/LaneChangeSimple.xosc b/scenario_runner/srunner/examples/LaneChangeSimple.xosc new file mode 100644 index 0000000..cceee23 --- /dev/null +++ b/scenario_runner/srunner/examples/LaneChangeSimple.xosc @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/LeadingVehicle.xml b/scenario_runner/srunner/examples/LeadingVehicle.xml new file mode 100644 index 0000000..043e76f --- /dev/null +++ b/scenario_runner/srunner/examples/LeadingVehicle.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/NoSignalJunction.xml b/scenario_runner/srunner/examples/NoSignalJunction.xml new file mode 100644 index 0000000..ceae7ca --- /dev/null +++ b/scenario_runner/srunner/examples/NoSignalJunction.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/scenario_runner/srunner/examples/ObjectCrossing.xml b/scenario_runner/srunner/examples/ObjectCrossing.xml new file mode 100644 index 0000000..a448a56 --- /dev/null +++ b/scenario_runner/srunner/examples/ObjectCrossing.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/OppositeDirection.xml b/scenario_runner/srunner/examples/OppositeDirection.xml new file mode 100644 index 0000000..8c03237 --- /dev/null +++ b/scenario_runner/srunner/examples/OppositeDirection.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/OscControllerExample.xosc b/scenario_runner/srunner/examples/OscControllerExample.xosc new file mode 100644 index 0000000..993905f --- /dev/null +++ b/scenario_runner/srunner/examples/OscControllerExample.xosc @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/PedestrianCrossingFront.xosc b/scenario_runner/srunner/examples/PedestrianCrossingFront.xosc new file mode 100644 index 0000000..4842214 --- /dev/null +++ b/scenario_runner/srunner/examples/PedestrianCrossingFront.xosc @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/RunningRedLight.xml b/scenario_runner/srunner/examples/RunningRedLight.xml new file mode 100644 index 0000000..f931565 --- /dev/null +++ b/scenario_runner/srunner/examples/RunningRedLight.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scenario_runner/srunner/examples/SignalizedJunctionLeftTurn.xml b/scenario_runner/srunner/examples/SignalizedJunctionLeftTurn.xml new file mode 100644 index 0000000..9d1a9ea --- /dev/null +++ b/scenario_runner/srunner/examples/SignalizedJunctionLeftTurn.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/SignalizedJunctionRightTurn.xml b/scenario_runner/srunner/examples/SignalizedJunctionRightTurn.xml new file mode 100644 index 0000000..31d9a44 --- /dev/null +++ b/scenario_runner/srunner/examples/SignalizedJunctionRightTurn.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/VehicleTurning.xml b/scenario_runner/srunner/examples/VehicleTurning.xml new file mode 100644 index 0000000..26076f9 --- /dev/null +++ b/scenario_runner/srunner/examples/VehicleTurning.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/catalogs/ControllerCatalog.xosc b/scenario_runner/srunner/examples/catalogs/ControllerCatalog.xosc new file mode 100644 index 0000000..3ee36a2 --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/ControllerCatalog.xosc @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/scenario_runner/srunner/examples/catalogs/EnvironmentCatalog.xosc b/scenario_runner/srunner/examples/catalogs/EnvironmentCatalog.xosc new file mode 100644 index 0000000..c34b2d5 --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/EnvironmentCatalog.xosc @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/catalogs/ManeuverCatalog.xosc b/scenario_runner/srunner/examples/catalogs/ManeuverCatalog.xosc new file mode 100644 index 0000000..a35636b --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/ManeuverCatalog.xosc @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scenario_runner/srunner/examples/catalogs/MiscObjectCatalog.xosc b/scenario_runner/srunner/examples/catalogs/MiscObjectCatalog.xosc new file mode 100644 index 0000000..893c3f1 --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/MiscObjectCatalog.xosc @@ -0,0 +1,14 @@ + + + + + + + +
+ + + + + + diff --git a/scenario_runner/srunner/examples/catalogs/PedestrianCatalog.xosc b/scenario_runner/srunner/examples/catalogs/PedestrianCatalog.xosc new file mode 100644 index 0000000..724a08e --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/PedestrianCatalog.xosc @@ -0,0 +1,13 @@ + + + + + + +
+ + + + + + diff --git a/scenario_runner/srunner/examples/catalogs/VehicleCatalog.xosc b/scenario_runner/srunner/examples/catalogs/VehicleCatalog.xosc new file mode 100644 index 0000000..2804482 --- /dev/null +++ b/scenario_runner/srunner/examples/catalogs/VehicleCatalog.xosc @@ -0,0 +1,38 @@ + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + diff --git a/scenario_runner/srunner/metrics/data/CriteriaFilter_criteria.json b/scenario_runner/srunner/metrics/data/CriteriaFilter_criteria.json new file mode 100644 index 0000000..8dbff1d --- /dev/null +++ b/scenario_runner/srunner/metrics/data/CriteriaFilter_criteria.json @@ -0,0 +1,1650 @@ +{ + "RouteCompletionTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "SUCCESS", + "expected_value_success": 100, + "expected_value_acceptable": null, + "actual_value": 100, + "optional": false, + "_wsize": 2, + "_current_index": 759, + "_route_length": 762, + "_accum_meters": [ + 0.0, + 1.1180341243743896, + 2.118034243583679, + 3.1180343627929688, + 4.118034482002258, + 5.118034601211548, + 6.118034720420837, + 7.118034839630127, + 8.118034958839417, + 9.118035078048706, + 10.118035197257996, + 11.118035316467285, + 12.118035435676575, + 13.118035554885864, + 14.118035674095154, + 15.118035793304443, + 16.118035912513733, + 17.408029437065125, + 17.408029437065125, + 18.408029556274414, + 19.408029675483704, + 20.408029794692993, + 21.408029913902283, + 22.60914123058319, + 23.882590174674988, + 25.156023859977722, + 26.42948305606842, + 27.702926516532898, + 28.976354002952576, + 30.22618818283081, + 31.444236278533936, + 32.66231644153595, + 33.88036382198334, + 35.098384618759155, + 36.31645858287811, + 37.5344922542572, + 38.54053473472595, + 40.18173956871033, + 40.18173956871033, + 41.18173956871033, + 42.18173956871033, + 44.18173956871033, + 45.18173956871033, + 46.18173956871033, + 47.18173956871033, + 48.18173956871033, + 49.18173956871033, + 50.18173956871033, + 51.18173956871033, + 52.18173956871033, + 53.18173956871033, + 54.18173956871033, + 55.18173956871033, + 56.18173956871033, + 57.18173956871033, + 58.18173956871033, + 59.18173956871033, + 60.18173956871033, + 61.18173956871033, + 62.18173956871033, + 63.18173956871033, + 64.18173956871033, + 65.18173956871033, + 66.18173956871033, + 67.18173956871033, + 68.18173956871033, + 69.18173956871033, + 70.18173956871033, + 71.18173956871033, + 72.18173956871033, + 73.18173956871033, + 74.18173956871033, + 75.18173956871033, + 76.18173956871033, + 77.18173956871033, + 78.18173956871033, + 79.18173956871033, + 80.18173956871033, + 81.18173956871033, + 82.18173956871033, + 83.18173956871033, + 84.18173956871033, + 85.18173956871033, + 86.18173956871033, + 87.18173956871033, + 88.18173956871033, + 89.18173956871033, + 90.18173956871033, + 91.18173956871033, + 92.18173956871033, + 93.18173956871033, + 94.18173956871033, + 95.18173956871033, + 96.18173956871033, + 97.18173956871033, + 98.18173956871033, + 99.18173956871033, + 100.18173956871033, + 101.18173956871033, + 102.18173956871033, + 103.18173956871033, + 104.18173956871033, + 105.18173956871033, + 106.18173956871033, + 107.18173956871033, + 108.18173956871033, + 109.18173956871033, + 110.1817090511322, + 111.1817090511322, + 112.1817090511322, + 113.1817090511322, + 114.1817090511322, + 115.1817090511322, + 116.1817090511322, + 117.1817090511322, + 118.1817090511322, + 119.1817090511322, + 120.1817090511322, + 121.1817090511322, + 122.1817090511322, + 123.1817090511322, + 124.1817090511322, + 125.1817090511322, + 126.1817090511322, + 127.1817090511322, + 128.1817090511322, + 129.1817090511322, + 130.1817090511322, + 131.1817090511322, + 132.1817090511322, + 133.1817090511322, + 134.1817090511322, + 135.1817090511322, + 136.1817090511322, + 137.1817090511322, + 138.1817090511322, + 139.1817090511322, + 140.1817090511322, + 141.1817090511322, + 142.1817090511322, + 143.1817090511322, + 144.1817090511322, + 145.1817090511322, + 146.1817090511322, + 147.1817090511322, + 148.1817090511322, + 149.1817090511322, + 150.1817090511322, + 151.1817090511322, + 152.1817090511322, + 153.1817090511322, + 154.1817090511322, + 155.1817090511322, + 156.1817090511322, + 157.1817090511322, + 158.1817090511322, + 159.1817090511322, + 160.1817090511322, + 161.1817090511322, + 162.1817090511322, + 163.1817090511322, + 164.1817090511322, + 165.1817090511322, + 166.1817090511322, + 167.1817090511322, + 168.1817090511322, + 169.1817090511322, + 170.1817090511322, + 171.1817090511322, + 172.1817090511322, + 173.1817090511322, + 174.1817090511322, + 175.1817090511322, + 176.1817090511322, + 177.1817090511322, + 178.1817090511322, + 179.1817090511322, + 180.1817090511322, + 181.1817090511322, + 182.1817090511322, + 183.1817090511322, + 184.1817090511322, + 185.1817090511322, + 186.1817090511322, + 187.1817090511322, + 188.1817090511322, + 189.1817090511322, + 190.1817090511322, + 191.1817090511322, + 192.1817090511322, + 193.1817090511322, + 194.1817090511322, + 195.1817090511322, + 196.1817090511322, + 197.1817090511322, + 198.1817090511322, + 199.1817090511322, + 200.1817090511322, + 201.1817090511322, + 202.1817090511322, + 203.1817090511322, + 204.1817090511322, + 205.1817090511322, + 206.1817090511322, + 207.1817090511322, + 208.1817090511322, + 209.1817090511322, + 210.1817090511322, + 211.1817090511322, + 212.1817090511322, + 213.1817090511322, + 214.1817090511322, + 215.1817090511322, + 216.1817090511322, + 217.1817090511322, + 218.1817090511322, + 219.1817090511322, + 220.1817090511322, + 221.1817090511322, + 222.1817090511322, + 223.1817090511322, + 224.1817090511322, + 225.1817090511322, + 226.1817090511322, + 227.1817090511322, + 228.1817090511322, + 229.1817090511322, + 230.1817090511322, + 231.1817090511322, + 232.1817090511322, + 233.1817090511322, + 234.1817090511322, + 235.1817090511322, + 236.1817090511322, + 237.1817090511322, + 238.18171668052673, + 239.18171668052673, + 240.18171668052673, + 241.18171668052673, + 242.18171668052673, + 243.18171668052673, + 244.18171668052673, + 245.18171668052673, + 246.18171668052673, + 247.18171668052673, + 248.18171668052673, + 249.18171668052673, + 250.18171668052673, + 251.18171668052673, + 252.18171668052673, + 253.18171668052673, + 254.18171668052673, + 255.18171668052673, + 256.18171668052673, + 258.18171668052673, + 259.18171668052673, + 260.18171668052673, + 261.18171668052673, + 262.18171668052673, + 263.18171668052673, + 264.43171668052673, + 264.43171668052673, + 265.43171668052673, + 266.4848858118057, + 267.6947091817856, + 268.9045317173004, + 270.11435973644257, + 271.3241786956787, + 272.53399670124054, + 273.74381709098816, + 274.95476615428925, + 276.1825375556946, + 277.41030740737915, + 278.6380902528763, + 279.86586582660675, + 281.093638420105, + 282.32140839099884, + 283.54918599128723, + 284.56516194343567, + 285.86318135261536, + 285.86318135261536, + 286.86318135261536, + 287.86318135261536, + 288.86318135261536, + 289.86318135261536, + 290.86318135261536, + 291.86318135261536, + 292.86318135261536, + 293.86318135261536, + 294.86318135261536, + 295.86318135261536, + 296.86318135261536, + 297.86318135261536, + 298.86318135261536, + 299.86318135261536, + 300.86318135261536, + 301.86318135261536, + 302.86318135261536, + 303.86318135261536, + 304.86318135261536, + 305.86318135261536, + 306.86318135261536, + 307.86318135261536, + 308.86318135261536, + 309.86318135261536, + 310.86318135261536, + 311.86318135261536, + 312.86318135261536, + 313.86318135261536, + 314.86318135261536, + 315.86318135261536, + 316.86318135261536, + 317.86318135261536, + 318.86318135261536, + 319.86318135261536, + 320.86318135261536, + 321.86318135261536, + 322.86318135261536, + 323.86318135261536, + 324.86318135261536, + 325.86318135261536, + 326.86318135261536, + 327.86318135261536, + 328.86318135261536, + 329.86318135261536, + 330.86318135261536, + 331.86318135261536, + 332.86318135261536, + 333.8631966114044, + 334.8631966114044, + 335.8631966114044, + 336.8631966114044, + 337.8631966114044, + 338.8631966114044, + 339.8631966114044, + 340.8631966114044, + 341.8631966114044, + 342.8631966114044, + 343.8631966114044, + 344.8631966114044, + 345.8631966114044, + 346.8631966114044, + 347.8631966114044, + 348.8631966114044, + 349.8631966114044, + 350.8631966114044, + 351.8631966114044, + 352.8631966114044, + 353.8631966114044, + 354.8631966114044, + 355.8631966114044, + 356.8631966114044, + 357.8631966114044, + 358.8631966114044, + 359.8631966114044, + 360.8631966114044, + 361.8631966114044, + 362.8631966114044, + 363.8631966114044, + 364.8631966114044, + 365.8631966114044, + 366.8631966114044, + 367.8631966114044, + 368.8631966114044, + 369.8631966114044, + 370.8631966114044, + 371.8631966114044, + 372.8631966114044, + 373.8631966114044, + 374.8631966114044, + 375.8631966114044, + 376.8631966114044, + 377.8631966114044, + 378.8631966114044, + 379.8631966114044, + 380.8631966114044, + 381.8631966114044, + 382.8631966114044, + 383.8631966114044, + 384.8631966114044, + 385.8631966114044, + 386.8631966114044, + 387.8631966114044, + 388.8631966114044, + 389.8631966114044, + 390.8631966114044, + 391.8631966114044, + 392.8631966114044, + 394.8331673145294, + 394.8331673145294, + 395.6912509202957, + 396.5167629122734, + 397.34227895736694, + 398.1678013205528, + 398.9933475255966, + 399.81885331869125, + 400.6444185972214, + 401.4699310064316, + 402.290342271328, + 403.09512996673584, + 403.8999582529068, + 404.70476245880127, + 405.509556889534, + 406.314362347126, + 407.1191706061363, + 407.92396891117096, + 409.09423565864563, + 409.09423565864563, + 410.0942357778549, + 411.0942358970642, + 412.0942360162735, + 413.0942361354828, + 414.0942362546921, + 415.09423637390137, + 416.09423649311066, + 417.09423661231995, + 418.09423673152924, + 419.0942368507385, + 420.0942369699478, + 421.0942370891571, + 422.0942372083664, + 423.0942373275757, + 424.094237446785, + 425.094233751297, + 426.0942338705063, + 427.0942339897156, + 428.09423410892487, + 429.09423422813416, + 430.09423434734344, + 431.09423446655273, + 432.094234585762, + 433.0942347049713, + 434.0942348241806, + 435.0942349433899, + 436.0942350625992, + 437.0942351818085, + 438.09423530101776, + 439.09423542022705, + 440.09423553943634, + 441.09423565864563, + 442.0942357778549, + 443.0942358970642, + 444.0942360162735, + 445.0942361354828, + 446.0942362546921, + 447.0942325592041, + 448.0942326784134, + 449.0942327976227, + 450.09423291683197, + 451.09423303604126, + 452.09423315525055, + 453.0942294597626, + 454.09422957897186, + 455.09422969818115, + 456.09422981739044, + 457.09423184394836, + 458.09423196315765, + 459.09423208236694, + 460.09423220157623, + 461.0942323207855, + 462.0942324399948, + 463.09423065185547, + 464.09423077106476, + 465.09423089027405, + 466.09423100948334, + 467.0942311286926, + 468.0942312479019, + 469.0942313671112, + 470.0942314863205, + 471.0942316055298, + 472.0942317247391, + 473.0942327976227, + 474.09423291683197, + 475.09423303604126, + 476.09423315525055, + 477.0942323207855, + 478.724232673645, + 478.724232673645, + 479.64406257867813, + 480.41382187604904, + 481.18358182907104, + 481.9533463716507, + 482.7230935692787, + 483.4928572177887, + 484.2626251578331, + 485.03238236904144, + 485.8388220667839, + 486.66605401039124, + 487.49329620599747, + 488.3205181956291, + 489.1477633714676, + 489.9749982357025, + 490.802244246006, + 492.28208762407303, + 492.28208762407303, + 493.28208762407303, + 494.28208762407303, + 495.28208762407303, + 496.28208762407303, + 497.28208762407303, + 498.28208762407303, + 499.28208762407303, + 500.28208762407303, + 501.28208762407303, + 502.28208762407303, + 503.28208762407303, + 504.28208762407303, + 505.28208762407303, + 506.28208762407303, + 507.28208762407303, + 508.28208762407303, + 509.28208762407303, + 510.28208762407303, + 511.28208762407303, + 512.282087624073, + 513.282087624073, + 514.282087624073, + 515.282087624073, + 516.282087624073, + 517.282087624073, + 518.282087624073, + 519.282087624073, + 520.282087624073, + 521.282087624073, + 522.282087624073, + 523.282087624073, + 524.282087624073, + 525.282087624073, + 526.282087624073, + 527.282087624073, + 528.282087624073, + 529.282087624073, + 530.282087624073, + 531.282087624073, + 532.282087624073, + 533.282087624073, + 534.282087624073, + 535.282087624073, + 536.282087624073, + 537.282087624073, + 538.282087624073, + 539.282087624073, + 540.282087624073, + 541.282087624073, + 542.282087624073, + 543.282087624073, + 544.282087624073, + 545.282087624073, + 546.282087624073, + 547.282087624073, + 548.282087624073, + 549.282087624073, + 550.282087624073, + 551.282087624073, + 552.282087624073, + 553.282087624073, + 554.2821028828621, + 555.2821028828621, + 556.2821028828621, + 557.2821028828621, + 558.2821028828621, + 559.2821028828621, + 560.2821028828621, + 561.2821028828621, + 562.2821028828621, + 563.2821028828621, + 564.2821028828621, + 565.2821028828621, + 566.2821028828621, + 567.2821028828621, + 568.2821028828621, + 569.2833998799324, + 570.2833999991417, + 571.283400118351, + 572.2834002375603, + 573.2834003567696, + 574.2834004759789, + 575.2834005951881, + 576.2834007143974, + 577.2834008336067, + 578.283400952816, + 579.2834010720253, + 580.2834011912346, + 581.2834013104439, + 582.2834014296532, + 583.2834015488625, + 584.2834016680717, + 585.283401787281, + 586.2834019064903, + 587.2834020256996, + 588.2834021449089, + 589.2834022641182, + 590.2834023833275, + 591.2834025025368, + 592.2834026217461, + 593.2834027409554, + 594.2834028601646, + 595.2834029793739, + 596.2834030985832, + 597.2834032177925, + 598.2834033370018, + 599.2834034562111, + 600.2834035754204, + 601.2834036946297, + 602.283403813839, + 603.2834039330482, + 604.2834040522575, + 605.2834041714668, + 606.2834042906761, + 607.2834044098854, + 608.2834045290947, + 609.283404648304, + 610.2834047675133, + 611.2834048867226, + 612.2834050059319, + 613.2834051251411, + 614.2834052443504, + 615.2834053635597, + 616.283405482769, + 617.2834056019783, + 618.2834057211876, + 619.2834058403969, + 620.2834059596062, + 621.2834060788155, + 622.2834061980247, + 623.283406317234, + 624.2834064364433, + 625.2834065556526, + 626.2834066748619, + 627.2834067940712, + 628.2834069132805, + 629.2834070324898, + 630.2834071516991, + 631.2834072709084, + 632.2834073901176, + 633.2834075093269, + 634.2834076285362, + 635.2834077477455, + 636.2834078669548, + 637.2834079861641, + 639.2834082245827, + 640.283408343792, + 641.2834084630013, + 642.2834085822105, + 643.2834087014198, + 644.2834088206291, + 645.2834089398384, + 646.2834090590477, + 647.283409178257, + 648.2834092974663, + 649.2834094166756, + 650.2834095358849, + 651.2834096550941, + 652.2833945155144, + 653.2833946347237, + 654.283394753933, + 655.2833948731422, + 656.2833949923515, + 657.2833951115608, + 658.2833952307701, + 659.2833953499794, + 660.2833954691887, + 661.283395588398, + 662.2833957076073, + 663.2833958268166, + 664.2833959460258, + 665.2833960652351, + 666.2833961844444, + 667.2833963036537, + 668.283396422863, + 669.2833965420723, + 670.2833966612816, + 671.2833967804909, + 672.2833968997002, + 673.2833970189095, + 674.2833971381187, + 675.283397257328, + 676.2833973765373, + 677.2833974957466, + 678.2833976149559, + 679.2833977341652, + 680.2833978533745, + 681.2833979725838, + 682.2834057211876, + 683.2834058403969, + 684.2834059596062, + 685.2834060788155, + 686.2834061980247, + 687.283406317234, + 688.2834064364433, + 689.2834065556526, + 690.2834066748619, + 691.2834067940712, + 692.2834069132805, + 693.2834070324898, + 694.2834071516991, + 695.2834072709084, + 696.2834073901176, + 697.2834075093269, + 698.2834076285362, + 699.2834077477455, + 700.2834078669548, + 701.2834079861641, + 702.2834081053734, + 703.2834082245827, + 704.283408343792, + 705.2834084630013, + 706.2834085822105, + 707.2834087014198, + 708.2834088206291, + 709.2834089398384, + 710.2834090590477, + 711.283409178257, + 712.2834016680717, + 713.283401787281, + 714.2834019064903, + 715.2834020256996, + 716.2834021449089, + 717.2834022641182, + 718.2834023833275, + 719.2834025025368, + 720.2834026217461, + 721.2834027409554, + 722.2815870046616, + 723.2815870046616, + 724.2815870046616, + 725.2815870046616, + 726.2815870046616, + 727.2815870046616, + 728.2815870046616, + 729.2815870046616, + 730.2815870046616, + 731.2815870046616, + 732.2815870046616, + 733.2815870046616, + 734.2815870046616, + 735.2815870046616, + 736.2815870046616, + 737.2815870046616, + 738.2815870046616, + 739.2815870046616, + 740.2815870046616, + 741.2815870046616, + 742.2815870046616, + 743.2815870046616, + 744.2815870046616, + 745.2815870046616, + 746.2815870046616, + 747.2815870046616, + 748.2815870046616, + 749.2815870046616, + 750.2815870046616, + 751.2815870046616, + 752.2815870046616, + 753.2815870046616, + 754.2815870046616, + 755.2815870046616, + 756.2815870046616, + 757.2815870046616, + 758.2815870046616, + 759.2815870046616, + 760.2815870046616 + ], + "_percentage_route_completed": 100, + "terminate_on_failure": false + }, + "CollisionTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "FAILURE", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 5, + "optional": false, + "_collision_sensor": null, + "other_actor": null, + "other_actor_type": null, + "registered_collisions": [], + "last_id": null, + "collision_time": 70.1000010445714, + "terminate_on_failure": false + }, + "InRouteTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": true, + "test_status": "SUCCESS", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 0, + "optional": false, + "list_traffic_events": [], + "_offroad_max": 30, + "_offroad_min": 15.0, + "_route_length": 762, + "_current_index": 760, + "_out_route_distance": 0, + "_in_safe_route": true, + "_accum_meters": [ + 0.0, + 1.1180341243743896, + 2.118034243583679, + 3.1180343627929688, + 4.118034482002258, + 5.118034601211548, + 6.118034720420837, + 7.118034839630127, + 8.118034958839417, + 9.118035078048706, + 10.118035197257996, + 11.118035316467285, + 12.118035435676575, + 13.118035554885864, + 14.118035674095154, + 15.118035793304443, + 16.118035912513733, + 17.408029437065125, + 17.408029437065125, + 18.408029556274414, + 19.408029675483704, + 20.408029794692993, + 21.408029913902283, + 22.60914123058319, + 23.882590174674988, + 25.156023859977722, + 26.42948305606842, + 27.702926516532898, + 28.976354002952576, + 30.22618818283081, + 31.444236278533936, + 32.66231644153595, + 33.88036382198334, + 35.098384618759155, + 36.31645858287811, + 37.5344922542572, + 38.54053473472595, + 40.18173956871033, + 40.18173956871033, + 41.18173956871033, + 42.18173956871033, + 44.18173956871033, + 45.18173956871033, + 46.18173956871033, + 47.18173956871033, + 48.18173956871033, + 49.18173956871033, + 50.18173956871033, + 51.18173956871033, + 52.18173956871033, + 53.18173956871033, + 54.18173956871033, + 55.18173956871033, + 56.18173956871033, + 57.18173956871033, + 58.18173956871033, + 59.18173956871033, + 60.18173956871033, + 61.18173956871033, + 62.18173956871033, + 63.18173956871033, + 64.18173956871033, + 65.18173956871033, + 66.18173956871033, + 67.18173956871033, + 68.18173956871033, + 69.18173956871033, + 70.18173956871033, + 71.18173956871033, + 72.18173956871033, + 73.18173956871033, + 74.18173956871033, + 75.18173956871033, + 76.18173956871033, + 77.18173956871033, + 78.18173956871033, + 79.18173956871033, + 80.18173956871033, + 81.18173956871033, + 82.18173956871033, + 83.18173956871033, + 84.18173956871033, + 85.18173956871033, + 86.18173956871033, + 87.18173956871033, + 88.18173956871033, + 89.18173956871033, + 90.18173956871033, + 91.18173956871033, + 92.18173956871033, + 93.18173956871033, + 94.18173956871033, + 95.18173956871033, + 96.18173956871033, + 97.18173956871033, + 98.18173956871033, + 99.18173956871033, + 100.18173956871033, + 101.18173956871033, + 102.18173956871033, + 103.18173956871033, + 104.18173956871033, + 105.18173956871033, + 106.18173956871033, + 107.18173956871033, + 108.18173956871033, + 109.18173956871033, + 110.1817090511322, + 111.1817090511322, + 112.1817090511322, + 113.1817090511322, + 114.1817090511322, + 115.1817090511322, + 116.1817090511322, + 117.1817090511322, + 118.1817090511322, + 119.1817090511322, + 120.1817090511322, + 121.1817090511322, + 122.1817090511322, + 123.1817090511322, + 124.1817090511322, + 125.1817090511322, + 126.1817090511322, + 127.1817090511322, + 128.1817090511322, + 129.1817090511322, + 130.1817090511322, + 131.1817090511322, + 132.1817090511322, + 133.1817090511322, + 134.1817090511322, + 135.1817090511322, + 136.1817090511322, + 137.1817090511322, + 138.1817090511322, + 139.1817090511322, + 140.1817090511322, + 141.1817090511322, + 142.1817090511322, + 143.1817090511322, + 144.1817090511322, + 145.1817090511322, + 146.1817090511322, + 147.1817090511322, + 148.1817090511322, + 149.1817090511322, + 150.1817090511322, + 151.1817090511322, + 152.1817090511322, + 153.1817090511322, + 154.1817090511322, + 155.1817090511322, + 156.1817090511322, + 157.1817090511322, + 158.1817090511322, + 159.1817090511322, + 160.1817090511322, + 161.1817090511322, + 162.1817090511322, + 163.1817090511322, + 164.1817090511322, + 165.1817090511322, + 166.1817090511322, + 167.1817090511322, + 168.1817090511322, + 169.1817090511322, + 170.1817090511322, + 171.1817090511322, + 172.1817090511322, + 173.1817090511322, + 174.1817090511322, + 175.1817090511322, + 176.1817090511322, + 177.1817090511322, + 178.1817090511322, + 179.1817090511322, + 180.1817090511322, + 181.1817090511322, + 182.1817090511322, + 183.1817090511322, + 184.1817090511322, + 185.1817090511322, + 186.1817090511322, + 187.1817090511322, + 188.1817090511322, + 189.1817090511322, + 190.1817090511322, + 191.1817090511322, + 192.1817090511322, + 193.1817090511322, + 194.1817090511322, + 195.1817090511322, + 196.1817090511322, + 197.1817090511322, + 198.1817090511322, + 199.1817090511322, + 200.1817090511322, + 201.1817090511322, + 202.1817090511322, + 203.1817090511322, + 204.1817090511322, + 205.1817090511322, + 206.1817090511322, + 207.1817090511322, + 208.1817090511322, + 209.1817090511322, + 210.1817090511322, + 211.1817090511322, + 212.1817090511322, + 213.1817090511322, + 214.1817090511322, + 215.1817090511322, + 216.1817090511322, + 217.1817090511322, + 218.1817090511322, + 219.1817090511322, + 220.1817090511322, + 221.1817090511322, + 222.1817090511322, + 223.1817090511322, + 224.1817090511322, + 225.1817090511322, + 226.1817090511322, + 227.1817090511322, + 228.1817090511322, + 229.1817090511322, + 230.1817090511322, + 231.1817090511322, + 232.1817090511322, + 233.1817090511322, + 234.1817090511322, + 235.1817090511322, + 236.1817090511322, + 237.1817090511322, + 238.18171668052673, + 239.18171668052673, + 240.18171668052673, + 241.18171668052673, + 242.18171668052673, + 243.18171668052673, + 244.18171668052673, + 245.18171668052673, + 246.18171668052673, + 247.18171668052673, + 248.18171668052673, + 249.18171668052673, + 250.18171668052673, + 251.18171668052673, + 252.18171668052673, + 253.18171668052673, + 254.18171668052673, + 255.18171668052673, + 256.18171668052673, + 258.18171668052673, + 259.18171668052673, + 260.18171668052673, + 261.18171668052673, + 262.18171668052673, + 263.18171668052673, + 264.43171668052673, + 264.43171668052673, + 265.43171668052673, + 266.4848858118057, + 267.6947091817856, + 268.9045317173004, + 270.11435973644257, + 271.3241786956787, + 272.53399670124054, + 273.74381709098816, + 274.95476615428925, + 276.1825375556946, + 277.41030740737915, + 278.6380902528763, + 279.86586582660675, + 281.093638420105, + 282.32140839099884, + 283.54918599128723, + 284.56516194343567, + 285.86318135261536, + 285.86318135261536, + 286.86318135261536, + 287.86318135261536, + 288.86318135261536, + 289.86318135261536, + 290.86318135261536, + 291.86318135261536, + 292.86318135261536, + 293.86318135261536, + 294.86318135261536, + 295.86318135261536, + 296.86318135261536, + 297.86318135261536, + 298.86318135261536, + 299.86318135261536, + 300.86318135261536, + 301.86318135261536, + 302.86318135261536, + 303.86318135261536, + 304.86318135261536, + 305.86318135261536, + 306.86318135261536, + 307.86318135261536, + 308.86318135261536, + 309.86318135261536, + 310.86318135261536, + 311.86318135261536, + 312.86318135261536, + 313.86318135261536, + 314.86318135261536, + 315.86318135261536, + 316.86318135261536, + 317.86318135261536, + 318.86318135261536, + 319.86318135261536, + 320.86318135261536, + 321.86318135261536, + 322.86318135261536, + 323.86318135261536, + 324.86318135261536, + 325.86318135261536, + 326.86318135261536, + 327.86318135261536, + 328.86318135261536, + 329.86318135261536, + 330.86318135261536, + 331.86318135261536, + 332.86318135261536, + 333.8631966114044, + 334.8631966114044, + 335.8631966114044, + 336.8631966114044, + 337.8631966114044, + 338.8631966114044, + 339.8631966114044, + 340.8631966114044, + 341.8631966114044, + 342.8631966114044, + 343.8631966114044, + 344.8631966114044, + 345.8631966114044, + 346.8631966114044, + 347.8631966114044, + 348.8631966114044, + 349.8631966114044, + 350.8631966114044, + 351.8631966114044, + 352.8631966114044, + 353.8631966114044, + 354.8631966114044, + 355.8631966114044, + 356.8631966114044, + 357.8631966114044, + 358.8631966114044, + 359.8631966114044, + 360.8631966114044, + 361.8631966114044, + 362.8631966114044, + 363.8631966114044, + 364.8631966114044, + 365.8631966114044, + 366.8631966114044, + 367.8631966114044, + 368.8631966114044, + 369.8631966114044, + 370.8631966114044, + 371.8631966114044, + 372.8631966114044, + 373.8631966114044, + 374.8631966114044, + 375.8631966114044, + 376.8631966114044, + 377.8631966114044, + 378.8631966114044, + 379.8631966114044, + 380.8631966114044, + 381.8631966114044, + 382.8631966114044, + 383.8631966114044, + 384.8631966114044, + 385.8631966114044, + 386.8631966114044, + 387.8631966114044, + 388.8631966114044, + 389.8631966114044, + 390.8631966114044, + 391.8631966114044, + 392.8631966114044, + 394.8331673145294, + 394.8331673145294, + 395.6912509202957, + 396.5167629122734, + 397.34227895736694, + 398.1678013205528, + 398.9933475255966, + 399.81885331869125, + 400.6444185972214, + 401.4699310064316, + 402.290342271328, + 403.09512996673584, + 403.8999582529068, + 404.70476245880127, + 405.509556889534, + 406.314362347126, + 407.1191706061363, + 407.92396891117096, + 409.09423565864563, + 409.09423565864563, + 410.0942357778549, + 411.0942358970642, + 412.0942360162735, + 413.0942361354828, + 414.0942362546921, + 415.09423637390137, + 416.09423649311066, + 417.09423661231995, + 418.09423673152924, + 419.0942368507385, + 420.0942369699478, + 421.0942370891571, + 422.0942372083664, + 423.0942373275757, + 424.094237446785, + 425.094233751297, + 426.0942338705063, + 427.0942339897156, + 428.09423410892487, + 429.09423422813416, + 430.09423434734344, + 431.09423446655273, + 432.094234585762, + 433.0942347049713, + 434.0942348241806, + 435.0942349433899, + 436.0942350625992, + 437.0942351818085, + 438.09423530101776, + 439.09423542022705, + 440.09423553943634, + 441.09423565864563, + 442.0942357778549, + 443.0942358970642, + 444.0942360162735, + 445.0942361354828, + 446.0942362546921, + 447.0942325592041, + 448.0942326784134, + 449.0942327976227, + 450.09423291683197, + 451.09423303604126, + 452.09423315525055, + 453.0942294597626, + 454.09422957897186, + 455.09422969818115, + 456.09422981739044, + 457.09423184394836, + 458.09423196315765, + 459.09423208236694, + 460.09423220157623, + 461.0942323207855, + 462.0942324399948, + 463.09423065185547, + 464.09423077106476, + 465.09423089027405, + 466.09423100948334, + 467.0942311286926, + 468.0942312479019, + 469.0942313671112, + 470.0942314863205, + 471.0942316055298, + 472.0942317247391, + 473.0942327976227, + 474.09423291683197, + 475.09423303604126, + 476.09423315525055, + 477.0942323207855, + 478.724232673645, + 478.724232673645, + 479.64406257867813, + 480.41382187604904, + 481.18358182907104, + 481.9533463716507, + 482.7230935692787, + 483.4928572177887, + 484.2626251578331, + 485.03238236904144, + 485.8388220667839, + 486.66605401039124, + 487.49329620599747, + 488.3205181956291, + 489.1477633714676, + 489.9749982357025, + 490.802244246006, + 492.28208762407303, + 492.28208762407303, + 493.28208762407303, + 494.28208762407303, + 495.28208762407303, + 496.28208762407303, + 497.28208762407303, + 498.28208762407303, + 499.28208762407303, + 500.28208762407303, + 501.28208762407303, + 502.28208762407303, + 503.28208762407303, + 504.28208762407303, + 505.28208762407303, + 506.28208762407303, + 507.28208762407303, + 508.28208762407303, + 509.28208762407303, + 510.28208762407303, + 511.28208762407303, + 512.282087624073, + 513.282087624073, + 514.282087624073, + 515.282087624073, + 516.282087624073, + 517.282087624073, + 518.282087624073, + 519.282087624073, + 520.282087624073, + 521.282087624073, + 522.282087624073, + 523.282087624073, + 524.282087624073, + 525.282087624073, + 526.282087624073, + 527.282087624073, + 528.282087624073, + 529.282087624073, + 530.282087624073, + 531.282087624073, + 532.282087624073, + 533.282087624073, + 534.282087624073, + 535.282087624073, + 536.282087624073, + 537.282087624073, + 538.282087624073, + 539.282087624073, + 540.282087624073, + 541.282087624073, + 542.282087624073, + 543.282087624073, + 544.282087624073, + 545.282087624073, + 546.282087624073, + 547.282087624073, + 548.282087624073, + 549.282087624073, + 550.282087624073, + 551.282087624073, + 552.282087624073, + 553.282087624073, + 554.2821028828621, + 555.2821028828621, + 556.2821028828621, + 557.2821028828621, + 558.2821028828621, + 559.2821028828621, + 560.2821028828621, + 561.2821028828621, + 562.2821028828621, + 563.2821028828621, + 564.2821028828621, + 565.2821028828621, + 566.2821028828621, + 567.2821028828621, + 568.2821028828621, + 569.2833998799324, + 570.2833999991417, + 571.283400118351, + 572.2834002375603, + 573.2834003567696, + 574.2834004759789, + 575.2834005951881, + 576.2834007143974, + 577.2834008336067, + 578.283400952816, + 579.2834010720253, + 580.2834011912346, + 581.2834013104439, + 582.2834014296532, + 583.2834015488625, + 584.2834016680717, + 585.283401787281, + 586.2834019064903, + 587.2834020256996, + 588.2834021449089, + 589.2834022641182, + 590.2834023833275, + 591.2834025025368, + 592.2834026217461, + 593.2834027409554, + 594.2834028601646, + 595.2834029793739, + 596.2834030985832, + 597.2834032177925, + 598.2834033370018, + 599.2834034562111, + 600.2834035754204, + 601.2834036946297, + 602.283403813839, + 603.2834039330482, + 604.2834040522575, + 605.2834041714668, + 606.2834042906761, + 607.2834044098854, + 608.2834045290947, + 609.283404648304, + 610.2834047675133, + 611.2834048867226, + 612.2834050059319, + 613.2834051251411, + 614.2834052443504, + 615.2834053635597, + 616.283405482769, + 617.2834056019783, + 618.2834057211876, + 619.2834058403969, + 620.2834059596062, + 621.2834060788155, + 622.2834061980247, + 623.283406317234, + 624.2834064364433, + 625.2834065556526, + 626.2834066748619, + 627.2834067940712, + 628.2834069132805, + 629.2834070324898, + 630.2834071516991, + 631.2834072709084, + 632.2834073901176, + 633.2834075093269, + 634.2834076285362, + 635.2834077477455, + 636.2834078669548, + 637.2834079861641, + 639.2834082245827, + 640.283408343792, + 641.2834084630013, + 642.2834085822105, + 643.2834087014198, + 644.2834088206291, + 645.2834089398384, + 646.2834090590477, + 647.283409178257, + 648.2834092974663, + 649.2834094166756, + 650.2834095358849, + 651.2834096550941, + 652.2833945155144, + 653.2833946347237, + 654.283394753933, + 655.2833948731422, + 656.2833949923515, + 657.2833951115608, + 658.2833952307701, + 659.2833953499794, + 660.2833954691887, + 661.283395588398, + 662.2833957076073, + 663.2833958268166, + 664.2833959460258, + 665.2833960652351, + 666.2833961844444, + 667.2833963036537, + 668.283396422863, + 669.2833965420723, + 670.2833966612816, + 671.2833967804909, + 672.2833968997002, + 673.2833970189095, + 674.2833971381187, + 675.283397257328, + 676.2833973765373, + 677.2833974957466, + 678.2833976149559, + 679.2833977341652, + 680.2833978533745, + 681.2833979725838, + 682.2834057211876, + 683.2834058403969, + 684.2834059596062, + 685.2834060788155, + 686.2834061980247, + 687.283406317234, + 688.2834064364433, + 689.2834065556526, + 690.2834066748619, + 691.2834067940712, + 692.2834069132805, + 693.2834070324898, + 694.2834071516991, + 695.2834072709084, + 696.2834073901176, + 697.2834075093269, + 698.2834076285362, + 699.2834077477455, + 700.2834078669548, + 701.2834079861641, + 702.2834081053734, + 703.2834082245827, + 704.283408343792, + 705.2834084630013, + 706.2834085822105, + 707.2834087014198, + 708.2834088206291, + 709.2834089398384, + 710.2834090590477, + 711.283409178257, + 712.2834016680717, + 713.283401787281, + 714.2834019064903, + 715.2834020256996, + 716.2834021449089, + 717.2834022641182, + 718.2834023833275, + 719.2834025025368, + 720.2834026217461, + 721.2834027409554, + 722.2815870046616, + 723.2815870046616, + 724.2815870046616, + 725.2815870046616, + 726.2815870046616, + 727.2815870046616, + 728.2815870046616, + 729.2815870046616, + 730.2815870046616, + 731.2815870046616, + 732.2815870046616, + 733.2815870046616, + 734.2815870046616, + 735.2815870046616, + 736.2815870046616, + 737.2815870046616, + 738.2815870046616, + 739.2815870046616, + 740.2815870046616, + 741.2815870046616, + 742.2815870046616, + 743.2815870046616, + 744.2815870046616, + 745.2815870046616, + 746.2815870046616, + 747.2815870046616, + 748.2815870046616, + 749.2815870046616, + 750.2815870046616, + 751.2815870046616, + 752.2815870046616, + 753.2815870046616, + 754.2815870046616, + 755.2815870046616, + 756.2815870046616, + 757.2815870046616, + 758.2815870046616, + 759.2815870046616, + 760.2815870046616 + ], + "terminate_on_failure": false + }, + "OutsideRouteLanesTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "FAILURE", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 35.22, + "optional": false, + "_current_index": 760, + "_route_length": 762, + "_outside_lane_active": true, + "_wrong_lane_active": true, + "_last_road_id": 15, + "_last_lane_id": -1, + "_total_distance": 759.2815870046616, + "_wrong_distance": 0, + "terminate_on_failure": false + }, + "RunningRedLightTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "FAILURE", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 3, + "optional": false, + "_last_red_light_id": 288, + "debug": false, + "terminate_on_failure": false + }, + "RunningStopTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "SUCCESS", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 0, + "optional": false, + "list_traffic_events": [], + "_list_stop_signs": [], + "_target_stop_sign": null, + "_stop_completed": false, + "_affected_by_stop": false, + "terminate_on_failure": false + }, + "ActorSpeedAboveThresholdTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": true, + "test_status": "SUCCESS", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 0, + "optional": false, + "list_traffic_events": [], + "_speed_threshold": 0.1, + "_below_threshold_max_time": 90.0, + "_time_last_valid_state": 70.80000105500221, + "terminate_on_failure": false + } +} \ No newline at end of file diff --git a/scenario_runner/srunner/metrics/data/DistanceBetweenVehicles_criteria.json b/scenario_runner/srunner/metrics/data/DistanceBetweenVehicles_criteria.json new file mode 100644 index 0000000..ee0423d --- /dev/null +++ b/scenario_runner/srunner/metrics/data/DistanceBetweenVehicles_criteria.json @@ -0,0 +1,21 @@ +{ + "CollisionTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "SUCCESS", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 0, + "optional": false, + "list_traffic_events": [], + "_collision_sensor": null, + "other_actor": null, + "other_actor_type": null, + "registered_collisions": [], + "last_id": null, + "collision_time": null, + "terminate_on_failure": false + } +} \ No newline at end of file diff --git a/scenario_runner/srunner/metrics/data/DistanceToLaneCenter_criteria.json b/scenario_runner/srunner/metrics/data/DistanceToLaneCenter_criteria.json new file mode 100644 index 0000000..ee0423d --- /dev/null +++ b/scenario_runner/srunner/metrics/data/DistanceToLaneCenter_criteria.json @@ -0,0 +1,21 @@ +{ + "CollisionTest": { + "children": [], + "feedback_message": "", + "blackbox_level": 4, + "_terminate_on_failure": false, + "test_status": "SUCCESS", + "expected_value_success": 0, + "expected_value_acceptable": null, + "actual_value": 0, + "optional": false, + "list_traffic_events": [], + "_collision_sensor": null, + "other_actor": null, + "other_actor_type": null, + "registered_collisions": [], + "last_id": null, + "collision_time": null, + "terminate_on_failure": false + } +} \ No newline at end of file diff --git a/scenario_runner/srunner/metrics/examples/basic_metric.py b/scenario_runner/srunner/metrics/examples/basic_metric.py new file mode 100644 index 0000000..331f48e --- /dev/null +++ b/scenario_runner/srunner/metrics/examples/basic_metric.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +This module provide BasicMetric, the basic class of all the metrics. +""" + +class BasicMetric(object): + """ + Base class of all the metrics. + """ + + def __init__(self, town_map, log, criteria=None): + """ + Initialization of the metric class. This calls the metrics log and creates the metrics + + Args: + town_map (carla.Map): Map of the simulation. Used to access the Waypoint API. + log (srunner.metrics.tools.Metricslog): instance of a class used to access the recorder information + criteria (dict): list of dictionaries with all the criteria information + """ + + # Create the metrics of the simulation. This part is left to the user + self._create_metric(town_map, log, criteria) + + def _create_metric(self, town_map, log, criteria): + """ + Pure virtual function to setup the metrics by the user. + + Args: + town_map (carla.Map): Map of the simulation. Used to access the Waypoint API. + log (srunner.metrics.tools.Metricslog): instance of a class used to access the recorder information + criteria (dict): dictionaries with all the criteria information + """ + raise NotImplementedError( + "This function should be re-implemented by all metrics" + "If this error becomes visible the class hierarchy is somehow broken") diff --git a/scenario_runner/srunner/metrics/examples/criteria_filter.py b/scenario_runner/srunner/metrics/examples/criteria_filter.py new file mode 100644 index 0000000..78938f7 --- /dev/null +++ b/scenario_runner/srunner/metrics/examples/criteria_filter.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +This metric filters the useful information of the criteria (sucess / fail ...), +and dump it into a json file + +It is meant to serve as an example of how to use the criteria +""" + +import json + +from srunner.metrics.examples.basic_metric import BasicMetric + + +class CriteriaFilter(BasicMetric): + """ + Metric class CriteriaFilter + """ + + def _create_metric(self, town_map, log, criteria): + """ + Implementation of the metric. This is an example to show how to use the criteria + """ + + ### Parse the criteria information, filtering only the useful information, and dump it into a json ### + + results = {} + for criterion_name in criteria: + criterion = criteria[criterion_name] + results.update({criterion_name: + { + "test_status": criterion["test_status"], + "actual_value": criterion["actual_value"], + "success_value": criterion["expected_value_success"] + } + } + ) + + with open('srunner/metrics/data/CriteriaFilter_results.json', 'w') as fw: + json.dump(results, fw, sort_keys=False, indent=4) diff --git a/scenario_runner/srunner/metrics/examples/distance_between_vehicles.py b/scenario_runner/srunner/metrics/examples/distance_between_vehicles.py new file mode 100644 index 0000000..5716c8f --- /dev/null +++ b/scenario_runner/srunner/metrics/examples/distance_between_vehicles.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +This metric calculates the distance between the ego vehicle and +another actor, dumping it to a json file. + +It is meant to serve as an example of how to use the information from +the recorder +""" + +import math +import matplotlib.pyplot as plt + +from srunner.metrics.examples.basic_metric import BasicMetric + + +class DistanceBetweenVehicles(BasicMetric): + """ + Metric class DistanceBetweenVehicles + """ + + def _create_metric(self, town_map, log, criteria): + """ + Implementation of the metric. This is an example to show how to use the recorder, + accessed via the log. + """ + + # Get the ID of the two vehicles + ego_id = log.get_ego_vehicle_id() + adv_id = log.get_actor_ids_with_role_name("scenario")[0] # Could have also used its type_id + + dist_list = [] + frames_list = [] + + # Get the frames both actors were alive + start_ego, end_ego = log.get_actor_alive_frames(ego_id) + start_adv, end_adv = log.get_actor_alive_frames(adv_id) + start = max(start_ego, start_adv) + end = min(end_ego, end_adv) + + # Get the distance between the two + for i in range(start, end): + + # Get the transforms + ego_location = log.get_actor_transform(ego_id, i).location + adv_location = log.get_actor_transform(adv_id, i).location + + # Filter some points for a better graph + if adv_location.z < -10: + continue + + dist_v = ego_location - adv_location + dist = math.sqrt(dist_v.x * dist_v.x + dist_v.y * dist_v.y + dist_v.z * dist_v.z) + + dist_list.append(dist) + frames_list.append(i) + + # Use matplotlib to show the results + plt.plot(frames_list, dist_list) + plt.ylabel('Distance [m]') + plt.xlabel('Frame number') + plt.title('Distance between the ego vehicle and the adversary over time') + plt.show() diff --git a/scenario_runner/srunner/metrics/examples/distance_to_lane_center.py b/scenario_runner/srunner/metrics/examples/distance_to_lane_center.py new file mode 100644 index 0000000..3916096 --- /dev/null +++ b/scenario_runner/srunner/metrics/examples/distance_to_lane_center.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +This metric calculates the distance between the ego vehicle and +the center of the lane, dumping it to a json file. + +It is meant to serve as an example of how to use the map API +""" + +import math +import json + +from srunner.metrics.examples.basic_metric import BasicMetric + + +class DistanceToLaneCenter(BasicMetric): + """ + Metric class DistanceToLaneCenter + """ + + def _create_metric(self, town_map, log, criteria): + """ + Implementation of the metric. + """ + + # Get ego vehicle id + ego_id = log.get_ego_vehicle_id() + + dist_list = [] + frames_list = [] + + # Get the frames the ego actor was alive and its transforms + start, end = log.get_actor_alive_frames(ego_id) + + # Get the projected distance vector to the center of the lane + for i in range(start, end + 1): + + ego_location = log.get_actor_transform(ego_id, i).location + ego_waypoint = town_map.get_waypoint(ego_location) + + # Get the distance vector and project it + a = ego_location - ego_waypoint.transform.location # Ego to waypoint vector + b = ego_waypoint.transform.get_right_vector() # Waypoint perpendicular vector + b_norm = math.sqrt(b.x * b.x + b.y * b.y + b.z * b.z) + + ab_dot = a.x * b.x + a.y * b.y + a.z * b.z + dist_v = ab_dot/(b_norm*b_norm)*b + dist = math.sqrt(dist_v.x * dist_v.x + dist_v.y * dist_v.y + dist_v.z * dist_v.z) + + # Get the sign of the distance (left side is positive) + c = ego_waypoint.transform.get_forward_vector() # Waypoint forward vector + ac_cross = c.x * a.y - c.y * a.x + if ac_cross < 0: + dist *= -1 + + dist_list.append(dist) + frames_list.append(i) + + # Save the results to a file + results = {'frames': frames_list, 'distance': dist_list} + with open('srunner/metrics/data/DistanceToLaneCenter_results.json', 'w') as fw: + json.dump(results, fw, sort_keys=False, indent=4) diff --git a/scenario_runner/srunner/metrics/tools/metrics_log.py b/scenario_runner/srunner/metrics/tools/metrics_log.py new file mode 100644 index 0000000..4dce1e5 --- /dev/null +++ b/scenario_runner/srunner/metrics/tools/metrics_log.py @@ -0,0 +1,428 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +Support class of the MetricsManager to query the information available +to the metrics. + +It also provides a series of functions to help the user querry +specific information +""" + +import fnmatch +from srunner.metrics.tools.metrics_parser import MetricsParser + +class MetricsLog(object): # pylint: disable=too-many-public-methods + """ + Utility class to query the log. + """ + + def __init__(self, recorder): + """ + Initializes the log class and parses it to extract the dictionaries. + """ + # Parse the information + parser = MetricsParser(recorder) + self._simulation, self._actors, self._frames = parser.parse_recorder_info() + + ### Functions used to get general info of the simulation ### + def get_actor_collisions(self, actor_id): + """ + Returns a dict where the keys are the frame number and the values, + a list of actor ids the actor collided with. + + Args: + actor_id (int): ID of the actor. + """ + actor_collisions = {} + + for i, frame in enumerate(self._frames): + collisions = frame["events"]["collisions"] + + if actor_id in collisions: + actor_collisions.update({i: collisions[actor_id]}) + + return actor_collisions + + def get_total_frame_count(self): + """ + Returns an int with the total amount of frames the simulation lasted. + """ + + return self._simulation["total_frames"] + + def get_elapsed_time(self, frame): + """ + Returns a float with the elapsed time of a specific frame. + """ + + return self._frames[frame]["frame"]["elapsed_time"] + + def get_delta_time(self, frame): + """ + Returns a float with the delta time of a specific frame. + """ + + return self._frames[frame]["frame"]["delta_time"] + + def get_platform_time(self, frame): + """ + Returns a float with the platform time time of a specific frame. + """ + + return self._frames[frame]["frame"]["platform_time"] + + ### Functions used to get info about the actors ### + def get_ego_vehicle_id(self): + """ + Returns the id of the ego vehicle. + """ + return self.get_actor_ids_with_role_name("hero")[0] + + def get_actor_ids_with_role_name(self, role_name): + """ + Returns a list of actor ids that match the given role_name. + + Args: + role_name (str): string with the desired role_name to filter the actors. + """ + actor_list = [] + + for actor_id in self._actors: + actor = self._actors[actor_id] + if "role_name" in actor and actor["role_name"] == role_name: + actor_list.append(actor_id) + + return actor_list + + def get_actor_ids_with_type_id(self, type_id): + """ + Returns a list of actor ids that match the given type_id, matching fnmatch standard. + + Args: + type_id (str): string with the desired type id to filter the actors. + """ + actor_list = [] + + for actor_id in self._actors: + actor = self._actors[actor_id] + if "type_id" in actor and fnmatch.fnmatch(actor["type_id"], type_id): + actor_list.append(actor_id) + + return actor_list + + def get_actor_attributes(self, actor_id): + """ + Returns a dictionary with all the attributes of an actor. + + Args: + actor_id (int): ID of the actor. + """ + if actor_id in self._actors: + return self._actors[actor_id] + + return None + + def get_actor_bounding_box(self, actor_id): + """ + Returns the bounding box of the specified actor + + Args: + actor_id (int): Id of the actor + """ + + if actor_id in self._actors: + if "bounding_box" in self._actors[actor_id]: + return self._actors[actor_id]["bounding_box"] + return None + + return None + + def get_traffic_light_trigger_volume(self, traffic_light_id): + """ + Returns the trigger volume of the specified traffic light + + Args: + actor_id (int): Id of the traffic light + """ + + if traffic_light_id in self._actors: + if "trigger_volume" in self._actors[traffic_light_id]: + return self._actors[traffic_light_id]["trigger_volume"] + return None + + return None + + def get_actor_alive_frames(self, actor_id): + """ + Returns a tuple with the first and last frame an actor was alive. + It is important to note that frames start at 1, not 0. + + Args: + actor_id (int): Id of the actor + """ + + if actor_id in self._actors: + + actor_info = self._actors[actor_id] + first_frame = actor_info["created"] + if "destroyed" in actor_info: + last_frame = actor_info["destroyed"] - 1 + else: + last_frame = self.get_total_frame_count() + + return first_frame, last_frame + + return None, None + + ### Functions used to get the actor states ### + def _get_actor_state(self, actor_id, state, frame): + """ + Given an actor id, returns the specific variable of that actor at a given frame. + Returns None if the actor_id or the state are missing. + + Args: + actor_id (int): Id of the actor to be checked. + frame: (int): frame number of the simulation. + attribute (str): name of the actor's attribute to be returned. + """ + frame_state = self._frames[frame - 1]["actors"] + + # Check if the actor exists + if actor_id in frame_state: + + # Check if the state exists + if state not in frame_state[actor_id]: + return None + + state_info = frame_state[actor_id][state] + return state_info + + return None + + def _get_all_actor_states(self, actor_id, state, first_frame=None, last_frame=None): + """ + Given an actor id, returns a list of the specific variable of that actor during + a frame interval. Some elements might be None. + + By default, first_frame and last_frame are the start and end of the simulation, respectively. + + Args: + actor_id (int): ID of the actor. + attribute: name of the actor's attribute to be returned. + first_frame (int): First frame checked. By default, 0. + last_frame (int): Last frame checked. By default, max number of frames. + """ + if first_frame is None: + first_frame = 1 + if last_frame is None: + last_frame = self.get_total_frame_count() + + state_list = [] + + for frame_number in range(first_frame, last_frame + 1): + state_info = self._get_actor_state(actor_id, state, frame_number) + state_list.append(state_info) + + return state_list + + def _get_states_at_frame(self, frame, state, actor_list=None): + """ + Returns a dict where the keys are the frame number, and the values are the + carla.Transform of the actor at the given frame. + + By default, all actors will be considered. + """ + states = {} + actor_info = self._frames[frame]["actors"] + + for actor_id in actor_info: + if not actor_list: + _state = self._get_actor_state(actor_id, state, frame) + if _state: + states.update({actor_id: _state}) + elif actor_id in actor_list: + _state = self._get_actor_state(actor_id, state, frame) + states.update({actor_id: _state}) + + return states + + # Transforms + def get_actor_transform(self, actor_id, frame): + """ + Returns the transform of the actor at a given frame. + """ + return self._get_actor_state(actor_id, "transform", frame) + + def get_all_actor_transforms(self, actor_id, first_frame=None, last_frame=None): + """ + Returns a list with all the transforms of the actor at the frame interval. + """ + return self._get_all_actor_states(actor_id, "transform", first_frame, last_frame) + + def get_actor_transforms_at_frame(self, frame, actor_list=None): + """ + Returns a dictionary {int - carla.Transform} with the actor ID and transform + at a given frame of all the actors at actor_list. + """ + return self._get_states_at_frame(frame, "transform", actor_list) + + # Velocities + def get_actor_velocity(self, actor_id, frame): + """ + Returns the velocity of the actor at a given frame. + """ + return self._get_actor_state(actor_id, "velocity", frame) + + def get_all_actor_velocities(self, actor_id, first_frame=None, last_frame=None): + """ + Returns a list with all the velocities of the actor at the frame interval. + """ + return self._get_all_actor_states(actor_id, "velocity", first_frame, last_frame) + + def get_actor_velocities_at_frame(self, frame, actor_list=None): + """ + Returns a dictionary {int - carla.Vector3D} with the actor ID and velocity + at a given frame of all the actors at actor_list. + """ + return self._get_states_at_frame(frame, "velocity", actor_list) + + # Angular velocities + def get_actor_angular_velocity(self, actor_id, frame): + """ + Returns the angular velocity of the actor at a given frame. + """ + return self._get_actor_state(actor_id, "angular_velocity", frame) + + def get_all_actor_angular_velocities(self, actor_id, first_frame=None, last_frame=None): + """ + Returns a list with all the angular velocities of the actor at the frame interval. + """ + return self._get_all_actor_states(actor_id, "angular_velocity", first_frame, last_frame) + + def get_actor_angular_velocities_at_frame(self, frame, actor_list=None): + """ + Returns a dictionary {int - carla.Vector3D} with the actor ID and angular velocity + at a given frame of all the actors at actor_list. + """ + return self._get_states_at_frame(frame, "angular_velocity", actor_list) + + # Acceleration + def get_actor_acceleration(self, actor_id, frame): + """ + Returns the acceleration of the actor at a given frame. + """ + return self._get_actor_state(actor_id, "acceleration", frame) + + def get_all_actor_accelerations(self, actor_id, first_frame=None, last_frame=None): + """ + Returns a list with all the accelerations of the actor at the frame interval. + """ + return self._get_all_actor_states(actor_id, "acceleration", first_frame, last_frame) + + def get_actor_accelerations_at_frame(self, frame, actor_list=None): + """ + Returns a dictionary {int - carla.Vector3D} with the actor ID and angular velocity + at a given frame of all the actors at actor_list. + """ + return self._get_states_at_frame(frame, "acceleration", actor_list) + + # Controls + def get_vehicle_control(self, vehicle_id, frame): + """ + Returns the control of the vehicle at a given frame. + """ + return self._get_actor_state(vehicle_id, "control", frame) + + def get_vehicle_physics_control(self, vehicle_id, frame): + """ + Returns the carla.VehiclePhysicsControl of a vehicle at a given frame. + Returns None if the id can't be found. + """ + + for i in range(frame - 1, -1, -1): # Go backwards from the frame until 0 + physics_info = self._frames[i]["events"]["physics_control"] + + if vehicle_id in physics_info: + return physics_info[vehicle_id] + + return None + + def get_walker_speed(self, walker_id, frame): + """ + Returns the speed of the walker at a specific frame. + """ + return self._get_actor_state(walker_id, "speed", frame) + + # Traffic lights + def get_traffic_light_state(self, traffic_light_id, frame): + """ + Returns the state of the traffic light at a specific frame. + """ + return self._get_actor_state(traffic_light_id, "state", frame) + + def is_traffic_light_frozen(self, traffic_light_id, frame): + """ + Returns whether or not the traffic light is frozen at a specific frame. + """ + return self._get_actor_state(traffic_light_id, "frozen", frame) + + def get_traffic_light_elapsed_time(self, traffic_light_id, frame): + """ + Returns the elapsed time of the traffic light at a specific frame. + """ + return self._get_actor_state(traffic_light_id, "elapsed_time", frame) + + def get_traffic_light_state_time(self, traffic_light_id, state, frame): + """ + Returns the state time of the traffic light at a specific frame. + Returns None if the id can't be found. + """ + + for i in range(frame - 1, -1, -1): # Go backwards from the frame until 0 + state_times_info = self._frames[i]["events"]["traffic_light_state_time"] + + if traffic_light_id in state_times_info: + states = state_times_info[traffic_light_id] + if state in states: + return state_times_info[traffic_light_id][state] + + return None + + # Vehicle lights + def get_vehicle_lights(self, vehicle_id, frame): + """ + Returns the vehicle lights of the vehicle at a specific frame. + """ + return self._get_actor_state(vehicle_id, "lights", frame) + + def is_vehicle_light_active(self, light, vehicle_id, frame): + """ + Returns the elapsed time of the traffic light at a specific frame. + """ + lights = self.get_vehicle_lights(vehicle_id, frame) + + if light in lights: + return True + + return False + + # Scene lights + def get_scene_light_state(self, light_id, frame): + """ + Returns the state of the scene light at a specific frame. + Returns None if the id can't be found. + """ + + for i in range(frame - 1, -1, -1): # Go backwards from the frame until 0 + scene_lights_info = self._frames[i]["events"]["scene_lights"] + + if light_id in scene_lights_info: + return scene_lights_info[light_id] + + return None diff --git a/scenario_runner/srunner/metrics/tools/metrics_parser.py b/scenario_runner/srunner/metrics/tools/metrics_parser.py new file mode 100644 index 0000000..2207229 --- /dev/null +++ b/scenario_runner/srunner/metrics/tools/metrics_parser.py @@ -0,0 +1,618 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de +# Barcelona (UAB). +# +# This work is licensed under the terms of the MIT license. +# For a copy, see . + +""" +Support class of the MetricsManager to parse the information of +the CARLA recorder into a readable dictionary +""" + +import carla + + +def parse_actor(info): + """ + Returns a dictionary with the basic actor information + + Args: + info (list): list corresponding to a row of the recorder + """ + + actor = { + "type_id": info[2], + "location": carla.Location( + float(info[5][1:-1]) / 100, + float(info[6][:-1]) / 100, + float(info[7][:-1]) / 100 + ) + } + + return actor + + +def parse_transform(info): + """ + Parses a list into a carla.Transform + + Args: + info (list): list corresponding to a row of the recorder + """ + transform = carla.Transform( + carla.Location( + float(info[3][1:-1]) / 100, + float(info[4][:-1]) / 100, + float(info[5][:-1]) / 100, + ), + carla.Rotation( + float(info[8][:-1]), # pitch + float(info[9][:-1]), # yaw + float(info[7][1:-1]) # roll + ) + ) + + return transform + + +def parse_control(info): + """ + Parses a list into a carla.VehicleControl + + Args: + info (list): list corresponding to a row of the recorder + """ + control = carla.VehicleControl( + float(info[5]), # throttle + float(info[3]), # steer + float(info[7]), # brake + bool(int(info[9])), # hand_brake + int(info[11]) < 0, # reverse + False, # manual_gear_shift + int(info[11]), # gear + ) + + return control + + +def parse_vehicle_lights(info): + """ + Parses a list into a carla.VehicleLightState + + Args: + info (list): list corresponding to a row of the recorder + """ + srt_to_vlight = { + "None": carla.VehicleLightState.NONE, + "Position": carla.VehicleLightState.Position, + "LowBeam": carla.VehicleLightState.LowBeam, + "HighBeam": carla.VehicleLightState.HighBeam, + "Brake": carla.VehicleLightState.Brake, + "RightBlinker": carla.VehicleLightState.RightBlinker, + "LeftBlinker": carla.VehicleLightState.LeftBlinker, + "Reverse": carla.VehicleLightState.Reverse, + "Fog": carla.VehicleLightState.Fog, + "Interior": carla.VehicleLightState.Interior, + "Special1": carla.VehicleLightState.Special1, + "Special2": carla.VehicleLightState.Special2, + } + + lights = [] + for i in range(2, len(info)): + lights.append(srt_to_vlight[info[i]]) + + return lights + + +def parse_traffic_light(info): + """ + Parses a list into a dictionary with all the traffic light's information + + Args: + info (list): list corresponding to a row of the recorder + """ + number_to_state = { + "0": carla.TrafficLightState.Red, + "1": carla.TrafficLightState.Yellow, + "2": carla.TrafficLightState.Green, + "3": carla.TrafficLightState.Off, + "4": carla.TrafficLightState.Unknown, + } + + traffic_light = { + "state": number_to_state[info[3]], + "frozen": bool(int(info[5])), + "elapsed_time": float(info[7]), + } + + return traffic_light + + +def parse_velocity(info): + """ + Parses a list into a carla.Vector3D with the velocity + + Args: + info (list): list corresponding to a row of the recorder + """ + velocity = carla.Vector3D( + float(info[3][1:-1]), + float(info[4][:-1]), + float(info[5][:-1]) + ) + + return velocity + + +def parse_angular_velocity(info): + """ + Parses a list into a carla.Vector3D with the angular velocity + + Args: + info (list): list corresponding to a row of the recorder + """ + velocity = carla.Vector3D( + float(info[7][1:-1]), + float(info[8][:-1]), + float(info[9][:-1]) + ) + + return velocity + + +def parse_scene_lights(info): + """ + Parses a list into a carla.VehicleLightState + + Args: + info (list): list corresponding to a row of the recorder + """ + + red = int(float(info[7][1:-1]) * 255) + green = int(float(info[8][:-1]) * 255) + blue = int(float(info[9][:-1]) * 255) + + scene_light = carla.LightState( + int(float(info[5])), + carla.Color(red, green, blue), + carla.LightGroup.NONE, + bool(info[3]) + ) + + return scene_light + + +def parse_bounding_box(info): + """ + Parses a list into a carla.BoundingBox + + Args: + info (list): list corresponding to a row of the recorder + """ + location = carla.Location( + float(info[3][1:-1])/100, + float(info[4][:-1])/100, + float(info[5][:-1])/100, + ) + + extent = carla.Vector3D( + float(info[7][1:-1])/100, + float(info[8][:-1])/100, + float(info[9][:-1])/100, + ) + + bbox = carla.BoundingBox(location, extent) + + return bbox + + +def parse_state_times(info): + """ + Parses a list into a dict containing the state times of the traffic lights + + Args: + info (list): list corresponding to a row of the recorder + """ + + state_times = { + carla.TrafficLightState.Green: float(info[3]), + carla.TrafficLightState.Yellow: float(info[5]), + carla.TrafficLightState.Red: float(info[7]), + } + + return state_times + + +def parse_vector_list(info): + """ + Parses a list of string into a list of Vector2D + + Args: + info (list): list corresponding to a row of the recorder + """ + vector_list = [] + for i in range(0, len(info), 2): + vector = carla.Vector2D( + float(info[i][1:-1]), + float(info[i+1][:-1]), + ) + vector_list.append(vector) + + return vector_list + + +def parse_gears_control(info): + """ + Parses a list into a GearPhysicsControl + + Args: + info (list): list corresponding to a row of the recorder + """ + gears_control = carla.GearPhysicsControl( + float(info[3]), + float(info[5]), + float(info[7]), + ) + + return gears_control + + +def parse_wheels_control(info): + """ + Parses a list into a WheelsPhysicsControl + + Args: + info (list): list corresponding to a row of the recorder + """ + gears_control = carla.WheelPhysicsControl( + float(info[3]), + float(info[5]), + float(info[7]), + float(info[9]), + float(info[11]), + float(info[13]), + carla.Vector3D() + ) + + return gears_control + + +class MetricsParser(object): + """ + Class used to parse the CARLA recorder into readable information + """ + + def __init__(self, recorder_info): + + self.recorder_info = recorder_info + self.frame_list = None + self.frame_row = None + self.i = 0 + + def get_row_elements(self, indent_num, split_string): + """ + returns a list with the elements of the row + """ + return self.frame_row[indent_num:].split(split_string) + + def next_row(self): + """ + Gets the next row of the recorder + """ + self.i += 1 + self.frame_row = self.frame_list[self.i] + + def parse_recorder_info(self): + """ + Parses the recorder into readable information. + + Args: + recorder_info (str): string given by the recorder + """ + + # Divide it into frames + recorder_list = self.recorder_info.split("Frame") + + # Get general information + header = recorder_list[0].split("\n") + sim_map = header[1][5:] + sim_date = header[2][6:] + + annex = recorder_list[-1].split("\n") + sim_frames = int(annex[0][3:]) + sim_duration = float(annex[1][10:-8]) + + recorder_list = recorder_list[1:-1] + + simulation_info = { + "map": sim_map, + "date:": sim_date, + "total_frames": sim_frames, + "duration": sim_duration + } + + actors_info = {} + frames_info = [] + + for frame in recorder_list: + + # Divide the frame in lines + self.frame_list = frame.split("\n") + + # Get the general frame information + frame_info = self.frame_list[0].split(" ") + frame_number = int(frame_info[1]) + frame_time = float(frame_info[3]) + + try: + prev_frame = frames_info[frame_number - 2] + prev_time = prev_frame["frame"]["elapsed_time"] + delta_time = round(frame_time - prev_time, 6) + except IndexError: + delta_time = 0 + + # Variable to store all the information about the frame + frame_state = { + "frame": { + "elapsed_time": frame_time, + "delta_time": delta_time, + "platform_time": None + }, + "actors": {}, + "events":{ + "scene_lights": {}, + "physics_control": {}, + "traffic_light_state_time": {}, + "collisions": {} + } + } + + # Loop through all the other rows. + self.i = 0 + self.next_row() + + while self.frame_row.startswith(' Create') or self.frame_row.startswith(' '): + + if self.frame_row.startswith(' Create'): + elements = self.get_row_elements(1, " ") + actor_id = int(elements[1][:-1]) + + actor = parse_actor(elements) + actors_info.update({actor_id: actor}) + actors_info[actor_id].update({"created": frame_number}) + else: + elements = self.get_row_elements(2, " = ") + actors_info[actor_id].update({elements[0]: elements[1]}) + + self.next_row() + + while self.frame_row.startswith(' Destroy'): + + elements = self.get_row_elements(1, " ") + + actor_id = int(elements[1]) + actors_info[actor_id].update({"destroyed": frame_number}) + + self.next_row() + + while self.frame_row.startswith(' Collision'): + + elements = self.get_row_elements(1, " ") + + actor_id = int(elements[4]) + other_id = int(elements[-1]) + + if actor_id not in frame_state["events"]["collisions"]: + frame_state["events"]["collisions"][actor_id] = [other_id] + else: + collisions = frame_state["events"]["collisions"][actor_id] + collisions.append(other_id) + frame_state["events"]["collisions"].update({actor_id: collisions}) + + self.next_row() + + while self.frame_row.startswith(' Parenting'): + + elements = self.get_row_elements(1, " ") + + actor_id = int(elements[1]) + parent_id = int(elements[3]) + actors_info[actor_id].update({"parent": parent_id}) + + self.next_row() + + if self.frame_row.startswith(' Positions'): + self.next_row() + + while self.frame_row.startswith(' '): + + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + transform = parse_transform(elements) + frame_state["actors"].update({actor_id: {"transform": transform}}) + + self.next_row() + + if self.frame_row.startswith(' State traffic lights'): + self.next_row() + + while self.frame_row.startswith(' '): + + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + traffic_light = parse_traffic_light(elements) + frame_state["actors"].update({actor_id: traffic_light}) + self.next_row() + + if self.frame_row.startswith(' Vehicle animations'): + self.next_row() + + while self.frame_row.startswith(' '): + + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + control = parse_control(elements) + frame_state["actors"][actor_id].update({"control": control}) + self.next_row() + + if self.frame_row.startswith(' Walker animations'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + frame_state["actors"][actor_id].update({"speed": elements[3]}) + self.next_row() + + if self.frame_row.startswith(' Vehicle light animations'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + lights = parse_vehicle_lights(elements) + frame_state["actors"][actor_id].update({"lights": lights}) + self.next_row() + + if self.frame_row.startswith(' Scene light changes'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + scene_light = parse_scene_lights(elements) + frame_state["events"]["scene_lights"].update({actor_id: scene_light}) + self.next_row() + + if self.frame_row.startswith(' Dynamic actors'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + velocity = parse_velocity(elements) + frame_state["actors"][actor_id].update({"velocity": velocity}) + + angular_v = parse_angular_velocity(elements) + frame_state["actors"][actor_id].update({"angular_velocity": angular_v}) + + if delta_time == 0: + acceleration = carla.Vector3D(0, 0, 0) + else: + prev_velocity = frame_state["actors"][actor_id]["velocity"] + acceleration = (velocity - prev_velocity) / delta_time + + frame_state["actors"][actor_id].update({"acceleration": acceleration}) + self.next_row() + + if self.frame_row.startswith(' Actor bounding boxes'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + bbox = parse_bounding_box(elements) + actors_info[actor_id].update({"bounding_box": bbox}) + self.next_row() + + if self.frame_row.startswith(' Actor trigger volumes'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + trigvol = parse_bounding_box(elements) + actors_info[actor_id].update({"trigger_volume": trigvol}) + self.next_row() + + if self.frame_row.startswith(' Current platform time'): + + elements = self.get_row_elements(1, " ") + + platform_time = float(elements[-1]) + frame_state["frame"]["platform_time"] = platform_time + self.next_row() + + if self.frame_row.startswith(' Physics Control'): + self.next_row() + + actor_id = None + while self.frame_row.startswith(' '): + + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + physics_control = carla.VehiclePhysicsControl() + self.next_row() + + forward_gears = [] + wheels = [] + while self.frame_row.startswith(' '): + + if self.frame_row.startswith(' '): + elements = self.get_row_elements(4, " ") + if elements[0] == "gear": + forward_gears.append(parse_gears_control(elements)) + elif elements[0] == "wheel": + wheels.append(parse_wheels_control(elements)) + + else: + elements = self.get_row_elements(3, " = ") + name = elements[0] + + if name == "center_of_mass": + values = elements[1].split(" ") + value = carla.Vector3D( + float(values[0][1:-1]), + float(values[1][:-1]), + float(values[2][:-1]), + ) + setattr(physics_control, name, value) + elif name == "torque_curve" or name == "steering_curve": + values = elements[1].split(" ") + value = parse_vector_list(values) + setattr(physics_control, name, value) + + elif name == "use_gear_auto_box": + name = "use_gear_autobox" + value = True if elements[1] == "true" else False + setattr(physics_control, name, value) + + elif "forward_gears" in name or "wheels" in name: + pass + + else: + name = name.lower() + value = float(elements[1]) + setattr(physics_control, name, value) + + self.next_row() + + setattr(physics_control, "forward_gears", forward_gears) + setattr(physics_control, "wheels", wheels) + frame_state["events"]["physics_control"].update({actor_id: physics_control}) + + if self.frame_row.startswith(' Traffic Light time events'): + self.next_row() + + while self.frame_row.startswith(' '): + elements = self.get_row_elements(2, " ") + actor_id = int(elements[1]) + + state_times = parse_state_times(elements) + frame_state["events"]["traffic_light_state_time"].update({actor_id: state_times}) + self.next_row() + + frames_info.append(frame_state) + + return simulation_info, actors_info, frames_info