Obtendo o deslocamento dos dados do acelerômetro com o Core Motion

Estou desenvolvendo um aplicativo de realidade aumentada que (no momento) deseja exibir um cubo simples em cima de uma superfície e ser capaz de se mover no espaço (girando e deslocando) para observar o cubo em todos os diferentes ângulos. O problema de calibrar a câmera não se aplica aqui, já que peço ao usuário para posicionar o iPhone na superfície em que ele deseja colocar o cubo e, em seguida, pressione um botão para redefinir a atitude. Descobrir a rotação da câmera é muito simples com o giroscópio e o movimento do núcleo. Eu faço assim:

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); 

Isso funciona muito bem. Mais problemas surgem de qualquer maneira quando tento encontrar o deslocamento no espaço durante uma aceleração. O exemplo do Apple Bule com o Core Motion apenas adiciona os valores x, y e z do vetor de aceleração ao vetor de posição. Isso (além de não ter muito sentido) tem o resultado de retornar o object para a posição original após uma aceleração. (Como a aceleração vai de positiva para negativa ou vice-versa). Eles fizeram assim:

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

O que devo fazer para descobrir o deslocamento da aceleração em algum momento? (com diferença de tempo conhecida). Olhando algumas outras respostas, parece que eu tenho que integrar duas vezes para obter velocidade da aceleração e, em seguida, posicionar a partir da velocidade. Mas não há nenhum exemplo no código, e eu não acho que isso seja realmente necessário. Além disso, existe o problema de que quando o iPhone ainda está em um avião, os valores do acelerômetro não são nulos (há algum ruído que eu acho). Quanto devo filtrar esses valores? Eu deveria filtrá-los?

Legal, tem gente lá fora lutando com o mesmo problema então vale a pena passar algum tempo 🙂

Eu concordo com a declaração do westsider enquanto passei algumas semanas experimentando diferentes abordagens e acabei com resultados ruins. Tenho certeza de que não haverá uma solução aceitável para distâncias maiores ou movimentos lentos que durem mais de 1 ou 2 segundos. Se você pode viver com algumas restrições, como pequenas distâncias (<10 cm) e uma velocidade mínima para seus movimentos, então acredito que pode haver a chance de encontrar uma solução - nenhuma garantia. Se assim for, você terá bastante dificuldade de pesquisa e muita frustração, mas se conseguir, será muito legal :-) Talvez você ache essas dicas úteis:

Primeiro de tudo, para facilitar as coisas, basta olhar para um eixo, por exemplo, x, mas considere ambos os lados esquerdo (-x) e direito (+ x) para ter uma situação representável.

Sim, você está certo, você tem que integrar duas vezes para obter a posição em function do tempo. E para processamento adicional, você deve armazenar o resultado da primeira integração (== velocidade), porque você precisará dela em um estágio posterior para otimização. Faça isso com muito cuidado, porque cada pequeno bug levará a erros enormes após um curto período de tempo.

Tenha sempre em mente que mesmo um erro muito pequeno (por exemplo, <0,1%) aumentará rapidamente após a integração duas vezes. A situação se tornará ainda pior após um segundo se você configurar o acelerômetro com, digamos, 50 Hz, ou seja, 50 pulsos serão processados ​​e o pequeno erro negligenciável irá ultrapassar o valor "verdadeiro". Eu recomendaria fortemente não confiar na regra trapezoidal, mas usar pelo menos Simpson ou uma fórmula de Newton-Cotes de grau mais elevado.

Se você conseguiu isso, terá que ficar de olho em configurar o filtro de baixa passagem correto. Eu não posso dar um valor geral, mas como regra geral, experimentar com fatores de filtragem entre 0,2 e 0,8 será um bom ponto de partida. O valor correto depende do caso de negócio que você precisa, por exemplo, que tipo de jogo, quão rápido reagir em events, …

Agora você terá uma solução que está funcionando muito bem em determinadas circunstâncias e dentro de um curto período de tempo. Mas depois de alguns segundos você terá problemas porque seu object está se afastando. Agora você vai entrar na parte difícil da solução que eu não consegui manipular eventualmente dentro do escopo de tempo determinado 🙁

Uma abordagem promissora é introduzir algo que chamo de “forças sintéticas” ou “forças virtuais”. Essa é uma estratégia para reagir a várias situações ruins que acionam o object, embora o dispositivo permaneça fixo (sem falantes nativos, quero dizer sem me mexer) em suas mãos. O mais preocupante é uma velocidade maior que 0 sem qualquer aceleração. Este é um resultado inevitável da propagação de erros e pode ser tratado abrandando artificialmente, o que significa introduzir uma desaceleração virtual, mesmo que não exista uma contrapartida real. Um exemplo muito simplificado:

 if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) { vX *= 0.9; } 

`

Você precisará de uma combinação dessas condições para domar a fera. Um monte de tentativa e erro é necessário para obter uma sensação para o caminho certo a seguir e esta será a parte mais difícil do problema.

Se você já conseguiu quebrar o código, pleeeease me avise, estou muito curioso para ver se é possível, em geral ou não 🙂

Felicidades Kay

Quando o iPhone 4 era muito novo, passei muitas e muitas horas tentando obter um deslocamento preciso usando acelerômetros e giroscópios. Não deveria haver muita preocupação com o desvio incremental, já que o dispositivo precisava apenas mover alguns metros no máximo e a coleta de dados normalmente durava no máximo alguns minutos. Tentamos todos os tipos de abordagens e até contamos com a ajuda de vários engenheiros da Apple. Em última análise, parecia que o giroscópio não estava à altura da tarefa. Foi bom para a orientação 3D, mas foi isso … novamente, de acordo com engenheiros muito qualificada.

Eu adoraria ouvir alguém contradizer isso – porque o aplicativo nunca saiu como esperávamos, etc.

Eu também estou tentando obter o deslocamento no iPhone. Em vez de usar integração, usei a fórmula física básica de d = .5a * t ^ 2, assumindo uma velocidade inicial de 0 (não parece que você pode assumir a velocidade inicial de 0). Até agora parece funcionar muito bem.

Meu problema é que estou usando o deviceMotion e os valores não estão corretos. deviceMotion.gravity ler perto de 0. Alguma idéia? – OK Corrigido, aparentemente deviceMotion.gravity possui valores ax, y e z. Se você não especificar qual deseja voltar x (que deve estar próximo de 0).

Encontre esta questão dois anos depois, eu acabei de encontrar um projeto AR no iOS 6 docset chamado pARk , ele fornece uma captura de deslocamento próximo e cálculo usando giroscópio, também conhecido como CoreMotion.Framework.

Eu estou apenas começando a inclinar o código.

continua…

    Intereting Posts