资讯

上海硅步ROS连载系列40期 创建服务器节点和客户端节点

转载 2017-11-24 15:46 上海硅步 来源:上海硅步
上海硅步科学仪器有限公司

  本节介绍使用C++编写ROS消息服务器节点和客户端节点的方法和步骤,以及如何构建和测试这两个节点。

  1.编写服务器节点代码

  使用kdevelop在ros_tutorials/src目录下创建一个名为add_two_ints_server的C++文件:

  $ roscd ros_tutorials

  $ cd src

  $ kdevelopadd_two_ints_server.cpp

  输入如下代码:

  #include"ros/ros.h"

  #include "ros_tutorials/AddTwoInts.h"

  bool add(ros_tutorials::AddTwoInts::Request &req,

  ros_tutorials::AddTwoInts::Response&res)

  {

  res.sum = req.a + req.b;1

  ROS_INFO("request: x="%ld," y="%ld"",(long int)req.a, (long int)req.b);

  ROS_INFO("sending back response:[%ld]", (long int)res.sum);

  return true;

  }

  int main(int argc, char**argv)

  {

  ros::init(argc, argv,"add_two_ints_server");

  ros::NodeHandle n;

  ros::ServiceServer service =n.advertiseService("add_two_ints", add);

  ROS_INFO("Ready to add two ints.");

  ros::spin();

  return 0;

  }

  部分代码解释如下:

  #include "ros_tutorials/AddTwoInts.h"

  ros_tutorials/AddTwoInts.h是由编译系统自动根据先前创建的srv文件生成的对应该srv文件的头文件。

  bool add(ros_tutorials::AddTwoInts::Request &req,

  ros_tutorials::AddTwoInts::Response&res)

  该函数提供两个int值求和的服务,int值从Request里面获取,而返回数据装入Response内,这些数据类型都定义在srv文件内部,函数返回一个bool值。

  {

  res.sum = req.a + req.b;

  ROS_INFO("request: x="%ld," y="%ld"",(long int)req.a, (long int)req.b);

  ROS_INFO("sending back response:[%ld]", (long int)res.sum);

  return true;

  }

  进行两个整数相加运算,结果存储在Response中。把Request和Response的一些信息记录日志,最后当运算完成时服务返回True。

  ros::ServiceServerservice = n.advertiseService("add_two_ints", add);

  创建服务service并在ROS网络上进行广播。

  2.编写客户端节点代码

  使用kdevelop在ros_tutorials/src目录下创建一个名为add_two_ints_client的C++文件:

  $ roscd ros_tutorials

  $ cd src

  $ kdevelopadd_two_ints_client.cpp

  输入如下代码:

  #include"ros/ros.h"

  #include "ros_tutorials/AddTwoInts.h"

  #include

  int main(int argc, char**argv)

  {

  ros::init(argc, argv,"add_two_ints_client");

  if (argc != 3)

  {

  ROS_INFO("usage: add_two_ints_client XY");

  return 1;

  }

  ros::NodeHandle n;

  ros::ServiceClient client =n.serviceClient ("add_two_ints");

  ros_tutorials::AddTwoInts srv;

  srv.request.a = atoll(argv[1]);

  srv.request.b = atoll(argv[2]);

  if (client.call(srv))

  {

  ROS_INFO("Sum: %ld", (longint)srv.response.sum);

  }

  else

  {

  ROS_ERROR("Failed to call serviceadd_two_ints");

  return 1;

  }

  return 0;

  }

  部分代码解释如下:

  ros::ServiceClientclient = n.serviceClient ("add_two_ints");

  为add_two_ints服务创建一个客户端。ros::ServiceClient对象用来随后调用服务。

  ros_tutorials::AddTwoIntssrv;

  srv.request.a= atoll(argv[1]);

  srv.request.b= atoll(argv[2]);

  实例化一个自动生成的服务类,并为其request成员赋值。一个服务类包含两个成员,request和response,也包括两个类的定义:Request和Response。

  if(client.call(srv))

  调用服务,调用完成后立即返回。如果服务调用成功,call()将返回true,此时srv.response中的值有效。如果服务调用失败,call()将返回false,srv.response中的值无效。

  3.生成节点

  打开~/catkin_ws/src/ros_tutorials/CMakeLists.txt,将以下代码添加到最后:

  add_executable(add_two_ints_serversrc/add_two_ints_server.cpp)

  target_link_libraries(add_two_ints_server${catkin_LIBRARIES})

  add_dependencies(add_two_ints_serverros_tutorials_gencpp)

  add_executable(add_two_ints_clientsrc/add_two_ints_client.cpp)

  target_link_libraries(add_two_ints_client${catkin_LIBRARIES})

  add_dependencies(add_two_ints_clientros_tutorials_gencpp)

  这将会创建两个可执行程序,add_two_ints_server和add_two_ints_client。默认情况下,它们将会位于你的开发空间里面的ros_tutorials功能包目录下(~/catkin_ws/devel/lib/ros_tutorials),你可以直接调用它们或者使用rosrun运行它们。

  运行 catkin_make:

  # In your catkinworkspace

  $ cd ~/catkin_ws

  $ catkin_make

  4.测试服务器和客户端节点

  首先启动roscore:

  $ roscore

  在另一个终端窗口运行下面的命令启动服务器节点:

  $ rosrun ros_tutorialsadd_two_ints_server

  你会看到下面的输出:

  Ready to add two ints.

  新建一个终端,运行客户端节点:

  $ rosrun ros_tutorials add_two_ints_client 2 3

  你会看到类似下面的输出:

  Requesting 2+3

  2 + 3 = 5

0 0

网友评论

取消