2010-01-03 18 views
12

Necesito implementar una aplicación nativa de iPhone para medir la velocidad del teléfono (básicamente un velocímetro). Sé que puede hacerlo a través de la API CoreLocation con bastante facilidad, pero me preocupa el consumo de la batería, ya que se trata de una medición en tiempo real que podría usarse durante un par de horas a la vez. Según tengo entendido, mientras supervisa activamente los eventos del LocationManager (aunque realmente no me importa la ubicación del GPS) consume mucha batería.Medición de velocidad a través del SDK de iPhone

La otra opción obvia para explorar sería usar los acelerómetros para intentar calcular la velocidad, pero no hay nada en la API que lo ayude a hacerlo. Basado en mi investigación, debería ser posible hacer esto, pero parece extremadamente complicado y propenso a errores. Traducir de la aceleración a la velocidad puede ser difícil, y los datos del acelerómetro iPhone pueden ser "ruidosos". Estoy familiarizado con el ejemplo de SDK que demuestra el uso de filtros de paso bajo/alto, etc., pero no he visto un buen ejemplo en ninguna parte que muestre el cálculo de la velocidad.

¿Alguien tiene alguna experiencia real con esto que puedan compartir? El código sería fantástico, pero en realidad solo quiero saber si alguien ha hecho esto con éxito (para una aplicación de larga duración) y qué enfoque tomaron.

EDIT: Tengo un prototipo funcional que utiliza la API de LocationManager. Funciona bien, pero el ciclo de actualización está lejos de ser ideal para una medición de velocidad en tiempo real. Dependiendo de las circunstancias, puede tardar hasta 4-5 segundos en actualizarse. Cruzar a una velocidad dada tiende a funcionar bien, pero la aceleración/desaceleración tiende a retrasarse mucho desde el punto de vista de la interacción del usuario. Además, necesito introducir la velocidad en algunos otros cálculos que estoy haciendo y la precisión no es realmente lo que necesito.

Parece posible basado en (muy pocas) otras aplicaciones que he visto, notablemente gMeter que dice que no hace uso del GPS pero calcula la velocidad con precisión. Estoy realmente sorprendido de que no haya referencias ni ningún código de muestra que demuestre esto en ningún lugar que pueda encontrar. Me doy cuenta de que es complejo, pero seguramente hay algo por ahí.

+0

Oye, me interesaría cualquier éxito que hayas tenido en esta área. Actualmente estoy investigando el uso de los datos de acelerómetro/Gryo de un iPhone 4 junto con datos de GPS para trazar una ruta de navegación inercial entre las actualizaciones de GPS. – Jerceratops

Respuesta

10

Desde el GPS y el acelerómetro tienen diferentes debilidades, su mejor opción es probablemente sea un enfoque combinado: obtenga una medición del GPS cada vez aproximadamente un minuto, luego agregue cambios en tiempo real desde el acelerómetro.

+0

Sí, este es el enfoque que he estado considerando en base a lo que he leído sobre la acumulación de errores utilizando la aceleración solo a largas distancias. Todavía estoy luchando con la aceleración convertida a velocidad para comenzar. –

3

No estoy seguro de que vaya a intentar seguir la velocidad con el acelerómetro. Para hacer esto, debes asegurarte de haber capturado CADA aceleración, ya que los puntos de datos perdidos indicarían una velocidad incorrecta (suponiendo, por supuesto, que puedas convertir los valores del acelerómetro informados en unidades estándar). Por lo tanto, tendrías que ejecutar constantemente las cosas del acelerómetro, lo que absorbería un poco de jugo en sí mismo (y, de nuevo, no se garantizarán todas las aceleraciones). Yo recomendaría usar CoreLocation.

+0

Suena como lo que he leído en aceleración -> velocidad, aunque mi impresión es que la antena interna utilizada por el iPhone para procesar señales satelitales/celulares usa mucha más energía que los acelerómetros (¿no están casi siempre encendidos?) –

10

Desde un punto de vista práctico, no obtendrás una velocidad precisa de las fuerzas que actúan sobre el acelerómetro.

Utilice el GPS con las lecturas tomadas en intervalos de 1 minuto y ponga el GPS para dormir entremedio.

Aquí se muestra un ejemplo:

SpeedViewController.h

CLLocationManager *locManager; 
CLLocationSpeed speed; 
NSTimer *timer; 

@property (nonantomic,retain) NSTimer *timer; 

SpeedViewController.m

#define kRequiredAccuracy 500.0 //meters 
#define kMaxAge 10.0 //seconds 

- (void)startReadingLocation { 
    [locManager startUpdatingLocation]; 
} 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 

    NSTimeInterval ageInSeconds = [newLocation.timestamp timeIntervalSinceNow]; 

    //ensure you have an accurate and non-cached reading 
    if(newLocation.horizontalAccuracy > kRequiredAccuracy || fabs(ageInSeconds) > kMaxAge) 
     return; 

    //get current speed  
    currentSpeed = newLocation.speed; 

    //this puts the GPS to sleep, saving power 
    [locManager stopUpdatingLocation]; 

    //timer fires after 60 seconds, then stops 
    self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(timeIntervalEnded:) userInfo:nil repeats:NO]; 
} 

//this is a wrapper method to fit the required selector signature 
- (void)timeIntervalEnded:(NSTimer*)timer { 
    [self startReadingLocation]; 
} 
+0

Gracias por el ejemplo. En realidad, esto tendría que ser una medida casi en tiempo real para mí. Todavía estoy preocupado por el consumo de energía si esto se hizo más en un segundo o dos intervalos de actualización. ¿Has hecho esto en una aplicación real? –

+0

No tengo pruebas en el mundo real de que esto realmente ahorrará energía. En teoría, apagar el GPS durante unos segundos después de cada lectura debería consumir mucha menos energía. – bentford

+0

Falta un "{" en - (nulo) locationManager –

4

El error en la aceleración se acumulará con el tiempo. Su mejor apuesta es conseguir una velocidad exacta del GPS, quizá una vez por minuto o menos:

distanceTravelled = sqrt((position2.x-position1.x)^2 + (position2.y-position1.y)^2) 
velocity = distanceTravelled/timeBetweenGPSReadings 

(donde ^2 significa cuadrados)

Luego tomar mediciones frecuentes del acelerómetro:

newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings 
2

Aunque no conozco la API de iPhone, sé algo sobre GPS y navegación inercial. Puede ser útil.

Los receptores de GPS con los que he trabajado pueden todos proporcionar una medición directa de la velocidad de las señales de GPS que reciben. Estas medidas son más precisas que los datos de posición, incluso. No sé si la API de Apple proporciona acceso, o incluso si Apple ha configurado su receptor para proporcionar estos datos. Esta sería la ruta más eficiente para obtener una medición de velocidad.

La siguiente ruta, dado que tiene datos de acelerómetro y datos de GPS es combinarlos como se mencionó anteriormente por otros carteles y comentarios. Usar el GPS para corregir periódicamente la medición intertial acumulada de los datos del acelerómetro funciona muy bien en la práctica. Proporciona el beneficio de mediciones de acelerómetro más frecuentes y la precisión de las mediciones de GPS. Un filtro de Kalman se usa comúnmente. Pero dada la precisión y los límites de tiempo de la plataforma elegida, un filtro kalman puede ser excesivo y algo más simple de implementar y ejecutar debería funcionar bien.

De todos modos, solo algunas cosas en que pensar.

Cuestiones relacionadas