Для чего нужен ОрбиКрафт
Подсистемы конструктора
Инструкции по работе с ОрбиКрафт
Уроки
Лабораторная оснастка
Знакомство с Arduino
Полезная нагрузка на базе Arduino
Обратная связь
Новости
Для чего нужен ОрбиКрафт
Подсистемы конструктора
Инструкции по работе с ОрбиКрафт
Уроки
Лабораторная оснастка
Знакомство с Arduino
Полезная нагрузка на базе Arduino
Обратная связь
Новости
Почти в каждом современном смартфоне установлен магнитометр, давайте познакомимся с ним. Установите в смартфон приложение для визуализации данных, полученных со встроенного магнитометра, например, MagnetMeter.
Откройте приложение – вы увидите синюю стрелку, которая показывает направление силовых линий магнитного поля.
Вращайте смартфон и убедитесь, что магнитные линии направлены всегда в одну сторону – почти на север. На показания магнитометра кроме поля Земли влияют и другие магнитные поля. Убедитесь в этом приблизив магнит к смартфону. Перемещая магнит около смартфона определите точное место установки магнитометра в корпусе смартфона.
Обратите внимание на величину напряженности магнитного поля Земли и поля вблизи магнита.
Соедините БКУ с СЭП и магнитометром.
Не прикрепляйте магнитометр к пластине, чтобы его было удобно вращать. Загрузите программу в БКУ и запустите ее.
Код на Python.
def control(): # Основная функция программы, в которой нужно вызывать остальные функции mgn_result = [0,0,0,0] # Инициализируем mgn_result num = 1 print "Enable magnetometer №", num magnetometer_turn_on(num) sleep(1) print "Get RAW data from magnetometer" for i in range(1000): mgn_result = magnetometer_request_raw(num) if not mgn_result[0]: # если сообщение об ошибке, print mgn_result[1], mgn_result[2], mgn_result[3] elif mgn_result[0] == 1: print "Fail because of access error, check the connection" elif mgn_result[0] == 2: print "Fail because of interface error, check your code" sleep(0.1) print "Disable magnetometer №", num magnetometer_turn_off(num)
Код на С.
#include <stdio.h> #include <stdint.h> #include "libschsat.h" #define LSS_OK 0 #define LSS_ERROR 1 #define LSS_BREAK 2 void control(void) // Основная функция программы, в которой вызываем остальные функции { int16_t mgn_result[] = {0, 0, 0, 0}; //Инициализируем mgn_result uint16_t num = 1; //номер магнитометра printf("Enable magnetometer № %d", num); magnetometer_turn_on(num); //Включение магнитометр Sleep(1); printf("Get RAW data from magnetometer"); int i; for (i = 0; i < 10; i++) { mgn_result[0] = magnetometer_request_raw(num, &mgn_result[1], &mgn_result[2], &mgn_result[3]); if (!mgn_result[0]) //если датчик вернул сообщение об ошибке, { printf("state: %d\n", i); printf(" x_raw = %d\n", mgn_result[1]); printf(" y_raw = %d\n", mgn_result[2]); printf(" z_raw = %d\n", mgn_result[3]); } else if (mgn_result[0] == 1) { printf("Fail because of access error, check the connection"); } else if (mgn_result[0] == 2) { printf("Fail because of interface error, check your code"); } Sleep(1); } printf("Disable magnetometer №%d", num); magnetometer_turn_off(num);//Выключение магнитометра }
Запустите программу и посмотрите на значения, которые она выдает. Если магнитометр не вращать, то значения не изменяются. Если его вращать, то значения будут изменяться. Если вращать магнитометр вокруг одной из осей, то преимущественно будет изменяться одно из трех числовых значений, другие два будут изменяться в меньшей степени. Поднесите к магнитометру магнит и посмотрите, как изменяются значения при движении магнита у неподвижного магнитометра.
Распечатайте транспортир (шаблон в файле Transportir.pdf), приклейте его к столу с помощью клеящих подушечек, не оставляющих следов (аналог UHU patafix), приклейте магнитометр на линейку аналогичным способом.
Загрузите в БКУ следующую программу, которая произведет 60 измерений с шагом в 1 сек.
Код на Python.
import math time_step = 1 # Временной шаг измерений, сек mag_num = 1 # Номер магнитометра def control(): # основная функция программы print "Enable magnetometer", mag_num magnetometer_turn_on(mag_num) sleep(10) mag_state = 0 # Инициализируем статус магнитометра alpha_goal = 0 # Целевой угол omega_goal = 0 # Целевая угловая скорость for i in range(12): mag_state, magx_raw, magy_raw, magz_raw = magnetometer_request_raw(mag_num) # опрос магнитометра if not mag_state: # если код ошибки 0, то ошибки нет mag_alpha = math.atan2(magy_raw, magx_raw)/math.pi*180 print "mag_alpha atan2= ", mag_alpha elif mag_state == 1: print "Fail because of access error, check the connection" elif mag_state == 2: print "Fail because of interface error, check your code" sleep(time_step) print "Disable magnetometer", mag_num magnetometer_turn_off(mag_num)
Код на С.
#include <stdio.h> #include <stdint.h> #include "libschsat.h" #define LSS_OK 0 #define LSS_ERROR 1 #define LSS_BREAK 2 #include <math.h> void control(void){ int time_step = 10; uint16_t mag_num = 1; printf("Enable magnetometer %d\n", mag_num); magnetometer_turn_on(mag_num); Sleep(1); int mag_state = 0; int16_t p_dataX; int16_t p_dataY; int16_t p_dataZ; int16_t *pRAW_dataX = &p_dataX; int16_t *pRAW_dataY = &p_dataY; int16_t *pRAW_dataZ = &p_dataZ; int i; for (i = 0; i < 12; i++){ mag_state = magnetometer_request_raw(mag_num, pRAW_dataX, pRAW_dataY, pRAW_dataZ); float mag_alpha; if (!mag_state){ mag_alpha = atan2(p_dataY, p_dataX)/M_PI*180; printf("mag_alpha atan2 = %f\n", mag_alpha); } else if (mag_state == 1){ printf("Fail because of access error, check the connection\n"); } else if (mag_state == 2){ printf("Fail because of interface error, check your code\n"); } Sleep(time_step); } printf("Disable magnetometer %d\n", mag_num); magnetometer_turn_off(mag_num); }
Поворачивайте магнитометр с шагом в 30 градусов и записывайте выдаваемое значение угла в таблицу EXCEL. Должна получится примерно вот такая таблица с данными.
Обратите внимание, при повороте на 30 градусов значение угла, выдаваемое магнитометром изменяется не ровно на 30 градусов. Давайте вычислим эти значения средствами EXCEL.
Создайте новый столбец, который будет содержать разность соседних чисел. Введите в пустую ячейку С2 знак равенства, а затем кликните мышкой в ячейку В1, введите знак «-», а затем кликните в ячейку В2 и нажмите Enter.
В ячейке С2 будет вычислена разность В1-В2. Протяните вниз уголок — формула автоматически скопируется во все нижние ячейки.
Разности будут вычислены автоматически.
Обратите внимание, значение -326 явно ошибочное. При переходе через значение 180 градусов изменился знак измеренного угла, следовательно вместо -326 нужно внести значение (180-155) сложенное со значением (180-171). Получится 25+9=34. Введите вместо -326 значение 34.
Теперь нужно построить график чтобы наглядно увидеть искажения, вносимые в измерение угла некалиброванным магнитометром. Выделите вычисленные значения разностей.
Нажмите Вставка и выберите круговую диаграмму.
Кликните правой кнопкой мышки в цветной круг и выберите белый цвет заливки и черный цвет контура.
Теперь невооруженным глазом видно, что магнитометр далек от идеала — сектора круга не ровно по 30 градусов. Некоторые уже, а некоторые шире.
Давайте построим еще один график, который наглядно проиллюстрирует неидеальность магнитометра. Выделите вычисленные значения разностей. Нажмите Вставка и выберите лепестковую диаграмму.
Теперь очень хорошо видно, что значения далеки от идеального 12 угольника радиусом 30.
А теперь давайте вычислим среднее значение разности между измеренными углами с использованием функции EXCEL СРЗНАЧ. Выберите любую ячейку, введите знак равенства, имя функции и откройте скобку.
Затем выберите мышкой диапазон вычисленных значение разностей, на основе которого мы строили диаграммы и закройте скобку. Функция будет иметь такой вид =СРЗНАЧ(C2:C13). Нажмите Enter, и функция вычислит среднее значение указанных чисел. А теперь давайте вычислим стандартное отклонение вычисленных разностей от среднего значения, которое покажет величину разброса значений относительно среднего. Для этого используем функцию СТАНДОТКЛОНА. Выберите любую ячейку, введите знак равенства, имя функции и откройте скобку.
Затем выберите мышкой диапазон вычисленных значение разностей, на основе которого мы строили диаграммы и закройте скобку. Функция будет иметь такой вид =СТАНДОТКЛОНА(C2:C13). Нажмите Enter, и функция вычислит стандартное отклонение вычисленных разностей от среднего значения. Теперь вычислите процентное соотношение среднего значения и стандартного отклонения.
Как видите, разброс очень велик и составляет 17% от среднего значения. Магнитометр необходимо откалибровать.
По умолчанию магнитометр не откалиброван, т.е. выдает неточные значения. Уточненные значения можно получить из сырых данных путем калибровки, которая заключается в нахождении матрицы преобразования и вектора смещения. Сырые данные с магнитометра можно получить, выполнив код на языке Python, представленный ниже. Во время сбора данных магнитометр необходимо хаотично вращать, стараясь повернуть его во все возможные стороны.
Код на Python.
def control(): #Основная программы, в которой вызываем остальные функции mgn_result = [0,0,0,0] #Инициализируем mgn_result num = 1 magnetometer_turn_on(num) #Включаем магнитометр sleep(1) for i in range(500): #Выполним 500 измерений mgn_result = magnetometer_request_raw(num) if not mgn_result[0]: #Если датчик не вернул сообщение об ошибке print mgn_result[1], mgn_result[2], mgn_result[3] sleep(0.05) #Задержка пять сотых секунды magnetometer_turn_off(num) #Выключение магнитометра
Код на С.
#include <stdio.h> #include <stdint.h> #include "libschsat.h" #define LSS_OK 0 #define LSS_ERROR 1 #define LSS_BREAK 2 void control(void){ //Основная программа, в которой вызываем остальные функции /*Для вывода данных необходимость в объявлении массива отпадает*/ int16_t mgn_result[] = {0, 0, 0, 0}; //Инициализируем mgn_result uint16_t num = 1; magnetometer_turn_on(num); //Включаем магнитометр Sleep(1); int i; for (i = 0; i < 500; i++) //Выполним 500 измерений { mgn_result[0] = magnetometer_request_raw(num, &mgn_result[1],&mgn_result[2],&mgn_result[3]); if(!mgn_result[0]){ //Если датчик не вернул сообщение об ошибке printf("%d, %d, %d\n", mgn_result[1], mgn_result[2], mgn_result[3]); } Sleep(0.5); //Задержка пять сотых секунды } magnetometer_turn_off(num); }
Соедините БКУ с СЭП и магнитометром. Не прикрепляйте магнитометр к пластине, чтобы его было удобно вращать. Загрузите программу в Орбикрафт и запустите ее. Хаотично вращайте магнитометр, чтобы собрать сырые данные со всех возможных вариантов его ориентации. Сохраните полученные данный в файл с расширением txt. Для этого выделите все результаты с помощью Ctrl+A и скопируйте с помощью Ctrl+C и сохраните.
В программе используются следующие функции работы с магнитометром.
magnetometer_turn_on(num)
– функция включения магнитометра, где num – это номер магнитометра.
magnetometer_request_raw(num)
– функция возвращающая сырые данные измеренные магнитометром с номером num, представляющие собой список из 4 числовых значений. Поэтому считанные данные мы помещаем в список mgn_result, состоящий из 4 значений. mgn_result = [0,0,0,0]
mgn_result = magnetometer_request_raw(num)
Первое значение списка возвращает информацию об ошибке. Если возвращено значение 0,то ошибки нет, если 1, то датчик не соединен, если 2, то ошибка в программе. В программе использован оператор цикла
for (i = 0; i < 500; i++)
который будет выполнен 500 раз, соответственно будет выведено 500 значений. Эти значения понадобятся на следующем уроке при калибровке магнитометра.