ScriptReader

Script code used by the ScriptSender is read from a file. That script code might have to be dynamically modified based on some configuration input. For example, if the script code contains connections to a remote PC, that PC’s IP address might be configured by the user. Another example would be to include certain parts of the script code only if the robot’s software version supports that.

For that purpose the ScriptReader class is provided. It reads the script code from a file and performs the following substitutions:

  • Replaces variables in the form of {{variable_name}} with the value of the variable from a provided dictionary.

  • Includes other script files using the directive {% include file_name %}. The included file is read from the same directory as the main script file. Nested includes are also possible.

  • Use conditionals in order to add certain parts of the script code only if a condition matches.

The supported substitutions use a basic implementation of the Jinja2 templating engine syntax.

Note

One special literal is defined for version information. Use a software version prefixed with a v character, e.g. v10.8.0 to encode a software version. Version information entries can be compared with each other.

Do not wrap version information into quotes, as this will be interpreted as a string.

Example

Given two script files:

The dictionary entry for feature_name is “torque control”.

Depending on the SOFTWARE_VERSION entry in the dictionary passed to the ScriptReader, the script code will be read as follows:

Given SOFTWARE_VERSION = v5.21.0, the script code will be:

popup("The cool new feature is not supported on Software version 5.23.0")

Given SOFTWARE_VERSION = v5.23.0, the script code will be:

textmsg("torque control is a very cool feature!")

Supported Data

Data dictionary (C++ side)

The data dictionary supports the following types

  • str: A string value, e.g. “Hello World”

  • int: An integer value, e.g. 42

  • double: A floating point value, e.g. 3.14

  • bool: A boolean value, e.g. true or false

  • VersionInformation: A version information value, e.g. VersionInformation::fromString("10.8.0")

Script code side

Variable replacements

Variable replacements in the script code are done using the syntax {{ variable_name }}. For this to work, the variable variable_name has to be defined in the data dictionary passed to the ScriptReader.

The expression {{ variable_name }} will be replaced with the string representation of the variable’s content.

  • If the variable is a string, it has to be wrapped into quotes in the script code. e.g.

    textmsg("{{ log_message }}")
    
  • Boolean variables will be replaced with the string True or False.

  • Numeric variables (integer and floating point) will be replaced with the string representation generated by std::to_string().

  • Version information variables will be replaced with the string representation similar to 10.7.0.0

Boolean expressions

Boolean expressions have to follow one of two possible syntax variations

  • Direct evaluation of a boolean variable from the data dictionary:

    boolean_variable_name
    
  • Comparison of a variable with a value using an operator.

    variable_name operator value
    

    The operator has to be one of ==, !=, <, <=, >, >=. On the lefthand side of the operator there has to be a variable from the data dictionary. The right hand side can be either a variable name or a value. If the right hand side is a variable name, it has to be defined in the data dictionary as well. Values will be parsed as follows:

    • Strings: Wrapped in quotes, e.g. "Hello World" or 'Universal Robots'.

    • Numerical values such as 42, 3.14, -1, 1e-12.

    • Boolean values: See below.

    • Version information: Prefixed with a v character, e.g. v10.8.0, v5.23.0.

Boolean values parsing

Boolean values can be parsed from the following strings:

  • true, True, TRUE

  • on, On, ON

  • yes, Yes, YES

  • 1

  • false, False, FALSE

  • off, Off, OFF

  • no, No, NO

  • 0

Conditional blocks

Conditional blocks have to be started with a {% if condition %} directive and closed with a {% endif %} directive. The condition can be any boolean expression as described above.

The {% elif condition %} and {% else %} directives can be used to add alternative paths.

Conditional blocks can be nested.