DIY. Подводный дрон. История одного сумасшествия

DIY. Подводный дрон. История одного сумасшествия Конструкторы

3d-модель робота в сапр

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

Мы выбрали редактор SolidWorks 2023 для платформы Windows, потому что в нём есть отличный плагин для экспорта проекта в формат URDF.

Старайтесь не описывать сразу всего робота. Добавляйте различные части к модели постепенно. Это поможет вам освоить процесс описания. Мы начали с детализации шасси.

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

На данный момент наша модель состоит из четырёх сегментов:

И трёх сочленений (joints):

  • left_wheel_to_base
  • right_wheel_to_base
  • caster_wheel_to_base

Для правильного экспорта нужно выполнить несколько действий.

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

ROS и URDF требуют правосторонних систем координат (Правило правой руки). Определите, где находится передняя, задняя и верхняя части вашего робота. Ось X должна указывать вперёд, ось Y — влево, а ось Z — вверх. По умолчанию стандартные виды SolidWorks и система координат повёрнуты на 90 градусов вокруг осей X и Z. Для удобства правильного размещения осей в SolidWorks можно разместить направляющие линии.

Каждый сегмент модели имеет свою систему координат:

  • CS_BASE
  • CS_RIGHT_WHEEL
  • CS_LEFT_WHEEL
  • CS_CASTER_WHEEL

Система координат CS_BASE условно расположена в центре нашего робота. CS_LEFT_WHEEL и CS_RIGHT_WHEEL находятся в центрах колёс. CS_CASTER_WHEEL находится в центре сферы всенаправленного опорного колеса.

Добавьте оси вращения для подвижных соединений и сочленений (joints). У нас есть три подвижных соединения: два вращающихся на осях колеса и одно всенаправленное колесо, которое вращается во все стороны и поэтому не нуждается в оси. Для колёс мы поместили оси AXIS_LEFT_WHEEL и AXIS_RIGHT_WHEEL.

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

Hey, what’s a flight controller?

Keeping it simple, a quadcopter consists of a frame, a battery, a flight controller (aka autopilot), motors and their ESCs (electronic speed controllers). A flight controller is a device equipped with microcontroller (like Arduino) and a bunch of sensors: accelerometers, angular rate sensors, magnetometers and barometer.

These sensors provide data for microcontroller to calculate drone’s current attitude, and with addition of an external positioning data, e.g. GPS, it also determines its position and speed. Using this information and control inputs (commands from the remote control or onboard computer), the flight controller calculates required motor commands and passes them to ESCs, which control drone’s motors.

PX4 is a popular open source autopilot firmware, supported by Dronecode Foundation, a Linux Foundation Collaborative Project. Its architecture is perfect for autonomous flights, controlled by a companion computer instead of a remote, and allows you to extend its functionality easily.

Clover docs contain info on how to connect Raspberry Pi so you can get your drone in the air in no time. Equip your Raspberry Pi with a camera to fly indoors.

If you don’t have a right drone, there are the clover quadcopter kits, perfectly suitable for tinkering.

Python raspberry pi pixhawk и квадрокоптер. или как не надо делать роботов

Привет, меня зовут Алексей, уже 7 лет я ведущий разработчик Smart TV-решений в «Центре Высоких Технологий». Каждый год у нас проводится конкурс новогодних украшений, и каждый раз мы ничего не украшаем, а пилим всякие технологичные штуки. В этот раз скрестили дрон и Smart TV-приложение. А что из этого получилось — читайте ниже.

Идея была вполне реализуемая. Хотели сделать квадрокоптер в виде саней Деда Мороза, который бы сам и под музыку развозил по офису подарки для сотрудников. При этом ориентироваться в пространстве он должен был с помощью анализа ArUco-меток, взаимодействуя с приложениями для телевизоров («сдувание» работающими винтами дыма из труб, выбегание зверушек для встречи или провожания квадрокоптера).

И на всё три месяца. Конечно же, мы не успели.

Хотя в разное время над проектом работали до семи человек, результат оказался далек от идеала. В общем, мы научились только запускать коптер и написали приложение для телевизоров. Настроили взаимодействие квадрокоптера с телевизорами. Но обо всём по порядку.

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

Да, мы перерыли интернетики с целью найти библиотеку для управления контроллером коптера. Да, надо было передавать в клиент стримом изображение с веб-камеры и анализировать его на сервере. Да, нужно было сделать бомболюк. Да, надо в целом написать оболочку, которая бы это всё в себе собирала. Ну и что? Мы всё это уже делали (кроме управления контроллером). Поэтому проекту дали зеленый свет.

Устройство

Каждая надсадно жужжащая у вас над головой эволюционная ошибка вертолета, в принципе, состоит из одного набора механизмов и схем. Это:

— контроллер;

— двигатели с винтами;

— аккумулятор;

— регулятор скорости (ESC);

— антенна телеметрии;

— GPS-модуль и компас;

— камера.

Последние два пункта опционально. Схему устройства винтокрылого друга можно увидеть вот тут:

