[Aerodynamik] Berechnung von Flugzeugtrajektorien



  • Guten Tag,

    ich suche Formeln wie ich Trajektorien von Flugzeugen "einfach" berechnen kann. Im Zuge meiner Master-Thesis geht es um ein Projekt, in dem Flugzeuge simuliert werden. Da es nur eine prototypische Implementierung ist, kann von der Realität etwas abstrahiert werden, allerdings sollte sich natürlich auch nicht allzu weit von ihr entfernt werden.

    Ich habe schon mal etwas angefangen und mir ein paar Daten von [0] geholt.

    Dementsprechend beschleunige ich nun solange bis ich weiß, daß mein Auftrieb größer als die Gewichtskraft ist (lift > weight), das Flugzeug also abheben kann.

    double t = 1.0; // Zeitschritt
    double lift = 0; // Auftrieb
    int mass = 560000; // kg
    double weight = mass* 9.81; // N
    int thrust = 311000*4; // N, vier Triebwerke
    double a = (double) trust/mass; // m/s^2; F = m*a <=> a = F/m
    Vector3D aVec = Vector3D(1,0,0)*a; // Startbahn liegt in X-Richtung
    Vector3D v = Vector3D(0,0,0); // m/s; Geschwindigkeit
    Vector3D s = Vector3D(0,0,0); // Ort
    
    while (weight > lift)
    {
      v = v + aVec*t; // einfach Euler Integration
      s = s + sVec*t;
    
      cl = 1.15; // Auftriebsbeiwert, willkürlich konstant gesetzt
      double airDensity = 1.0; // kg/m^3
      int wingArea = 845; // m^2
      lift = cl * wingArea * 0.5 * airDensity * v * v;
    }
    

    Ist das soweit schon ok? Wie mache ich nun weiter?
    Ich möchte, daß mein Flugzeug ein paar Wegpunkte abfliegt (bzw. bis auf 100m an sie heran kommt, würde ja reichen), was vom Prinzip her ja einfach ist.

    Vector3D waypoint = ...;
    Vector3D dir = (wayPoint - s).normalize();
    Vector3D a = dir*this->getMaxAcceleration();
    this->euler(a); // macht wieder Euler-Integration und berechnet v und s
    

    Problem ist, daß es sich (einigermaßen) korrekt verhalten soll, also daß Steigwinkel und die Enge von Kurven der Realität entsprechen (u.U. muß das Flugzeug also etwas weiter "ausholen", um einen Wegpunkt zu erreichen).
    Später soll es dann auf eine vordefinierte Reisehöhe mit vorgegebener Reisegeschwindigkeit weitersteigt und in Richtung des Zieles fliegt.

    Weiß noch jemand Rat, wie ich das genau umsetze? Gibt es vielleicht schon Implementierungen, die sowas können?

    Gruß
    Hackbard_C

    [0] http://www.airbus.com/en/aircraftfamilies/a380/a380/specifications.html



  • ich würd ja alle (im wesentlichen) vier kräfte simulieren. Auftrieb, Gewichtskraft, Reibungskraft und Schubkraft. Ausserdem hängt der Lift vom Anstellwinkel der Tragfläche ab, sonst könnte ein flugzeug ja garnich verschiedene gschwindigkeiten haben und trotzdem die gleiche höhe halten.


  • Mod

    Für mich sieht das so aus, dass du deine Trajektorien derzeit nicht berechnest, sondern dass du quasi vorgibst, was bei deinen Rechnungen rauskommen soll. An deiner Stelle würde ich erstmal mit ein paar einfachen veränderlichen Werten für das Flugzeug anfangen: Ort, Geschwindigkeit
    Dazu noch ein paar vorgegebene Modellparameter für das Flugzeug: Masse, Schub (zeitabhängig! Hier steckt drin, was der Pilot macht.), Reibungskoeffizient
    Und ein paar Modellparameter für die Umgebung: Luftdichte (höhenabhängig) und je nachdem wie genau es werden soll noch weitere.

    Damit kannst du dann ganz gut genähert die Kräfte, die auf das Flugzeug wirken ausrechnen und daraus durch Euler oder eine andere Integration die Veränderung von Ort und Geschwindigkeit berechnen. Und dabei nicht so Kram wie "while (weight > lift)" benutzen - das korrekte Verhalten ergibt sich dann nämlich von ganz alleine, ohne dass du vorgibst, was du glaubst, was rauskommen sollte.

    Mit diesem einfachen Modell bekommst du sicherlich schonmal Start, Landung und Geradeausflug recht gut hinbekommen.

    Kurven dürften damit aber eher schlecht als Recht gehen, deshalb sollte (wenn obiges gemacht wurde) unbedingt auch die Neigung des Flugzeugs (Stichwort: Eulerwinkel) noch beachtet werden. In einem einfachen Modell könnte man bestimmt annehmen, dass der Auftrieb einfach immer senkrecht zu den Flügeln steht), wodurch die Berechnung nicht wesentlich komplizierter sein dürfte. Es fehlt aber noch etwas, dass die Neigung überhaupt verändert. Ich würde mal annehmen, dass die Neigung maßgeblich vom Piloten beeinflusst wird und keine große Rückkopplung der anderen Modellparameter auf die Neigung stattfindet. Die Neigung wäre demnach wie der Schub ein vorgegebener Modellparameter.

    Also nochmal kurz zusammengefasst mein Modellvorschlag:
    Variablen:
    -Ort (Vektor)
    -Geschwindigkeit (Vektor)

    vorgegebene Modellparameter:
    -Luftdichte(Skalar, als Funktion der Höhe)
    -Masse (Skalar), Schub(Skalar, als Funktion der Zeit)
    -Neigung(3 Winkel, als Funktion der Zeit)
    -Reibungsfaktor (Skalar)

    Kräfte:
    -Schubkraft(nach vorne, abhängig von Neigung und Schub, evtl. auch Luftdichte)
    -Gravitation(Richtung Boden, abhängig von Masse)
    -Reibung(Gegenrichtung der Geschwindigkeit, abhängig von Geschwindigkeit, reibungsfaktor, Luftdichte)
    -Auftrieb(nach oben vom Flugzeug aus gesehen, abhängig von Geschwindigkeit, Luftdichte und Neigung)
    -Noch irgendwas, das verhindert, dass das Flugzeug durch den Boden fällt, wenn es zu langsam und zu tief ist (Start, Landung)

    Bewegungsgleichung: Einfach die Newtonschen mit obigen Kräften. Diese Integrieren mit deinem Lieblingsalgorithmus

    Kann man natürlich noch beliebig verkomplizieren (der Pilot z.B. kann bestimmt einstellen, wieviel Auftrieb die Flügel bei welcher Geschwindgkeit haben sollen) aber dürfte schon ganz gut gehen.



  • SeppJ schrieb:

    Für mich sieht das so aus, dass du deine Trajektorien derzeit nicht berechnest, sondern dass du quasi vorgibst, was bei deinen Rechnungen rauskommen soll.

    Jein, also was das Flugzeug bekommt ist die Daten wie z.B. von der Airbusseite (also Schub, Flügelfläche, Masse, ..., ggf. mehr wenn noch was fehlt), dazu kommt die Position des Flughafens für Start und die für die Landung (sowie einen Richtungsvektor für die Ausrichtung der Start- bzw. Landebahn). Ebenso gibt es (Lärmschutz^^) für jeden Flughafen Waypoints für An- und Abflug an die sich gehalten werden muß.

    Gedacht ist als Folgendes: Das Flugzeug bekommt die Starterlaubnis des Flughafens, es startet automatisch und fliegt die Abflug-Waypoints ab, danach steigt es automatisch auf Reiseflughöhe (genauso vorher festzulegen wie die Reisegeschwindigkeit) und fliegt (selbstständig) in Richtung des Ziel.
    Nähert es sich dem Flughafen auf 10 Kilometern (oder wieviel auch immer) beginnt es selbstständig mit dem Landeanflug über die Anflug-Waypoints und schließlich auf den Flughafen (sofern es die Landeerlaubnis erhält, alternativ muß es noch eine Warteschleife fliegen).

    Die Trajektorie wird also nicht komplett vorgegeben, sondern nur Anfang und Ende.

    Hackbard_C


  • Mod

    Hackbard_C schrieb:

    SeppJ schrieb:

    Für mich sieht das so aus, dass du deine Trajektorien derzeit nicht berechnest, sondern dass du quasi vorgibst, was bei deinen Rechnungen rauskommen soll.

    Jein, also was das Flugzeug bekommt ist die Daten wie z.B. von der Airbusseite (also Schub, Flügelfläche, Masse, ..., ggf. mehr wenn noch was fehlt), dazu kommt die Position des Flughafens für Start und die für die Landung (sowie einen Richtungsvektor für die Ausrichtung der Start- bzw. Landebahn). Ebenso gibt es (Lärmschutz^^) für jeden Flughafen Waypoints für An- und Abflug an die sich gehalten werden muß.

    Gedacht ist als Folgendes: Das Flugzeug bekommt die Starterlaubnis des Flughafens, es startet automatisch und fliegt die Abflug-Waypoints ab, danach steigt es automatisch auf Reiseflughöhe (genauso vorher festzulegen wie die Reisegeschwindigkeit) und fliegt (selbstständig) in Richtung des Ziel.
    Nähert es sich dem Flughafen auf 10 Kilometern (oder wieviel auch immer) beginnt es selbstständig mit dem Landeanflug über die Anflug-Waypoints und schließlich auf den Flughafen (sofern es die Landeerlaubnis erhält, alternativ muß es noch eine Warteschleife fliegen).

    Die Trajektorie wird also nicht komplett vorgegeben, sondern nur Anfang und Ende.

    Hackbard_C

    Das meinte ich gar nicht. Das was du hier beschreibst ist vollkommen in Ordnung.

    Was ich meinte ist der Code den du in deinem ersten Beitrag zeigst. Besonders dieser Abschnitt:

    while (weight > lift)
    {
      v = v + aVec*t; // einfach Euler Integration
      s = s + sVec*t;
    
      cl = 1.15; // Auftriebsbeiwert, willkürlich konstant gesetzt
      double airDensity = 1.0; // kg/m^3
      int wingArea = 845; // m^2
      lift = cl * wingArea * 0.5 * airDensity * v * v;
    }
    

    Hier soll anscheinend die Startphase simuliert werden und du hast recht genaue Vorstellungen wie diese auszusehen hat und wie lange sie dauert. Und nach deiner Frage dazu vermute ich, dass du wahrscheinlich nochmal extra Code für die Aufstiegsphase und dann für Geradeausflug, Absinken und Ausrollen anfügen willst. Du müsstest jeweils deine Vorstellungen einbringen, wie diese Phasen aussehen, wüsstest aber nicht, ob dies auch tatsächlich richtig ist. Beim Start wie du ihn zeigst, geht das noch einigermaßen gut, da es offensichtlich scheint, dass das Flugzeug einfach geradeaus über die Startbahn fährt, immer schneller wird und irgendwann abhebt. Und genau dass macht dein Programm auch. Aber du kannst nicht sicher sein,

    1. ob das so richtig ist
    2. wie das danach weitergeht (darum fragst du ja)
      Die Lösung für dieses Problem ist, dass du den Flug auf grundlegende Gesetze zurückführst aus denen sich dann die Trajektorien ergeben. Wenn du diese Gesetzmäßigkeiten begründen kannst, dann hast du hinterher auch die richtigen Trajektorien und du musst nicht einmal jede Phase einzeln simulieren, sondern der gesamte Flug ergibt sich in einer Programmschleife.

    P.S.: Das hat jetzt nichts mit deinem Problem zu tun, aber ein allgemeiner Hinweis zum Programmierstil: Überlege dir besser, welche Variablen du wo brauchst und wie der Programmfluss aussieht und welche Rechnungen nötig sind. Um obiges Bespiel nochmal aufzugreifen, kann man das wesentlich besser so schreiben:

    /* Das folgende sind Konstanten, es besteht kein Grund, diesen bei jedem Schleifendurchlauf erneut einen Wert zuzuweisen. 
    Einmal außerhalb der Schleife definieren reicht */
      cl = 1.15; // Auftriebsbeiwert, willkürlich konstant gesetzt
      double airDensity = 1.0; // kg/m^3
      int wingArea = 845; // m^2
    
    double vergleichswert=sqrt(weight / (cl * wingArea * 0.5 * airDensity)); // siehe unten
    while (vergleichswert > v)  // Siehe unten
    {
      v = v + aVec*t; // einfach Euler Integration
      s = s + sVec*t; // sVec kommt vorher nirgends vor. Wohl eher v?
    
      // Folgendes ist eine lange Rechnung, die größtenteils immer gleich ist
      // also raus damit aus der Schleife, siehe oben
      /* lift = cl * wingArea * 0.5 * airDensity * v * v;*/
    }
    


  • SeppJ schrieb:

    Hier soll anscheinend die Startphase simuliert werden und du hast recht genaue Vorstellungen wie diese auszusehen hat und wie lange sie dauert. Und nach deiner Frage dazu vermute ich, dass du wahrscheinlich nochmal extra Code für die Aufstiegsphase und dann für Geradeausflug, Absinken und Ausrollen anfügen willst. Du müsstest jeweils deine Vorstellungen einbringen, wie diese Phasen aussehen, wüsstest aber nicht, ob dies auch tatsächlich richtig ist. Beim Start wie du ihn zeigst, geht das noch einigermaßen gut, da es offensichtlich scheint, dass das Flugzeug einfach geradeaus über die Startbahn fährt, immer schneller wird und irgendwann abhebt. Und genau dass macht dein Programm auch. Aber du kannst nicht sicher sein,

    1. ob das so richtig ist
    2. wie das danach weitergeht (darum fragst du ja)
      Die Lösung für dieses Problem ist, dass du den Flug auf grundlegende Gesetze zurückführst aus denen sich dann die Trajektorien ergeben. Wenn du diese Gesetzmäßigkeiten begründen kannst, dann hast du hinterher auch die richtigen Trajektorien und du musst nicht einmal jede Phase einzeln simulieren, sondern der gesamte Flug ergibt sich in einer Programmschleife.

    Ok, das sehe ich ein und ist natürlich optimal, da das Flugzeug "wirklich" fliegt. Mein Gedanke war ja auch das alles auf den Gesetzmäßigkeiten basieren zu lassen. Wenn ich jetzt deine Idee von oben aufgreife und den Schub als Funktion über die Zeit definieren lassen. Dann gebe ich ja damit (indirekt) den Flugverlauf schon komplett vor, korrekt?
    Leider ist das bei mir nicht möglich, da ich noch Einflüsse habe, die auf mein Flugzeug wirken, so kann es durch Wind kommen, daß das Flugzeug etwas "abdriftet". Der Pilot muß also je nach Windlage einen etwas anderen Kurs fliegen (davon ausgehen, daß er eine konstante Reisegeschwindigkeit besitzt, die er beibehalten will). Das kann ich mit Schub(t) nicht umsetzen.

    Was ich mir gedacht hatte, daß ich quasi eine Funktion baue, die als Parameter Richtungsvektor zum nächsten Wegpunkt bekommt (wie im Eingangspost erwähnt müssen Wegpunkte natürlich nicht 100%ig getroffen werden, sondern in einem Radius von z.B. 100m). Diese Funktion wendet dann den Euler an und verändert Geschwindigkeit und Position in Abhängigkeits dieses Richtungsvektors.
    Vielleicht ist der Winkel zwischen aktueller Geschwindigkeitsrichtung und des Richtungsvektors zu groß, sodaß das Flugzeug diese Kursänderung auf einmal nicht schaffen würde, dann tut die Funktion halt ihr Bestes und schaut was mit den aktuellen Modellparametern möglich ist.

    Vielleicht sowas irgendwie...

    // Folgende Variablen sind Variablen der Klasse, können also via this erreicht werden
    // double t Zeitschritt
    // Vector3D pos Position
    // Vector3D v Geschwindigkeit
    void fly(Vector3D dir)
    {
      if (pos.angleBetween(dir) > getMaxAngle())
      {
        // Bestimmte Winkel der in der "zwischen" pos und dir liegt
        // und dabei die Winkel-Bedingung nicht verletzt
        dir = ...;
      }
    
      // bestimmte die Beschleunigung so, daß das Flugzeug nicht "herunter fällt"
      // sondern wirklich fliegen kann (Auftrieb >= Gewicht)
      // berücksichtige dabei, einen Status, der sagt, daß noch weiterbeschleunigt  (z.B. für den Start), 
      // auf eine bestimmte Geschwindigkeit beschleunigt oder die Geschwindigkeit konstant bleiben sollen
      Vector3D a = dir*getMaxAcceleration()*...;
      // an dieser Stelle wird, wenn vorhanden, einfach nochmal die Windgeschwindigkeit addiert.
      v = v + a*t; 
      pos = pos + v*t;
    }
    

    ...bin mir aber nicht sicher, ob ich da vielleicht noch von der Geschwindigkeit immer den Widerstand abziehen sollte oder so und vor allem nicht, wie ich a vernünfigt bestimme.

    SeppJ schrieb:

    P.S.: Das hat jetzt nichts mit deinem Problem zu tun, aber ein allgemeiner Hinweis zum Programmierstil: Überlege dir besser, welche Variablen du wo brauchst und wie der Programmfluss aussieht und welche Rechnungen nötig sind.

    Danke, aber das habe ich nur für das Beispiel so geschrieben. Den Kram habe ich in die While-Schleife getan, damit man besser sieht was zusammengehört. (Ich studiere Informatik, programmieren ist kein Thema für mich *g* Auch wenn solches Auslagern im Sinne der Lauftzeit (Groß-O-Notation) nichts bringt, so bin ich doch auch immer ein Fan von sowas und den Lift so teilweise über die Wurzel auszulagern hatte ich wirklich noch nicht dran gedacht. Danke!)



  • Hackbard_C schrieb:

    Mein Gedanke war ja auch das alles auf den Gesetzmäßigkeiten basieren zu lassen. Wenn ich jetzt deine Idee von oben aufgreife und den Schub als Funktion über die Zeit definieren lassen. Dann gebe ich ja damit (indirekt) den Flugverlauf schon komplett vor, korrekt?
    Leider ist das bei mir nicht möglich, da ich noch Einflüsse habe, die auf mein Flugzeug wirken, so kann es durch Wind kommen, daß das Flugzeug etwas "abdriftet". Der Pilot muß also je nach Windlage einen etwas anderen Kurs fliegen (davon ausgehen, daß er eine konstante Reisegeschwindigkeit besitzt, die er beibehalten will). Das kann ich mit Schub(t) nicht umsetzen.

    Naja, prinzipiell schon. Du hast eben einen Trajektorienplaner, der dir einen optimalen Verlauf für Schub(t) erzeugt (optimal in dem Sinne, das er alle Punkte möglichst schnell abfliegt). Wenn Du keinen Wind hättest, dann wäre das doch deine komplette Lösung. Gut, jetzt sagen wir mal, Du bist schon deltaT geflogen und stellst jetzt eine Abweichung zur Optimaltrajektorie fest. Wenn Du deine aktuelle Position genau genug bestimmen kannst und genug Rechenpower an Bord hast, dann kannst Du von diesem Punkt die Trajektorienplanung einen neuen Verlauf von Schub(t) berechnen lassen und den dann an das Flugzeug weitergeben. Wenn Du nicht genug Rechenpower an Bord hast, dann kannst Du dem Flugzeug einfach noch einen weiteren simplen Regler geben, der versucht, die original erzeugte Solltrajektorie (also die Trajektorie, die das Flugzeug ohne Störung zurückgelegt hätte) exakt zu tracken. Da das Gebiet (Luft) nicht besonders kompliziert ist, sollte das halbwergs funktionieren.

    (Ich denke, ich der Realität kann man die Windstöreinflüsse auf Flugzeuge recht gut messen [weil Drehsensoren billig sind] und kompensieren, da muß der Pilot nicht mehr viel machen.)

    Zum Festlegen der Schubtrajektorie brauchst Du halt eine Recheneinheit, die dir ein Variationsproblem löst und Du mußt eine Kostenfunktion aufstellen, die minimiert werden soll ("möglichst nah an die Punkte ran, aber auch möglichst schnell zum Endpunkt" o.ä.). Außerdem würde ich mich wirklich mal in der Literatur nach einem vernünftigen Flugzeugmodell umsehen, das gibt es bestimmt schon (also so was in die Richtung: http://assets.cambridge.org/97805218/09924/sample/9780521809924ws.pdf).

    Es sollten sich eigentlich auch im Internet oder am Regelungstechniklehrstuhl deiner Uni extrem viele Sachen zur Regelung von Flugzeugen finden lassen, da ist bestimmt auch was nütliches für dich dabei.


Anmelden zum Antworten