Offboard Software

 

Inhaltsverzeichnis[Anzeigen]

Nutzen und Anforderungen

Das Programm, mit dem der Flug des Zeppelin geplant, überwacht und geregelt wird, wurde innerhalb des "Praktikum Informationsverarbeitung" am LDV entwickelt. Die grundlegenden Aufgaben des Programms sind:

  • die Entfernungen von verschiedenen Punkten im Raum zu einem Flugobjekt in Positionsdaten (X, Y und Höhe) umzuwandeln. 
  • Anhand von definierten Zielkoordinaten eine Wegstrecke zwischen Hindernissen selbstständig zu errechnen
  • Die Flugstrecke zu überwachen und ggf. zu korrigieren

Dabei gibt es zwei wichtige Schnittstellen: Der Empfang der Entfernungen über eine serielle Schnittstelle (z.B. Arduino mit USB-Kabel) und das Senden der Schubdaten über einen weiteren seriellen Port (z.B. Xbee)

 

Was kann das Programm

  • Positionsbestimmung anhand Alex's IPS
    • Kommunikation mit dem IPS über serielle Schnittstelle
    • Verarbeitung des Datenpakets (mit bis zu 9 Stationen) und Filterung der Werte
    • Positionsbestimmung im Raum (Breite, Länge und Höhe)
    • Datenrate kann sich beliebig dem IPS anpassen
  • Lagebestimmung
    • Die Lage kann anhand der Positionshistorie des IPS ermittelt werden oder durch einen Lagesensor auf dem Flugobjekt. Eine Kombination beider liefert die besten Werte.
  • Wegberechnung
    • Es wird ein Weg zu einem Zielpunkt berechnet
    • dabei werden alle Hindernisse umflogen (inkl. Wände)
  • Regelung während des Fluges
    • Während des Flugs wird die Flugbahn überwacht und der Kurs ggf. korrigiert
    • Die Schubdaten werden anhand eines einfachen Protokolls über die serielle Schnittstelle übertragen
  • Benutzeroberfläche
    • Die Benutzeroberfläche ermöglicht eine Anpassung des Programms ohne tiefgehende PC und Programmierkenntnisse
    • In der Benutzeroberfläche können nahezu alle Werte angepasst werden: Position der Distanzmesser, Hindernisse, Zielkoordinaten, Spannweite der Motoren, Grenzwerte für die Reglung, Abweichungen der Motoren,..
    • Anzeige von: berechnetem Weg, geflogenem Weg, aktuellen Schubwerten, Kommunikation der zwei seriellen Schnittstellen
    • manuelle Steuerung über die Tastatur zuschaltbar
  • Plattformunabhängiger C++ Code, fertig kompiliert für Windows und Linux

 

Was kann es nicht

  • Positionsbestimmung anhand von Systemen die nicht auf der Distanzmessung beruhen (Winkelmessung, Beschleunigungssensoren) (muss programmiert werden)
  • Wegberechnungen von einem beliebigen Startpunkt aus. (Es wird immer die aktuelle Position des Zeppelins zur Berechnung verwendet)

 

Vorausetzungen

  • Es muss ein distanzmessendes System vorhanden sein (z.B. Alex's IPS inkl. Sender auf dem Flugobjekt)
  • Ein Lagesensor auf dem Flugobjekt ist von Vorteil
  • Eine Kommunikationsmöglichkeit zwischen Flugobjekt und serieller Schnittstelle am PC (z.B. Xbee)
  • ausreichend starker PC auf x86 Architektur (Linux oder Windows)
  • Das Flugobjekt muss die Höhen-/Rechts-/Links-Schubwerte selbständig umsetzen können

 

Konzept

 

Grundlegendes

Das Konzept des Programms ist für den Bediener nur in den Grundzügen wichtig. Solltest du allerdings vorhaben Änderungen im Programmcode vorzunehmen, legen wir dir nahe unbedingt das Kapitel "Vertiefung des Konzepts" zu lesen.

Bei dem Entwurf des Programms wurde besonders auf die einfache Bedienbarkeit wert gelegt. Daher lassen sich die wichtigsten Parameter vom Nutzer einstellen. Teilweise wären einzelne Funktionen technisch einfacher oder besser umsetzbar gewesen, aber hätten der Usability geschadet, in solchen Fällen haben wir uns konsequent für die leichter Bedienbarkeit entschieden.

Wichtig ist zuerst zu verstehen, dass die Wegfindung in diesem Programm nicht anhand von vorgegebenen Wegpunkten festgelegt wird, sondern nur ein Ziel angegeben wird. Zusätzlich werden Hindernisse eingetragen und festgelegt wie rum diese umflogen werden sollen. Anhand dieser Daten berechnet die Wegfindung die Flugstrecke. Dieses Konzept basiert auf der Annahme dass ein Slalom passiert werden muss, funktioniert aber auch in anderen Szenarien.

 

Ablauf der Datenverarbeitung

Das distanzmessende System (z.B. IPS) sammelt die Laufzeiten der einzelnen Stationen und übertragt diese über eine serielle Schnittstelle (z.B. ein Arduino der per USB angeschlossen ist) an das Programm. Die Werte werden abgespeichert.

Das Programm aktualisiert seine Positionsdaten in festen Zeitintervallen (kann anhand der Einstellung "Refreshrate [ms]" geändert werden). Dafür werden die letzten gesendeten Daten gefiltert (unter "Filtereinstellungen" kann der Filter angepasst werden) und in der Liste der Wegpunkte abgelegt.

Die Wegberechnung nutzt diese Daten und überprüft anhand dieser verschiedene Fälle:

    • Ist das Ziel erreicht? Hier stoppen alle Motoren
    • Ist das Zwischenziel erreicht? Hier wird ein gesondertes Signal gesendet. (Die erste Zahl im Datenpacket an das Flugobjekt wechselt von 1 auf 2). Im Code des Flugobjekts kann dadurch ein beliebiger Code ausgeführt werden.
    • Ist ein Kurswechsel nötig? Die Flugbahn unterscheidet sich in zwei Modi: Der Geradeausflug und der Kreisflug. Die Verbindungsstrecke zwischen zwei Hindernissen wird immer gerade geflogen. Hindernisse werden immer in einem möglichst großen Kreisradius umflogen. Flugrichtungsänderungen werden nur an Hindernissen vorgenommen

 

  • Ist die Abweichung vom aktuellen Kurs zu groß? Dabei werden 3 Szenarien unterschieden:
    • Abweichung innerhalb der Toleranzgrenze (Einstellung "Regelgrenze in der GUI")? Dann erfolgt keine Änderung der Flugbahn
    • Ist die Abweichung innerhalb des Regelbereichs? Dann wird das Flugobjekt durch einen Regler wieder zurück auf seine Flugbahn geregelt.
    • Ist die Abweichung im Notfall Bereich? (Einstellung "Notfallgrenze"). Wird der Notfallmodus aktiviert. Der Notfallmodus dreht das Flugobjekt senkrecht zur Sollstrecke, fliegt dann geradeaus bis zum Erreichen der Sollstrecke und richtet sich zum Schluss wieder entlang der Flugstrecke aus

Ist der Weg berechnet werden die aktuellen Schubdaten der Motoren ermittelt: rechter und linker Motor und mit dem Höhenschub kombiniert als Paket an das Flugobjekt gesendet.

Die Höhensteuerung gleicht den Soll und Ist-Wert der Höhe ab und regelt dementsprechend den Schub für den Höhenmotor. Die Sollhöhe kann in der GUI unter "Sollwert" eingestellt werden.

Bei der Handsteuerung werden die Schubdaten manuell manipuliert. Dabei wird die autonome Wegberechnung deaktiviert. Die Tasterturbefehle sind: Pfeiltasten zum Kurven und Geradeausflug, die Tasten X und Y für den Höhenschub und die Leertaste zum Stoppen aller Motoren. 

 

 GUI

How to fly

Alle Einstellungsmöglichkeiten sind mit einem Tooltip, direkt im Programm versehen. Wenn man mit dem Cursor länger über den Einstellungen bleibt erscheint der Tooltip.

Im folgenden soll nur eine kurze Anleitung gegeben werden, wie man losfliegt:

 

Einige Einstellungen müssen vor dem Starten des Fluges getroffen werden:

Zuerst sollten auf der rechten Seite die Com Ports für die Kommunikation PC-Bodenstationen (IPS-Com) und PC-Zeppelin (XBee-Com) geöffnet werden. Hier kann man auch ablesen, welche Daten empfangen und welche Daten gesendet werde.

Die BAUD-Rate kann so bleiben, den COM-Port muss man je nach Computer auswählen, bei Problemen schreibt man den COM-Port manuell in das Feld. (Wichtig: darauf achten, dass an dem Xbee Port auch wirklich das Xbee hängt und ebenso beim IPS)

Anschließend werden im zweiten Reiter (Hindernisse + Zielkoordinaten +...) die erforderlichen  Eingaben für die Wegfindung vorgenommen :

  • Zielkoordinaten des Parcours
  • Koordinaten des Abwurfpunktes
  • Wenn man um Hindernisse fliegen will, muss man die erforderlichen Werte für die Hindernisse in der linken Tabelle eintragen
  • bei echtem Flug muss hier auch der Offset der beiden Motoren eingetragen werden

Will man mit dem IPS fliegen, muss man im dritten Reiter (IPS-Sender) die Einstellungen für das IPS durchführen:

 

  • Bodenstationen eintragen
  • Filtereinstellungen vornehmen

 

Hat man diese Einstellungen erledigt kann man zum ersten Reiter (Karte+Handsteuerung) zurückkehren:

Hier muss erst einmal der Start/Reset Button betätigt werden. Dabei wird das erste Zwischenziel berechnet und in die Karte eingetragen.

Danach hat man zwei Optionen:

Realer Flug: zunächst muss die Imu initialisiert werden. Dafür muss der Zeppelin in x-Richtung ausrichten und IMU-Reset-Button drücken. Danach muss bei den Flugeinstellungen die Positionsbestimmung, Höhensteuerung und der reale Flug angeklickt werden und der Zeppelin startet.

Flug nach Simulation: hierzu einfach die Simulation anwählen. Startpunkt ist immer der Ursprung.

Wenn man seine Positionen löschen möchte oder die Simulation neu starten möchte, kann man per Klick auf den Reset-Button alle Positionen löschen.

Man kann den Zeppelin aber auch per Hand steuern. Dann dürfen aber weder realer Flug noch Simulation angeklickt sein. (autonome Höhensteuerung ist möglich)

 

Vertiefung des Konzepts

Struktogramm des Programmablaufs (in höherer Auflösung im Anhang)


IPS und Schnittstellen

 

Das Konzept der Bodenstationen wird hier (Gemeinsames IPS) erläutert. Das Kommunikationsprotokoll zwischen IPS ist wie in der Grafik aufgebaut.

In unsere Software werden alle Datenpakete die nicht das "t" an Position 2 beinhalten verworfen. Die letzten 15 Laufzeiten der Stationen werden im Programm abgespeichert.

Wird nun eine Position durch das Programm angefordert durchläuft das System folgende Schritte:

Filter Stufe 1: Es werden (entsprechend der GUI Einstellungen) die letzen x Zeitwerte einer Station abgefragt, ist eine Null dabei (Station hat nichts gesendet) wird der Wert übersprungen und der nächste genommen (Bis zum Limit in der GUI). Danach werden die Werte sortiert und die Randwerte (GUI) gestrichen, aus den restlichen Werten wird der Mittelwert gebildet.

Dieses Filterverfahren ist an sich gut, nur treten bei dem IPS sehr häufig 0 Werte auf, will man die Positionsbestimmung noch verbessern, sollte man sich hier Gedanken machen. Außerdem kann durch eine geschicktere "Portionierung" der Com-Port Werte sicherlich ein besserer Wert erzielt werden.

Positionsermittlung: Aus den Mittelwerten der verschiedenen Stationen wird in einem numerischen Verfahren (Gradientenverfahren, Ursprung: Markus) die Position des Zeppelins ermittelt.

Filterstufe 2: In dem plausibilitäts Filter werden alle Werte verworfen die eine zu große Abweichung zu den letzten Werten darstellen (GUI Max-Speed). Wird aber 5 mal hintereinander ein Wert außerhalb der Toleranz ermittelt, wird der aktuelle Wert trotz Abweichung übernommen.

Vorsicht: Durch diesen Filter kann es passieren, dass längere Zeit alte Werte verwendet werden, allerdings konnten wir damit in der Realität keine Probleme feststellen.

Quellcode: ips.cpp


Regelung

Regelung

Bei der Höhensteuerung haben wir selber einen rudimentären PD-Regler geschrieben. Die Abweichung vom Sollwert wird in den Schub des Höhenmotors umgewandelt. Sollte sich der Motor schon wieder in Richtung des Sollwertes bewegen, gibt es einen Rückschub um den Flug abzubremsen. Dies soll einen stark schwingenden Flug verhindern.

Auch die Flugregelung ist eher einfach aufgebaut und logikbasiert:

Sobald das Flugobjekt außerhalb einer Notfalltoleranz ist, wird der Notfallmodus aufgerufen. Das Flugobjekt richtet sich auf die Flugbahn, fliegt hin und dreht sich dann wieder Richtung Ziel.

Ist der Zeppelin außerhalb der Regeltoleranz, aber innerhalb der Notfalltoleranz wird die Abweichung von der Flugbahn zusätzlich zum Schub des rechten bzw linken Motors addiert. Dies passiert solange bis sich das Flugobjekt wieder innerhalb der Toleranz befindet oder die Ausrichtung auf die Flugbahn einen Winkel von 20° erreicht hat.

Innerhalb dieser Toleranz wird versucht die Ausrichtung des Zeppelins in Richtung der Flugbahn zu halten. Auch hier wird wieder die Abweichung vom Sollwert in den Schub umgewandelt.

Wenn das Flugobjekt im Ziel befindet, werden die seitlichen Motoren gestoppt (und die Flugregeung beendet). Die Höhensteuerung bleibt aber aktiv.

Sobald die Abwurfkoodinaten erreicht sind, wird der Befehl "Abwurf auslösen" an das Flugobjekt (siehe Schnittstelle Xbee) kommuniziert.

Da wir sehr spät mit den Testflügen beginnen konnten, ist uns die Zeit ausgegangen die Regelung zu verbessern. Hier besteht Optimierungsbedarf.


Quellcode: https://github.com/Koerner/Sturzflug-at-daedalus.ei.tum.de/blob/master/weg.cpp

 

Wegfindung


Sobald man Hindernisse in der GUI eingetragen hat und „Hindernisse speichern"-Button geklickt hat, werden die Radien der Kreise, auf denen der Zeppelin entlang fliegen muss, berechnet. Um einen möglichst großen Abstand zu allen Hindernissen während des Kreisfluges zu erhalten, ist der Radius die Hälfte des Abstandes zum nächsten Nachbar (anderes Hindernis oder Wand).

Um einen flüssigen Verlauf durch den Parcour zu garantieren, soll das Flugobjekt auf einer Kreisbahn um die Hindernisse und auf Geraden zwischen den Kreisen, die Tangenten mit den Kreisen bilden, fliegen.
In der Wegfindung wird also immer der Tangentenpunkt als nächstes Zwischenziel bestimmt.
Sobald ein Zwischenziel erreicht ist, wird der Modus geändert und das nächste Zwischenziel berechnet. Bevor man startet muss allerdings die Berechnung des ersten Zwischenziels manuell gestartet werden. Dazu dient der „Start und Reset"-Button.
Wenn die Wegfindung gestartet wurde, läuft sie nach folgendem Algorithmus:

 

1)Eintrittspunkt

 