Это добро ставится на корпус. Впрочем, корпус решили сделать свой. Потому что:

— Сами с усами;

— Нуждались в корпусе именно в виде саней;

— Уже неприлично дорого получалось.

Контроллер

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

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

Мы выбрали относительно мажорский контроллер. «Относительно», потому что я потом внимательнее посмотрел на монстров, которые предлагаются для серьёзных дядей… Тем не менее, контроллер имеет GPS, компас, автопилот, всякие прочие хорошие плюшки, поддерживает до восьми двигателей.

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

Двигатели

Этих друзей превеликое множество. Круглых, квадратных, кривых, косых, больших, маленьких, дорогих и дешевых. Основное отличие: максимальная потребляемая мощность, сила тока и количество оборотов в секунду. В идеальном представлении сани должны были уметь поднимать банку пива (0,5 кг).

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

Аккумулятор

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

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

Во-вторых, он не только жрет, но ещё и умеет оставлять заряд «про запас». Идея хорошая, потому что при достижении порогового значения напряжения, машина прерывает полет и совершает мягкую посадку, но выражается это в том, что банка «высаживается» ещё быстрее.

Регулятор скорости

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

Антенна телеметрии

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

Кстати, телеметрия осуществляется посредством подачи и передачи сигналов на список каналов. Программно ими тоже можно управлять, но это категорически не рекомендуется, потому что так мы фактически отказываемся от вшитого автопилота и пишем свой. На коленке. И вещества и палок. В последний вечер. Как мы любим.

GPS-модуль

Основной и практически единственный способ позиционирования летающего уничтожителя нервов в пространстве. Обычно GPS-модуль содержит в себе ещё и компас. Чтобы на него ничего не влияло в полете, модуль ставится на специальную штангу, чтобы вот совсем ничего не влияло. Мы его использовали только ради компаса, потому что в помещении GPS не очень хорошо ловит. Поддерживает и другие системы позиционирования.

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

Камера

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

Управление

Все поделки инженерной мысли сапиенсов, использующие контроллеры, в сущности управляются одной программой: Mission Planer. Выглядит она примерно так:

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

Само ручное управление можно осуществлять чем душе угодно. Есть настройки для пульта, для джойстика. Можно вывести управление на мышку и клавиатуру. Основное требование — откалибровать пульт управления. Ну и управлять вручную. Поскольку мы ленивые разработчики, то управлять вручную не хотелось. Хотелось, чтобы винтокрылый побочный результат мыслительной деятельности сам летал.

Программный контроль

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

Правило №2: неполная документация. Часто не пишут самые очевидные вещи

Например, для соединения из питона с контроллером необходимо указать адрес и порт: connectionString = ’127.0.0.1:14540′.

Но оказалось, что этот адрес и порт необходимо указать и в строке запуска прокси-сервера. Вот тут:

mavproxy.py —master=/dev/ttyAMA0 —baudrate 921600 —aircraft MyCopter

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

В последний момент выяснилось, что данных для подключения к дрону надо существенно больше. Условно, он должен начать отдавать данные в подключенную телеметрию, в противном случае, он её просто не подключал и сидел довольный.

Отсюда правило №3: используй USB

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

Тестовый полет

И тут внезапно выяснилось, что:

— Коптер летает неровно;

— Ошибки его телеметрии /- метр и более;

— Для полета адекватны задачи типа: поднимись на 10-20 метров, пролети 100 метров на север и так далее.

Напомню, что эта конструкция, созданная под влиянием вертолетов из фильма «Аватар», запускалась в стенах офиса, где много оргтехники, с потолка свисают лампы, вентиляция и декор. Ну ещё и сотрудники имеются. В общем, очень быстро выяснилось, что серьезный полет в помещении чреват 160 отрубленными головами.

Правило №4: используй нормальные тестовые условия

Если летающий танк размером 50х60 см, то его нахождение в воздухе в замкнутом пространстве неминуемо приведет либо к его повреждению, либо повреждению находящихся рядом с ним. Идеальной тестовой зоной будет помещение размером со спортзал.

Компьютерное зрение

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

Пример меток:

Для реализации использовалась библиотека openCV. Она используется для распознавания вообще всего, что только есть, в частности: лиц людей, предметов, автомобильных номеров, ну и наших меток. Установка библиотеки на операционную систему малины — Rasbian — стала сущим кошмаром, с которым поочередно бились четыре человека.

Тем не менее, мы её успешно решили, и теперь машина «научилась» распознавать метки в видеопотоке с веб-камеры. Но опять-таки не хватило времени всё настроить. Например, из двух и более меток библиотека возвращала распознанные номера всех меток, а данные только по одной. Почему так? Тайна велика есть.

Правило главное: выделяй достаточно времени на доводку решения

Прочие органы чувств

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

Этот функционал мы не успели сделать совсем.

Маршруты

Мы много говорили про маршруты движения коптера. А что же это за звери такие? Скажу сразу, этот функционал был реализован самым первым и в полном объеме, но… не пригодился.

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

