Beispiel #1
0
 def _parse_property(self, text, topic_types, pns=""):
     ast = self.property_parser.parse(text)
     refs = {}
     events = (ast.scope.activator, ast.pattern.trigger,
               ast.pattern.behaviour, ast.scope.terminator)
     for event in events:
         if event is None or not event.is_publish:
             continue
         topic = RosName.resolve(event.topic, private_ns=pns)
         if topic not in topic_types:
             raise HplTypeError(
                 "No type information for topic '{}'".format(topic))
         rostype = topic_types[topic]
         if event.alias:
             assert event.alias not in refs, "duplicate event alias"
             assert rostype.is_message, "topic type is not a message"
             # update refs without worries about temporal order of events
             # prop.sanity_check() already checks that
             refs[event.alias] = rostype
     for event in events:
         if event is None or not event.is_publish:
             continue
         topic = RosName.resolve(event.topic, private_ns=pns)
         rostype = topic_types[topic]
         event.predicate.refine_types(rostype, **refs)
     return ast
Beispiel #2
0
 def _parse_assumption(self, text, topic_types, pns=""):
     ast = self.assumption_parser.parse(text)
     # assumptions, like events, also have .topic and .predicate
     topic = RosName.resolve(ast.topic, private_ns=pns)
     if topic not in topic_types:
         raise HplTypeError(
             "No type information for topic '{}'".format(topic))
     ast.predicate.refine_types(topic_types[topic])
     return ast
Beispiel #3
0
    def extract_node(self, name, node_name, pkg_name, ns, ws, rossystem):
        pkg = Package(pkg_name)
        rospack = rospkg.RosPack()
        pkg.path = rospack.get_path(pkg_name)
        roscomponent = None
        #HAROS NODE EXTRACTOR
        node = Node(node_name, pkg, rosname=RosName(node_name))

        srcdir = pkg.path[len(ws):]
        srcdir = os.path.join(ws, srcdir.split(os.sep, 1)[0])
        bindir = os.path.join(ws, "build")
        #HAROS CMAKE PARSER
        parser = RosCMakeParser(srcdir, bindir, pkgs=[pkg])
        model_str = ""
        if os.path.isfile(os.path.join(pkg.path, "CMakeLists.txt")):
            parser.parse(os.path.join(pkg.path, "CMakeLists.txt"))
            for target in parser.executables.itervalues():
                if target.output_name == node_name:
                    for file_in in target.files:
                        full_path = file_in
                        relative_path = full_path.replace(
                            pkg.path + "/", "").rpartition("/")[0]
                        file_name = full_path.rsplit('/', 1)[-1]
                        source_file = SourceFile(file_name, relative_path, pkg)
                        node.source_files.append(source_file)
            if node.language == "cpp":
                parser = CppAstParser(workspace=ws)
                analysis = RoscppExtractor(pkg, ws)
            if node.language == "py":
                parser = PyAstParser(workspace=ws)
                analysis = RospyExtractor(pkg, ws)
            #node.source_tree = parser.global_scope
            for sf in node.source_files:
                try:
                    if parser.parse(sf.path) is not None:
                        # ROS MODEL EXTRACT PRIMITIVES
                        if node.language == "py":
                            node_name = node_name.replace(".py", "")
                        rosmodel = ros_model(pkg.name, node_name, node_name)
                        roscomponent = ros_component(name, ns)
                        try:
                            self.extract_primitives(node, parser, analysis,
                                                    rosmodel, roscomponent,
                                                    pkg_name, node_name,
                                                    node_name)
                            # SAVE ROS MODEL
                            model_str = rosmodel.save_model(
                                self.args.model_path)
                        except:
                            pass
                except:
                    pass
            if rossystem is not None and roscomponent is not None:
                rossystem.add_component(roscomponent)
        if self.args.output:
            print model_str
Beispiel #4
0
 def _get_node_topics(self, node, pns):
     # FIXME this should be in the metamodel or extraction code
     topic_types = {}  # topic -> TypeToken
     for call in chain(node.advertise, node.subscribe):
         if call.name == "?" or call.type == "?":
             self.log.warning(
                 "Skipping unresolved topic '%s' in node '%s'.", call.name,
                 node.node_name)
             continue
         topic = RosName.resolve(call.name, private_ns=pns)
         try:
             topic_types[topic] = get_type(call.type)
         except KeyError as e:
             self.log.warning(str(e))
     return topic_types
Beispiel #5
0
    def launch(self):
        self.parse_arg()
        if self.args.node:
            #FIND WORKSPACE:
            #Fixme: the env variable ROS_PACKAGE_PATH is not the best way to extract the workspace path
            ros_pkg_path = os.environ.get("ROS_PACKAGE_PATH")
            ws = ros_pkg_path[:ros_pkg_path.find("/src:")]
            #FIND PACKAGE PATH
            pkg = Package(self.args.package_name)
            rospack = rospkg.RosPack()
            pkg.path = rospack.get_path(self.args.package_name)

            #BONSAI PARSER
            parser = CppAstParser(workspace=ws)
            parser.set_library_path("/usr/lib/llvm-3.8/lib")
            parser.set_standard_includes(
                "/usr/lib/llvm-3.8/lib/clang/3.8.0/include")
            db_dir = os.path.join(ws, "build")
            if os.path.isfile(os.path.join(db_dir, "compile_commands.json")):
                parser.set_database(db_dir)
            #HAROS NODE EXTRACTOR
            analysis = NodeExtractor(pkg,
                                     env=dict(os.environ),
                                     ws=ws,
                                     node_cache=False,
                                     parse_nodes=True)
            node = Node(self.args.name, pkg, rosname=RosName(self.args.name))
            srcdir = pkg.path[len(ws):]
            srcdir = os.path.join(ws, srcdir.split(os.sep, 1)[0])
            bindir = os.path.join(ws, "build")
            #HAROS CMAKE PARSER
            parser = RosCMakeParser(srcdir, bindir, pkgs=[pkg])
            parser.parse(os.path.join(pkg.path, "CMakeLists.txt"))
            for target in parser.executables.itervalues():
                if target.output_name == self.args.name:
                    for file_in in target.files:
                        full_path = file_in
                        relative_path = full_path.replace(
                            pkg.path + "/", "").rpartition("/")[0]
                        file_name = full_path.rsplit('/', 1)[-1]
                        source_file = SourceFile(file_name, relative_path, pkg)
                        node.source_files.append(source_file)
            parser = CppAstParser(workspace=ws)
            node.source_tree = parser.global_scope
            model_str = ""
            for sf in node.source_files:
                if parser.parse(sf.path) is None:
                    print "File not found"
                else:
                    # ROS MODEL EXTRACT PRIMITIVES
                    rosmodel = ros_model(self.args.package_name,
                                         self.args.name, self.args.name)
                    self.extract_primitives(node, parser.global_scope,
                                            analysis, rosmodel)
                    # SAVE ROS MODEL
                    model_str = rosmodel.save_model()
            if self.args.output:
                print model_str
            else:
                text_file = open(self.args.name + ".ros", "w")
                text_file.write(model_str)
                text_file.close()