Протокол Mailbox | Беспроводная передача сообщений¶
Общее описание протокола¶
Mailbox - это протокол передачи данных между устройствами в сети WI-FI. Данный протокол был впервые реализован в контроллерах Трик, после чего получил поддержку со стороны квадрокоптеров Геоскан. Данные передаются побайтово в текстовом формате, принцип работы очень похож на работу с серийным последовательным портом (Serial / UART).
У каждого устройства в сети «почтовых ящиков» есть свой борт-номер, устанавливаемый пользователем в программе на этом устройстве. Борт-номер представляет собой целое число > 0, оно должно быть уникальным для каждого устройства в сети.
В сети нет главного устройства (отсутствует иерархия MASTER - SLAVES), каждый может общаться с каждым, однако это не распределенная сеть, поскольку при выходе из строя точки доступа WI-Fi, передача данных будет нарушена.
Точкой доступа не обязательно должен быть WI-Fi роутер, в качестве точки доступа может быть одно из устройств, выспутающих участниками сети обмена сообщениями, напрмер, квадрокоптер Геоскан Пионер Мини.
Примечание
Пионер Мини поддерживает лишь одно активное подключение по WI-FI, поэтому, если у вас обмениваться сообщениями должны больше двух устройств, то нужно перевести Мини в режим клиента и подключить к существующей WI-Fi сети (вашему роутеру, или, например, контроллеру Трик). Про подключение квадрокоптера к существующей сети можно почитать на странице описания веб интерфейса.
После подключения минимум двух устройств к WI-FI сети они могут начать обмениваться данными, для этого одно из этих устройств
(и каждое новое подключающееся к WI-FI сети) должно зарегистрироваться в сети почтовых ящиков.
Это делается командой mailbox.connect(ip, port)
(см описание).
В момомент выполнения этой команды новое подключающееся устройство регистрируется в сети почтовых ящиков, но казалось бы, судя по команде, подключение происходит только к одному устройству, назовем его D1. Дело в том, что когда устройство D1 получает сообщение о регистрации в сети от нового устройства, то D1 передает новому устройству таблицу со всеми известными ему устройствами, которые уже были зарегистрированы в сети, таким образом, новое устройство узнает информацию о всех участниках сети и может отправлять сообщения любому из них.
Важно
После инициализации подключения, т.е. вызова команды mailbox.connect(ip, port)
, что со стороны Трик, что со стороны Пионер, для стабильной работы обязательно нужно ставить задержку (примерно 100мс), чтобы устройства успели обработать новые подключения.
После регистрации в сети, устройства могут обмениваться сообщениями. Как уже говорилось, на данный момент протокол поддерживают две платформы: Геоскан Пионер и Трик. Удобной особенностью является то, что вне зависимости от платформы, API не будет значительно отличаться.
Основными и самыми часто используемыми командами являются (полное описание API см. на странице):
mailbox.connect(ip, port)
- производит подключение и регистрацию в сети,mailbox.send(hull, message)
- отправляет сообщение,mailbox.receive(blocking)
- принимает сообщение.
Алгоритм написания программ для общения между устройствами¶
Рассмотрим последовательность действий, когда одно устройство хочет передать сообщение другому:
Произвести регистрацию в сети командой
mailbox.connect(ip, port)
при первом запуске программы;Выполнить команду ожидания (примерно 100мс);
- Выполить команды приемопередачи сообщений:
Для отправки сообщения выполнить команду
mailbox.send(hull, message)
;Для приема сообщения выполнить команду
mailbox.receive(true)
, которая остановит выполнение программы до момента получения сообщения;
Можно производить любые дальнейшие операции. Если вы отправляете числовую информацию, то после приема сообщения не забывайте перевести полученное сообщение к числовому типу.
Примечание
Дополнительное напоминание, что регистрацию в сети производить нужно только один раз в начале выполнения программы, до различных циклов и функций, если они у вас есть.
Подготовка к использованию протокола¶
Алгоритм действий для квадрокоптеров Пионер
Чтобы начать использовать протокол mailbox с квадрокоптерами Пионер необходимо выполнить следующие действия:
Установить поддерживающие эту функцию прошивки автопилота и ESP32 по интрукциям: для АП, для ESP32;
Ознакомиться с документацией по API протокола mailbox;
Подключить все устройства Пионер к одной WI-Fi сети по инструкции с помощью WEB интерфеса квадрокоптера.
Алгоритм действий для контроллеров Трик
Если вы планируете использовать контроллер Трик, то необходимо выполнить следующие действия:
Удостовериться в актуальности прошивки, при необходимости обновить ее по инструкции;
Для программирования контроллеров ТРИК необходимо скачать среду разработки TrikStudio, скачать ее можно с официального сайта;
Подключить все устройства Трик к одной WI-Fi сети по инструкции с помощью WEB интерфеса контроллера ТРИК.
Алгоритм действий для настройки виртуального Трик
Если вы планируете использовать виртуальный контроллер Трик в среде TrikStudio, то необходимо выполнить следующие действия:
Скачать среду разработки TrikStudio с официального сайта,
Открыть среду TrikStudio и либо создать новый проект, либо октрыть любой существующий:
Открыть настройки:
Промотать немного вниз и поставить флажок для параметра «Активировать Mailbox» и установить любой борт-номер:
После перезагрузки среды разработки вы сможете писать идентичный код, как для настоящего контроллера Трик. При выборе 2д модели и запуске программы у вас откроется Режим Отладки, в котором будет находиться виртуальная модель робота, позволяющая пользоваться протоколом mailbox не имея реального контроллера Трик:
Примеры программ¶
Передача сообщений между Пионером и Триком
Контроллер Тик переведен в режим точки доступа с помощью WEB-интерфейса, а квадрокоптер Пионер Мини переведен в режим клиента и подключен к WI-FI сети Трика так же с помощью своего WEB-интерфейса.
В настройках контроллера Трик (меню Взаимодействие) установлен бортномер 01 и указан его IP адрес:
Код для квадрокоптера на Lua:
function callback(event)
end
mailbox.connect("192.168.0.100", 8889)
sleep(0.1)
data,_,_,_,_ = Sensors.range();
mailbox.send(1, data);
Код для контроллера Трик на JS:
var main = function() {
var msg = mailbox.receive()
print("Received message: " + msg)
}
Прием значений для управления светодиодами
От некоторого устройства в сети должен приходить закодированный байт следующей структуры:
7-5 бит - команда (001 - установить значение светодиодов)
4-3 бит - незначащие биты
2-0 бит - вкл/выкл красный, зеленый и синий светодиод соответственно
Например, 0b00100111
:
0b - обозначение двоичной системы,
001 - биты 7-5, т.е команда установки светодиодов;
00 - биты 4-3, незначащие биты;
111 - биты 2-0, включить все светодиоды
После приема этой структуры как единого байта, его необходимо раскодировать в несколько переменных с помощью битовых сдвигов.
Битовый сдвиг - это операция, как понятно из названия, сдвигающая все биты числа в одну из сторон: вправо или влево. Например,
если число 1 = 0b00000001
сдвинуть на 2 влево, то получится число 4 = 0b00000100
. В используемой версии луа нет такой математической операции,
поэтому необхдимо написать функции, добавляющие такой функционал.
Функция сдвига влево:
function lshift(x, by)
return x * 2 ^ by
end
Функция сдвига вправо:
function rshift(x, by)
return math.floor(x / 2 ^ by)
end
В обоих функциях первым указывается число, биты которого подвергаются сдвигу, а вторым параметром указывается на сколько бит будет произведен сдвиг.
Однако одних лишь двигов недостаточно, чтобы раскодировать и правильно интерпретировать полученное сообщение, поскольку когда, например, мы смотрим на биты 2-0, то нужно не забывать, что значения есть еще и в битах 7-5, т.е. нельзя сообщение сравнивать кокнретными числами, когда оно «в сборе», нужно как-то вычленять биты 7-5, когда проверяется команда, биты 2-0, когда проверяются значения светодиодов…
Для этого используется еще одна битовая операция - Битовое И. Эта операция оперирует двумя числами: изменяемым числом и маской. Изменяемое число - это тго число, в котором мы хотим вычленить некоторые биты, а маска - это маркер, который показывает, какие позиции мы хотим рассматривать, а какаие отбросить.
Например, у нас есть следующее двоичное число - 0b00100101
, и мы хотим оставить в нем только последние 3 бита (отсчет ведется справа).
Поэтому мы должны взять следующую двоичную маску - 0b11100000
. И после применения «Битового И» у нас останется число 0b00100000
.
Ну а теперь, чтобы полученное число было легче обрабатывать, можно все его биты сдвинуть на 5 вправо:
0b00100000
-> 0b00000001
.
Функция, реализующая операцию Побитовое И:
function BitAND(a,b)
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra+rb>1 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
Затем, если командой является установка значений светодиодов, то происходит соответсвующее действие.
-- Simplification and caching table.unpack calls
local unpack = table.unpack
-- Base pcb number of RGB LEDs
local ledNumber = 4
-- RGB LED control port initialize
local leds = Ledbar.new(ledNumber)
-- Function changes color on all LEDs
local function changeColor(color)
-- Changing color on each LED one after another
for i=0, ledNumber - 1, 1 do
leds:set(i, unpack(color))
end
end
-- Table of colors in RGB form for changeColor function
local colors = {
{1, 0, 0}, -- r
{0, 1, 0}, -- g
{0, 0, 1}, -- b
{1, 1, 1}, -- w
}
-- Event processing function called automatically by autopilot
function callback(event)
end
function lshift(x, by)
return x * 2 ^ by
end
function rshift(x, by)
return math.floor(x / 2 ^ by)
end
function BitAND(a,b)
local p,c=1,0
while a>0 and b>0 do
local ra,rb=a%2,b%2
if ra+rb>1 then c=c+p end
a,b,p=(a-ra)/2,(b-rb)/2,p*2
end
return c
end
mailbox.setHullNumber(45)
while(true)
do
hull, msg = mailbox.receive(true)
cmd = rshift(BitAND(tonumber(msg), 224), 5)
if(msg=="0") then
changeColor({0,0,0})
break
end
if(cmd == 1) then
local r = rshift(BitAND(tonumber(msg), 4), 2)
local g = rshift(BitAND(tonumber(msg), 2), 1)
local b = BitAND(tonumber(msg), 1)
changeColor({r,g,b})
end
Проект
Управление квадрокоптером с контроллера Трик
В данном проекте реализовано управление светодиодами, полетом, а также получение данных телеметрии квадрокоптера с помощью протокола Mailbox. Управление производится с помощью самостоятельно написанного графического интерфейса на контроллере Трик.
Подробнее можете узнать на странице проекта