behavior_library.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import os
00003 import rospy
00004 from rospkg import RosPack
00005 import xml.etree.ElementTree as ET
00006 import zlib
00007 
00008 
00009 '''
00010 Created on 10.01.2017
00011 
00012 @author: Philipp Schillinger
00013 '''
00014 
00015 class BehaviorLibrary(object):
00016         '''
00017         Provides a list of all known behavior manifests.
00018         '''
00019 
00020         def __init__(self):
00021                 self._rp = RosPack()
00022                 self._behavior_lib = dict()
00023                 self.parse_packages()
00024 
00025 
00026         def parse_packages(self):
00027                 """
00028                 Parses all ROS packages to update the internal behavior library.
00029                 """
00030                 self._behavior_lib = dict()
00031                 for pkg in self._rp.list():
00032                         for export in self._rp._load_manifest(pkg).exports:
00033                                 if export.tag == "flexbe_behaviors":
00034                                         self._add_behavior_manifests(self._rp.get_path(pkg), pkg)
00035 
00036 
00037         def _add_behavior_manifests(self, path, pkg=None):
00038                 """
00039                 Recursively add all behavior manifests in the given folder to the internal library.
00040                 If a package name is specified, only manifests referring to this package are added.
00041 
00042                 @type path: string
00043                 @param path: Path of the folder to be traversed.
00044                 
00045                 @type pkg: string
00046                 @param pkg: Optional name of a package to only add manifests referring to this package.
00047                 """
00048                 for entry in os.listdir(path):
00049                         entry_path = os.path.join(path, entry)
00050                         if os.path.isdir(entry_path):
00051                                 self._add_behavior_manifests(entry_path, pkg)
00052                         elif entry.endswith(".xml") and not entry.startswith("#"):
00053                                 m = ET.parse(entry_path).getroot()
00054                                 # structure sanity check
00055                                 if m.tag != "behavior" \
00056                                 or len(m.findall(".//executable")) == 0 \
00057                                 or m.find("executable").get("package_path") is None \
00058                                 or len(m.find("executable").get("package_path").split(".")) != 2:
00059                                         continue;
00060                                 e = m.find("executable")
00061                                 if pkg is not None and e.get("package_path").split(".")[0] != pkg:
00062                                         continue # ignore if manifest not in specified package
00063                                 be_id = zlib.adler32(e.get("package_path"))
00064                                 self._behavior_lib[be_id] = {
00065                                         "name": m.get("name"),
00066                                         "package": e.get("package_path").split(".")[0],
00067                                         "file": e.get("package_path").split(".")[1],
00068                                         "class": e.get("class")
00069                                 }
00070 
00071 
00072         def get_behavior(self, be_id):
00073                 """
00074                 Provides the library entry corresponding to the given ID.
00075 
00076                 @type be_id: int
00077                 @param be_id: Behavior ID to look up.
00078 
00079                 @return Corresponding library entry or None if not found.
00080                 """
00081                 try:
00082                         return self._behavior_lib[be_id]
00083                 except KeyError:
00084                         rospy.logwarn("Did not find ID %d in libary, updating..." % be_id)
00085                         self.parse_packages()
00086                         return self._behavior_lib.get(be_id, None)
00087 
00088 
00089         def find_behavior(self, be_name):
00090                 """
00091                 Searches for a behavior with the given name and returns it along with its ID.
00092 
00093                 @type be_name: string
00094                 @param be_name: Behavior ID to look up.
00095 
00096                 @return Tuple (be_id, be_entry) corresponding to the name or (None, None) if not found.
00097                 """
00098                 find = lambda: next((id, be) for (id, be) in self._behavior_lib.items() if be["name"] == be_name)
00099                 try:
00100                         return find() 
00101                 except StopIteration:
00102                         rospy.logwarn("Did not find behavior '%s' in libary, updating..." % be_name)
00103                         self.parse_packages()
00104                         return find()
00105 
00106 
00107         def count_behaviors(self):
00108                 """
00109                 Counts the available behaviors.
00110 
00111                 @return Number of behaviors.
00112                 """
00113                 return len(self._behavior_lib)
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 


flexbe_core
Author(s): Philipp Schillinger
autogenerated on Thu Jun 6 2019 19:32:27