ios core-location core-motion magnetometer

En iOS, ¿cuál es la diferencia entre los valores de campo magnético de Core Location y Core Motion?



core-location core-motion (4)

Tengo dos formas de obtener los campos magnéticos (fuerza, x, y, z) usando el magnetómetro del dispositivo iOS.

1) Ubicación central
Usé el CLHeading del método CLLocationManagerDelegate locationManager:didUpdateHeading: Esto es similar a la aplicación de muestra Teslameter de Apple.

2) Core Motion
Se utilizó CMMagneticField de CMMotionManager ''s magnetometerData.magneticField .

Preguntas:
a) ¿Cuál es la diferencia entre los dos? Estoy obteniendo valores diferentes de ambos. Estaba esperando que devuelvan los mismos valores.
La diferencia es más notable cuando comienzo la aplicación desde una posición de descanso (boca arriba en una mesa), y luego levanto el dispositivo al aire.
b) Si hay una diferencia, ¿cuándo debería usar el campo magnético del rumbo de Core Location, y cuándo debería usar el campo magnético de Core Motion?

Nota: Tampoco estoy seguro si el "campo magnético" de Core Location y Core Motion se refiere a diferentes conceptos de campo magnético.
Nota: Calculé la fuerza como la raíz cuadrada de (x ^ 2 + y ^ 2 + z ^ 2) para ambos enfoques.


Creo que el magnetómetroData.magneticField te dice la aceleración, no la posición (de ahí por qué obtienes grandes valores moviéndose de fijo a móvil) mientras que el administrador de ubicación proporciona datos sobre la dirección en la que apunta el dispositivo.


Para desentrañar esto, he pasado demasiado tiempo investigando los documentos de Apple.

Hay tres formas de obtener datos de magnetómetro

1 / marco Core Motion
Clase CMMagnetometer CMMagnetometer

2 / Marco Core Motion
CMDeviceMotion CMCalibratedMagneticField

3 / Marco de ubicación principal
CLHeading del CLHeading

1 / suministra datos ''en bruto'' del magnetómetro.
2 / y 3 / devuelve datos ''derivados''. Los números en ambos casos son similares (aunque no exactamente iguales).

Diferencia entre el CMMagnetometer de Core Motion y CMCalibratedMagneticField

1 / y 2 / - ambos del marco de Core Motion - difieren de la siguiente manera:

Referencia de la clase CMDeviceMotion

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField

Discusión
El campo CMCalibratedMagneticField devuelto por esta propiedad le proporciona el campo magnético total en las proximidades del dispositivo sin predisposición del dispositivo. A diferencia de la propiedad magneticField de la clase CMMagnetómetro, estos valores reflejan el campo magnético terrestre más los campos circundantes, menos el sesgo del dispositivo.

CMMagnetometer nos da datos brutos, CMCalibratedMagneticField es datos ajustados.

Diferencia entre CMCalibratedMagneticField de Core Motion y CLHeading de Core Location

Los documentos no son inmediatamente claros sobre la diferencia entre 2 / y 3 /, pero generan números diferentes así que vamos a hacer un poco de excavación ...

Marco de ubicación central
CLHeading

De la guía de programación de concientización de ubicación

Obtención de eventos relacionados con el título

Los eventos de encabezado están disponibles para aplicaciones que se ejecutan en un dispositivo que contiene un magnetómetro. Un magnetómetro mide los campos magnéticos cercanos que emanan de la Tierra y los utiliza para determinar la orientación precisa del dispositivo. Aunque un magnetómetro puede verse afectado por campos magnéticos locales, como los que emanan de imanes fijos que se encuentran en parlantes de audio, motores y muchos otros tipos de dispositivos electrónicos, Core Location es lo suficientemente inteligente como para filtrar los campos que se mueven con el dispositivo.

Aquí están las propiedades CLHeading relevantes ''raw''

@property(readonly, nonatomic) CLHeadingComponentValue x @property(readonly, nonatomic) CLHeadingComponentValue y @property(readonly, nonatomic) CLHeadingComponentValue z

