適用於支援 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 程式碼。
目前支援以下資料類型:
bool
uint8
、 uint16
、 uint32
和uint64
float32
、 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 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
的相同資料夾即可。然後,您可以使用 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
。已知限制: