Опыт домашнего марсоходостроения

в 11:57, , рубрики: raspberry opencv, Блог компании Wargaming, Разработка под Linux, Разработка робототехники, метки:

Опыт домашнего марсоходостроения - 1
Привет! Я работаю RnD-художником в минском центре разработки Wargaming. А в свободное время даю волю своей инженерной фантазии. В этой статье я хочу поделиться своим опытом домашнего марсоходостроения.

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

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

Hardware


Перво-наперво была приобретена платформа — радиоуправляемый танк Abrams M1A2, содержимое которого (за исключением двигателей) было беспощадно выпотрошено:
Опыт домашнего марсоходостроения - 2

Далее, я приступил к поиску источника питания. К сожалению, Плутоний-238 для самодельного РИТЭГа найти не удалось, поэтому пришлось использовать альтернативный вариант. Достойной заменой стала батарея из 16 аккумуляторов NCR18650B (3400 мА) с контроллером заряда/разряда. Расчетная емкость — 27 А/ч при напряжении 7,2 В:
Опыт домашнего марсоходостроения - 3

Мозгом ровера стал Raspberry Pi 2. Шлейфом (удлиненным и армированным скотчем) к нему подключена камера без IR фильтра, с инфракрасной подсветкой:
Опыт домашнего марсоходостроения - 4

Подсветка потребляет достаточно много энергии, поэтому включается лишь во время съемки при уровне освещения ниже установленного порога. Также только на время замера включается и оптический дальномер. Включение и отключение происходит при помощи 40-амперных мосфетов (других ключей в запасе не нашлось), управляемых микроконтроллером Atmega328 с минимальной обвязкой. К этому же контроллеру подключен дальномер и фоторезистор. Для последнего я подобрал функцию аппроксимации под промышленный люксметр, взятый на работе (там мы его используем для валидации освещения). Также я использовал бесконтактный датчик температуры MLX90614. Вся эта обвязка была собрана на макетной плате и прикручена к серводвигателям вращения головы. К Raspberry головной модуль подключен всего четырьмя проводами — питание и шина I2C.
Опыт домашнего марсоходостроения - 5

Для управления сервоприводами я использовал специализированный I2C-контроллер PCA9685 на 16 ШИМ выходов. Сначала попробовал Arduino, но библиотека для сервоприводов там реализована программно. Из-за этого возникали спонтанные рывки и подергивания во время работы контроллера с I2C. Как-то раз ровер даже начал молотить камерой о стол. После замены Arduino на PCA9685 все движения стали ровными и шелковистыми.

Для управления двигателями я использовал немного доработанный Dual Channel H-Bridge Motor Shield.
Опыт домашнего марсоходостроения - 6

По умолчанию для управления требуется семь линий, две из которых ШИМ. Я выбросил входную логику, подключившись к входам драйверов на прямую. Получилось пять управляющих линий. Но теперь стало необходимо, чтобы четыре из них управлялись через ШИМ. Пытался использовать оставшиеся линии PCA9685, но оказалось, что частота ШИМ на всех каналах должны быть одна, а 50 герц для управления серводвигателями мне никак не подходили. У Raspberry всего один полноценный ШИМ, а связываться с программными не хотелось. В результате я решил использовать дополнительный контроллер, который заодно измеряет напряжение батареи. В итоге получился I2C моторшилд:
Опыт домашнего марсоходостроения - 7

Дополнительно я установил энкодеры от мышек с прорезинеными колесами от них же, которые отслеживают скорость и дистанцию при движении. Энкодеры подключены к малинке через RC-фильтры и вызывают прерывания в обработчике при срабатывании. Применение простых фильтров почти убрало дребезг контактов, а оставшиеся случайные срабатывания элементарно отсекались в коде. Скорость меряется по временным промежутка между прерываниями, и усредняется по нескольким замерам.

Для питания ровера используется два понижающих стабилизатора — отдельно для Raspberry и электроники, и отдельно для сервоприводов. Внутренности марсохода выглядят так:
Опыт домашнего марсоходостроения - 8

Датчики влажности и давления, а также GPS, я вынес на «броню». GPS подключен к нативному последовательному порту Raspberry. В итоге у меня получился вот такой «зоопарк» I2C-устройств:
Опыт домашнего марсоходостроения - 9

Изначально в качестве центра управления трудился Arduino c радиомодулем, подключенным к PC. Но решение было не совсем аутентичным, поэтому я заменил его на еще один Raspberry Pi 2, управляемый по SSH. Заодно это позволило управлять ровером не из дома (если вы понимаете, о чем я). Обмен данными с ровером идет через модули nrf24L01 PA.
Опыт домашнего марсоходостроения - 10

Итоговое фото марсохода:
Опыт домашнего марсоходостроения - 11

Software