Los datos geomagnéticos (medidos en microteslas) para el eje [x | y | z]. (solo lectura)
Este valor representa la desviación del eje [x | y | z] de las líneas de campo magnético que rastrea el dispositivo. ( las versiones anteriores de los documentos agregan:) El valor informado por esta propiedad se normaliza en el rango de -128 a +128.

No estoy seguro de cómo una medición de microtesla puede ''normalizarse'' (¿comprimirse o recortarse?) Hasta un rango de +/- 128 y aún representar la unidad que dice medir. Tal vez es por eso que la oración fue eliminada de los documentos. Las unidades en un iPad mini parecen ajustarse a este tipo de alcance, pero el iPhone4S da lecturas de CMMagnetometer en rangos más altos, por ejemplo, 200-500.

La API claramente espera que use las propiedades derivadas:

@property(readonly, nonatomic) CLLocationDirection magneticHeading @property(readonly, nonatomic) CLLocationDirection trueHeading

que dan lecturas estables de la brújula N / SE / W en grados (0 = Norte, 180 = Sur, etc.). Para el rumbo verdadero, se requieren otros servicios de ubicación central (geolocalización) para obtener la desviación de los magnéticos del norte verdadero.

Aquí hay un fragmento del archivo de encabezado CLHeading

/* * CLHeading * * Discussion: * Represents a vector pointing to magnetic North constructed from * axis component values x, y, and z. An accuracy of the heading * calculation is also provided along with timestamp information. * * x|y|z * Discussion: * Returns a raw value for the geomagnetism measured in the [x|y|z]-axis.

Marco de Core Motion
CMDeviceMotion CMCalibratedMagneticField

/* * magneticField * * Discussion: * Returns the magnetic field vector with respect to the device for devices with a magnetometer. * Note that this is the total magnetic field in the device''s vicinity without device * bias (Earth''s magnetic field plus surrounding fields, without device bias), * unlike CMMagnetometerData magneticField. */ @property(readonly, nonatomic) CMCalibratedMagneticField magneticField NS_AVAILABLE(NA,5_0);

CMMagnetometer

* magneticField * * Discussion: * Returns the magnetic field measured by the magnetometer. Note * that this is the total magnetic field observed by the device which * is equal to the Earth''s geomagnetic field plus bias introduced * from the device itself and its surroundings. */ @property(readonly, nonatomic) CMMagneticField magneticField;

CMMagneticField
Esta es la estructura que contiene el vector.
Es lo mismo para el campo magnético calibrado CMMagnetometer y la versión no calibrada de CMMagnetometer :

