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. 42double
: A floating point value, e.g. 3.14bool
: A boolean value, e.g.true
orfalse
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
orFalse
.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.