Estou experimentando sensores no Android e decidi fazer um aplicativo para medir a distância pela qual o dispositivo se move, usando o sensor de aceleração linear. Eu criei o seguinte pedaço de código:
override fun onSensorChanged(e: SensorEvent?) {
if (e != null) {
when (e.sensor.type) {
Sensor.TYPE_LINEAR_ACCELERATION -> {
var time = if (dta != 0L) (e.timestamp - dta) * 10f.pow(-9) else 0f
for (i in 0..2) {
acceleration[i] = e.values[i]
position[i] += acceleration[i] * time * time / 2
}
dta = e.timestamp
}
}
}
}
onde dta
é o tempo da última atualização do sensor e acceleration
e position
são listas de estados mutáveis, exibidas na atividade.
No entanto, notei que as medições são muito imprecisas. Para reduzir o erro, decidi definir acceleration[i]
como 0f
se o valor do evento correspondente estiver abaixo de um limite. Mas ainda assim, mesmo que a leitura pareça correta, não tenho uma boa maneira de converter, pelo menos parcialmente, dados de aceleração brutos em mudanças de posição.
Não sei realmente como lidar com isso, por exemplo, por causa da característica de aceleração dos passos humanos (eles continuam aumentando uma vez, diminuindo uma vez), conforme mostrado no gráfico plotado na atividade:
Onde vermelho significa aceleração X, verde - Y, azul - Z e preto é a aceleração "total" - a raiz quadrada da soma das acelerações quadradas de eixo único.
O que acho notável é que a ideia do aplicativo é medir a distância percorrida na faixa de 1 a 5 metros, na taxa de ritmo normal de caminhada de uma pessoa (ele aperta um botão, anda, coloca o telefone no chão e volta para o local original), então o período de movimento não deve ser maior que um minuto. Dadas essas ordens de magnitude, o desvio do sensor não deve atrapalhar tanto, mas ao custo de nenhuma possibilidade de usar GPS para corrigir os resultados.
Eu gostaria de atingir uma precisão de 15-20 centímetros. Isso é possível e, se for, como obter esse efeito? E se não, há outras maneiras de medir efetivamente a distância do usuário do dispositivo? Ouvi falar do Google ARCore que deve ser teoricamente capaz de calcular a distância entre dois pontos (chamado Hit Records), mas a qualidade das leituras depende muito da qualidade da câmera e das condições de iluminação. Também li ( aqui ,
aqui ,
aqui ,
aqui e
aqui ) conselhos sobre "implementar filtros de Kalman" e "fundir sensores" - o que isso significa? Talvez possa ajudar?
Eu realmente aprecio cada resposta!
Este é tanto um problema de matemática aplicada ou física quanto qualquer outra coisa. Seu código para atualizar a posição só está correto para um sensor em repouso. Mecânica clássica as duas equações mais úteis que são relevantes aqui são:
Seu código está assumindo que
u=0
para todost
.E tem um possível viés de erro sistemático que é proporcional ao tempo gasto fazendo o cálculo. e.timestamp pode mudar entre o primeiro e o segundo uso.
Não falo a linguagem que você está usando para codificar isso, mas com base no código que você mostrou, o seguinte deve estar muito mais próximo de funcionar (obviamente você tem que declarar
velocity[]
no escopo correto). Introduzi uma nova variáveldt = time - otime...
e renomeeidta
comootime
porque é o valor de registro de data e hora anterior e não uma diferença de tempo.Eu me pergunto se a escala do intervalo de tempo também pode estar errada e se o sensor realmente retorna a aceleração em unidades SI m/s^2. O valor do timestamp é realmente medido em nanossegundos? Vários fatores de escala de calibração do sensor serão importantes, então você precisa verificar o manual para eles.
Você não. Há muitos problemas com acelerômetros que os tornam inapropriados para medir distâncias.
1)Mesmo que funcionassem perfeitamente, a integração dupla (de aceleração->velocidade->distância) faria com que o ruído natural no sensor fosse imensamente ampliado.
2)Acelerômetros são barulhentos por natureza. Eles precisam ser PESADAMENTE filtrados para obter resultados decentes para algo assim. A menos que você seja um especialista em DSP, é improvável que você faça isso bem.
3) Acelerômetros não são projetados para isso. Eles atingem o máximo - há uma aceleração máxima que eles podem medir, e além disso eles não podem aumentar. O que é isso depende do modelo exato do sensor, mas você pode facilmente atingir esse ponto correndo.
4) Acelerômetros medem aceleração. Não velocidade. Então, se você viajar a uma velocidade constante de 1 m/s, o acelerômetro sempre mediria 0 (ignorando ruído). Assim, você veria movimento 0, mesmo que esteja se movendo a 1 m/s. Em outras palavras, quando você integra aceleração em velocidade e obtém
v= v_0+a(t)*t
, o termo v_0 não é mensurável por um acelerômetro. Quando você integra novamente à distânciax(t)= x_0+v_0*t+1/2a(t)^2
, os termos x_0 e v_0 são ambos zerados, um erro significativo.5) Inclinação/rotação. Segure seu telefone enquanto estiver sentado e gire seu pulso rapidamente. Você verá um pico de aceleração da força centrífuga da rotação. Mas você não se moveu. Você pode talvez cancelar isso lendo o giroscópio e fazendo alguma matemática, mas giroscópios também são barulhentos.
Tudo isso é o motivo pelo qual acelerômetros nunca são usados para cálculos de distância. Se você quer distância, use GPS ou localização baseada em rede. Qualquer um deles será muito mais correto do que o acelerômetro.
Agora você diz que quer medir com uma precisão de 0,15 m. Não acho que haja nenhuma maneira de fazer isso. O GPS não é tão preciso, mesmo em condições de céu aberto - isso é cerca de 5 m com condições atmosféricas perfeitas. Talvez o hardware militar classificado possa chegar perto, mas em um telefone comercial espere mais como 10 m, e com saltos ocasionais de 100 m se estiver em um local no centro da cidade ou em montanhas, e > 5 m se estiver dentro. Se você quiser fazer isso em um local específico, você pode configurar beacons BLE e usar triangulação de distância a partir deles, mas mesmo isso é improvável que lhe dê esse grau de precisão. A tecnologia simplesmente não foi feita para isso.
Você mencionou o ARCore - O ARCore faz algo muito diferente. Quando mede distância, ele não sabe nada sobre sua localização no mundo. Ele usa visão computacional para tentar descobrir onde os objetos estão em uma imagem e, então, estima a distância até esse objeto. Ele não detecta movimento de um telefone (bem, ele tem um modo em que usará GPS para permitir que você coloque objetos em uma coordenada GPS, mas esse é um subsistema totalmente diferente do ARCore).