web-dev-qa-db-fra.com

Dans iOS, quelle est la différence entre les valeurs de champ magnétique des infrastructures Core Location et Core Motion?

J'ai deux façons d'obtenir les champs magnétiques (intensité, x, y et z) en utilisant le magnétomètre de l'appareil iOS.

1) Emplacement central
A utilisé le CLHeading de la méthode CLLocationManagerDelegatelocationManager:didUpdateHeading:. Ceci est similaire à l'exemple d'application Teslameter d'Apple.

2) Core Motion
Utilisé CMMagneticField de CMMotionManager's magnetometerData.magneticField.

Des questions:
a) Quelle est la différence entre les deux? Je reçois des valeurs différentes des deux. Je m'attendais à ce qu'ils renvoient les mêmes valeurs.
La différence est la plus notable lorsque je démarre l'application à partir d'une position de repos (face vers le haut dans une table), puis que je soulève l'appareil en l'air.
b) En cas de différence, quand dois-je utiliser le champ magnétique de l'en-tête Emplacement du noyau et quand dois-je utiliser le champ magnétique de Core Motion?

Remarque: Je ne sais pas non plus si le "champ magnétique" de Core Location et Core Motion fait référence à différents concepts de champ magnétique.
Remarque: J'ai calculé la force comme la racine carrée de (x ^ 2 + y ^ 2 + z ^ 2) pour les deux approches.

61
MiuMiu

Pour résoudre ce problème, j'ai passé un peu trop de temps à fouiller dans les documents Apple.

Il existe trois façons d'obtenir des données de magnétomètre

1/ framework Core Motion
CMMotionManagers's CMMagnetometer classe

2/Framework Core Motion
CMDeviceMotionCMCalibratedMagneticField propriété

3/ Framework d'emplacement central
CLLocationManager CLHeading

1/fournit des données "brutes" du magnétomètre.
2/et 3/renvoient des données "dérivées". Les chiffres dans les deux cas sont similaires (mais pas exactement les mêmes).

Différence entre le CMMagnetometer de Core Motion et CMCalibratedMagneticField

1/et 2/- tous deux issus du framework Core Motion - diffèrent comme suit:

Référence de la classe CMDeviceMotion

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField

Discussion
Le champ CMCalibratedMagneticField renvoyé par cette propriété vous donne le champ magnétique total à proximité de l'appareil sans biais de l'appareil. Contrairement à la propriété magnetField de la classe CMMagnetometer, ces valeurs reflètent le champ magnétique terrestre plus les champs environnants, moins la polarisation de l'appareil.

CMMagnetometer nous donne des données brutes, CMCalibratedMagneticField est des données ajustées.

Différence entre CMCalibratedMagneticField de Core Motion et CLHeading de Core Location

Les documents ne sont pas immédiatement clairs sur la différence entre 2/et 3 /, mais ils génèrent des nombres différents alors faisons quelques recherches….

Infrastructure de localisation centrale
CLHeading

De Guide de programmation de la localisation

Obtention d'événements liés à la rubrique

Les événements de titre sont disponibles pour les applications exécutées sur un appareil contenant un magnétomètre. Un magnétomètre mesure les champs magnétiques proches émanant de la Terre et les utilise pour déterminer l'orientation précise de l'appareil. Bien qu'un magnétomètre puisse être affecté par des champs magnétiques locaux, tels que ceux émanant d'aimants fixes trouvés dans des haut-parleurs audio, des moteurs et de nombreux autres types d'appareils électroniques, Core Location est suffisamment intelligent pour filtrer les champs qui se déplacent avec l'appareil.

Voici les propriétés CLHeading 'raw' pertinentes

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

Les données géomagnétiques (mesurées en microteslas) pour l'axe [x | y | z]. (lecture seulement)
Cette valeur représente l'écart d'axe [x | y | z] par rapport aux lignes de champ magnétique suivies par l'appareil. ( les anciennes versions de la documentation ajoutent:) La valeur rapportée par cette propriété est normalisée dans la plage -128 à +128.

Je ne sais pas comment une mesure microtesla peut être "normalisée" (compressée? Coupée?) Sur une plage de +/- 128 et représente toujours l'unité qu'elle prétend mesurer. C'est peut-être pour cela que la phrase a été supprimée des documents. Les unités d'un iPad mini semblent conformes à ce type de plage, mais l'iPhone4S donne des lectures CMMagnetometer dans des plages plus élevées, par exemple 200-500.

L'API attend clairement de vous que vous utilisiez les propriétés dérivées:

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

qui donnent des lectures de boussole N/S E/W stables en degrés (0 = nord, 180 = sud, etc.). Pour le cap vrai, d'autres services de localisation centrale sont nécessaires (géolocalisation) pour obtenir la déviation magnétique du nord vrai.

Voici un extrait du fichier d'en-tête 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.

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

CMMagnétomètre

 *  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
Ceci est la structure qui contient le vecteur.
C'est la même chose pour le champ magnétique calibré de CMDeviceMotion et la version non calibrée 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 différence entre 2/et 3/est indiquée ici:

Emplacement principal CLHeading

Représente un vecteur pointant vers le nord magnétique construit à partir des valeurs des composantes de l'axe x, y et z

Core Location est assez intelligent pour filtrer les champs qui se déplacent avec l'appareil

Core Motion CMCalibratedMagneticField

