Набор инструментов сериализации данных для компьютеров и встроенных систем с поддержкой C++ или MATLAB
microbuf
?Возможно, вы захотите использовать его, если планируете создать интерфейс между устройствами, на которых выполняется приложение C++ (компьютер или встроенная система), и/или устройствами, на которых выполняется (возможно, скомпилированный) код MATLAB (Simulink на ПК или встроенные системы). Одним из возможных вариантов использования может быть «Отправка управляющих данных с компьютера через UDP во встроенную систему». В настоящее время поддерживаются языки C++ и MATLAB как для сериализации, так и для десериализации (Tx+Rx). Это позволяет, например, отправлять данные из узла ROS в dSPACE MicroAutoBox, из Arduino в симуляцию Simulink на ПК или обмениваться данными между несколькими Arduinos - без побайтовой записи кода интерфейса или беспокойства о таких вещах, как порядок байтов. Поддержка большего количества языков может быть добавлена при разумных усилиях.
protobuf
/ JSON
/ matlab-msgpack
/...? Использование другого фреймворка с большим количеством функций, такого как protobuf, действительно может иметь смысл во многих случаях. microbuf
предназначен для случаев использования с сильными ограничениями, например встроенных систем или аналогичных сред с ограниченной цепочкой инструментов. microbuf
не зависит от внешних библиотек (или даже от функций в пространстве имен C++ std
), и возможна компиляция с использованием стандартных инструментов языка.
matlab-msgpack от bastibe не может быть скомпилирован в код C с помощью кодера Simulink/MATLAB.
В настоящее время поддерживаются следующие типы данных:
bool
uint8
, uint16
, uint32
и uint64
float32
, float64
Язык | Сериализация | Десериализация | Поддержка CRC | Примеры | Примечания |
---|---|---|---|---|---|
С++ | ✔ | ✔ | ✔ | узел РОС; приложение С++; Скетч Ардуино | |
МАТЛАБ | ✔ | ✔ | ✔ | dSPACE MicroAutoBox; Симулинк-симуляция | Можно использовать в Simulink; компилируется с помощью Simulink/MATLAB Coder |
... | ✘ | ✘ | ✘ | Пожалуйста, откройте запрос на добавление функции или PR для новых целевых языков. |
microbuf
использует файлы описания сообщений, заканчивающиеся на .mmsg
для описания структуры сообщений, мало чем отличаясь от ROS. Файлы mmsg
должны иметь определенную структуру и быть действительными в YAML
. Следующий пример можно сохранить как SensorData.mmsg
и затем использовать в качестве сообщения microbuf
:
version : 1
append_checksum : yes
content :
distance : float32[10]
angle : float32[10]
robot_id : uint8
Дополнительные примеры можно найти в разделе test/messages/.
Когда вы теперь выполните ./microbuf.py SensorData.mmsg
, сериализаторы и десериализаторы для поддерживаемых языков будут созданы автоматически. Вы можете использовать сериализаторы для преобразования данных в байты, отправки их получателю (например, через UDP или I2C) и декодирования их там с помощью десериализаторов.
Сериализация microbuf
основана на спецификации MessagePack. Все элементы данных упаковываются в плоский массив, к которому добавляется необязательная контрольная сумма CRC16.
git clone https://github.com/nspo/microbuf.git
cd microbuf
pyyaml
) установлены:sudo apt install python3-yaml
pip
: pip3 install -r requirements.txt
microbuf
с примером сообщения: ./microbuf.py SensorData.mmsg
git submodule update --init --recursive
Предположим, вы хотите отправить упомянутое выше сообщение SensorData.mmsg
с компьютера (с использованием C++) в систему моделирования Simulink. microbuf
сгенерирует заголовочный файл SensorData.h
, который вы можете включить в свой код C++. Этому файлу заголовка сообщения требуется доступ к файлу заголовка microbuf.h
, поэтому просто скопируйте оба файла в одну и ту же папку, где их найдет ваш компилятор, или адаптируйте свой CMakeLists.txt
. Затем вы можете использовать структуру SensorData_struct_t
в C++, чтобы заполнить данные и преобразовать их в байтовый вектор, например так:
SensorData_struct_t sensor_data {};
// fill example data into SensorData msg
for ( size_t i= 0 ; i< 10 ; ++i)
{
sensor_data. distance [i] = 2.5 * static_cast < float >(i);
sensor_data. angle [i] = 4.2 * static_cast < float >(i);
}
sensor_data.robot_id = 42U ;
const auto bytes = sensor_data.as_bytes(); // convert to bytes
bytes
теперь необходимо как-то отправить в систему-получатель, например, через UDP. В папке examples
содержится пример того, как это можно сделать.
Симуляцию Simulink можно настроить для получения сериализованных байтов. Этого можно достичь, например, с помощью блока UDP Receive из DSP System Toolbox. Добавив файл deserialize_SensorData.m
, который сгенерировал microbuf
, в модель Simulink, вы сможете легко десериализовать полученные данные:
Обратите внимание, что для моделирования или компиляции такой модели папка matlab
microbuf
должна находиться в вашем пути MATLAB, поскольку она содержит необходимые функции, которые не включены в deserialize_SensorData.m
. Конечно, вы также можете просто скопировать содержащуюся папку +microbuf
в место вашего проекта, которое в любом случае находится на вашем пути к MATLAB.
Папка examples
также содержит полную модель Simulink. В том же файле вы также найдете закомментированный пример использования MATLAB для сериализации данных.
Для этого примера нужно сделать по существу то же самое, что и для предыдущего. Код в большинстве случаев можно использовать повторно. Вам необходимо включить необходимый код C++ в свой узел ROS и подумать, когда вы хотите отправить сообщение в MicroAutoBox (например, с какой скоростью).
На стороне MicroAutoBox вы не можете использовать один и тот же блок приема UDP, поскольку вам нужен аппаратно-зависимый блок. Аналогичный блок приема UDP включен в набор блоков RTI Ethernet (UDP), поэтому вместо него вы можете использовать его. Обратите внимание, что согласно документации максимальная полезная нагрузка UDP-пакетов для этого набора блоков составляет 1472 байта. Функцию десериализации можно включить, как в предыдущем примере, и она будет автоматически скомпилирована в код C.
Заголовки, которые генерирует microbuf
, можно легко включить в скетч Arduino. Код компилируется, поскольку не требует функциональности пространства имен std
. Возможно, в зависимости от вашего конкретного оборудования Arduino, данные float64
, вероятно, не могут быть сериализованы на Arduino, поскольку double
s может иметь только 32 бита. При использовании библиотеки Wire (I2C) за один шаг можно передать только 32 байта.
Один из примеров отправки данных с одного Arduino на другой через I2C можно найти здесь.
microbuf
знает необходимое количество байтов, см., например, константу data_size
сгенерированной структуры C++. Известные пределы: