ROS的基本用法二 服务通信

第一节:ROS的服务

摘要:

介绍ROS的服是双向的通信,客户端提交,服务端处理后返回到客户端。

1. *理论介绍*

自定义数据类型,根据自定义数据类型进行处理,客户端请求,服务端处理之后,返回客户端,是一种双向的通信机制。

2. *功能实现*

创建一个客户端,输入求积的两个数

创建一个服务端,处理求积的回调函数,并返回在输出端显示结果

3. *步骤实现*

3.1在ROS的工作空间中,创建一个功能包,并且进行编译:

wpf@wpfpc:$ cd ~/catkin_fs/src
wpf@wpfpc:~/catkin_fs/src$ catkin_create_pkg test_addtwo std_msgs roscpp rospy
wpf@wpfpc:~/catkin_fs/src$ cd ..
wpf@~/catkin_fs$ catkin_make

文件功能包的文件目录如下

wpf@wpf:~/catkin_ps/src/test_addtwo$ tree
.
├── CMakeLists.txt
├── include
│   └── test_addtwo
├── package.xml
├── src
│   ├── client1.cpp
│   └── server1.cpp
└── srv
    └── AddTwoInts.srv

4 directories, 5 files

3.2 修改package.xml的内容

 <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>


  <build_depend>message_generation</build_depend>



  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>


    <exec_depend>message_runtime</exec_depend>

创建src 文件夹和 AddTwoInts.srv文件,

int64 a
int64 b
---
int64 sum

关键是加上两句话

<build_depend>message_generation</build_depend>

<exec_depend>message_runtime</exec_depend>

进行catkin_make 操作,

/home/wpf/catkin_ps/devel/include/test_srv

路径下生成三个文件

wpf@wpf:~/catkin_ps/devel/include/test_srv$ ls
PassWord.h  PassWordRequest.h  PassWordResponse.h

在创建的功能包的src目录下创建两个文件

├── client1.cpp
└── server1.cpp

3.3 修改功能包中CMakeList.txt的内容

3.4 代码修改之后,编译成功之后即可运行

3.5 打开四个终端分别执行,一个roscore;两个节点,以及运行rqt查看节点之间的通信关系。

wpf@wpfpc:~/catkin_fs$ roscore
wpf@wpfpc:~/catkin_fs$ wpf@wpf:~$ rosrun test_addtwo server1 
wpf@wpfpc:~/catkin_fs$wpf@wpf:~$ rosrun test_addtwo client1 3 4
wpf@wpfpc:~/catkin_fs$ rosrun rqt_graph  rqt_graph

代码运行结果如下:

客户端

wpf@wpf:~$ rosrun test_addtwo client1 3 4
[ INFO] [1654681331.194028686]: sum: 7

服务端

 wpf@wpf:~$ rosrun test_addtwo server1 
[ INFO] [1654681326.655080262]: Ready to add two ints.
[ INFO] [1654681331.193792048]: request: x=3, y=4
[ INFO] [1654681331.193824662]: sending back response: [7]

节点之间的通信框图如下:

在这里插入图片描述

*实验分析:*

本实验,实现了节点之间的通信功能,由图可知,无需多言。

代码附录

服务端代码

#include "ros/ros.h"
#include "test_addtwo/AddTwoInts.h"
 
// service回调函数,输入参数req,输出参数res
bool add(test_addtwo::AddTwoInts::Request  &req,
         test_addtwo::AddTwoInts::Response &res)
{
  // 将输入参数中的请求数据相加,结果放到应答变量中
  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;
}
 
int main(int argc, char **argv)
{
  // ROS节点初始化
  ros::init(argc, argv, "add_two_ints_server");
  
  // 创建节点句柄
  ros::NodeHandle n;
 
  // 创建一个名为add_two_ints的server,注册回调函数add()
  ros::ServiceServer service = n.advertiseService("add_two_ints", add);
  
  // 循环等待回调函数
  ROS_INFO("Ready to add two ints.");
  ros::spin();
 
  return 0;
}

客户端代码

#include <cstdlib>
#include "ros/ros.h"
#include "test_addtwo/AddTwoInts.h"
 
int main(int argc, char **argv)
{
  // ROS节点初始化
  ros::init(argc, argv, "add_two_ints_client");
  
  // 从终端命令行获取两个加数
  if (argc != 3)
  {
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }
 
  // 创建节点句柄
  ros::NodeHandle n;
  
  // 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoInts
  ros::ServiceClient client = n.serviceClient<test_addtwo::AddTwoInts>("add_two_ints");
  
  // 创建learning_communication::AddTwoInts类型的service消息
  test_addtwo::AddTwoInts srv;
  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);
  
  // 发布service请求,等待加法运算的应答结果
  if (client.call(srv))
  {
    ROS_INFO("sum: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("Failed to call service add_two_ints");
    return 1;
  }
 
  return 0;
}

CMakeLists.txt代码

cmake_minimum_required(VERSION 3.0.2)
project(test_addtwo)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)


 add_service_files(
   FILES
	AddTwoInts.srv
 )


 generate_messages(
   DEPENDENCIES
   std_msgs
 )

catkin_package(
  CATKIN_DEPENDS 
  message_runtime
)


include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

 add_executable(server1 src/server1.cpp)
 add_executable(client1 src/client1.cpp)
 
 add_dependencies(server1 ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
 add_dependencies(client1 ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
 
 target_link_libraries(server1 ${catkin_LIBRARIES})
 target_link_libraries(client1 ${catkin_LIBRARIES})


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值