Для работы с железом я собрал и установил библиотеки BCM2835, WiringPi, NRF24 и OpenCV. По поводу последней были большие опасения, но на удивление, все прошло гладко. Хоть на сборку и ушло более трех часов. OpenCV понадобился для исправления сильного искажения камеры (для этого откалибровал камеру), для отрисовки GUI поверх снимков и создания примитивной панорамы:
Опыт домашнего марсоходостроения - 12

С библиотеками для I2C-датчиков пришлось повозиться. В итоге я понял, что каждый датчик предпочитает свою частоту шины. Большую часть кода датчиков пришлось переписать под библиотеку BCM2835 — тут частоту шины можно регулировать. Не обошлось без казусов. Оказалось, что магнитомер девятиосевого гироскопа —отдельный девайс со своим адресом. При его программном подключении на общую шину он почему-то вырубал датчик влажности, хотя они и имели разные адреса. Поэтому магнитометр программно подключается к шине только перед замером.

Обновлять данные акселерометра для фильтра MadgwickAHRS нужно с равными промежутками времени, поэтому его код я вынес в отдельный поток. Во избежание конфликтов доступа к шине добавил мьютекс для I2C. Кстати, MadgwickAHRS очень удобная штука — скармливаем ему сырые данные, а на выходе получаем готовый отфильтрованный кватернион поворота ровера в пространстве. Чтобы данные сильно не плыли, необходим откалиброванный гироскоп. Также он позволяет получать крен и тангаж марсохода и осуществлять поворот на заданный угол.

Для реализации настраиваемой задержки радиомодуля я использовал очереди из структур (32 байта пакета и метка времени), а также два отдельных потока. Один непосредственно общается с радиомодулем, а второй занимается управлением данными. Опять же есть мьютексы для защиты от конфликтов. Протокол обмена прост до безобразия — принять/отправить строку или файл. Благодаря этому можно передать роверу скомпилированную программу из центра управления — в итоге пригодилось для правки багов уже во время миссии.

Двигателями управляю посредством ПИД-регуляторов, с учетом данных от энкодеров. На настройку коэффициентов регуляторов потратил несколько дней, снимая десятки и даже сотни графиков и подстраивая параметры. Но в итоге добился плавной и четкой работы.

Были некоторые проблемы с потерей данных на шине I2C между малиной и микроконтроллерами. Решилось использованием контрольных сумм.

Написал парсер для модуля GPS, благо протокол NMEA 0183 не отличается сложностью. Парсер работает в отдельном потоке и посимвольно обрабатывает входящую информацию.

Научил марсоход делать тепловые карты, используя mlx90614 (тот же вид с балкона):
Опыт домашнего марсоходостроения - 13

Миссия 1: тест в домашних условиях


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

Итак, ровер был активирован перед уходом на работу. Я удаленно связался с центром управления и успешно установил связь с марсоходом. Задержку сигнала установил на две минуты. Вскоре получил первую панораму (кликабельно):
Опыт домашнего марсоходостроения - 14

В целом лог управления ровером выглядел так:

Опыт домашнего марсоходостроения - 15

Внезапно обнаружился баг в коде — ровер не ждал окончания команд движения. Пришлось править, собирать и отправлять ему пофикшенную прошивку. И вот ровер отправляется навстречу неизвестности:
Опыт домашнего марсоходостроения - 16

Но всплыла очередная проблема — внезапно начала портиться приходящая по радиоканалу информация. Пример (тут отключена проверка на контрольную сумму, иначе файлы не были бы приняты):
Опыт домашнего марсоходостроения - 17

Быстрый разбор показал, что виновата шина SPI в центре управления. Снизив ее частоту вдвое, проблему удалось решить. Заодно я снизил частоту шины для ровера и залил ему новую прошивку.
Итак, миссия продолжилась. Первый тепловой скан:
Опыт домашнего марсоходостроения - 18

В целом удаленно управлять ровером со значительной задержкой оказалось очень увлекательно. Вот только скорость продвижения невысока. Например, заехав в кладовку, ровер целый час пытался оттуда выбраться. Как потом стало ясно — я не рассчитал расстояние и зацепился головным модулем за шланг пылесоса:
Опыт домашнего марсоходостроения - 19
Опыт домашнего марсоходостроения - 20

Еще снимки:

Опыт домашнего марсоходостроения - 21
Опыт домашнего марсоходостроения - 22
Опыт домашнего марсоходостроения - 23
Опыт домашнего марсоходостроения - 24

Когда в центре управления отказал радиомодуль, миссию пришлось свернуть, т.к. на уровне ПО решить проблему не удалось (подвели разъемы).


Весна близко! Поэтому планирую в ближайшее время пофиксить все баги и отправить марсоход на улицу.
Если вы можете поделиться полезным опытом или просто хотите задать вопросы — пишите комментарии.

Все исходники тут github.com/DIMOSUS/Rover

Автор: Wargaming

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js