Raumschiff: Bremswegbestimmung (mit "Reibung")

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Benutzeravatar
donelik
Beiträge: 56
Registriert: 28.11.2006, 17:49
Benutzertext: Will releasen!
Kontaktdaten:

Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von donelik »

Hallo Freunde,

ich habe ein Problem. Ich versuche 2 Modi für die Steuerung meines Raumschiffes (2D) zu implementieren:

- manuell (Schub geben, Steuerdüsen ansteueren)
- automatisch (Mausklick -> fliege zu)

Ein Schiff hat bei mir folgende Attribute:
- Friction = Reibung (aus Gameplay-Gründen ;) )
- MaxSpeed = maximale Geschwindigkeit

In jeder Frame passiert jetzt (unter anderen) Folgendes:

Code: Alles auswählen

this->m_vVelocity; // aktuelle Geschwindigkeit
this->m_rFriction; // Reibung
this->m_rThrottle; // Schub ... von -0.5f bis 1.0f (=Vollschub)
deltaTime; // (float) Wie viel Zeit ist seit der letzten Frame vergangen?

this->m_vVelocity.z += this->m_rThrottle * this->m_rMaxAccel * deltaTime;

Vector3 vMove = this->m_vVelocity * deltaTime;	// wie muss ich das Schiff in dieser Frame bewegen?

this->entity().getParentSceneNode()->translate(vMove, LOCAL);

if(this->m_rMovementFriction != 1.0f) this->m_vVelocity *= powf(this->m_rFriction, deltaTime);
Das heißt, das Raumschiff verliert stets an Geschwindigkeit (ist eine schöne Kurve die gen Null strebt).

Nun will ich für den Steuerungsmodus "automatisch" den Schub zurücknehmen (auf 0 setzen) sobald das Schiff soweit vom Zielpunkt entfernt ist, dass es direkt anhält (ich denke eine Genauigkeit von 0.0001 sollte reichen).

Wie gehe ich das an? Mir wurde was von Intergralen und Grenzwerten empfohlen, aber da bin ich nicht das hellste Licht am Sternenhimmel...

Die Rotation kann hier vernachlässigt werden, da ich vermute dass ich die hier gewonnenen Informationen problemlos auf die Rotation übertragen kann.

Vielen Dank schonmal
DonElik
Ach hör' auf ...
simbad
Establishment
Beiträge: 132
Registriert: 14.12.2011, 14:30

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von simbad »

Energieerhaltungssatz.

Dein Raumschiff hat Bewegungsenergie, Reibung wandelt kontinuierlich Bewegungsenergie in Wärmeenerige um. Im einfachsten Fall. Ist der Energiegehalt des Raumschiffs bei 0 steht es.

Keine Ahnung ob das stimmt. Aber das ist so mein erster Ansatz.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von Schrompf »

Die Geschwindigkeit wird ja nie 0, sie nähert sich nur 0 an. Meine begrenzten Mathefähigkeiten reichen jetzt nicht aus, um mit Sicherheit zu sagen, ob es eine Obergrenze für den zurückgelegten Weg gibt oder nicht.

Ansonsten: Der Weg ist ja das Integral über die Geschwindigkeit. Und die Geschwindigkeit hast Du ja mit der pow()-Formel korrekt berechnet. Mit "korrekt" meine ich: stetig und unabhängig von der Framerate, im Gegensatz zur Wegstrecke. Man müsste also eine Geschwindigkeit-Nach-Zeit-Formel finden können, die dann integrieren und schauen, ob die mit t gegen unendlich einen Grenzwert hat oder nicht. Die Geschwindigkeitsformel ist wahrscheinlich irgendwas von e^(t/tau), also müsste das Integral auch ein e^irgendwas sein. Und ob das konvergiert oder nicht... puh, mein Studium ist schon ne Weile her. Sorry, aber ich höre an dieser Stelle auf.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von Artificial Mind »

Schrompf hat geschrieben:Die Geschwindigkeit wird ja nie 0, sie nähert sich nur 0 an.
Da der Abfall allerdings exponentiell ist, gibt es eine obere Schranke ;)

Angenommen du fliegst mit Geschwindigkeit v und hast Reibung a, dann ist deine Geschwindigkeit zur Zeit t gleich v * a ^ t (wobei Reibung halt zwischen 0 und 1 ist und a = 0.99 bedeutet dass du 1% Geschwindigkeit pro Zeit verlierst)
Die Strecke ist das Integral über die Geschwindigkeit, also Integral von 0 bis unendlich über t von v * a ^ t und voila ( Foren-url funktioniert anscheinend nicht, hier der Wolfram-Link: http://www.wolframalpha.com/input/?i=in ... finity}%5D ) wir bekommen als Ergebnis, dass dein Raumschiff genau einen Weg von - v / log a zurücklegen wird! (log = logarithmus naturalis in diesem Fall, also zur Basis e)
Nicht wundern dass das Ergebnis vermeintlich negativ ist, da a < 1 (bzw < e) ist log a < 0 und somit das Ergebnis positiv.

Rechenbeispiel: du fliegst 100 und hast eine Reibung von 0.9, dann hält das Raumschiff nach ca 949,122 Einheiten.

Cheers,
Mind

PS: falls ich falsch liege, korrigiert mich :D
PSS: Ja, dein Raumschifft kommt nach unendlich langer Zeit erst dort an, allerdings kommt es relativ schnell relativ dicht dran bevor es ganz langsam wird^^
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von eXile »

Konvergieren wird es auf jeden Fall als geometrische Reihe. Es gibt aber ein ganz anderes Problem: Du benutzt einen Euler-Integrator, um die eigentlich zugrunde liegende Differentialgleichung zu lösen (in deinem Fall x'(t) = rho * v(t), v'(t) = Throttle*MaxAccel * a(t)). D.h. selbst wenn wir hier mit Energieerhaltungssatz oder einer simplem Integralgleichung rumhantieren, wird dieses Ergebnis wohl nicht verwendbar sein, weil dein Euler-Integrator nicht die gleiche Position wie bei einer analytischen Lösung berechnen wird.

Ich würde daher das ganze Problem anders angehen: Als Feder. Und zwar einer relativ schwachen Feder (d.h. das ist gutmütig zu deinem Euler-Integrator); die aktuelle Geschwindigkeit und Beschleunigung kriegst du dann via numerischer Differentiation raus (z.B. einfach aus den letzten zwei oder drei Werte nehmen, und daraus die ungefähre Steigung bestimmen).
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von Artificial Mind »

eXile hat geschrieben:Konvergieren wird es auf jeden Fall als geometrische Reihe. Es gibt aber ein ganz anderes Problem: Du benutzt einen Euler-Integrator, um die eigentlich zugrunde liegende Differentialgleichung zu lösen (in deinem Fall x'(t) = rho * v(t), v'(t) = Throttle*MaxAccel * a(t)). D.h. selbst wenn wir hier mit Energieerhaltungssatz oder einer simplem Integralgleichung rumhantieren, wird dieses Ergebnis wohl nicht verwendbar sein, weil dein Euler-Integrator nicht die gleiche Position wie bei einer analytischen Lösung berechnen wird.
Ich glaube er meint, dass er a(t) auf 0 setzen will, wenn er die richtige Distanz zum Ziel erreicht hat. Und dann sollte meine analytische Lösung greifen.
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von eXile »

Artificial Mind hat geschrieben:Ich glaube er meint, dass er a(t) auf 0 setzen will, wenn er die richtige Distanz zum Ziel erreicht hat. Und dann sollte meine analytische Lösung greifen.
Eine analytische Lösung greift schon deshalb nicht immer bei einem iterativen DGL-Löser, weil der nächste Frame einfach eine Minute zum Rechnen brauchen könnte, und wir dann irgendwo beim Neptun landen.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von Artificial Mind »

eXile hat geschrieben:
Artificial Mind hat geschrieben:Ich glaube er meint, dass er a(t) auf 0 setzen will, wenn er die richtige Distanz zum Ziel erreicht hat. Und dann sollte meine analytische Lösung greifen.
Eine analytische Lösung greift schon deshalb nicht immer bei einem iterativen DGL-Löser, weil der nächste Frame einfach eine Minute zum Rechnen brauchen könnte, und wir dann irgendwo beim Neptun landen.
Ich weiß nicht wie du darauf kommst das wir eine DGL haben. Wenn ich donelik richtig verstanden habe will er wissen ab wann er den Schub auf 0 setzen kann (also unser a(t) = 0 ist) um mit der restlichen Geschwindigkeit und der Reibung genau zum Ziel zu kommen.

Ergo haben wir v(t) = v_0 * r ^ t, v_0 = Anfangsgeschwindigkeit, r = Reibungskoeffizient, t = Zeit
und damit ist s(t) = int( v(t'), t' = 0..t )
Nix DGL.

Die Geschwindigkeit ist quasi die Restgeschwindigkeit vermindert um den Reibungseinfluss und der Reibungseinfluss hängt nur von der Geschwindigkeit ab.

EDIT: da er natürlich die s(t) nur durch die Timesteps approximiert kommt natürlich ein Fehler rein, aber da er ja (hoffentlich) eine fixed-Timestep-Simulation hat mit Timesteps <= 20 ms und Geschwindigkeitsverhältnissen die einem normalen Spielbetrieb nahekommen, sollte dieser nicht so stark ins Gewicht fallen.
dronus
Establishment
Beiträge: 114
Registriert: 11.01.2010, 01:53

Re: Raumschiff: Bremswegbestimmung (mit "Reibung")

Beitrag von dronus »

Wenn die Friction wie üblich exponentiell wirkt (als Lösung einer realistischen Gleichung) ist der Bremsweg unendlich lang, wenn man nicht eine Haftreibung dazu nimmt mit der es plötzlich kleben bleibt. Ich würde die Reibung dann vielleicht linear gestalten, das müsste man mal testen ob das so 'verkehrt' aussieht wie es ist. Wenn nicht, dann ist der Bremsweg quadratisch (wie bei der Daumenregel mit dem Tacho :-) ) und der Zeitpunkt mit Wurzelziehen auszurechnen.
Antworten