Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums

Die Seite wird erstellt Ansgar-Maximilian Geiger
 
WEITER LESEN
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Eine Dokumentation über Visual Programming Language

 Im Rahmen des Microsoft Robotics Studio Praktikums
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Vorwort

Dieses Dokument wurde im Rahmen des Softwarepraktikums MS Robotics Studio erstellt während
des WS 07/08.

Lieber Leser, liebe Leserin,

unser Ziel ist es, einen ersten Einblick in die Funktionsweise von Microsoft Robotics zu
geben, so dass auch jemand, der zum ersten Mal damit in Berührung kommt, in kurzer
Zeit einen Roboter zu steuern vermag.
Um dies zu erreichen, gibt es zunächst einen kleinen Rundgang durch die Standard-
Steuerelemente wie Daten-I/O oder Rechenoperationen, danach wird der Umgang und die
Kommunikation mit dem NXT-Roboter erläutert.

Um das Ganze ein wenig aufzufrischen (und die Seitenzahl zu erhöhen) wird alles mit
Hilfe von Beispielen motiviert, unter anderem ein einfaches „Hello World“, erste
Fahrversuche des Roboters, vollendet mit dem Programm, welches NXT durch ein
Labyrinth ohne fremde Hilfe geleitet. Einige dieser Beispiele werden sie auch auf der
Homepage zum Download finden, wenn Sie mal nicht weiterkommen oder einfach
ausprobieren wollen.

Da es natürlich nicht möglich ist, im Rahmen eines solchen Praktikums alle Aspekte der
Software zu erkunden, beschränken wir uns größtenteils darauf, die Visual Programming
Language zu erläutern, einige Hinweise zu den anderen Bestandteilen werden Sie aber
hier sicher auch finden. Dies begünstigt einen sanften Einstieg in die Materie, für wirklich
umfangreiche Routinen ist jedoch die Auseinandersetzung mit C# im Rahmen von
Microsoft Robotics ratsam.

                         Viel Spaß bei der Lektüre wünschen Ihnen

      Buote Xu (Buote.xu'at'gmail.com)            Robert Grandl (robert.grandl'at'googlemail.com)
      Mit freundlicher Unterstützung von Dr. Katja Mombaur und Benjamin Reh
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Inhaltsverzeichnis

Zu Microsoft Robotics Studio                1
VPL-Interface                               2
Input/Output                                3/4
Rechenoperationen                           5
Timing-Probleme / Parallelisierung          6
Die verschiedenen Ausgänge eines Services   7
Und Action!                                 8ff.

Robotik                                     13
Manifeste                                   14
Lego                                        15

FAQ                                         20
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Ein kurzer Überblick

Microsoft Robotics Studio (im Folgenden MRS) wurde im Jahre 2006 veröffentlicht und ist
zum Download frei verfügbar. (Installation siehe Anhang)

Mittlerweile in der Version 1.5 angekommen, bietet MRS eine Vielzahl an Möglichkeiten,
mit dem Roboter Ihrer Wahl Verbindung aufzunehmen. So wird unter anderem das eigene
VPL unterstützt, wer jedoch z.B. lieber in C#, Visual Basic oder .NET arbeitet wird sich
auch hier heimisch fühlen.
Das derzeit 87.5 MB große Softwarepaket umfasst derzeit die VPL Umgebung (die auf den
nächsten Seiten erläutert wird), mit deren Hilfe man Programme schreiben und debuggen
kann, web- und fensterbasierte Interfaces zur Kontaktaufnahme mit dem Roboter (wobei
sich das Webinterface weigert, mit Opera zusammen zu arbeiten) sowie
hardwarebeschleunigte 3D-Simulationen, in denen sich ein virtueller Roboter, der über den
DSS Manifest Editor erstellt wurde, austoben kann.
Intern steuert MRS über so genannte „Services“ den Roboter, diese können immer wieder
aktualisiert werden um auch neuere Modelle zu unterstützen, sowie Fehler bei älteren
auszumerzen, (der Lichtsensor funktioniert z.B. noch nicht 100% fehlerfrei mit den
derzeitigen Services)
auf diesem Wege können aber auch Beispielprogramme von Microsoft vertrieben werden
wie eine Fußballsimulation oder ein Sumo-Wettstreit.
Die Technik(Spiele)-Interessierten wird freuen, dass die 3D-Simulation über die PhysX-
Engine von Ageia realisiert wird, die auch in vielen Spielen eingesetzt wird.

Aber genug Gerede, jetzt geht es an die Praxis:

                                                                                          1
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
VPL: Visual Programming Language

Wenn Sie das Programm zum ersten Mal öffnen, wird Ihnen dieses Fenster begegnen:

        1                                                                          2
                                         3

          4                                                                      5

Unter 1 finden sie die Basic Activities, die größtenteils selbsterklärend sind, unter 2
haben sie schnellen Zugriff auf die verschiedenen Diagramme und Konfigurationen.

Die große leere Fläche namens Diagram bei 3 wird unser Hauptarbeitsplatz sein und sich
schneller füllen als Ihnen lieb ist, glücklicherweise gibt es rechts unten einen Schieberegler
mit dem man sich etwas mehr Überblick verschaffen kann.
Man füllt die Leere indem man Einträge aus 1 und 4 per Drag-and-Drop reinzieht.

4 beinhaltet die schon erwähnten Services, darunter so wichtige wie Text/Sprachausgabe,
mathematische Funktionen und die NXT-Steuerung. Tutorials sind auch vorhanden, aber
dazu haben wir ja den Guide hier. ;)

5 die Properties unterscheiden je nach ausgewähltem Objekt und bieten vor allem die
Möglichkeit sich einen schnellen Überblick zu verschaffen über die gewählte Konfiguration
des und die Daten, die über die Verbindung ankommen, Kommentare können hier auch
festgehalten werden.

Wir kommen zu unserem ersten Programm:

                                                                                            2
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Good morning, Vietnam!

Neu: Data, SimpleDialog
           Bei einem Klick auf int erhält man einen Überblick auf die unterstützten
           Datentypen, ansonsten ist Data unsere Methode Daten in unser Programm
           einzufügen.
           Wichtig: VPL ist case-sensitive.

             Dieser Service ist dafür zuständig, eine Dialogbox zu erzeugen, auf mehr als
             eine Weise!

Um unser Programm zu schreiben, ziehen wir einfach die beiden Einträge auf das große
Diagramm-Fenster und verbinden sie wieder mit Drag-and-Drop:

                                                               So einfach wird der Bund fürs
                                                               Leben geschlossen!

Anmerkung:
Der linke orange Kasten bezeichnet immer den Input, der rechte den Output eines
Elements.
Es sind mehrere Outputverbindungen möglich, jedoch immer nur ein Input.
                              Wundern Sie sich nicht über die aufpoppende Box: Wie
                              auch viele andere Services, bietet SimpleDialog mehrere
                              Methoden an, wie es mit den Daten verfahren soll:
                              AlertDialog erzeugt ein einfaches Popup, ConfirmDialog
                              eine Ja/Nein-Wahl und PromptDialog wartet auf eine
                              Eingabe des Nutzers mit möglicher Standardantwort, wir
                              begnügen uns hier mit Alert.

                              Die nächste Abfrage bestimmt darüber, welche Daten von
                              links nach rechts übertragen werden, dies kann man am
                              selben Output je nach Datenverbindung festlegen, also
                              auch an 2 verschiedene SimpleDialogs unterschiedlich
                              senden. Der Standardausgabewert vieler Objekte in MRS
                              wie auch hier ist value.
                              Ein Druck auf F5 sollte nach einem länglichen
                              Kompiliervorgang eine Dialogbox mit dem geforderten
                              Eintrag erzeugen. Glückwunsch zum ersten Programm!

                                                                                               3
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Falls es nicht funktioniert hat: halten Sie den Mauszeiger über die Verbindung und warten
Sie auf das Popup um nochmal zu überprüfen, dass alle Daten richtig übertragen werden
            oder klicken sie auf die Verbindung und betrachten die Properties.
                 Machen Sie dies immer wenn Ihr Programm nicht läuft!
MRS setzt gerne nach Änderung von Objekten Datenverbindungen auf null und der
Nutzer tappt bei seiner Fehlersuche dann im Dunkeln.
Wem es beliebt darf noch ein zweites SimpleDialog einfügen und sich gleichzeitig Length
ausgeben lassen, das Ergebnis sollten 2 Dialogboxen sein.

Hier sei noch zu erwähnen, dass Services mit dem selben Namen auch die gleiche
Instanz bezeichnen, dies wird später noch nützlich sein, ist jedoch beim SimpleDialog
nicht weiter wichtig.
Weiter im Programm:

Wie bereits erwähnt, kann PromptDialog eine vorgefertigte Standardantwort anbieten
zusätzlich zur Beschriftung der Dialogbox, aber wie fügt man einen 2. Wert hinzu, es ist
doch nur ein Input möglich? Die Lösung bietet folgende Basic Activity:
neu: Join
            Dies ist das Mittel der Wahl um einen Verbund (auch bekannt als struct) weiter
            zu geben, dabei sind beliebig viele Unterpunkte möglich.

Beispiel1:

Dem Leser sei nun überlassen, die Verbindungen richtig anzulegen um die Frage „Was ist
5+5?“ zu stellen, die zweite Dialogbox soll unsere Eingabe ausgeben.
Anmerkungen:
Join gibt einen Verbund value aus mit Unterpunkten msg und msg0, man kann zwar diese
direkt ansprechen, sollte sich aber im Hinterkopf behalten dass man sie eigentlich mit
value.msg bzw. value.msg0 bezeichnen muss.
Ausserdem wird auch nur ein Verbund ausgegeben, wenn alle Unterpunkte aktiv sind -
ganz im Gegensatz zu merge, doch dazu später.
PromptDialog gibt einen Verbund aus mit dem Unterpunkt TextData, man kann eine
unterschiedliche Aktion im Falle eines Misserfolges definieren.

                                                                                           4
