Skip to content

Commit 2387735

Browse files
committed
Rework ActivateControllerAction OSC action
1 parent 3f5a4a2 commit 2387735

File tree

8 files changed

+146
-17
lines changed

8 files changed

+146
-17
lines changed

Docs/CHANGELOG.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@
1313
### :rocket: New Features
1414
* Added a sensor barrier for the agents to ensure that the simulation waits for them to render their data.
1515
* Added an option to produce a machine-readable JSON version of the scenario report.
16-
* Added a static obstacle evasion OpenSCENARIO scenario
17-
* Added support for OSC Routing options
18-
* Added support for OSC SynchronizeAction
19-
* Added support to place OSC controller implementation alongside the OSC scenario
2016
* Updated *GameTime.restart()* at *srunner/scenariomanager/timer.py* to also reset the frame number
17+
* OpenSCENARIO Support:
18+
* Added a static obstacle evasion OpenSCENARIO scenario
19+
* Added support for OSC Routing options
20+
* Added support for OSC SynchronizeAction
21+
* Added support to place OSC controller implementation alongside the OSC scenario
22+
* Extended SimpleVehicleController
23+
* Added controller using CARLA's autopilot (in replacement for ActivateControllerAction)
24+
* Updated ActivateControllerAction to its specified behavior according to OSC 1.0
25+
* Added support for storyboards with multiple stories
26+
* Added support for ObjectControllers. Note that the controller has to be implemented in Python,
27+
or be one of the provided controllers.
2128
### :bug: Bug Fixes
2229
* Fixed metrics-manager.py failing to run with port argument
2330
* Fixed exception when using OSC scenarios without EnvironmentAction inside Storyboard-Init

Docs/openscenario_support.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ contains of submodules, which are not listed, the support status applies to all
197197
<td><code>ActivateControllerAction</code></td>
198198
<td>&#10060;</td>
199199
<td>&#9989;</td>
200-
<td>Can be used to activate/deactive the CARLA autopilot.</td>
200+
<td></td>
201201
<tr>
202202
<td><code>ControllerAction</code></td>
203203
<td>&#9989;</td>

srunner/scenariomanager/actorcontrols/actor_control.py

+18
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,24 @@ def set_init_speed(self):
150150
"""
151151
self.control_instance.set_init_speed()
152152

153+
def change_lon_control(self, enable):
154+
"""
155+
Enable/Disable longitudinal control component of actor controller
156+
157+
Args:
158+
enable (boolean): Enable/Disable signal
159+
"""
160+
self.control_instance.change_lon_control(enable)
161+
162+
def change_lat_control(self, enable):
163+
"""
164+
Enable/Disable lateral control component of actor controller
165+
166+
Args:
167+
enable (boolean): Enable/Disable signal
168+
"""
169+
self.control_instance.change_lat_control(enable)
170+
153171
def run_step(self):
154172
"""
155173
Execute on tick of the controller's control loop

srunner/scenariomanager/actorcontrols/basic_control.py

+26
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ class BasicControl(object):
3737
Defaults to False.
3838
_reached_goal (boolean):
3939
Defaults to False.
40+
_use_lon_control (boolean):
41+
Use longitudinal component of controller
42+
Defaults to True
43+
_use_lat_control (boolean):
44+
Use lateral component of controller
45+
Defaults to True
4046
"""
4147

4248
_actor = None
@@ -45,6 +51,8 @@ class BasicControl(object):
4551
_target_speed = 0
4652
_reached_goal = False
4753
_init_speed = False
54+
_use_lon_control = True
55+
_use_lat_control = True
4856

4957
def __init__(self, actor):
5058
"""
@@ -78,6 +86,24 @@ def set_init_speed(self):
7886
"""
7987
self._init_speed = True
8088

89+
def change_lon_control(self, enable):
90+
"""
91+
Enable/Disable longitudinal control component
92+
93+
Args:
94+
enable (boolean): Enable/Disable signal
95+
"""
96+
self._use_lon_control = enable
97+
98+
def change_lat_control(self, enable):
99+
"""
100+
Enable/Disable lateral control component
101+
102+
Args:
103+
enable (boolean): Enable/Disable signal
104+
"""
105+
self._use_lat_control = enable
106+
81107
def check_reached_waypoint_goal(self):
82108
"""
83109
Check if the actor reached the end of the waypoint list

srunner/scenariomanager/actorcontrols/simple_vehicle_control.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class SimpleVehicleControl(BasicControl):
5555
(consider_trafficlights, true/false) - Enable consideration of traffic lights
5656
(max_deceleration, float) - Use a reasonable deceleration value for
5757
this vehicle
58+
(max_acceleration, float) - Use a reasonable acceleration value for
59+
this vehicle
5860
(attach_camera, true/false) - Attach OpenCV display to actor
5961
(useful for debugging)
6062
@@ -69,6 +71,12 @@ class SimpleVehicleControl(BasicControl):
6971
Defaults to False.
7072
_proximity_threshold (float): Distance in front of actor in which obstacles are considered
7173
Defaults to infinity.
74+
_consider_trafficlights (boolean): Enable/Disable consideration of red traffic lights
75+
Defaults to False.
76+
_max_deceleration (float): Deceleration value of the vehicle when braking
77+
Defaults to None (infinity).
78+
_max_acceleration (float): Acceleration value of the vehicle when accelerating
79+
Defaults to None (infinity).
7280
_cv_image (CV Image): Contains the OpenCV image, in case a debug camera is attached to the actor
7381
Defaults to None.
7482
_camera (sensor.camera.rgb): Debug camera attached to actor
@@ -281,7 +289,6 @@ def _set_new_velocity(self, next_location):
281289
target_speed = 0
282290

283291
if target_speed < current_speed and math.fabs(target_speed - current_speed) > 0.01:
284-
print(target_speed, current_speed)
285292
self._actor.set_light_state(carla.VehicleLightState.Brake)
286293
if self._max_deceleration is not None:
287294
target_speed = max(target_speed, current_speed - (current_time -

srunner/scenariomanager/scenarioatomics/atomic_behaviors.py

+59-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class ChangeActorControl(AtomicBehavior):
278278
Atomic to change the longitudinal/lateral control logic for an actor.
279279
The (actor, controller) pair is stored inside the Blackboard.
280280
281-
The behavior immediately terminates with SUCCESS after the controller.
281+
The behavior immediately terminates with SUCCESS after the controller was changed.
282282
283283
Args:
284284
actor (carla.Actor): Actor that should be controlled by the controller.
@@ -329,6 +329,64 @@ def update(self):
329329
return py_trees.common.Status.SUCCESS
330330

331331

332+
class DeActivateActorControlComponents(AtomicBehavior):
333+
334+
"""
335+
Atomic to enable/disable the longitudinal/lateral control component of an actor controller.
336+
The (actor, controller) pair is retrieved from the Blackboard.
337+
338+
The behavior immediately terminates with SUCCESS.
339+
340+
Args:
341+
actor (carla.Actor): Actor that should be controlled by the controller.
342+
control_py_module (string): Name of the python module containing the implementation
343+
of the controller.
344+
args (dictionary): Additional arguments for the controller.
345+
scenario_file_path (string): Additional path to controller implementation.
346+
name (string): Name of the behavior.
347+
Defaults to 'ChangeActorControl'.
348+
349+
Attributes:
350+
_actor_control (ActorControl): Instance of the actor control.
351+
"""
352+
353+
def __init__(self, actor, lon_control=None, lat_control=None, name="ChangeActorControl"):
354+
"""
355+
Setup actor controller.
356+
"""
357+
super(DeActivateActorControlComponents, self).__init__(name, actor)
358+
359+
self._lon_control = lon_control
360+
self._lat_control = lat_control
361+
362+
def update(self):
363+
"""
364+
Write (actor, controler) pair to Blackboard, or update the controller
365+
if actor already exists as a key.
366+
367+
returns:
368+
py_trees.common.Status.SUCCESS
369+
"""
370+
371+
actor_dict = {}
372+
373+
try:
374+
check_actors = operator.attrgetter("ActorsWithController")
375+
actor_dict = check_actors(py_trees.blackboard.Blackboard())
376+
except AttributeError:
377+
pass
378+
379+
if self._actor.id in actor_dict:
380+
if self._lon_control is not None:
381+
actor_dict[self._actor.id].change_lon_control(self._lon_control)
382+
if self._lat_control is not None:
383+
actor_dict[self._actor.id].change_lat_control(self._lat_control)
384+
else:
385+
return py_trees.common.Status.FAILURE
386+
387+
return py_trees.common.Status.SUCCESS
388+
389+
332390
class UpdateAllActorControls(AtomicBehavior):
333391

334392
"""

srunner/scenarios/open_scenario.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,14 @@ def _create_behavior(self):
258258
Basic behavior do nothing, i.e. Idle
259259
"""
260260

261-
stories_behavior = py_trees.composites.Parallel(policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL, name="OSCStories")
261+
stories_behavior = py_trees.composites.Parallel(policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL,
262+
name="OSCStories")
262263
joint_actor_list = self.other_actors + self.ego_vehicles + [None]
263264

264265
for story in self.config.stories:
265266
story_name = story.get("name")
266-
story_behavior = py_trees.composites.Parallel(policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL, name=story_name)
267+
story_behavior = py_trees.composites.Parallel(policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL,
268+
name=story_name)
267269
for act in story.iter("Act"):
268270

269271
act_sequence = py_trees.composites.Sequence(
@@ -289,7 +291,8 @@ def _create_behavior(self):
289291
for entity in actor.iter("EntityRef"):
290292
entity_name = entity.attrib.get('entityRef', None)
291293
for k, _ in enumerate(joint_actor_list):
292-
if joint_actor_list[k] and entity_name == joint_actor_list[k].attributes['role_name']:
294+
if (joint_actor_list[k] and
295+
entity_name == joint_actor_list[k].attributes['role_name']):
293296
actor_ids.append(k)
294297
break
295298

@@ -298,10 +301,11 @@ def _create_behavior(self):
298301
sequence.attrib.get('name')))
299302
actor_ids.append(len(joint_actor_list) - 1)
300303

301-
# Collect catalog reference maneuvers in order to process them at the same time as normal maneuvers
304+
# Collect catalog reference maneuvers to process them at the same time as normal maneuvers
302305
catalog_maneuver_list = []
303306
for catalog_reference in sequence.iter("CatalogReference"):
304-
catalog_maneuver = OpenScenarioParser.get_catalog_entry(self.config.catalogs, catalog_reference)
307+
catalog_maneuver = OpenScenarioParser.get_catalog_entry(self.config.catalogs,
308+
catalog_reference)
305309
catalog_maneuver_list.append(catalog_maneuver)
306310
all_maneuvers = itertools.chain(iter(catalog_maneuver_list), sequence.iter("Maneuver"))
307311
single_sequence_iteration = py_trees.composites.Parallel(
@@ -319,7 +323,8 @@ def _create_behavior(self):
319323
if child.tag == "Action":
320324
for actor_id in actor_ids:
321325
maneuver_behavior = OpenScenarioParser.convert_maneuver_to_atomic(
322-
child, joint_actor_list[actor_id], joint_actor_list, self.config.catalogs)
326+
child, joint_actor_list[actor_id],
327+
joint_actor_list, self.config.catalogs)
323328
maneuver_behavior = StoryElementStatusToBlackboard(
324329
maneuver_behavior, "ACTION", child.attrib.get('name'))
325330
parallel_actions.add_child(
@@ -370,7 +375,8 @@ def _create_behavior(self):
370375
start_triggers = act.find("StartTrigger")
371376
if list(start_triggers) is not None:
372377
for start_condition in start_triggers:
373-
parallel_start_criteria = self._create_condition_container(start_condition, story, "StartConditions")
378+
parallel_start_criteria = self._create_condition_container(start_condition, story,
379+
"StartConditions")
374380
if parallel_start_criteria.children:
375381
start_conditions.add_child(parallel_start_criteria)
376382
end_triggers = act.find("StopTrigger")

srunner/tools/openscenario_parser.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
ChangeActorControl,
3333
ChangeActorWaypoints,
3434
ChangeActorLateralMotion,
35+
DeActivateActorControlComponents,
3536
SyncArrivalOSC,
3637
Idle)
3738
# pylint: disable=unused-import
@@ -1111,13 +1112,19 @@ def convert_maneuver_to_atomic(action, actor, actor_list, catalogs):
11111112
raise AttributeError("Unknown speed action")
11121113
elif private_action.find('ActivateControllerAction') is not None:
11131114
private_action = private_action.find('ActivateControllerAction')
1114-
activate = strtobool(private_action.attrib.get('longitudinal'))
1115-
atomic = ChangeAutoPilot(actor, activate, name=maneuver_name)
1115+
lon_control = None
1116+
lat_control = None
1117+
if 'longitudinal' in private_action.attrib.keys():
1118+
lon_control = strtobool(private_action.attrib.get('longitudinal'))
1119+
if 'lateral' in private_action.attrib.keys():
1120+
lat_control = strtobool(private_action.attrib.get('lateral'))
1121+
atomic = DeActivateActorControlComponents(actor, lon_control, lat_control, name=maneuver_name)
11161122
elif private_action.find('ControllerAction') is not None:
11171123
controller_action = private_action.find('ControllerAction')
11181124
module, args = OpenScenarioParser.get_controller(controller_action, catalogs)
11191125
atomic = ChangeActorControl(actor, control_py_module=module, args=args,
1120-
scenario_file_path=OpenScenarioParser.osc_filepath)
1126+
scenario_file_path=OpenScenarioParser.osc_filepath,
1127+
name=maneuver_name)
11211128
elif private_action.find('TeleportAction') is not None:
11221129
teleport_action = private_action.find('TeleportAction')
11231130
position = teleport_action.find('Position')

0 commit comments

Comments
 (0)