Перейти к содержимому

Фотография

Программирование на квадрокоптере AR.Drone


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 187

#81
erbol

erbol
  • Читатель
  • 361 сообщений
Благодаря использованию потоков и мьютексов можно реализовывать параллельное выполнение нескольких заданий.

Если программа реализована в одном потоке, то команды выполняются последовательно. В нашем случае робот должен одновременно выполнять несколько действий. Обрабатывать видео, получать и обрабатывать навигационные данные, выдавать команды моторам , еще должен быть канал для ручного управления роботом в случае нештатных ситуаций.

Потоки создают видимость параллельного (одновременного) выполнения нескольких действий. Дело в том что ОС создает очередь заданий к процессору и каждое из них получает свой квант времени процессора в порядке очереди.

Дал роботу простое задание - взлететь , 10 секунд висеть и посадка. Для реализации задания создал новый поток и новый метод который выполняется потоком.

Проект Puku имеет в своем составе два файла. ardrone.h и command.cpp. Создаем описание переменной потока и метода для выполнения задания


pthread_t *threadCommand1;
virtual void loopCommand2(void);

static void *runCommand1(void *args) {
reinterpret_cast(args)->loopCommand2();
return NULL;
}

В файл command.cpp добавляем такой код



void ARDrone::setL(void)
{
// Create a thread
threadCommand1 = new pthread_t;
if (pthread_create(threadCommand1, NULL, runCommand1, this) != 0) {
CVDRONE_ERROR("pthread_create() was failed. (%s, %d)\n", __FILE__, __LINE__);

}

}



void ARDrone::loopCommand2(void)
{
takeoff();
msleep(10000);
landing();

}

В файл main.cpp добавляем инструкцию для вызова метода setL()

Сообщение отредактировал erbol: 10.05.2013, 08:22:03


#82
erbol

erbol
  • Читатель
  • 361 сообщений
Вот метод класса который дает несколько последовательных команд

1. Взлет
2. Висим неподвижно некоторое время
3. Вращение
4. Снова висим
5. Вращение в другую сторону.
6. Висим
7. Посадка


void ARDrone::loopCommand3(void)
{
takeoff();
msleep(5000);
    double vx = 0.0, vy = 0.0, vz = 0.0, vr = 1.0;
    move3D(vx, vy, vz, vr);
msleep(10000);
vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
    move3D(vx, vy, vz, vr);
msleep(5000);
vx = 0.0, vy = 0.0, vz = 0.0, vr = -1.0;
    move3D(vx, vy, vz, vr);
msleep(10000);
vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
    move3D(vx, vy, vz, vr);
msleep(5000);
landing();
}



#83
erbol

erbol
  • Читатель
  • 361 сообщений
Я заметил, что когда drone висит над ковром , в квартире, он неправильно показывает высоту, со временем как будто высота растет. хотя на самом деле он опускается.

У меня при маневрировании даже до 4 метров показывала программа высоту, хотя на самом деле он на высоте полметра находился.

#84
erbol

erbol
  • Читатель
  • 361 сообщений
Алгоритм поворота вокруг вертикальной оси

Шкала углов в данном случае состоит из двух равных по величине диапазонов. Нулю соответствует направление на север. В направлении против часовой стрелки от нуля значения растут от нуля до 180 градусов. Это первый диапазон. 180 градусам соответствует направление на юг

В точке соответствующей направлению на юг угол шкала углов имеет два значения - плюс/минус 180 градусов. Второй начинается со значения минус 180 градусов и растет до нуля. Нуль - направление на север.

Для того чтобы повернуться на заданный угол нужно

1. Измерить текущий (начальный) угол.
2. Вычислить конечный угол. Он равен сумме начального угла и заданного угла поворота
3. Начать поворот и в процессе сравнивать текущий угол и конечный




