LCM通訊模塊簡介

1. LCM通訊模塊簡介 
LCM(Lightweight Communications and Marshalling)是一套用於消息傳遞和數據編組的庫和工具的集合,旨在爲實時系統提供高帶寬和低延遲的消息傳遞的能力。它提供了一個發佈/訂閱消息傳遞模型以及爲各類編程語言的應用程序自動生成編/解組代碼。 
LCM容許多個進程以安全和高性能地方式進行消息的交換。消息是LCM通訊的基本單元,開發者可將消息定義爲與編程語言無關的數據結構,而後使用LCM提供的lcm-gen工具將自定義的數據結構編譯爲特定語言的代碼。lcm-gen支持C、C++、Java、Python等編程語言,關於lcm-gen的使用能夠參考官方文檔。 
LCM官方下載地址爲:https://github.com/lcm-proj/lcmgit

2. LCM通訊模塊使用方法 
本節旨在介紹基於C編程語言進行LCM通訊的使用方法。在此以前,用戶須要使用lcm-gen工具將自定義的數據結構編譯爲LCM可以處理的消息格式。 
開發者使用LCM進行消息交換時須要完成如下三個主要步驟: 
1)初始化LCM; 
2)發佈一個消息; 
3)訂閱及接收消息。 
2.1 初始化 
LCM的初始化代碼以下所示。github

#include <stdio.h>
#include <lcm/lcm.h>
int main(int  argc, char  **argv)
{
    lcm_t *lcm = lcm_create(NULL);
    if(!lcm) {
        return  (PX_ERROR);
}

    /*
     *  用戶應用程序代碼
     */
    lcm_destroy(lcm);

    return  (ERROR_NONE);
}

數lcm_create主要完成lcm_t實例的分配與初始化,該實例表示與LCM網絡的鏈接。其入參爲NULL表示使用默認設置來初始化LCM。初始化的默認值適合於本地計算機上的其餘LCM應用程序進行通訊,也能夠指定底層網絡通訊機制的字符串。 
完成以後,調用lcm_destroy來清理LCM使用的資源。 
2.2 發佈消息 
假定用戶已使用lcm-gen生成了「exlcm_example_t.h」和「exlcm_example_t.c」兩個文件,其中用戶定義的數據結構被lcm-gen編譯並保存在「exlcm_example_t.h」中,假設生成的消息結構以下所示。編程

typedef struct _exlcm_example_t exlcm_example_t;
struct _exlcm_example_t {
    int64_t  timestamp;
    double   position[3];
    double   orientation[4];
    int32_t  num_ranges;
    int16_t  ranges;
    char     name;
    int8_t   enabled;
};

下來咱們將按照消息結構實例化一些數據並進行發佈,以下所示。安全

#include <stdio.h>
#include <lcm/lcm.h>
#include "exlcm_example_t.h"
int main(int  argc, char  **argv)
{
    int      i;
    int16_t  ranges[15];
    lcm_t   *lcm = lcm_create(NULL);
    if(!lcm) {
        return  (PX_ERROR);
    }

    exlcm_example_t lcmData = {
        .timestamp   = 0,
        .position    = { 1, 2, 3 },
        .orientation = { 1, 0, 0, 0 },
    };

    for(i = 0; i < 15; i++) {
        ranges[i] = i;
    }
    lcmData.num_ranges = 15;
    lcmData.ranges     = ranges;
    lcmData.name       = "example string";
    lcmData.enabled    = 1;

    exlcm_example_t_publish(lcm, "EXAMPLE", &lcmData);

    lcm_destroy(lcm);

    return  (ERROR_NONE);
}

數exlcm_example_t_publish將數據串行化爲字節流,並使用LCM將數據包發送給接收器,「EXAMPLE」在這裏表示通道名,是與數據包一塊兒進行傳輸的字符串,用於向接收方標識內容。接收這使用該標識符訂閱不一樣的通道,從而能夠快速有效的丟棄無關的數據。 
2.3 訂閱消息 
如2.2節所描述,每一個LCM消息都以相關聯的通道名發送,用戶能夠根據通道名決定應用程序接收哪些已訂閱的消息。發佈者與接收者必須就每種消息類型達成使用的通道名的一致性。 
消息訂閱示例代碼以下所示。網絡

#include <stdio.h>
#include <inttypes.h>
#include <sys/select.h>
#include <lcm/lcm.h>
#include "exlcm_example_t.h"
static void my_handler (const lcm_recv_buf_t   *rbuf,
                        const char             *channel,
                       const exlcm_example_t  *msg,
                       void                    *user)
{
    printf("Received message on channel %s:\n", channel);
}

int main(int argc, char ** argv)
{
    int     status
    lcm_t  *lcm;

    lcm = lcm_create(NULL);
    if(!lcm) {
        return  (PX_ERROR);
    }

    exlcm_example_t_subscription_t  *sub =
        exlcm_example_t_subscribe(lcm, "EXAMPLE", &my_handler, NULL);

    while(1) {
        fd_set  fds;
        int     lcm_fd = lcm_get_fileno(lcm);

        FD_ZERO(&fds);
        FD_SET(lcm_fd, &fds);

        struct timeval timeout = {
            1,
            0
        };

        status = select(lcm_fd + 1, &fds, 0, 0, &timeout);
        if(ERROR_NONE == status) {
            printf("waiting for message\n");
        } else if(FD_ISSET(lcm_fd, &fds)) {
            lcm_handle(lcm);
        }
    }

    exlcm_example_t_unsubscribe(lcm, sub);
    lcm_destroy(lcm);

    return  (ERROR_NONE);
}

示例代碼首先建立了一個LCM實例,而後向「EXAMPL」通道添加訂閱,當該通道接收到消息,將會調用my_handler將該通道打印出來。其中my_handler是在lcm_handle函數內被調用的。若是其餘通道上有消息傳輸,則該示例程序不會接收到,由於該程序只訂閱了「EXAMPL」通道。一般一個特定的LCM實例可能具備若干數量的訂閱。 
3. 最後 
SylixOS基於LCM通訊模塊開發了一套板間通訊機制。該機制主要完成了對LCM庫的進一步封裝。詳細內容參見文檔《SylixOS板間通訊框架開發手冊》。數據結構

相關文章
相關標籤/搜索