在ROS通讯中,除了话题通讯,还有一种就是服务通讯。服务包括客户端和服务端,客户端就是请求服务,服务端就是提供服务的。本节就以客户端为主要内容,说c++和python如何实现客户端。
1)、切换至~/catkin_ws/src目录下,
catkin_create_pkg learning_server std_msgs rospy roscpp geometry_msgs turtlesim
2)、切换至~/catkin_ws目录下,
xxxxxxxxxx
catkin_make
1)、初始化ROS节点
2)、创建句柄
3)、创建一个Client实例
4)、初始化并发布服务请求数据
5)、等待Server处理之后的应答结果
a_new_turtle.cpp
x/**
* 该例程将请求小海龟节点里的/spawn服务,会在规定的位置出现一只新的小海龟
*/
int main(int argc, char** argv)
{
ros::init(argc, argv, "a_nes_turtle");// 初始化ROS节点
ros::NodeHandle node;
ros::service::waitForService("/spawn"); // 等待/spawn服务
ros::ServiceClient new_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");//创建一个服务客户端,连接名为/spawn的服务
// 初始化turtlesim::Spawn的请求数据
turtlesim::Spawn new_turtle_srv;
new_turtle_srv.request.x = 6.0;
new_turtle_srv.request.y = 8.0;
new_turtle_srv.request.name = "turtle2";
// 请求服务传入xy位置参数以及名字参数
ROS_INFO("Call service to create a new turtle name is %s,at the x:%.1f,y:%.1f", new_turtle_srv.request.name.c_str(),
new_turtle_srv.request.x,
new_turtle_srv.request.y);
new_turtle.call(new_turtle_srv);
ROS_INFO("Spwan turtle successfully [name:%s]", new_turtle_srv.response.name.c_str());// 显示服务调用结果
return 0;
};
1)、程序流程图
2)、在CMakelist.txt中配置,build区域下,添加如下内容
xxxxxxxxxx
add_executable(a_new_turtle src/a_new_turtle.cpp)
target_link_libraries(a_new_turtle ${catkin_LIBRARIES})
3)、工作空间目录下编译代码
xxxxxxxxxx
cd ~/catkin_ws
catkin_make
source devel/setup.bash #需要配置环境变量,否则系统无法找到运行程序
4)、运行程序
xxxxxxxxxx
roscore
rosrun turtlesim turtlesim_node
rosrun learning_server a_new_turtle
5)、运行效果截图
6)、程序说明
在启动小海龟的节点后,再运行a_new_turtle这个程序会发现,画面中会出现另外一直小海龟,这是因为小海龟的节点提供了服务/spawn,该服务会产生另外一直小海龟turtle2,查看小海龟提供的服务可以通过rosservice list命令来查看,如下图所示
可以通过rosservice info /spawn,查看这个服务需要的参数,如下图所示
可以看出需要有4个参数:x,y,theta,name,这四个参数在a_new_turtle.cpp里边有初始化
xxxxxxxxxx
srv.request.x = 6.0;
srv.request.y = 8.0;
srv.request.name = "turtle2";
注意:theta没有赋值,默认为0
a_new_turtle.py
xxxxxxxxxx
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import rospy
from turtlesim.srv import Spawn
def turtle_spawn():
rospy.init_node('new_turtle')# ROS节点初始化
rospy.wait_for_service('/spawn')# 等待/spawn服务
try:
new_turtle = rospy.ServiceProxy('/spawn', Spawn)
response = new_turtle(2.0, 2.0, 0.0, "turtle2")# 输入请求数据
return response.name
except rospy.ServiceException, e:
print "failed to call service : %s"%e
if __name__ == "__main__":
#服务调用并显示调用结果
print "a new turtle named %s." %(turtle_spawn())
1)、程序流程图
2)、运行程序
xxxxxxxxxx
roscore
rosrun turtlesim turtlesim_node
rosrun learning_server a_new_turtle.py
3)、程序运行效果和程序说明与C++实现的效果一致,这里主要说下python如何提供服务需要的参数,
xxxxxxxxxx
response = add_turtle(2.0, 2.0, 0.0, "turtle2")
对应的参数,分别是x,y,theta,name。