1212import carla
1313
1414from srunner .scenariomanager .scenario_manager import ScenarioManager
15- from srunner .scenario_decoder .json_to_xml_files import XMLToFiles
16- from srunner .tools .results_manager import ResultsManager
15+ from srunner .tools .results_manager import ScenarioDefinitionManager
1716from srunner .scenarios .route_scenario import RouteScenario
1817from srunner .scenariomanager .carla_data_provider import CarlaDataProvider
1918from srunner .tools .route_parser import RouteParser
2322 RouteScenarioConfiguration ,
2423)
2524
25+ from srunner .objects .ego_vehicle import EgoVehicle
26+
2627from srunner .tools .log import LogUtil
2728
29+ logger = logging .getLogger ("scenario-runner" )
30+
2831
2932class AWScenarioRunner (object ):
33+ # flags
34+ DEV_MODE = False
35+ DEBUG = False
36+
37+ # global class instances
3038 ego_vehicles = []
3139
32- # world and scenario handlers
3340 carla_world = None
3441 carla_client = None
3542
3643 scenario_manager = None
37- scenario_decoder = None
38- results_manager = None
39-
40- wait_for_update = False
41- finished = False
44+ definition_manager = None
4245
4346 aw_agent = None
4447
4548 def __init__ (self , config : dict ) -> None :
4649 """
4750 Setup Scenario Manager and the Carla client
4851 """
52+
4953 self ._carla_config = config ["carla" ]
5054 self ._tm_config = config ["traffic_manager" ]
5155 self ._scenario_config = config ["scenario_runner" ]
5256
5357 self .carla_client = carla .Client (
5458 self ._carla_config ["host" ], int (self ._carla_config ["port" ])
5559 )
60+
5661 self .carla_client .set_timeout (self ._carla_config ["timeout" ])
5762
58- # update the client
63+ # Flags
64+ self .DEV_MODE = self ._scenario_config ["dev_mode" ]
65+ self .DEBUG = self ._scenario_config ["dev_mode" ]
66+
5967 CarlaDataProvider .set_client (self .carla_client )
6068
61- # load autoware agent
62- # only load if in docker environment
63- # debug
64- if self ._scenario_config ["in_docker" ]:
65- autoware_agent_path = "srunner/autoagents/autoware_agent"
69+ if not self .DEV_MODE : # only load agents and algorithms in non-dev mode
70+ autoware_agent_path = self ._scenario_config ["agent" ]
6671 module_name = os .path .basename (autoware_agent_path ).split ("." )[0 ]
6772 sys .path .insert (0 , os .path .dirname (autoware_agent_path ))
6873 self .module_aw_agent = importlib .import_module (module_name )
6974
70- # load the algorithm of choice
71- # algorithm = self._scenario_config["algorithm"] # relative path to entry point
72- # alg_module = os.path.basename(algorithm).split(".")[0]
73- # sys.path.insert(0, os.path.dirname(algorithm))
74- # self.module_algorithm = importlib.import_module(alg_module)
75+ algorithm = self ._scenario_config ["algorithm" ]["path" ]
76+ alg_module = os .path .basename (algorithm ).split ("." )[0 ]
77+ sys .path .insert (0 , os .path .dirname (algorithm ))
78+ self .module_algorithm = importlib .import_module (alg_module )
7579
7680 # main class to execute scenarios
7781 self .scenario_manager = ScenarioManager (
@@ -80,9 +84,9 @@ def __init__(self, config: dict) -> None:
8084 self ._carla_config ["timeout" ],
8185 )
8286
83- self .results_manager = ResultsManager ()
87+ self .results_manager = ScenarioDefinitionManager ()
8488
85- # Create signal handler for SIGINT
89+ # capture SIGINT for cleanp
8690 self ._shutdown_requested = False
8791 if sys .platform != "win32" :
8892 signal .signal (signal .SIGHUP , self ._signal_handler )
@@ -91,33 +95,14 @@ def __init__(self, config: dict) -> None:
9195
9296 self ._start_wall_time = datetime .datetime .now ()
9397
94- # parse the JSON scenario file
95- if self .scenario_decoder is None :
96- self .scenario_decoder = XMLToFiles ()
97-
9898 scenario_name = os .path .split (
9999 os .path .splitext (self ._scenario_config ["json" ])[0 ]
100100 )[1 ]
101- self ._parse_json (self ._scenario_config ["json" ], scenario_name , "0" )
102-
103- def _parse_json (self , json : str , scenario : str , iteration : str ) -> None :
104- """Parses a given JSON Scenario definition. Outputs two XML files used by scenario runner
105-
106- Args:
107- json (str): filepath to JSON scenario definition
108- scenario (str): Name of the scenario
109- iteration (str): ID of the scenario. Can be anything, but must be unique
110- """
111- # create run directory if doesn't exist
112- if not self .results_manager .results_path :
113- self .results_manager .create_run_folder ()
114101
115- self .results_manager .create_scenario_folder (
116- scenario , iteration , self . results_manager . results_path
102+ self .results_manager .parse_json (
103+ self . _scenario_config [ "json" ], scenario_name , "0"
117104 )
118105
119- self .scenario_decoder .parse_scenario (json , self .results_manager .last_scenario )
120-
121106 def _signal_handler (self , signum , frame ) -> None :
122107 """
123108 Handle shutdown signal, do cleanup
@@ -132,148 +117,87 @@ def _signal_handler(self, signum, frame) -> None:
132117 def run_scenario (
133118 self , route_config : RouteScenarioConfiguration , env_config : EnvironmentConfig
134119 ) -> bool :
135- # find the ego vehicle by name
136- # only supports one ego
137-
138- # setup world based on env config
139- # make sure to reload
140120 self .carla_world = self .carla_client .get_world ()
141121 self .carla_client .load_world (env_config .town )
142122
143- # update carla provider
144123 CarlaDataProvider .set_world (self .carla_world )
145124
146- # replace with spawning ego
147- # ego_missing = True
148- # while ego_missing:
149- # self.ego_vehicles = []
150- # for ego in route_config.ego_vehicles:
151- # carla_vehicles = (
152- # self.carla_client.get_world().get_actors().filter("vehicle.*")
153- # )
154- #
155- # for carla_vehicle in carla_vehicles:
156- # if carla_vehicle.attributes["role_name"] == ego:
157- # self.ego_vehicles.append(carla_vehicle)
158- # ego_missing = False
159- # break
160- # print("Can't find ego, waiting...")
161- # time.sleep(1)
162- # ego_missing = False
163-
164- print ("Spawning ego..." )
165- self ._spawn_ego (env_config )
166-
167- print ("Spawned ego..." )
125+ logger .info ("Spawning ego..." )
126+ ego = EgoVehicle (env_config )
127+ self .ego_vehicles .append (ego .spawn ())
128+ logger .info ("Spawned ego..." )
168129
169130 self .carla_world .wait_for_tick ()
170131
171- if self ._scenario_config ["in_docker" ]:
172- print ("Loading Autoware agent" )
132+ logger .info ("Setting up sensort configuration..." )
133+ ego .setup_sensors ()
134+
135+ if not self .DEV_MODE :
136+ logger .info ("Loading Autoware agent" )
173137 agent_class_name = self .module_aw_agent .__name__ .title ().replace ("_" , "" )
174138 try :
175- print (getattr (self .module_aw_agent , agent_class_name ))
176- # call the agent method to notify the bridge of the ego spawn
177- # this will loop until the bridge is ready
139+ logger .info (getattr (self .module_aw_agent , agent_class_name ))
178140 self .aw_agent = getattr (self .module_aw_agent , agent_class_name )(
179141 env_config
180142 )
181143 route_config .agent = self .aw_agent
182144 except Exception as e : # Forces the simulation to run synchronously # pylint: disable=broad-except
183- traceback .print_exc ()
184- print ("Could not setup required agent due to {}" .format (e ))
145+ logger .error ("Could not setup required agent due to {}" .format (e ))
185146 # self._cleanup()
186147 return False
187148
188- # only set synchronous mode once bridge is ready
149+ ego .prepare_ego ()
150+
151+ logger .info ("Updating world settings:" )
152+
189153 # tick asynchronously until then
190154 settings = CarlaDataProvider .get_world ().get_settings ()
191155 settings .synchronous_mode = True
192156 settings .fixed_delta_seconds = self ._carla_config ["fixed_delta_seconds" ]
193157 CarlaDataProvider .get_world ().apply_settings (settings )
194158
195- # ADD TRAFFIC MANAGER SEED TO CONFIG
196- tm_port = int (self ._tm_config ["port" ]) # type: ignore
197- CarlaDataProvider .set_traffic_manager_port (tm_port )
198- tm = self .carla_client .get_trafficmanager (tm_port )
199- tm .set_random_device_seed (1 ) # ADD TO CONFIG
159+ logger .info (f"{ settings .__str__ ()} " )
200160
201- tm .set_synchronous_mode (self ._tm_config ["sync" ])
161+ if self ._tm_config ["active" ]:
162+ logger .info ("Loading Traffic Manager..." )
163+ tm_port = int (self ._tm_config ["port" ]) # type: ignore
164+ CarlaDataProvider .set_traffic_manager_port (tm_port )
165+ tm = self .carla_client .get_trafficmanager (tm_port )
202166
203- print ("Preparing ego..." )
167+ tm .set_random_device_seed (int (self ._tm_config ["seed" ])) # ADD TO CONFIG
168+ tm .set_synchronous_mode (self ._tm_config ["sync" ])
204169
205- # update ego position to one specified in route
206- self .ego_vehicles [0 ].set_transform (env_config .ego_spawn )
207- self .ego_vehicles [0 ].set_target_velocity (carla .Vector3D ())
208- self .ego_vehicles [0 ].set_target_angular_velocity (carla .Vector3D ())
209- CarlaDataProvider .register_actor (self .ego_vehicles [0 ], env_config .ego_spawn )
170+ logger .info ("Loading route..." )
210171
211- print ("Loading route..." )
212172 try :
213173 scenario = RouteScenario (
214174 world = self .carla_world ,
215175 config = route_config ,
216176 debug_mode = self ._carla_config ["debug" ],
217177 )
218178 except Exception :
219- print ("Could not load Route Scenario" )
179+ logger . info ("Could not load Route Scenario" )
220180 traceback .print_exc ()
221181 return False
222182
223- print ("Starting scenario..." )
183+ logger . info ("Starting scenario..." )
224184 try :
225185 self .scenario_manager .load_scenario (scenario , self .aw_agent )
226186 self .scenario_manager .run_scenario ()
227187 result = True
228188 except Exception :
229189 traceback .print_exc ()
230- print ("It doesn't work" )
190+ logger . info ("It doesn't work" )
231191 result = False
232192 return result
233193
234- def _load_scenario_config (self ) -> EnvironmentConfig :
235- return EnvironmentParser .parse_scenario_env (
194+ def run (self ) -> bool :
195+ env_config = EnvironmentParser .parse_scenario_env (
236196 os .path .join (self .results_manager .last_scenario , "scenario.xml" )
237197 )
238-
239- def _spawn_ego (self , env_config : EnvironmentConfig ) -> None :
240- ego = CarlaDataProvider .request_new_actor (
241- model = env_config .ego_model ,
242- spawn_point = env_config .ego_spawn ,
243- rolename = env_config .ego_name ,
244- )
245- self .ego_vehicles .append (ego )
246-
247- CarlaDataProvider .get_world ().wait_for_tick () # wait for tick
248-
249- bp_library = self .carla_world .get_blueprint_library ()
250- # setup sensors
251- for sensor in env_config .sensor_config :
252- sensor ._spawn (bp_library , ego )
253- print (f"Spawned sensor type { sensor .type } " )
254-
255- def _load_route_scenario (
256- self , env_config : EnvironmentConfig
257- ) -> RouteScenarioConfiguration :
258198 route_config = RouteParser .parse_routes_file (
259199 self .results_manager .last_scenario , env_config
260- ) # type: ignore
261-
262- return route_config [0 ]
263-
264- def run (self ) -> bool :
265- # load the original JSON file
266- # load the route config
267- # load the scenario config
268- # run scenario
269- # get the metrics
270- # call the algorithm callback
271- # save using ResultsManager static class
272-
273- # repeat for iterations
274-
275- env_config = self ._load_scenario_config ()
276- route_config = self ._load_route_scenario (env_config )
200+ )[self ._scenario_config ["route_id" ]]
277201
278202 scenario_result = self .run_scenario (route_config , env_config )
279203 return scenario_result
@@ -296,7 +220,7 @@ def _cleanup(self) -> None:
296220 try :
297221 # Reset to asynchronous mode
298222 self .carla_client .get_trafficmanager (
299- int (self ._args . traffic_port )
223+ int (self ._tm_config [ "port" ] )
300224 ).set_synchronous_mode (False )
301225 except RuntimeError :
302226 sys .exit (- 1 )
@@ -308,7 +232,9 @@ def _cleanup(self) -> None:
308232 for i , _ in enumerate (self .ego_vehicles ):
309233 if self .ego_vehicles [i ]:
310234 if self .ego_vehicles [i ] is not None and self .ego_vehicles [i ].is_alive :
311- print ("Destroying ego vehicle {}" .format (self .ego_vehicles [i ].id ))
235+ logger .info (
236+ "Destroying ego vehicle {}" .format (self .ego_vehicles [i ].id )
237+ )
312238 self .ego_vehicles [i ].destroy ()
313239 self .ego_vehicles [i ] = None
314240 self .ego_vehicles = []
@@ -319,14 +245,15 @@ def _cleanup(self) -> None:
319245
320246
321247def main ():
248+ # single argument of configuration file
249+
322250 # configure logger
323251 config = None
324252 with open ("config.yaml" , "r" ) as stream :
325253 config = yaml .safe_load (stream )
326254
327255 log_config = config ["log" ]
328256
329- logger = logging .getLogger ("scenario-runner" )
330257 logger .setLevel (logging .INFO )
331258
332259 log_path = LogUtil .create_log_file (log_config ["path" ])
@@ -338,7 +265,7 @@ def main():
338265 try :
339266 scenario_runner = AWScenarioRunner (config )
340267 results = scenario_runner .run ()
341- print (results )
268+ logger . info (results )
342269 except Exception : # NOT GOOD PRACTICE PROBABLY CHANGE
343270 traceback .print_exc ()
344271 finally :
0 commit comments