Punkt P ist Position des Flugobjekts
Punkt M ist die Position des Hindernisses mit Radius R
Kreis um S (Mittelpunkt der Strecke [P,M]) mit Radius r=(|P,M|)/2
Schnittpunkte S1 und S2 ergeben die Tangentenpunkte
Entscheidung Tangentenpunkt (siehe 5))

 

2)Berechnung der äußeren Tangenten


- M1 ist das Hindernis, um das der Zeppelin gerade fliegt
- M2 ist das nächste Hindernis
- Punkt P ist der Schnittpunkt der beiden Tangenten:
P=M1-|M1,M2|*R/(r2+R) (Strahlensatz)
Mittelpunkt S von [P,M1] mit Radius r=(|P,M1|)/2
Schnittpunkte berechnen
Entscheidung Tangentenpunkt (siehe 5))

3)Berechnung der inneren Tangenten


- M1 ist das Hindernis, um das der Zeppelin gerade fliegt
- M2 ist das nächste Hindernis
- Punkt P ist der Schnittpunkt der beiden Tangenten:
P=M1+|M1,M2|*R/(r2+R) (Strahlensatz)
Mittelpunkt S der Strecke [P,M] mit Radius r=(|P,M|)/2
Schnittpunkte berechnen
Entscheidung Tangentenpunkt (siehe 5))

