В iOS, в чем разница между значениями магнитного поля от расположения ядра и рамок движения ядра?

у меня есть два способа получения магнитных полей (сила, x, y и z) с помощью магнитометра устройства iOS.

1) Ядра Месте
Используется CLHeading из CLLocationManagerDelegate метод locationManager:didUpdateHeading:. Это похоже на пример приложения Apple Teslameter.

2) Движение Ядра
Используется CMMagneticField С CMMotionManager ' s magnetometerData.magneticField.

вопросы:
а) в чем разница между ними? Я получаю разные ценности от обоих. Я ожидал, что они будут верните те же значения.
Разница наиболее заметна, когда я запускаю приложение из положения покоя (лицом вверх в таблице), а затем поднимаю устройство в воздух.
b) если есть разница, когда я должен использовать магнитное поле от курса местоположения ядра, и когда я должен использовать магнитное поле от движения ядра?

Примечание: я также не уверен, что "магнитное поле" расположения сердечника и движения сердечника относятся к различным концепциям магнитного поля.
Примечание: I вычисленная сила как квадратный корень из (x^2 + y^2 + z^2) для обоих подходов.

4 ответов


чтобы распутать это, я потратил слишком много времени, копаясь в документах Apple.

существует три способа получения данных магнитометра

1/ основные рамки движения
CMMagnetometer класс

2/ основы движения
CMDeviceMotion CMCalibratedMagneticField свойства

3 / основные рамки местоположения
Метод CLLocationManager по CLHeading

1/ поставляет "сырые" данные от магнитометра.
2/ и 3 / возвращают "производные" данные. Цифры в обоих случаях одинаковы (хотя и не совсем одинаковы).

разница между CMMagnetometer движения сердечника и CMCalibratedMagneticField

1/ и 2 / - оба из основных рамок движения-отличаются следующим образом:

Ссылка На Класс CMDeviceMotion

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField

Обсуждение
CMCalibratedMagneticField, возвращаемое этим свойством, дает общее магнитное поле в окрестности устройства без смещения устройства. В отличие от свойства magneticField класса CMMagnetometer, эти значения отражают магнитное поле Земли плюс окружающие поля, минус смещение устройства.

CMMagnetometer дает нам необработанные данные, CMCalibratedMagneticField отрегулированные данные.

разница между движением ядра CMCalibratedMagneticField и Clheading основного местоположения

документы не сразу ясны о разнице между 2/ и 3/, но они генерируют разные числа, поэтому давайте немного покопаемся....

основные рамки местоположения
CLHeading

С Руководство По Программированию Осведомленности О Местоположении

Получение Событий, Связанных С Заголовком

заголовок события доступны для приложений, работающих на устройстве, содержащем магнитометр. Магнитометр измеряет близлежащие магнитные поля, исходящие от Земли, и использует их для определения точной ориентации устройства. Хотя на магнитометр могут влиять локальные магнитные поля, такие как те, которые исходят от неподвижных магнитов, найденных в звуковых динамиках, двигателях и многих других типах электронных устройств, расположение сердечника достаточно умно, чтобы отфильтровать поля, которые перемещаются с помощью магнитных полей. устройство.

вот соответствующие CLHeading ' raw ' свойства

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

геомагнитные данные (измеренные в микротесласе) для оси [x|y|z]. (только для чтения)
Это значение представляет собой отклонение оси [x|y|z] от линий магнитного поля, отслеживаемых устройством. (старые версии документов добавить:) значение, сообщаемое этим свойством, нормализуется в диапазоне от -128 до +128.

I не ясно, как измерение microtesla может быть " нормализовано "(сжато? обрезан?) в диапазоне +/-128 и по-прежнему представляют устройства, утверждает измерить. Возможно, именно поэтому приговор был удален из документов. Устройства на iPad mini, похоже, соответствуют такому диапазону, но iPhone4S дает CMMagnetometer чтения в более высоких диапазонах, например 200-500.

API явно ожидает, что вы будете использовать производные свойства:

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

, которые дают стабильные показания компаса N/S E/W в градусах (0 = Север, 180 = Юг и т. д.). Для истинного курса требуются другие основные службы определения местоположения (геолокация) для получения отклонения магнитного поля от истинного Севера.

вот фрагмент файл