Eine Dokumentation über Visual Programming Language Im Rahmen des Microsoft Robotics Studio Praktikums
Du kannst mehr Mathe als du denkst.

Im Jahr der Mathematik darf selbiges natürlich nicht zu kurz kommen:
neu: Calculate
             Dieses Objekt stellt die vier Grundrechenarten sowie den modulo-Operator zur
             Verfügung, doch das ist nicht alles!
             Auch eingebaut ist eine implizite Typumwandlung, so z.B. von Zahlen in
             Strings.
          Weitere Anwendung ist die Extraktion von einzelnen Daten aus einem Verbund.
Beispiel2:

Wieder unser Beispiel von vorhin, doch diesmal mit einem zusätzlichen
Kontrollmechanismus.
Wie in vielen anderen Programmiersprachen findet hier die Umwandlung statt indem man
einfach den Typ in Klammern vor den Ausdruck schreibt, so geschehen im ersten
Calculate. Dass dies funktioniert hat, kann man an der Verbindung zum Join sehen, wenn
man es mal selbst geschrieben hat: Das Popup berichtet über einen Datenfluss
CalculatedResult -> Join vom Typ int.
Strings werden wie so oft durch '' '' gekennzeichnet, unsere Typumwandlung lässt
außerdem als Eingaben nur Integer zu, Werte wie 10.5 oder auch AB werden einen leeren
String erzeugen.
Beispiel3:

Eine einfache Rechnung, zu beachten ist, dass man die Werte in Join sowohl als Verband
als auch ohne vorangestelltes value anfordern kann. Da Dialogboxen auf Dauer langweilig
sind, werden wir in den nächsten paar Programmen mit dem TexttoSpeech-Service
arbeiten und einige Timing-Probleme besprechen.

                                                                                            5
Das leidige Problem mit der Zeit

Die zeitliche Abfolge von Programmteilen ist mitunter etwas unklar, dies lässt sich gut mit
dem erwähnten TexttoSpeech sowie zwei weiteren Basic Activities zeigen:
neu: if und merge
              Verhält sich wie in jeder anderen Programmiersprache, über das Plus-
              Zeichen lassen sich weitere Abfragen einbauen, das Else-Kästchen darf
              dabei unverbunden bleiben.

              Zwar wurde zu Anfang behauptet, dass jedes Objekt nur einen Eingang
              besitzt, doch es gibt eine kleine Ausnahme: dieses kleine unscheinbare
              Objekt leitet alles weiter, was an seinen Eingang gelangt, dabei werden die
              Daten durchgelitten - es entsteht also ein Wert und kein Verbund.
                    Um dies zu verdeutlichen, die nächsten Beispiele:
Beispiel 4:

Die If-Abfrage wird hier dreimal nacheinander ausgeführt, da 3 verschiedene Datenströme
fließen, alternativ könnte man auch das ganze Konstrukt verdreifachen, die Reihenfolge
der Ausgabe ist allerdings nicht klar definiert.

Beispiel 5: Aufzählen der Zahlen von 10 bis 0

Zu diesem Programm ist zu sagen, dass das Endresultat nicht vorhersagbar ist!
(Es ist übrigens auch eins der Microsoft-Beispielprogramme)

                                                                                              6
Dies ist dem Umstand zu verdanken, dass die Schleife in einer sehr kurzen Zeit
durchlaufen wird, während die Textausgabe auf sich warten lässt. Die erhaltenen
Ergebnisse werden also in einen Puffer geschrieben und mehr oder weniger zufällig
ausgelesen, zumindest nicht 100% in der erwarteten Reihenfolge.
Wie also lässt sich dies lösen?
Weil TTS als Ausgabe nur Success bzw. Failure besitzt, ist es nicht möglich die Zahlen
durch zu leiten und TTS in die Schleife einzubauen, bleibt also nur eine Lösung:

          Der Grund, wieso sie nicht schon zu Anfang eingeführt wurden ist folgender:
          Sie sind in der Handhabung etwas umständlich und für einfache Programme
          schlichtweg nicht notwendig, jedoch ist es an der Zeit sie einzusetzen:

Variablendeklaration: Die Variablendeklaration erfolgt durch einen Klick auf ... des
Variablensymbols oder durch Edit -> Variables, es muss ein Name und ein Datentyp
angegeben werden.
Der Zugriff auf die Variable erfolgt auch durch die beiden Methoden SetValue und
GetValue:
                          Die einfachste Methode einer Variable einen Wert zu zu weisen.
                          Sie liefert auch einen Output mit dem Wert ihrer Variable,
                          allerdings als Verbund. (also als value.counter)

                           Den Wert der Variable liest man mit GetValue aus, welcher
                           unverständlicherweise auch einen Verbund ausgibt. Dies kann
                           zusammen mit join zu größeren Ketten/Variablennamen
                           führen.
                                  Wichtige Notizen zu Variablen:
