基于LCM(C++)的双机通信测试(linux主机+upboard)

测试案例介绍 
linux主机 subscriber代码 
upboard publisher代码

1.测试案例介绍

  upboard连接路由器,linux主机连接路由器wifi,使二者处于同一局域网下
  upboard作为publisher,每隔2seconds发布一则消息,linux主机作为subscriber,接收到消息后在终端打印接受的消息。

2.linux主机subscriber代码

subscriber.cpp

#include "subscriber.h"

Subscriber::Subscriber():_lcm(getLcmUrl(255)){}

void Subscriber::subscribe(){
    _lcm.subscribe("EXAMPLE",&Subscriber::handleMessage,this); //处理回调函数
    _lcmThread = std::thread([&](){
         while(_lcm.handle() == 0) 
               if(IsExit) break;                               //获取到终止标志,退出线程
     std::cout << "goodbye !" << std::endl;
    });
}


void Subscriber::handleMessage(const lcm::ReceiveBuffer* rbuf,const std::string &chan,
				   const exlcm::example_t *msg)
{
    (void)rbuf;

    _mutex.lock(); 
	int i;
    std::cout << std::endl;
    std::cout << "i am the subscriber !" << std::endl;
    printf("Received message on channel \"%s\":\n", chan.c_str());
    printf("  timestamp   = %lld\n", (long long) msg->timestamp);
    printf("  position    = (%f, %f, %f)\n", msg->position[0], msg->position[1],
    msg->position[2]);
    printf("  orientation = (%f, %f, %f, %f)\n", msg->orientation[0], msg->orientation[1],
    msg->orientation[2], msg->orientation[3]);
    printf("  ranges:");
    for (i = 0; i < msg->num_ranges; i++)
    printf(" %d", msg->ranges[i]);
    printf("\n");
    printf("  name        = '%s'\n", msg->name.c_str());
    printf("  enabled     =   %d\n", msg->enabled);
    std::cout << "looking for your next message !" << std::endl;
    std::cout << std::endl;
   _mutex.unlock(); 

    if(msg->timestamp >= 3)     IsExit = true;            //接受到终止信号
}

subscriber.h

#pragma once
#include <lcm/lcm-cpp.hpp>
#include <stdio.h>
#include "exlcm/example_t.hpp"
#include <thread>
#include <mutex>
#include "utilities.h"

class Subscriber{
	public:
     Subscriber();
	~Subscriber(){};
	 void handleMessage(const lcm::ReceiveBuffer* rbuf,const std::string &chan,
				   const exlcm::example_t *msg);
     void subscribe();
     bool getIsExit() {return IsExit;}

    private:
       lcm::LCM     _lcm;
       std::thread  _lcmThread;
       std::mutex   _mutex;
       bool IsExit = false;
};

main.cpp

#include <mutex>
#include "utilities.h"
#include "subscriber.h"
#include <unistd.h>

int main(int argc,char** argv){
    Subscriber _s;   
 
    _s.subscribe();

    while(!_s.getIsExit());      //阻塞主线程,等待subscriber接收完毕
  
    sleep(1);                    //等待subscriber线程退出,退出主线程

    return 0;
}

Makefile

CXX = g++

#Use pkg-config to lookup the proper compiler and linker flags for LCM
CFLAGS  = "/usr/local/include/`ls /usr/local/include/lcm`"        #lcm库相关头文件
LDFLAGS =  lcm                                                    #lcm库相关动态库文件

           

all:exlcm/example_t.hpp \
    main                         

all:
	@rm -f *.o                


main:main.o subscriber.o utilities.o
	$(CXX) -o $@ $^ -l$(LDFLAGS) -lpthread

%.o:%.cpp exlcm/example_t.hpp           #生成二进制文件
	$(CXX) -I$(CFLAGS) -I. -o $@ -c $<

exlcm/%.hpp:                            #利用lcm-gen将.lcm转换为.hpp
	lcm-gen -x *.lcm


clean:
	rm -f main   
	rm -f exlcm/*.hpp

3.upboard publisher代码

publisher.cpp

#include "publisher.h"
Publisher::Publisher():_lcm(getLcmUrl(255)){
        memset(&my_data,0,sizeof(exlcm::example_t));
}

void Publisher::publish(int num){
	my_data.timestamp = num;
        my_data.position[0] = 1;
        my_data.position[1] = 2;
        my_data.position[2] = 3; 
        my_data.orientation[0] = 1;

	my_data.num_ranges = 15;
        my_data.ranges.resize(my_data.num_ranges);
        for (int i = 0; i < my_data.num_ranges; i++)
           my_data.ranges[i] = i;

        my_data.name = "example string";
        my_data.enabled = true;

        _mutex.lock();
        _lcm.publish("EXAMPLE", &my_data);            //利用publish函数发布消息
        _mutex.unlock();
}
}

publisher.h

#pragma once
#include <lcm/lcm-cpp.hpp>
#include <stdio.h>
#include <stdlib.h>
#include "exlcm/example_t.hpp"
#include <thread>
#include <mutex>
#include "utilities.h"

class Publisher{
public:
     Publisher();
	~Publisher(){};
     void publish(int num);
private:
     lcm::LCM     _lcm;
     exlcm::example_t my_data;
     std::mutex   _mutex;
};

main.cpp

#include <lcm/lcm-cpp.hpp>
#include <stdio.h>
#include "exlcm/example_t.hpp"
#include <thread>
#include <mutex>
#include "utilities.h"
#include "publisher.h"
#include <unistd.h>

int main(int argc,char** argv){
    int count = 0;
    Publisher _p;
 
    std::thread Publisher_Thread([&](){           //开启子线程,执行publish任务
       while(count++ != 3){
           sleep(2);
           _p.publish(count);
           std::cout << "i am the publisher !" << std::endl <<
                "i have published the " << count << "th message" <<std::endl;
       }
    });

    Publisher_Thread.join();                      //等待publish子线程终止,退出主线程

    return 0;
}

Makefile

CXX = g++

#Use pkg-config to lookup the proper compiler and linker flags for LCM
CFLAGS  = "/usr/local/include/`ls /usr/local/include/lcm`"        #lcm库相关头文件
LDFLAGS =  lcm                                                    #lcm库相关动态库文件             

all:exlcm/example_t.hpp \
    main                

all:
	@rm -f *.o                


main:main.o  publisher.o utilities.o
	$(CXX) -o $@ $^ -l$(LDFLAGS) -lpthread

%.o:%.cpp exlcm/example_t.hpp           #生成二进制文件
	$(CXX) -I$(CFLAGS) -I. -o $@ -c $<

exlcm/%.hpp:                            #利用lcm-gen将.lcm转换为.hpp
	lcm-gen -x *.lcm


clean:
	rm -f main
	rm -f exlcm/*.hpp

4.getLcmUrl

程序中还用到了getLcmUrl函数,用于获取局域网下的udp地址,这个函数我单独存放在了utilities文件中
utilities.cpp

#include "utilities.h"
#include <assert.h>
/*!
 * Get the LCM URL with desired TTL.
 */
std::string getLcmUrl(int64_t ttl) {
  assert(ttl >= 0 && ttl <= 255);
  return "udpm://239.255.76.67:7667?ttl=" + std::to_string(ttl);
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值