2010-12-15 14 views
19

Rozwijam aplikację rzeczywistości rozszerzonej, która (w tej chwili) chce wyświetlić prostą kostkę na powierzchni i być w stanie poruszać się w przestrzeni (zarówno obrotowej, jak i przemieszczającej), aby spójrz na kostkę pod różnymi kątami. Problem kalibracji kamery nie ma tu zastosowania, ponieważ poproszę użytkownika, aby umieścił iPhone'a na powierzchni, na której chce umieścić kostkę, a następnie naciśnij przycisk, aby zresetować ustawienie. Aby dowiedzieć się, obracanie kamery jest bardzo proste dzięki żyroskopowi i rdzenia. Robię to w następujący sposób:Uzyskiwanie danych z akcelerometru za pomocą Core Motion

if (referenceAttitude != nil) { 
    [attitude multiplyByInverseOfAttitude:referenceAttitude]; 
} 

CMRotationMatrix mat = attitude.rotationMatrix; 

GLfloat rotMat[] = { 
    mat.m11, mat.m21, mat.m31, 0, 
    mat.m12, mat.m22, mat.m32, 0, 
    mat.m13, mat.m23, mat.m33, 0, 
    0, 0, 0, 1 
}; 

glMultMatrixf(rotMat); 

Działa to naprawdę dobrze. Więcej problemów powstaje w każdym razie, gdy próbuję znaleźć przemieszczenie w przestrzeni podczas przyspieszania. Przykład Apple Teapot z Core Motion po prostu dodaje wartości x, yiz wartości wektora przyspieszenia do wektora położenia. To (oprócz braku sensu) powoduje powrót przedmiotu do pierwotnej pozycji po przyspieszeniu. (Ponieważ przyspieszenie idzie od dodatniego do ujemnego lub odwrotnie). Zrobili to tak:

translation.x += userAcceleration.x; 
translation.y += userAcceleration.y; 
translation.z += userAcceleration.z; 

Co należy zrobić, aby dowiedzieć się, przemieszczenie z przyspieszeniem w niektórych istant? (ze znaną różnicą czasu). Patrząc na kilka innych odpowiedzi, wydaje mi się, że muszę dwa razy zintegrować, aby uzyskać prędkość od przyspieszenia, a następnie pozycję z prędkości. Ale nie ma żadnego przykładu w kodzie i nie sądzę, że jest to naprawdę konieczne. Problemem jest również to, że kiedy iPhone jest nadal w płaszczyźnie, wartości akcelerometru nie są zerowe (wydaje mi się, że są jakieś zakłócenia). Ile powinienem odfiltrować te wartości? Czy mam je w ogóle filtrować?

Odpowiedz

7

Kiedy iPhone 4 był bardzo nowy, spędziłem wiele godzin próbując uzyskać dokładne przesunięcie za pomocą akcelerometrów i żyroskopu. Nie powinno być obawy o dryf przyrostowy, ponieważ urządzenie wymagało jedynie przesunięcia co najwyżej kilku metrów, a gromadzenie danych zwykle trwało najwyżej kilka minut. Próbowaliśmy różnych podejść, a nawet otrzymaliśmy pomoc od kilku inżynierów Apple. Ostatecznie wydawało się, że żyroskop nie nadąża za zadaniem. To było dobre dla orientacji 3D, ale to było to ... znowu, według bardzo dobrze poinformowanych inżynierów.

chciałbym usłyszeć ktoś zaprzecza to - ponieważ aplikacja nigdy nie okazało się, jak mieliśmy nadzieję, itp

21

Cool, istnieją ludzie, którzy zmagają się z tym samym problemem, więc warto, aby leżał czas :-)

Zgadzam się z oświadczeniem westsider za to, że spędziłem kilka tygodni eksperymentowania z różnymi podejściami i zakończyłem z kiepskimi wynikami. Jestem pewien, że nie będzie akceptowalnego rozwiązania dla większych odległości lub powolnych ruchów trwających dłużej niż 1 lub 2 sekundy. Jeśli możesz żyć z pewnymi ograniczeniami, takimi jak małe odległości (< 10 cm) i daną minimalną prędkością dla twoich ruchów, to wierzę, że może być szansa na znalezienie rozwiązania - bez żadnej gwarancji. Jeśli tak, to zajmie Ci to sporo trudu i sporo frustracji, ale jeśli go zdobędziesz, będzie to bardzo fajne :-) Może uważasz, że te wskazówki są przydatne:

Przede wszystkim do zrobienia rzeczy proste wystarczy spojrzeć na jedną oś, np. x, ale rozważmy zarówno lewy (-x) i prawy (+ x), aby mieć reprezentowalną sytuację.

