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


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

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

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

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

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

4 57

4 ответа:

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

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

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

2 / Core Motion framework
CMDeviceMotionCMCalibratedMagneticField свойства

3 / Core Location framework
Метод CLLocationManager по CLHeading

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

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

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

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

@property(readonly, nonatomic) CMCalibratedMagneticField magneticField

Обсуждение
CMCalibratedMagneticField, возвращаемый этим свойством, дает вам полное магнитное поле в окрестности устройства без смещения устройства. В отличие от свойства магнитного поля класса 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 не ясно, как измерение микротеслы может быть "нормализовано" (сжато? подрезали?) в диапазоне + / -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

расположение ядра достаточно умно, чтобы отфильтровать поля, которые перемещаются вместе с устройством

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

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

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

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 для чтения магнитного компаса-гораздо более стабильна, чем любой из них. Он использует данные от других датчиков для стабилизации данных магнитометра. Но вы не получите сырой разбивка 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.
если вы заинтересованы в локальных магнитных поля
"Сырые" свойства 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 это "отклонение от линий магнитного поля отслеживаемых прибором " пока магнитометердата.магнитное поле " - это общее магнитное поле наблюдаемый прибором, который равен геомагнитному полю Земли плюс смещение, вносимое самим прибором и его окружением".

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

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

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

  • (BOOL)locationManagerShouldDisplayHeadingcalibration: (CLLocationManager *)manager

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

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