[学习笔记]服务通讯初体验

ros通讯之服务通。

早知道有这个东西我还写什么tcp通讯啊(笑)

0、自定义srv消息&&配置

与话题通信不一样的是,这个通讯需要自定义消息类型。

与话题通讯的自定义相同,要在src目录下建立一个srv文件夹,并且定义一个***.srv文件用来存储数据类型。

int32 num1
int32 num2//发送端
---
int32 sum //回复端

接下来,就是配置cmakelist和package.xml了

package.xml的配置与话题通讯相同,

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

message_generation&&message_runtime

CMakeLists也与话题通讯大差不差

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation//添加message_generation
)
add_service_files(
  FILES
  Addints.srv//添加我们自定义的包
)
generate_messages(
  DEPENDENCIES
  std_msgs
)//打开注释
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime //打开注释并且添加mmessage_runtime

然后编译一下,就能看到./devel/include里的三个头文件了

这里与话题通讯不同的是有三个头文件,从名字就能看出来,分别是给发送端和回复端使用的。

然后,把头文件路径加进c_cpp_properties.json中,就可以正常写代码了

2、服务端&客户端代码实现

发送端:

#include <ros/ros.h>
#include "plumbing_server_client/Addints.h"//这里需要调用一下头文件

int main(int argc,char *argv[])
{
    if(argc!=3)//这里调用argv,直接从命令行里获得参数,rosrun 包名 程序名,从程序名开始算参数,会计入argv中,之后如果输入数字就可以调用
    {
        ROS_INFO("num_error");
        return 1;
    }
    ros::init(argc, argv, "dabao");//一系列初始化操作
    ros::NodeHandle nh;
    ros::ServiceClient client=nh.serviceClient<plumbing_server_client::Addints>("AddInts");//直接调用句柄的函数成员
    plumbing_server_client::Addints ai;
    ai.request.num1 = atoi(argv[1]);//因为argv中的参数是字符型,调用atoi函数进行转化
    ai.request.num2 = atoi(argv[2]);
    bool flag = client.call(ai);//发送并且用client获得参数
    if(flag)//如果回调参数存在
    {
        ROS_INFO("success");//balabala
        ROS_INFO("%d", ai.response.sum);
    }
    else//如果回调参数不存在
    {
        ROS_INFO("failure");//balabala
    }
    return 0;
}

回复端:

#include<ros/ros.h>
#include"plumbing_server_client/Addints.h"
using namespace ros;
bool doNums(plumbing_server_client::Addints::Request &request,//回调函数,布尔型,成员是请求和回复两个类的指针
            plumbing_server_client::Addints::Response &reponse)
{
    int num1 = request.num1;
    int num2 = request.num2;
    ROS_INFO("%d %d", num1,num2);
    int sum = num1 + num2;
    reponse.sum = sum;
    ROS_INFO("%d", sum);
    return true;//如果执行了就回复true
}
int main(int argc, char *argv[])
{
    init(argc, argv, "hs");
    NodeHandle nh;
    ServiceServer server = nh.advertiseService("addints", doNums);//回复
    spin();
    return 0;
}

(完)

 

posted @ 2022-07-13 10:26  阿基米德的澡盆  阅读(31)  评论(0编辑  收藏  举报