середа, 30 листопада 2016 р.

Учусь программировать робота для хакатона

Некоторое время назад я записалась быть учителем на детских курсах по программированию. Поигрались мы со Скретчем , и учителя решили, что детки могут больше. Стали им давать HTML. Вот, кстати, презентация о табличках с заданием сделать открытку на праздники маме-папе. Детям всегда лучше давать то, что позволяет быстро увидеть результат. Когда ребенку можно показать, что методом малых усилий что-то меняется и это что-то ему нравится, то, значит, основное задание учителя выполнено. Когда ребенок придумал идею, хочет ее реализовать доступными методами, и попал при этом в тупик, тогда надо подсказывать. Идея будет расти, и сам ребенок будет двигаться к звездам. :)

Организаторы курсов предложили учителям провести детский хакатон, основная задача которого - собрать и запрограммировать робота. За основу взяли конструктор Lego Mindstorm EV3 45544 и бесплатную программу LEGO® MINDSTORMS® Education EV3 Teacher Edition для программирования на нем.


До того, как я сама попробовала что-то запрограммировать для робота, задача мне казалась нетривиальной. Когда же я увидела, что программирование осуществляется визуальными блоками, которые должны взаимодействовать между собой, мне подумалось, что дети справятся. Но стоило мне поставить перед собой цель запрограммировать прохождение роботом лабиринта, после того, как научила его идти прямо и в случае преграды поворачивать направо, я впала в ступор. Дело в том, что я привыкла к объектно-ориентированному языку программирования, а тут пишешь все в кучу и не знаешь, как поставить метку, чтобы перейти на тот или иной кусок программы в некий момент. Спустя несколько дней, за которые я робота даже не трогала, пришло вдохновение, и я поняла, что без методов и функций тоже можно сделать что-то толковое, и притом даже изящно.

Даже если у вас нет под рукой робота, могу предложить вам придумать собственный алгоритм для прохождения лабиринта, используя только:
  • датчик расстояния от робота до преграды, дающий на выходе количество сантиметров;
  • двигатель, которому можно задать направление движения, его мощность и продолжительность (измеряется либо в количестве секунд, либо в оборотах колеса, либо длится вечно, пока не выполнится некоторое условие по таймеру);
  • циклы;
  • операторы выбора (switches);
  • переменные;
  • математические операции.

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

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


Робот может находиться в четырех основных состояниях:
0: Движение прямо;
1: Поворот направо;
2: Поворот налево;
3: Разворот назад.

После пунктов 1-3 подразумевается движение прямо в случае отсутствия близкой преграды. Движение прямо выполняется, пока преграда не окажется на расстоянии менее 20 см. После каждого поворота в коде стоит switch, основанный на расстоянии до преграды. В нем переменная заполняется значением цифры, которая станет управляющей на следующей итерации.

Вы спросите, зачем же делать проверку при развороте назад? Программирование для робота сильно отличается от написания обычной программы, которая не будет обитать в случайно меняющейся среде и у которой есть физический облик. Случается, что перед роботом неожиданно вырастает преграда в виде маминой ноги или папиной руки, и роботу недостаточно места для разворота. В таких случаях ему лучше отъехать назад на расстояние, которого ему хватит для маневра. У меня это - один оборот колеса. Данное действие в случае необходимости выполняется перед входом в switch выбора направления движения и его реализации. Другая причина - робот разворачивается не одинаково точно в зависимости от поверхности, на которой он ездит: ковер и паркет дают разные результаты. Также на градусы поворота влияет мощность поворота и калибровка робота. Мне одолжили такой экземпляр, которому для поворота на 90° на мощности 50 из 100  пришлось прописать 400°.



Вроде бы, все основное рассказала. Смотрите саму программу.



На этом видео можно увидеть робота в действии.


Если смотреть внимательно, то видно, что робот ни разу не входит в состояние “3”. Посмотрите внимательно на картинку программы, и вы поймете причину. Предпоследний блок ссылается на “3”, если расстояние слишком мало, и на “0”, если места достаточно. Последний блок называется “4”, а блока “3” не существует. :) А в таком случае он по умолчанию идет в “0” (на switch рядом с нулем отмечена соответствующая радио-кнопка). Тут корректная работа алгоритма

Алгоритм вышел действенный и простой, но у него есть недостаток. Что случится, если отверстие, в которое нужно попасть, находится в середине стены? Например, робот идет по шляпке буквы Т, а выход - в ноге. Этот алгоритм ждет преграды, и в отверстие в стене сбоку без случайности не попадет. Иными словами, алгоритм хорош для прогулок по квартире или офису. А что, если имеем настоящий лабиринт?

Модернизацию выполнить не так сложно. Для этого необходимо дописать диагностику правой стены с некой частотой во время движения прямо. Почему только правой, а не двух? Потому что если окажется, что справа прохода нет, а слева есть, то когда робот обойдет все слева и не найдет выхода, он, вернувшись в исходное место, уже не будет знать, куда ему поворачивать, чтобы пройти по коридору дальше. Повернет он в стандартном направлении, которое будет противоположно тому, куда бы он повернул, если бы был открыт правый проход. То же самое на примере: робот шел по шляпке буквы Т справа налево и зашел в ножку, обошел ее и вернулся на перекресток, где есть дорога как вправо, так и влево. Следует помнить, что тут он уже был, и чтоб идти дальше, нужно повернуть налево. А такой алгоритм уже будет в разы сложнее.

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


  
К сожалению, робота мне пришлось отдать, и настоящий лабиринт для тестирования времени построить не хватило. Но с помощью метода “внезапного препятствия” можно увидеть, как работает робот.

От детей, понятное дело, требовать такой сложности еще рано. Дети хоть и заинтересованы, но им порой не хватает усидчивости, чтоб перебрать несколько вариантов того, как можно заставить программу работать. На хакатоне у детей вышло запрограммировать последовательности конкретных движений робота. Отступать они не догадались, циклы тоже не применили. Поэтому робот мог падать в результате сталкновений, поворачивать под неправильным углом, когда пытался развернуть стенку вместе с собой, и т. п.  Больше всего детям понравилось собирать конструктор лего. :) Возраст детей - от 10 до 14.

Другие задания, которые были на хакатоне:

  1. Собрать роборуку и ею поднимать бумажный стаканчик.
  2. Собрать и написать логику для принтера (двигать машинку так, чтоб она ездила по особой осмысленной траектории и рисовала прикрепленным к ней фломастером).
  3. Борьба роботов: 2 команды собирают по роботу и встраивают в них датчик касания, так что при нажатии на него робот “умирает”. Один робот должен атаковать другого и попасть в то самое место :)

Скоро будет новый хакатон. Взрослые будут учиться давать детям посильные интересные задачи, а дети - их выполнять. :)

Если у кого-нибудь есть соответствующий опыт или полезные советы, буду рада прочитать.