Tak, masz rację, musisz dwa razy zintegrować, aby uzyskać pozycję w funkcji czasu. A do dalszego przetwarzania powinieneś zapisać wynik pierwszej integracji (== prędkość), ponieważ będziesz go potrzebować na późniejszym etapie do optymalizacji. Zrób to bardzo ostrożnie, ponieważ każdy drobny błąd doprowadzi do ogromnych błędów po krótkim czasie.

Zawsze należy pamiętać, że nawet bardzo mały błąd (np. < 0,1%) wzrośnie szybko po dwukrotnym wykonaniu integracji. Sytuacja stanie się jeszcze gorsza po jednej sekundzie, jeśli skonfigurujesz akcelerometr z powiedzmy 50 Hz, to znaczy 50 kleszczy zostanie przetworzonych, a mały pomijalny błąd przekroczy wartość "prawdziwą". Zdecydowanie nie polecam stosowania regu³ trapezowych, ale u¿ywaæ co najmniej formu³y Simpsona lub wy¿szego stopnia Newtona-Cotesa.

Jeśli to się udało, będziesz musiał uważać na skonfigurowanie właściwego filtrowania dolnoprzepustowego. Nie mogę podać ogólnej wartości, ale z reguły eksperymentowanie z czynnikami filtrującymi od 0,2 do 0,8 będzie dobrym punktem wyjścia. Odpowiednia wartość zależy od potrzeb biznesowych, na przykład od rodzaju gry, szybkości reakcji na zdarzenia, ...

Teraz będziesz miał rozwiązanie, które działa całkiem dobrze w pewnych okolicznościach iw krótkim czasie okres czasu. Ale po kilku sekundach wpadniesz w kłopoty, ponieważ twój obiekt odpływa. Teraz przejdziesz do trudnej części rozwiązania, której nie udało mi się ostatecznie rozwiązać w danym przedziale czasowym :-(

Jednym z obiecujących podejść jest wprowadzenie czegoś, co nazywam "siłami syntezy" lub "siłami wirtualnymi". strategia reagowania na kilka złych sytuacji, które powodują dryfowanie obiektu, chociaż urządzenie pozostaje niezmienne (bez rodzimego głośnika, mam na myśli bez poruszania się) w twoich rękach, najbardziej niepokojące jest prędkość większa niż 0 bez żadnego przyspieszenia. wytrącany propagacji błędów i może być obsługiwany przez spowolnienie sztucznie to znaczy wprowadzenie wirtualnego hamowania, nawet jeśli nie ma rzeczywistego odpowiednik bardzo uproszczony przykład.

if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) { 

    vX *= 0.9; 
} 

`

Będziesz potrzebował kombinacji takich warunków, aby oswoić bestię. Potrzeba wielu prób i błędów, aby poczuć właściwą drogę, a to będzie trudną częścią problemu.

Jeśli kiedykolwiek udało się złamać kod, pleeeease daj mi znać, jestem bardzo ciekaw, czy możliwe jest w ogóle lub nie :-)

Cheers Kay

5

Jestem również próbuje uzyskać przesuwanie na iPhonie. Zamiast korzystać z integracji użyłem podstawowej formuły fizyki d = .5a * t^2 przyjmując początkową prędkość 0 (nie brzmi jak można przyjąć prędkość początkową 0). Jak dotąd wydaje się, że działa całkiem dobrze.

Mój problem polega na tym, że używam deviceMotion.and wartości są nieprawidłowe. deviceMotion.gravity czytaj w pobliżu 0. Jakieś pomysły? - OK Naprawiono, najwyraźniej deviceMotion.gravity ma wartości x, yi z. Jeśli nie określisz, co chcesz, otrzymasz zwrot x (który powinien znajdować się w pobliżu 0).

+1

Problem d = 0,5 * a * t^2 na ogół jest to, że wymaga to stałego przyspieszenia, jak opisano w http://en.wikipedia.org/wiki/ Przyspieszenie. – Kay

+1

Zakładając, że v (0) == 0 jest krytyczne, ale potrzebujemy punktu, aby zacząć i powinieneś z tym żyć. IMO, im bardziej krytyczna część pojawia się po kilku sekundach, kiedy masz == 0 i v! = 0 (jak wyjaśniono w mojej odpowiedzi). – Kay

1

Znajdź to pytanie dwa lata później, I just find a AR project on iOS 6 docset named pARk, Zapewnia on przechwytywanie i obliczanie przybliżonego przemieszczenia za pomocą żyroskopu, znanego również jako CoreMotion.Framework.

Właśnie zaczynam przechylać kod.

być kontynuowane ...