Автопилот своими руками: Автопилот своими силами. Часть 1 — набираем обучающие данные / Хабр

Автопилот своими силами. Часть 1 — набираем обучающие данные / Хабр

Привет, Хабр. Это пост-отчет-тьюториал про беспилотные автомобили — как (начать) делать свой без расходов на оборудование. Весь код доступен на github, и помимо прочего вы научитесь легко генерить такие класные картинки:

Поехали!


Вкратце

Краткое содержание для знакомых с темой: традиционно для набора обучающей выборки для автопилота на основе машинного обучения нужен был специально оборудованный автомобиль с достаточно информативной CAN шиной и интерфейсом к ней, что дорого. Мы поступим проще и бесплатно — будем набирать такие же по сути данные просто со смартфона на лобовом стекле. Подходит любой авто, никаких модификаций оборудования. В этой серии — вычисляем поворот руля в каждый момент времени по видео. Если в этом абзаце всё понятно, можно перепрыгивать через введение сразу к сути подхода.


Что-зачем-почему более подробно

Итак, ещё пару лет назад без серьёзных ресурсов большой корпорации в тему автопилотов было не сунуться — один только LIDAR сенсор стоил десятки тысяч долларов, но недавняя революция в нейросетях всё изменила. Стартапы из нескольких человек с простейшими наборами сенсоров из пары вебкамер на равных конкурируют по качеству результата со знаменитыми брендами. Почему бы не попробовать и нам, тем более столько качественных компонентов уже в открытом доступе.

Автопилот преобразует данные сенсоров в управляющие воздействия — поворот руля и требуемое ускорение/замедление. В системе с лазерными дальномерами, как у Google, это может выглядеть так:

Простейший же вариант сенсора — видеокамера, «смотрящая» через лобовое стекло. С ним и будем работать, ведь камера на телефоне уже есть у каждого.

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

Хороших архитектур нейросетей хватает в открытом доступе, а вот с данными ситуация более печальная: во-первых данных просто мало, во-вторых почти все выборки — из США, а у нас на дорогах много от тех мест отличий.

Дефицит открытых данных легко объясним. Во-первых данные — не менее ценный актив, чем экспертиза в алгоритмах и моделях, поэтому делиться никто не торопится:


The rocket engine is the models and the fuel is the data.
Andrew Ng

Во-вторых, процесс сбора данных недёшев, особенно если действовать «в лоб». Хороший пример — Udacity. Они специально подобрали модель автомобиля, где рулевое управление и газ/тормоз завязаны на цифровую шину, сделали интерфейс к шине и считывают оттуда данные напрямую. Плюс подхода — высокое качество данных. Минус — серьезная стоимость, отсекающая подавляющее большинство непрофессионалов. Ведь далеко не каждый даже современный авто пишет в CAN всю нужную нам информацию, да и с интерфейсом придется повозиться.

Мы поступим проще. Записываем «сырые» данные (пока что это будет просто видео) смартфоном на лобовом стекле как видеорегистратором, затем софтом «выжимаем» оттуда нужную информацию — скорость движения и поворотов, на которых уже можно будет обучать автопилот. В результате получаем почти бесплатное решение — если есть держалка для телефона на лобовое стекло, достаточно нажать кнопку, чтобы набирать обучающие данные по дороге на работу.

В этой серии — «выжималка» угла поворота из видео. Все шаги легко повторить своими силами с помощью кода на github.


Задача

Решаем задачу:


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

Ожидаемый результат:


Сразу чуть упростим — вместо угла поворота руля будем вычислять угловую скорость в горизонтальной плоскости. Это примерно эквивалентная информация если знать поступательную скорость, которой мы займемся в следующей серии.


Решение

Решение можно собрать из общедоступных компонент, немного их доработав:


Восстанавливаем траекторию камеры

Первый шаг — восстановление траекториии камеры в трехмерном пространстве с помощью библиотеки SLAM по видео (simultaneous localization and mapping, одновременная локализация и построение карты). На выходе для каждого (почти, см. нюансы) кадра получаем 6 параметров положения: 3D смещение и 3 угла ориентации.

В коде за эту часть отвечает модуль optical_trajectories

Нюансы:


  • При записи видео не гонитесь за максимальным разрешением — дальше определенного порога оно только повредит. У меня хорошо работают настройки в окрестностях 720х480.
  • Камеру нужно будет откалибровать (инструкции, теория — актуальны части 1 и 2) на тех же настройках, с которыми записывалось видео с заезда.
  • Системе SLAM нужна «хорошая» последовательность кадров, за которую можно «зацепиться» как за точку отсчета, поэтому часть видео в начале, пока система не «зацепится» останется не аннотированным. Если на вашем видео локализация не работает совсем, вероятны либо проблемы с калибровкой (попробуйте откалибровать несколько раз и посмотрите на разброс результатов), либо проблемы с качеством видео (слишком высокое разрешание, слишком сильное сжатие и т.д.).
  • Возможны срывы отслеживания SLAM системой, если между соседними кадрами потеряется слишком много ключевых точек например, стекло на мгновение залило всплеском из лужи). В этом случае система сбросится в исходное не локализованное состояние и будет локализовываться заново. Поэтому из одного видео можно получить несколько траекторий (не пересекающихся во времени). Системы координат в этих траекториях будут совершенно разными.
  • Конкретная библиотека ORB_SLAM2, которой я воспользовался, дает не очень надежные результаты по поступательным перемещениям, поэтому их пока игнорируем, а вот вращения определяет неплохо, их оставляем.

Определяем плоскость дороги

Траектория камеры в трехмерном пространстве — это хорошо, но напрямую еще не дает ответа на конечный вопрос — поворачивать налево или направо, и насколько быстро. Ведь у системы SLAM нет понятий «плоскость дороги», «верх-низ», и т.д. Эту информацию тоже надо добывать из «сырой» 3D траектории.

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

Горизонтальную плоскость выделяем прекрасным методом главных компонент по всем 3D точкам траектории — убираем направление с наименьшим собственным числом, и оставшиеся два дадут оптимальную плоскость.

За логику выделения плоскости также отвечает модуль optical_trajectories

Нюанс:


  • Из сути главных компонент понятно, что кроме горных дорог выделение главной плоскости будет плохо работать если машина всё время ехала по прямой, — ведь тогда только одно направление настоящей горизонтальной плоскости будет иметь большой диапазон значений, а диапазон по оставшемуся перпендикулярному горизонтальному направлению и по вертикали будут сопоставимы.

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



Вычисляем угол поворота

Зная базисные векторы горизонтальной плоскости v1 и v2 (два главных компонента с наибольшими собственными значениями из предыдущей части), проецируем на горизонтальную плоскость оптическую ось камеры:

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

Угол поворота между соседними кадрами дает школьная тригонометрия (первый множитель — абсолютная величина поворота, второй — знак, определяющий направление налево/направо). Здесь под at понимаем вектор проекции ahorizontal в момент времени t:

Эта часть вычислений тоже делается модулем optical_trajectories. На выходе получаем JSON файл следующего формата:

