Skip to main content

07.客户端

7、客户端

在ROS通讯中,除了话题通讯,还有一种就是服务通讯。服务包括客户端和服务端,客户端就是请求服务,服务端就是提供服务的。本节就以客户端为主要内容,说c++和python如何实现客户端。

7.1、准备工作

7.1.1、建立功能包

1)、切换至~/catkin_ws/src目录下,

xxxxxxxxxx catkin_create_pkg learning_server std_msgs rospy roscpp geometry_msgs turtlesim

2)、切换至~/catkin_ws目录下,

xxxxxxxxxx catkin_make

7.2、C++语言实现

7.2.1、实现步骤

1)、初始化ROS节点

2)、创建句柄

3)、创建一个Client实例

4)、初始化并发布服务请求数据

5)、等待Server处理之后的应答结果

7.2.2、切换至~/catkin_ws/src/learning_server/src目录下,新建一个.cpp文件,命名为a_new_turtle,把下边代码粘贴在里边

a_new_turtle.cpp

xxxxxxxxxx /** * 该例程将请求小海龟节点里的/spawn服务,会在规定的位置出现一只新的小海龟 */ ​ #include <ros/ros.h> #include <turtlesim/Spawn.h> ​ 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)、程序流程图

image-20220225112117967

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)、运行效果截图

image-20220225112424249

6)、程序说明

在启动小海龟的节点后,再运行a_new_turtle这个程序会发现,画面中会出现另外一直小海龟,这是因为小海龟的节点提供了服务/spawn,该服务会产生另外一直小海龟turtle2,查看小海龟提供的服务可以通过rosservice list命令来查看,如下图所示

image-20220218180756612

可以通过rosservice info /spawn,查看这个服务需要的参数,如下图所示

image-20220218181244822

可以看出需要有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

7.3、python语言实现

7.3.1、切换至~/catkin_ws/src/learning_server目录下,新建一个script文件夹,切进去,新建一个py文件,命名为a_new_turtle,把下边代码粘贴在里边

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)、程序流程图

image-20220225113010789

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。