1. Home
  2. Docs
  3. Yonohub
  4. YonoArc
  5. YonoArc Python 3 API

YonoArc Python 3 API

YonoArc Block Class

The API of YonoArc is event-driven. A block is represented by a single class that implements one or more event handlers. It is important to note that every port or property has a unique key that you select while creating the block on the User Interface. This is to allow the block to know on which port a particular message is received and the values of the different properties. For the source code of an actual block, please check the Edge Detection block in this tutorial: Custom Python 3 Block.

YonoArc supports the following event handlers:

 class Example:

    def on_start(self):
        ''' [Optional] Called at the beginning when the block starts. '''
        pass

    def on_new_messages(self, messages):
        ''' [Optional] Called according to the execution mode of the block.

        Parameters
        ----------
        messages : dict
            A dictionary of the port keys and the values of the incoming messages.
        
        '''
        pass

    def run(self):
        ''' [Optional] Called after on_start in a separate thread. 
        
        Notes
        -----
        This method can be useful for background tasks.

        '''
        pass 

    def on_properties_changed(self, affected_properties):
        ''' [Optional] Called when one or more block properties are changed in live mode. 
        
        Parameters
        ----------
        affected_properties : dict
            A dictionary of the keys of the affected properties and their new values.

        '''
        pass

    def on_button_clicked(self, button_key):
        ''' [Optional] Called when a block button is clicked in live mode. 
        
        Parameters
        ----------
        button_key : string
            The key of the button that has been clicked.

        '''
        pass
  • To publish a message on one of the output ports:
self.publish(port_key, message)
  • To send an alert to the user of the block (causes the block’s alerts icon to flicker and the alert message to be provided in the block’s Alerts tab), use the following method given that alert_message can be any arbitrary string and level is a string whose value is either INFO, WARN, or ERROR.
self.alert(alert_message, level)
  • To get the current value of a property:
self.get_property(property_key)
  • If your block supports multiple execution modes, you can get the currently selected mode (e.g., {“type”: “async”}, {“type”: “sync”, “interval”: 1}, {“type”: “triggered”, “port_key”: port_key}, {“type”: “periodic”, “interval”: 1}) using:
self.get_property('execution_mode')

 

YonoArc Messages

Each message is represented by a class which can be imported from its package as follows:

from yonoarc_msgs.msg import UInt8Array
from sensor_msgs.msg import Image

To construct a message object, you need to instantiate an object from the class representing the message and set the object attributes.

arr = UInt8Array()
arr.header = header
arr.data = data
arr.shape = shape

You can also construct the message on one line by passing the object attributes to the constructor as follows:

arr = UInt8Array(header=header, data=data, shape=shape)

YonoArc Utilities Package

The yonoarc_utils package includes useful utilities that can be used by any block. This package is provided on the fly by YonoArc before your block starts execution, so you can not use this package in Jupyter Notebook for example. The package is organized into different modules as follows:

The image Module

  • To import methods from the image module:
from yonoarc_utils.image import to_ndarray, from_ndarray
  • To convert an image message to a numpy.ndarray:
ndarray = to_ndarray(image)
  • To create an image message using a numpy.ndarray and a header:
image = from_ndarray(ndarray, header)

In order for all blocks dealing with images to work well together, we advise everyone to order their image channels as BGR. This is the default used by OpenCV.

The header Module

  • To import methods from the header module:
from yonoarc_utils.header import set_timestamp, get_timestamp
  • To set the timestamp in the header of a message using a float timestamp (seconds since epoch):
set_timestamp(header, timestamp)
  • To get the timestamp in the header of a message as a float timestamp (seconds since epoch):
get_timestamp(header)

The label Module

Many blocks need to deal with labels, e.g., a block detecting objects in an image and classifying them into different labels, such as car, person, bus. In order for blocks to be connected together, they need to follow the same naming standard for labels. That is why we use the WordNet database v3.0 as our standard.

Each label (or synonym set or synset) in WordNet has a single ID, but can be described by multiple words or word phrases. For example, the label n02958343 represents the following words: car, auto, automobile, machine, motorcar.

One way to browse many images representing each label is using ImageNet database. Beware that a single word can be used in multiple labels. You need to select the label that best describes what you need. Once you click a label, you can retrieve its ID by clicking WordNet IDs and selecting the first ID in the page.

The label ID can be used in the yonoarc_msgs/Label message. The label module provide several useful functions to process label IDs:

  • To import methods from the label module:
from yonoarc_utils.label import is_parent, is_a, get_labels, get_label_details, get_lowest_common_parents
  • To check if a label is a parent of another label:
is_parent(parent_label_id, child_label_id)
  • To check if any of two labels is parent of the other:
is_a(label1_id, label2_id)
  • To get the details of all the possible labels of a given word:
get_labels(word)
  • To get the details of a label given its ID:
get_label_details(label_id)
  • To get the lowest common parents of two labels:
get_lowest_common_parents(label1_id, label2_id)