void ARDrone::loopCommand5(void)
{

double fi0, fi1, fi, fi_t, fi_t1;
fi = 90; // угол поворота
fi0 = getYaw()*RAD_TO_DEG; // начальный угол
fi1 = fi0 + fi; // конечный угол
double vx = 0.0, vy = 0.0, vz = 0.0, vr = 1.0;
boolean flag = false;

while (!GetAsyncKeyState(VK_ESCAPE)) {
move3D(vx, vy, vz, vr);

fi_t = getYaw()*RAD_TO_DEG; // текущий угол
if (flag) fi_t = fi_t + 360;
if (fi_t != fi_t1) {

if (fi_t < fi_t1) {
fi_t = fi_t + 360;
flag = true;
}

//printf("fi_t = %3.2f\n", fi_t);

if (fi_t > fi1) {
break;
}
}
fi_t1 = fi_t;

cvWaitKey(1);
}
vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
move3D(vx, vy, vz, vr);
}



#85
erbol

erbol
  • Читатель
  • 361 сообщений
При повороте вокруг вертикальной оси возникает еще один интересный вопрос. Допустим надо нужно повернуть вертолет строго на юг. В этой точке как известно значения угла имеют разрыв в точке. Резко изменяются от 180 до минус 180 градусов.

Определимся с терминами , положительное направление это движение против часовой стрелки, если смотреть на вертолет сверху.

Навигационные данные с вертолета, в том числе значение угла поворота вокруг оси z мы получаем дискретно, в режиме demo примерно 20 раз в секунду.

Можно поставить такое условие для завершения поворота - если текущее значение больше нуля, поворачиваем в положительном направлении до тех пор пока текущее значение положительно, и наоборот , если текущее значение отрицательно, то поворачиваем в отрицательном направлении до тех пор пока оно не станет положительным

#86
erbol

erbol
  • Читатель
  • 361 сообщений
Программа для поворота в направление на север из произвольного положения


void ARDrone::loopCommand6(void)
{

double fi0, fi1, fi, fi_t, fi_t1;

fi0 = getYaw()*RAD_TO_DEG; // начальный угол
boolean flag = false;
double vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;

if (fi0 >= 0){
if (fi0==0) return;
vr = -1.0;
flag = false;
}
else
{
vr = 1.0;
flag = true;
}


while (!GetAsyncKeyState(VK_ESCAPE)) {
move3D(vx, vy, vz, vr);

fi_t = getYaw()*RAD_TO_DEG; // текущий угол
if (flag) {
if (fi_t >= 0) break;
}
else
{
if (fi_t <= 0) break;
}


cvWaitKey(1);
}
vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
move3D(vx, vy, vz, vr);
}


#87
erbol

erbol
  • Читатель
  • 361 сообщений
Подобрал значения HSV для желтого теннисного шарика. Эти значения конечно зависят от освещенности помещения.

Вечер, лампочка накаливания

H 0 - 15
S 110 - 145
V 105 - 200

HSV (англ. Hue, Saturation, Value — тон, насыщенность, значение) — цветовая модель, в которой координатами цвета являются:
* Hue — цветовой тон, (например, красный, зелёный или сине-голубой). Варьируется в пределах 0—360°, однако иногда приводится к диапазону 0—100 или 0—1.
* Saturation — насыщенность. Варьируется в пределах 0—100 или 0—1. Чем больше этот параметр, тем «чище» цвет, поэтому этот параметр иногда называют чистотой цвета. А чем ближе этот параметр к нулю, тем ближе цвет к нейтральному серому.
* Value (значение цвета) или Brightness — яркость. Также задаётся в пределах 0—100 и 0—1.

http://robocraft.ru/...vision/402.html

#88
erbol

erbol
  • Читатель
  • 361 сообщений
Алгоритм движения (поворота) вертолета за шариком

1. Находим ширину картинки получаемой с камеры вертолета
2. Находим положение центра шарика на картинке, если он найден при анализе
3. Находим расстояние между шариком и центром картинки
4. Если расстояние превышает четверть ширины картинки, то смещаем вертолет вслед за шариком

#89
erbol

erbol
  • Читатель
  • 361 сообщений
Вот такой код получился для того чтобы поморгать лампочками когда шарик отдаляется от центра картинки


    IplImage* image = ardrone.getImage();
// Находим ширину картинки
int w = (int) image->width/2;

    bool flag = true;
// Main loop
    while (!GetAsyncKeyState(VK_ESCAPE)) {

if (circles->total > 0)
{
float *p1 = (float*) cvGetSeqElem(circles, 0);
int a1 = cvRound(p1[0]);
int razn = abs(w-a1);

if (razn > w/4 && flag) {
ardrone.setLED(RED_SNAKE, 5.0, 2);
flag=false;
}
else
{
if (razn < w/4)flag=true;
}
}
}



#90
erbol

erbol
  • Читатель
  • 361 сообщений
Поворачивается вертолет за шариком.

Код такой


if (circles->total > 0)
{
float *p1 = (float*) cvGetSeqElem(circles, 0);
int a1 = cvRound(p1[0]);
int razn = abs(w-a1);

if (razn > w/4) {
if (a1-w > 0) {
vr = -1.0;
//printf("left\n");
}
else
{
vr = 1.0;
//printf("right\n");
}

}
else
{
vr = 0.0;
//printf("nothing\n");

}

}
else
{
vr = 0.0;
//printf("nothing\n");

}
ardrone.move3D(vx, vy, vz, vr);



#91
erbol

erbol
  • Читатель
  • 361 сообщений
Поэкспериментировал немного с разными шариками теннисными. У меня их три вида, по цвету.

Красный, белый и оранжевый. Из них наиболее четко детектируется цветовым фильтром HSV оранжевый шарик.

Это в дневное время. Вечером, при электрическом освещении детектирование ненадежное

В дневное время также есть ограничение. Шарик плохо детектируется на ярко освещенном фоне.

#92
erbol

erbol
  • Читатель
  • 361 сообщений
SLAM

http://www.mrpt.org/node/441

Предполагается , что карта статическая, то есть нет движущихся объектов в окружающем пространстве

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

Проблема состоит в способе нахождения расстояний между различными точками на карте и их правильном расположении на карте


В окружающем пространстве ищутся особенности разными способами. Самый простой пример особенностей – геометрические – углы, прямые.

На основе сопоставления нового набора особенностей с особенностями, полученными на предыдущем шаге можно определить как изменилось их расположение на сцене. Так как особенности сами по себе стационарны – очевидно что этот сдвиг – результат изменения положения камеры (робота). На основе этой информации можно выразить координаты камеры через систему линейных уравнений для решения которой используются различные методы и их комбинации

Обновление структуры (Features Integration) хранящей историю перемещений, где каждое состояние представляет собой глобальное положение робота и взаиморасположение обозреваемых особенностей на определенном промежутке времени. В последнее время кроме непосредственно данных о положении, хранятся также и вероятностные оценки для каждого значения. На данном этапе производится анализ и добавление полученных ранее данных в общую структуру для хранения информации о мире за все время исследования. Как правило, данные добавляются не на каждом шаге а при условии, что позиции робота(камеры) существенно изменилась – например, сдвиг или поворот по сравнению с предыдущей запомненной позицией составил более некоего граничного значения.

В нашем случае особенности это проемы, прямоугольной формы, расположенные на разной высоте, имеющие различные размеры и препятствия различной формы и расположенные на разной высоте

Коридоры все предполагаются прямоугольной формы, под углом в 90 градусов друг к другу.

http://my-it-notes.c...at-open-source/

#93
erbol

erbol
  • Читатель
  • 361 сообщений
Для контроля направления движения робот ar.drone имеет компас. Ошибка показаний компаса - шесть градусов. Немного , но в процессе движения ошибка может накапливаться.

Типа 6, 12, 18, 24 градусов отклонения от курса и так далее.

Нужен механизм для проверки показаний компаса. Для этого можно использовать картинки получаемые с вертолета.

