MAVLink это очень облегченный протокол обмена сообщениями для коммуникаций с дронами (и между бортовыми компонентами дронов).
MAVLink следует современной гибридной схеме публикации-подписки (publish-subscribe) и шаблону организации взаимосвязи точка-точка (point-to-point): потоки данных отправляются / публикуются как темы (topics), в то время как конфигурация подчиненных протоколов, таких как протокол функционирования (mission protocol) или протокол параметров (parameter protocol) является point-to-point с повторной передачей (retransmission).
Примечание: расшифровку незнакомых терминов и сокращений см. в Словарике MAVLink, в конце статьи.
Сообщения протокола определяются стандартным способом через файлы XML [2]. Каждый файл XML определяет набор сообщений, поддерживаемых частной системой MAVLink, что также называют диалектом. Набор справочных сообщений, реализуемый большинством наземных станций управления и автопилотов, определен в common.xml (большинство диалектов строится на основе этого определения).
Генераторы кода [3] создают из этих XML-описаний готовые программные библиотеки для определенных языков программирования. Эти библиотеки можно использовать для обмена данными в дронах, наземных станциях (пультах) управления, и в других MAVLink-системах. Генерируемые библиотеки обычно имеют защиту лицензией MIT, и таким образом могут без каких-либо ограничений использоваться в любых приложениях, в том числе и с закрытым исходным кодом.
Примечание: C-реализация состоит библиотеки состоит только из заголовочных файлов (*.h), и она жестко оптимизирована, что хорошо подходит для встраиваемых систем, ограниченных по ресурсам памяти (RAM, flash). Это проверенное решение, используемое во многих продуктах, обеспечивающее надежное взаимодействие между компонентами от разных производителей.
Ключевые особенности MAVlink:
• Очень высокая эффективность. MAVLink 1 использует только 8 байт дополнительной информации на пакет, включающей поддержку сигнала старта (start sign) и детектирования пропуска пакета (packet drop). MAVLink 2 использует уже 14 байт служебной информации (однако этот протокол более безопасный и расширяемый). Поскольку MAVLink не требует дополнительного кадрирования, он очень хорошо подходит для приложений, где используется очень ограниченная полоса пропускания канала. • Очень надежный. MAVLink используется с 2009 года для обмена между различными моделями, пультами управления (и другими узлами) по различным и сложным каналам связи (с высокой задержкой и шумами). Он предоставляет методы обнаружения отбрасывания, повреждения пакетов и их аутентификацию. • Можно использовать множество популярных языков программирования на различных микроконтроллерах и операционных системах (ARM7, ATMega, dsPic, STM32, а также Windows, Linux, MacOS, Android и iOS). • Позволяет сосуществовать в сети до 255 конкурентных систем (модели, пульты управления, и т. д.). • Позволяет реализовать как внешние коммуникации (offboard, т. е. как пример между наземной станцией управления и дроном), так и внутренние (onboard, например между автопилотом и бортовой камерой, управляемой через MAVLink).
Список поддерживаемых языков и генераторов см. [1].
Отличие версий MAVLink 1 и MAVLink 2. В основном протокол версии 2 разработан как расширение версии 1, т. е. в версии 2 сохраняется обратная совместимость с протоколом версии 1. Максимальный размер пакета у MAVLink v1.0 составляет 263 байта, а у MAVLink v2.0 составляет 280 байт, максимальный размер полезной нагрузки у обоих версий 255 байт (определяется макросом MAVLINK_MAX_PAYLOAD_LEN в заголовочном файле mavlink_types.h сгенерированной библиотеки). Вероятно размер пакета был выбран с привязкой к LoRa. Более подробно про особенности версий протокола см. [7].
[Пошаговое руководство для новичка]
1. Определитесь с диалектом вашего протокола MAVlink. Т. е. нужно подготовить XML-файл, где будут описаны передаваемые сообщения протокола. За основу можно взять готовый XML-файл из папки message_definitions/v1.0 репозитория [4].
2. Скачайте пакет генератора C-библиотеки. Рекомендую утилиту mavlink [5], она написана на Python и имеет простой интерфейс как командной строки, так и GUI. Если у вас возникли трудности с установкой, то см. врезку ниже.
MAVLink Toolchain это пакет утилит, предназначенный для автоматической генерации библиотеки пользователя MAVLink из предоставленного XML-файла с описанием диалекта.
В состав этого пакета входят XML-определения MAVLink [2], а также 2 варианта утилиты генератора библиотеки, оба написаны на Python: одна с интерфейсом командной строки, другая GUI. Обе утилиты генерируют исходный код библиотеки MAVLink на выбранном пользователем языке программирования. Доступны варианты языков для генерируемой библиотеки: C, C++11, CS, Java, JavaScript, JavaScript_Stable, JavaScript_NextGen, TypeScript, Python, Python2, Python3, Lua, WLua, ObjC, Swift, также можно выбрать версию протокола MAVLink: 1.0 или 2.0.
Замечание: вам не нужно устанавливать этот тулчейн, если вы используете язык программирования C и стандартный диалект [2] для своего проекта. В этом случае просто загрузите готовые библиотеки (см. Prebuilt MAVLink C Libraries) перейдите к документации по из использованию (см. Using C Libraries).
Чтобы использовать MAVLink, вам понадобятся следующие программы и библиотеки:
Python 3 Python 3 Pip TkInter (библиотека Python, которая нужна для GUI-утилиты генератора), она включена в Python 3.7.
Если вы создаете новые определения XML, то должны установить lxml и libxml2 для проверки на корректность XML и для форматирования XML.
[Установка MAVLink toolchain]
1. Установите Python 3.7+:
На Windows: загрузите Python for Windows (https://www.python.org/downloads/). Ubuntu Linux проверьте, что у вас установлены Python и Pip:
$ sudo apt install python3 python3-pip
2. Выполните клонирование официального репозитория mavlink:
Генерировать код библиотек MAVLink можно с помощью двух программных инструментов:
• GUI-утилита: mavgenerate. • Утилита командной строки: mavgen, которая используется утилитой mavgenerate как фоновый инструментарий.
Эти утилиты генераторов могут синтезировать библиотеки версий MAVLink 2 и MAVLink 1 для следующих языков программирования: C, C++11, CS, Java, JavaScript, JavaScript_Stable, JavaScript_NextGen, TypeScript, Python, Python2, Python3, Lua, WLua, ObjC, Swift. Для MAVLink 1 доступны только языки C#, JavaScript, ObjC, Swift.
Предварительные требования. У вас должен быть установлен MAVLink toolchain (см. врезку выше), где содержатся как утилиты mavgenerate и mavgen, так и XML-определения сообщений [2]. Если вы генерируете сообщения для своего диалекта, то сделайте копию файла (файлов) определений в директорию message_definitions/v1.0/.
[Сборка библиотек с помощью Mavgenerate GUI]
Программа mavgenerate.py это Python-скрипт графического интерфейса генератора библиотек для MAVLink. Она под капотом запускает утилиту командной строки mavgen, и поддерживает те же самые опции.
GUI-утилиту можно запустить в любом месте, указав аргумент -m в командной строке Python:
$ python3 -m mavgenerate
В после выполнения этой команды вы увидите следующий интерфейс:
Для генерации библиотечного кода MAVLink выполните следующие действия:
1. Выберите целевой файл XML, из которого должна генерироваться библиотека (кнопка Browse напротив поля ввода XML). Это может быть как готовый файл, например один из XML-файлов каталога mavlink/message_definitions/1.0, так и ваш собственный файл, созданный на основе примера.
Если вы используете собственный диалект, то скопируйте в папку XML-файла вашего диалекта также файлы all.xml, common.xml, minimal.xml, взятые из каталога mavlink/message_definitions/1.0. Они могут понадобиться и должны находиться в одной директории, если ваш диалект зависит от этих файлов. Как вариант можно сделать копию вашего диалекта в каталог mavlink/message_definitions/1.0 и выбрать файл вашего диалекта из этого каталога.
2. Выберите целевую директорию, куда будет записана генерируемая библиотека (кнопка Browse напротив поля ввода Out). Это может быть любая пустая папка на диске (например mavlink/include).
3. Выберите один из вариантов языка программирования (кнопкой справа от метки Language), для которого будет сгенерирована библиотека.
В частности, для JavaScript есть 3 опции:
• JavaScript_Stable это старая версия, которая поддерживает только MAVLink 1.0. • JavaScript_NextGen более свежая версия, которая поддерживает MAVLink 1 и 2 с подписью. • JavaScript это "доверенный вариант" для рекомендуемой версии. В настоящий момент соответствует JavaScript_Stable.
4. Выберите целевую версию протокола MAVLink (кнопка справа от метки Protocol). Если генератор для выбранного языка это поддерживает, то используйте 2.0.
Предупреждение: попытка генерации закончится неудачей, если выбранная версия протокола MAVLink не поддерживается для выбранного языка.
[Генерация библиотек с помощью Mavgen Command Line Tool]
Скрипт mavgen.py это утилита командной строки для генерации библиотек MAVLink для различных языков программирования. Вы можете запустить утилиту mavgen из директории mavlink. Однако если вы решили запускать её из любого каталога, то необходимо добавить путь до содержимого директории mavlink в переменную окружения PYTHONPATH.
Замечание: скрипт mavgen.py является backend-ом, который использует GUI mavgenerate. Все, что описано далее, относится к обоим утилитам, как командной строки, так и GUI. Однако существует отличие в синтаксисе для опции --output: GUI-утилита задает имя выходного файла, а утилита командной строки имя выходной директории.
Ниже показан пример генерации библиотек MAVLink 2 для языка программирования C и использованием диалекта my_dialect.xml:
Скопируйте сгенерированные файлы библиотеки в каталог вашего проекта.
[Как использовать, на примере протокола UART]
4. Передача. Реализуйте низкоуровневую функцию передачи через последовательный порт. В зависимости от вашей системы это может быть функция, которая передает по одному байту, или функция, которая передает сразу блок байт:
comm_send_ch (chan, uint8_t) Функция, которая передает один байт через MAVlink-канал chan.
MAVLINK_SEND_UART_BYTES(chan, (const uint8_t *)buf, len) Функция, которая передает len байт данных из буфера buf через MAVlink-канал chan.
Пример формирования, проверки и передачи пакетов см. в сгенерированном файле MyMavlink/testsuite.h.
5. Прием. Вставьте вызов функции mavlink_parse_char на каждом получаемом байте. Например:
// Получена порция из received байт данных в буфере buf. mavlink_status_t status; mavlink_message_t msg; int chan;
int byteidx = 0; while(byteidx < received)
{
if (mavlink_parse_char(chan, buf[byteidx], &msg, &status))
{
printf("Received message with ID %d, sequence: %d from component %d of system %d\n",
msg.msgid, msg.seq, msg.compid, msg.sysid);
// В этом месте должна быть обработка данных в структурах status и msg.memset(&status, 0, sizeof(status));
memset(&msg, 0, sizeof(msg));
}
byteidx++;
}
Функция mavlink_parse_char накапливает и парсит приходящие данные по протоколу MAVlink. Функция может вернуть 0, 1 или 2. Если 0, то делать ничего не надо, пакет MAVlink еще не принят. Если функция возвратила 1, то это означает, что пакет был успешно принят, и данные могут быть использованы/проанализированы в структурах msg и status. Если функция возвратила 2, то произошла ошибка CRC.
В случае успешного возврата (когда функция mavlink_parse_char вернула 1) данные полезной нагрузки могут быть извлечены из msg с помощью вспомогательных функций наподобие mavlink_msg_status_get_имя_параметра, которые были автоматически сгенерированы в соответствующем заголовочном файле MyMavlink/mavlink_msg_xxxxxx.h.
В случае ошибочного возврата (когда функция mavlink_parse_char вернула 2) данные в msg могут быть недостоверны, и их использование может быть только с учетом определенного риска. Данные в структуре status можно потенциально использовать для оценки причины отказа.
Вы можете запрограммировать два одинаковых устройства, соединить их сигналы RXD и TXD, и проверить работу протокола MAVlink вызовом функции mavlink_test_all (определена в MyMavlink/testsuite.h).
[Пример PC-утилиты MAVlink]
Скачайте и скомпилируйте утилиту mavlink_control [6].
$ git clone https://github.com/mavlink/c_uart_interface_example.git
$ cd c_uart_interface_example
$ make
Подключите вашу систему к UART тестируемого устройства, и выполните команду:
$ ./mavlink_control -d /dev/ttyUSB1 -b 115200
Запустите передачу сообщений MAVlink на тестируемом устройстве. Обратите внимание, что на обоих сторонах обмена должны обрабатываться одинаковые диалекты MAVlink.
[Словарик MAVLink]
AGL altitude at ground level, высота над землёй.
APM относится к ArduPilotMega, специфический диалект или определение сообщения в протоколе MAVLink (APM это одна из реализаций MAVlink).
ARM Сокращение от "Armed", обычно означает о статусе устройства - активно оно (ARMED) или неактивно (DISARMED).
DCM означает Direction Cosine Matrix, косинусная матрица направления. Это матрица 3x3, используемая для представления поворотов, и способ представления ориентации, свободный от gimbal-lock. Это более надежный способ, чем углы Эйлера, которые могут пострадать ль gimbal lock.
EKF Extended Kalman Filter, алгоритм для вычисления позиции, ускорения и угловой ориентации MAV на основе данных гироскопов, компаса, GPS, скорости относительно воздуха и измерений барометрического давления.
ENU East North Up, относится к кадру с информацией о координатах устройства (см. также NED, FRD, FLU).
FLU Forward Left Up относится к кадру с информацией о координатах устройства (см. также NED, ENU, FRD).
FRD Forward Right Down, относится к кадру с информацией о координатах устройства (см. также NED, ENU, FLU).
GCS Ground Control Station, наземная станция управления.
gimbal lock потеря одной степени свободы, которая происходит когда два кардана гироскопа вращаются параллельно друг другу. Термин относится к способу представления угловых координат в пространстве (более подробно см. "Understanding Gimbal Lock and how to prevent it").
IMU Inertial Measurement Unit, инерциальный измерительный блок, в просторечии гироскоп - электронное устройство, которое измеряет и сообщает приложенную силу, угловое ускорение, а также иногда ориентацию в пространстве. Эти изменения используют акселерометры, гироскопы, а также иногда магнитометры. Когда используется магнитометр, то IMU называют IMMU (из Википедии).
MAV Micro Air Vehicle, дистанционно управляемая летающая модель.
NED North East Down, относится к кадру с информацией о координатах устройства (см. также FLU, FRD, ENU).
MSL Mean Sea Level, высота относительно уровня моря.
Odometry одометрия, оценка перемещения в пространстве, принцип измерения которого основан на движителе (колесо, гребной винт).
RC Remote Control, дистанционное управление.
RSSI Received Signal Strength Indicator, индикатор уровня принимаемого сигнала.
RTC Real Time Clock, часы реального времени.
UAV Unmanned Aerial Vehicle, беспилотник.
UAVCAN означает Uncomplicated Application-level Vehicular Computing And Networking. Это открытый коммуникационный протокол для распределенных вычислений и обмена данными, используемый в аэрокосмической технике и робототехнике. Аббревиатура звучит так, как будто в протоколе используется шина CAN, но на самом деле это отдельный протокол с собственным происхождением.