Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

14.07.2018, 14:21

Steuerung einer RoRo-Fähre

Guten Tag liebe Community!
Vielleicht gibt es hier jemanden der mir bei einen kleinen Problem weiterhelfen kann.
Ich versuche derzeit eine einfache Steuerung für eine RoRo-Fähre, wie sie auch zwischen Puttgarden - Rodby verkehrt, zu implementieren.
Kurze beschreibung zur Technik:
- Das Fährschiff besitzt 4 POD-Antriebe die sich umabhängig voneinander steuern lassen.
- Jeder POD-Anrieb besteht aus einer Gondel die sich um 360 Grad frei drehen lässt, die Gondel dient als Ruder.
- An jeder Gondel befinden sich die Schiffschrauben.

Wenn weitere Information benötigt werden bitte ich dieses hier zuhinterfragen, da ich hier jetzt nicht extra einen halben Roman schreiben möchte der am Ende nur zur verwirrung führt.
Ich möchte wenn es möglich ist das einbinden einer Physikengine wie z.b. Bullet oder ODE vermeiden.
Worum es mir hier eigntlich geht ist das Verschieben und Ausrichten der Fähre anhand der Oben genannten POD-Anriebe.
Es gibt verschiedene Fahrstellungen wie die Antriebe zusammen Arbeiten.
Mir geht es vorallem darum wie sich das Schiff bewegt, wenn ich die einzelene Gondeln um einen Wert X drehe und die Schiffschrauben der entsprechenen POD-Antriebe mit ein Schub von einem Wert Y betreibe.

Derzeit bekomme ich von den jeweiligen Antrieben folgende Werte zurück:
- Richtungsvektor ( Wertebereich -1 bis 1 )
- Geschwindigkeits bzw Schubwert im bereich 0 - 1
- Derzeitigen Drehwinkel in Grad

Dazu ein Bild vom Rumpf mit den POD-Antrieben:



Wenn ich nun alle 4 Antriebe gleichzeitig und synchron laufen lasse ist das berechnen der Bewegung nicht besonders schwer.
Wie kann ich anhand der Oben genanten POD-Antriebswerte die Ausrichtung und Verschiebung vom Schiff berechnen?
Ich habe versucht die Werte aller Antriebe zu Addieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
//...
for (int x = 0; x < 4; x++)
{
    eigenverschiebung.X += ((sin(degToRad(NormalizeAngle(this->mShipHeading + _podThrusterRotation[x]))) * (timeMs * this->mShipVelocity)) * _podThrusterSpeed[x]);
    eigenverschiebung.Z += ((cos(degToRad(NormalizeAngle(this->mShipHeading + _podThrusterRotation[x]))) * (timeMs * this->mShipVelocity)) * _podThrusterSpeed[x]);
}
//...


Den Rotationswinkel vom Schiff berechne ich aus der derzeitigen Position und der Eigenverschiebung.
Damit die Drehung vom Schiff langsam abläuft verwende ich für die Drehbewegung folgende Technik:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
if (_targetAngle != this->mShipHeading)
{
    if (this->mShipHeading < _targetAngle)
    {
        this->mShipHeading += (_rotationSpeed * max_<float>(this->mShipVelocity, 0.01f));
        this->mShipHeading = min_<float>(this->mShipHeading, _targetAngle);
    }
    else if (this->mShipHeading > _targetAngle)
    {
        this->mShipHeading -= (_rotationSpeed * max_<float>(this->mShipVelocity, 0.01f));
        this->mShipHeading = max_<float>(this->mShipHeading, _targetAngle);
    }
}


Wenn ich jetzt z.b. die beiden linken POD-Antriebe auf 90 Grad Stelle ( Ausrichtung lokale X Achse ) diese 20% Schub bekommen und die beiden rechten bleiben auf 0 Grad ausgerichtet bekommen aber keinen Schub.
So müsste sich ja normal das Schiff zu Seite bewegen was es auch tu aber hier darf keine Drehung stattfinden, wie kann ich das unterbinden das sich das Schiff dreht?

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

15.07.2018, 06:51

Wenn ich das richtig sehe, geht die relative Position der Pods am Schiff garnicht in die Rechnungen mit ein, oder?

Ich würde nach meinen Kenntnisstand aus klassischer Mechanik darauf tippen, dass man kaum darum kommt Drehmomente und Translationskräfte entsprechend zu berücksichtigen. Entsprechende Grundlagen dazu sollten sich im Inet genug finden lassen. Allerdings steckt der Teufel im Detail (gerade bei numerischen Problemen-nicht ohne Grund sind selbst nach Jahren der Entwicklung die Ergebnisse von Physikengines bisweilen unbefriedigend).
Doch glaube ich lässt sich die grundlegende Mechanik für diesen Fall vmtl schwerlich vereinfachen ohne entsprechende "fehlerhaftes Verhalten" einzubauen.

P.S. wie "realistisch" muss denn das Ergebnis sein?
P.P.S. Richtungsvektor und Drehwinkel in Grad erscheinen mir redundant, oder was genau ist mit dem Richtungsvektor gemeint? Drei (bzw. zwei) Werte die die Schubrichtung angeben?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

3

15.07.2018, 11:11