Поскольку для каждой вершины мы знаем её координаты, а у коптера мы знаем его расположение (компас) и положение (метки), то вычислить куда надо лететь — чисто технический вопрос. Задача поиска пути между стартовой точкой и финишной решена рекурсивной функцией. Маршруты, ребра и вершины хранятся в развернутой на малине БД.

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

Технологический стек

Коптер: Raspberry Pi, Rasbian, OpenCV, Python 3.5, aiohttp, DroneKit, RPi.GPIO, SQLite.

Сервер с динамикой для ТВ: node.js, Express, socket.io.

Приложения для ТВ: JavaScript ES6, webpack 2, Canvas.

Репозиторий с кодом коптера вот тут. За звездочки — плюсы в карму.

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

— Raspberry Pi. Полноценный микрокомпьютер с имеющимися пинами и выходами для специальной камеры и сенсорного экрана. Именно на нем расположен управляющий код, веб-сервер, openCV библиотека. По сути коптер — это летающий сервер.

— Rasbian. Линуксовая операционная система для «малины». Их несколько и вообще можно ставить любые, но лучше ставить специально предназначенные, иначе могут возникнуть проблемы со взаимодействием с оборудованием компьютера, с теми же пинами, к примеру. Есть даже адаптированная версия десятой Windows.

— OpenCV. Библиотека для распознавания элементов в видеопотоке. Также умеет стримить видеопоток, что используется в проекте для выдачи изображения на клиент (да, у коптера есть свой веб-клиент).

— Python 3.5. Питон. 3.5. Не 2.*.

— Aiohttp. Асинхронный фреймворк для веб-сервера, написанный на питоне. Почему-то он понравился больше Django. Но тут на выбор.

— DroneKit. Библиотека для подключения к контроллеру коптера из программы. Весьма богатый функционал, помноженный на относительно неплохую документацию. При условии отсутствия аналогов — блестящий инструмент.

— RPi.GPIO. Библиотека на питоне для взаимодействия с пинами «малины». Позволяет включать и выключать пины, слушать их значения. Не умеет передавать значения, отличные от 0 или 1. Или я не нашел.

— SQLite. СУБД БД дрова, объединенные в один файл. Идеально подходит для учебных и непродовых проектов, если не надо разворачивать что-нибудь высоконагруженное. Удобно вносить изменения.

— Node.js. Серверный JavaScript.

— Express. Фреймворк для веб-серверов, написанный на node.js. Весьма удобен и минималистичен.

— Socket.io. Серверная и клиентская библиотека для реализации протокола webSocket. Основной плюс — стабильность работы и обширный предоставляемый функционал.

Выводы

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

Лично мне было интересно. И автоматизированный бомбардировщик-наноситель подарков я всё равно сделаю так или иначе. А всем заинтересовавшимся, пожалуй, оставлю:

Правило единственное: ставь высокие и сложные цели и иди к ним!

Удачи всем!

Raspberry pi flashlight control

Потихоньку продолжаем наращивать функционал и на этот раз займемся светодиодами. У нас есть два XHP-50 диода и драйвер-контроля (см. раздел «Выбор компонентов»). Они очень хорошо греются, поэтому без радиаторов использовать их никому не рекомендую. На том же сайте, благо, они есть. Главное, не напутать с размером.

Итак, прикручиваем диоды на радиатор, паяем минус одного к плюсу другого (на них есть маркировка) и припаиваем минусовой и плюсовой провода:

Далее смотрим на наш контроллер и тоже паяем.

Питание — 12V плюс и минус, можно запитаться тем же, чем и питаем двигатели. Выводы на диод соединяем с ранее припаянными соответственно L- к минусу, L  к плюсу. Аналоговый контакт (А) в данной реализации не нужен, оставляем пустым.

Теперь нас интересует цифровой вход (D) и земля (G). Коннектим цифру (D) на GPIO 11 и землю на многострадальный GND (любой, можно один). Теперь возвращаемся к нашей Raspberry PI, создаем файлик light.js и добавляем следующее:

//Наша знакомая библиотека
const Gpio = require('pigpio').Gpio;
//Создаем Gpio для нашего пина
const light = new Gpio(11, {mode: Gpio.OUTPUT});
// Значение можно ставить от 0 до 255 (из доков по драйверу светодиода)
const LIGHT_MIN = 0;
const LIGHT_MAX = 255;
//Нужно будет для вычислений
const LIGHT_DIAPASONE = LIGHT_MAX - LIGHT_MIN;
//Выключаем светодиод изначально (система стартует с включенными на максимум светодиодами)
light.pwmWrite(LIGHT_MIN);
//Экспортируем методы работы
module.exports.light = {
  on: () => {
    //Передаем на драйвер значение 255
light.pwmWrite(LIGHT_MAX);
  },
  off: () => {
//Передаем на драйвер значение 0
    light.pwmWrite(LIGHT_MIN);
  },
//Здесь принимаем значение в процентах от 0 до 100
  set: (val) => {
    if(val < 0 || val > 100) return;
//Вычисляем значение исходя из процента
    val = Math.round(LIGHT_MIN   LIGHT_DIAPASONE / 100 * val);
    console.log("Light:" val);
//Передаем на драйвер значение
    light.pwmWrite(val);
  }
}

