1. 服务通信的定义

服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。

2.自定义srv的配置

功能包下新建 srv 目录,添加 xxx.srv 文件,内容:

2.1定义srv文件

# 客户端请求时发送的两个数字
int32 num1
int32 num2
---
# 服务器响应发送的数据
int32 sum

2.2编辑配置文件

package.xml中添加编译依赖与执行依赖

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

2.3CMakeLists.txt编辑 srv 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
add_service_files(
  FILES
  AddInts.srv
)
generate_messages(
  DEPENDENCIES
  std_msgs
)

2.3编译

3.vscode配置

配置c_cpp_properies.json
在(c_cpp_properies.json )下配置文件的路径

4.服务端

服务器实现:
1.包含头文件
2.初始化 ROS 节点
3.创建 ROS 句柄
4.创建 服务 对象
5.回调函数处理请求并产生响应
6.由于请求有多个,需要调用 ros::spin()

//1.包含头文件
#include "ros/ros.h"
#include“xxxxx/xxx"(srv文件的路径)
bool doReq(demo03_server_client::AddInts::Request& req,
          demo03_server_client::AddInts::Response& resp){	
    //处理请求
    int num1 = req.num1;
    int num2 = req.num2;
    ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);
    //处理相应
    resp.sum = num1 + num2;
    return true;
}         
int main(int argc, char *argv[])
{
	//2.初始化 ROS 节点
    ros::init(argc,argv,"AddInts_Server");
    ROS_INFO("action");
    //3.创建 ROS 句柄
    ros::NodeHandle nh;
    // 4.创建 服务 对象
    ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
    ROS_INFO("服务已经启动....");
    //5.回调函数处理请求

	//6.
    ros::spin();
    return 0;
}

5.客户端

服务器实现:
1.包含头文件
2.初始化 ROS 节点
3.创建 ROS 句柄
4.创建 客户端 对象
5.请求服务,接收响应

// 1.包含头文件
#include "ros/ros.h"
#include "demo03_server_client/AddInts.h"
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
	//检查传入的参数的数量,如果传入参数不为3个,则返回
    if (argc != 3)
    {
        ROS_ERROR("请提交两个整数");
        return 1;
    }


    // 2.初始化 ROS 节点
    ros::init(argc,argv,"AddInts_Client");
    // 3.创建 ROS 句柄
    ros::NodeHandle nh;
    // 4.创建 客户端 对象
    ros::ServiceClient client = nh.serviceClient<demo03_server_client::AddInts>("AddInts");
    //允许先启动客户端再等待服务端启动的方法
    ros::service::waitForService("AddInts");
    //也可以执行下列代码
    // client.waitForExistence();
    // 5.组织请求数据
    demo03_server_client::AddInts ai;
    //argv中储存的是char类型参数,需用atoi将char转化成int类型
    ai.request.num1 = atoi(argv[1]);
    ai.request.num2 = atoi(argv[2]);
    // 6.发送请求,返回 bool 值,标记是否成功
    bool flag = client.call(ai);
    // 7.处理响应
    if (flag)
    {
        ROS_INFO("请求正常处理,响应结果:%d",ai.response.sum);
    }
    else
    {
        ROS_ERROR("请求处理失败....");
        return 1;
    }

    return 0;
}

6.配置CMakeLists.txt

add_executable(AddInts_Server src/AddInts_Server.cpp)
add_executable(AddInts_Client src/AddInts_Client.cpp)


add_dependencies(AddInts_Server ${PROJECT_NAME}_gencpp)
add_dependencies(AddInts_Client ${PROJECT_NAME}_gencpp)


target_link_libraries(AddInts_Server
  ${catkin_LIBRARIES}
)
target_link_libraries(AddInts_Client
  ${catkin_LIBRARIES}
)

4.执行
rosrun 包名 服务
rosrun 包名 客户端 参数1 参数2

学习视频
【【Autolabor初级教程】ROS机器人入门】 https://www.bilibili.com/video/BV1Ci4y1L7ZZ/?p=71&share_source=copy_web&vd_source=d76161aaff16cdf3f82144c736e33912

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