–   Der Zugriff auf eine Variable erfolgt ausschließlich über GetValue, es ist also nicht
    möglich in ein beliebiges Calculate „counter“ zu schreiben in der Hoffnung etwas zu
    erreichen.
–   Dies führt dazu dass der Eingang eines Variable-Blocks immer verbunden sein muss,
    damit entweder Get- oder SetValue ausgelöst werden kann.
–   Diese Variablen sind nicht global, dieses Problem wird uns im Zusammenhang mit
    selbst geschriebenen Activities begegnen.
                                                         *Beispiel6:
                                                         Die Lösung unseres Problems,
                                                         man beachte ausserdem die
                                                         Umstellung auf
                                                         „SayTextSynchronous“; es wird
                                                         erst dann „Success“ ausgegeben
                                                         und die Schleife wieder in Gang
                                                         gesetzt wenn der Text
                                                         gesprochen ist, damit bleibt der
                                                         Puffer leer.

                                                                                            7
Exkurs: Ergebnisse und Ereignisse
Wer schon etwas eigenen Code gebastelt und dabei mit diversen Services
herumexperimentiert hat wird festgestellt haben, dass einige Objekte zwei Anschlüsse
besitzen, so zum Beispiel der Timer.

Neu: Timer

             Mit dem Timer kann man zum Beispiel den gesamten Programmablauf für eine
             bestimmte Zeit pausieren (wait), es ist aber auch möglich nur eine bestimmte
             Aktion verzögert beginnen zu lassen. (SetTimer -> TimerComplete)

Interessant: Wenn man an den runden Ausgang etwas anschließt, verschwindet der
Eingang! Das liegt daran, dass der Timer sowohl einen Ergebnis- als auch einen
Ereignis-Ausgang besitzt, wobei der runde Ereignisausgang hier eingangsunabhängig ist
und diesen somit nicht benötigt. Alle unserer bisherigen Objekte geben nur einmal einen
Wert aus, – von Schleifen natürlich abgesehen – genau dann, wenn ein Eingangswert
anliegt.
Ereignisse werden also verwendet, um mehrere Ausgaben zeitversetzt zu erzeugen.

Beispiel7:

Damit haben wir einen Wecker in VPL gebaut!
Die Tick-Funktion führt dazu, dass einmal pro Sekunde der Datenfluss angeregt, danach
die Uhrzeit ausgelesen und zum Schluss mit unserem gewünschten Wert verglichen wird.
Beispiel8:

                                                       Auch hier können wir viele
                                                       Ausgaben kriegen, ohne VPL-
                                                       Dateneingabe.
Um die Seite voll zu machen: Das erste Objekt werden wir später noch einmal verwenden,
um einen Roboter in der Simulation zu steuern. Aufgabe des Lesers ist es nun, sich damit
selbst etwas zu befassen, bei Ermangelung eines echten Controllers muss der
DirectionDialog herhalten.

                                                                                          8
Ordnung muss auch sein

Neu: Activity, Switch
              Activities entsprechen Funktionen in C++ und werden eingesetzt, um
              Übersichtlichkeit zu gewährleisten und Code zu sparen bei Wiederholungen.
              Es gibt jedoch (leider) einige wichtige Regeln im Umgang mit ihnen zu
              beachten:
–   Activities besitzen verschiedene Funktionen (actions) mit jeweils eigenen
    Eingabe/Ausgabetypen.
–   Funktionen innerhalb einer Activity können nicht auf Variablen auf der Hauptebene
    zugreifen, man muss also ein separates Set deklarieren.
–   Ereignisse können nur in der Start-Action einer Activity verwendet werden
–   Alle Funktionen innerhalb derselben Activity können auf die selben, internen Variablen
    zugreifen.
–   Die Entwickler haben eine Sicherheitsmaßnahme implementiert, die im
    Zusammenhang mit Funktionen und Variablenmanipulation zu einem Programmstop
    führen kann: Eine Funktion, innerhalb derer eine Variable verändert wird, bezeichnet
    man als exklusiv - diese können nur ablaufen, wenn keine anderen Funktion (müssen
    nicht exklusiv sein) aktiv ist. Umgekehrt kann also letztere auch nicht ausgeführt
    wurden wenn bereits eine exklusive am arbeiten ist. Dies kann, wie noch in einem
    Beispiel demonstriert wird, zu erheblichen Problemen führen. (In der nächsten Revision
    wird man vor der Kompilation gewarnt, falls ein solcher Konflikt vorliegt.)

              Ein Switch dient dazu, einen ankommenden Wert mit einer vorgegebenen
              Auswahl zu vergleichen und gegebenenfalls die dazugehörige Anweisung
              auszuführen. Dabei wird, falls es mehrere matches gibt, nur der oberste
              Eintrag aktiviert. Hinweis: Else ist nicht unbedingt nötig, value als unterster
              Vergleichswert funktioniert auch.
*Beispiel9: Rechner

                                Ok, und weiter?

