Инструменты пользователя

Инструменты сайта


lesson5

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

lesson5 [2020/02/27 15:58]
golikov
lesson5 [2020/03/25 16:28]
Строка 1: Строка 1:
-====== 05 Урок. Получение сырых данных с магнитометра. ====== 
- 
-===== Знакомство с магнитометром смартфона ===== 
-Почти в каждом современном смартфоне установлен магнитометр,​ давайте познакомимся с ним. Установите в смартфон приложение для визуализации данных,​ полученных со встроенного магнитометра,​ например,​ MagnetMeter. 
- 
-{{::​05image001.png?​nolink&​400|}} 
- 
-Откройте приложение – вы увидите синюю стрелку,​ которая показывает направление силовых линий магнитного поля. 
- 
-{{:​05image003.png?​nolink&​200|}} 
- 
-Вращайте смартфон и убедитесь,​ что магнитные линии направлены всегда в одну сторону – почти на север. ​ 
-На показания магнитометра кроме поля Земли влияют и другие магнитные поля. Убедитесь в этом приблизив магнит к смартфону. Перемещая магнит около смартфона определите точное место установки магнитометра в корпусе смартфона. 
- 
-{{::​05image004.png?​nolink&​200|}} 
- 
-Обратите внимание на величину напряженности магнитного поля Земли и поля вблизи магнита. 
- 
-===== Проверка работоспособности магнитометра Орбикрафт===== 
- 
-Соедините БКУ с СЭП и магнитометром. ​ 
- 
-Не прикрепляйте магнитометр к пластине,​ чтобы его было удобно вращать. Загрузите программу в БКУ и запустите ее. 
- 
-Код на Python. 
-<file python mag_test_2.py>​ 
- 
-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) 
-</​file>​ 
- 
-Код на С. 
-<file c mag_test_2.c>​ 
-#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);//​Выключение магнитометра 
-  
-} 
-</​file>​ 
- 
- 
-Запустите программу и посмотрите на значения,​ которые она выдает. Если магнитометр не вращать,​ то значения не изменяются. Если его вращать,​ то значения будут изменяться. ​ 
-Если вращать магнитометр вокруг одной из осей, то преимущественно будет изменяться одно из трех числовых значений,​ другие два будут изменяться в меньшей степени. 
-Поднесите к магнитометру магнит и посмотрите,​ как изменяются значения при движении магнита у неподвижного магнитометра. 
- 
-===== Получение азимута с магнитометра ===== 
- 
-Распечатайте транспортир (шаблон в файле Transportir.pdf),​ приклейте его к столу с помощью клеящих подушечек,​ не оставляющих следов (аналог UHU patafix), приклейте магнитометр на линейку аналогичным способом. 
- 
-{{::​05image005.png?​nolink&​200|}} 
- 
-Загрузите в БКУ следующую программу,​ которая произведет 60 измерений с шагом в 1 сек. ​ 
- 
- 
-Код на Python. 
-<file python azimuth.py>​ 
- 
-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) 
- 
-</​file>​ 
- 
-Код на С. 
-<file c azimuth.c>​ 
-#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);​ 
-} 
-</​file>​ 
- 
-Поворачивайте магнитометр с шагом в 30 градусов и записывайте выдаваемое значение угла в таблицу EXCEL. Должна получится примерно вот такая таблица с данными. 
- 
-{{:​05_image_101.png?​nolink&​200|}} 
- 
-===== Анализ данных в Excel ===== 
- 
-Обратите внимание,​ при повороте на 30 градусов значение угла, выдаваемое магнитометром изменяется не ровно на 30 градусов. Давайте вычислим эти значения средствами EXCEL. 
- 
-==== Создание таблицы ==== 
- 
-Создайте новый столбец,​ который будет содержать разность соседних чисел. Введите в пустую ячейку С2 знак равенства,​ а затем кликните мышкой в ячейку В1, введите знак «-», а затем кликните в ячейку В2 и нажмите Enter. 
- 
-{{::​05_image007.png?​nolink&​200|}} 
- 
-В ячейке С2 будет вычислена разность В1-В2. Протяните вниз уголок — формула автоматически скопируется во все нижние ячейки. ​ 
- 
-{{::​05_image008.png?​nolink&​200|}} 
- 
-Разности будут вычислены автоматически. 
- 
-{{::​05image009.png?​nolink&​200|}} 
- 
-Обратите внимание,​ значение -326 явно ошибочное. При переходе через значение 180 градусов изменился знак измеренного угла, следовательно вместо -326 нужно внести значение (180-155) сложенное со значением (180-171). Получится 25+9=34. Введите вместо -326 значение 34. 
- 
-==== Построение диаграмм ==== 
- 
-Теперь нужно построить график чтобы наглядно увидеть искажения,​ вносимые в измерение угла некалиброванным магнитометром. Выделите вычисленные значения разностей. 
- 
-{{::​05_image010.png?​nolink&​200|}} 
- 
-Нажмите **Вставка** и выберите круговую диаграмму. 
- 
-{{::​05image011.png?​nolink&​200|}} 
- 
-{{::​05image012.png?​nolink&​200|}} 
- 
-Кликните правой кнопкой мышки в цветной круг и выберите белый цвет заливки и черный цвет контура. 
- 
-{{::​05image014.png?​nolink&​200|}} 
- 
-{{::​05image015.png?​nolink&​200|}} 
- 
-Теперь невооруженным глазом видно, что магнитометр далек от идеала — сектора круга не ровно по 30 градусов. Некоторые уже, а некоторые шире. 
- 
-{{::​05_image016.png?​nolink&​200|}} 
- 
-Давайте построим еще один график,​ который наглядно проиллюстрирует неидеальность магнитометра. Выделите вычисленные значения разностей. 
-Нажмите **Вставка** и выберите лепестковую диаграмму. 
- 
-{{::​05image017.png?​nolink&​200|}} 
- 
-{{::​05image018.png?​nolink&​200|}} 
- 
-Теперь очень хорошо видно, что значения далеки от идеального 12 угольника радиусом 30. 
- 
- 
-{{:​2_1.gif?​direct|}} 
- 
-==== Анализ данных с помощью функций ==== 
- 
-А теперь давайте вычислим среднее значение разности между измеренными углами с использованием функции EXCEL СРЗНАЧ. 
-Выберите любую ячейку,​ введите знак равенства,​ имя функции и откройте скобку. 
- 
-{{::​05image019.png?​nolink&​200|}} 
- 
-Затем выберите мышкой диапазон вычисленных значение разностей,​ на основе которого мы строили диаграммы и закройте скобку. Функция будет иметь такой вид =СРЗНАЧ(C2:​C13). 
-Нажмите Enter, и функция вычислит среднее значение указанных чисел. 
-А теперь давайте вычислим стандартное отклонение вычисленных разностей от среднего значения,​ которое покажет величину разброса значений относительно среднего. Для этого используем функцию СТАНДОТКЛОНА. 
-Выберите любую ячейку,​ введите знак равенства,​ имя функции и откройте скобку. 
- 
- 
-{{::​05image020.png?​nolink&​200|}} 
- 
-Затем выберите мышкой диапазон вычисленных значение разностей,​ на основе которого мы строили диаграммы и закройте скобку. 
-Функция будет иметь такой вид =СТАНДОТКЛОНА(C2:​C13). 
-Нажмите Enter, и функция вычислит стандартное отклонение вычисленных разностей от среднего значения. 
-Теперь вычислите процентное соотношение среднего значения и стандартного отклонения. 
- 
- 
-{{::​05image021.png?​nolink&​200|}} 
- 
-{{::​05image022.png?​nolink&​200|}} 
- 
-Как видите,​ разброс очень велик и составляет 17% от среднего значения. 
-Магнитометр необходимо откалибровать. 
- 
-===== Получение сырых данных для калибровки магнитометра ===== 
- 
-По умолчанию магнитометр не откалиброван,​ т.е. выдает неточные значения. Уточненные значения можно получить из сырых данных путем калибровки,​ которая заключается в нахождении матрицы преобразования и вектора смещения. Сырые данные с магнитометра можно получить,​ выполнив код на языке Python, представленный ниже. Во время сбора данных магнитометр необходимо хаотично вращать,​ стараясь повернуть его во все возможные стороны. 
- 
-Код на Python. 
-<file python raw_data.py>​ 
- 
-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) #​Выключение магнитометра 
-</​file>​ 
- 
-Код на С. 
-<file c raw_data.c>​ 
-#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); ​ 
-} 
-</​file>​ 
- 
-Соедините БКУ с СЭП и магнитометром. Не прикрепляйте магнитометр к пластине,​ чтобы его было удобно вращать. Загрузите программу в Орбикрафт и запустите ее. Хаотично вращайте магнитометр,​ чтобы собрать сырые данные со всех возможных вариантов его ориентации. 
-Сохраните полученные данный в файл с расширением txt. Для этого выделите все результаты с помощью Ctrl+A и скопируйте с помощью Ctrl+C и сохраните. 
- 
-==== Анализ работы программы ==== 
- 
-В программе используются следующие функции работы с магнитометром. 
-<code python> magnetometer_turn_on(num) </​code>​ – функция включения магнитометра,​ где num – это номер магнитометра. 
- 
-<code python> magnetometer_request_raw(num) </​code>​ – функция возвращающая сырые данные измеренные магнитометром с номером num, представляющие собой список из 4 числовых значений. 
-Поэтому считанные данные мы помещаем в список mgn_result, состоящий из 4 значений. 
-mgn_result = [0,0,0,0] 
-<code c>​mgn_result = magnetometer_request_raw(num) </​code> ​ 
-Первое значение списка возвращает информацию об ошибке. Если возвращено значение 0,то ошибки нет, если 1, то датчик не соединен,​ если 2, то ошибка в программе. 
-В программе использован оператор цикла <code c>for (i = 0; i < 500; i++)</​code>​ который будет выполнен 500 раз, соответственно будет выведено 500 значений. 
-Эти значения понадобятся на следующем уроке при калибровке магнитометра. 
- 
- 
  
lesson5.txt · Последние изменения: 2020/03/25 16:28 (внешнее изменение)

Инструменты страницы