适用于支持 C++ 或 MATLAB 的计算机和嵌入式系统的数据序列化工具链

microbuf ?如果您计划在运行 C++ 应用程序(计算机或嵌入式系统)的设备和/或运行(可能编译的)MATLAB 代码(PC 或嵌入式系统上的 Simulink)的设备之间创建接口,您可能需要使用它。一种可能的用例是“通过 UDP 将控制数据从计算机发送到嵌入式系统”。当前支持的语言是 C++ 和 MATLAB,用于序列化和反序列化 (Tx+Rx)。这样就可以将数据从 ROS 节点发送到 dSPACE MicroAutoBox,从 Arduino 发送到 PC 上的 Simulink 仿真,或者在多个 Arduino 之间交换数据 - 无需逐字节编写接口代码或担心诸如此类的事情字节序。通过合理的努力可以添加对更多语言的支持。
protobuf / JSON / matlab-msgpack /...?在许多情况下,使用另一个具有更多功能(例如 protobuf)的框架确实是有意义的。 microbuf适用于具有严格限制的用例,例如嵌入式系统或具有受限工具链的类似环境。 microbuf不依赖于外部库(甚至 C++ std命名空间中的功能),并且可以仅使用标准语言工具进行编译。
bastibe 的 matlab-msgpack 无法使用 Simulink/MATLAB 编码器编译为 C 代码。
目前支持以下数据类型:
booluint8 、 uint16 、 uint32和uint64float32 、 float64| 语言 | 序列化 | 反序列化 | CRC 支持 | 示例 | 笔记 |
|---|---|---|---|---|---|
| C++ | ✔ | ✔ | ✔ | ROS节点; C++应用程序; Arduino草图 | |
| MATLAB | ✔ | ✔ | ✔ | dSPACE MicroAutoBox; Simulink 仿真 | 可在 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 microbufpyyaml ):sudo apt install python3-yamlpip : pip3 install -r requirements.txtmicrobuf示例消息: ./microbuf.py SensorData.mmsggit submodule update --init --recursive 假设您要将上述消息SensorData.mmsg从计算机(使用 C++)发送到 Simulink 仿真。 microbuf将生成一个头文件SensorData.h ,您可以将其包含在 C++ 代码中。此消息头文件需要访问microbuf.h头文件,因此只需将这两个文件复制到编译器将找到它们或调整CMakeLists.txt的同一文件夹即可。然后,您可以使用 C++ 中的 struct SensorData_struct_t填充数据并将其转换为字节向量,例如:
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 仿真可以配置为接收序列化字节。这可以通过 DSP System Toolbox 中的 UDP 接收模块来实现。通过将microbuf生成的文件deserialize_SensorData.m添加到 Simulink 模型中,您可以轻松地反序列化接收到的数据:

请注意,为了模拟或编译此类模型, microbuf的matlab文件夹需要位于 MATLAB 路径上,因为它包含deserialize_SensorData.m中未包含的必要功能。当然,您也可以将包含的+microbuf文件夹复制到项目中位于 MATLAB 路径上的位置。
examples文件夹还包含完整的 Simulink 模型。在同一文件中,您还会发现一个使用 MATLAB 序列化数据的注释掉示例。
此示例需要执行的操作与前一个示例基本相同。代码大部分可以重用。您需要在 ROS 节点中包含必要的 C++ 代码,并考虑何时要向 MicroAutoBox 发送消息(例如以何种速率)。
在 MicroAutoBox 一侧,您不能使用相同的 UDP 接收块,因为您需要一个特定于硬件的接收块。不过,RTI 以太网 (UDP) 模块集中包含类似的 UDP 接收模块,因此您可以改用该模块。请注意,根据文档,此块集的 UDP 数据包的最大有效负载为 1472 字节。反序列化函数可以像前面的示例一样包含在内,并将自动编译为 C 代码。
microbuf生成的标头可以轻松包含在 Arduino 草图中。该代码可以编译,因为它不需要std命名空间中的功能。可能取决于您特定的 Arduino 硬件, float64数据可能无法在 Arduino 上序列化,因为double可能只有 32 位。使用Wire(I2C)库时,一步只能传输32个字节。
可以在此处找到通过 I2C 从一个 Arduino 向另一个 Arduino 发送数据的示例。

microbuf知道所需的字节数,请参见生成的 C++ 结构体的常量data_size 。已知限制: