ROS基本编程--Service

本文最后更新于:2022年5月29日 上午

服务编程流程

  • 创建服务器
  • 创建客户端
  • 添加编译选项
  • 运行可执行程序

node1

发布一个话题,发布接收到数字总数
接收话题,话题接收一个int型
服务:求和,求话题接收到的所有数字的和
服务:清零

node2

发布一个话题,发布int,隔一个5S随机时间发布
隔60S后,调用求和服务,把结果打印出来。
接收话题,打印NOde1,接收到的数字数量。

1,创建程序包

在工作空间的src目录下:

1
2
cd ~/catkin_ws/src/ 
catkin_create_pkg add_ints roscpp rospy std_msgs

2,修改package.xml作者邮箱

1
2
cd ~/catkin_ws/src/ add_ints
gedit package.xml

3,编译测试

在工作空间目录下:

1
catkin_make

4,定义新的消息

1
2
3
cd ~/catkin_ws/src/add_ints 
mkdir msg
echo "int64 num" > msg/Num.msg

5,修改package.xml

查看package.xml,确保它包含一下两条语句(接近末尾处),如果没有,添加进去:

1
2
<build_depend>message_generation</build_depend> 
<exec_depend>message_runtime</exec_depend>

6,修改CMakeLists.txt文件

1)在find_packag函数的COMPONENTS的列表里增加message_generation,就像这样:

1
2
3
4
5
6
find_package(catkin REQUIRED COMPONENTS 
roscpp
rospy
std_msgs
message_generation
)

2)设置了运行依赖:

1
2
3
4
5
catkin_package(
...
CATKIN_DEPENDS message_runtime
...
)

3)用你的.msg文件替代Message*.msg:

1
2
3
4
add_message_files(
FILES
Num.msg
)

4)取消generate_messages()的注释:

1
2
3
4
add_message_files(
FILES
Num.msg
)

7,检查ROS是否能够识消息

通过rosmsg show命令检查:

1
rosmsg show add_ints/Num

将会看到:

1
int64 num

8,创建一个srv

1
roscd add_ints mkdir srv

9,创建一个服务文件

1
2
cd srv
gedit AddInts.srv

输入一下内容:

1
2
3
4
5
int64 a 
int64 b
int64[13]
---
int64 sum

10,增加额外的依赖项

修改CMakeLists.txt文件,删掉add_service_files的注释: 用你自己的srv文件名替换掉那些Service*.srv文件:

1
2
3
4
add_service_files(
FILES
AddInts.srv
)

11,检查ROS是否能够识该服务

通过rosmsg show命令:

1
rossrv show add_ints/AddInts

将会显示:

1
2
3
4
5
int64 a
int64 b
int64[13]
---
int64 sum

12,重新编译package

1
2
3
# In your catkin workspace 
cd ~/catkin_ws
catkin_make

Service节点和Client节点程序

1,在add_ints/src目录下创建创建程序源代码

1)add_ints_server.cpp

实现一个服务器

  • 初始化ROS节点;
  • 创建Server实例;
  • 循环等待服务请求,进入回调函数;
  • 在回调函数中完成服务功能处理,并反馈应答数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "ros/ros.h"
#include "add_ints/AddInts.h"


bool add(add_ints::AddInts::Request &req,
add_ints::AddInts::Response &res)
{
if(req.b == 12)
{
res.sum = 0;
for(int i=0;i<req.b;i++)
res.sum += req.c[i];

ROS_INFO("sending back response: [%ld]", (long int)res.sum);
}
else
{
ROS_INFO("request: x=%ld", (long int)req.a);
}

return true;
}


int main(int argc, char **argv)
{
ros::init(argc, argv, "add_ints_server");
ros::NodeHandle n;

ros::ServiceServer service = n.advertiseService("add_ints", add);
ROS_INFO("Ready to add ints.");
ros::spin();

return 0;
}

2)add_ints_client.cpp

实现一个客户端

  • 初始化ROS节点;
  • 穿件一个Client实例;
  • 发布服务请求数据;
  • 等待Server处理之后的应答结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "ros/ros.h"
#include "add_ints/AddInts.h"
#include <cstdlib>
#include <ctime>

int main(int argc, char **argv)
{
// 初始化ros节点,第三个参数是节点名称
ros::init(argc, argv, "add_ints_client");
// 节点句柄
ros::NodeHandle n;
// 声明一个频率 0.2Hz(5S)
ros::Rate loop_rate(0.2);

ros::ServiceClient client = n.serviceClient<add_ints::AddInts>("add_ints");
add_ints::AddInts srv;

srand(int(time(0)));
srv.request.a = rand();
srv.request.b = 0;

while(ros::ok())
{
if (client.call(srv))
{
if(srv.request.b == 12)
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
srv.request.c[srv.request.b] = srv.request.a;
srv.request.a = rand();
srv.request.b++;
}
else
{
ROS_ERROR("Failed to call service add_ints");
return 1;
}

if(srv.request.b == 13)
srv.request.b = 0;
else // 按照频率休眠(5s)
loop_rate.sleep();

}
return 0;
}

2,修改程序包的 CMakeLists.txt

添加可执行程序和可执行程序的链接库:

1
2
3
4
5
6
add_executable(add_ints_server src/add_ints_server.cpp)
target_link_libraries(add_ints_server ${catkin_LIBRARIES})
add_dependencies(add_ints_server add_ints_gencpp)
add_executable(add_ints_client src/add_ints_client.cpp)
target_link_libraries(add_ints_client ${catkin_LIBRARIES})
add_dependencies(add_ints_client add_ints_gencpp)

3,编译运行

1
2
cd ~/catkin_ws 
catkin_make

编译完成后即可运行:

  • 先启动master节点:

    1
    rosrun master
  • 启动service节点:

    1
    rosrun add_ints add_ints_server
  • 启动客client节点:

    1
    rosrun add_ints add_ints_client

ROS基本编程--Service
https://kevinloongc.github.io/posts/32520.html
作者
Kevin Loongc
发布于
2019年4月23日
许可协议