ROS node调用service: ros::service::call/client.call()

摘要:
开始时,教程包如下所示。1.创建msg文件夹和srv文件夹。2.然后更改CMakeList。txt文件转换为以下内容,主要设计msg和srv的其他依赖关系以及编译和运行关系##Findcatkinmacrosandlibraries##ifCOMPONENTSlistlikefind_ package##,还可以找到其他catkinpackagesfind_package##在'msg'文件夹中生成消息messages_files##在'srv'文件夹中产生服务add_service_files##生成具有此处列出的任何依赖项的添加消息和服务generate_messages#include_directoriesinclude_directories_catkin_也可以引用包。在wiki中,CreatingMsgAndSrv中的进程名称没有更改,但文件中的内容已更改。重写后,您可以单击ws目录下的catkin_catkin一次,然后单击sourcedevel/setup.bash下的。

简介:介绍如何在一个node里调用现有的rosservice list查询到的service。

效果:通过talker publish需要调用服务的数据,listener接收到数据后调用服务进行三个整形数据相加,并返回相加和。

环境:ubuntu 14.04 +indigo.

备注:文中未详细介绍的api或ros的基本函数请参看之前博文。

[正文]

创建过程类似wiki教程中msg和srv的测试过程。在beginner_turtorials包下面创建。

1,创建msg文件夹,srv文件夹。

msg 文件夹下创建Num.msg,内容是

int32 A

int32 B

int32 C

srv文件夹下AddTwoInts.srv,内容是

int32 A

int32 B

int32 C

---

int32 sum

该文件表面输入是ABC,返回是 sum,两者通过“---”分割。

2,然后更改CMakeList.txt文件,修改为如下内容,主要设计msg,srv的其他依赖关系及编译运行的相关关系。

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
## Generate messages in the 'msg' folder
 add_message_files(
   FILES
   Num.msg
 )


## Generate services in the 'srv' folder
 add_service_files(
   FILES
   AddTwoInts.srv
 )
## Generate added messages and services with any dependencies listed here
 generate_messages(
   DEPENDENCIES
   std_msgs
 )
# include_directories(include)
include_directories(
  ${catkin_INCLUDE_DIRS}
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES beginner_tutorials
#  CATKIN_DEPENDS roscpp rospy std_msgs
#  DEPENDS system_lib
  CATKIN_DEPENDS message_runtime
)

也可参考,wiki中CreatingMsgAndSrv中过程,名称都没有改变,只是改变了文件中内容,改写完成后可以在catkin_ws目录下catkin_make一次,并source devel/setup.bash下。

3,建立几个cpp的源文件,位于src目录下。

3.1 src/example_srv_request.cpp

作用:主要实现服务的定义,初始化,注释由于ubuntu没装汉语输入,因此注释为英文...聊胜于无。

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"

bool add(beginner_tutorials::AddTwoInts::Request &req,
         beginner_tutorials::AddTwoInts::Response &res)
{
    res.sum=req.A+req.B+req.C;
    ROS_INFO("request: A=%ld,B=%ld,C=%ld",(int)req.A,(int)req.B,(int)req.C);
    ROS_INFO("sending back response:[%ld]",(int)res.sum);

    return true;
}


int main(int argc,char **argv)
{
   ros::init(argc,argv,"add_3_ints_server");
   ros::NodeHandle n;
   //init service:
   //Name: add_3_ints,advertise the service. add: call back function
   ros::ServiceServer service=n.advertiseService("add_3_ints",add);
   ROS_INFO("Ready to add 3 ints.");
   ros::spin();// start to deal with the call back event

   return 0;
}
3.2 src/example_srv_response.cpp,该文件并非必要,是典型的client调用服务的形式,并非此文目的,不添加最终目的也可实现,调用示例是(现在还不能调用):

rosrun beginner_tutorials example_srv_response 1 2 3

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>


