![]()
Die Festo Didactic AR App ist NICHT zur Steuerung oder Überwachung von industriellen Anlagen gedacht oder geeignet und sollte nur für didaktische Zwecke in ungefährlichen Umgebungen eingesetzt werden!
AR-Szenen werden über einen Webserver bereitgestellt, bitte beachten Sie, dass https-Zertifikate nicht geprüft werden. In der App greifen Sie über die URL darauf zu.
Eine Szene enthält alle anzuzeigenden Elemente und besteht aus einer Beschreibung in Form einer XML-Datei. Der Inhalt dieser Datei kann statisch als Datei auf dem Webserver liegen oder dynamisch erzeugt werden.
Ein Verzeichnis ist eine Sammlung von Verweisen auf Szenen oder weitern Verzeichnissen. So können thematisch zusammenhängende Szenen für den Anwender einfach aufgerufen werden.
Beispiel:
<DIRECTORY name="Verzeichnis" desc="Verschiedene Szenen"> <ENTRY url="http://srv.lan/index.xml" name="Test" desc="Eine Testszene."/> <ENTRY url="http://srv.lan/ofen.xml" name="Tunnelofen"/> <ENTRY url="http://example.net/ar/index.xml" name="Tunnelofen (internet)"/> </DIRECTORY>
Jedes LINK-Element stellt einen Eintrag dar. Im Attribut “name” lässt sich eine Beschriftung und unter “desc” ein Beschreibungstext hinterlegen. Siehe auch: Element METADATA.
Mehrere Szenen können in einer Szenenkombination gleichzeitig geladen werden. Sie werden sich dabei so verhalten, als wären sie eine einzige Szene.
<COMPILATION> <ENTRY url="./std.xml"/> <ENTRY url="./modules.xml"/> <ENTRY url="http://srv.lan/ar/index.xml"/> </COMPILATION>
Alte Szenen können weiterhin geladen werden. Folgende Unterschiede sollten beachtet werden:
Um auf AR-Szenen zuzugreifen, geben Sie in der Festo Didactic AR App die URL einer Szene, Szenenkombination oder eines Szenenverzeichnisses an. Sie können auch über den Webbrowser direkt auf Inhalte verlinken: “fdar://srv.lan/ar.xml” wird versuchen “http://srv.lan/ar.xml” zu laden.
Die Szenenbeschreibung enthällt die Struktur der Szene als Baum. Änderungen an Position und Skalierung einer NODE wirken sich auf alle Elemente darunter aus.
<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>Wurzelelement
<AUGMENTATION name="Name der Szene" desc="Beschreibung der Szene" preview="preview.jpg" viewlist="normal,extended" viewswitch="false" viewdisplay="true"> </AUGMENTATION>
namedescpreviewversionviewlistviewswitchviewdisplayUnterelement von AUGMENTATION, DIRECTORY, ENTRY, COMPILATION, WEBSOCKET, TARGET, IMGTARGET, CAMERA, NODE, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, TRANSMIT, ANIMATION und KEYFRAME.
Ermöglicht es Attribute eines Elements sprachabhängig zu setzen. Die Unterelemente des Knotens mit dem Attributnamen werden nach zweistelligen ISO-Kennungen für die jeweilige Sprache benannt. Es werden auch CDATA-Inhalte unterstützt. Die Inhalte überschreiben (falls für die aktuelle Sprache vorhanden) die Attribute des übergeordneten Elements und werden wiederum von Animationen überschrieben.
Die Inhalte müssen über die verschiedenen Sprachen nicht konsistent sein. Ein Attribut kann auch nur in einer Sprache verfügbar sein.
<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>
fallbackUnterelement von AUGMENTATION
Enthält die Verbindungen, von denen Kenndaten bezogen werden können.
<VALUESERVER predefined="{"var": 123}">
</VALUESERVER>
predefined" ersetzt werden.Unterelement von VALUESERVER
JSON-Objekt mit vordefinierten Variablen. Entspricht dem predefined Attribut von VALUESERVER, Steuerzeichen müssen aber nicht maskiert werden, wenn ein CDATA Element genutzt wird. Außerdem werden Prefixe und mehrere JSON Elemente unterstützt. Ist kein text-Attribut gesetzt, wird versucht das innere Element als JSON-Objekt zu interpretieren.
<JSON>
<![CDATA[
{ "var": 123,
"otherVar": "something" }
]]>
</JSON>
<JSON>
<METADATA fallback="en">
<text>
<de><![CDATA[{"greet": "Hallo!"}]]></de>
<en><![CDATA[{"greet": "Hi there!"}]]></en>
</text>
</METADATA>
</JSON>
prefixtextUnterelement von VALUESERVER
Zu einem Websocket eine Verbindung aufbauen, um Kenndaten empfangen zu können.
<WEBSOCKET url="ws://srv.lan:1880/ws/data"/>
urlprefixtransmitterUnterelement von VALUESERVER
Eine über HTTP erreichbare REST API nach Kenndaten abfragen. Die Antwort muss aus einem JSON Objekt mit Eigenschaften bestehen. Unterstützt nicht das Senden von Daten.
<RESTJSON url="http://srv.lan:1880/rest/data"/>
Attribute:
urlprefixUnterelement von VALUESERVER
Eine Verbindung zu einem Mqtt Broker aufbauen, um Kenndaten empfangen zu können.
<MQTT url="mqtt://srv.lan" topic="sample/topic"/>
urltopicprefixtransmitterUnterelement von AUGMENTATION
Ein Referenzpunkt (“Ziel”) für einen Marker.
<IMGTARGET file="marker.jpg" width="0.1" extended="true"> ... </IMGTARGET> <IMGTARGET file="http://example.net/marker.jpg" width="0.08" extended="true"> ... </IMGTARGET>
filewidthextendedUnterelement von AUGMENTATION
Ein virtueller Referenzpunkt für Inhalte. Seine Position und die Sichtbarkeit der untergeordneten Elemente wird durch REFLECT Elemente beeinflusst.
Mögliche Szenarien sind beispielsweise Inhalte, die auf mehreren Markern sichtbar sein sollen oder die Aufspaltung einer komplexen Szene in kleinere Teilstrukturen.
Sollen mehrere Marker einen gemeinsamen Inhalt am gleichen physikalischen Ort zeigen, müssen diese in einem festgelegten Abstand zueinander sein und jedes REFLECT Element mittels Transformation an den gleichen Ort verschoben sein.
<VIRTUAL name="mytarget" prioritisation="highest">...</VIRTUAL>
<IMGTARGET file="marker.png">
<NODE>
<REFLECT to="mytarget" priority="activated"/>
</NODE>
</IMGTARGET>
<IMGTARGET file="other.png">
<NODE tx="0.4" ty="-0.3" ty="0.2" rx="-90">
<REFLECT to="mytarget" priority="activated"/>
</NODE>
</IMGTARGET>
nameprioritisationweighted (Standard): Je größer die Priorität einer Eingabe, desto stärker ist ihr Einfluss. lowest: Nur die Eingabe mit der niedrigsten Priorität wird verarbeitet. heighest: Nur die Eingabe mit der höchsten Priorität wird verarbeitet.Unterelement von AUGMENTATION
Wird die angegebene Datenbank mit Zielen laden.
<TARGETBASE file="basefile"> </TARGETBASE>
fileUnterelement von TARGETBASE
Ein Referenzpunkt für einen Marker.
<TARGET marker="Marker_10" extended="true"> ... </TARGET>
markerextendedUnterelement von AUGMENTATION
Referenzpunkt der Kamera. Hier eingefügte Elemente sind immer sichtbar und nicht an einen Marker gebunden. Sie stehen fest vor der Kamera.
<CAMERA x="1" y="0.5" distance="0.2">
<NODE>
...
</NODE>
</CAMERA>
x, ydistancescaletowidth ist es die Breite des Bildschirms, bei height die Höhe. Bei min ist es der kleiner Wert von beiden, entsprechend bei max der Größere.Unterelement von TARGET, IMGTARGET, CAMERA, NODE, TOUCH
Definiert einen Knoten, der wiederum Knoten oder darstellbare Elemente enthalten kann.
<NODE ry="-90.0" sxyz="3" sz="-1" view="normal" show="false" collapse="false"> </NODE>
tx, ty, tzrx, ry, rzsx, sy, szsxyzviewshowcollapsesxyz und sx, bzw. sy und sz. In diesem Beispiel entspricht die tatsächliche Skalierung der X-Achse “3 (sxyz) * 1 (Standardwert für alle Skalierungsangaben) = 3”. Für die Y-Achse: “3 * 1 = 3” und für die Z-Achse “3 * -1 = -3”. Die Inhalte des Knoten werden also dreifach vergrößert und in der Z-Achse gespiegelt dargestellt.Unterelement von TARGET, IMGTARGET, CAMERA, NODE, TOUCH
Definiert einen von Hand dreh-, skalier- und bewegbaren Knoten, der wiederum Knoten oder darstellbare Elemente enthalten kann.
<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>
rotatescaletranslatetx, ty, tztranslate aktiv ist, werden diese Werte durch die Benutzereingabe verändert. Die Werten dürfen dann nicht animiert werden.rx, ry, rzrotate aktiv ist, werden diese Werte durch die Benutzereingabe geändert. Die automatische Drehung oder Animationen dürfen dann nicht genutzt werden.sx, sy, szsxyzscale aktiv ist, wird dieser Wert durch die Benutzereingabe geändert. Der Wert darf dann nicht animiert werden.viewshowcollapsergbrgbaalphapulsew, h, drotate und translate sollten nicht gleichzeitig aktiv sein, da beide die Eingabe mit einem Finger nutzen.sxyz und sx, bzw. sy und sz.Unterelement von NODE, TOUCH
Zeigt ein dreidimensionales Modell an.
<MODEL file="car.obj" texture="red.png"/>
filetexturefiletypetintclipplayplaymodepositionUnterelement von NODE, TOUCH
Zeigt einen Text an.
<TEXT label="Textfeld" rgba="00ff0088" backrgba="ffffff88" border="2" width="100" />
rgbabackrgbaborderwidthUnterelement von NODE, TOUCH
Zeigt einen anklickbaren Bereich an, der den Standard-Webbrowser öffnet und eine angegebene URL ansteuert oder zu einer anderen Ansicht in der AR-Szene wechselt. Der Bereich ist blau transparent und pulsiert schwach.
<LINK w="0.12" h="0.06" d="0.04" refer="http://www.festo-didactic.de/" rgb="00dd00"/>
w, h, dreferrefer="@view:extended", refer="http://example.org")rgbrgbaalphapulseBesonderheit:
Unterelement von NODE, TOUCH
Zeigt einen visuellen Effekt an.
<EFFECT type="fire" enabled="true"/>
typeenabledUnterelement von NODE, TOUCH
Zeigt ein Video an. Das Video wird dabei NICHT auf dem Gerät zwischengespeichert.
<STREAMER url="video.mp4" loop="true" status="play" position="0" showpos="true" w="0.4" h="0.225"/>
urlstatuslooppositionshowposwhUnterelement von NODE, TOUCH
Zeigt Bilder an und aktualisiert diese Regelmäßig neu. Die Bilder werden nicht zwischengespeichert. Benötigt das Herunterladen des Bildes mehr Zeit, als in einem Intervall zur Verfügung steht, werden alle nächsten Intervalle übersprungen, bis das Bild heruntergeladen wurde oder die Übertragung fehlschlug.
<VIEWER w="0.09" h="0.13" refresh="5" picture="http://srv.lan/pic.jpg" showtimer="true"/>
picturerefreshwhshowtimerUnterelement von NODE, TOUCH
Ein mechanisches Zählwerk mit optionalen Nachkommastellen.
<COUNTER value="10.42" intdigits="3" fractdigits="1" intrgb="fff" wheelintrgb="00f" fractrgb="fff" wheelfractrgb="f00" casergb="111" commargb="00de10"/>
valueintdigitsfractdigitsintrgb, fractrgbwheelintrgb, wheelfractrgbcommargbcasergbvalue="anim:value:1”@ um das Zählwerk beim Wechsel 1 Sekunde lang weiterdrehen zu lassen.Unterelement von NODE, TOUCH
Simuliert ein mechanisches Zeigerinstrument. Die Nadel hat einen geringen Nachlauf und eine rote Lampe signalisiert Übersteuerung und Untersteuerung.
<VUMETER value="0.5" label="Zeigerausschlag" labelmin="gering" labelmax="hoch"/>
valuelabellabelmin, labelmaxUnterelement von NODE, TOUCH
Zeigt eine Signalleuchte der angegebenen Farbe an.
<SIGNAL rgb="f00" status="true"/>
rgbstatusUnterelement von NODE, TOUCH
Zeigt einen anklickbaren Bereich wie LINK an, hält aber Zustände bereit, die mit TRANSMIT ausgelesen werden können.
<SWITCH w="0.03" h="0.03" d="0.02" rgb="0ff" on="true"/>
w, h, drgbrgbaalphapulsepressedonpressedvalueunpressedvalueonvalueoffvalueUnterelement von NODE, TOUCH
Ist das übergeordnete NODE Element sichtbar, also der zugehörige Marker wird erkannt und das Element ist auch nicht mittels Sichtbarkeitsattributen unsichtbar, wird die aktuelle Position eben dieses Elements auf den in to angegebenen virtuellen Referenzpunkt (siehe VIRTUAL) übertragen.
Es können auch mehrere REFLECT Elemente auf den gleichen virtuellen Referenzpunkt verweisen.
<VIRTUAL name="mytarget" prioritisation="highest">...</VIRTUAL>
<IMGTARGET file="marker.png">
<NODE>
<REFLECT to="mytarget" priority="activated"/>
</NODE>
</IMGTARGET>
<IMGTARGET file="other.png">
<NODE tx="0.4" ty="-0.3" ty="0.2">
<REFLECT to="mytarget" priority="activated"/>
</NODE>
</IMGTARGET>
topriorityactivated: Der Zeitpunkt in Sekunden, an dem die übergeordnete Node sichtbar wurde. running: Die Dauer in Sekunden, wie lange die übergeordnete Node aktuell unterbrechungsfrei sichtbar ist.Unterelement von NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION, KEYFRAME
Schreibt den Inhalt eines Attributs des Übergeordneten Elements in eine Variable und sendet diese über den angegebenen Transmitter.
<SWITCH> <TRANSMIT attribute="pressed" variable="btnPressed" transmitter="send" /> </SWITCH>
attributevariabletransmitterthresholdUnterelement von CAMERA, NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION, KEYFRAME
Ändert das Attribut des übergeordneten Elements im Verlauf der Zeit. Siehe “Animationen”. Der Wert des zu ändernden Attributs wird den Schlüsselbildern entnommen.
pre(code).
attributeincrementdoubletriplejumpUnterelement von ANIMATION
Beschreibt ein Schlüsselbild in einer Animation, welches den Wert zu einer bestimmten Zeit definiert.
<KEYFRAME time="4" value="2" lerp="linear"/>
timevaluelerpdirect: (Standard) Keine Interpolation. linear: (Nur gültig für Zahlen) Lineare InterpolationWurzelelement
Definiert ein herunterladbares Paket mit einer oder mehrerer Szenen.
<PACK name="pack" desc="..." preview="preview.jpg">
namedescpreviewUnterelement von PACK
Ein Verweis auf ein ZIP-Archiv mit Inhalten.
<CONTENT file="content.zip"/>
fileDie App kann sich auf einen Websocket verbinden und von dort Werte erhalten und an diesen senden. Diese Werte sind an einen Bezeichner gekoppelt (Variablenname und Variablenwert). Ebenso werden JSON-Objekte etwa von einer REST API als Datenquelle unterstützt.
<VALUESERVER> <WEBSOCKET url="ws://nodered.local:1880/ws/data"/> </VALUESERVER>
Es können mehrere Websockets angegeben werden, jedoch wird nicht unterschieden von welchem Websocket die Variable kommt. Senden also zwei Websockets einen Wert für die Variable “position” gilt der zuletzt empfangene Wert. Dieses Problem können Sie jedoch vermeiden, wenn Sie den Websockets eindeutige Präfixe geben. Eine Variable ist auch nicht bekannt, bis sie das erste Mal empfangen wurde. Der Versuch ihren Wert abzufragen wird nichts zurückgeben (für Zahlenattribute entspricht das einer 0). Im Zweifel müssen wichtige Variablen sofort beim Verbinden durch den Server übertragen werden oder im Element VALUESERVER vordefiniert werden. Die App kann sie nicht explizit anfordern.