So sieht zwar die oberste Ebene eines Taschenrechnerprogramms aus, doch wird man in
dieser Ansicht nicht viel damit anfangen können, wir beginnen also erst einmal mit einem
kleinen Crashkurs in Sachen Activity:
Nachdem man eine neue Activity erstellt hat, kann man durch einen simplen Doppelklick
Einfluss auf die Funktion unseres neuen Objektes ausüben.
                       Bei 1 wird die gerade aktive Unterfunktion angezeigt, von denen man
                       beliebig viele haben kann. Über 2 erhält man Zugriff auf ein neues
          1        2   Menü, mit dem man einige nützliche Sachen machen kann.

                                                                                                9
Hier ist das angesprochene Menü,
                                                      dabei hat jedes Activity sein eigenes.
                                                      Unter 1 kann man weitere Aktionen
                                                      erstellen, für die man jeweils
                                                      Datentypen für die 2 Ein-bzw.
                                                      3 Ausgabe festlegen kann.
         1                                            Wer gerne eine Ereignisausgabe
                                                      haben möchte, muss dies im Reiter
                                                      Notifications vornehmen, Beispiele
                                                      dazu folgen.
                           2             3
                                                      Unser Programm soll nun in der
                                                      Lage sein, 2 Werte und einen Befehl
                                                      entgegen zu nehmen und daraufhin
                                                      eine Lösung zu präsentieren.

Es wird langsam eng!

Nicht im Bild zu sehen: Das oberste SimpleDialog-Objekt ist mit dem Action-Eingang
verbunden, diese Daten sind vom Typ string (oben als result zu sehen). Außerdem wird
hier stark von der Möglichkeit Gebrauch gemacht, Werte direkt einzugeben, in unserem
Fall hier sparen wir etwa 10 Data-Blöcke.
Wichtig: DefaultValue des erstes Dialoges muss den Wert des Eingangs annehmen, da
wir dies auch als Ergebnisausgabe nutzen werden.
Die Calculate-Blöcke dienen dazu, die Eingaben der Prompts auszuwerten und
weiterzugeben. Den Join-Block erreichen 3 Strings, da der PromptDialog nur diese
erzeugt. Da die Beschriftung des Blocks eindeutig ist, sollte klar sein, an welcher Stelle
welche Daten übergeben werden müssen, dies wird dann gesammelt an unsere Activity
geschickt, jedoch an einen anderen Action-Block.
Man beachte, dass unsere Action keinen Ausgang benötigt.

                                                                                             10
Hinweis: Man sieht in
diesem Block einige
Warnungen: Das liegt
daran, dass eine Action
nicht weiß, dass am
Eingang ein Verbund von
Daten anliegt und
demnach nichts damit
anfangen kann, wenn wir
z.B. input.value1
anfordern. Der
tatsächlichen
Funktionsweise tut dies
jedoch keinen Abbruch.

                      11
Einige Hinweise:
–   Da wir als Eingabewerte Strings erhalten haben, muss innerhalb der Calculate-Activity
    eine Typumwandlung vollzogen werden damit gerechnet werden kann.
–   Es wird auf die Unterpunkte des vorherigen Join zugegriffen, dies ist tatsächlich trotz
    der Warnungen, dass unsere angeforderten Werte nicht existieren, möglich.
–   Wir bedienen uns hier der Tatsache, dass ein Join erst dann etwas ausgibt, wenn alle
    Werte anliegen, switch steuert somit die Ergebnisauswahl, da nur ein Wert
    weitergegeben werden sollte.
–   Da Calculate immer value ausgibt, wird spätestens hier eine Übereinstimmung
    stattfinden und unser Programm auch bei einer fehlerhaften Eingabe weiterlaufen.
    (Selbst wenn es Humbug produziert)
–   Aus den verschiedenen Verbunden muss noch der Wert extrahiert werden, dies
    geschieht wie bisher über ein Calculate.
–   Unser Ergebnis wird zurück an unseren vorherigen Block geschickt, es sollte klar sein
    in welchem Rahmen das Ergebnis nun erscheinen wird.
–   Es ist theoretisch möglich beliebig lange weiter zu rechnen, beendet werden die
    rekursiven Aufrufe indem man bei einem der Dialogboxen auf x klickt.

Neu: List, List Functions, Compile as Service
           Dieses Element wird verwendet um neue Listen zu erzeugen, dabei werden
           alle Standarddatentypen unterstützt. Elemente werden über listenname[i]
           ausgegeben, wobei der Zählindex i bei 0 anfängt.

               Es ist möglich, Listen zu vereinigen oder auch einfach nur Elemente
               anzuhängen, um spezifische Objekte zu verändern kann man sich der
               remove bzw. insert Option bedienen.

*Beispiel10:
–   Dieses Beispiel berechnet mit Hilfe des Siebs von Erastothenes alle Primzahlen
    zwischen 2 und 10000
–   Es wird zuerst eine Liste mit 10000 Einträgen geschaffen, wobei die hinteren 9998 auf
    den Wert 'true' gesetzt werden.
–   Beginnend bei 2 wird zunächst untersucht ob der Listeneintrag auf 'true' steht, wenn ja
    werden alle Vielfachen auf 'false' gesetzt, ansonsten wird einfach der nächste Eintrag
    überprüft.
–   Wenn man bei 100 angekommen ist, sind nur noch Primzahlen markiert
–   Dieses Verfahren ist in VPL durch die vielen Listenoperationen und Echtzeitkontrolle
    langsam, deshalb gibt es zum Vergleich noch *Beispiel11, dort wird einfach die
    Teilbarkeit durch Primzahlen überprüft, welches schneller funktioniert.
–   Als kompilierter Service beschleunigt sich die Durchführung um ein Vielfaches, das
    Ergebnis lässt sich im Service Directory betrachten.

                                                                                              12
Der Umgang mit einem Roboter

Da Microsoft Robotics Studio vor allem der Kommunikation mit Robotern dienen soll, wird
es Zeit, einige der Services vorzustellen die dies ermöglichen.
Zunächst einige Hintergrundinformationen:
–   Wenn der gewählte Roboter kein eigenes MSRS-fähiges Betriebssystem besitzt ( wie
    zum Beispiel der Lego NXT ), wird ein Computer benötigt der die Steuerung des
    Roboters übernimmt, indem er mit ihm über eine geeignete Schnittstelle kommuniziert
    (seriell, Bluetooth, USB)
–   Bis jetzt ist MSRS auf Windows bzw. Windows CE lauffähig, da es sich um ein offenes
    Protokoll handelt (DSSP) ist jedoch auch eine Portierung auf andere Plattformen
    denkbar.
–   Die meisten Services besitzen bis jetzt nur Implementierungen für
    Zustandsänderungen, kompliziertere, z.B. kinetische Vorgänge müssen entsprechend
    selbst geschrieben werden, am besten in Visual C#.

Wir beginnen nun mit einem kleinen Programm, welches eine simulierte Umgebung erstellt
und uns eine kleine Rundfahrt ermöglicht.

Neu: GenericDifferentialDrive, DirectionDialog
                     Ein Service der 2 Motoren steuern kann, optionale Angaben für
                     Reifenabstand/radius möglich für Drehungen um einen
                     vorgegebenen Winkel. Benötigt als Anfangskonfiguration ein
                     Manifest um die Hardwarezugehörigkeit zu ermitteln.

                     Zur Steuerung, erzeugt ein Dashboard mit 5 verschiedenen
                     Ausgaben.

Beispiel11:

                                                                                      13
–   Der DirectionDialog gibt einen Verband aus, muss daher über Calculate ausgewertet
    werden.
–   Über den Datenpfad SetDrivePower kann man den beiden Rädern jeweils einen der
    Werte weitergeben.
–   Beliebter Fehler: Beim Wenden in eine bestimmte Richtung muss jeweils das andere
    Rad eine positive DrivePower erhalten.
–   Über die Eigenschaften des GenericDifferentialDrive lässt sich ein Manifest laden,
    hier ist LEGO.NXT.Tribot.Simulation.Manifest.xml empfehlenswert, es wird eine
    simulierte 3D Umgebung geladen mit einem Tribot, den man über das Dashboard
    steuern kann.

Exkurs: Manifeste

Mit diesem Programm, welches zu Microsoft Robotics Studio gehört, lassen sich Manifeste
erstellen.
Diese sind *.xml-Dateien, die dazu dienen eine vorgegebene Liste von Services zu laden,
dabei ist es möglich Konfigurationen vorzugeben. Darüber hinaus kann man schon in
dieser Ebene Bauteile miteinander verbinden, wie zum Beispiel die Motoren mit der Lego
Steuereinheit.
Eine weitere Fähigkeit besteht darin, Deployment Packages zu erstellen, dies sind
selbstextrahierende Archive die neben dem Manifest auch die einzelnen Services
beinhalten.
Zu guter Letzt kann man das Manifest starten, ähnlich wie in der VPL Umgebung wird
dadurch der DSS-Host aufgerufen und das Webinterface steht bereit, eine kleine
Abkürzung falls man kein eigenständiges Programm sondern nur die Services laden
möchte.

                                                                                         14
Lego in der Praxis

Hier sehen wir den Lego-Tribot, der während des Praktikums zum Einsatz gekommen ist.
Dabei wurden, zusätzlich zur Steuereinheit und zweier Motoren, Lichtsensoren eingesetzt
damit der Roboter auf eine Änderung seiner Umgebung korrekt reagieren kann.
Auf den nächsten Seiten werden die Services vorgestellt, die es möglich machen den
Lego-Tribot anzusprechen, diese sind mittlerweile in der Version 2 vorhanden und bei der
Standardinstallation von Microsoft Robotics Studio mitgeliefert.
Dazu werden noch einige Beispielprogramme gezeigt, die im Laufe dieses Projektes
entstanden sind und die Fähigkeiten von VPL demonstrieren sollen, Kommentare werden
nicht fehlen jedoch sollten einige trivialere Bausteine auch vom Leser schon verstanden
werden.
Den Abschluss bildet ein kleines FAQ, welches von VPL Distanz nimmt und einige
generelle Fragen zu Microsoft Robotics Studio beantwortet, soweit es der Rahmen dieses
Projekts ermöglicht.

                                                                                       15