Запустить можем из нашего app.js так же, как и engines:

const light = require('./light.js').light;
light.on();
light.off();
light.set(50);

Видеодемонстрация готового решения:

Если понять главную идею, то все предельно просто: подключил, подал сигнал, смотришь результат. Грубо говоря, это весь функционал контроля, который нам нужен для активизации элементов. Но все это бесполезно без какого-то контроллера, который и будет включать/регулировать все это, а это говорит о том, что надо построить коммуникацию между сервером и клиентом. Значит придумаем протокол 🙂

Видео stream

Тут было проделано достаточно много работы для подбора необходимых способов стриминга.

HLS сразу отпал, так как задержка была порядка 10 секунд. При желании можно было добиться 5, но это все равно далеко не то, что надо. В управлении крайне необходимо передать видео с минимальной задержкой. Но передачу организовать не сложно, что со стороны Raspberry, что отображение с Android.

RTMP уже будет потяжелее. Проблема в том, что не было особо простого варианта реализации на Android (на момент конца 2023 года). Есть платные варианты, с которыми тоже повозиться, есть многострадальный VLC, который надо компилить с C и настраивать, есть уже собранный VLC как библиотека, который тоже из коробки не хотел проигрывать.

Зато нашел очень даже рабочее решение, которое подходило по моим параметрам. RPi Camera Viewer for Android — решение, которое получает Raw H.264 поток с камеры и отображает на TextureView c использованием нативного MediaCodec. Если честно, то я до конца не раскрутил всю логику отображения, но собрал и чуть модифицировал под себя для использования.

Со стороны Raspberry команда запуска потока будет следующая:

raspivid -t 0 -w 1280 -h 720 -hf -ih -fps 10 -o - | nc -k -l 2222

Raspivid — команда, которая осуществляет «захват» видео с подключенной камеры (но не USB, а именно подключенной шлейфом). Параметры выбирал методом «научного» тыка. Качество 1280×720, частота кадров 10fps. Безумно мало, но минимальная задержка.

И весь поток, который транслируется с камеры передается без изменений командой Netcat на 2222 порт.

Приложение на Android коннектится к нему и уже обрабатывает видео, отображая на экране.Неделю вечеров пришлось потратить на поиск и тестирование таких простых решений, так как общение с Raspberry для меня было в новизну, как и стриминг с Unix-системы.

Настройка raspberry pi сервера

Теперь перейдем к настройке Raspberry PI.

  1. Качаем последний дистрибутив системы тут.
  2. Скачиваем и устанавливаем Etcher.
  3. Вставляем пустую microSD флешку в картридер (тут уже сами думайте, где их взять).
  4. Открываем Etcher и выбираем zip или img Raspbian, который скачали на первом шаге.
  5. Нажимаем ’Flash!’
  6. Ждем окончания установки и извлекаем microSD.
  7. Вставляем флешку в наш Raspberry.

DIY. Подводный дрон. История одного сумасшествия

Подключаем к сети Wi-Fi, и в целом система готова. Я бы советовал настроить ваш роутер и дать static IP адресс для малины, ибо подключаться будем именно по IP.

Если вы уже работали с Linux, то дальнейшие действия вам будут не дики. Самым простым способом создать серверное приложение будет NodeJS. Разобраться, что да как не составляет труда, так как в Гугле еще никого не банили. Открываем терминал и поехали:

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install -y nodejs

И проверочно запускаем node -v, дабы точно понять, что все установилось.

Можно сразу слить весь проект с репозитория и запустить (ссылка будет в конце статьи), но разве мы здесь ради этого собрались? 🙂 Теперь создаем папку нашего проекта mkdir ~/drone и переходим в нее cd ~/drone и инициализируем проект: npm init. Установщик спросит название и индекс файл — укажем app.js.

https://www.youtube.com/watch?v=j9hlP4FTKOk

После инициализации ставим express: npm install express. И создаем файл app.js: touch app.js.

Для тех, кто работает с GUI (моник и клава), советую поставить Atom. В нем очень даже удобно писать js-код. Для остальных — Vim, Nano, MCEdit (и сами знаете).

Далее добавляем код в app.js и сохраняем файл:

'use strict';
const express = require('express');
const net = require('net');
const app = express();

const server = net.createServer((socket) => {
  socket.on('data', (data) => {
    var command = data.toString();
  	console.log(err);
  });
}).on('error', (err) => {
  console.log(err);
  // handle errors here
  // throw err;
});
server.timeout = 0;
// grab an arbitrary unused port.
server.listen(49655, () => {
  console.log('opened server on', server.address());
});

И запускаем из консоли node app.js в папке(!!) drone. Теперь у вас крутится сервер, который слушает подключения на 49655 порт. Запомним: наш локальный IP (ifconfig в консоли) и все подключения будем производить на IP:49655.

