• ROS 消息订阅 服务器客户端客户端 通信方式


    理解服务

    服务service和消息msg的区别在于:

    1.  每一个消息都和一个话题相关,发布者对消息是发送后不管

    2.  消息可以一对多,也可以多对多

     3. 消息是单向的,没有响应的概念

    4.  每一个service服务由一个节点发起,服务的响应也返回同一个节点

     5. service服务是一对一通信

     6. service服务是双向的,并且响应是同步的

     7. service 由请求和响应构成

    查看服务

     查看服务的信息 $rosservice info [服务名]

     查看活动服务列表

    $rosservice list                                  小海龟示例。

    服务的组织:

    服务由请求、响应两部分构成,请求和响应之间通过“---”隔开,

    通常以srv为后缀放置在srv目录下。

    一个服务文件的示例如下:

    1. int64 a
    2. int64 b
    3. ---
    4. int64 sum

    服务的每行声明和消息类型一样由两部分:

    域、变量构成,域由独立域、复合域构成,支持的基本数据类型和消息相同。

    服务的实现

    在实现上,服务在底层由一个GlobalCallbackQueue和ServiceManager管理,

    服务的请求req、响应resp本质上也是序列化的消息。

       

    在底层,客户端和服务器通过

    ServiceClientLink的boost::signals2::connection的信号、槽连接机制实现回调。

    自定义服务步骤:

     步骤1:创建自定义服务.srv

    1. int64 a
    2. int64 b
    3. ---
    4. int64 sum

     步骤2:编写服务文件service

    1. #include "ros/ros.h"
    2. #include "example_4/Sum.h"
    3. bool add(example_4::Sum::Request &req,
    4. example_4::Sum::Response &res)
    5. {
    6. res.sum = req.a + req.b; // a+b 完成响应
    7. ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
    8. ROS_INFO("sending back response: [%ld]", (long int)res.sum);
    9. return true;
    10. }
    11. int main(int argc, char **argv)
    12. {
    13. ros::init(argc, argv, "service");
    14. ros::NodeHandle nh;
    15. ros::ServiceServer service = nh.advertiseService("add_two_ints", add); // 名字 + 回调名字
    16. ROS_INFO("Ready to add two ints.");
    17. ros::spin();
    18. return 0;
    19. }

     步骤3:编写客户端文件 client

    1. #include "ros/ros.h"
    2. #include "example_4/Sum.h"
    3. #include
    4. int main(int argc, char **argv)
    5. {
    6. int a = 0,b = 0;
    7. ros::init(argc, argv, "client"); // 表明是客户端
    8. /*
    9. if (argc != 3)
    10. {
    11. ROS_INFO("usage: add_two_ints_client X Y");
    12. return 1;
    13. }
    14. */
    15. ros::NodeHandle nh;
    16. ros::ServiceClient client = nh.serviceClient("add_two_ints");
    17. example_4::Sum srv;
    18. if(nh.getParam("/client/client_x",a)){
    19. srv.request.a = a;
    20. }
    21. if(nh.getParam("/client/client_y",b)){
    22. srv.request.b = b;
    23. }
    24. //srv.request.a = atoll(argv[1]);
    25. //srv.request.b = atoll(argv[2]);
    26. if (client.call(srv)) // 调用 call 就可以发起请求
    27. {
    28. ROS_INFO("Sum: %ld", (long int)srv.response.sum);
    29. }
    30. else
    31. {
    32. ROS_ERROR("Failed to call service add_two_ints");
    33. return 1;
    34. }
    35. return 0;
    36. }

     步骤4:创建启动launch文件

    1. "service" pkg="example_4" type="service" respawn="true"/>
    2. "client" pkg="example_4" type="client" output="screen">
    3. "client_x" type="int" value="1" />
    4. "client_y" type="int" value="5" />
    5. #两个节点一个1
    6. #两个节点一个5

     步骤5:package.xml、CMakeLists.txt配置

    1. cmake_minimum_required(VERSION 3.0.2)
    2. project(example_4)
    3. ## Compile as C++11, supported in ROS Kinetic and newer
    4. # add_compile_options(-std=c++11)
    5. ## Find catkin macros and libraries
    6. ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    7. ## is used, also find other catkin packages
    8. find_package(catkin REQUIRED COMPONENTS
    9. roscpp
    10. rospy
    11. std_msgs
    12. message_generation
    13. )
    14. ## System dependencies are found with CMake's conventions
    15. # find_package(Boost REQUIRED COMPONENTS system)
    16. ## Uncomment this if the package has a setup.py. This macro ensures
    17. ## modules and global scripts declared therein get installed
    18. ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
    19. # catkin_python_setup()
    20. ################################################
    21. ## Declare ROS messages, services and actions ##
    22. ################################################
    23. ## To declare and build messages, services or actions from within this
    24. ## package, follow these steps:
    25. ## * Let MSG_DEP_SET be the set of packages whose message types you use in
    26. ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
    27. ## * In the file package.xml:
    28. ## * add a build_depend tag for "message_generation"
    29. ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
    30. ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
    31. ## but can be declared for certainty nonetheless:
    32. ## * add a exec_depend tag for "message_runtime"
    33. ## * In this file (CMakeLists.txt):
    34. ## * add "message_generation" and every package in MSG_DEP_SET to
    35. ## find_package(catkin REQUIRED COMPONENTS ...)
    36. ## * add "message_runtime" and every package in MSG_DEP_SET to
    37. ## catkin_package(CATKIN_DEPENDS ...)
    38. ## * uncomment the add_*_files sections below as needed
    39. ## and list every .msg/.srv/.action file to be processed
    40. ## * uncomment the generate_messages entry below
    41. ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
    42. ## Generate messages in the 'msg' folder
    43. # add_message_files(
    44. # FILES
    45. # Message1.msg
    46. # Message2.msg
    47. # )
    48. ## Generate services in the 'srv' folder
    49. add_service_files(
    50. FILES
    51. Sum.srv
    52. )
    53. ## Generate actions in the 'action' folder
    54. # add_action_files(
    55. # FILES
    56. # Action1.action
    57. # Action2.action
    58. # )
    59. ## Generate added messages and services with any dependencies listed here
    60. generate_messages(
    61. DEPENDENCIES
    62. std_msgs
    63. )
    64. ################################################
    65. ## Declare ROS dynamic reconfigure parameters ##
    66. ################################################
    67. ## To declare and build dynamic reconfigure parameters within this
    68. ## package, follow these steps:
    69. ## * In the file package.xml:
    70. ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
    71. ## * In this file (CMakeLists.txt):
    72. ## * add "dynamic_reconfigure" to
    73. ## find_package(catkin REQUIRED COMPONENTS ...)
    74. ## * uncomment the "generate_dynamic_reconfigure_options" section below
    75. ## and list every .cfg file to be processed
    76. ## Generate dynamic reconfigure parameters in the 'cfg' folder
    77. # generate_dynamic_reconfigure_options(
    78. # cfg/DynReconf1.cfg
    79. # cfg/DynReconf2.cfg
    80. # )
    81. ###################################
    82. ## catkin specific configuration ##
    83. ###################################
    84. ## The catkin_package macro generates cmake config files for your package
    85. ## Declare things to be passed to dependent projects
    86. ## INCLUDE_DIRS: uncomment this if your package contains header files
    87. ## LIBRARIES: libraries you create in this project that dependent projects also need
    88. ## CATKIN_DEPENDS: catkin_packages dependent projects also need
    89. ## DEPENDS: system dependencies of this project that dependent projects also need
    90. catkin_package(
    91. # INCLUDE_DIRS include
    92. # LIBRARIES example_4
    93. # CATKIN_DEPENDS roscpp rospy std_msgs
    94. # DEPENDS system_lib
    95. )
    96. ###########
    97. ## Build ##
    98. ###########
    99. ## Specify additional locations of header files
    100. ## Your package locations should be listed before other locations
    101. include_directories(
    102. # include
    103. ${catkin_INCLUDE_DIRS}
    104. )
    105. ## Declare a C++ library
    106. # add_library(${PROJECT_NAME}
    107. # src/${PROJECT_NAME}/example_4.cpp
    108. # )
    109. ## Add cmake target dependencies of the library
    110. ## as an example, code may need to be generated before libraries
    111. ## either from message generation or dynamic reconfigure
    112. # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    113. ## Declare a C++ executable
    114. ## With catkin_make all packages are built within a single CMake context
    115. ## The recommended prefix ensures that target names across packages don't collide
    116. ## Rename C++ executable without prefix
    117. ## The above recommended prefix causes long target names, the following renames the
    118. ## target back to the shorter version for ease of user use
    119. ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
    120. # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
    121. ## Add cmake target dependencies of the executable
    122. ## same as for the library above
    123. # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    124. ## Specify libraries to link a library or executable target against
    125. if(CMAKE_BUILD_TYPE STREQUAL DEBUG)
    126. add_executable(service src/service.cpp)
    127. add_executable(client src/client.cpp)
    128. target_link_libraries(service
    129. ${catkin_LIBRARIES}
    130. )
    131. target_link_libraries(client
    132. ${catkin_LIBRARIES}
    133. )
    134. endif()
    135. #############
    136. ## Install ##
    137. #############
    138. # all install targets should use catkin DESTINATION variables
    139. # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
    140. ## Mark executable scripts (Python etc.) for installation
    141. ## in contrast to setup.py, you can choose the destination
    142. # catkin_install_python(PROGRAMS
    143. # scripts/my_python_script
    144. # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    145. # )
    146. ## Mark executables for installation
    147. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
    148. # install(TARGETS ${PROJECT_NAME}_node
    149. # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    150. # )
    151. ## Mark libraries for installation
    152. ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
    153. # install(TARGETS ${PROJECT_NAME}
    154. # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    155. # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    156. # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
    157. # )
    158. ## Mark cpp header files for installation
    159. # install(DIRECTORY include/${PROJECT_NAME}/
    160. # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
    161. # FILES_MATCHING PATTERN "*.h"
    162. # PATTERN ".svn" EXCLUDE
    163. # )
    164. ## Mark other files for installation (e.g. launch and bag files, etc.)
    165. # install(FILES
    166. # # myfile1
    167. # # myfile2
    168. # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
    169. # )
    170. #############
    171. ## Testing ##
    172. #############
    173. ## Add gtest based cpp test target and link libraries
    174. # catkin_add_gtest(${PROJECT_NAME}-test test/test_example_4.cpp)
    175. # if(TARGET ${PROJECT_NAME}-test)
    176. # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
    177. # endif()
    178. ## Add folders to be run by python nosetests
    179. # catkin_add_nosetests(test)

    package.xml

    1. "1.0"?>
    2. "2">
    3. example_4
    4. 0.0.0
    5. The example_4 package
    6. "miaozl@todo.todo">miaozl
    7. D
    8. O
    9. O
    10. T
    11. catkin
    12. roscpp
    13. rospy
    14. std_msgs
    15. message_generation
    16. roscpp
    17. rospy
    18. std_msgs
    19. roscpp
    20. rospy
    21. std_msgs
    22. message_runtime

     步骤6:生成服务文件  编译执行

  • 相关阅读:
    Stable Doodle:简单涂鸦一键变成艺术品
    6-10java8中关于接口的新特性
    Java面试八股文宝典:初识数据结构-数组的应用扩展之HashMap
    数据库学习之索引
    计算机网络——wireshark抓包
    秒杀系统(1)——秒杀功能设计理念
    用进程和线程完成TCP进行通信操作及广播和组播的通信
    MyBatis学习笔记(一)
    python实现的一些方法,可以直接拿来用的那种
    网络信号最好的坐标 (暴力leetcode1620)-------------------c++实现
  • 原文地址:https://blog.csdn.net/weixin_44025389/article/details/126470105