Hallo Nox,
danke für deine schnelle Antwort.

Zitat

Wenn ich das richtig sehe, geht die relative Position der Pods am Schiff garnicht in die Rechnungen mit ein, oder?

Dieses ist nur ein Teil der Rechnung aber im nachfolgenden poste ich mal den Teil wo es darum geht die Werte der Antriebe mit einzubinden.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// numOfPods = 4
vector3df _forward = ((_podInfo[0].mForward + _podInfo[1].mForward + _podInfo[2].mForward + _podInfo[3].mForward) / (float)numOfPods);
float _angle = 90.f;

float _a0 = ((_podInfo[0].mDir.X * _angle) * ((_podInfo[0].mCP.Z < 0.f) ? -1.f : 1.f) * _podInfo[0].mPodThrusterSpeed);
float _a1 = ((_podInfo[2].mDir.X * _angle) * ((_podInfo[2].mCP.Z < 0.f) ? -1.f : 1.f) * _podInfo[2].mPodThrusterSpeed);
float _a2 = ((_podInfo[1].mDir.X * _angle) * ((_podInfo[1].mCP.Z < 0.f) ? -1.f : 1.f) * _podInfo[1].mPodThrusterSpeed);
float _a3 = ((_podInfo[3].mDir.X * _angle) * ((_podInfo[3].mCP.Z < 0.f) ? -1.f : 1.f) * _podInfo[3].mPodThrusterSpeed);
/// Dieser Teil berechnet den korrigier Winkel wenn nur auf Steuer- oder Backbord Schub vorhanden ist.
/// Dies führt dazu dass das Schiff mit der Zeit eine drehung macht.
float _ca0 = ((_podInfo[0].mDir.Y * _angle) * ((_podInfo[0].mCP.X < 0.f) ? -1.f : 1.f) * _podInfo[0].mPodThrusterSpeed);
float _ca1 = ((_podInfo[1].mDir.Y * _angle) * ((_podInfo[1].mCP.X < 0.f) ? -1.f : 1.f) * _podInfo[1].mPodThrusterSpeed);
float _ca2 = ((_podInfo[2].mDir.Y * _angle) * ((_podInfo[2].mCP.X < 0.f) ? -1.f : 1.f) * _podInfo[2].mPodThrusterSpeed);
float _ca3 = ((_podInfo[3].mDir.Y * _angle) * ((_podInfo[3].mCP.X < 0.f) ? -1.f : 1.f) * _podInfo[3].mPodThrusterSpeed);
float _ca =  ((_ca0 + _ca1) + (_ca2 + _ca3)) * _forward.Z;

float _targetAngle = (((_a0 + _a1) + (_a2 + _a3)) + _ca);


Zitat

Ich würde nach meinen Kenntnisstand aus klassischer Mechanik darauf tippen, dass man kaum darum kommt Drehmomente und Translationskräfte entsprechend zu berücksichtigen.

Das ist auch so ein Problem welches mich beschäftigt, denn kein Schiff bewegt sich direkt mit wenn man Schub gibt.
Und auch wenn die POD-Antriebe gedreht werden dreht sich das Schiff auch nicht sofort mit und vorallem so schnell wie man die Gondeln drehen würde.
Ich habe jetzt schon mehrere ansätze versucht um es überhaupt Stückweise anzugehen.
Hierbei habe ich erstmal versucht die Linearbewegung hinzubekommen.
Danach habe ich versucht die Drehbewehgung mit einfließen zulassen wie sich der Schiffskörper drehen würde.

Zitat

P.S. wie "realistisch" muss denn das Ergebnis sein?

Hier soll kein einfluss von Wasserwiderstand, Luft oder andere Umwelteinflüsse berücksichtigt werden.
Nur das reine Verhalten anhand der Aurichtung.

Zitat

P.P.S. Richtungsvektor und Drehwinkel in Grad erscheinen mir redundant, oder was genau ist mit dem Richtungsvektor gemeint?

Der Richtungsvektor ist beschreibt die Ausrichtung der POD-Antriebe im lokalen Raum, also wenn X -1 oder 1 ist dann kann Y nur den Wert Null haben und andersherum ebenso.
Der Richtungsvektor ist ein 2d-Vektor und beinhaltet den Sinus und Cosinuswert vom derzeitigen Drehwinkel der Gondel.
Dieser Vektor soll dazu da sein um die Schubrichtung zubekommen.
Und der Drehwinkel in Grad der fließt in dieser Rechnung nicht mehr mit ein da man den Drehwinkel auch über den Richtungsvektor bestimmen kann, da es sich bei Richtungsvektor um Sinus und Cosinuswerte handelt.
Nur bei der Berechnung der Eigenverschiebung wie im ersten post fließt der Drehwinkel noch mit ein "_podThrusterRotation[x]"

Der Schubwert selbst ist eindimensional also nur ein floatwert im Bereich 0 - 1.

Es denke mal das dieser Typ Antrieb doch besser über eine Physikengine zulösen ist.
Ich würde mich halt auch über einen anderen Weg freuen, da ich keine wirkliche Physik benötige.

LG
Garfield

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Garfield83« (15.07.2018, 11:26)


Werbeanzeige