示例#1
0
    def populateData(self):
        main_thread = self.associated_class.getMainThread()

        if main_thread is None:
            return False, "Unable to get the Main Thread"

        # Ottengo le informazioni necessarie per i thread di tipo Timer:
        # - Source Text
        # - Period

        thread_function = tfs.getSubprogram(self.thread)
        if thread_function is None:
            return False, "Unable to find the right Subprogram"

        # TRANSFORMATION FRAME

        # Controllo l'uso del Transformation Frame
        self.thread_uses_tf = self.setUsesTransformationFrame()

        # Source Text

        self.source_text_function = self.createSourceTextFileFromSourceText(
            tfs.getSourceText(thread_function),
            tfs.getSourceName(thread_function))

        if self.source_text_function is None:
            return False, "Unable to find property Source_Text or Source_Name"

        self.source_text_function.setTF(self.thread_uses_tf)

        # FREQUENCY

        (period, period_unit) = tfs.getPeriod(self.thread)

        if period is None or period_unit is None:
            return False, "Unable to find property Period with relative value and unit"

        # Conversione in secondi della frequenza a partire da qualunque unità di misura
        try:
            period_quantity = ureg("{} {}".format(period, period_unit))
            period_quantity.ito(ureg.second)
            self.frequency_in_hz = 1.0 / period_quantity.magnitude
            self.period_in_seconds = period_quantity.magnitude
        except ValueError:
            return False, "Unable to convert Period in seconds"

        # TIMER
        var_timer = Variable(self.associated_class)
        var_timer.setName("timer_{}".format(self.name))
        var_timer.setType(ROS_Timer(self.associated_class))
        self.associated_class.addInternalVariable(var_timer)

        ######################
        ### TIMER CALLBACK ###
        ######################

        self.timerCallback = Method(self.associated_class)
        self.timerCallback.method_name = "{}_callback".format(self.name)
        self.timerCallback.return_type = Void(self.associated_class)
        self.timerCallback.namespace = self.associated_class.class_name

        input_par = Variable(self.associated_class)
        input_par.setIsParameter()
        input_par.setType(ROS_TimerEvent(self.associated_class))
        input_par.setName("")
        self.timerCallback.addInputParameter(input_par)

        # Aggiungo la chiamata alla funzione custom
        if self.source_text_function:
            code = "{};".format(self.source_text_function.generateInlineCode())
            self.timerCallback.addMiddleCode(code)

        self.associated_class.addPrivateMethod(self.timerCallback)

        main_thread.prepare.addMiddleCode(
            "{} = handle.createTimer(ros::Duration({}), {}, this);".format(
                var_timer.name, self.period_in_seconds,
                self.timerCallback.getThreadPointer()))

        return True, ""
