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