{
  "plane": [
    [ 0.35, 0.20, 0.91],
    [ 0.94, -0.11, -0.33]
  ],
   "trajectory": [
    ...,
    {
      "frame_id": 6710,
      "planar_direction": [ 0.91, -0.33 ],
      "pose": {
        "rotation": {
          "w": 0.99,
          "x": -0.001,
          "y": 0.001,
          "z": 0.002
        },
        "translation": [ -0.005, 0.009, 0.046 ]
      },
      "time_usec": 223623466,
      "turn_angle": 0.0017
    },
    .....
}

Значения компонент:


  • plane — базисные векторы горизонтальной плоскости.
  • trajectory — список элементов, по одному на каждый успешно отслеженный системой SLAM кадр.
    • frame_id — номер кадра в исходном видео (начиная с 0).
    • planar_direction — проекция отпической оси на горизонтальную плоскость
    • pose — положение камеры в 3D пространстве
      • rotation — ориентация оптической оси в формате единичного кватерниона.
      • translation — смещение.
    • time_use — время с начала видео в микросекундах
    • turn_angle — горизонтальное вращение относительно предыдущего кадра в радианах.

Убираем шум

Мы почти у цели, но остается еще проблема. Посмотрим на получившийся (пока что) график угловой скорости:

Визуализируем на видео:


Видно, что в общем направление поворота определяется правильно, но очень много высокочастотного шума. Убираем его Гауссовским размытием, которое является низкочастотным фильтром.

Сглаживание в коде производится модулем smooth_heading_directions

Результат после фильтра:


Это уже можно «скормить» обучаемой модели и рассчитывать на адекватные результаты.


Визуализация

Для наглядности по данным из JSON файлов траекторий можно наложить виртуальный руль на исходное видео, как на демках выше, и проверить, правильно ли он крутится. Этим занимается модуль render_turning.

Также легко построить покадровый график. Например, в IPython ноутбуке с установленным matplotlib:

import matplotlib
%matplotlib inline
import matplotlib.pyplot as plt
import json
json_raw = json.load(open('path/to/trajectory.json'))
rotations = [x['turn_angle'] for x in json_raw['trajectory']]
plt.plot(rotations, label='Rotations')
plt.show()

На этом пока всё. В следующей серии — определяем поступательную скорость, чтобы обучить еще и управление скоростью, а пока что приветствуются pull-request’ы.

Автопилот своими рукам. Добавляем электронное управление steer-by-wire на обычный автомобиль / Хабр

Всем привет. Любому автопилоту, очевидно, нужно не только принимать решения по управлению, но и заставлять автомобиль этим решениям подчиняться.

Сегодня увидим, как весьма доступными средствами доработать обычный автомобиль полностью электронным рулевым управлением (steer-by-wire). Оказывается, сам авто для разработки не очень и нужен, а большинство функционала можно с комфортом отлаживать дома или в офисе. В главных ролях всем известные компоненты из хобби-магазинов электроники.

Задумаемся на секунду, что нужно для системы электронного управления? Сервопривод, который может поворачивать колёса, и контроллер, чтобы сервоприводом управлять. Внезапно, всё это в большинстве современных автомобилей уже есть, и называется «усилитель рулевого управления». Традиционные чисто механические (как правило, гидравлические) усилители стремительно исчезают с рынка, уступая место узлам с электронным блоком управления (ЭБУ). А значит, задача сразу упрощается: нам остается только «уговорить» имеющийся ЭБУ усилителя выдать нужные команды на сервопривод.

Очень удобным для доработки оказался KIA Cee’d начиная с 2015 модельного года (скорее всего аналогично и его соплатформенники от KIA/Hyundai). Сошлись одновременно несколько факторов:


  • Усилитель руля полностью электрический, нет возни с гидравликой, стоит копейки (относительно) на разборках. Вся нужная проводка выведена наружу и легко доступна.
  • Усилитель интегрирован с рулевой колонкой, поэтому к нему есть легкий доступ на автомобиле и любая дополнительная электроника останется в салоне в тепличных условиях (в отличие от усилителей, интегрированных в рулевую рейку).
  • Очень важно — есть пример успешной доработки аналогичного KIA Soul. Американская PolySync разрабатывает апгрейд Soul до полностью drive-by-wire платформы для беспилотников, и на их гитхабе можно подсмотреть много полезного.

Итак, получена в распоряжение рулевая колонка в сборе:

Будем заставлять её крутиться. Для этого нужно создать у блока управления впечатление, что


  1. Он находится в автомобиле с работающим двигателем.
  2. Водитель прикладывает вращающее усилие к рулевому колесу.

Пойдем по порядку.


Нужно понять интерфейс между электронным блоком управления (ЭБУ) усилителя и остальным автомобилем. Нагуглив электрическую схему видим картинку:

Из схемы видно, что физически интерфейс очень прост:


  • Питание (12V постоянное) через разъем E29.
  • Сигнал включенного зажигания (12V) через разъем M46.
  • CAN-шина данных также через разъем M46.

Внешний вид и распиновки разъемов находим на том же сайте.

С питанием и зажиганием всё просто, берем 12V с обычного компьютерного блока питания. Но если просто подать питание и зажигание, усилитель полноценно не включится, и усиливать не будет. Дополнительно нужна информация от других блоков автомобиля: работает ли двигатель (чтобы не тратить энергию аккумулятора при выключенном), текущая скорость (чтобы делать руль «тяжелее» на скорости), наверняка что-то ещё.

Обмен данными между электронными блоками в современных автомобилях организован по шинам CAN (Controller Area Network). Это широковещательная (у пакетов нет адресов назначения) локальная сеть на витой паре, где каждый блок может публиковать свои данные. У каждого типа данных свой идентификатор. Например, в нашем случае усилитель руля рассылает значения угла поворота руля с ID 0x2B0. Часто бывает несколько физически разделенных шин, чтобы второстепенные блоки типа контроллеров стеклоподъемников не мешались обмену между критически важными компонентами. В Cee’d используется две шины: C-CAN и B-CAN (схема здесь, в части «Информация о канале передачи данных»). На C-CAN «висят» почти все блоки с ней и будем работать.


Выбор адаптера CAN-шины

Первым делом понадобится CAN интерфейс для компьютера. Детальный обзор возможных решений есть например здесь, цены варьируются от десятков до сотен долларов. По устройствам у нас относительно доступны:


  1. Адаптеры в сборе с алиэкспресса. Их не пробовал, по слухам довольно много брака и софт видимо только под Windows.
  2. Arduino шилды на MCP2515/MCP2551, в основном клоны дизайна от seeed в любом магазине ардуинной тематики. Но совмещать такой шилд надо не с Arduino (я так и не смог заставить связку работать на воспроизведение с нужной скоростью), а с Raspberry Pi. В приложении ниже подробная инструкция.
  3. USB адаптер CANHacker Baby, разработка Artemka86. Выгодно отличается от вариантов с алиэкспресса отличной поддержкой «из первых рук» от разработчика (проверено лично, Артём подходит к делу с душой). Также плюсом является поддержка стандартного протокола LAWICEL совместимого с широким набором софта.

Софта разного тоже много (за обзором опять сюда). Самый простой вариант — Linux c can-utils из SocketCAN, за который спасибо инженерам Volkswagen. Большой плюс SocketCAN в стандартизации — любое USB устройство с поддержкой протокола LAWICEL (pdf) видится системой как обычный сетевой интерфейс. Таким образом избегаем привязки к вендор-специфическому софту конкретного устройства. У текущей версии CANHacker есть небольшая несовместимость со стоковыми can-utils по работе с USB, поэтому берём патченную версию отсюда. Raspberry Pi с CAN шилдом работает со стоковым пакетом can-utils из Raspbian OS без проблем.


Подключение к шине, запись пакетов

С подключением к индивидуальному узлу на стенде всё просто: соединяем контакт CAN-High адаптера с CAN-High автомобильного узла, CAN-Low — c CAN-Low. По стандарту между CAN-High и CAN-Low должно быть 2 замыкающих резистора по 120 Ом, на практике обычно всё работает на довольно широком интервале сопротивлений, у меня например одно на 110 Ом.

На автомобиле замыкающий резистор не нужен (они там уже стоят, чтобы шина сама по себе работала). В зависимости от модели авто, возможно придется повозиться с физическим доступом к проводке шины. Самый удобный вариант — разъём OBD-II (on-board diagnostic), он обязателен на всех легковых автомобилях, выпущенных в Европе с начиная 2001-2004 года и находится не дальше 60 см от рулевого колеса. На Cee’d разъём слева под рулём, за пластмасовой крышкой блока предохранителей.

Распиновка OBD-II стандартизована и включает шину CAN (CANH на 6 контакте, CANL на 14). Нам повезло, корейцы пошли по пути наименьшего сопротивления и вывели C-CAN, на которой висят все важные узлы, прямо на диагностический разъём:

В результате на Cee’d можно прослушать весь внутренний трафик, ничего в авто не разбирая. Когда машина не твоя, а знакомые пустили повозиться — большой плюс. Но такая халява не везде. У Volkswagen например служебная CAN изолирована от OBD шлюзом, поэтому подключаться пришлось бы примерно так:

Подключив все контакты, поднимаем сетевой интерфейс:

$ sudo slcand -o -c -s6 -S 115200 ttyACM0 slcan0 && sleep 1 && sudo ifconfig slcan0 up

Проверяем, что сеть работает и данные принимаются (включив зажигание):

$ cansniffer slcan0

И наконец, если всё нормально, можно записывать лог:

$ candump -L slcan0 > real-car-can-log.txt

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


Воспроизведение записи шины на стенде

С записанным логом с авто можно возвращаться на стенд и приступать к обману нашего одинокого усилителя. Первым делом вспомним, что в автомобиле стоит свой собственный усилитель, он тоже шлёт данные в CAN шину, и эти пакеты есть и в нашем логе. Отфильтруем их, чтобы избежать конфликтов. Подключаемся к усилителю на стенде, смотрим, что он выдает:

$ $ candump slcan0
  slcan0  2B0   [5]  00 00 00 00 00
  slcan0  2B0   [5]  FF 7F FF 06 F1
  slcan0  2B0   [5]  FF 7F FF 06 C2
  slcan0  2B0   [5]  FF 7F FF 06 D3
  slcan0  2B0   [5]  FF 7F FF 06 A4
  slcan0  2B0   [5]  FF 7F FF 06 B5
  slcan0  2B0   [5]  FF 7F FF 06 86
  slcan0  2B0   [5]  FF 7F FF 06 97
  slcan0  2B0   [5]  FF 7F FF 06 68
  slcan0  5E4   [3]  00 00 00
  slcan0  2B0   [5]  FF 7F FF 06 79
  slcan0  2B0   [5]  FF 7F FF 06 4A
....

Видим, что рассылаются пакеты 2B0 (текущий угол поворота руля) и, реже, 5E4 (какой-то общий статус усилителя). Отфильтровываем их из общего лога:

$ cat real-car-can-log.txt | grep -v ' 2B0' | grep -v ' 5E4 ' > can-log-no-steering.txt

Фильтрованный лог можно подавать на воспроизведение:

% sudo ifconfig slcan0 txqueuelen 1000
$ canplayer -I can-log-no-steering.txt

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


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

Блок управления обрабатывает сигналы датчиков и выдаёт команды сервоприводу на создание дополнительного усилия на поворот рулевого вала.


По информации PolySync, на Soul, у которого с Cee’d общая платформа, два аналоговых датчика крутящего момента. Cигнал каждого — отклонение уровня постоянного напряжения от базовых 2.5V, провода в жгуте — зеленый и синий. Проверим, что у нас то же самое:


  • Размыкаем разъем на ЭБУ, пробрасываем нужные контакты через макетку и заводим на аналоговые входы arduino.


  • Загружаем скетч, в цикле замеряющий напряжения и печатающий их в терминал.
  • Запускаем Serial Plotter в Arduino IDE, поворачиваем рулевой вал. Видим результат на графике, схема совпадает с Soul:
  • Радуемся сэкономленному времени.

Переходим к эмуляции сигнала датчиков. Для этого поставим свой модуль в разрыв цепи между датиком и ЭБУ, будем транслировать настоящий сигнал с датчика и по команде сдвигать его на фиксированный уровень (изображая приложенное к рулевой колонке усилие). Силами одной arduino это не получится: там нет полноценного цифро-аналогового преобразователя, который мог бы выдавать постоянное напряжение. Аналоговые входы arduino нам тоже не очень подходят — хотя пинов для них целых 6, канал АЦП в контроллере только один, и его переключение между пинами занимает заметное время.

Нужно добавить к arduino внешние ЦАП/АЦП. Мне попались модули YL-40 (описание в pdf) на основе чипа PCF8591 — на каждой по 4 канала 8-бит АЦП и 1 8-бит ЦАП. Модуль может общаться с arduino по протоколу I2C. Потребуется небольшое допиливание (в буквальном смысле): китайские товарищи поставили на плату светодиод индикации напряжения на выходе ЦАП — его обязательно надо отсоединить. Иначе утекающий через диод ток не даст ЦАП поднять напряжение на выходе больше 4.2V (вместо штатных 5V). Диод отсоединяем, отковыривая резистор R4 с обратной стороны платы.

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

С интерфейсом к arduino есть нюанс — нам нужно 2 канала ЦАП, соотвественно 2 модуля, но у них одинаковые адреса I2C (зашиты в чип). Хотя чип позволяет менять свой I2C адрес, замыкая определенные ноги на +5V вместо земли, на плате эти перемычки не разведены. Вместо перепайки возьмем костыль — две разные библиотеки I2C на arduino (стандартная Wire и SoftI2CMaster), каждая на свою пару пинов. Получаем модули на разных шинах, конфликт пропадает.

Остальное прямолинейно — ставим модули в разрыв цепи от датчиков, соединяем с arduino, загружаем скетч. Подробности по распиновке подключения есть в комментариях в скетче. Остается включить всё в сборе, здесь важна последовательность:


  1. Включаем arduino, открываем Serial Monitor. Важно запустить arduino первой, не останавливать и не прерывать. Иначе напряжение на выходах ЦАПов сбросится, ЭБУ усилителя определит ошибку сигнала с датчиков, уйдет в безопасный редим и придется все перезапускать по новой.
  2. Запитываем усилитель, подключаем зажигание.
  3. Запускаем воспроизведение лога CAN-шины.
  4. Теперь по командам l и r через Serial Monitor усилитель будет поворачивать рулевой вал. Объявляется победа.

На сегодня всё, на очереди доработка софта (интеграция с CAN шиной, чтение оттуда текущего угла поворота и динамическое управление крутящим усилием, чтобы внешний контроллер мог задать фиксированный угол поворота руля и система его выдерживала), отработка на автомобиле (на стенде не смоделируешь сопротивление от колёс). Возможно замена 8-битных ЦАП/АЦП на 10 или 12 бит (взял первое, что под руку попалось). Рулящая нейросеть тоже в процессе, надеюсь скоро сделать пост.

Спасибо Artemka86 за ценные консультации по работе с CAN и помощь с оборудованием.


Ресурсы для дальнейшего погружения


  1. Car Hacking: The definitive source. Начинать можно с Car Hacking for Poories, там отлично покрыты основы. Остальное тоже интересно, но с упором на несанкционированный доступ.
  2. The Car Hacker’s Handbook: A Guide for the Penetration Tester. Больше деталей, чем в Car Hacking: The definitive source, тоже акцент на несанкционированный доступ. Если читать как первое введение в тему, надо приспособиться пропускать большие куски.
  3. Car Hacking 101: Tools of the Trade, MCD Software — обзоры инструментов. В основном малоинтересная экзотика на мой взгляд.
  4. Open Source Car Control — открытая платформа для KIA Soul, в процессе разработки. Они делают полное решение (руль, акселератор, тормоза), включвя доработки по «железу» на машине (в основном для тормозов — ставятся дополнительные тормозные приводы, что-то меняется в тормозной гидравлике итд). Релиза ещё не было, но многие вещи уже можно подсмотреть.

Прежде всего, внимание, CAN шилд и raspberry pi нельзя соединять напрямую, они не совместимы по напряжению. На Arduino UNO-совместимых платах напряжение логики 5V, а на raspberry pi только 3.3V, поэтому прямое соединение только сожжет задействованные пины.

Нам понадобятся:


  • Raspberry Pi (проверялось на версии 3B).
  • Arduino CAN шилд на MCP2515/MCP2551.
  • Преобразователь уровня логики на 5 каналов или больше (можно 2 по 4 канала, но понадобится больше соединений). Мне попался этот

Нужно завести на CAN шилд питание (5V), соединения интерфейса данных SPI (4 пина: MOSI, MISO, SCLK, CS) и 1 пин сигнала прерывания. Всё, кроме питания, идет через преобразователь уровня, который в свою очередь тоже надо запитать.

На схемах ищем нужные пины.

Raspberry Pi:

CAN шилд:

Получаем результат:


  • SPI на raspberry pi 19, 21, 23, 24 (MOSI, MISO, SCLK, CS) соответствуют D11, D12, D13, D9 (или на некоторых версиях D10) на CAN шилде.
  • Прерывание с D2 на шилде можно завести на любой GPIO пин raspberry, у меня это пин 22 (GPIO 25). Номер пина укажем в софте при настройке.

Соединяем через преобразователь, заводим нужные напряжения питания на каждую сторону преобразователя, получается такая лапша:

Всё, кроме 5V питания и земли на шилд идёт через преобразователь:

Переходим к настройке софта (стандартный Raspbian).


  1. Включаем поддержку SPI и CAN модуля. В /boot/config.txt добавляем

    dtparam=spi=on
    dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25,spimaxfrequency=1000000
    dtoverlay=spi0-hw-cs

    Здесь interrupt=25 указывает пин, на который заведено прерывание с шилда. Индексация идёт по GPIO пинам, поэтому interrupt=25 это GPIO 25, он же пин 22 по сквозной индексации всех пинов. Также важно указать частоту интерфейса SPI spimaxfrequency, т.к. значение по умолчанию — 10 МГц — слишком высокое для шилда, он просто не соединится.


  2. Перезагружаем raspberry pi, проверяем соединение с шилдом:

    $ dmesg
    ...
    [   12.985754] CAN device driver interface
    [   13.014774] mcp251x spi0.0 can0: MCP2515 successfully initialized.
    ...

  3. Устанавливаем can-utils:

    $ sudo apt install can-utils

  4. Запускаем виртуальный сетевой интерфейс:

    $ sudo /sbin/ip link set can0 up type can bitrate 500000
    $ sudo ifconfig can0 txqueuelen 1000

    Вторая команда важна при воспроизведении большого количества данных с raspberry pi, то есть когда записанный на автомобиле полный лог CAN шины воспоизводим для изолированного узла на стенде. Без увеличения буфера он скорее всего переполнится, когда в логе встретится несколько CAN пакетов с маленькими интервалами, и тогда соединение зависнет.


  5. Готово, можно пользоваться candump, cansniffer и всем остальным из can-utils.

Самодельный автопилот – Dinghy Dreams

Прочтите мою техническую статью, конечно же, с анекдотом!

Я плавал на лодке с ручным управлением по разным водоемам, и я скажу вам, что последнее место, где я хотел бы это делать, — это во время плавания в открытом море в 4 часа утра мимо реки Савана, где дисплей АИС выглядит как пакет. чувак, холодно и дует, а твою команду тошнит от морской болезни, спящей на полу, черт возьми, потому что проводка к блоку автопилота под палубой в четверти причала была слишком хлипкой, чтобы рисковать ее выдергиванием. Но, несмотря на эту предосторожность, чтобы не спать рядом с проводкой, ее все равно вырывают. К счастью, моя команда могла управлять, пока я собирал это дерьмо.

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

Честно говоря, я думаю, что это произошло СНОВА (почему я такой) на мини-переходе из Бьюфорта, Северная Каролина, в Райтсвилл-Бич. И затем, очевидно, с моей командой у реки Савана. Так что в основном каждый чертов проход вдоль всего побережья.

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

Я также пробую «от листа к культиватору», потому что на данный момент мне нужно как можно больше резервных копий!

Что приводит к моему следующему пункту; Я хочу флюгер. Но мне также нужно было собраться с силами. Я повеселился с автопилотами и румпелем, и буду стремиться иметь их на борту судна в дополнение к флюгеру… Может быть, это избыточность, которая заставит меня чувствовать себя в большей безопасности. Или кто знает, может быть, я один из тех людей, которые никогда не «ходят», потому что думают, что им всегда нужна следующая часть снаряжения. У меня есть друг, который в одиночку проехал на своем Dailer26 с Гавайев в Калифорнию, затем переправил его в Персидский залив, спустил на воду, а затем поплыл обратно вверх и вниз по восточному побережью.

У него был только румпельный пилот. Так что да, это можно сделать.

Тем временем я довольно хорошо познакомился с Pypilot Auto Pilot . Программное обеспечение с открытым исходным кодом, подпалубный компьютер автопилота и блок управления двигателем. Он продается здесь pypilot.org чуть менее 200 долларов. Для любого моряка с ограниченным бюджетом это довольно заманчиво. Но у этого есть свои оговорки, такие как установка собственного привода из старого пилота румпеля или создание нового с двигателем стеклоочистителя. И сайт/интернет-магазин без особого направления и описания.

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

Для остальных из нас… Я не уверен, как кто-то, кто не является полным кретином, понимает это дерьмо. Даже мой приятель Сэм Холмс, который находится на другом конце спектра, чем я, когда дело доходит до инженерии, не понимал, как это работает, глядя на магазин. У меня было предварительное знание обо всем этом, потому что я встретил Инженер Pypilot , Шон Д’Эпанье. Без этого я бы ни хрена не понял, что это за коробочки, провода и прочее дерьмо.

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

Итак, без лишних слов..

Для моряка выходного дня и летнего круиза это просто великолепно. Для плавания по озеру, заливу, реке и в хорошую погоду на море. Я не тестировал его на скорости более 20 узлов с порывами ветра 25 от берега на расстоянии 20 миль. Он работал хорошо, но для чего-то большего Шон предлагает более мощный приводной двигатель. Я использую двигатель размером с Simrad TP22. Шон также делает контроллер двигателя для гидравлического управления большими лодками, так что это можно сделать.

Я лично с успехом использовал его во время нескольких проходов через Чесапикский залив, пролив Памлико, до 20 миль от берега Атлантического океана.

Планируйте потратить на все это не менее 12 часов, потому что лодки, и если у вас вообще СДВГ, как у меня, намного дольше/на всю жизнь. Также учитывайте количество времени, которое требуется Шону или кому-либо на форуме, чтобы ответить на вопросы. Что он и сделает. Если только он не пересекает океан или что-то в этом роде. Имейте в виду, что Шон тоже вручную делает это дерьмо на своем тримаране. Некоторые из них автоматизированы.

1. У меня есть компьютер автопилота TinyPilot за 120 долларов и контроллер двигателя за 65 долларов. Я не знаю, есть ли у Шона адаптер или что бы он порекомендовал, но оригинальный блок, который он мне дал, и то, что я до сих пор использую, это вход 12 В (+,-) 5 В 3 А (USB). У меня тоже есть запасные. Положительный и отрицательный провода контроллера мотора подключаются вместе с положительным и отрицательным проводами компьютерного адаптера автопилота к одному и тому же переключателю. Затем с помощью шнура компьютер AP и контроллер двигателя соединяются вместе. И включается и выключается как единое целое.

2. Привод/Привод/Мотор. Это рука, которая физически будет управлять лодкой. Вы только что подключили мозги. Есть еще два провода, которые выходят из контроллера двигателя, для них нужны защелки с внутренней резьбой (я понятия не имею, правильное ли это название). Острые концы проводов на приводе будут иметь штуцеры. Вам нужно открыть сломанный пилот румпеля, у которого сгорела электроника, и внимательно проследить за проводами, чтобы найти два, которые подключаются к самому двигателю. Клип тех. Вы в деле. Присоедините их к проводу с помощью концевых фитингов с наружной резьбой. Вы хотите, чтобы эта проводка была достаточно длинной, чтобы достать до штурвала с места, где вы устанавливаете устройство.

Позже методом проб и ошибок вы поймете, какой цветной провод к какому разъему на контроллере мотора подключается, чтобы устройство не ехало назад… если это вообще имеет смысл.

3. Теперь пришло время откалибровать акселерометр. Это может потребоваться или не потребоваться сделать или написать правильно, но это можно сделать в Интернете, подключив устройство к Wi-Fi pypilot и перейдя на страницу управления на pypilot.io. Затем вы должны поместить устройство на каждую из его шести сторон на несколько секунд, чтобы выровнять инерциальные датчики. Если вы все сделали правильно, вы увидите точки сенсора внутри сферы. На самом деле вполне устраивает.

4. Теперь смонтируй это дерьмо. Найдите уровень в меню настроек и нажмите на него, чтобы выровнять датчики.

5. Откалибруйте компас, плывя под парусом, гребя на веслах или управляя лодкой по кругу (но Шон на самом деле говорит, что 180 градусов — это нормально). Это в основном автоматическое и будет перекалибровываться каждый раз, когда лодка поворачивается на 180 градусов и включается! Вы также можете видеть, как точки попадают в сферу после калибровки. Неато.

6. Установите магнитное смещение (я понятия не имею, почему это так, я знаю только, что это ЕСТЬ). Я использовал кучу компасов, чтобы попытаться приблизиться как можно ближе, и я просто регулировал смещение, пока направление на экране не совпало с направлением на моем другом компасе».

7. Теперь еще немного настроек. Я установил Servo.max_current на 5 ампер. Это довольно очевидно, я думаю, поскольку он контролирует максимальный поток тока. Максимальная и минимальная скорости сервопривода также должны быть установлены на 100. 

Примечание. Pypilot можно управлять удаленно, через Wi-Fi на любом устройстве, подключившись к автоматической сети Wi-Fi pypilot и перейдя на pypilot.io, или подключившись к плагину. через OpenCPN. Но пока это не может контролироваться вашим разумом. Хотя я думаю, что он работает над этим, руля по ветру! Сумасшедший!

pypilot.io контролирует

Теперь вы готовы протестировать свое устройство. Я протестировал два устройства, которые я только что установил, успешно объезжая якорную стоянку. У меня еще есть несколько лодочных проектов, которые нужно завершить, в том числе от шкота до румпеля, прежде чем отправиться в море, чтобы протестировать устройства (плюс шкот до румпеля), а затем использовать Pypilot и пройти примерно 600 морских миль на север. Я отчитаюсь.

Слоган Pypilot гласит: «Наконец-то освобожденный автопилот». Спасибо Шону за то, что он позволил мне бесплатно протестировать Pypilot. Начните с вашего менее чем за 200 долларов на pypilot.org.

Некоторые из проблем, с которыми я сталкивался

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

— экран сгорел на одном устройстве, поэтому его нужно было контролировать через Wi-Fi, но по какой-то причине Wi-Fi периодически сбоил, поэтому невозможно было управлять через веб-браузер, что означало 0 контроля… Шон прислал мне новое устройство, которое имеет беспроводной пульт дистанционного управления, который может регулировать точку доступа из кабины, плюс обычный пульт, который вы должны указать на контроллер двигателя, + Wi-Fi . .. так что, даже если экран сгорел + Wi-Fi снова не работает, этот все еще можно настроить … однако вы бы не видеть заголовок курса

— ошибка драйвера. Я по-прежнему сдержанно отношу это к действительно слабому / почти несуществующему ветру, но, например, к 3-футовым волнам, поэтому на самом деле недостаточно импульса вперед. Но я исправил это, заменив сервопривод. макс., мин. и текущие настройки.

Заставить автопилот работать — boats.com

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

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

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

Не ошибитесь в том, что делает автопилот. Он направляет лодку по прямой в самых разных условиях моря и ветра. Автопилот не корректирует лодку, которая плохо рулится без автопилота. У таких лодок есть и другие проблемы, которые необходимо решить, прежде чем вы решите добавить автопилот. Поэтому всегда помните о первом шаге устранения неполадок автопилота; если ваш автопилот когда-то работал идеально, а сейчас нет, проблема может быть в одном из электронных компонентов. Если он никогда не работал должным образом, проблема может быть в самой лодке.

Проблемы с лодкой

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

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

Электронный компас

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

Насос

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

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

Микропроцессор

Если ваша лодка усредняет правильный курс, но, кажется, поворачивает слишком далеко в каждом направлении, чтобы достичь этого, возможно, виновата регулировка состояния моря. В мозгу автопилота есть «мертвая зона» пространства по обе стороны от желаемого курса, которая устанавливает его пределы — обычно от 1 до 5 градусов. Это означает, что устройство будет ждать, пока ваше судно не отклонится от курса на указанную величину, прежде чем выполнять коррекцию. Чем шире зона нечувствительности, тем меньше работы выполняет пилот и тем меньше энергии он потребляет.

Датчик обратной связи руля направления

Датчик обратной связи руля направления сообщает автопилоту, в каком направлении находится руль направления или блок привода. Если это не отрегулировано, автопилот будет думать, что движется по прямому курсу, хотя на самом деле судно поворачивает. Будучи компьютером, устройство не сможет функционировать в рамках этой дихотомии.

Interfacing

Современные автопилоты обычно подключаются к GPS или картплоттеру, который передает пилоту информацию о курсе. Конечно, жизнь становится проще, когда вы можете навести курсор на ряд путевых точек, затем нажать «Пуск», и автопилот направит вас к каждой путевой точке по очереди — автоматически. Однако, если GPS перестанет давать информацию о направлении, ваш курс не изменится, как только вы достигнете первой путевой точки. Автопилот просто считывает информацию о курсе с компаса феррозонда и продолжает движение по последнему известному курсу. Тем не менее, велика вероятность того, что сигнал тревоги сработает, когда вы потеряете информацию о местоположении от GPS.

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

Проводка

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

Программное обеспечение

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *