Cadena de herramientas de serialización de datos para computadoras y sistemas integrados con soporte C++ o MATLAB
microbuf
?Es posible que desee usarlo si planea crear una interfaz entre dispositivos que ejecutan una aplicación C++ (una computadora o sistema integrado) y/o dispositivos que ejecutan código MATLAB (posiblemente compilado) (Simulink en PC o sistemas integrados). Un posible caso de uso sería "Enviar datos de control desde la computadora a través de UDP al sistema integrado". Los lenguajes soportados actualmente son C++ y MATLAB, tanto para serialización como para deserialización (Tx+Rx). Esto hace posible, por ejemplo, enviar datos desde un nodo ROS a un dSPACE MicroAutoBox, desde un Arduino a una simulación de Simulink en una PC, o intercambiar datos entre múltiples Arduinos, sin escribir el código de la interfaz byte a byte ni preocuparse por cosas como endianidad. Se puede agregar soporte para más idiomas con un esfuerzo razonable.
protobuf
/ JSON
/ matlab-msgpack
/...? Usar otro marco con más funciones como protobuf puede tener sentido en muchos casos. microbuf
está destinado a casos de uso con fuertes limitaciones, por ejemplo, sistemas integrados o entornos similares con una cadena de herramientas restringida. microbuf
no depende de bibliotecas externas (ni siquiera de la funcionalidad en el espacio de nombres std
de C++) y es posible una compilación simplemente utilizando herramientas de lenguaje estándar.
matlab-msgpack de bastibe no se puede compilar en código C con el codificador Simulink/MATLAB.
Actualmente se admiten los siguientes tipos de datos:
bool
uint8
, uint16
, uint32
y uint64
float32
, float64
Idioma | Publicación por entregas | Deserialización | Apoyo a la Convención sobre los Derechos del Niño | Ejemplos | Notas |
---|---|---|---|---|---|
C++ | ✔ | ✔ | ✔ | nodo ROS; Aplicación C++; boceto de arduino | |
MATLAB | ✔ | ✔ | ✔ | dSPACE MicroAutoBox; Simulación de enlace simultáneo | Utilizable en Simulink; compila con Simulink/MATLAB Coder |
... | ✘ | ✘ | ✘ | Abra una solicitud de función o PR para nuevos idiomas de destino |
microbuf
utiliza archivos de descripción de mensajes que terminan en .mmsg
para describir la estructura de los mensajes, a diferencia de ROS. Los archivos mmsg
deben seguir una estructura específica y deben ser YAML
válidos. El siguiente ejemplo se puede guardar como SensorData.mmsg
y luego usarse como un mensaje microbuf
:
version : 1
append_checksum : yes
content :
distance : float32[10]
angle : float32[10]
robot_id : uint8
Se pueden encontrar más ejemplos en prueba/mensajes/.
Cuando ejecute ahora ./microbuf.py SensorData.mmsg
, se generarán automáticamente serializadores y deserializadores para los idiomas admitidos. Puede utilizar los serializadores para convertir datos a bytes, enviarlos a su receptor (por ejemplo, a través de UDP o I2C) y decodificarlos allí con los deserializadores.
La serialización de microbuf
se basa en la especificación MessagePack. Todos los elementos de datos están empaquetados en una matriz plana y se adjunta una suma de comprobación CRC16 opcional.
git clone https://github.com/nspo/microbuf.git
cd microbuf
pyyaml
al momento de escribir este artículo) estén instalados:sudo apt install python3-yaml
pip
: pip3 install -r requirements.txt
microbuf
con el mensaje de ejemplo: ./microbuf.py SensorData.mmsg
git submodule update --init --recursive
Suponga que desea enviar el mensaje SensorData.mmsg
mencionado anteriormente desde una computadora (usando C++) a una simulación de Simulink. microbuf
generará un archivo de encabezado SensorData.h
que puede incluir en su código C++. Este archivo de encabezado de mensaje necesita acceso al archivo de encabezado microbuf.h
, así que simplemente copie ambos archivos a la misma carpeta donde su compilador los encontrará o adapte su CMakeLists.txt
. Luego puede usar la estructura SensorData_struct_t
en C++ para completar sus datos y convertirlos en un vector de bytes, por ejemplo, así:
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
Ahora bytes
deben enviarse al sistema receptor de alguna manera, por ejemplo, a través de UDP. La carpeta de examples
contiene un ejemplo de cómo se podría hacerlo.
La simulación de Simulink se puede configurar para recibir los bytes serializados. Esto se puede lograr, por ejemplo, con el bloque de recepción UDP de DSP System Toolbox. Al agregar el archivo deserialize_SensorData.m
que generó microbuf
al modelo de Simulink, puede deserializar fácilmente los datos recibidos:
Tenga en cuenta que para simular o compilar dicho modelo, la carpeta matlab
de microbuf
debe estar en su ruta de MATLAB porque contiene la funcionalidad necesaria que no está incluida en deserialize_SensorData.m
. Por supuesto, también puede simplemente copiar la carpeta +microbuf
contenida en un lugar de su proyecto que de todos modos esté en su ruta de MATLAB.
La carpeta de examples
también contiene el modelo completo de Simulink. En el mismo archivo también encontrará un ejemplo comentado que utiliza MATLAB para serializar datos.
En este ejemplo se deben hacer prácticamente las mismas cosas que en el anterior. En su mayoría, el código se puede reutilizar. Debe incluir el código C++ necesario en su nodo ROS y pensar cuándo desea enviar un mensaje al MicroAutoBox (por ejemplo, con qué velocidad).
En el lado de MicroAutoBox, no puede usar el mismo bloque de recepción UDP porque necesita uno específico del hardware. Sin embargo, se incluye un bloque de recepción UDP similar en el conjunto de bloques RTI Ethernet (UDP), por lo que puede usarlo en su lugar. Tenga en cuenta que la carga útil máxima de paquetes UDP para este conjunto de bloques es de 1472 bytes, según la documentación. La función de deserialización se puede incluir como en el ejemplo anterior y se compilará en código C automáticamente.
Los encabezados que genera microbuf
se pueden incluir fácilmente en un boceto de Arduino. El código se compila ya que no requiere funcionalidad del espacio de nombres std
. Posiblemente dependiendo de su hardware Arduino específico, los datos float64
probablemente no se puedan serializar en Arduino ya que los double
pueden tener solo 32 bits. Cuando se utiliza la biblioteca Wire (I2C), solo se pueden transmitir 32 bytes en un paso.
Puede encontrar un ejemplo de envío de datos de un Arduino a otro a través de I2C aquí.
microbuf
conoce el número requerido de bytes; consulte, por ejemplo, el data_size
constante de la estructura C++ generada. Límites conocidos: