The Festo Didactic AR App is NOT intended or suitable for controlling or monitoring industrial plants and should only be used for didactic purposes in harmless environments!
AR scenes are provided via a web server, please note that https certificates are not checked. In the app, you access content via the URL.
A scene contains all elements to be displayed and consists of a description in the form of an XML file. The content of this file can be stored statically as a file on the web server or generated dynamically.
A directory is a collection of references to scenes or other directories. This makes it easy for the user to load thematically related scenes.
Example:
<DIRECTORY name="Directory" desc="Various scenes"> <ENTRY url="http://srv.lan/index.xml" name="Test" desc="A test scene."/> <ENTRY url="http://srv.lan/ofen.xml" name="Tunnel" desc="furnace tunnel"/> <ENTRY url="http://example.net/ar/index.xml" name="Tunnel (internet)"/> </DIRECTORY>
Each LINK element represents an entry. In the attribute “name” a label and under “desc” a description text can be deposited. See also: Element METADATA.
Several scenes can be loaded simultaneously in a scene combination. They will behave as if they were a single scene.
<COMPILATION> <ENTRY url="./std.xml"/> <ENTRY url="./modules.xml"/> <ENTRY url="http://srv.lan/ar/index.xml"/> </COMPILATION>
Old scenes can still be loaded. The following differences should be noted:
To access AR scenes, enter the URL of a scene, scene compilation or scene directory in the Festo Didactic AR app. You can also link directly to content via the web browser: “fdar://srv.lan/ar.xml” will try to load “http://srv.lan/ar.xml”.
The scene description contains the structure of the scene as a tree. Changes to the position and scaling of a NODE affect all child elements.
<AUGMENTATION viewlist="normal,extended"> <VALUESERVER> <WEBSOCKET url="ws://nodered.local:1880/ws/data"/> </VALUESERVER> <IMGTARGET file="Marker_10.jpg"> <NODE tx="0.14" ty="0.2"> <COUNTER value="@anim:itemCount:1.5" intdigits="3" fractdigits="0"/> </NODE> <NODE tx="-0.1" ty="0.2" view="extended"> <VIEWER picture="http://srv.lan/cam/now.jpg" w="0.2" h="0.3"/> <NODE ty="0.13" sxyz="0.1" view="extended"> <TEXT label="@anim:time" rgba="00ff" backrgba="8088"/> </NODE> </NODE> </IMGTARGET> <IMGTARGET file="Marker_20.jpg"> <NODE> <MODEL file="obj/model.obj"/> <NODE tx="0.15" ty="0.08" tz="0.02"> <LINK w="0.04" h="0.02" d="0.05" refer="http://srv.lan/info.htm"> <METADATA> <refer> <de>http://srv.lan/info-de.htm</de> </refer> </METADATA> </LINK> </NODE> </NODE> </IMGTARGET> </AUGMENTATION>
Root element
<AUGMENTATION name="Name of scene" desc="Description of scene" preview="preview.jpg" viewlist="normal,extended" viewswitch="false" viewdisplay="true"> </AUGMENTATION>
name
desc
preview
version
viewlist
viewswitch
viewdisplay
Child element of AUGMENTATION, DIRECTORY, ENTRY, COMPILATION, WEBSOCKET, TARGET, IMGTARGET, CAMERA, NODE, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, TRANSMIT, ANIMATION and KEYFRAME.
Allows to set attributes of an element language-dependently. The child elements of the node with the attribute name are named according to two-character ISO identifiers for the respective language. CDATA contents is also supported. The contents override (if available for the current language) the attributes of the parent element and are in turn overridden by animations.
The contents do not have to be consistent across languages. An attribute may also be available in only one language.
<TEXT> <METADATA fallback="en"> <label> <en><!CDATA[content]]></en> <de><!CDATA[Inhalt]]></de> <fr><!CDATA[contenu]]></fr> <es><!CDATA[contenido]]></es> </label> <rgba> <fr>0f0f</fr> </rgba> </METADATA> </TEXT>
fallback
Child element of AUGMENTATION
Contains the connections from which characteristic data can be obtained.
<VALUESERVER predefined="{"var": 123}"> </VALUESERVER>
predefined
"
.Child element of VALUESERVER
Establish a connection to a websocket to be able to receive characteristic data.
<WEBSOCKET url="ws://srv.lan:1880/ws/data"/>
url
prefix
transmitter
Child element of VALUESERVER
Query a REST API accessible via HTTP for characteristic data. The response must consist of a JSON object with properties. Does not support sending data.
<RESTJSON url="http://srv.lan:1880/rest/data"/>
Attributes:
url
prefix
Child element of VALUESERVER
Establish a connection to a Mqtt broker to be able to receive characteristic data.
<MQTT url="mqtt://srv.lan" topic="sample/topic"/>
url
topic
prefix
transmitter
Sub-element of AUGMENTATION
A reference point (“target”) for a marker.
<IMGTARGET file="marker.jpg" width="10" extended="true"> ... </IMGTARGET> <IMGTARGET file="http://example.net/marker.jpg" width="8" extended="true"> ... </IMGTARGET>
file
width
extended
Child element of AUGMENTATION
Will load the specified database with targets.
<TARGETBASE file="basefile"> </TARGETBASE>
file
Sub-element of TARGETBASE
A reference point for a marker.
<TARGET marker="Marker_10" extended="true"> ... </TARGET>
marker
extended
Child element of AUGMENTATION
Reference point of the camera. Elements inserted here are always visible and not bound to a marker. They are fixed in front of the camera.
<CAMERA x="1" y="0.5" distance="0.2"> <NODE> ... </NODE> </CAMERA>
x
, y
distance
scaleto
width
it is the width of the screen, with height
the height. For min
it is the smaller value of the two, correspondingly for max
the larger.Sub-element of TARGET, IMGTARGET, CAMERA, NODE, TOUCH.
Defines a node, which may contain nodes or displayable elements.
<NODE tx="0.15" ry="-90.0" sxyz="3" sz="-1" view="normal" show="false" collapse="false"> </NODE>
tx
, ty
, tz
rx
, ry
, rz
sx
, sy
, sz
sxyz
view
show
collapse
sxyz
and sx
, resp. sy
and sz
. In this example, the actual scaling of the X-axis is “3 (sxyz) * 1 (default value for all scaling specifications) = 3”. For the Y-axis: “3 * 1 = 3” and for the Z-axis “3 * -1 = -3”. The contents of the node are thus scaled up by three and mirrored in the Z-axis.Child element of TARGET, IMGTARGET, CAMERA, NODE, TOUCH.
Defines a manually rotatable, scalable and movable node, which may contain nodes or displayable elements.
<TOUCH w="0.2" d="0.2" h="0.2" rotate="true"> </TOUCH> <TOUCH w="0.1" h="0.1" d="0.1" rotate="true" scale="true"> </TOUCH>
rotate
scale
translate
tx
, ty
, tz
translate
is active, these values are changed by user input. The values may then not be animated.rx
, ry
, rz
rotate
is active, these values are changed by user input. The automatic rotation or animations must not be used then.sx
, sy
, sz
sxyz
scale
is active, this value is changed by user input. The value may then not be animated.view
show
collapse
rgb
rgba
alpha
pulse
w
, h
, d
rotate
and translate
should not be active at the same time, as both use one finger input.sxyz
and sx
, resp. sy
and sz
.Child element of NODE, TOUCH
Displays a three-dimensional model.
<MODEL file="car.obj" texture="red.png"/>
file
texture
filetype
tint
clip
play
playmode
position
Child element of NODE, TOUCH
Displays a text.
<TEXT label="Text field" rgba="00ff0088" backrgba="ffffff88" border="2" width="100" />
rgba
backrgba
border
width
Child element of NODE, TOUCH.
Displays a clickable area that opens the default web browser and navigates to a specified URL or switches to another view in the AR scene. The area is transparent blue and pulses faintly.
<LINK w="0.12" h="0.06" d="0.04" refer="http://www.festo-didactic.de/" rgb="00dd00"/>
w
, h
, d
refer
view:<name of view>)
###. -
rgb@ := colour of the interaction area (semi-transparent).rgba
:= colour of the interaction area with opacity specified.alpha
:= Opacity value of the interaction area. (0..1, default: 0.1)pulse
:= Intensity of the change of the opacity value. (0..1, default : 0.2)Special feature:
Child element of NODE, TOUCH
Displays a visual effect.
<EFFECT type="fire" enabled="true"/>
type
enabled
Child element of NODE, TOUCH
Displays a video. The video is NOT cached on the device.
<STREAMER url="video.mp4" loop="true" status="play" position="0" showpos="true" w="0.4" h="0.225"/>
url
status
loop
position
showpos
w
h
Child element of NODE, TOUCH
Displays images and refreshes them regularly. The images are not cached. If downloading the image takes more time than is available in an interval, all next intervals are skipped until the image has been downloaded or the transfer failed.
<VIEWER w="0.09" h="0.13" refresh="5" picture="http://srv.lan/pic.jpg" showtimer="true"/>
picture
refresh
w
h
showtimer
Child element of NODE, TOUCH.
A mechanical counter with optional decimal places.
<COUNTER value="10.42" intdigits="3" fractdigits="1" intrgb="fff" wheelintrgb="00f" fractrgb="fff" wheelfractrgb="f00" casergb="111" commargb="00de10"/>.
value
intdigits
fractdigits
intrgb
, fractrgb
wheelintrgb
, wheelfractrgb
commargb
casergb
value="
anim:value:1”@ to make the counter spin on for 1 second when changing.Child element of NODE, TOUCH
Simulates a mechanical pointer instrument. The needle has a small overtravel and a red lamp signals over- and underdrive.
<VUMETER value="0.5" label="pointer deflection" labelmin="low" labelmax="high"/>
value
label
labelmin
, labelmax
Child element of NODE, TOUCH
Indicates a signal light of the specified colour.
<SIGNAL rgb="f00" status="true"/>
rgb
status
Child element of NODE, TOUCH
Displays a clickable area like LINK, but holds states that can be read with TRANSMIT.
<SWITCH w="0.03" h="0.03" d="0.02" rgb="0ff" on="true"/>
w
, h
, d
rgb
rgba
alpha
pulse
pressed
on
pressedvalue
unpressedvalue
onvalue
offvalue
Child element of NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION, KEYFRAME.
Writes the content of an attribute of the parent element into a variable and sends it via the specified transmitter.
<SWITCH> <TRANSMIT attribute="pressed" variable="btnPressed" transmitter="send" /> </SWITCH>
attribute
variable
transmitter
threshold
Child element of CAMERA, NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION, KEYFRAME.
Changes the attribute of the parent element over time. See “Animations”. The value of the attribute to be changed is taken from the keyframes.
pre(code).
attribute
increment
double
triple
jump
Child element of ANIMATION
Describes a keyframe in an animation that defines the value at a given time.
<KEYFRAME time="4" value="2" lerp="linear"/>.
time
value
lerp
direct
: (Default) No interpolation. linear
: (Only valid for numbers) Linear interpolation.Root element
Defines a downloadable package containing one or more scenes.
<PACK name="pack" desc="..." preview="preview.jpg">
name
desc
preview
Child element of PACK.
A reference to a ZIP archive with contents.
<CONTENT file="content.zip"/>.
file
The app can connect to a websocket and receive values from it and send them to it. These values are linked to an identifier (variable name and variable value). Similarly, JSON objects are supported as a data source, for example from a REST API.
<VALUESERVER> <WEBSOCKET url="ws://nodered.local:1880/ws/data"/> </VALUESERVER>
Multiple websockets can be specified, but no distinction is made as to which websocket the variable comes from. So if two websockets send a value for the variable “position”, the last value received is valid. However, you can avoid this problem if you give the websockets unique prefixes. A variable is also not known until it is received the first time. Attempting to retrieve its value will return nothing (for number attributes, this is equivalent to 0). When in doubt, important variables must be transmitted by the server immediately upon connection or predefined in the VALUESERVER element. The app cannot request them explicitly.
context.set("value", msg.payload || (context.get("value") || 0.0)); msg.payload = { variableName: context.get("value") }; // adjust variableName return msg;
Any number of values can be transmitted at the same time:
msg.payload = { var1: value1, var2: value2, var3: value3 };
The websocket node must be set to respond to incoming requests (listen on) and transmit only the payload data (payload only).
You can send attributes of elements when they change (for example, the “on” attribute of SWITCH elements). To do this, insert the TRANSMIT element below the element whose attributes you want to send.
<SWITCH w="2" h="3" d="2" rgb="0ff"> <TRANSMIT attribute="pressed" variable="btnPressed" transmitter="send" /> </SWITCH>
When the attribute is changed, the value of the attribute with the assigned variable name is sent to all transmitters with the name “send”.
{ "btnPressed": "true" }
These identifiers are fixed and cannot be used for custom purposes:
fdarcurrentview
The elements CAMERA, NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION and KEYFRAME are animatable. This means that they support a child element ANIMATION, which can change the value of an attribute at runtime. Not all attributes are changeable (see reference of elements).
An animation contains at least a specification about the attribute to be changed and a keyframe.
<TEXT> <ANIMATION attribute="label"> <KEYFRAME value="sensorData"/> </ANIMATION> </TEXT>
First, an attempt is made to find a variable whose name equals the string specified in the keyframe and to apply the corresponding value. If no variable is found, the value remains unchanged. If a calculation is required for the animation, the value is converted and processed. If this fails or is not necessary, the value is simply copied and passed on to the element attribute. It will deal with it accordingly and either react or do nothing if the value is invalid.
In this example, the value of the variable sensorData is output via a text.
Since this case occurs frequently, it can also be abbreviated as follows:
<TEXT label="@anim:sensorData"/>
If you want to transfer a position for an element, it may be desirable to smooth the values between transfers to create the effect of a fluid movement. The attribute “increment” is used for this purpose. It determines the maximum possible change of a value over the duration of one second. Of course, this is not possible with strings.
<NODE> <ANIMATION attribute="tx" increment="0.2"> <KEYFRAME value="position"/> </ANIMATION> <MODEL ... /> </NODE>
Can be abbreviated as:
<NODE tx="@anim:position:0.2"> <MODEL ... /> </NODE
When the app receives a value for the variable “position”, this is compared with the current value of “tx” and “tx” is adjusted with a maximum of 0.2/s.
Further example:
<COUNTER value="@anim:pieces:1.5"/>
A counter is to display a number that is known to increment by 1 approximately once per second. Since “increment” is set to 1.5, this ensures that the display has enough time to catch up and at the same time preserves the intermediate steps necessary for the effect of the mechanical counter.
Sometimes, however, it is not known how much variables can change or they change heavily. In this case, the attributes “double”, “triple” and “jump” can provide compensation.
“double” and “triple” indicate a threshold at which the speed with which the target value is adjusted is doubled or tripled. “jump” at which the target value is set immediately.
Example:
<NODE> <ANIMATION attribute="tx" increment="20" double="25" triple="40" jump="100"> <KEYFRAME value="position"/> </ANIMATION> <MODEL ... /> </NODE>
So if the current value of “tx” is 0 and is now to change to 15, it will do so at the 20/s specified. If the value is to change from 0 to 35, the difference will exceed the threshold specified in “double” and the movement will now take place at 40/s until the difference to the target value falls below 20. If the value changes from 0 to 70, the movement initially takes place at 60/s, later at speeds corresponding to the difference. If even 140 is to be approached from the start position, the difference exceeds the threshold specified in “jump” and the new position is taken immediately. If a new value of 150 were to arrive afterwards, the interpolation speed would be 20/s again.
Further example:
<COUNTER> <ANIMATION attribute="value" increment="2" jump="10"> <KEYFRAME value="pieces"/> </ANIMATION> </COUNTER>
If only one keyframe is needed and more fields are to be used than the abbreviation already presented allows, this abbreviation form can also be used:
<COUNTER> <ANIMATION attribute="value" targetvalue="pieces" increment="2" jump="10"> </COUNTER>
“targetvalue” only abbreviates the notation for a key image and is thus not an animatable attribute (but can accommodate an abbreviated notation for an animation). If the target value itself is to be changed, for example to be able to enter other variable names, this can be solved like this:
<COUNTER> <ANIMATION attribute="value" targetvalue="@anim:whichPieces" increment="2" jump="10"/> </COUNTER>
And would correspond to this long notation:
<COUNTER> <ANIMATION attribute="value" increment="2" jump="10"> <KEYFRAME> <ANIMATION attribute="value"> <KEYFRAME value="whichPieces"/> </ANIMATION> </KEYFRAME> </ANIMATION> </COUNTER>
The value of the variable “whichPieces” is assigned to the attribute “value” of the keyframe of Counter’s animation. If the animation is calculated by Counter, the attribute “value” is interpreted and if it is a valid variable, its value is read and used for the animation.
Important: The order of processing is not predictable for nested animations. It is possible that a change may only be visible one frame later.
However, the notation below would be invalid and would not do anything because ANIMATION will not accept the value:
<COUNTER> <ANIMATION attribute="value" increment="2" jump="10"> <ANIMATION attribute="targetvalue" value="whichPieces" <!-- INVALID! --> /> </ANIMATION> </COUNTER>
Key frames can be used for more complex animations:
<NODE> <ANIMATION attribute="sxyz"> <KEYFRAME time="0" value="0"/> <KEYFRAME time="4" value="2"/> <KEYFRAME time="5" value="1.5"/> <KEYFRAME time="7" value="3"/> <KEYFRAME time="10" value="0"/> </ANIMATION> <MODEL ... /> </NODE>
“time” indicates the position of the key frame in time. Time 0 is the moment when the app was started. The animation is repeated endlessly.
The change of the sxyz attribute will proceed as follows:
To avoid the hard jumps and get a soft interpolation, use the attribute “lerp”. In the last keyframe the lerp attribute is obsolete because it is only used for the transition to the next keyframe. So if the animation is not supposed to “jump” back to the beginning, the last keyframe must have the same value as the first, as in this example.
<NODE> <ANIMATION attribute="sxyz"> <KEYFRAME time="0" value="0" lerp="linear"/> <KEYFRAME time="4" value="2" lerp="linear"/> <KEYFRAME time="5" value="1.5" lerp="linear"/> <KEYFRAME time="7" value="3" lerp="linear"/> <KEYFRAME time="10" value="0"/> </ANIMATION> <MODEL ... /> </NODE>
This results in this progression:
Strings can also be used for the value attribute. But then lerp cannot be used.
<SIGNAL> <ANIMATION attribute="on"> <KEYFRAME time="0" value="true"/> <!-- lerp has no effect. --> <KEYFRAME time="1" value="false" lerp="linear"/> <KEYFRAME time="2" value="true"/> </ANIMATION> </SIGNAL>
Will flash a lamp every second.
To save scenes permanently on a device, they can be bundled into packages. A package can contain any number of contents.
To create a package, first place all the necessary files in a directory. It may also contain subdirectories, but no references to parent directories. Before packing, please remove all files that are not required, otherwise they will unnecessarily take up space on the device.
An “index.xml” file is mandatory, as this is always accessed first. This can be a scene, a scene collection or a directory from which other scenes contained in the package are accessed.
In principle, download packages can also have references to external content.
You then compress the contents of the directory into a ZIP archive.
Example of an archive:
CONTENT.ZIP - img/ texture.png button.png index.xml scene.xml target.jpg model.obj
Please note that the index.xml must not be located in any subdirectory. However, it may refer to subdirectories.
In order to be able to load the contents onto the device, you also need a description of the download package. This is an XML file that contains a reference to the archive and optionally a description and a preview image.
Example:
<PACK name="AR scene package" desc="various scenes" preview="preview.jpg"> <CONTENT file="content.zip"/> </PACK>
When you upload the two files, you can access the XML file with the AR App and download the package from it.
You can find downloaded packages in the bookmarks.
Version 5.5 (2023-09-15)
Festo Didactic SE
Rechbergstraße 3
73770 Denkendorf
Germany
☏ | +49 711 3467-0 |
🖷 | +49 711 34754-88500 |
🌐 | www.festo-didactic.com |
✉ | did@de.festo.com |