context.set("value", msg.payload || (context.get("value") || 0.0));
msg.payload = { variableName: context.get("value") }; // variableName anpassen
return msg;
Es können beliebig viele Werte gleichzeitig übertragen werden:
msg.payload = { var1: value1, var2: value2, var3: value3 };
Die Websocket-Node muss so eingestellt sein, dass Sie auf eingehende Anfragen reagiert (listen on) und nur die Nutzdaten überträgt (payload only).
Sie können Attribute von Elementen senden, wenn diese sich verändern (zum Beispiel das “on”-Attribut von SWITCH-Elementen). Fügen Sie dazu das TRANSMIT-Element unterhalb des Elements ein, dessen Attribute Sie senden wollen.
<SWITCH w="2" h="3" d="2" rgb="0ff"> <TRANSMIT attribute="pressed" variable="btnPressed" transmitter="send" /> </SWITCH>
Bei einer Änderung des Attributs wird an alle Transmitter mit dem Namen “send” der Wert des Attributs mit dem Zugewiesenen Variablennamen gesendet.
{ "btnPressed": "true" }
Diese Bezeichner sind fest definiert und können nicht für eigene Zwecke genutzt werden:
fdarcurrentviewDie Elemente CAMERA, NODE, TOUCH, MODEL, TEXT, LINK, EFFECT, STREAMER, VIEWER, COUNTER, VUMETER, SIGNAL, SWITCH, TRANSMIT, ANIMATION und KEYFRAME sind animierbar. Das heißt, diese unterstützen ein Unterelement ANIMATION, welches den Wert eines Attributes zur Laufzeit ändern kann. Nicht alle Attribute sind änderbar (siehe Referenz der Elemente).
Eine Animation enthält mindestens eine Angabe über das zu ändernde Attribut und ein Schlüsselbild.
<TEXT>
<ANIMATION attribute="label">
<KEYFRAME value="sensorData"/>
</ANIMATION>
</TEXT>
Zuerst wird versucht eine Variable zu finden, deren Name der im Schlüsselbild angegebenen Zeichenkette entspricht und den entsprechenden Wert zu übernehmen. Wird keine Variable gefunden bleibt der Inhalt bestehen. Ist für die Animation eine Berechnung erforderlich, wird der Wert umgewandelt und verrechnet. Wenn das fehlschlägt oder nicht erforderlich ist wird der Wert einfach so übernommen und dem Elementattribut übergeben. Es wird entsprechend damit umgehen und entweder reagieren oder bei einem ungültigen Wert nichts tun.
In diesem Beispiel wird der Wert der Variable sensorData über einen Text ausgegeben.
Da dieser Fall häufig vorkommt, kann man ihn auch wie folgt abkürzen:
<TEXT label="@anim:sensorData"/>
Wenn Sie eine Position für ein Element übertragen möchten, kann eine Glättung der Werte zwischen den Übertragungen wünschenswert sein, um den Effekt einer flüssigen Bewegung zu erzeugen. Dazu wird das Attribut “increment” benutzt. Es legt die maximal mögliche Veränderung eines Werts über die Dauer einer Sekunde fest. Mit Zeichenketten ist das natürlich nicht möglich.
<NODE>
<ANIMATION attribute="tx" increment="20">
<KEYFRAME value="position"/>
</ANIMATION>
<MODEL ... />
</NODE>
Lässt sich abkürzen als:
<NODE tx="@anim:position:20"> <MODEL ... /> </NODE
Wenn die App einen Wert für die Variable “position” erhält wird dieser mit dem aktuellen von “tx” verglichen und “tx” mit maximal 20/s angeglichen.
Weiteres Beispiel:
<COUNTER value="@anim:pieces:1.5"/>
Ein Zähler soll eine Zahl anzeigen, von der bekannt ist, dass sie sich etwa einmal pro Sekunde um 1 erhöht. Da “increment” auf 1,5 gesetzt wird, ist sichergestellt, dass die Anzeige genügend Zeit hat nachzuziehen und erhalten gleichzeitig die für den Effekt des mechanischen Zählwerks notwendigen Zwischenschritte.
Manchmal ist aber nicht bekannt wie stark sich Variablen ändern können oder sie ändern sich stark schwankend. Die Attribute “double”, “triple” und “jump” können in diesem Fall einen Ausgleich bewirken.
“double” und “triple” geben eine Schwelle an, ab welcher die Geschwindigkeit mit der sich dem Zielwert angepasst wird verdoppelt oder verdreifacht wird. “jump” bei welcher sofort der Zielwert gesetzt wird.
Beispiel:
<NODE>
<ANIMATION attribute="tx" increment="20" double="25" triple="40" jump="100">
<KEYFRAME value="position"/>
</ANIMATION>
<MODEL ... />
</NODE>
Wenn der aktuelle Wert von “tx” also 0 ist und sich nun auf 15 ändern soll, wird er dies mit den angegebenen 20/s tun. Soll sich der Wert von 0 auf 35 ändern, übersteigt die Differenz die in “double” festgelegte Schwelle und die Bewegung findet nun mit 40/s statt, bis die Differenz zum Zielwert auf unter 20 fällt. Bei einer Änderung von 0 auf 70 findet die Bewegung anfangs mit 60/s statt, später mit der Differenz entsprechenden Geschwindigkeiten. Sollen gar 140 von der Startposition aus angefahren werden, übersteigt die Differenz die in “jump” angegebene Schwelle und die neue Position wird sofort eingenommen. Käme danach ein neuer Wert von 150 würde die Interpolationsgeschwindigkeit wieder 20/s betragen.
Weiteres Beispiel:
<COUNTER>
<ANIMATION attribute="value" increment="2" jump="10">
<KEYFRAME value="pieces"/>
</ANIMATION>
</COUNTER>
Ist nur ein Schlüsselbild notwendig und sollen mehr Felder genutzt werden als die schon vorgestellte Abkürzung zulässt, kann auch diese Abkürzungsform genutzt werden:
<COUNTER> <ANIMATION attribute="value" targetvalue="pieces" increment="2" jump="10"> </COUNTER>
“targetvalue” verkürzt dabei nur die Schreibweise für ein Schlüsselbild und ist damit kein animierbares Attribut (kann aber eine abgekürzte Schreibweise für eine Animation aufnehmen). Soll der Zielwert selbst verändert werden, etwa um andere Variablennamen eintragen zu können, kann das so gelöst werden:
<COUNTER> <ANIMATION attribute="value" targetvalue="@anim:whichPieces" increment="2" jump="10"/> </COUNTER>
Und entspräche dieser langen Schreibweise:
<COUNTER>
<ANIMATION attribute="value" increment="2" jump="10">
<KEYFRAME>
<ANIMATION attribute="value">
<KEYFRAME value="whichPieces"/>
</ANIMATION>
</KEYFRAME>
</ANIMATION>
</COUNTER>
Der Wert der Variable “whichPieces” wird dem Attribut “value” des Schlüsselbilds der Animation von Counter zugewiesen. Wird die Animation von Counter berechnet, wird das Attribut “value” interpretiert und wenn es sich um eine gültige Variable handelt wird deren Wert ausgelesen und für die Animation verwendet.
Wichtig: Die Reihenfolge der Abarbeitung ist für verschachtelte Animationen nicht vorherzusehen. Möglicherweise kann eine Änderung erst ein Einzelbild später sichtbar sein.
Die unten stehende Schreibweise wäre jedoch ungültig und würde nichts bewirken, da ANIMATION den Wert nicht annehmen wird:
<COUNTER>
<ANIMATION attribute="value" increment="2" jump="10">
<ANIMATION attribute="targetvalue" value="whichPieces" <!-- UNGÜLTIG! --> />
</ANIMATION>
</COUNTER>
Bei komplexeren Animationen können Schlüsselbilder genutzt werden:
<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” gibt die Position des Schlüsselbilds im Zeitverlauf an. Der Zeitpunkt 0 ist der Moment, in dem die App gestartet wurde. Die Animation wird endlos wiederholt.
Die Veränderung des sxyz Attributs wird wie folgt verlaufen:
Um die harten Sprünge zu vermeiden und eine weiche Interpolation zu erhalten, benutzen Sie das Attribut “lerp”. Im letzten Schlüsselbild ist das lerp-Attribut obsolet, da es nur für den Übergang zum nächsten Schlüsselbild genutzt wird. Soll die Animation also nicht an den Anfang zurück “springen”, muss das letzte Schlüsselbild den gleichen Wert wie das erste haben, wie in diesem Beispiel.
<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>
Daraus ergibt sich dieser Verlauf:
Für das value-Attribut können auch Zeichenketten genutzt werden. Dann kann lerp aber nicht genutzt werden.
<SIGNAL>
<ANIMATION attribute="on">
<KEYFRAME time="0" value="true"/>
<!-- lerp hat keine Auswirkung. -->
<KEYFRAME time="1" value="false" lerp="linear"/>
<KEYFRAME time="2" value="true"/>
</ANIMATION>
</SIGNAL>
Wird eine Lampe im Sekundentakt blinken lassen.
Um Szenen dauerhaft auf einem Gerät zu speichern können diese in Pakete gebündelt werden. Ein Paket kann beliebig viele Inhalte enthalten.
Um ein Paket zu erstellen platzieren Sie zunächst alle erforderlichen Dateien in einem Verzeichnis. Es darf auch Unterverzeichnisse enthalten, aber keine Referenzen zu übergeordneten Verzeichnissen. Bitte entfernen Sie vor dem Packen alle nicht benötigten Dateien, da diese sonst unnötig Platz auf dem Gerät belegen.
Eine “index.xml” Datei ist zwingend erforderlich, denn auf diese wird immer zuerst zugegriffen. Das kann eine Szene, eine Szenensammlung oder ein Verzeichnis sein, von dem aus auf weitere im Paket enthaltene Szenen zugegriffen wird.
Prinzipiell können Downloadpakete auch Referenzen auf externe Inhalte haben.
Den Inhalt des Verzeichnisses komprimieren Sie dann in ein ZIP Archiv.
Beispiel für ein Archiv:
CONTENT.ZIP
- img/
texture.png
button.png
index.xml
scene.xml
target.jpg
model.obj
Bitte beachten Sie, dass die index.xml in keinem Unterverzeichnis liegen darf. Sie darf allerdings durchaus auf Unterverzeichnisse verweisen.
Um die Inhalte auf das Gerät laden zu können benötigen Sie außerdem eine Beschreibung des Downloadpakets. Das ist eine XML-Datei, welche einen Verweis auf das Archiv und optional eine Beschreibung und ein Vorschaubild enthällt.
Beispiel:
<PACK name="AR-Szenenpaket" desc="verschiedene Szenen" preview="preview.jpg"> <CONTENT file="content.zip"/> </PACK>
Wenn Sie die beiden Dateien hochladen können Sie mit der AR App auf die XML-Datei zugreifen und darüber das Paket herunterladen.
Sie finden heruntergeladenen Pakete in den Lesezeichen.
Version 5.6 (2025-06-13)
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 |
Hack Font is used for example snippets.
Some translations by DeepL.