示例#2
0
    def populateData(self):
        main_thread = self.associated_class.getMainThread()

        if main_thread == None:
            return (False, "Unable to get the Main Thread")

        # Ottengo le informazioni necessarie per i thread di tipo Publisher:
        # - Source Text
        # - Period

        thread_function = tfs.getSubprogram(self.thread)
        if thread_function == None:
            return (False, "Unable to find the right Subprogram")

        ############################
        ### TRANSFORMATION FRAME ###
        ############################

        # Controllo l'uso del Transformation Frame
        self.thread_uses_tf = self.setUsesTransformationFrame()

        ###################
        ### Output Port ###
        ###################

        # Ottengo la connesione che mappa la porta di input del thread subscriber
        # con quella che entra nel process
        process_output_port = tfs.getConnectionPortInfoBySource(self.process, self.type, self.output_port_name)
        if process_output_port is None:
            return False, "Unable to find the right binding between process input port and thread input port"

        (dest_parent_name, dest_name) = tfs.getDestFromPortInfo(process_output_port)

        if dest_parent_name is None or dest_name is None:
            return False, "Unable to find the process input port name"

        self.process_port = tfs.getFeatureByName(self.process, name=dest_name)
        if self.process_port is None:
            return False, "Unable to find the process input port name feature"

        (aadl_namespace, aadl_type) = tfs.getPortDatatypeByPort(self.process_port)
        if aadl_namespace is None or aadl_type is None:
            return False, "Unable to identify process port type"

        # Controllo se c'è un file ASN.1 associato alla porta. Se c'è allora il tipo di messaggio
        # è custom e lo dovrò generare, mentre se non c'è allora è un messaggio standard ROS
        port_data_info = tfs.getPortDataInfo(self.process_port)
        if port_data_info is None:
            return False, "Unable to get the port data info for process port"

        port_data_source_asn = tfs.getSourceText(port_data_info)
        if port_data_source_asn is None:
            # Se è None allora non c'è alcun file ASN.1 associato e quindi è un messaggio standard ROS
            raw_output_type = dt.getROSDatatypeFromAADL(aadl_namespace, aadl_type, self.associated_class)
            if raw_output_type is None:
                return False, "Datatype {} NOT supported".format(raw_output_type)
            else:
                self.output_type = raw_output_type
        else:
            self.custom_message = mfs.getMessageFromJSON(aadl_namespace,
                                                         aadl_type,
                                                         port_data_source_asn,
                                                         self.associated_class)

            self.output_type = Type(self.associated_class)
            self.output_type.setTypeName(self.custom_message.name)
            self.output_type.setNamespace(self.custom_message.namespace)

        # Associo la librerie del messaggio al tipo di output, sia custom che standard
        output_type_library = Library()
        output_type_library.setPath("{}/{}.h".format(self.output_type.namespace, self.output_type.type_name))

        self.output_type.setLibrary(output_type_library)

        ###################
        ### Source Text ###
        ###################

        self.source_text_function = self.createSourceTextFileFromSourceText(tfs.getSourceText(thread_function),
                                                                            tfs.getSourceName(thread_function))

        if self.source_text_function is None:
            return False, "Unable to find property Source_Text or Source_Name"

        self.source_text_function.setTF(self.thread_uses_tf)
        self.source_text_function.setFunctionType(self.output_type)

        #################
        ### FREQUENCY ###
        #################

        (period, period_unit) = tfs.getPeriod(self.thread)

        if period is None or period_unit is None:
            return False, "Unable to find property Period with relative value and unit"

        # Conversione in secondi della frequenza a partire da qualunque unità di misura
        try:
            period_quantity = ureg("{} {}".format(period, period_unit))
            period_quantity.ito(ureg.second)
            self.frequency_in_hz = 1.0 / period_quantity.magnitude
            self.period_in_seconds = period_quantity.magnitude
        except ValueError:
            return False, "Unable to convert Period in seconds"

        # param_freq = Variable( self.associated_class )
        # param_freq.setName( "frequency_{}".format(self.name) )
        # param_freq.setType( Int( self.associated_class ))
        # self.associated_class.addParameter( param_freq )

        #############
        ### TOPIC ###
        #############

        (status, desc) = self.getDefaultTopicName(self.output_port_name, output=True)
        if status is False:
            return status, desc

        #####################
        ### PUBLISHER VAR ###
        #####################

        var_publisher_pub = Variable(self.associated_class)
        var_publisher_pub.setName("pub_{}".format(self.name))
        var_publisher_pub.setType(ROS_Publisher(self.associated_class))
        self.associated_class.addInternalVariable(var_publisher_pub)

        #######################
        ### PUBLISHER TIMER ###
        #######################

        var_timer_pub = Variable(self.associated_class)
        var_timer_pub.setName("timer_{}".format(self.name))
        var_timer_pub.setType(ROS_Timer(self.associated_class))
        self.associated_class.addInternalVariable(var_timer_pub)

        ##########################
        ### PUBLISHER CALLBACK ###
        ##########################

        self.publisherCallback = Method(self.associated_class)
        self.publisherCallback.method_name = "{}_callback".format(self.name)
        self.publisherCallback.return_type = Void(self.associated_class)
        self.publisherCallback.namespace = self.associated_class.class_name

        input_par = Variable(self.associated_class)
        input_par.setIsParameter()
        input_par.setType(ROS_TimerEvent(self.associated_class))
        input_par.setName("")
        self.publisherCallback.addInputParameter(input_par)

        # Aggiungo la chiamata alla funzione custome
        if self.source_text_function:
            code = "{}.publish({});".format(var_publisher_pub.name,
                                            self.source_text_function.generateInlineCode())
            self.publisherCallback.addMiddleCode(code)

        self.associated_class.addPrivateMethod(self.publisherCallback)

        main_thread.prepare.addMiddleCode("{} = handle.advertise < {} > (\"{}\", 10);"
                                          .format(var_publisher_pub.name, self.output_type.generateCode(), self.topic))

        main_thread.prepare.addMiddleCode("{} = handle.createTimer(ros::Duration({}), {}, this);"
                                          .format(var_timer_pub.name, self.period_in_seconds,
                                                  self.publisherCallback.getThreadPointer()))

        return True, ""