/* CMMagneticField - used in * CMDeviceMotion.magneticField.field * CMMagnetometerData.magneticField * * Discussion: * A structure containing 3-axis magnetometer data. * * Fields: * x: * X-axis magnetic field in microteslas. * y: * Y-axis magnetic field in microteslas. * z: * Z-axis magnetic field in microteslas.

La diferencia entre 2 / y 3 / se insinúa aquí:

Core Location CLHeading

Representa un vector que apunta al Norte magnético construido a partir de los valores del componente del eje x, y, y z

Core Location es lo suficientemente inteligente como para filtrar los campos que se mueven con el dispositivo

Core Motion CMCalibratedMagneticField

[representa] el campo magnético de la Tierra más los campos circundantes , sin sesgo del dispositivo

Entonces, de acuerdo con los documentos, tenemos:

1 / CMMagnetometer
Lecturas crudas del magnetómetro

2 / CMDeviceMotion (CMCalibratedMagneticField *) magneticField
Lecturas del magnetómetro corregidas para el sesgo del dispositivo (campos magnéticos a bordo)

3 / CLHeading [x | y | z]
Lecturas de magnetómetro corregidas para el sesgo del dispositivo y filtradas para eliminar los campos magnéticos externos locales (detectados por el movimiento del dispositivo; si el campo se mueve con el dispositivo, ignórelo; de lo contrario, mételo)

Probando la teoría

He puesto una aplicación de demostración Magnet-O-Meter en gitHub que muestra algunas de estas diferencias. Es bastante revelador mover un imán alrededor de su dispositivo cuando la aplicación se está ejecutando y observar cómo reaccionan las diversas API:

CMMagnetometer no reacciona mucho a nada a menos que tire de un imán de tierras raras de cerca. Los campos magnéticos a bordo parecen mucho más importantes que los campos externos locales o el campo magnético de la tierra. En mi iPhone 4S apunta consistentemente a la parte inferior izquierda del dispositivo; en el iPad mini, generalmente apunta hacia la parte superior derecha.

CLHeading. [X | y | z] es el más vulnerable (sensible) a los campos externos locales, ya sean móviles o estáticos en relación con el dispositivo.

(Dispositivo CM) CMCalibratedMagneticField es el más estable frente a campos externos variables, pero de lo contrario realiza un seguimiento muy cercano de su homólogo de Ubicación Central CLHeading. [X | y | z] .

CLHeading.magneticHeading - La recomendación de Apple para la lectura de la brújula magnética - es mucho más estable que cualquiera de estos. Está utilizando datos de otros sensores para estabilizar los datos del magnetómetro. Pero no obtienes un desglose en bruto de x, y, z

influenced by onboard fields local external fields earth''s field yellow X X X green _ X X blue _ _ X red _ _ X

CMMagnetómetro amarillo
green CLHeading. [x | y | z]
azul CMCalibratedMagneticField
rojo CLHeading.magneticHeading

Esto parece contradecir los documentos, que sugieren que CLHeading. [X | y | z] debería estar menos influenciado por campos externos locales que CMCalibratedMagneticField .

¿Qué enfoque debes tomar? Basado en mis pruebas limitadas, sugeriría ...
Si quieres una lectura de brújula
CLHeading''s magneticHeading y trueHeading le dará la lectura más precisa y estable de la brújula.
Si necesita evitar Core Location
El CMCalibratedMagneticField de CMCalibratedMagneticField parece ser el próximo más deseable, aunque considerablemente menos estable y preciso que el CMCalibratedMagneticField magneticHeading .
Si te interesan los campos magnéticos locales
Las propiedades "en bruto" xyz de CLHeading parecen ser más sensibles a los campos magnéticos locales.
Si desea todos los datos, incluidos los campos magnéticos a bordo
Datos crudos del magnetómetro de CMMagnetometer. Realmente no tiene mucho sentido usar esto a menos que esté preparado para hacer toneladas de filtrado, ya que está muy influenciado por los campos magnéticos generados en el dispositivo.


Una cosa importante para recordar al usar los valores CLHeading. [X | y | z] para calcular la intensidad del campo magnético local es que el método CLLocationManagerDelegate

  • (BOOL) locationManagerShouldDisplayHeadingCalibration: (CLLocationManager *) manager

debe establecerse para que devuelva SÍ. He descubierto que las lecturas del magnetómetro nunca se calibran si esta advertencia de calibración se apaga y que, como resultado, la intensidad de campo calculada es muy inestable cuando se cambia la orientación del dispositivo.


esta respuesta se basa en mi interpretación de los enlaces de documentación a continuación

http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLHeading_Class/Reference/Reference.html#//apple_ref/doc/c_ref/CLHeading

CMMagnetometer

a) CLHeading es " desviación de las líneas de campo magnético rastreadas por el dispositivo" mientras que magnetometerData.magneticField "es el campo magnético total observado por el dispositivo que es igual al campo geomagnético de la Tierra más el sesgo introducido desde el dispositivo mismo y su entorno" .

Entonces CLHeading te da valores filtrados con el Frame of Reference como el campo magnético existente de la tierra. Mientras magnetometerData le da valores sin filtrar con el Frame of reference como dispositivo.

b) si estuvieras haciendo algo con una ubicación en la que quisieras saber dónde está el norte magnético o verdadero, te recomendaría usar CLHeading. Si desea crear una aplicación que responda a los campos magnéticos en los alrededores inmediatos de los dispositivos o si tuviera alguna fusión específica de sensores que quisiera realizar quizás intente crear un AHRS por ejemplo, luego vaya con CMMagneticField.