Калибровка магнитометра NOVOTEST МФ-1 осуществляется в аккредитованной лаборатории РЦСМ и занимает от 1 до 5 дней.
Магнитометр NOVOTEST МФ-1 предназначен для оперативного неразрушающего контроля следующих материалов и параметров:
В комплект модели портативного магнитометра (тесламетра) NOVOTEST МФ-1 входит также датчик Холла для осуществления измерений магнитной индукции с отображением в таких единицах измерения как Гаусс, Тесла, Ампер/метр (А/м).
Кроме того, с помощью данного прибора можно проводить замеры постоянных полей. Измерение импульсных и переменных полей производится по специальному заказу.
Составные части прибора – это электронный блок и разнообразные съемные датчики (радиальные, аксиальные, специализированные). Магнитометра работает от обычных батареек или аккумуляторов типа ААА.
Магнитометр (тесламетр) NOVOTEST МФ-1 также используется для обнаружения различных несанкционированных вмешательств в работу разных приборов контроля и учета (счетчики электрической энергии). Это происходит благодаря установке магнитов для остановки счетчиков:
Главная страница-Персональные страницы-Коновалов Дмитрий Александрович
| ||
Мой первый контакт с цифровым магнитометром датируется летом 2009 года. В то время, как многие arduinoers , меня больше заботило кодирование Драйвер I2C/SPI, кроме понимания самого устройства. Через несколько месяцев я получил iPhone 4 и понял, что приложение компаса, которое использовало внутренний магнитометр телефона, требующий калибровки каждый раз, когда его приходилось использовать. И так, мне стало интересно, зачем нужен был этот шаг и как его можно сделанный. В этом посте я попытаюсь объяснить, вместе с практическим примером, способ сделать это. По сути, это метод, описанный здесь, но с некоторыми другими подробности и ссылки.
Прежде чем мы начнем, важно прояснить несколько понятий. Это кажется логичным что нам необходимо иметь общее представление о магнитном поле Земли, поскольку оно что мы хотим измерить. Кроме того, базовые знания о квадриках (например, сферах или эллипсоиды) окажутся важными. Может показаться неудобным говорить о квадрики тут, но быстро будет смысл.
В любом месте на Земле магнитное поле можно локально представить как постоянный трехмерный вектор (\(\mathbf{h}_0\)). Этот вектор может быть характеризуется тремя свойствами. Во-первых, интенсивность или величина (\(\mathcal{F}\)), обычно измеряется в нанотеслах (нТл) с приблизительным диапазон от 25000 нТл до 65000 нТл. Во-вторых, наклон (\(\mathcal{I}\)), с отрицательные значения (до -90°), если направлены вверх, и положительные (до 90°), если указывая вниз. В-третьих, склонение (\(\mathcal{D}\)), которое измеряет отклонение поля относительно географического севера и положительна на восток.
Система отсчета магнитного поля. Источник: Wikimedia CommonsИспользуя систему отсчета на рисунке выше, магнитное поле Земли вектор \(\mathbf{h}_0\) можно записать как:
\[\mathbf{h}_0 = \mathcal{F} \begin{bmatrix} \cos{(\mathcal{I})} \cos{(\mathcal{D})} \\ \cos{(\mathcal{I})} \sin{(\mathcal{D})} \\ \sin{(\mathcal{I})} \end{bматрица}. \метка{eq_h0} \тег{1}\]Учитывая географическую точку WMM модель можно использовать для получения ожидаемые значения для \(\mathcal{F}\), \(\mathcal{I}\) и \(\mathcal{D}\). Магнитное склонение особенно полезно для расчета географический север в компасе. 9Т\]
и \(\mathbf{M}\), \(\mathbf{n}\) соответственно:
\[\mathbf{M} = \begin{bmatrix} а&ч&г \\ ч & б & ж \\ г и е и в \end{bmatrix}, ~~ \mathbf{n} = \begin{bmatrix} п \\ д \\ р \end{bmatrix}.\]Сфера радиуса 1 с центром в начале координат определяется:
\[\mathbf{M} = \begin{bmatrix} 1 и 0 и 0 \\ 0 и 1 и 0 \\ 0 и 0 и 1 \end{bmatrix}, ~~ \mathbf{n} = \begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix} ~ \текст{и} ~ д=-1.\] 9т и д \конец{массив} \верно].\]Тип квадрики определяется некоторыми свойствами матриц \(\mathbf{M}\) и \(\mathbf{Q}\) как подробно здесь.
Сначала предположим, что мы находимся в среде, свободной от магнитных возмущений. и что у нас есть идеальный 3-осевой магнитометр. В этих условиях а показания магнитометра \(\mathbf{h}\), взятые с произвольной ориентацией, будут предоставлено:
\[\mathbf{h} = \mathbf{R}_x(\phi) \mathbf{R}_y(\theta) \mathbf{R}_z(\varphi) \mathbf{h}_0, \метка{eq_h} \тег{4}\] 92. \метка{eq_h_const} \тег{5}\]Такой взгляд на образцы магнитометра дает нам геометрическую перспектива проблемы. Расчетный пример показан в интерактивном сюжет найден ниже.
Ожидаемые образцы 3-осевого магнитометра вокруг Ирвина, Калифорния, к дате написанияВ реальной жизни нет ничего идеального, и окружающая среда не свободна от помех. Как подробно в этой публикации, существует две основные категории источников искажений измерений: ошибок и магнитных помех. В следующих разделах они будут кратко описан, заканчивая моделью измерения.
Инструментальные ошибки уникальны и постоянны для каждого устройства. Они могут быть моделируется в результате трех компонентов. T. \тег{9} $$ Мягкое железо обусловлено взаимодействием внешнего магнитного поля с ферромагнитные материалы, вызывающие изменение интенсивности и направления воспринимаемое поле. Его можно смоделировать как: $$ \mathbf{A}_{si} = \begin{bmatrix} а_{11} и а_{12} и а_{13} \\ а_{12} и а_{22} и а_{23} \\ а_{31} и а_{32} и а_{33} \end{bmatrix} \метка{eq_si} \тег{10} $$
Вам может быть полезно прочитать это приложение примечание, где обсуждается, какие элементы на печатной плате могут вызвать магнитное поле. вмешательство.
Схематическое изображение каждой магнитной помехи (-)После детализации каждого источника искажения мы можем легко записать измерение модель. Все источники искажений, описанные в \(\eqref{eq_s}-\eqref{eq_si}\) можно объединить, чтобы выразить измеренное магнитное поле \(\mathbf{h}_m\) как:
\[\mathbf{h}_m = \mathbf{SN}(\mathbf{A}_{si}\mathbf{h} + \mathbf{b}_{hi}) + \mathbf{b}_{так} \label{eq_h_meas_ns} \тег{11}\], где \(\mathbf{h}\) — истинное магнитное поле, определяемое как \(\eqref{eq_h}\). Это Здесь стоит отметить, что наша модель измерения не включает никаких стохастический шум. Это в некотором роде нереально, однако упрощает подход к решению за счет слегка предвзятого решения (при условии небольшого амплитудный шум). Вы можете использовать метод, описанный в этом бумага для расширить наше решение, включив шум.
Термины группировки \(\eqref{eq_h_meas_ns}\) можно переписать как:
\[\mathbf{h}_m = \mathbf{A}\mathbf{h} + \mathbf{b} \label{eq_h_meas} \тег{12}\]где:
\[\начать{матрицу} \mathbf{A} = \mathbf{СНС}_{si} \\ \mathbf{b} = \mathbf{SNb}_{привет} + \mathbf{b}_{so}. \конец{матрица}\]\(\mathbf{A}\) — это матрица, объединяющая масштабные коэффициенты, смещения и мягкое железо. эффекты, а \(\mathbf{b}\) — комбинированный вектор смещения. Можно доказать, что линейное преобразование \(\mathbf{h}\) в \(\eqref{eq_h_meas}\) делает измерения \(\mathbf{h}_m\) лежат на эллипсоиде. Поэтому мы увидим в следующий раздел, который процесс калибровки сводится к подгонке эллипсоида проблема. 92. \метка{eq_cal_d} \тег{15c}\]
Как мы отмечали в предыдущем разделе, наша квадратичная поверхность будет эллипсоидом. Таким образом, нам нужно использовать алгоритм подгонки эллипсоида, который дает нам оценки параметров квадратичной поверхности, \(\mathbf{\hat{M}}\), \(\mathbf{\шляпа{n}}\) и \(\шляпа{d}\). Было разработано множество алгоритмов для подогнать набор точек к поверхности эллипсоида. Мы будем использовать метод подгонки LS описано в этом статья К. Ли и другие. Этот метод прост в реализации, также существует версия для MATLAB. легко доступный. Несмотря на то, что он представлен как итерационный метод, одношаговой подгонки достаточно, если точки хорошо описывают эллипсоид (что и будет нашим случаем). Кроме того, это показал, что он достаточно хорошо работает при низком уровне шума. 9{-1}\). Это сделает калиброванная сфера имеет радиус \(\mathcal{F}\). Однако во многих приложениях например, в оценке отношения, величина не имеет значения. Если это твой случае, вы можете сделать его одним или любым другим удобным значением.
Чтобы завершить этот раздел, предлагаемый код для выполнения калибровки показано ниже. Он использует Numpy и SciPy для числовых расчетов, а также датчик класс подробно описан в следующем разделе.
система импорта импортировать numpy как np из scipy import linalg класс Магнитометр (объект): ''' Класс магнитометра с возможностью калибровки. Параметры ---------- датчик: ул. Датчик для использования. автобус: внутр. Шина, на которой установлен датчик. F : плавающая (необязательно) Ожидаемая напряженность магнитного поля Земли, по умолчанию = 1. ''' # доступные датчики _sensors = {'ak8975c': Датчик AK8975C} def __init__(я, датчик, шина, F=1.): # датчик если датчик не в себе._sensors: поднять NotImplementedError («Датчик %s недоступен» % сенсор) self.sensor = self._sensors[датчик](шина) # инициализировать значения сам. F = F self.b = np.zeros ([3, 1]) self.A_1 = np.eye(3) деф читать (сам): '''Возьмите образец. Возвращает ------- с: список Образец в uT, [x,y,z] (исправлено, если выполнена калибровка). ''' s = np.array(self.sensor.read()).reshape(3, 1) s = np.dot(self.A_1, s - self.b) вернуть [с[0,0], с[1,0], с[2,0]] калибровка по определению (само): ''' Выполняет калибровку. ''' print('Сбор образцов (Ctrl-C, чтобы остановить и выполнить калибровку)') пытаться: с = [] п = 0 пока верно: s.append(self.sensor.read()) п += 1 sys.stdout.write('\rВсего: %d' % n) sys.stdout.flush() кроме KeyboardInterrupt: проходить # эллипсоид подходит s = np.массив(ы).T M, n, d = self.__ellipsoid_fit(s) # параметры калибровки # примечание: некоторые реализации sqrtm возвращают сложный тип, принимая реальный M_1 = linalg. inv(M) self.b = -np.dot (M_1, n) self.A_1 = np.real (self.F / np.sqrt (np.dot (nT, np.dot (M_1, n)) - d) * linalg.sqrtm(M)) def __ellipsoid_fit (я, с): ''' Оценить параметры эллипсоида по набору точек. Параметры ---------- s : массив_подобный Выборки (M,N), где M=3 (x,y,z) и N=количество выборок. Возвращает ------- M, n, d : array_like, array_like, float Параметры эллипсоида M, n, d. Рекомендации ---------- .. [1] Циндэ Ли; Гриффитс, Дж. Г., "Специфика эллипсоида наименьших квадратов. подгонка», в журнале «Геометрическое моделирование и обработка», 2004 г. Труды, т., №, стр. 335-340, 2004 г. ''' № Д (образцы) D = np.array([s[0]**2., s[1]**2., s[2]**2., 2.*s[1]*s[2], 2.*s[0]*s[2], 2.*s[0]*s[1], 2.*s[0], 2. *s[1], 2.*s[2], np.ones_like(s[0])]) # S, S_11, S_12, S_21, S_22 (уравнение 11) S = np.dot (D, D.T) S_11 = S[:6,:6] S_12 = S[:6,6:] S_21 = S[6:,:6] S_22 = S[6:,6:] # C (уравнение 8, k=4) C = np.массив([[-1, 1, 1, 0, 0, 0], [1, -1, 1, 0, 0, 0], [1, 1, -1, 0, 0, 0], [0, 0, 0, -4, 0, 0], [0, 0, 0, 0, -4, 0], [ 0, 0, 0, 0, 0, -4]]) # v_1 (уравнение 15, решение) E = np.dot (linalg.inv (C), S_11 - np.dot (S_12, np.dot (linalg.inv (S_22), S_21))) E_w, E_v = np.linalg.eig(E) v_1 = E_v[:, np.argmax(E_w)] если v_1[0] < 0: v_1 = -v_1 # v_2 (уравнение 13, решение) v_2 = np.dot (np.dot (-np.linalg.inv (S_22), S_21), v_1) # параметры квадратичной формы M = np.массив([[v_1[0], v_1[3], v_1[4]], [v_1[3], v_1[1], v_1[5]], [v_1[4], v_1[5], v_1[2]]]) n = np. массив([[v_2[0]], [v_2[1]], [v_2[2]]]) д = v_2[3] возврат М, п, д
В заключение этого поста мы будем использовать образцы реального магнитометра, которые позволяют нам увидеть, ведет ли себя предлагаемое решение так, как ожидалось. Это важно обратите внимание, что мы не будем оценивать точность нашего решения, ни другие например, как количество выборок или их пространственное распределение влияет на калибровка. Это темы, которые потребуют дальнейшего изучения вне охват этого поста.
Выбранный магнитометр находится внутри Invensense.
МПУ-9150: АК8975С. Это модуль, который
также содержит акселерометр и гироскоп, не нужные для наших целей. А
Raspberry Pi 2 будет использоваться в качестве хост-платформы, как показано ниже. Это позволит
нам быстро закодировать доказательство концепции, используя всего несколько строк Python. Примечание
что вам нужно будет активировать драйвер I2C и установить python-smbus
на
Raspberry Pi (подробности)
здесь).
Предлагаемый код для привода AK8975C:
импорт smbus # МПУ9150 используемых регистров MPU9150_ADDR = 0x68 MPU9150_PWR_MGMT_1 = 0x6B MPU9150_INT_PIN_CFG = 0x37 MPU9150_INT_PIN_CFG_I2C_BYPASS_EN = 0x02 # AK8975C использует регистры AK8975C_ADDR = 0x0C AK8975C_ST1 = 0x02 AK8975C_ST1_DRDY = 0x01 AK8975C_HXL = 0x03 AK8975C_CNTL = 0x0A AK8975C_CNTL_SINGLE = 0x01 # преобразовать в s16 из дополнения до двух to_s16 = lambda n: n - 0x10000, если n > 0x7FFF, иначе n класс SensorAK8975С (объект): ''' AK8975C Простой драйвер. Параметры ---------- автобус: внутр. Номер шины I2C (например, 1). ''' # чувствительность сенсора (uT/LSB) _чувствительность = 0,3 def __init__(я, шина): self.bus = smbus.SMBus(автобус) # просыпаемся и устанавливаем байпас для AK8975C self.bus.write_byte_data (MPU9150_ADDR, MPU9150_PWR_MGMT_1, 0) self.bus.write_byte_data (MPU9150_ADDR, MPU9150_INT_PIN_CFG, MPU9150_INT_PIN_CFG_I2C_BYPASS_EN) защита __del__(я): self. bus.close () деф читать (сам): '''Возьмите образец. Возвращает ------- с: список Выборка в uT, [x, y, z]. ''' # запрос одиночного выстрела self.bus.write_byte_data (AK8975C_АДДР, AK8975C_CNTL, AK8975C_CNTL_SINGLE) # ждем готовности данных r = self.bus.read_byte_data (AK8975C_ADDR, AK8975C_ST1) пока нет (r&AK8975C_ST1_DRDY): r = self.bus.read_byte_data (AK8975C_ADDR, AK8975C_ST1) # читать x, y, z данные = self.bus.read_i2c_block_data (AK8975C_ADDR, AK8975C_HXL, 6) вернуть [self._sensitivity * to_s16 (данные [0] | (данные [1] << 8)), self._sensitivity * to_s16 (данные [2] | (данные [3] << 8)), self._sensitivity * to_s16(data[4] | (data[5] << 8))]
Объединение показанного выше драйвера датчика с кодом из предыдущего раздела приведет к позволяют нам как пробовать, так и калибровать. Мы также можем добавить код, показанный ниже, что позволит нам хранить некалиброванные и калиброванные образцы для последующего визуализировать результаты с любой графической библиотекой:
из времени импорта сна защита сбора (fn, fs = 10): ''' Соберите образцы магнитометра Параметры ---------- фн : ул Выходной файл. ФС : целое (необязательно) Приблизительная частота дискретизации (Гц), по умолчанию 10 Гц. ''' print('Сбор [%s]. Ctrl-C для завершения' % fn) с открытым (fn, 'w') как f: f.write('x,y,z\n') пытаться: пока верно: с = м.прочитать() f.write('%.1f,%.1f,%.1f\n' % (s[0], s[1], s[2])) сон(1./fs) кроме KeyboardInterrupt: пройти m = магнитометр ('ak8975в', 1, 46,85) собрать('ncal.csv') м. откалибровать () collect('cal.csv')
Реальные результаты отображаются на следующем интерактивном графике:
Образцы, взятые до и после калибровки, показаны вместе с эталонной сферой.
Магнитометры используются для измерения напряженности магнитного поля. Их также можно использовать для определения ориентации и компенсации дрейфа гироскопа. Магнитометр обеспечивает последние три степени свободы в 9Датчики глубины резкости.
Есть одна проблема, магнитометры склонны к искажениям.
Магнитное поле, используемое для определения курса, представляет собой магнитное поле Земли. Помимо земного существуют дополнительные магнитные поля, вызывающие помехи. Помехи могут быть вызваны ферромагнитным материалом или оборудованием, находящимся поблизости от магнитометров. Если магнитное поле является постоянным, его называют «твердым железом».
Например, у мобильного телефона есть динамик. Динамик постоянно подключен к телефону. Благодаря этому расположение и ориентация магнитного поля динамиков не меняется со временем. Для магнитометра внутри телефона динамик считается железным.
Смещение твердого железа хорошо тем, что его можно легко исправить. Искажение твердого железа всегда добавляется к магнитному полю Земли. Другими словами, показания датчика могут быть скорректированы, т.е. беспристрастный, просто удалив смещение. Псевдокод для удаления смещения будет примерно следующим.
offset_x = (макс.(х) + мин.(х)) / 2 offset_y = (макс.(у) + мин.(у)) / 2 offset_z = (макс.(z) + мин.(z))/2 исправлено_x = датчик_x - смещение_x исправленное_у = датчик_у - смещение_у corrected_z = sensor_z - offset_z
Искажение из мягкого железа является результатом материала, который искажает магнитное поле, но не обязательно сам создает магнитное поле. Например, железо (металл) будет генерировать искажение, но это искажение зависит от ориентации материала относительно магнитометра.
В отличие от искажения жесткого железа, искажение мягкого железа нельзя удалить, просто удалив постоянное смещение. Исправление искажения из мягкого железа обычно требует больших вычислительных затрат и требует матрицы преобразования 3x3.
Существует также более дешевый в вычислительном отношении способ — использование смещений масштаба, как объяснил Крис Винер. Этот метод также должен давать достаточно хорошие результаты. Приведенный ниже пример псевдокода также включает смещение жесткого железа по сравнению с предыдущим шагом.
avg_delta_x = (макс.(х) - мин.(х)) / 2 avg_delta_y = (макс.(у) - мин.(у)) / 2 avg_delta_z = (макс.(z) - мин.(z)) / 2 avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3 масштаб_x = средняя_дельта / средняя_дельта_x масштаб_у = средняя_дельта / средняя_дельта_у масштаб_z = средняя_дельта / средняя_дельта_z исправленное_x = (датчик_x - смещение_x) * масштаб_x исправленное_у = (датчик_у - смещение_у) * масштаб_у corrected_z = (sensor_z - offset_z) * scale_z
Визуализация данных помогает понять их. Это также помогает увидеть различия после калибровки. Для захвата я использовал M5Stack MPU9250 4MB, который, как следует из названия, имеет внутри датчик MPU-9250 9DOF.
MPU-9250 представляет собой систему в корпусе (SiP), которая объединяет два чипа: MPU-6500, который содержит 3-осевой гироскоп и 3-осевой акселерометр, и AK8963, который представляет собой 3-осевой цифровой компас.
Показания датчиков выводятся с помощью сценария MicroPython на последовательную консоль. Скрипт использует I2C MPU-9250 водитель. После запуска скрипта переместите датчик в виде большой восьмерки. В основном то же самое, что вы делали в детстве, играя с игрушечным самолетом. Датчик должен несколько раз повернуться вокруг осей X, Y и Z.
импортный микропитон импортировать ютайм из машинного импорта I2C, Pin, Timer из mpu9250 импортировать MPU9250 micropython.alloc_emergency_exception_buf(100) i2c = I2C (scl = контакт (22), sda = контакт (21)) датчик = MPU9250 (i2c) def read_sensor (таймер): значение = датчик. магнитный print(",".join(карта(ул, значение))) timer_0 = Таймер (0) timer_0.init (период = 500, режим = Timer.PERIODIC, обратный вызов = read_sensor)
Примерно через 1-2 минуты махания скопируйте показания датчика с консоли в CSV-файл. Назовем его magnetometer.csv
. Чем больше данных вы захватите, тем лучше.
Gnuplot — отличная кроссплатформенная графическая утилита командной строки. Это, вероятно, не нравится хипстерам. Там нет смайликов единорога и прочего. Тем не менее, он выполняет свою работу.
Если вы используете macOS, установите Gnuplot с Homebrew.
$ варить установить gnuplot --with-qt $ gnuplot
Сначала сообщите, что входной файл gnuplot будет файлом CSV.
gnuplot> установить разделитель файлов данных ","
Точечная диаграмма удобна для визуализации показаний магнитометра. Для трех осей нам нужны три отдельных графика.
В команде графика с использованием 1:2
указано, что значения для графика XY берутся из первого и второго столбца. XZ использует данные из первого и третьего столбца, таким образом, использует 1:3
. YZ построен с с использованием 2:3
, которые являются второй и третьей колонками.
gnuplot> график "magnetometer.csv" с использованием заголовка 1:2 "XY" размер точки 2 тип точки 7, \ "magnetometer.csv" с использованием заголовка 1:3 "XZ" размер точки 2 тип точки 7, \ "magnetometer.csv" с использованием заголовка 2:3 "YZ" размер точки 2 тип точки 7
В результате должны получиться три сферы одинакового размера с центром вокруг координат 0,0
. Вот что я получил.
Первый WTF момент. Графики не имеют никакого смысла. Затем я понял, что нижняя пластина M5Stack имеет магнит, который является примером помех из школьного учебника из твердого железа.
Новая попытка со снятой задней панелью.
Гораздо лучше, но все равно много искажений. Большим смещением по-прежнему является жесткая железная дисторсия. Скорее всего из-за динамика внутри M5Stack. Ниже приведена реализация удаления жесткого смещения железа в Python.
#!/usr/local/bin/python3 импортировать CSV импорт системы читатель = csv.reader(iter(sys.stdin.readline, ""), разделитель=",") данные = список (читатель) x = [float(row[0]) для строки в данных] y = [float(row[1]) для строки в данных] z = [float(row[2]) для строки в данных] offset_x = (макс.(х) + мин.(х))/2 offset_y = (макс.(у) + мин.(у)) / 2 offset_z = (макс.(z) + мин.(z))/2 для строки в данных: corrected_x = float (строка [0]) - offset_x corrected_y = float (строка [1]) - offset_y corrected_z = число с плавающей запятой (строка [2]) - offset_z print(",".join(format(value, ".15f") для значения в [corrected_x, corrected_y, corrected_z]))
Запустите скрипт, чтобы сгенерировать новый CSV-файл с исправленным железным искажением.
$ ./hardiron.py < магнитометр.csv > hardiron.csv
Постройте новый график, используя скорректированные значения.
gnuplot> построить "hardiron.csv" с использованием заголовка 1:2 "XY" размер точки 2 тип точки 7, \ "hardiron.csv" с использованием заголовка 1:3 "XZ" размер точки 2 тип точки 7, \ "hardiron.csv" с использованием заголовка 2:3 "YZ" размер точки 2 тип точки 7
Результат уже выглядит так, как должен выглядеть; три сферы с центром вокруг 0,0
. Все еще есть некоторые искажения, поэтому давайте посмотрим, что делает удаление мягкого железа.
#!/usr/local/bin/python3 импортировать CSV импорт системы читатель = csv.reader(iter(sys.stdin.readline, ""), разделитель=",") данные = список (читатель) x = [float(row[0]) для строки в данных] y = [float(row[1]) для строки в данных] z = [float(row[2]) для строки в данных] avg_delta_x = (макс.(х) - мин.(х))/2 avg_delta_y = (макс.(у) - мин.(у)) / 2 avg_delta_z = (макс.(z) - мин.(z)) / 2 avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3 масштаб_x = средняя_дельта / средняя_дельта_x масштаб_у = средняя_дельта / средняя_дельта_у масштаб_z = средняя_дельта / средняя_дельта_z для строки в данных: исправлено_x = число с плавающей запятой (строка [0]) * масштаб_x исправлено_y = число с плавающей запятой (строка [1]) * масштаб_x corrected_z = число с плавающей запятой (строка [2]) * масштаб_x print(",". join(format(value, ".15f") для значения в [corrected_x, corrected_y, corrected_z]))
Запустите этот сценарий, используя в качестве входных данных скорректированные значения жесткого железа.
$ ./softiron.py < hardiron.csv > softiron.csv
Снова постройте график.
gnuplot> построить "softiron.csv" с использованием заголовка 1:2 "XY" размер точки 2 тип точки 7, \ "softiron.csv" с использованием заголовка 1:3 "XZ" размер точки 2 тип точки 7, \ "softiron.csv" с использованием заголовка 2:3 "YZ" размер точки 2 тип точки 7
На первый взгляд разница не так уж и велика. Однако, если вы посмотрите ближе, точки создают немного лучшую форму сферы, чем раньше.
Простая и эффективная калибровка магнитометра Крис Винер, которая является основой для этого сообщения в блоге. Остальная вики тоже хороша для чтения.
Способ калибровки магнитометра от Teslabs для более глубокого погружения в математику.