Why PYthon in RTMaps ?
RTMaps is a real-time solution; so why make a Python component? In comparison, compiled languages, like C++, are faster and more optimized for this kind of computing. There are several reasons to this:
- Python is easy to use: Python can be easily used with little programming knowledge.
- Python is very powerful! You can use python to implement complex and object-oriented codes in a very few lines.
- Python has many libraries: numpy for manipulating arrays and matrix, matplotlib to plot easily your data, etc.
- On the flow: When developing an algorithm, the programmer may lose a lot of time between compilation/run loops. By using Python, s/he would be able to change the code during the execution and immediately see the results! The Python package for RTMaps encapsulates the version 3.4 of Python; therefore there isn’t any necessity of installing Python on your system when using the component.
A QUICK LOOK TO THE PYTHON COMPONENT
The Python component has a small editor with syntax coloration to help you develop in Python. The editor can be opened via an action (right click on the component).
Figure 1: Python action. When right-clicking on the python component, it is possible to open the Python editor. This action will create a new window where it will be possible to create/edit a Python script file.
When right-clicking on the python component, it is possible to open the Python editor. This action will create a new window where it will be possible to create/edit a Python script file.
When loading your component for the first time on the diagram, the code editor displays a template code that multiplies the input by 2. The next figure shows how this template code looks like. It is composed of one Python class and 4 functions:
- The class constructor: __init__(self). It is the Python constructor. This function is highly optional. It allows to initialized variable you might want to set-up when your component enters the diagram and when the diagram is still not running yet.
- The Birth(self). This function is optional. This function is called once when the diagram starts.
- The Core(self). This function is mandatory. Core is called when inputs have arrived on your Python component. Depending on your reading policy, it may be called every new input (Reactive) or only when inputs have a matching timestamp (Synchro). You can also set the reading policy to sampling policy, so that Core will be called periodically at a given sampling rate.
- The Death(self). This function is optional. Death is called once when the user shutdowns the diagram.
Figure 2: Birth()/Core()/Death() functions; those works similarly to their definition in the C++ SDK
From this interface, you should not forget to save your code for it to be executed by RTMaps.
Note: In Python, remember that indentation of the code is necessary.
Warning! All inputs and outputs are part of your class instance (self). This step is necessary for RTMaps to be able to bind the variable to the actual output of the component. In the figure 2, self.output_0 represents the output of the Python component.
Figure 3: Properties of the Python component
- filename: Path to the python script (.py file) to execute.
- className : the name of the Python class RTMaps has to call.
- readingPolicy: Can be Reactive or Synchro; policy for reading from multiple inputs (see: Reading modes mono and multi inputs ).
- Inputs List: List of the desired inputs, separated by “,;:|” or space.
- Outputs List : List of the desired outputs, separated by “,;:|” or space.
- Properties List : List of the desired outputs, separated by “,;:|” or space.
- x, y, width, height: Position in x/y and width/height of the editor window, has no effect in python whatsoever.
Warning! When naming an input/output, it is impossible to name them the same way as a property of the component itself (for example: it is impossible to name an input ‘x’ as this property name already exists).
Interaction with RTMaps
The reading policies are:
- Synchro: This is the same as SynchroStartReading in C++. All the inputs will be read if they are under the synchro tolerance threshold. It means if you choose 0 tolerance, you will receive only inputs that have the exact same timestamp.
- Reactive: This is the same as multiple StartReading. The Core() function will be called every time a new input has arrived. When a new data arrive, the variable self.input_that_answered is set to the actual input that answered so that you can know which input has arrived precisely. Note also that Reactive has a timeout property set to zero by default, which means your Python component will wait for a data forever. But if you plan to wait for a data for a specific duration and not more, then you can specify a timeout value in microseconds. If the timeout occurs, Core() will be called with a self.input_that_answered set to -1.
- Sampling: Here you choose to launch Core() every X microseconds. In this mode, you are independent of the inputs sampling rate.
- Triggered: The Python component will be triggered by the first input. Every time a new data comes on the first input, Core() will be called.blocking function like sleep (from time package) for example.
Note that if the Python component has no input at all and you are not in sampling mode, Core() will be called in a loop, so you have to use a
I/O TYPES SUPPORTS
For now, the Python component supports a fixed number of input/outputs types:
- Array of Integer32/64
- Array of Float32/64
- Vector of Integer32/64
- Vector of Float32/64
You can import the rtmaps module to use our functions. The simplest solution is to use “from rtmaps import *” but any other standard python import will be fine.
Here are some useful functions that you can call in Python:
- report_info(string): write some information on the RTMaps console (blue)
- report_warning(string): write some information on the RTMaps console (yellow)
- report_error(string): write some information on the RTMaps console (red)
- parse(string): call the RTMaps Engine with a command
- async_parse(string): call the RTMaps Engine in an asynchronous way. Very useful if you plan to do some shutdown.
- get_property(string): get the property value from an RTMaps component
- current_time(): retrieve the MAPS::CurrentTime() in Python
- time_speed(): retrieve the MAPS::TimeSpeed() in Python
number_of_inputs is available in Python if you want to know the current number of inputs that you have. self.number_of_inputs has to be used because all variables are inside the current Python instance.
Suppose your input data is named foo. Additional data is available in Python to get more information. All variables are suffixes (_ts, _buffer_size, etc.) to your initial input name.
- The timestamp of any input data can be easily retrieve thanks to a specific_variable "foo_ts". For example, if your input is called foo, then the timestamp is stored in the foo_ts variable.
- The buffer size of the MAPSIOElt (see C++ SDK) is stored in the foo_buffer_size variable.
- The vector size of the MAPSIOElt (see C++ SDK) is stored in the foo_vector_size variable.
- The frequency field (if present on the data) is stored in the foo_frequency variable.
Suppose your output data is name bar. Additional data is available in Python to get more information. All variables are suffixes (same as previous section) to your initial output name.
- You can set your buffer_size manually by setting the bar_buffer_size variable. This is useful if you want to set a custom size.