Сейчас давайте усложнять конструкции 🙂

Настройка wi-fi и графической оболочки

Теперь нам нужно подключиться к Интернету через Wi-Fi-адаптер на Raspberry. Предполагается, что у вас уже есть точка доступа Wi-Fi.

Первый шаг — определить имя вашего беспроводного сетевого интерфейса. Оно может быть разное, но обычно это wlan0:

ls /sys/class/net/

Затем перейдём в каталог /etc/netplan и найдём соответствующие файлы конфигурации Netplan. Файл конфигурации имеет имя типа 50-cloud-init.yaml:

ls /etc/netplan/

Отредактируем файл конфигурации Netplan:

nano /etc/netplan/50-cloud-init.yaml

Весь файл конфигурации должен выглядеть примерно так, как показано ниже. Убедитесь, что все блоки кода выровнены. Для выравнивания используйте пробелы вместо табуляции. Замените строки SSID и PASSWORD на имя и пароль вашей сети Wi-Fi.

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
	ethernets:
		eth0:
			dhcp4: true
			optional: true
	version: 2
	wifis:
		wlan0:
			optional: true
			access-points:
				"SSID":
					password: "PASSWORD"
			dhcp4: true

Запустим службу, перезагрузимся и войдём в систему:

systemctl start wpa_supplicant
reboot now

Применим изменения Netplan и подключимся к беспроводной сети:

sudo netplan generate
sudo netplan apply

https://www.youtube.com/watch?v=S04r5wE7Q0c

Ещё раз перезагрузимся и снова войдём в систему. Теперь наша Raspberry в сети Wi-Fi, и мы можем пропинговать наш сетевой шлюз:

ip addr show
ping 192.168.88.1

Следующим шагом будет установка графического интерфейса для удобства работы с операционной системой. Обновим список пакетов из репозитория, обновим сами пакеты и установим любую понравившуюся графическую оболочку. Например, мы выбрали XFce:

sudo apt-get update && apt-get upgrade
sudo apt-get install xubuntu-desktop

Установка графической оболочки может занять некоторое время. После установки перезагрузимся и войдём в систему под ubuntu.

Настройка и запуск ardupilot

Релизы новых версий Ardupilot немного запаздывают в сборке от Emlid. Если необходимый функционал доступен в самой последней версии, то установить ее из исходников можно

Разработчики Navio добавили в свою сборку простую и удобную утилиту Emlid tool для проверки датчиков и настройки Ardupilot. Сначала проверим, видит ли Raspberry контроллер Navio:

emlidtool info

Если в ответ на эту команду выдает что-то вроде:

Vendor: Emlid Limited
Product: Navio 2
Issue: Emlid 2023-06-05 831f3b08594f2da17dccae980a2e3659115ef71f
Kernel: 4.14.34-emlid-v7 
RCIO firmware: 0xcaec2284

значит видит. Проверим состояние датчиков (покажет список и состояние):

emlidtool test

и драйвера ШИМ-контроллера в ядре Linux:

cat /sys/kernel/rcio/status/alive

0 = не работает, 1 = работает.

Прошивка ШИМ-контроллера обновляется так:

sudo emlidtool rcio update

Теперь настроим Ardupilot:

sudo emlidtool ardupilot

В терминале откроется текстовый GUI с пошаговыми менюшками. Выбираем copter последней версии, тип

arducopter