4)Austrittspunkt
Berechnung ist dieselbe wie bei 1), nur dass der Punkt P die Zielkoordinaten sind.

Wahl des richtigen Tangentenpunktes:
Im Anschluss daran muss noch der richtige Tangentenpunkt bestimmt werden. Beim Linksflug der rechts von der Strecke und bei Rechtsflug der links von der Geraden. Dazu werden die Winkel der Tangenten und der Verbindungsgeraden [P,M] berechnet. Wenn der Winkel der Tangente größer als der der Verbindungsgeraden ist, befindet sich der Tangentenpunkt rechts von der Geraden. Ansonsten links.

Quellcode: weg.cpp

 

Simulation


Da das IPS vor der Zwischenpräsentation noch nicht funktionsfähig war, haben wir eine Simulation implementiert, die den Flug des Zeppelins nachstellt. Da wir aber nur testen wollten, ob die geschriebenen Programme (Wegfindung, Regelung) funktionieren, ist die Simulation sehr ideal. Das heißt, dass wir keine Störstellen eingebaut haben.

Folglich ist sie sehr einfach strukturiert. Von der Regelung werden die Schubdaten an die Simulation weitergegeben, daraus wird die zurückgelegte Strecke errechnet und die neue Position und Ausrichtung des Flugobjekts bestimmt.

