测试案例介绍
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);
}