Links
💻

Using the Python Script Block

Getting familiar with the Python Script Block
Custom blocks can be implemented using the Python script block:

How it works

By default, a new block has one input and one output port. More input and output ports can be added using the block menu:
Note that each port is assigned a default name. These names can be changed by the user but must be unique within the block.
Double clicking on the block opens a text editor containing a Python script where the names of the input and output ports correspond to Python variables.
The script can contain arbitrary Python code including function and class definitions. Note, however, that at present, one can import only modules in the Python standard library and a curated list of libraries such asnumpy, scipy, python-control, roboticstoolbox, torch

Example 1: using numpy

At present, the input ports on Python script blocks can receive only floats, vectors and matrices. All outputs must be Python floats or integers. Integer outputs are converted to floats for the receiving block. Vectors and matrices are mapped to numpy arrays. For instance, if in_0 is connected to a block emitting square matrices, then the following will generate the corresponding stream of determinants.
import numpy as np
out_0 = np.linalg.det(in_0)

Example 2: state machines

A common use case for Python script blocks is for implementing state machines. For example, consider the machine:
This machine has two states: {Heating, Cooling}, and two actions {Heat, Cool}. We assume that the input port on the block is given the name temp and the output port control. With this, the state machine can be implemented with the following Python script:
if time == 0:
from enum import Enum
class State(Enum):
Heating = 0
Cooling = 1
class Control(Enum):
Cool = -1
Heat = 1
state = State.Heating
if state is State.Heating:
if temp <= 22:
control = Control.Heat.value
else:
control = Control.Cool.value
state = State.Cooling
elif state is State.Cooling:
if temp >= 18:
control = Control.Cool.value
else:
contol = Control.Heat.value
state = State.Heating
Note that the Python variable time is assigned the current simulation time before each activation of the block. It follows that the code within the conditional if time == 0: will be executed exactly once. This code serves to initialize any persistent state for the block and, in case above, to define the symbolic names for the states and actions using Python’s Enum class:
If the class definitions were moved outside the if time == 0:conditional, they would be executed every time the block was activated. Each invocation would create new classes which, while identical, would nevertheless be distinct and the logic that follows would fail.