当前位置:   article > 正文

ROS学习(五)客户端与服务端通信_client.call

client.call

目录

 服务模型

一、实现客户端

1.创建服务功能包

2.创建turtle_spawn.cpp

3.配置CMakeLists.txt

4.编译

5.运行

二、实现服务端

1.创建turtle_command_server.cpp

2.配置CMakeLists.txt

3.编译

4.运行

 三、自定义服务

1.创建srv文件

2.在 package.xml中添加功能依赖包

3.在CMakeLists.txt添加编译选项

4.编译

5.应用此自定义服务


服务模型

实现过程
客户端(Client)产生请求的节点,发布请求,服务端(Server)做出操作并给客户端回馈


ros服务端与客户端通信icon-default.png?t=M666https://download.csdn.net/download/m0_56451176/86398723?spm=1001.2014.3001.5503 

一、实现客户端

实现目的:通过客户端请求海龟仿真器产生第二子海龟

1.创建服务功能包

  1. cd ~/catkin_ws/src
  2. catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

2.创建turtle_spawn.cpp

  1. cd learning_service/src
  2. touch turtle_spawn.cpp
  3. gedit turtle_spawn.cpp

turtle_spawn.cpp内容如下:

  1. //该例程将请求/spawn服务,服务数据类型turtlesim::Spawn
  2. #include <ros/ros.h>
  3. #include <turtlesim/Spawn.h>
  4. int main(int argc, char** argv)
  5. {
  6. // 初始化ROS节点
  7. ros::init(argc, argv, "turtle_spawn");
  8. // 创建节点句柄
  9. ros::NodeHandle node;
  10. // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
  11. ros::service::waitForService("/spawn"); //若找不到服务则一直等待
  12. ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
  13. // 初始化turtlesim::Spawn的请求数据
  14. turtlesim::Spawn srv;
  15. srv.request.x = 2.0;
  16. srv.request.y = 2.0;
  17. srv.request.name = "turtle2";
  18. // 请求服务调用
  19. ROS_INFO("Call service to spwan turtle[x:%0.6f, y:%0.6f, name:%s]", srv.request.x, srv.request.y, srv.request.name.c_str());
  20. add_turtle.call(srv); //发出请求,等待反馈
  21. // 显示服务调用结果
  22. ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());
  23. return 0;
  24. };

3.配置CMakeLists.txt

在build区域中添加:

  1. add_executable(turtle_spawn src/turtle_spawn.cpp)
  2. target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

4.编译

  1. cd ~/catkin_ws
  2. catkin_make

5.运行

启动ROS核心 

roscore

启动海龟仿真器 

rosrun turtlesim turtlesim_node

运行客户端 

  1. source ~/catkin_ws/devel/setup.bash
  2. rosrun learning_service turtle_spawn

效果为产生第二只海龟


二、实现服务端

实现目的:控制海龟运动

1.创建turtle_command_server.cpp

  1. cd ~/catkin_ws/src/learning_service/src
  2. touch turtle_command_server.cpp
  3. gedit turtle_command_server.cpp

turtle_command_server.cpp内容如下:

  1. //该例程将执行/turtle_command服务,服务数据类型std_srvs/Trigger
  2. #include <ros/ros.h>
  3. #include <geometry_msgs/Twist.h>
  4. #include <std_srvs/Trigger.h>
  5. ros::Publisher turtle_vel_pub;
  6. bool pubCommand = false; //是否在运动的标志,作为开关
  7. // service回调函数,输入参数req,输出参数res
  8. bool commandCallback(std_srvs::Trigger::Request &req,std_srvs::Trigger::Response &res)
  9. {
  10. pubCommand = !pubCommand;
  11. // 显示请求数据
  12. ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");
  13. // 设置反馈数据
  14. res.success = true; //在服务中显示输出
  15. res.message = "Change turtle command state!";
  16. return true;
  17. }
  18. int main(int argc, char **argv)
  19. {
  20. // ROS节点初始化
  21. ros::init(argc, argv, "turtle_command_server");
  22. // 创建节点句柄
  23. ros::NodeHandle n;
  24. // 创建一个名为/turtle_command的server,注册回调函数commandCallback
  25. ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);
  26. // 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
  27. turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
  28. // 循环等待回调函数
  29. ROS_INFO("Ready to receive turtle command.");
  30. // 设置循环的频率
  31. ros::Rate loop_rate(10);
  32. while(ros::ok())
  33. {
  34. // 查看一次回调函数队列
  35. ros::spinOnce();
  36. // 如果标志为true,则发布速度指令
  37. if(pubCommand)
  38. {
  39. geometry_msgs::Twist vel_msg;
  40. vel_msg.linear.x = 0.5;
  41. vel_msg.angular.z = 0.2;
  42. turtle_vel_pub.publish(vel_msg);
  43. }
  44. //按照循环频率延时
  45. loop_rate.sleep();
  46. }
  47. return 0;
  48. }

2.配置CMakeLists.txt

在build区域中添加:

  1. add_executable(turtle_command_server src/turtle_command_server.cpp)
  2. target_link_libraries(turtle_command_server ${catkin_LIBRARIES})

