Полет по точкам, используя координаты из QR-кода

Прежде чем приступить к этому разделу, ознакомьтесь с основным разделом по этой теме:

Распознавание QR-кода с захватом одного кадра

Для начала выведем в терминал зашифрованный текст из QR-кода, для этого вставим в функцию распознавания QR-кода следующую строчку:

print(barcodes[0].data)

В результате получим:

В тексте зашифрованы числа, причем, имеются нецелые числа. Всего чисел 6. Для полета, к примеру, возьмем первые 3 числа: 2.5, 1.5, 1.

Все эти числа воспринимаются программой как строка (тип данных string). Нам для приведения их в координаты полета, необходимо преобразовать их в числа (тип данных int или float). Т.е. сделать простое преобразование строки в число.

Про преобразование строки в числа можно почитать здесь: https://otus.ru/nest/post/993/

Добавим следующие строчки:

coord=barcodes[0].data 
result=list(map(float, coord.split()))
print(result)

Введу пояснение по каждой их этих строчек:

coord=barcodes[0].data - создаем переменную coord, в которую поместим строку текста, расшифрованного QR-кода

result=list(map(float, coord.split())) - преобразуем все элементы строки (coord) в вещественный тип данных (float), создадим массив (list) на основе преобразованных данных и разделим их запятыми (.split)

print(result) - выведем в терминал, получившийся массив

код целиком выглядит следующим образом:

В результате получим:

В данном сообщение сказано, что индекс массива coord выходит за его пределы, т.е. камера не может определить элемент barcodes[0].data. Это означает, что мы не распознали qr-код. Ошибка возникает по многим причинам, вот несколько из них:

  1. Большое значение высоты полета - коптер не видит qr-код

  2. Коптер "висит" не по центру qr кода

  3. Мы допустили ошибку в коде

Чтобы исключить эту проблему добавим в наш код конструкцию try except. Она позволит не прерывать код при появлении ошибки в коде. В блок try добавим строчку вызова функции распознавания qr кода, ведь именно там появляется ошибка. В блок except добавим команды, которые необходимо выполнить в случае ошибки. Наш код примет вид:

Подробнее про конструкцию try except читай здесь: https://pythonworld.ru/tipy-dannyx-v-python/isklyucheniya-v-python-konstrukciya-try-except-dlya-obrabotki-isklyuchenij.html

Запускаем программу:

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

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

Поясню некоторые изменения в этой программе. Сначала мы добавили булеву переменную с именем flag. Булева переменная может принимать только 2 значения: True или False (правда или ложь). Изначально зададим ей значение ложь (False).

flag=False

Эта переменная будет служить флагом (отсечкой), если мы распознаем Qr-код, тогда flag примет значение True (правда) и цикл прекратиться и программа закончиться. Сделаем эту переменную глобальной. Таким образом, мы сможем пользоваться переменой во всем коде.

global flag

Как только функция распознавания QR кода будет выполнена - мы ставим значение переменной flag - True.

flag=True

Теперь в самом низу создадим две переменных n и a.

n=100
a=0

Переменная n определяет количество повторений цикла. Переменная a обозначает значение высоты, на которое необходимо опуститься. Далее идет цикл while c условием пока n больше 0.

while n>0:

Это означает, что когда переменная n станет равной 0 или меньше, тогда цикл прекратится. На каждой итерации цикла мы будем опускаться на 0.1 м вниз, т.е. увеличивать значение переменной a на 0.1. Напомню, что переменная a означает общую величину, на которую необходимо опуститься на каждой итерации цикла. Также на каждой итерации цикла будем вычитать единицу из переменной n, создавая при этом счетчик итераций цикла.

a+=0.1
n-=1

В цикл добавим функцию полета, в которой параметр высоты (z) будет меняться после каждой итерации, а именно, уменьшаться на 0.1 метра.

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

Подробнее про конструкцию try except можно почитать по ссылке: https://pythonworld.ru/tipy-dannyx-v-python/isklyucheniya-v-python-konstrukciya-try-except-dlya-obrabotki-isklyuchenij.html

try:
    image_callback()
except IndexError:
    a+=0.1
    print('Opuskaus')
    n-=1
    if flag==True:
        n=0
    
    

Таким образом, коптер пытается выполнить функцию распознавания QR кода (image_callback()), если есть ошибка, связанная с индексом массива (такая ошибка появляется, если QR-код не получилось распознавать), тогда код выполняет блок except, а именно, изменить значения переменных a и n, печатаем сообщение в терминал "Опускаюсь" (Opuskaus), если значение переменной flag равно True (оно будет равно такому значению только тогда, когда будет распознан QR код) мы приравняем переменную n к нулю, тем самым нарушим условия цикла while и выйдем из цикла и из всей программы.

Запустим наш код и получим наш заветный массив:

В этом массиве 6 элементов. Напомню, что нумерация этих элементов начинается с нуля.

Теперь добавим в функцию распознавания QR кода (image_callback()) функцию полета, где в качестве координат полета будут указаны элементы полученного ранее массива:

navigate(x=result[0], y=result[1], z=1, speed=0.5, frame_id='aruco_map')

Итоговый код приведен ниже:

ЗАДАНИЯ НА САМОСТОЯТЕЛЬНУЮ РАБОТУ:

  1. Измените код, чтобы появился топик в web-сервисе

  2. Измените код, чтобы после распознавания QR кода, квадрокоптер выполнил фигуру в виде многоугольника. Координаты необходимо использовать из массива.

Last updated