Протокол Mailbox | Беспроводная передача сообщений

Общее описание протокола

Mailbox - это протокол передачи данных между устройствами в сети WI-FI. Данный протокол был впервые реализован в контроллерах Трик, после чего получил поддержку со стороны квадрокоптеров Геоскан. Данные передаются побайтово в текстовом формате, принцип работы очень похож на работу с серийным последовательным портом (Serial / UART).

У каждого устройства в сети «почтовых ящиков» есть свой борт-номер, устанавливаемый пользователем в программе на этом устройстве. Борт-номер представляет собой целое число > 0, оно должно быть уникальным для каждого устройства в сети.

https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/mailbox_1.png

В сети нет главного устройства (отсутствует иерархия 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 см. на странице):

  1. mailbox.connect(ip, port) - производит подключение и регистрацию в сети,

  2. mailbox.send(hull, message) - отправляет сообщение,

  3. mailbox.receive(blocking) - принимает сообщение.

Алгоритм написания программ для общения между устройствами

Рассмотрим последовательность действий, когда одно устройство хочет передать сообщение другому:

  1. Произвести регистрацию в сети командой mailbox.connect(ip, port) при первом запуске программы;

  2. Выполнить команду ожидания (примерно 100мс);

  3. Выполить команды приемопередачи сообщений:
    • Для отправки сообщения выполнить команду mailbox.send(hull, message);

    • Для приема сообщения выполнить команду mailbox.receive(true), которая остановит выполнение программы до момента получения сообщения;

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

Примечание

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

Подготовка к использованию протокола

Алгоритм действий для квадрокоптеров Пионер

Чтобы начать использовать протокол mailbox с квадрокоптерами Пионер необходимо выполнить следующие действия:

  1. Установить поддерживающие эту функцию прошивки автопилота и ESP32 по интрукциям: для АП, для ESP32;

  2. Ознакомиться с документацией по API протокола mailbox;

  3. Подключить все устройства Пионер к одной WI-Fi сети по инструкции с помощью WEB интерфеса квадрокоптера.

Алгоритм действий для контроллеров Трик

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

  1. Удостовериться в актуальности прошивки, при необходимости обновить ее по инструкции;

  2. Для программирования контроллеров ТРИК необходимо скачать среду разработки TrikStudio, скачать ее можно с официального сайта;

  3. Подключить все устройства Трик к одной WI-Fi сети по инструкции с помощью WEB интерфеса контроллера ТРИК.

Алгоритм действий для настройки виртуального Трик

Если вы планируете использовать виртуальный контроллер Трик в среде TrikStudio, то необходимо выполнить следующие действия:

  1. Скачать среду разработки TrikStudio с официального сайта,

  2. Открыть среду TrikStudio и либо создать новый проект, либо октрыть любой существующий:

    https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/virtual-trik-1.png
  3. Открыть настройки:

    https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/virtual-trik-2.png
  4. Промотать немного вниз и поставить флажок для параметра «Активировать Mailbox» и установить любой борт-номер:

    https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/virtual-trik-3.png https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/virtual-trik-4.png
  5. После перезагрузки среды разработки вы сможете писать идентичный код, как для настоящего контроллера Трик. При выборе 2д модели и запуске программы у вас откроется Режим Отладки, в котором будет находиться виртуальная модель робота, позволяющая пользоваться протоколом mailbox не имея реального контроллера Трик:

    https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/virtual-trik-5.png

Примеры программ

Передача сообщений между Пионером и Триком

https://storage.yandexcloud.net/pioneer-doc.geoscan.ru-static/images/programming/interfaces/geo-trik.png

Контроллер Тик переведен в режим точки доступа с помощью 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. Управление производится с помощью самостоятельно написанного графического интерфейса на контроллере Трик.

Подробнее можете узнать на странице проекта