Skip to content

Commit b6ef71d

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

File tree

9 files changed

+159
-31
lines changed

9 files changed

+159
-31
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

+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

+9-2
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
@@ -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)