Skip to content

Commit 0d0bb3c

Browse files
Merge pull request #42 from Intelligent-Testing-Lab/28-add-support-for-spawning-ego-vehicle-through-scenario-runner
moved some files and added docstrings
2 parents e96285f + 1ae8b04 commit 0d0bb3c

6 files changed

Lines changed: 134 additions & 115 deletions

File tree

aw_scenario_runner.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
1818
from srunner.tools.route_parser import RouteParser
1919
from srunner.tools.environment_parser import EnvironmentParser
20-
from srunner.tools.environment_parser import EnvironmentConfig
20+
from srunner.scenarioconfigs.environment_configuration import EnvironmentConfig
2121
from srunner.scenarioconfigs.route_scenario_configuration import (
2222
RouteScenarioConfiguration,
2323
)
@@ -191,16 +191,20 @@ def run_scenario(
191191
result = False
192192
return result
193193

194-
def run(self) -> bool:
194+
def run(self) -> None:
195+
"""The Scenario loop. Read the scenario configuration from the parsed XML files,
196+
configure the scenario in CARLA and execute. Use the results to and parse to the algorithm callback.
197+
Repeats **iterations** times, as defined in config.yaml
198+
199+
"""
195200
env_config = EnvironmentParser.parse_scenario_env(
196201
os.path.join(self.results_manager.last_scenario, "scenario.xml")
197202
)
198203
route_config = RouteParser.parse_routes_file(
199204
self.results_manager.last_scenario, env_config
200205
)[self._scenario_config["route_id"]]
201206

202-
scenario_result = self.run_scenario(route_config, env_config)
203-
return scenario_result
207+
self.run_scenario(route_config, env_config)
204208

205209
def destroy(self) -> None:
206210
"""Deletes instances of all classes related to CARLA"""

srunner/autoagents/autoware_agent.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,18 @@
77

88
from srunner.autoagents.agent_state import autoware_state
99

10-
from srunner.tools.environment_parser import EnvironmentConfig
10+
from srunner.scenarioconfigs.environment_configuration import EnvironmentConfig
1111

1212
from autoware_carla_interface_msgs.msg import EgoConfig, SensorConfig
1313

1414
import threading
1515
import rclpy
1616
import time
17+
import logging
1718

19+
logger = logging.getLogger("scenario-runner")
1820

19-
DEBUG_ENV = False
2021

21-
22-
# uncomment if testing in scenario runner
2322
class AutowareAgent(AutonomousAgent):
2423
timestamp = None
2524
current_map = None
@@ -66,7 +65,9 @@ def setup(self, config: EnvironmentConfig | None = None) -> None:
6665
ego_config_msg.sensors.append(sensor_config_msg)
6766

6867
# keep publishing ego_sensor config until the bridge is ready
68+
# big performance diminishment here
6969
while not self.autoware_state.bridge_ready:
70+
logger.info("Sending Sensor state to Agent...")
7071
time.sleep(5)
7172
self.state_node.ego_config_publisher.publish(ego_config_msg)
7273

@@ -81,10 +82,10 @@ def set_route(self) -> None:
8182
self.waypoints_world = self._global_plan_world_coord[:-1]
8283

8384
# reinitialise localization
84-
print("called localise")
85+
logger.info("called localise")
8586
# self.autoware_node.request_localize() # None uses GNSS
8687

87-
print("called clear route")
88+
logger.info("called clear route")
8889
# clear route
8990
# self.route_node.request_clear_route()
9091

@@ -108,15 +109,15 @@ def destroy(self) -> None:
108109
self._node_threads[thread].join()
109110
self._nodes[thread].destroy_node()
110111
except RuntimeError:
111-
print("Cleaned up threads...")
112+
logger.info("Cleaned up threads...")
112113

113114
rclpy.shutdown()
114115

115116
def run_step(self) -> None:
116117
"""Tick method containing all logic based on autoware state"""
117118
self.counter += 1
118119
if self.counter % 20 == 0:
119-
print("1 second")
120+
logger.info("1 second")
120121

121122
if not self.agent_set_route:
122123
self.set_route()

srunner/objects/ego_vehicle.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,10 @@ def prepare_ego(self) -> None:
6262
self._actor.set_target_velocity(carla.Vector3D())
6363
self._actor.set_target_angular_velocity(carla.Vector3D())
6464
CarlaDataProvider.register_actor(self._actor, self._env.ego_spawn)
65+
66+
def __del__(self) -> None:
67+
"""Clean up
68+
Check if the actor exists in CARLA, delete if so
69+
"""
70+
if self._actor.is_alive():
71+
self._actor.destroy()

srunner/objects/sensors.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
2+
3+
import carla
4+
5+
6+
class DefaultSensor(object):
7+
"""
8+
A class to encapsulate information about a basic sensor
9+
"""
10+
11+
def __init__(self) -> None:
12+
self.type: str = ""
13+
self.id: str = ""
14+
self.spawn: carla.Transform | None = None
15+
16+
def _spawn(self, bp_library, vehicle) -> None:
17+
sensor_bp = bp_library.find(str(self.type))
18+
19+
ignored_params = ["serealize", "id", "spawn", "type"]
20+
21+
sensor_params = [
22+
attr
23+
for attr in dir(self)
24+
if attr not in ignored_params or not attr.startswith("_")
25+
]
26+
27+
for param in sensor_params:
28+
sensor_bp.set_attribute(param, str(getattr(self, param)))
29+
30+
CarlaDataProvider.get_world().spawn_actor(sensor_bp, self.spawn, vehicle)
31+
CarlaDataProvider.get_world().wait_for_tick()
32+
33+
def serealize(self):
34+
return self.type, self.id
35+
36+
37+
class CameraRGB(DefaultSensor):
38+
"""
39+
A class to hold additional information about a camera sensor
40+
"""
41+
42+
def __init__(self) -> None:
43+
super().__init__()
44+
self.image_size_x: int = 0
45+
self.image_size_y: int = 0
46+
self.fov: float = 0.0
47+
48+
49+
class LidarRayCast(DefaultSensor):
50+
"""
51+
A class to hold additional information about a Lidar sensor
52+
"""
53+
54+
def __init__(self) -> None:
55+
super().__init__()
56+
self.range: int = 0
57+
self.channels: int = 0
58+
self.points_per_second: int = 0
59+
self.upper_fov: float = 0.0
60+
self.lower_fov: float = 0.0
61+
self.rotation_frequency: int = 0
62+
63+
64+
class SensorGNSS(DefaultSensor):
65+
"""
66+
A class to hold additional information about GNSS
67+
"""
68+
69+
def __init__(self) -> None:
70+
super().__init__()
71+
self.noise_alt_stddev = 0.0
72+
self.noise_lat_stddev = 0.0
73+
self.noise_lon_stddev = 0.0
74+
self.noise_alt_bias = 0.0
75+
self.noise_lat_bias = 0.0
76+
self.noise_lon_bias = 0.0
77+
78+
79+
class SensorIMU(DefaultSensor):
80+
"""
81+
A class to hold additional information about IMU
82+
"""
83+
84+
def __init__(self) -> None:
85+
super().__init__()
86+
self.noise_accel_stddev_x = 0.0
87+
self.noise_accel_stddev_y = 0.0
88+
self.noise_accel_stddev_z = 0.0
89+
self.noise_gyro_stddev_x = 0.0
90+
self.noise_gyro_stddev_y = 0.0
91+
self.noise_gyro_stddev_z = 0.0
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from srunner.objects.sensors import DefaultSensor
2+
3+
import carla
4+
5+
6+
class EnvironmentConfig(object):
7+
"""
8+
Simple object to store information about the initial environment setup for the scenario loop
9+
"""
10+
11+
def __init__(self) -> None:
12+
self.town: str = ""
13+
self.ego_model: str = ""
14+
self.ego_name: str = ""
15+
self.ego_spawn: carla.Transform | None = None
16+
self.sensor_config: list[DefaultSensor] = []
17+
self.route_id: int = 0

srunner/tools/environment_parser.py

Lines changed: 2 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,13 @@
11
import xml.etree.ElementTree as ET
22
from xml.etree.ElementTree import Element
33

4-
from srunner.scenariomanager.carla_data_provider import CarlaDataProvider
4+
from srunner.scenarioconfigs.environment_configuration import EnvironmentConfig
5+
from srunner.objects.sensors import DefaultSensor, CameraRGB, LidarRayCast
56

67
import carla
78
import logging
89

910

10-
class EnvironmentConfig(object):
11-
"""
12-
Simple object to store information about the initial environment setup for the scenario loop
13-
"""
14-
15-
def __init__(self) -> None:
16-
self.town: str = ""
17-
self.ego_model: str = ""
18-
self.ego_name: str = ""
19-
self.ego_spawn: carla.Transform | None = None
20-
self.sensor_config: list[DefaultSensor] = []
21-
self.route_id: int = 0
22-
23-
24-
class DefaultSensor(object):
25-
"""
26-
A class to encapsulate information about a basic sensor
27-
"""
28-
29-
def __init__(self) -> None:
30-
self.type: str = ""
31-
self.id: str = ""
32-
self.spawn: carla.Transform | None = None
33-
34-
def _spawn(self, bp_library, vehicle) -> None:
35-
sensor_bp = bp_library.find(str(self.type))
36-
37-
ignored_params = ["serealize", "id", "spawn", "type"]
38-
39-
sensor_params = [
40-
attr
41-
for attr in dir(self)
42-
if attr not in ignored_params or not attr.startswith("_")
43-
]
44-
45-
for param in sensor_params:
46-
sensor_bp.set_attribute(param, str(getattr(self, param)))
47-
48-
CarlaDataProvider.get_world().spawn_actor(sensor_bp, self.spawn, vehicle)
49-
CarlaDataProvider.get_world().wait_for_tick()
50-
51-
def serealize(self):
52-
return self.type, self.id
53-
54-
55-
class CameraRGB(DefaultSensor):
56-
"""
57-
A class to hold additional information about a camera sensor
58-
"""
59-
60-
def __init__(self) -> None:
61-
super().__init__()
62-
self.image_size_x: int = 0
63-
self.image_size_y: int = 0
64-
self.fov: float = 0.0
65-
66-
67-
class LidarRayCast(DefaultSensor):
68-
"""
69-
A class to hold additional information about a Lidar sensor
70-
"""
71-
72-
def __init__(self) -> None:
73-
super().__init__()
74-
self.range: int = 0
75-
self.channels: int = 0
76-
self.points_per_second: int = 0
77-
self.upper_fov: float = 0.0
78-
self.lower_fov: float = 0.0
79-
self.rotation_frequency: int = 0
80-
81-
82-
class SensorGNSS(DefaultSensor):
83-
"""
84-
A class to hold additional information about GNSS
85-
"""
86-
87-
def __init__(self) -> None:
88-
super().__init__()
89-
self.noise_alt_stddev = 0.0
90-
self.noise_lat_stddev = 0.0
91-
self.noise_lon_stddev = 0.0
92-
self.noise_alt_bias = 0.0
93-
self.noise_lat_bias = 0.0
94-
self.noise_lon_bias = 0.0
95-
96-
97-
class SensorIMU(DefaultSensor):
98-
"""
99-
A class to hold additional information about IMU
100-
"""
101-
102-
def __init__(self) -> None:
103-
super().__init__()
104-
self.noise_accel_stddev_x = 0.0
105-
self.noise_accel_stddev_y = 0.0
106-
self.noise_accel_stddev_z = 0.0
107-
self.noise_gyro_stddev_x = 0.0
108-
self.noise_gyro_stddev_y = 0.0
109-
self.noise_gyro_stddev_z = 0.0
110-
111-
11211
class EnvironmentParser(object):
11312
"""
11413
Purely Static class for parsing Scenarion configuration files generated by the JSON parsers

0 commit comments

Comments
 (0)