Нет времени объяснять, сделай автопилот
Здравствуйте, товарищи!
На выходных проходил хакасборкатон — гонки на самоуправляемых моделях автомобилей на базе комплекта donkeycar при содействии Х5 и FLESS.
Задача заключалась в следующем: сначала надо было собрать машинку из запчастей, затем ее обучить проходить трассу. Победитель определялся по самому быстрому прохождению 3 кругов. За наезд на конус — дисквалификация.
Хотя подобная задача для машинного обучения не нова, но сложности могут поджидать на всем пути: от невозможности заставить нормально работать вайфай до нежелания обученной модели пилотировать железо по треку. И все это в жестких временных рамках!
Когда мы собирались на это соревнование, сразу было понятно, что будет очень весело и очень сложно, ведь нам давалось всего 5 часов с учётом перерыва на обед чтобы собрать машинку, записать датасет и обучить модель.
Ослик-машинка
Donkeycar состоит из корпуса, на который крепится камера с широкоугольным объективом (170 град), Raspberry Pi3+, платы управления сервоприводами, софт и вообщем-то всё. Но как оказалось впоследствии, сборка даже такого простого аппарата в условиях ограниченного времени и рандомных глюков оборудования может затянуться, и вы не успеете.
Сборка
Соревнование началось с того, что сначала надо было разобрать машинку и собрать её снова. Надо отдать должное организаторам, нам не предложили собирать непонятную кучу деталей с нуля, а дали возможность разобраться в устройстве на готовом примере. Мы сэкономили массу времени, сделав фотки всех соединений, и собрали машинку обратно минут за 10 =)
Подключение к машинке и проверка работы
После того, как мы собрали машинку, образовалась пауза, потому что нам надо было подключить машинку к вайфай и начать калибровку шасси. Как оказалась, работа с вайфаем в дальнейшем будет одной из самых больших проблем при работе с Raspberry, видимо надо было брать свой вайфай с антенной.
Мы решили не скучать и подключиться по Ethernet кабелю, который вместе с остальным барахлом всегда у меня валяется в рюкзаке. Почему-то на машинке то ли не было DHCP сервера, то ли он не работал, то ли вообще он там не должен был быть, и мы смекнули, что wireshark запросто достатнет source ip по broadcast при подключении кабеля к Raspberry. Так и получилось, но зайдя на машинку, мы потратили довольно много времени пытаясь заставить вайфай работать. В конечном итоге всем участникам скинули специальный файл, где находился конфиг.
Калибровка шасси и подключение джойстика
Подключение джойстика у нас заняло примерно 35 минут, пока мы читали доки и сканировали bluetooth, пытаясь сопрячь машинку и джойстик. Оказалось, что проблема в том, что в помещении было слишком много джойстиков и они случайным образом сопрягались с машинками коллег по гонкам — было очень весело обнаружить, что ты управляешь шасси случайной машинки =)
На следующем этапе требовалось откалибровать steering и throttle, то есть PWM на поворот и газ. Это был один из самых важных параметров, требовалось сделать так, чтобы значение соотносилось со скоростью движения машинки и модель справлялась с управлением.
На интуиции мы постарались сделать ускорение и поворот такими, чтобы машинка ехала достаточно быстро, но при этом могла быть управляема.
Сбор данных и обучение модели
До конца мероприятия уже оставалось всего около 2-х часов с учётом выступления команд, и надо было срочно ускоряться. Мы побежали записывать данные с мыслью о том, что необходимо создать как можно более разнообразные условия, в которых будет пребывать машинка. Мы предположили, что когда начнутся соревнования, скорее всего переставят свет, рядом с трассой появятся посторонние предметы и т.д.
Мы записали порядка 18 тыс картинок вместе со значениями газа и поворота, стараясь, чтобы в кадр попадало много людей, мы бегали вокруг трассы, прыгали через неё, ставили стулья, делали мостики, случайным образом располагали свет, ездили в обратном направлении.
Так же мы добавили albumentations как аугментации и постарались навалить их как можно больше!
В этом форке я злостно захардкодил тяжёлые аугментации с конвертом из pil и обратно — это потребовало еще пересобрать окружение для машинки, что отразилось на времени.
К тому моменту как обучилась первая модель, у нас уже был готов код для второй, ребята притащили новых данных с соседней трассы и побежали проверять, как поедет первая модель.
Первая модель проехала 3 круга с ошибками и на 4 вылетела с трассы. После этого мы потеряли еще минут 20, потому что забыли вставить в машинку SD-карту.
Окончательная модель была обучена на 19 тыс. картинках с кастомными аугментациями и чисткой данных.
Вот так выглядит сама сеть:
Видно, что тут есть поле для разворота, можно для начала хотя бы впилить batchnorm, но мы решили трогать по-минимуму, что бы не произошло fuckup’а.
Далее графики первой и второй модели с лучшим значением MSE loss 0.093 и 0.086 соотвественно.
Кажется, что второй график выглядит получше!
Из видео понятно, что мы плохо откалибровали steering и слабенько почистили датасет, но нам этого хватило =)
Видео с GoPro, которое мы записали уже после основного старта:
Финал
Мы первые были готовы начинать заезд и пошли к трассе, но там нас ждала неудача, вайфай постоянно отваливался, нас чуть не сняли с соревнования. И вот, когда уже почти был дан старт, машинка вдруг начала ехать назад. Видимо, я что-то напутал при калибровке throttle =)
Но ничего, под хохот всего зала она поехала вперёд и достойно держалась кругов 8 или 9 на трассе, сильно петляя, но всё равно принесла нам заслуженную победу!
Стараюсь не смотреть в кадр =)
Благодраности
Спасибо сообществу ods.ai, без него невозможно развиваться! Огромное спасибо товарищам по команде: Вале Бирюковой, Егору Урванову (Urvanov), Роме Дербаносову (Yandex). Ждем с нетерпением видео обзора от Виктора Рогуленко (FLESS).
p.s. Отдельное спасибо Вале Бирюковой, которая, к сожалению, за день до соревнований свалилась с температурой 38.5, но очень помогла ссылкой.
Aurorai, llc