int main(int argc,char **argv)
{
    ros::init(argc,argv,"add_3_ints_client");
    if(argc != 4)
    {
        ROS_INFO("usage: add_3_ints_client A B C");
        return 1;
    }
    ros::NodeHandle n;
    ros::ServiceClient client=n.serviceClient<beginner_tutorials::AddTwoInts>("add_3_ints");

    beginner_tutorials::AddTwoInts srv;

    //atoll:convert a string to long long int variable
    srv.request.A=atoll(argv[1]);
    srv.request.B=atoll(argv[2]);
    srv.request.C=atoll(argv[3]);


    if(client.call(srv))
    {
        ROS_INFO("Sum:%ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_ERROR("Failed to call service add_three_ints");
        return 1;

    }
    return 0;
}
3.3 src/example_talker_msg.cpp

该文件主要实现3个参数的发布,此处发布了A=1,B=2,C=3;

#include "ros/ros.h"
#include "beginner_tutorials/Num.h"
#include <sstream>
//Usage:publish a msg with topic named message


int main(int argc, char **argv)
{
  ros::init(argc, argv, "example_talker_msg");
  ros::NodeHandle n;
  //advertise a topic named "message"
  ros::Publisher pub=n.advertise<beginner_tutorials::Num>("message",1000);
  ros::Rate loop_rate(10);
  while (ros::ok())
  {
    beginner_tutorials::Num msg;
    msg.A=1;
    msg.B=2;
    msg.C=3;
    pub.publish(msg);

    ros::spinOnce();
    loop_rate.sleep();
  }
  return 0;
}
3.4 src/example_listener_msg.cpp

该文件主要实现对前文talker发布的数据的监听,监听到Num类型定义数据后,通过service: ros::service::call / client.call()两种方式进行add_3_ints服务的调用。

#include "ros/ros.h"
#include "beginner_tutorials/Num.h"
#include "beginner_tutorials/AddTwoInts.h"

//declaration of the Example class:construct function, member and so on.
class Example{
public:
    Example();
private:
    ros::NodeHandle nh;
    ros::ServiceClient client;
    ros::Subscriber listener;
    void messageCallback(const beginner_tutorials::Num::ConstPtr& msg);

};

//implementation of construct function.
Example::Example()
{
    client=nh.serviceClient<beginner_tutorials::AddTwoInts>("add_3_ints");
    //monitor a topic named "message",this -> current object,pointer
    listener=nh.subscribe("message",1000,&Example::messageCallback,this);

}

//implementation of one of the Example class memeber.
void Example::messageCallback( const beginner_tutorials::Num::ConstPtr& msg)
{
//    ROS_INFO("I heard:[%d] [%d] [%d]",msg->A,msg->B,msg->C);
    beginner_tutorials::AddTwoInts srv;
    srv.request.A=msg->A;
    srv.request.B=msg->B;
    srv.request.C=msg->C;
    if(ros::service::call("add_3_ints",srv))
        ROS_INFO("SUM: %ld",(long int)srv.response.sum);
    else
        ROS_ERROR("Failed to call service add_three_ints");
    /*
    if(client.call(srv))
    {
        ROS_INFO("SUM: %ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_ERROR("Failed to call service add_three_ints");

    }
    */
}



int main(int argc, char **argv)
{
  ros::init(argc, argv, "example_listener_msg");
  Example exp;
  ros::spin();
  return 0;
}
4 再次修改CMakeList.txt文件
添加编译链接的相关控制语句。

add_executable(example_srv_request src/example_srv_request.cpp)
target_link_libraries(example_srv_request ${catkin_LIBRARIES})

add_executable(example_srv_response src/example_srv_response.cpp)
target_link_libraries(example_srv_response ${catkin_LIBRARIES})

add_executable(example_talker_msg src/example_talker_msg.cpp)
target_link_libraries(example_talker_msg ${catkin_LIBRARIES})

add_executable(example_listener_msg src/example_listener_msg.cpp)
target_link_libraries(example_listener_msg ${catkin_LIBRARIES})
添加后在工作空间主目录cd ~/catkin_ws下进行catkin_make编译,理论上不会出现问题,若有问题检查自己包和msg,srv的生成及cmakelist文件。
5 测试

一个终端运行命令:roscore,

一个终端运行命令(注意此时近乎所有命令和包的名称及可执行文件名称都可以<table>自动补全):rosrun beginner_tutorials example_srv_request;会返回:  [INFO][时间戳]:Ready to add 3 ints.  此时若通过roservice list查询ros提供的服务则会返回add_3_ints等几个服务。

一个终端运行命令:rosrun beginner_tutorials example_talker_msg

一个终端运行命令:rosrun beginner_tutorials example_listener_msg;此时会返回: [INFO][时间戳]:SUM: 6

在此文件中,我们实现了在一个node中以下面两种方式对add_3_ints的服务调用,而不是在命令行中通过rosrun beginner_tutorials example_srv_response 1 2 3调用。

 if(ros::service::call("add_3_ints",srv))
        ROS_INFO("SUM: %ld",(long int)srv.response.sum);
    else
        ROS_ERROR("Failed to call service add_three_ints");
    /*
    if(client.call(srv))
    {
        ROS_INFO("SUM: %ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_ERROR("Failed to call service add_three_ints");

    }
    */






免责声明:文章转载自《ROS node调用service: ros::service::call/client.call()》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java ArrayList【笔记】分布式系统常见的事务处理机制下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

android编译系统的makefile文件Android.mk写法

(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件,即要编译的文件。由于一般情况下 Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式: LOCAL_PATH:=$(call my-dir) 上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。 (2)Android.mk中可以定义多个编...

qmake的使用(可设置c编译器flag参数)

本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso***还是先说一下当前的系统环境:Ubuntu 14.04 + Qt5.4如果没有安装过QT,可以安装下面几个qt软件 sudo apt-get install qt5-default qt5-doc-html qt5-qmake qt5-doc qt5-image-form...

HBase 学习(二) Hbase安装与启动

一,前言 二,前期准备   2.1 文件下载   2.2 服务器准备 三,配置文件配置   3.1 hbase-env.sh   3.2 hbase-site.xml   3.3 regionservers   3.4 将hbase的bin目录添加到环境变量   3.5 Hbase的官方配置文档 四,Hbase服务启动   4.1 Hbase启动   4....

getsockopt的TCP层实现剖析

应用层 NAME getsockopt - get options on sockets SYNOPSIS #include <sys/types.h> #include <sys/socket.h> int getsockopt (int s, int level, int optname, void *optval, sockl...

codeforces 765 F Souvenirs 线段树+set

题意:多次询问区间内 两数差的绝对值的最小值 题解:离线询问则可以按照询问的l排序,倒着询问,倒着从r更新到l 每次更新i+1到n这个区间,保证这次的更新不会影响到下一次以及以后的更新。因为当两个区间出现覆盖时,l更小的那个区间的值一定小于等于另一个,画个图就可以明白。 #include <iostream> #include <cstd...

zynq_ps端点亮led灯代码

#include "stdio.h"#include "xparameters.h"#include "xgpiops.h"#include "sleep.h" //ps_led#define MIO15_LED 15#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID XGpioPs_Config *Config...