[représente] le champ magnétique terrestre plus les champs environnants, sans polarisation de l'appareil

Donc - selon la documentation - nous avons:

1/ CMMagnétomètre
Lectures brutes du magnétomètre

2/ CMDeviceMotion (CMCalibratedMagneticField *) champ magnétique
Lectures du magnétomètre corrigées pour la polarisation de l'appareil (champs magnétiques embarqués)

3/ CLHeading [x | y | z]
Lectures du magnétomètre corrigées pour la polarisation de l'appareil et filtrées pour éliminer les champs magnétiques externes locaux (détectés par le mouvement de l'appareil - si le champ se déplace avec l'appareil, ignorez-le, sinon mesurez-le)

Test de la théorie

enter image description here

J'ai mis une application de démonstration Magnet-O-Meter sur gitHub qui affiche certaines de ces différences. Il est assez révélateur d'agiter un aimant autour de votre appareil lorsque l'application est en cours d'exécution et de regarder comment les différentes API réagissent:

CMMagnetometer ne réagit pas beaucoup à quoi que ce soit, sauf si vous tirez un aimant de terres rares de près. Les champs magnétiques embarqués semblent beaucoup plus importants que les champs externes locaux ou le champ magnétique terrestre. Sur mon iPhone 4S, il pointe systématiquement vers le bas à gauche de l'appareil; sur l'iPad mini, il pointe généralement vers le haut à droite.

CLHeading. [X | y | z] est le plus vulnérable (sensible) aux champs externes locaux, qu'ils soient mobiles ou statiques par rapport à l'appareil.

(CMDevice) CMCalibratedMagneticField est le plus stable face à divers champs externes, mais suit autrement son homologue Core Location CLHeading. [X | y | z] assez étroitement.

CLHeading.magneticHeading - La recommandation d'Apple pour la lecture de la boussole magnétique - est beaucoup plus stable que n'importe lequel d'entre eux. Il utilise les données des autres capteurs pour stabiliser les données du magnétomètre. Mais vous n'obtenez pas une ventilation brute 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           

jaune CMMagnetometer
vert CLHeading. [x | y | z]
bleu CMCalibratedMagneticField
rouge CLHeading.magneticHeading

Cela semble contredire les documents, qui suggèrent que CLHeading. [X | y | z] devrait être moins influencé par les champs externes locaux que CMCalibratedMagneticField.

Quelle approche devez-vous adopter? Sur la base de mes tests limités, je suggère…
Si vous voulez une lecture au compas
magneticHeading et trueHeading de CLHeading vous donneront la lecture de boussole la plus précise et la plus stable.
Si vous devez éviter Core Location
CMCalibratedMagneticField de CMDeviceMotion semble être le suivant le plus souhaitable, bien que considérablement moins stable et précis que magneticHeading.
Si vous êtes intéressé par les champs magnétiques locaux
Les propriétés "brutes" x y et z de CLHeading semblent être plus sensibles aux champs magnétiques locaux.
Si vous voulez toutes les données, y compris les champs magnétiques embarqués
Données magnétométriques brutes de CMMagnetometer. Cela ne sert vraiment à rien à moins que vous ne soyez prêt à effectuer des tonnes de filtrage, car il est énormément influencé par les champs magnétiques générés sur l'appareil lui-même.

178
foundry

cette réponse est basée sur mon interprétation des liens de documentation ci-dessous

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

http://developer.Apple.com/library/ios/#documentation/CoreMotion/Reference/CMMagnetometerData_Class/Reference/Reference.html#//Apple_ref/doc/c_ref/CMMagnetometerData

a) CLHeading est " écart par rapport aux lignes de champ magnétique suivies par l'appareil" tandis que magnetometerData.magneticField "est le champ magnétique total observé par l'appareil qui est égal au champ géomagnétique de la Terre plus la polarisation introduite par l'appareil lui-même et ses environs ".

CLHeading vous donne donc des valeurs filtrées avec le référentiel étant le champ magnétique existant de la terre. Alors que magnetometerData vous donne des valeurs non filtrées avec le cadre de référence étant l'appareil.

b) si vous faisiez quelque chose avec un endroit où vous vouliez savoir où est magnétique ou le nord vrai, je recommanderais d'utiliser CLHeading. Si vous vouliez créer une application qui répond aux champs magnétiques dans les environs immédiats des appareils ou si vous aviez une fusion de capteur spécifique que vous vouliez effectuer, essayez par exemple de créer un AHRS, puis allez avec CMMagneticField.

1
Pete

Une chose importante à retenir lors de l'utilisation des valeurs CLHeading. [X | y | z] pour calculer la force du champ magnétique local est que la méthode CLLocationManagerDelegate

  • (BOOL) locationManagerShouldDisplayHeadingCalibration: (CLLocationManager *) gestionnaire

doit être réglé pour retourner OUI. J'ai constaté que les lectures du magnétomètre ne sont jamais étalonnées si cet avertissement d'étalonnage est désactivé, et qu'en conséquence la force de champ calculée est très instable lorsque l'orientation de l'appareil est modifiée.

1
millport

Je pense que le magnetometerData.magneticField vous indique l'accélération, pas la position (d'où la raison pour laquelle vous obtenez de grandes valeurs passant de fixe à mobile) tandis que le gestionnaire de localisation fournit des données sur la direction dans laquelle l'appareil pointe.

0
BanksySan