The NXT Generation

neu: LegoNXTBrickv2, LegoNXTLightSensorv2, LegoNXTDrivev2,
     LegoNXTSoundSensorv2, LegoNXTUltrasonicSensorv2

            Dies ist die zentrale Steuereinheit die in jedem Projekt vorhanden sein muss,
            welches in irgendeiner Weise den Lego NXT Roboter verwendet. Es lässt
            sich sowohl die Kommunikationsmethode als auch der verwendete Port
            festlegen, welches man auch tunlichst machen sollte.
            Ein Service der vom GenericDifferentialDrive abgelitten wurde und somit
            die selben Methoden (und bugs) besitzt. Es lassen sich einige zusätzliche
            Einstellungen wie der Verbindungsport mit der Brick angeben, die Räder
            müssen einzeln zugeordnet werden.

Wir kommen zur Gruppe der Sensoren, die größtenteils ähnlich aufgebaut und
angesprochen werden können, da sie allesamt auf dem GenericAnalogSensor basieren.
           Der Lichtsensor ist leider etwas verbuggt, die LED muss manuell über den
           Eingang SpotlightUpdate eingeschaltet werden. Ansonsten funktioniert er wie
           erwartet und gibt einen Double-Wert zurück, der der Helligkeit entspricht und
           skaliert werden kann.
             Der Tastsensor besitzt sowohl einen analogen als auch einen digitalen
             Wiedergabewert, diese sind ziemlich klar.

             Ab einem Bereich von 70 cm gibt der Ultraschall-Sensor einigermaßen
             verlässliche cm-Werte aus.

             Der letzte unserer Sensoren, gibt die Intensität der Umgebungslautstärke an.

Beispiel12: Spotlight anschalten
                                                Sieht einfach aus, ist es auch. Dem
                                                Leser sei überlassen das Ausschalten
                                                der LED über den TouchSensor
                                                zusätzlich zu implementieren.

                                                                                        16
Beispiel13: Hindernissen ausweichen

Noch ein einfaches Programm bei dem unser Roboter lernt diversen Hindernissen
auszuweichen indem er sich weg dreht, aber eigentlich ist das Programm relativ
selbsterklärend.
*Beispiel14: Labyrinth
Hardware: Brick, 2 Motoren, 2 Lichtsensoren

Wir verwenden hier eine Activity, die 3 Actions enthält: Initialize, Drivecontrol und Compare
–   Es wird eine Verzögerung eingebaut weil die LEDs eine gewisse Zeit benötigen um
    aktiviert zu werden, da die Initialize-Funktion einen Richtwert setzt mit dem im weiteren
    Programmablauf verglichen wird – geschieht dies zu früh ist natürlich die Messung
    nicht zu gebrauchen.

Dies ist das Innere der Compare-Funktion, sie wird in der Drivecontrol verwendet und ist
vom Lichtsensor unabhängig.

                                                                                           17
Dies ist nun der Kern des Programms, wie
                                              man sieht kann die Compare-Funktion
                                              mehrere Male genutzt werden, weil die
                                              DriveControl-Funktion keine
                                              Variablenmanipulation ausführt.

Die Suche funktioniert nun folgendermaßen:
Es wird möglichst versucht eine Rechtsdrehung zu vollführen sofern dies möglich ist, also
der rechte Lichtsensor einen Weg „sieht“. Wenn der gerade Weg zur Verfügung steht, ist
er die 1. Alternative, ansonsten wird auf gut Glück nach links gedreht – wenn nichts
gefunden wird macht sich der Roboter auf den Rückweg.
Dieser Algorithmus sorgt nun dafür, dass der Roboter zum Einen relativ stabil auf einer
Geraden bleibt, zum Anderen wird sichergestellt, dass alle Wege einer Kreuzung
zumindest einmal abgefahren werden, das Ziel wird also in einer endlichen Zeit gefunden.
Der rekursive Aufruf macht hierbei das Timing wesentlich einfacher, da keine Variablen zur
Zwischenspeicherung der Sensorwerte genutzt werden müssen. So eine Variante ist im
Beispielordner vorhanden als Beispiel14b, so kann man sich selbst ein Bild machen
welche zu bevorzugen ist.

                                                                                        18
*Beispiel15: Linie
Hardware: Brick, Motoren, 1 Lichtsensor
Diesmal ist die iterative Variante vorzuziehen, doch beide haben ihre diversen Probleme in
VPL, bei der Bekämpfung selbiger lernt man aber schnell was dort einfach nicht möglich
ist bzw. über Umwege gelöst werden muss.

Bemerkenswertes zu Beispiel15/15b: (man möge die Datei in VPL laden und mitlesen)
–   für die verzögerte Ausführung eines einzelnen Programmteils ist es nicht sinnvoll, Wait
    zu verwenden, da dabei der gesamte Programmablauf unterbrochen wird. Stattdessen
    wird, wie in Drivecontrol geschehen, ein Timer gesetzt, der über den Ausgang
    TimerComplete abgefragt wird.
–   Problem: TimerComplete kann nur über den Ereignisausgang verwendet werden, also
    muss der Timer in die Start-Aktion gesetzt werden da nur dort Ereignisse auftreten
    können.
–   Um einen reibungslosen Ablauf zu garantieren, sollten Flags in Form von Variablen
    gesetzt werden, es gibt sonst keine Methode den Roboter einen bestimmten Winkel
    drehen zu lassen da diverse Sensorcheck Befehle immer wieder von neuem
    ausgeführt werden würden.
–   Bei der rekursiven Implementation ist es nicht möglich die Compare-Funktion
    innerhalb von Drivecontrol auszuführen, da beide auf Variablen zugreifen und somit
    gegen diverse Sicherheitsrichtlinien von MRS verstoßen – bleibt nur die Funktionen
    aufzuschlüsseln.
–   Das Programm funktioniert nun derart, dass über diverse Variablen sowohl der
    Suchbereich wie auch die Suchrichtung festgehalten werden und zwar
    folgendermaßen: (vorgeführt an der iterativen Variante ohne b)
–   search_direction ist ein double-Wert der zwischen 1 und -1 wechseln kann, dies
    ermöglicht effizient eine Richtungsänderung, da Drive_Power nur damit multipliziert
    werden muss.
–   Searching ist unsere Flag, die angibt ob gerade nach dem Weg gesucht wird. Solange
    dies für eine bestimmte Zeitspanne gemacht wird, kann der Vorgang nur dadurch
    gestoppt werden dass der Lichtsensor das richtige Signal findet.
–   Ist allerdings die Zeitspanne verronnen und es ist kein Pfad in Sicht, so wird durch step
    die Zeitdauer erhöht und die Suchrichtung gedreht, die Suche beginnt von neuem.
–   Diese Implementation führt dazu, dass bei einer geraden Strecke der Roboter
    gegensteuert, sodass er auch nach dem Wieder eintritt sehr schnell wieder geradeaus
    fährt und nicht „twitcht“.

                                                                                          19
Häufig gestellte Fragen:

–   Welche Betriebssysteme werden unterstützt?
      Bis jetzt ist MSRS lauffähig auf Windows2k/XP, CE sowie Vista ,wobei dort die
      Simulationsumgebung noch nicht funktioniert. Es soll aber laut Microsoft nur
      eine Frage der Zeit sein, bis auch die Unix-Systeme unterstützt werden.

–   Welche Anforderungen werden an meinen Roboter gestellt?
      Prinzipiell keine, so lange er programmierbar ist.
      Bis jetzt werden unter anderem der Lego NXT und die Fischer-Roboter nativ
      unterstützt, einige findige Hobbyisten sind dabei, viele Weitere zu implementieren –
      dies entspricht dem Aufwand den Roboter über C# anzusteuern.
      Da es nicht nötig ist, die Software auf dem Roboter selbst laufen zu lassen und
      somit genügend Rechenpower zur Verfügung steht, lassen sich auch andere
      Komponenten wie eine Webcam parallel ansteuern.

–   Wie schnell reagiert die Steuerung des Roboters?
       Es gibt verschiedene Faktoren die die Perfomanz negativ beeinflussen:
       Bluetooth ist sehr angenehm, verzögert aber jeden Signalrichtungswechsel um
       mehrere zig Millisekunden.
       Wenn man in VPL programmiert und eine niedrige Latenz benötigt wird, ist es
       empfehlenswert sein Programm zu kompilieren – sonst muss mit
       Leistungseinbußen gerechnet werden da VPL eine interpretierte Sprache ist.

–   Ich habe ein Problem, wo finde ich Hilfe?
       Deutschsprachige Anlaufstellen sind bis jetzt leider Mangelware, wer hingegen des
       Englischen mächtig ist findet schnell Hilfe im offiziellen Microsoft Developers
       Forum oder im MRS Wiki, auch einige der Programmierer von Robotics Studio
       stehen dort mit Rat und Tat zur Seite.

–   Wie ist die Einarbeitungszeit in Robotics Studio einzuschätzen?
       Dies kommt ganz darauf an, was man damit machen will. Solange man mit
       existenten Teilen arbeitet und nur sein erstes Programm sehen will, ist mit wenigen
       Stunden gut dabei, Erfahrung im Umgang mit visuellen Sprachen ist aber dabei
       hilfreich.
       Will man tiefer in die Materie einsteigen, also über die VPL und den Simulator
       hinaus neues entwickeln, dem sei ans Herz gelegt, dass es ein längerer
       Lernprozess sein kann der sich nur lohnt, wenn man sehr viel mit Robotern zu tun
       hat.

                                                                                         20
Sie können auch lesen