3.编译

  1. cd ~/catkin_ws
  2. catkin_make

4.运行

启动ROS核心 

roscore

启动海龟仿真器 

rosrun turtlesim turtlesim_node

运行服务端 

  1. source ~/catkin_ws/devel/setup.bash
  2. rosrun learning_service turtle_command_server

运行turtle_command服务

rosservice call /turtle_command "{}"	


 三、自定义服务

1.创建srv文件

  1. cd ~/catkin_ws/src/learning_service
  2. mkdir srv
  3. cd srv
  4. touch Person.srv
  5. gedit Person.srv

Person.srv内容如下

  1. string name
  2. uint8 age
  3. uint8 sex
  4. uint8 unknown = 0
  5. uint8 male = 1
  6. uint8 female = 2
  7. ---
  8. string result

注:三根横线上为request数据,下方为response 

2.在 package.xml中添加功能依赖包

在服务功能包的package.xml中添加功能包的编译依赖和运行依赖

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

3.在CMakeLists.txt添加编译选项

  1. find_package(...message_generation)
  2. #依赖,在messages,services栏中加
  3. add_service_files(FILES Person.srv)
  4. generate_messages(DEPENDENCIES std_msgs)
  5. #依赖若被注释要取消
  6. catkin_package(...message_runtime)

  

 

4.编译

  1. cd ~/catkin_ws
  2. catkin_make

此时在devel/include/功能包目录下会生成srv文件定义的整体头文件,三横线前在request头文件,三横线下在response头文件,其信息即为在srv中定义的内容,应用时引入Person.h即可

5.应用此自定义服务

1.在话题功能包的src目录下创建person_client.cpp

  1. cd ~/catkin_ws/src/learning_service/src
  2. touch person_client.cpp
  3. gedit person_client.cpp

 person_client.cpp内容如下

  1. //该例程将请求/show_person服务,服务数据类型learning_service::Person
  2. #include <ros/ros.h>
  3. #include "learning_service/Person.h"
  4. int main(int argc, char** argv){
  5. // 初始化ROS节点
  6. ros::init(argc, argv, "person_client");
  7. // 创建节点句柄
  8. ros::NodeHandle node;
  9. // 发现/spawn服务后,创建一个服务客户端,连接名为/show_person的service
  10. ros::service::waitForService("/show_person");
  11. ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
  12. // 初始化learning_service::Person的请求数据
  13. learning_service::Person srv; //定义Person的对象
  14. srv.request.name = "Tom";
  15. srv.request.age = 20;
  16. srv.request.sex = learning_service::Person::Request::male;
  17. // 请求服务调用
  18. ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", srv.request.name.c_str(), srv.request.age, srv.request.sex);
  19. person_client.call(srv);
  20. // 显示服务调用结果
  21. ROS_INFO("Show person result : %s", srv.response.result.c_str());
  22. return 0;
  23. }

2.创建person_server.cpp

在服务功能包的src目录下创建person_server.cpp

  1. cd ~/catkin_ws/src/learning_service/src
  2. touch person_server.cpp
  3. gedit person_server.cpp

person_server.cpp内容如下

  1. //该例程将执行/show_person服务,服务数据类型learning_service::Person
  2. #include <ros/ros.h>
  3. #include "learning_service/Person.h"
  4. // service回调函数,输入参数req,输出参数res
  5. bool personCallback(learning_service::Person::Request &req,learning_service::Person::Response &res){
  6. // 显示请求数据
  7. ROS_INFO("Person: name:%s age:%d sex:%d", req.name.c_str(), req.age, req.sex);
  8. // 设置反馈数据
  9. res.result = "OK";
  10. return true;
  11. }
  12. int main(int argc, char **argv){
  13. // ROS节点初始化
  14. ros::init(argc, argv, "person_server");
  15. // 创建节点句柄
  16. ros::NodeHandle n;
  17. // 创建一个名为/show_person的server,注册回调函数personCallback
  18. ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
  19. // 循环等待回调函数
  20. ROS_INFO("Ready to show person informtion.");
  21. ros::spin();
  22. return 0;
  23. }

3.配置功能包的CMakeLists.txt中的编译规则,build栏中

  1. add_executable(person_server src/person_server.cpp)
  2. target_link_libraries(person_server ${catkin_LIBRARIES})
  3. add_dependencies(person_server ${PROJECT_NAME}_gencpp)
  4. add_executable(person_client src/person_client.cpp)
  5. target_link_libraries(person_client ${catkin_LIBRARIES})
  6. add_dependencies(person_client ${PROJECT_NAME}_gencpp)

 4.编译

  1. cd ~/catkin_ws
  2. catkin_make

5.运行

roscore
  1. source ~/catkin_ws/devel/setup.bash
  2. rosrun learning_service person_server
  1. source ~/catkin_ws/devel/setup.bash
  2. rosrun learning_service person_client

 注:spinOnce()执行后还会执行之后的程序,而spin()不会

先打开服务端,再开客户端,服务端可直接反馈
若服务端未开,则在waitForService函数等待服务端,当服务端可用即可请求并反馈

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/797830
推荐阅读
相关标签
  

闽ICP备14008679号