Робот летит вдоль коридора и видит стенки. В случае если он летит вдоль коридора то видны три стенки, две боковые (продольно к движению) и дальняя (перпендикулярно движению). Каждая стенка имеет две границы на рисунке - верхнюю и нижнюю

Если углы одноименных (верхней или нижней ) границ боковых стенок имеют одинаковый угол к оси х, то робот летит перпендикулярно к дальней стенке коридора, то есть вдоль оси коридора. Зная угол между осью коридора и направлением на север, можно узнать истинное направление движения вертолета

Вот картинка тренировочного полигона для полетов роботов организаторов конкурса ( в Москве), компания Крок). С цветом стенок организаторы пока не определились. Сверху натянута сетка, чтобы роботы не улетали в космос.

Изображение

А вот эта картинка после обработки фильтром Гаусса и Кенни

Изображение

#94
erbol

erbol
  • Читатель
  • 361 сообщений
Познакомился с понятием "центральная проекция". В данном случае строится проекция прямоугольника на плоскость и лучи исходят из одной точки, точки наблюдателя.

http://stu.sernam.ru..._mod.php?id=107

В общем случае такая проекция будет иметь форму трапеции. Основание трапеции это ближняя к нам сторона прямоугольника, а вершина - дальняя сторона. Боковые стороны трапеции это стенки коридора.

Случай когда углы боковых сторон трапеции к основанию или вершине равны соответствует положению наблюдателя посередине основания трапеции.

Если еще и боковые стороны трапеции равны значит ось проекции перпендикулярна основанию и вершине трапеции

#95
erbol

erbol
  • Читатель
  • 361 сообщений
Миссия 1. Движение робота по линии

В качестве видеокамеры используем вертикальную (320*240 пикселей), угол обзора - 64 градуса, 60 кадров/секунду

Анализ картинок состоит в том что контролируется положение линии по центру. Если положение линии смещается от центра, корректируем положение вертолета

#96
erbol

erbol
  • Читатель
  • 361 сообщений
Поиск лиц на основе скрытых марковских моделей

http://habrahabr.ru/post/109956/

Скрытые Марковские модели в распознавании речи

http://habrahabr.ru/post/134954/

Скрытые Марковские модели

http://neerc.ifmo.ru...рковские_модели

http://ru.wikibooks....рковские_модели

Локализация и составление карты с помощью DP-SLAM

http://robot-develop.../3954#more-3954

#97
erbol

erbol
  • Читатель
  • 361 сообщений
Пусть мы движемся вдоль стенки коридора, горизонтальная камера перпендикулярна ей и наблюдаем точки (стабильные, хорошо различимые маркеры, типа кружки).

Надо нарисовать карту стены и определить свое положение по отношению к стене.

Изображение

Точки лежащие на одной линии смещаются на одинаковое расстояние при изменении позиции вертолета

Прямоугольником на рисунке обозначен вертолет. Он делает измерения (картинки) 3 раза. Треугольником обозначен угол зрения камеры вертолета. Кружки на рисунке - маркеры)

#98
erbol

erbol
  • Читатель
  • 361 сообщений
Бывает такое , пишешь сообщение на форум , включаешь в него код и коротко описываешь алгоритм, кажется что все понятно читателю и нет необходимости подробно описывать алгоритм (идею) кода

Через некоторое время читаешь свое сообщение и ничего не понимаешь. Вот такая вот польза от чтения своих прошлых сообщений. Приходится переписывать сообщение и более подробно описывать алгоритм кода

Сейчас пишу программу для вертолета чтобы он летал по квадрату и решил воспользоваться кодом для поворота на фиксированный угол

Алгоритм такой

Постановка: Допустим нужно повернуться справа-налево (против часовой стрелки) на определенный угол.

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

Такой способ работает если в процессе поворота не встретилась особая точка в которой угол поворота меняется скачком от плюс 180 до минус 180 градусов.

Что же делать если это случилось?

Допустим начальный угол равен 100 градусам, а повернуться надо на угол 90 градусов. Следуя нашему алгоритму складываем 100 и 90, получаем 190

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

