Exemple #1
0
    def _set_actor_information(self):
        """
        Extract all actors and their corresponding specification

        NOTE: The rolename property has to be unique!
        """
        for entity in self.xml_tree.iter("Entities"):
            for obj in entity.iter("ScenarioObject"):
                rolename = obj.attrib.get('name', 'simulation')
                args = {}
                for prop in obj.iter("Property"):
                    key = prop.get('name')
                    value = prop.get('value')
                    args[key] = value

                for catalog_reference in obj.iter("CatalogReference"):
                    entry = OpenScenarioParser.get_catalog_entry(self.catalogs, catalog_reference)
                    if entry.tag == "Vehicle":
                        self._extract_vehicle_information(entry, rolename, entry, args)
                    elif entry.tag == "Pedestrian":
                        self._extract_pedestrian_information(entry, rolename, entry, args)
                    elif entry.tag == "MiscObject":
                        self._extract_misc_information(entry, rolename, entry, args)
                    else:
                        self.logger.debug(
                            " A CatalogReference specifies a reference that is not an Entity. Skipping...")

                for vehicle in obj.iter("Vehicle"):
                    self._extract_vehicle_information(obj, rolename, vehicle, args)

                for pedestrian in obj.iter("Pedestrian"):
                    self._extract_pedestrian_information(obj, rolename, pedestrian, args)

                for misc in obj.iter("MiscObject"):
                    self._extract_misc_information(obj, rolename, misc, args)

        # Set transform for all actors
        # This has to be done in a multi-stage loop to resolve relative position settings
        all_actor_transforms_set = False
        while not all_actor_transforms_set:
            all_actor_transforms_set = True
            for actor in self.other_actors + self.ego_vehicles:
                if actor.transform is None:
                    try:
                        actor.transform = self._get_actor_transform(actor.rolename)
                    except AttributeError as e:
                        if "Object '" in str(e):
                            ref_actor_rolename = str(e).split('\'')[1]
                            for ref_actor in self.other_actors + self.ego_vehicles:
                                if ref_actor.rolename == ref_actor_rolename:
                                    if ref_actor.transform is not None:
                                        raise e
                                    break
                        else:
                            raise e
                    if actor.transform is None:
                        all_actor_transforms_set = False
    def _create_behavior(self):
        """
        Basic behavior do nothing, i.e. Idle
        """

        story_behavior = py_trees.composites.Parallel(
            policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL, name="Story")

        joint_actor_list = self.other_actors + self.ego_vehicles + [None]

        for act in self.config.story.iter("Act"):

            act_sequence = py_trees.composites.Sequence(
                name="Act StartConditions and behaviours")

            start_conditions = py_trees.composites.Parallel(
                policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE,
                name="StartConditions Group")

            parallel_behavior = py_trees.composites.Parallel(
                policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ONE,
                name="Maneuver + EndConditions Group")

            parallel_sequences = py_trees.composites.Parallel(
                policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL,
                name="Maneuvers")

            for sequence in act.iter("ManeuverGroup"):
                sequence_behavior = py_trees.composites.Sequence(
                    name=sequence.attrib.get('name'))
                repetitions = sequence.attrib.get('maximumExecutionCount', 1)

                for _ in range(int(repetitions)):

                    actor_ids = []
                    for actor in sequence.iter("Actors"):
                        for entity in actor.iter("EntityRef"):
                            entity_name = entity.attrib.get('entityRef', None)
                            for k, _ in enumerate(joint_actor_list):
                                if joint_actor_list[
                                        k] and entity_name == joint_actor_list[
                                            k].attributes['role_name']:
                                    actor_ids.append(k)
                                    break

                    if not actor_ids:
                        print(
                            "Warning: Maneuvergroup {} does not use reference actors!"
                            .format(sequence.attrib.get('name')))
                        actor_ids.append(len(joint_actor_list) - 1)

                # Collect catalog reference maneuvers in order to process them at the same time as normal maneuvers
                    catalog_maneuver_list = []
                    for catalog_reference in sequence.iter("CatalogReference"):
                        catalog_maneuver = OpenScenarioParser.get_catalog_entry(
                            self.config.catalogs, catalog_reference)
                        catalog_maneuver_list.append(catalog_maneuver)
                    all_maneuvers = itertools.chain(
                        iter(catalog_maneuver_list), sequence.iter("Maneuver"))
                    single_sequence_iteration = py_trees.composites.Parallel(
                        policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL,
                        name=sequence_behavior.name)
                    for maneuver in all_maneuvers:  # Iterates through both CatalogReferences and Maneuvers
                        maneuver_parallel = py_trees.composites.Parallel(
                            policy=py_trees.common.ParallelPolicy.
                            SUCCESS_ON_ALL,
                            name="Maneuver " + maneuver.attrib.get('name'))
                        for event in maneuver.iter("Event"):
                            event_sequence = py_trees.composites.Sequence(
                                name="Event " + event.attrib.get('name'))
                            parallel_actions = py_trees.composites.Parallel(
                                policy=py_trees.common.ParallelPolicy.
                                SUCCESS_ON_ALL,
                                name="Actions")
                            for child in event.iter():
                                if child.tag == "Action":
                                    for actor_id in actor_ids:
                                        maneuver_behavior = OpenScenarioParser.convert_maneuver_to_atomic(
                                            child, joint_actor_list[actor_id],
                                            joint_actor_list,
                                            self.config.catalogs)
                                        maneuver_behavior = StoryElementStatusToBlackboard(
                                            maneuver_behavior, "ACTION",
                                            child.attrib.get('name'))
                                        parallel_actions.add_child(
                                            oneshot_with_check(variable_name=# See note in get_xml_path
                                                               get_xml_path(self.config.story, sequence) + '>' + \
                                                               get_xml_path(maneuver, child),
                                                               behaviour=maneuver_behavior))

                                if child.tag == "StartTrigger":
                                    # There is always one StartConditions block per Event
                                    parallel_condition_groups = self._create_condition_container(
                                        child, "Parallel Condition Groups",
                                        sequence, maneuver)
                                    event_sequence.add_child(
                                        parallel_condition_groups)

                            parallel_actions = StoryElementStatusToBlackboard(
                                parallel_actions, "EVENT",
                                event.attrib.get('name'))
                            event_sequence.add_child(parallel_actions)
                            maneuver_parallel.add_child(
                                oneshot_with_check(
                                    variable_name=get_xml_path(
                                        self.config.story, sequence) + '>' +
                                    get_xml_path(maneuver,
                                                 event),  # See get_xml_path
                                    behaviour=event_sequence))
                        maneuver_parallel = StoryElementStatusToBlackboard(
                            maneuver_parallel, "MANEUVER",
                            maneuver.attrib.get('name'))
                        single_sequence_iteration.add_child(
                            oneshot_with_check(
                                variable_name=get_xml_path(
                                    self.config.story, sequence) + '>' +
                                maneuver.attrib.get(
                                    'name'),  # See get_xml_path
                                behaviour=maneuver_parallel))

                    # OpenSCENARIO refers to Sequences as Scenes in this instance
                    single_sequence_iteration = StoryElementStatusToBlackboard(
                        single_sequence_iteration, "SCENE",
                        sequence.attrib.get('name'))
                    single_sequence_iteration = repeatable_behavior(
                        single_sequence_iteration,
                        get_xml_path(self.config.story, sequence))

                    sequence_behavior.add_child(single_sequence_iteration)

                if sequence_behavior.children:
                    parallel_sequences.add_child(
                        oneshot_with_check(variable_name=get_xml_path(
                            self.config.story, sequence),
                                           behaviour=sequence_behavior))

            if parallel_sequences.children:
                parallel_sequences = StoryElementStatusToBlackboard(
                    parallel_sequences, "ACT", act.attrib.get('name'))
                parallel_behavior.add_child(parallel_sequences)

            start_triggers = act.find("StartTrigger")
            if list(start_triggers) is not None:
                for start_condition in start_triggers:
                    parallel_start_criteria = self._create_condition_container(
                        start_condition, "StartConditions")
                    if parallel_start_criteria.children:
                        start_conditions.add_child(parallel_start_criteria)
            end_triggers = act.find("StopTrigger")
            if end_triggers is not None and list(end_triggers) is not None:
                for end_condition in end_triggers:
                    parallel_end_criteria = self._create_condition_container(
                        end_condition, "EndConditions", success_on_all=False)
                    if parallel_end_criteria.children:
                        parallel_behavior.add_child(parallel_end_criteria)

            if start_conditions.children:
                act_sequence.add_child(start_conditions)
            if parallel_behavior.children:
                act_sequence.add_child(parallel_behavior)

            if act_sequence.children:
                story_behavior.add_child(act_sequence)

        # Build behavior tree
        behavior = py_trees.composites.Parallel(
            policy=py_trees.common.ParallelPolicy.SUCCESS_ON_ALL,
            name="behavior")

        env_behavior = self._create_environment_behavior()
        if env_behavior is not None:
            behavior.add_child(
                oneshot_with_check(variable_name="InitialEnvironmentSettings",
                                   behaviour=env_behavior))

        init_behavior = self._create_init_behavior()
        if init_behavior is not None:
            behavior.add_child(
                oneshot_with_check(variable_name="InitialActorSettings",
                                   behaviour=init_behavior))

        behavior.add_child(story_behavior)

        return behavior