, автозапуск при включении (

On boot: enable

), старт после настройки (

Ardupilot: start

Выходим через пункт меню Quit.

Проверим запустился ли Ardupilot:

sudo systemctl status arducopter

Обратите внимание, файл запуска в systemd называется

arducopter

, так как настроен был вариант

copter

Теперь нужно настроить Ardupilot так, чтобы он отправлял нам телеметрию. Для этого отредактируем файл конфигурации:

sudo nano /etc/default/arducopter 

В нем должны быть такие строки:

TELEM1="-A udp:127.0.0.1:14550"
ARDUPILOT_OPTS="$TELEM1"

Сохраняем файл (

Ctrl X

, затем

Y

) и перезапускаем Ardupilot:

sudo systemctl daemon-reload
sudo systemctl restart arducopter


Проверить состояние процесса Ardupilot можно такой командой:

sudo systemctl status arducopter

С такими настройками Ardupilot будет транслировать телеметрию (пакеты

) в локальный UDP-порт 14550. Далее, скрипт

(описание ниже) будет забирать оттуда телеметрию и передавать в GCS или скрипт, а также отправлять в обратном направлении пакеты с командами.

Вместо локального адреса и порта можно записать IP-адрес ПК или планшета в локальной сети и пакеты будут транслироваться сразу туда.

Однако, такой подход оправдан, если данные телеметрии больше нигде не используются и у устройства с GCS статический IP адрес. Иначе каждый раз в настройках Ardupilot придется прописывать новый. Чтобы общаться с автопилотом по TCP могли одновременно несколько GCS с динамическими адресами и еще какие-нибудь скрипты на самом бортовом компьютере, удобнее использовать MAVProxy.

Этот скрипт (написан на Python) может получать пакеты MAVLink на локальный UDP-адрес и ретранслировать их на несколько локальных или удаленных IP-адресов как по UDP, так и по TCP. Пакеты передаются в обоих направлениях Ardupilot ⇔ GCS. Кроме того, MAVProxy представляет из себя полноценную GCS, но с текстовым интерфейсом.

Привод с omni-колёсами

Этот тип привода использует особые Omni-колёса или поликолеса вместо обычных. Поликолесо — это всенаправленное колесо с небольшими роликами, расположенными по окружности. Оси роликов перпендикулярны оси вращения колеса. Контролируя скорость и направление вращения поликолёс, вы можете заставить робота двигаться в любом направлении — другими словами, сделать его движение голономным.

Обычно шасси с Omni-колёсами насчитывает ровно 3 или 4 колеса. Шасси с тремя колёсами обеспечивает большую тягу, поскольку любая реактивная сила распределяется только через три точки, и робот хорошо сбалансирован даже на неровной местности. Всенаправленные колёса имеют высокую стоимость, поэтому трёхколёсное шасси обходится заметно дешевле варианта с четырьмя.

Чаще всего для трёхколёсного шасси выбирают угол установки 120°. Иногда два колеса параллельны друг другу, а третье ставится перпендикулярно к ним. Последняя конструкция может быть более эффективной, потому что когда колёса расположены под углом 120°, только одно из них является ведущим, а два других по сути тормозят его, снижая общую скорость.

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

Пример определения векторов скоростей колёс для трёхколёсного шасси:

Четырёхколёсное шасси имеет четыре ведущих колеса, расположенных под углом 90° друг к другу. Эта конструкция удобнее для расчёта скоростей, так как два колеса параллельны друг другу, а два других перпендикулярны к ним. Как и в трёхколёсном шасси, КПД всех колёс также не используется на 100%.

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

Пример определения скорости вращения колёс для четырёхколёсного шасси:

Особенности шасси:

  • Поскольку всенаправленные колёса представляют собой комбинацию из множества роликов, возникает сопротивление вращению, что приводит к повышенному трению и значительным потерям энергии.
  • Не все колёса являются ведущими, в каждый момент времени эффективно работают лишь одно-два поликолеса.
  • С помощью Omni-колёс достигается голономное движение робота.
  • Работа поликолёс изначально строится на принципах проскальзывания. Невозможно поставить датчик вращения на каждый ролик Omni-колеса, поэтому полученная колёсная одометрия совсем неточная.
  • Чаще всего роботы с таким шасси используются внутри помещений на ровных и гладких поверхностях.

Программирование esc

К сожалению, Afro ESC из коробки имеет только одно направление вращения, поэтому надо «шить». Самая засада в том, что надо ждать линкер из Китая, остальное детали. Предположим, что он у вас уже есть 🙂

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

Качаем файл прошивки на диск и программу для прошивки KKMulticopter Flashtool.

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

  1. Пара красный-черный толстых кабелей с бананом «папой» на конце. Силовое питание двигателя. Я подавал 12 вольт и ампер — сколько просило 🙂
    1. Красный — ВХОД плюс.
    2. Черный — ВХОД минус.
  2. Толстые провода красный-черный-желтый — питание на двигатель. Пока мы их не трогаем, но в дальнейшем будем соединять на аналогичные «цвета» электродвигателя.
  3. Тонкие провода управления и питания.
    1. Желтый — это непосредственно кабель, по которому передаем сигнал управления.
    2. Красный — выход 5в (в целом я его не использовал). Их есть несколько разных типов, если захотите — читайте.
    3. Черный — минус.

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

Открываем программу прошивки и выбираем:

Programmer: Turnigy USB Linker or Afro USB Linker (зависит о того, что у вас есть).Port: собственно тот USB, куда включили. Благо, выбор там не велик.Baud rate: 9600.Controller: atmega 8-based brushless ESC (8kB flash).

И выбираем уже скачанный файл прошивки. Жмем кнопку «Run» и молимся 🙂 Скоро прошивка успешно зальется на ESC, и все будет готово. Весь процесс можете посмотреть здесь:

Из 8-ми программируемых мною ESC сдох только один 🙂

Протокол общения

Как вы поняли из первоначальной настройки Raspberry PI, общение будет произведено по сокет подключению. И нужен какой-то набор команд, который будет захардкожен на сервере и клиенте. Так как я сам себе д’артаньян, то решил использовать свой формат, ибо варианты, которые есть, не совсем подходят по критерию вес/читаемость. Строим, основываясь на базе модели управления, а это телефон с Android на борту.

Вот приблизительно и сама модель (программа будет описана чуть ниже). Экран разделен на две части. Левая отвечает за горизонтальную плоскость (вперед и назад), правая — за вертикальную. Ставите палец в какой-то области — это считается точкой отсчета и контроля парой двигателей, но при этом это точка спокойствия.

Если ведете его вертикально вверх — потихоньку повышается скорость вращения обоих двигателей в прямом направлении с мощностью от 0 до максимума (зависит от расстояния от точки касания до текущей).

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

Если вправо: левый крутится в прямом, правый в реверсном.

То есть по факту нам нужно знать угол отклонения от точки касания (где верх = 90, низ — 90, право 0, лево 180) и коэффициент скорости — удаленность пальца от точки касания (от 0 до 100). Конечные команды выглядит так:

C:L;A:45;V:35;
C:R;A:0;V:100;
C:LIGHT;V:50;

С — любая команда начинается с этой буквы (command);

: — разделитель ключ-значения;

; — разделитель пар ключ-значение;

L — говорит, что нажатие было в левой части экрана;

R — соответственно в правой;

LIGHT — внезапно, свет 🙂

A — ANGLE угол отклонения;

V — value значение чего-то.

То есть первая команда говорит: «Горизонтальна пара двигателей, направление 45 градусов (левый на максимуме (но максимум — это 35%, исходя из V), правый стоит), со скоростью вращения 35% от максимума».

Вторая соответственно: «Вертикальная пара двигателей, направление 0 градусов (левый на максимуме, правый на максимальном реверсе), с максимальной скоростью вращения». Третья: «Включить свет на 50% яркости».

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

Сборка и тестирование конструкций

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

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

Вот такой адок получился в итоге:

Был забит болт на потери при передаче (кабеля было 10 метров) и на основные косяки такого решения. Потому основная цель была посмотреть:

  1. Можно ли жить с 4-мя движками?
  2. Можно ли управлять с телефона?
  3. Будет ли затекать вода в коробку?

Но я упустил один важный момент, о котором Серега меня предупреждал. После теста в ванной все эти контакты надо было хорошенько просушить, ибо они — самое слабое звено. А я забил и получил в итоге комбо из 48 мест(!!!) соединения, которые могут (а если могут — обязательно будут) терять контакт.

Здесь как на всех мемасиках ожидание-реальность.

Тест в ванной:

Его сильно кренит из-за проводов, но он способен перемещаться. Ну и чутка перегружен грузами, так как коробка пустая — не рассчитал. А вот следующий тест в «поле» оказался еще хуже:

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

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

Так как никто не был уверен, что на глубине 10  метров эта конструкция не даст течь и не зальет электронику — решили сделать усиленный вариант «коробка в коробке». Заказали в Китае все необходимое и приступили к дальнейшей сборке:

В коробке были просверлены отверстия для проводов, которые выходили через cable glands (забыл, как они называются по-другому).

Дополнительно была прикручена коробка для диодов и камеры. Естественно, на резиновую прокладку и плотненько зажата винтами. Далее была спаяна плата соединений, с отдельными разъемами под каждый ESC, драйвер диода и гироскоп.

Типы приводов

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

Роботы могут передвигаться в 2D- или 3D-пространстве. Очевидно, что только летающие роботы способны маневрировать во всех плоскостях, и они чрезвычано сложны. Например, летающие дроны ориентируются в помещении или на местности, используя трёхмерные камеры глубины.

Если роботу нужно передвигаться только в двухмерном пространстве, всё становится уже проще. Мы можем рассмотреть движение робота как движение материальной точки в плоскости (X, Y) в прямоугольной или Декартовой системе координат (X, Y, Z).

Движение робота в плоскости может быть голономным (Holonomic) или неголономным (Non-holonomic). Что это значит? При голономном движении робот способен свободно двигаться по любому вектору XY, не меняя при этом своей ориентации. При неголономном движении робот может передвигаться только в нескольких ограниченных направлениях.

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

Вы, наверное, спрашиваете себя: «Зачем мне всё это нужно знать?» Понимание того, каким именно образом движется робот, и понимание принципов получения проекций его скоростей в системе координат чрезвычайно важно при создании управляющей программы. Чем больше направлений движения и вращения имеет робот, тем сложнее сконструировать его механику и контролировать его движение.

Ещё одиним важным фактором при выборе привода робота является сложность получения одометрии и её точность.

Одометрия — это использование данных с установленных на роботе сенсоров и датчиков для расчёта его текущего положения и ориентации в пространстве. С некоторых приводов получить качественную одометрию очень легко — например, с двухколёсного дифференциального привода (2WD differential drive).

Мы попробовали собрать самые популярные способы передвижения для хобби-роботов.

Управление электродвигателями с raspberry pi

Итак, начинаем самую веселую часть нашей работы — пишем управление на Raspberry PI. Идем в папку проекта ~/drone и устанавливаем PiGpio библиотеку:

sudo apt-get update
sudo apt-get install pigpio
npm install pigpio

Теперь небольшой ликбез по управлению ESC. Нам надо передать некую частоту на управляемый провод (желтый тонкий) (см. раздел «Программирование ESC»). Прошивка afro_nfet_besc30_r1 имеет диапазон 1100-1900, где значение 1500 — состояние спокойствия, 1100 макс реверс, 1900 макс форвард.

Создаем файлик engines.js и в него добавляем JS-код:

//Константа состояния спокойствия
const SERVO_ZERO = 1500;
//Подключаем библиотеку 'pigpio'
const Gpio = require('pigpio').Gpio;

//Определяем наши 4 двигателя по пинам расбперри (пиновка будет объяснена чуть ниже)
const servo1 = new Gpio(22, {mode: Gpio.OUTPUT});
const servo2 = new Gpio(10, {mode: Gpio.OUTPUT});

const servo3 = new Gpio(9, {mode: Gpio.OUTPUT});
const servo4 = new Gpio(27, {mode: Gpio.OUTPUT});

//Устанавливаем каждой плате состояние “спокойствия”
servo1.servoWrite(SERVO_ZERO);
servo2.servoWrite(SERVO_ZERO);
servo3.servoWrite(SERVO_ZERO);
servo4.servoWrite(SERVO_ZERO);

//По вызову этого метода пишем значение в наш ESC
module.exports.engines = {
  leftEsc: (value) => {
    servo1.servoWrite(value);
  },
  rightEsc: (value) => {
    servo2.servoWrite(value);
  },
  topLeftEsc: (value) => {
    servo3.servoWrite(value);
  },
  topRightEsc: (value) => {
    servo4.servoWrite(value);
  }
}

Дабы использовать этот код, пишем в app.js:

const engines = require('./engines.js').engines;
engines.leftEsc(*VALUE[1100;1900]*);

Собственно говоря, servo1.servoWrite() — и есть магическое управление. Подаем 1100 — двигатель крутится в реверсном направлении. Подаем 1900 — max forward. А вот распиновка нашей малины:

Если вкратце, то мы используем оранжевые GPIO. Одна пара GPIO 10 — GPIO 22, вторая GPIO 9 и GPIO 27 (логичнее было бы использовать 27;22 10;9, но при пайке не учел, и пришлось поменять). Если брать по порядочным числам (указаны серым), то это 13;15 и 19;21 контакты. На каждый из них подключаем желтые провода из ESC, а минус же объединяем в один GND, к примеру 39 контакт.

Осталось подключить остальное. Коннектим провода питания (красный и черный) Afro ESC к отдельному блоку питания(12v), подключаем моторы к желтый-красный-черный толстым проводам и уже можем играться. Например, допилить код и по интервалу подавать разные сигналы на пины. Небольшое видео, правда, там управление осуществляется с Android, но это опишу немного позже:

Энкодеры

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

Абсолютный энкодер выдаёт сигнал, который однозначно соответствует углу поворота вала. Энкодеры этого типа не требуют привязки системы отсчёта к какому-либо нулевому положению.

Инкрементальный энкодер генерирует импульсы на выходе. Контроллер подсчитывает количество импульсов с помощью счётчика и определяет текущее положение вала. Сразу после включения контроллера положение вала неизвестно. Для привязки системы отсчёта к нулевой позиции существует специальная нулевая отметка, через которую вал должен пройти после включения.

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

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

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

Наиболее популярны квадратурные энкодеры с двумя каналами А и В. Реже у энкодеров в хобби-сегменте есть канал с нулевой отметкой — Z. Чем выше значение PPR, тем меньше угол поворота вала, который может зафиксировать датчик. Чем точнее энкодер, тем точнее одометрия робота, поэтому не пренебрегайте высококачественными энкодерами и не используйте энкодеры с низким значением PPR.

Максимальная скорость вращения может быть любой, так как большинство энкодеров способно работать на очень высоких скоростях. Скорее всего, скорость вращения, которую вы будете измерять, будет в несколько раз меньше максимальной. Даже если вы планируете использовать высокоскоростные BLDC двигатели с высоким значением kv, то существуют энкодеры, которые работают с максимальными скоростями 28000 об/мин, 60000 об/мин или даже больше.

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

Мы обзавелись двумя такими двигателями с энкодерами — мотор-редуктор TT с энкодером (160 об/мин, 6 В, 120:1).

Почему мы выбрали именно эти моторы?

  • Во-первых, их конструкция специально разработана для нашего шасси Turtle, и нам не придётся придумывать крепление.
  • Во-вторых, производитель исправил существенные недостатки, заменил пластиковые шестерни металлическими и добавил схеме двигателя обвязку.
  • Эта сборка имеет квадратурный магнитный энкодер с разрешением 16 PPR, установленный на валу двигателя. Передаточное отношение редуктора 120:1 даёт полное разрешение в 1920 импульсов на оборот колеса с минимальным измеряемым шагом в 0°11’15″. Для поставленной нам задачи такой точности более чем достаточно.

Заменив моторы и убрав всё лишнее, мы получили вот такое шасси:

Смотрите про коптеры:  Вернуть квадрокоптер качественый и бракованный в магазин - инструкция в 2023 году
Оцените статью
Радиокоптер.ру
Добавить комментарий