Quellcode: simulation.cpp

Schnittstelle Xbee

Zur Kommunikation mit dem Zeppelin dient ein Xbee. Das KommunikationsProtokoll ist wie folgend:

Pc zu Zeppelin:

Das Protokoll besteht aus einer unsigned long, die erste Ziffer ist die Aktionsziffer, hier können individuelle Aktionen am Arduino ausgelöst werden, im jetzigen Fall ist der Abwurf auf die 2 gelegt. Wichtig ist, dass der Grundwert 1 ist um die Länge der Zahl immer konstant zu halten (niemals 0)

Zeppelin zu PC:

Eine 6 stellige Zahl, die ersten drei Stellen beinhalten die Höhe (Ultraschallsensor) in cm + 100 (Offset), die letzten 3 den Ausrichtungswinkel von -180 bis 180 Grad +500(Offset).

Quellcode: mainwindow.cpp

Installation und Kompilieren der Software

Das Programm ist in C++ mit der Qt IDE geschrieben. Da man mit der nicht kommerziellen Version keine kompletten Programme als .exe abspeichern kann, ist der einfachste Weg Qt zu installieren (im Daedalus Raum schon vorhanden) und die aktuelle Code-Version herunterzuladen:

Lade die aktuelle Version von Qt herunter (4.8 aufwärts), dabei ist eine Version mit integrierten Kompiler (MinGW) die einfachste Installation, natürlich kann man auch den Visual Studio kompiler verwenden (trotzdem Qt installieren): 

www.qt-project.com -> Downloads -> Version mit MinGW (bervorzugt)

Nun muss man den Quellcode herunterladen und extrahieren:

https://github.com/Koerner/Sturzflug-at-daedalus.ei.tum.de.git -> Download Zip (rechte Spalte)

In den Dateein findet sich eine .pro Datei, die man mit dem Qt Creator öffnet. Falls Project Einstellungen erscheinen, mit Ok bestätigen.

Zum kompilieren des Programms auf den grünen Pfeil klicken, nun startet das Programm.

per Hand kompilieren

natürlich kann man das Programm auch mit einer anderen IDE/Kompiler kompilieren. Auch wenn diese Methode wesentlich umständlicher ist:

Es muss nur die Gt-Core.lib integriert werden (Qextserial.lib ist bereits im Quellcode vorhanden). Sonst entsprechend der Anleitung der IDE kompilieren.

Arduino Simulation

Ebenfalls ist die IPS-Simulation im Ordner Arduino enthalten. Diese lässt sich mit der Arduino Software kompilieren und hochladen. Der Arduino Ordner ist hier auf dem GitHub zu finden: https://github.com/Koerner/Sturzflug-at-daedalus.ei.tum.de/tree/master/Arduino

Anhänge:
Diese Datei herunterladen (Struktogramm.gif)Struktogramm.gif[ ]%2013-%07-%19 %1:%Jul%+02:00
Diese Datei herunterladen (Struktogramm.pptx)Struktogramm.pptx[ ]%2013-%07-%19 %1:%Jul%+02:00