ROS系统学习7---LCM数据的发送和接收

前面的几篇文章我们简单介绍了ROS的一些基本操作和数据获取的实现。下面,我们将更深入地研究ROS的数据传递,因为这关系到能不能真正把ROS用于实际的工程项目中。

如果工程只用ROS搭建,那么是不需要用到命题所说的LCM的。但如果ROS只是整体系统的一部分,则需要利用内存共享或者网络传输等方式与其他程序进行数据交互,这时候LCM就是一种比较简单的选择(如果不清楚什么是LCM,可以参考这篇文章)。

下面,我们将逐步介绍如何在ROS系统中使用LCM。

联系前面,我们已经知道ROS归根结底是一个多进程的管理工具,因此我们可以把上面的工作分成两步。

第一步:在Ubuntu下把LCM搭建起来,可以直接发送和接收数据。

第二步:把上面做完的用LCM发送和接收的代码移植到ROS中。

下面我们来做第一步(这里只用C++实现,其他版本类似):

先安装编译LCM会用到的依赖项:

sudo apt-get install build-essential autoconf automake autopoint libglib2.0-dev libtool openjdk-8-jdk python-dev

到github上下载源码包,这里本人下的是"lcm-1.4.0.zip"

下完后直接解压缩,然后cd进去解压后的文件夹:

mkdir build
cd build
cmake ..
make

 

 

等待编译完成(意外的快),然后安装:

 

sudo make install

完成这一步就算搞定了,但这个时候系统不知道lib的库在哪里,因此需要告诉它。

为lcm创建一个ld.so.conf文件:

 

export LCM_INSTALL_DIR=/usr/local/lib
sudo sh -c "echo $LCM_INSTALL_DIR > /etc/ld.so.conf.d/lcm.conf"

更新

 

sudo ldconfig

 

配置pkgconfig来查找lcm.pc

 

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$LCM_INSTALL_DIR/pkgconfig

做完上面的步骤,则LCM就全部安装配置完成了。接着我们可以写一个客户端和服务器测试下。

首先写服务器,LCM_Client.cpp:

#include 
#include "lcm/lcm-cpp.hpp"
 
int main()
{
	lcm::LCM lcm;
	if (!lcm.good())
	{
		return 1;
	}
	char data[5];
	data[0] = 1;
	data[1] = 5;
	data[2] = 1;
	data[3] = 2;
	data[4] = 1;
	lcm.publish("EXAMPLE", data,5);//第一个参数是通道名,第二个参数是数据指针,第三个参数是长度
	std::cout << "发送成功!";
	return 0;
}

然后编译+链接:

g++ `pkg-config --cflags lcm` -I. -o Client.o -c LCM_Client.cpp

g++ -o Client Client.o `pkg-config --libs lcm`

 

其次写客户端,LCM_Server.cpp:

 

#include 
#include "lcm/lcm-cpp.hpp"
 
class MyMessageHandler 
{
public:
	void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel) 
	{
		std::cout << (int)((unsigned char*)rbuf->data)[0] << std::endl;
		std::cout << (int)((unsigned char*)rbuf->data)[1] << std::endl;
		std::cout << (int)((unsigned char*)rbuf->data)[2] << std::endl;
		std::cout << (int)((unsigned char*)rbuf->data)[3] << std::endl;
		std::cout << (int)((unsigned char*)rbuf->data)[4] << std::endl;
		std::cout << "接收成功!";
	}
};
 
int main() {
	lcm::LCM lcm;
	MyMessageHandler handler;
	lcm.subscribe("EXAMPLE", &MyMessageHandler::onMessage, &handler);
	while (true)
		lcm.handle();
	return 0;
}

同样编译+链接:

g++ `pkg-config --cflags lcm` -I. -o Server.o -c LCM_Server.cpp

g++ -o Server Server.o `pkg-config --libs lcm`

这样我们就得到了LCM的服务器和客户端,运行效果如下:

ROS系统学习7---LCM数据的发送和接收_第1张图片

接下来我们看看怎么把LCM放到ROS里面跑。

在我们前面文章创建的rosOpenCV包下新建两个文件,分别为“LCM_Client.cpp”、“LCM_Server.cpp”,内容如下:

LCM_Client.cpp

 

#include 
#include 
#include "lcm/lcm-cpp.hpp"

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;

  lcm::LCM lcm;
  if (!lcm.good())
  {
    return 1;
  }
  char data[5];
  data[0] = 1;
  data[1] = 5;
  data[2] = 1;
  data[3] = 2;
  data[4] = 1;
  lcm.publish("EXAMPLE", data,5);//第一个参数是通道名,第二个参数是数据指针,第三个参数是长度
  std::cout << "发送成功!";

  ros::spinOnce();
}

LCM_Server.cpp

#include 
#include 
#include "lcm/lcm-cpp.hpp"

class MyMessageHandler 
{
public:
  void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel) 
  {
    std::cout << (int)((unsigned char*)rbuf->data)[0] << std::endl;
    std::cout << (int)((unsigned char*)rbuf->data)[1] << std::endl;
    std::cout << (int)((unsigned char*)rbuf->data)[2] << std::endl;
    std::cout << (int)((unsigned char*)rbuf->data)[3] << std::endl;
    std::cout << (int)((unsigned char*)rbuf->data)[4] << std::endl;
    std::cout << "接收成功!";
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;

  lcm::LCM lcm;
  MyMessageHandler handler;
  lcm.subscribe("EXAMPLE", &MyMessageHandler::onMessage, &handler);
  while (true)
    lcm.handle();

  ros::spin();
}

接着修改“CmakeLists.txt”,主要内容如下:

 

include_directories(${catkin_INCLUDE_DIRS})
add_executable(LCM_Client /home/weixin/桌面/lcmdemo/src/printHelloRosPK/src/LCM_Client.cpp)
target_link_libraries(LCM_Client lcm)
target_link_libraries(LCM_Client ${catkin_LIBRARIES})

add_executable(LCM_Server /home/weixin/HelloRos/src/rosOpenCV/src/LCM_Server.cpp)
target_link_libraries(LCM_Server lcm)
target_link_libraries(LCM_Server ${catkin_LIBRARIES})

最后编译运行一下即可。

ROS系统学习7---LCM数据的发送和接收_第2张图片

 

 

 

 

你可能感兴趣的:(ROS学习,ROS操作系统学习)