[学习笔记]服务通讯初体验
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; }
(完)