behavior_library.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import os
3 import rospy
4 from rospkg import RosPack
5 import xml.etree.ElementTree as ET
6 import zlib
7 
8 
9 '''
10 Created on 10.01.2017
11 
12 @author: Philipp Schillinger
13 '''
14 
15 class BehaviorLibrary(object):
16  '''
17  Provides a list of all known behavior manifests.
18  '''
19 
20  def __init__(self):
21  self._rp = RosPack()
22  self._behavior_lib = dict()
23  self.parse_packages()
24 
25 
26  def parse_packages(self):
27  """
28  Parses all ROS packages to update the internal behavior library.
29  """
30  self._behavior_lib = dict()
31  for pkg in self._rp.list():
32  for export in self._rp._load_manifest(pkg).exports:
33  if export.tag == "flexbe_behaviors":
34  self._add_behavior_manifests(self._rp.get_path(pkg), pkg)
35 
36 
37  def _add_behavior_manifests(self, path, pkg=None):
38  """
39  Recursively add all behavior manifests in the given folder to the internal library.
40  If a package name is specified, only manifests referring to this package are added.
41 
42  @type path: string
43  @param path: Path of the folder to be traversed.
44 
45  @type pkg: string
46  @param pkg: Optional name of a package to only add manifests referring to this package.
47  """
48  for entry in os.listdir(path):
49  entry_path = os.path.join(path, entry)
50  if os.path.isdir(entry_path):
51  self._add_behavior_manifests(entry_path, pkg)
52  elif entry.endswith(".xml") and not entry.startswith("#"):
53  m = ET.parse(entry_path).getroot()
54  # structure sanity check
55  if m.tag != "behavior" \
56  or len(m.findall(".//executable")) == 0 \
57  or m.find("executable").get("package_path") is None \
58  or len(m.find("executable").get("package_path").split(".")) != 2:
59  continue;
60  e = m.find("executable")
61  if pkg is not None and e.get("package_path").split(".")[0] != pkg:
62  continue # ignore if manifest not in specified package
63  be_id = zlib.adler32(e.get("package_path"))
64  self._behavior_lib[be_id] = {
65  "name": m.get("name"),
66  "package": e.get("package_path").split(".")[0],
67  "file": e.get("package_path").split(".")[1],
68  "class": e.get("class")
69  }
70 
71 
72  def get_behavior(self, be_id):
73  """
74  Provides the library entry corresponding to the given ID.
75 
76  @type be_id: int
77  @param be_id: Behavior ID to look up.
78 
79  @return Corresponding library entry or None if not found.
80  """
81  try:
82  return self._behavior_lib[be_id]
83  except KeyError:
84  rospy.logwarn("Did not find ID %d in libary, updating..." % be_id)
85  self.parse_packages()
86  return self._behavior_lib.get(be_id, None)
87 
88 
89  def find_behavior(self, be_name):
90  """
91  Searches for a behavior with the given name and returns it along with its ID.
92 
93  @type be_name: string
94  @param be_name: Behavior ID to look up.
95 
96  @return Tuple (be_id, be_entry) corresponding to the name or (None, None) if not found.
97  """
98  find = lambda: next((id, be) for (id, be) in self._behavior_lib.items() if be["name"] == be_name)
99  try:
100  return find()
101  except StopIteration:
102  rospy.logwarn("Did not find behavior '%s' in libary, updating..." % be_name)
103  self.parse_packages()
104  return find()
105 
106 
107  def count_behaviors(self):
108  """
109  Counts the available behaviors.
110 
111  @return Number of behaviors.
112  """
113  return len(self._behavior_lib)
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
def _add_behavior_manifests(self, path, pkg=None)


flexbe_core
Author(s): Philipp Schillinger
autogenerated on Wed Jun 5 2019 21:51:59