/*
 *  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.

основные рамки движения
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
Это структура, которая содержит вектор.
То же самое для CMDeviceMotionкалиброванное магнитное поле и 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.

разница между 2/ и 3 / намекаются здесь:

Расположенный CLHeading

представляет собой вектор, указывающий на магнитный север, построенный из значений компонентов оси x, y и z

Core Location достаточно умен, чтобы фильтр, что двигаться с устройством

Ядро Движения CMCalibratedMagneticField

[представляет] магнитное поле Земли плюс окрестные поля, без устройства смещения

So-согласно документам - у нас есть:

1/ CMMagnetometer
Сырые показания магнитометра

2/ CMDeviceMotion (CMCalibratedMagneticField*) magneticField
Показания магнитометра скорректированы на смещение прибора (бортовые магнитные поля)

3/ CLHeading [x|y / z]
Показания магнитометра скорректированы для смещения устройства и отфильтрованы для устранения локальных внешних магнитных полей (как обнаружено движением устройства-если поле перемещается вместе с устройством, игнорируйте его; в противном случае измерьте его)

проверка теории

enter image description here

Я поставил Магнит-O-метр демо-приложение на gitHub, который отображает некоторые из этих различий. Это довольно показательно, чтобы махать магнитом вокруг вашего устройства, когда приложение работает и наблюдает, как различные API реагируют:

CMMagnetometer не реагирует на что-либо, если вы притяните к себе редкоземельный Магнит. Бортовые магнитные поля кажутся гораздо более значимыми, чем локальные внешние поля или магнитное поле Земли. На моем iPhone 4S он последовательно указывает на нижнюю левую часть устройства; на iPad mini он обычно указывает на верхний правый.

CLHeading.[x / y/z] является наиболее уязвимым (реагирующим) на локальные внешние поля, будь то движущиеся или статические относительно устройства.

(CMDevice)CMCalibratedMagneticField является наиболее устойчивым перед лицом различных внешних полей, но в остальном отслеживает его основной аналог местоположения CLHeading.[x / y/z] довольно тесно.

CLHeading.magneticHeading - рекомендация Apple для чтения магнитного компаса-гораздо более стабильна, чем любая из них. Он использует данные от других датчиков для того чтобы стабилизировать данные по магнитометра. Но вы не получите raw разбивка x, y, z

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

желтое CMMagnetometer
зеленый CLHeading.[x / y/z]
синий CMCalibratedMagneticField
красный CLHeading.magneticHeading

это, похоже, противоречит документам, которые предполагают, что CLHeading.[x / y/z] должно меньше зависеть от локальных внешних полей, чем CMCalibratedMagneticField.

что подход вы должны принять? Основываясь на моем ограниченном тестировании, я бы предложил...
если вы хотите компаса
CLHeading это magneticHeading и trueHeading даст вам наиболее точное и стабильное чтение компаса.
Если вам нужно избежать основного местоположения
CMDeviceMotion это CMCalibratedMagneticField кажется следующим наиболее желательным, хотя значительно менее стабильным и точным, чем magneticHeading.
если вы заинтересованы в локальных магнитных поля
Свойства " raw " x y и z CLHeading кажутся более чувствительными к локальным магнитным полям.
если вы хотите все данные, включая бортовые магнитные поля
Необработанные данные магнитометра от CMMagnetometer. На самом деле нет смысла использовать это, если вы не готовы делать тонны фильтрации, так как на нее сильно влияют магнитные поля, генерируемые на самом устройстве.


этот ответ основан на моей интерпретации ссылок документации ниже

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

а) CLHeading это "отклонение от линий магнитного поля отслеживаемых прибором " пока магнитометердата.magneticField "является общее магнитное поле наблюдается устройством, равным геомагнитному полю Земли плюс смещение, введенное от самого устройства и его окружения".

таким образом, CLHeading дает вам отфильтрованные значения с рамки быть существующим магнитным полем Земли. Хотя magnetometerData дает вам нефильтрованные значения с рамки устройство.

b) если вы делали что-нибудь с местоположением, где вы хотели знать, где находится магнитный или истинный север, я бы рекомендовал использовать CLHeading. Если вы хотите создать приложение, которое реагирует на магнитные поля в непосредственной близости от устройств или у вас был какой-то конкретный датчик слияния вы хотели выполнить, возможно, попробуйте создать AHRS, например, затем пойти с CMMagneticField.


важно помнить при использовании CLHeading.[x|y|z] значения для расчета локальной напряженности магнитного поля заключается в том, что метод CLLocationManagerDelegate

  • (BOOL)locationManagerShouldDisplayHeadingcalibration: (CLLocationManager *)manager

должно быть установлено для возврата YES. Я обнаружил, что показания магнитометра никогда не калибруются, если это калибровочное предупреждение выключено, и что в результате вычисленная напряженность поля очень нестабильна при изменении ориентации устройства.


Я думаю, что magnetometerData.magneticField это говорит вам ускорение, а не положение (следовательно, почему вы получаете большие значения, движущиеся от неподвижного к движущемуся), тогда как менеджер местоположения предоставляет данные о направлении, в котором указывает устройство.