Vuforia Kamera Stabilisation in Unity

Einleitung

Dieser Artikel befasst sich mit der Smart Terrain Funktionalität von Vuforia. Ungenauigkeiten beim Tracken des Smart Terrains kann zu sehr starken Schwankungen in der Position und Rotation der Augmented Reality-Kamera führen. Das Resultat ist, dass die komplette Szene zu wackeln scheint. Solange Vuforia das eigentliche Target zum Tracken hat, sind die Schwankungen minimal, sobald jedoch das Smart Terrain alleinsteht, ist ein deutliches Wackeln zu erkennen.

Dieses Problem tritt schon beim Ausführen von Vuforia im Unity-Editor auf, wobei man eine befestigte Webcam als Kamera benutzt. Später, auf dem mobilen Endgerät, werden diese Schwankungen durch das einfache Halten des Gerätes in den Händen nochmal verschlimmert.

Manifestation des Problems in Unity

Wenn man Vuforias ARCamera in Unity beim Ausführen genauer betrachtet, sieht man deutlich die Schwankungen in Position und Rotation.

Es gilt also, diese Schwankungen abzuschwächen. Wir brauchen ein Skript, welches direkt auf der ARCamera ausgeführt wird. Hierfür benötigen wir zunächst den genauen Zeitpunkt, zu welchem diese Werte geschrieben werden. Vuforia bietet hierfür ein Callback Event, wenn alle vorhandenen Trackables in einem Frame verarbeitet wurden.

Die generelle Update-Methode eines Skriptes kann man nicht verwenden, da man sonst in eine Race Condition reinläuft. Das Verarbeiten der Trackables kann je nach Frame kürzer oder länger dauern und somit ist nicht garantiert, dass in der Update-Methode die Werte bereits geschrieben wurden. Eine mögliche Alternative ist jedoch die LateUpdate-Methode, welche einem auch den Aufwand sich ordentlich an dem Event zu registrieren und abzumelden spart.

Einfache Stabilisierung

Wir haben also die richtige Stelle gefunden, wo wir die Werte auslesen und verarbeiten können. Jetzt ist die Frage, wie diese verarbeitet werden sollen. Die einfachste Möglichkeit ist die vorherigen Werte zu speichern und dann über die Zeit zu den neuen Werten interpolieren. Einen einfachen Durchschnitt zwischen den zwei Punkten würde das Problem nur geringfügig verbessern, da die zwei Punkte immer stark unterschiedlich sind.

Mathematisch korrekt ist die Benutzung der Interpolation hier nicht, da die Näherung immer schwächer wird und man den Wert nie ganz erreicht. Jedoch ändert sich der neue Wert in unserem Fall mit jedem Frame und funktioniert deshalb auch ganz ok. Die Näherung kann man noch etwas verstärken, indem man die verstrichene Zeit mit einem Faktor multipliziert, wenn dieser Faktor zu hoch wird nähern wir uns natürlich wieder dem Ausgangszustand.

Man sieht, dass die Schwankungen im Ruhezustand verschwunden sind. Der Nebeneffekt ist, dass die ARCamera nur sehr langsam folgt, wenn man die Position der physischen Kamera ändert.

Man könnte diese sehr einfache Berechnung jetzt noch weiter ausbauen, um die Stabilisation zu verbessern. Anstatt einem einzelnen Wert könnte man mehrere nehmen und dann aus allen einen Durchschnitt zu berechnen. Weiterhin könnte man die Stärke der Interpolation anpassen, je nachdem wie groß die Differenz zwischen den Werten ist.

Erweiterte Stabilisierung

Das MixedRealityToolkit-Unity besitzt bereits eine Komponente, die genau solche Berechnungen vornimmt. Der GazeStabilizer wird dort benutzt, um die Blickrichtung des Nutzers zu stabilisieren, womit die Position des Cursors berechnet wird. Ein Problem dieser Komponenten ist noch, dass sie die Up-Axis der Kamera nicht beachtet. Auf einem mobilen Endgerät rotiert die Szene dadurch nicht mit der Ausrichtungen des Gerätes.

Dies ist sehr einfach zu beheben, indem man in der Berechnung der Rotation noch die Up-Axis der Kamera hinzufügt.

Abschluss

Ein letztes Problem mit dieser Stabilisierung ist noch, dass Objekte, die der Kamera folgen, nun dieselben Schwankungen anstelle der Kamera besitzen. In meinem Fall habe ich dieses Problem gelöst, indem ich die Stabilisierung deaktiviert habe, solange ein anderes Objekt im Fokus stehen soll und nicht das Smart Terrain.

Damit haben wir die Stabilisierung unserer Szene nun abgeschlossen. Falls einem die Stabilisierung so noch nicht gefällt, kann man die Parameter des GazeStabilizer weiter anpassen.

Das Demo-Projekt ist auf GitHub zu finden.