Conjunto de ferramentas de serialização de dados para computadores e sistemas embarcados com suporte C++ ou MATLAB

microbuf ?Você pode querer usá-lo se planeja criar uma interface entre dispositivos que executam um aplicativo C++ (um computador ou sistema embarcado) e/ou dispositivos que executam código MATLAB (possivelmente compilado) (Simulink em PC ou sistemas embarcados). Um possível caso de uso seria "Enviar dados de controle do computador por UDP para o sistema embarcado". As linguagens atualmente suportadas são C++ e MATLAB, tanto para serialização quanto para desserialização (Tx+Rx). Isso torna possível, por exemplo, enviar dados de um nó ROS para um dSPACE MicroAutoBox, de um Arduino para uma simulação Simulink em um PC ou trocar dados entre vários Arduinos - sem escrever o código da interface byte por byte ou se preocupar com coisas como endianismo. O suporte para mais idiomas pode ser adicionado com esforço razoável.
protobuf / JSON / matlab-msgpack /...? Usar outra estrutura com mais recursos como o protobuf pode realmente fazer sentido em muitos casos. microbuf destina-se a casos de uso com fortes limitações, por exemplo, sistemas embarcados ou ambientes semelhantes com um conjunto de ferramentas restrito. microbuf não depende de bibliotecas externas (ou mesmo de funcionalidade no namespace C++ std ) e é possível uma compilação usando apenas ferramentas de linguagem padrão.
matlab-msgpack por bastibe não pode ser compilado para código C com o codificador Simulink/MATLAB.
Os seguintes tipos de dados são atualmente suportados:
booluint8 , uint16 , uint32 e uint64float32 , float64| Linguagem | Serialização | Desserialização | Suporte CRC | Exemplos | Notas |
|---|---|---|---|---|---|
| C++ | ✔ | ✔ | ✔ | Nó ROS; Aplicação C++; Esboço do Arduino | |
| MATLAB | ✔ | ✔ | ✔ | dSPACE MicroAutoBox; Simulação Simulink | Utilizável em Simulink; compila com codificador Simulink/MATLAB |
| ... | ✘ | ✘ | ✘ | Abra uma solicitação de recurso ou PR para novos idiomas de destino |
microbuf usa arquivos de descrição de mensagens que terminam em .mmsg para descrever a estrutura das mensagens, não muito diferente do ROS. Os arquivos mmsg precisam seguir uma estrutura específica e devem ser YAML válidos. O exemplo a seguir pode ser salvo como SensorData.mmsg e depois usado como uma mensagem microbuf :
version : 1
append_checksum : yes
content :
distance : float32[10]
angle : float32[10]
robot_id : uint8Mais exemplos podem ser encontrados em test/messages/.
Quando você executar agora ./microbuf.py SensorData.mmsg , serializadores e desserializadores para os idiomas suportados serão gerados automaticamente. Você pode usar os serializadores para converter dados em bytes, enviá-los para o seu receptor (por exemplo, via UDP ou I2C) e decodificá-los lá com os desserializadores.
A serialização de microbuf é baseada na especificação MessagePack. Todos os elementos de dados são compactados em uma matriz simples e uma soma de verificação CRC16 opcional é anexada.
git clone https://github.com/nspo/microbuf.git
cd microbufpyyaml no momento da escrita) estejam instalados:sudo apt install python3-yamlpip : pip3 install -r requirements.txtmicrobuf com a mensagem de exemplo: ./microbuf.py SensorData.mmsggit submodule update --init --recursive Suponha que você queira enviar a mensagem SensorData.mmsg mencionada acima de um computador (usando C++) para uma simulação Simulink. microbuf irá gerar um arquivo de cabeçalho SensorData.h que você pode incluir em seu código C++. Este arquivo de cabeçalho de mensagem precisa de acesso ao arquivo de cabeçalho microbuf.h , então basta copiar os dois arquivos para a mesma pasta onde seu compilador irá encontrá-los ou adaptar seu CMakeLists.txt . Você pode então usar a estrutura SensorData_struct_t em C++ para preencher seus dados e convertê-los em um vetor de bytes, por exemplo, assim:
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 agora precisam ser enviados ao sistema receptor de alguma forma, por exemplo, via UDP. A pasta examples contém um exemplo de como fazer isso.
A simulação Simulink pode ser configurada para receber os bytes serializados. Isto pode ser conseguido, por exemplo, com o bloco UDP Receive da caixa de ferramentas do sistema DSP. Ao adicionar o arquivo deserialize_SensorData.m que microbuf gerou ao modelo Simulink, você pode desserializar facilmente os dados recebidos:

Observe que para simular ou compilar tal modelo, a pasta matlab do microbuf precisa estar no caminho do MATLAB porque contém a funcionalidade necessária que não está incluída em deserialize_SensorData.m . É claro que você também pode simplesmente copiar a pasta +microbuf contida para um local do seu projeto que esteja no caminho do MATLAB de qualquer maneira.
A pasta examples também contém o modelo Simulink completo. No mesmo arquivo você também encontrará um exemplo comentado usando MATLAB para serializar dados.
Em grande parte, as mesmas coisas precisam ser feitas neste exemplo e no anterior. O código pode ser reutilizado principalmente. Você precisa incluir o código C++ necessário em seu nó ROS e pensar em quando deseja enviar uma mensagem para o MicroAutoBox (por exemplo, com que taxa).
No lado do MicroAutoBox, você não pode usar o mesmo bloco de recebimento UDP porque precisa de um bloco específico de hardware. Um bloco de recebimento UDP semelhante está incluído no conjunto de blocos RTI Ethernet (UDP), portanto, você pode usá-lo. Observe que a carga máxima de pacotes UDP para este conjunto de blocos é de 1.472 bytes, de acordo com a documentação. A função de desserialização pode ser incluída como no exemplo anterior e será compilada para código C automaticamente.
Os cabeçalhos gerados microbuf podem ser facilmente incluídos em um esboço do Arduino. O código é compilado porque não requer funcionalidade do namespace std . Possivelmente dependendo do hardware específico do seu Arduino, os dados float64 provavelmente não podem ser serializados no Arduino, pois double s podem ter apenas 32 bits. Ao usar a biblioteca Wire (I2C), apenas 32 bytes podem ser transmitidos em uma etapa.
Um exemplo de envio de dados de um Arduino para outro via I2C pode ser encontrado aqui.

microbuf conhece o número necessário de bytes, veja, por exemplo, a constante data_size da estrutura C++ gerada. Limites conhecidos: