Skip to content

Commit 55725bd

Browse files
committed
Rework ActivateControllerAction OSC action
1 parent 16fecb6 commit 55725bd

File tree

8 files changed

+157
-64
lines changed

8 files changed

+157
-64
lines changed

.pylintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[MESSAGES CONTROL]
22
max-line-length=120
3-
disable=no-self-use,anomalous-backslash-in-string,too-many-arguments,too-few-public-methods,too-many-instance-attributes,redefined-variable-type,unused-argument,bad-continuation,too-many-lines,too-many-branches,locally-disabled,too-many-locals,too-many-statements,duplicate-code,too-many-nested-blocks,fixme
3+
disable=no-self-use,anomalous-backslash-in-string,too-many-arguments,too-few-public-methods,too-many-instance-attributes,redefined-variable-type,unused-argument,bad-continuation,too-many-lines,too-many-branches,locally-disabled,too-many-locals,too-many-statements,duplicate-code,too-many-nested-blocks,fixme,useless-object-inheritance
44
ignored-modules=carla,carla.command,agents.navigation.basic_agent,agents.navigation.roaming_agent,agents.tools.misc,agents.navigation.local_planner,agents.navigation.global_route_planner,agents.navigation.global_route_planner_dao,shutil,carla_msgs,nav_msgs,sensor_msgs,std_msgs,tf,cv_bridge,geometry_msgs,rosgraph_msgs,rospy
55
variable-rgx=[a-z0-9_]{1,40}$
66
function-rgx=[a-z0-9_]{1,40}$

Docs/CHANGELOG.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@
1111
* [CARLA ScenarioRunner 0.9.2](#carla-scenariorunner-092)
1212

1313
## Latest Changes
14+
### :rocket: New Features
15+
* OpenSCENARIO Support:
16+
* Added controller using CARLA's autopilot (in replacement for ActivateControllerAction)
17+
* Added support for storyboards with multiple stories
18+
* Added support for ObjectControllers. Note that the controller has to be implemented in Python,
19+
or be one of the provided controllers.
20+
* Updated ActivateControllerAction to its specified behavior according to OSC 1.0
1421
### :ghost: Maintenance
1522
* Generalized visualizer attached to OSC controllers
16-
17-
18-
* Fixed bug at the Getting Started docs which caused an import error
23+
* Extended SimpleVehicleController
24+
* Fixed bug at the Getting Started docs which caused an import error
1925

2026
## CARLA ScenarioRunner 0.9.11
2127
### :rocket: New Features
@@ -24,7 +30,6 @@
2430
* Added a static obstacle evasion OpenSCENARIO scenario
2531
* Added support for OSC Routing options
2632
* Added support for OSC SynchronizeAction
27-
* Added support for OSC LaneOffsetAction
2833
* Added support to place OSC controller implementation alongside the OSC scenario
2934
* Updated *GameTime.restart()* at *srunner/scenariomanager/timer.py* to also reset the frame number
3035
### :bug: Bug Fixes

srunner/scenariomanager/actorcontrols/actor_control.py

+18
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ def set_init_speed(self):
173173
"""
174174
self.control_instance.set_init_speed()
175175

176+
def change_lon_control(self, enable):
177+
"""
178+
Enable/Disable longitudinal control component of actor controller
179+
180+
Args:
181+
enable (boolean): Enable/Disable signal
182+
"""
183+
self.control_instance.change_lon_control(enable)
184+
185+
def change_lat_control(self, enable):
186+
"""
187+
Enable/Disable lateral control component of actor controller
188+
189+
Args:
190+
enable (boolean): Enable/Disable signal
191+
"""
192+
self.control_instance.change_lat_control(enable)
193+
176194
def run_step(self):
177195
"""
178196
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
@@ -47,6 +53,8 @@ class BasicControl(object):
4753
_target_speed = 0
4854
_reached_goal = False
4955
_init_speed = False
56+
_use_lon_control = True
57+
_use_lat_control = True
5058

5159
def __init__(self, actor):
5260
"""
@@ -90,6 +98,24 @@ def set_init_speed(self):
9098
"""
9199
self._init_speed = True
92100

101+
def change_lon_control(self, enable):
102+
"""
103+
Enable/Disable longitudinal control component
104+
105+
Args:
106+
enable (boolean): Enable/Disable signal
107+
"""
108+
self._use_lon_control = enable
109+
110+
def change_lat_control(self, enable):
111+
"""
112+
Enable/Disable lateral control component
113+
114+
Args:
115+
enable (boolean): Enable/Disable signal
116+
"""
117+
self._use_lat_control = enable
118+
93119
def check_reached_waypoint_goal(self):
94120
"""
95121
Check if the actor reached the end of the waypoint list

srunner/scenariomanager/actorcontrols/simple_vehicle_control.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class SimpleVehicleControl(BasicControl):
5454
(consider_trafficlights, true/false) - Enable consideration of traffic lights
5555
(max_deceleration, float) - Use a reasonable deceleration value for
5656
this vehicle
57+
(max_acceleration, float) - Use a reasonable acceleration value for
58+
this vehicle
5759
(attach_camera, true/false) - Attach OpenCV display to actor
5860
(useful for debugging)
5961
@@ -68,6 +70,12 @@ class SimpleVehicleControl(BasicControl):
6870
Defaults to False.
6971
_proximity_threshold (float): Distance in front of actor in which obstacles are considered
7072
Defaults to infinity.
73+
_consider_trafficlights (boolean): Enable/Disable consideration of red traffic lights
74+
Defaults to False.
75+
_max_deceleration (float): Deceleration value of the vehicle when braking
76+
Defaults to None (infinity).
77+
_max_acceleration (float): Acceleration value of the vehicle when accelerating
78+
Defaults to None (infinity).
7179
_cv_image (CV Image): Contains the OpenCV image, in case a debug camera is attached to the actor
7280
Defaults to None.
7381
_camera (sensor.camera.rgb): Debug camera attached to actor
@@ -277,11 +285,10 @@ def _set_new_velocity(self, next_location):
277285

278286
if self._consider_traffic_lights:
279287
if (self._actor.is_at_traffic_light() and
280-
self._actor.get_traffic_light_state() == carla.TrafficLightState.Red):
288+
self._actor.get_traffic_light_state() == carla.TrafficLightState.Red):
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

+24-18
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,14 +323,15 @@ 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(
326-
oneshot_with_check(variable_name=# See note in get_xml_path
327-
get_xml_path(story, sequence) + '>' + \
328-
get_xml_path(maneuver, child),
329-
behaviour=maneuver_behavior))
331+
oneshot_with_check(variable_name= # See note in get_xml_path
332+
get_xml_path(story, sequence) + '>' + \
333+
get_xml_path(maneuver, child),
334+
behaviour=maneuver_behavior))
330335

331336
if child.tag == "StartTrigger":
332337
# There is always one StartConditions block per Event
@@ -340,14 +345,14 @@ def _create_behavior(self):
340345
event_sequence.add_child(parallel_actions)
341346
maneuver_parallel.add_child(
342347
oneshot_with_check(variable_name=get_xml_path(story, sequence) + '>' +
343-
get_xml_path(maneuver, event), # See get_xml_path
344-
behaviour=event_sequence))
348+
get_xml_path(maneuver, event), # See get_xml_path
349+
behaviour=event_sequence))
345350
maneuver_parallel = StoryElementStatusToBlackboard(
346351
maneuver_parallel, "MANEUVER", maneuver.attrib.get('name'))
347352
single_sequence_iteration.add_child(
348353
oneshot_with_check(variable_name=get_xml_path(story, sequence) + '>' +
349-
maneuver.attrib.get('name'), # See get_xml_path
350-
behaviour=maneuver_parallel))
354+
maneuver.attrib.get('name'), # See get_xml_path
355+
behaviour=maneuver_parallel))
351356

352357
# OpenSCENARIO refers to Sequences as Scenes in this instance
353358
single_sequence_iteration = StoryElementStatusToBlackboard(
@@ -360,7 +365,7 @@ def _create_behavior(self):
360365
if sequence_behavior.children:
361366
parallel_sequences.add_child(
362367
oneshot_with_check(variable_name=get_xml_path(story, sequence),
363-
behaviour=sequence_behavior))
368+
behaviour=sequence_behavior))
364369

365370
if parallel_sequences.children:
366371
parallel_sequences = StoryElementStatusToBlackboard(
@@ -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")
@@ -390,8 +396,8 @@ def _create_behavior(self):
390396
story_behavior.add_child(act_sequence)
391397

392398
stories_behavior.add_child(oneshot_with_check(variable_name=get_xml_path(story, story) + '>' +
393-
story_name, # See get_xml_path
394-
behaviour=story_behavior))
399+
story_name, # See get_xml_path
400+
behaviour=story_behavior))
395401

396402
# Build behavior tree
397403
behavior = py_trees.composites.Parallel(

0 commit comments

Comments
 (0)