Хотя это условие корректно с логической точки зрения при вращательном движении, в реальности, перед началом вращения, когда вертолет еще не среагировал на команду move3D(vx, vy, vz, vr), он будет шарахаться в разные стороны от своего начального направления в режиме hover (зависания в точке) и поэтому может случится, что условие будет выполнено в самом начале поворота и произойдет выход из цикла. Визуально это выглядит как микродерганье вертолета

Поэтому я использовал другое для установки флажка, который устанавливается в true при проходе "особой точки"

if (angle_current < 0 && angle_prev > 170) {
angle_current = angle_current + 360;
flag = true;
}

Это ключевое условие которое позволяет нам зафиксировать факт наличия "особой точки" в процессе измерения углов поворота и путем прибавления к измеренному отрицательному углу числа 360, получить положительное значение угла которое будет больше чем предыдущее значение

Зафиксировать наличие "особой точки" в программе можно с помощью логической переменной, которая будет менять свое значение если точка пройдена в процессе поворота. И далее для получения значения угла поворота к измеренному отрицательному значению будем прибавлять число 360

Сама процедура поворота на заданный угол выглядит следующим образом

// Поворот на заданный угол
void ARDrone::loopCommand5(void)
{

double angle_start, angle_finish, angle, angle_current, angle_prev;
angle = 90; // угол поворота
angle_start = getYaw()*RAD_TO_DEG; // начальный угол
angle_prev = angle_start;
angle_finish = angle_start + angle - 10; // конечный угол
double vx = 0.0, vy = 0.0, vz = 0.0, vr = 1.0;
boolean flag = false;

while (1) {


move3D(vx, vy, vz, vr);
angle_current = getYaw()*RAD_TO_DEG; // текущий угол
// если "особая точка" пройдена, то прибавляем к измеренному значению число 360
if (flag) angle_current = angle_current + 360;
// Если текущее и предыдущее значение углов не равны

if (angle_current != angle_prev) {

if (angle_current < 0 && angle_prev > 170) {
angle_current = angle_current + 360;
flag = true;
}

if (angle_current >= angle_finish) break;

}
angle_prev = angle_current;

msleep(1);
}
vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0;
move3D(vx, vy, vz, vr);
}

Еще нужно сделать такое замечание. Хотя повернуть в данном случае вертолет нужно на 90 градусов, формула для расчета конечного угла выглядит так

angle_finish = angle_start + angle - 10; // конечный угол

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

#99
erbol

erbol
  • Читатель
  • 361 сообщений
Comparision: Complementary Filters vs Kalman Filter vs Extended Kalman Filter



http://habrahabr.ru/post/118192/

#100
erbol

erbol
  • Читатель
  • 361 сообщений
http://we.easyelectr...y-i-otvety.html

Задача - повышения точности измерения нужных нам параметров за счет использования нескольких датчиков (или датчиков разного типа), называется «sensors fusion»

Итак, у нас есть MEMS гироскоп и акселерометр, и мы хотим максимально точно измерять углы крена и тангажа. Гироскоп довольно неплохо позволяет нам вычислить эти углы в краткосрочной перспективе, но со временем вычисленные показания уплывают. Акселерометр наоборот, дает нам весьма неточное и зашумленное измерение углов, но зато его показания не плывут со временем, ошибка большая, но она не накапливается.

Используя определенные алгоритмы, мы можем «объединить» показания этих датчиков, что даст нам более точное представление о реальных значениях углов.

Комплементарный фильтр.

http://we.easyelectr...rnyy-filtr.html

http://we.easyelectr...m-razgovor.html

http://habrahabr.ru/post/118192/

http://habrahabr.ru/post/118243/


Количество пользователей, читающих эту тему: 2

пользователей: 0, неизвестных прохожих: 2, скрытых пользователей: 0

Размещение рекламы на сайте     Предложения о сотрудничестве     Служба поддержки пользователей

© 2011-2022 vse.kz. При любом использовании материалов Форума ссылка на vse.kz обязательна.