• ROS回顾与整理《二、多种通信机制编程》


    2、话题编程:

    在/home/catkin_ws/src/learning_comnunication/src 编写源码文件;
    其中talker.cpp 与 listener.cpp 是发布者与订阅者实现,源代码分别如下:

     1 /**
     2  * 该例程将发布chatter话题,消息类型String
     3  */
     4  
     5 #include <sstream>
     6 #include "ros/ros.h"
     7 #include "std_msgs/String.h"
     8 
     9 int main(int argc, char **argv)
    10 {
    11   // ROS节点初始化
    12   ros::init(argc, argv, "talker");
    13   
    14   // 创建节点句柄
    15   ros::NodeHandle n;
    16   
    17   // 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
    18   ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
    19 
    20   // 设置循环的频率
    21   ros::Rate loop_rate(10);
    22 
    23   int count = 0;
    24   while (ros::ok())
    25   {
    26     // 初始化std_msgs::String类型的消息
    27     std_msgs::String msg;
    28     std::stringstream ss;
    29     ss << "hello world " << count;
    30     msg.data = ss.str();
    31 
    32     // 发布消息
    33     ROS_INFO("%s", msg.data.c_str());
    34     chatter_pub.publish(msg);
    35 
    36     // 循环等待回调函数
    37     ros::spinOnce();
    38     
    39     // 按照循环频率延时
    40     loop_rate.sleep();
    41     ++count;
    42   }
    43 
    44   return 0;
    45 }
    /**
     * 该例程将订阅chatter话题,消息类型String
     */
     
    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    // 接收到订阅的消息后,会进入消息回调函数
    void chatterCallback(const std_msgs::String::ConstPtr& msg)
    {
      // 将接收到的消息打印出来
      ROS_INFO("I heard: [%s]", msg->data.c_str());
    }
    
    int main(int argc, char **argv)
    {
      // 初始化ROS节点
      ros::init(argc, argv, "listener");
    
      // 创建节点句柄
      ros::NodeHandle n;
    
      // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
      ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
    
      // 循环等待回调函数
      ros::spin();
    
      return 0;
    }

    在/home/catkin_ws/src/learning_comnunication 中的CMakeLists.txt 中添加如下:

    add_executable(talker src/talker.cpp)

    target_link_libraries(talker ${catkin_LIBRARIES})

    add_executable(listener src/listener.cpp)
    target_link_libraries(listener ${catkin_LIBRARIES})

    在/home/catkin_ws下编译、运行
    catkin_make

    在新终端执行
    root@sry:~# rosrun learning_communication talker
    报错:
    [rosrun] Couldn't find executable named talker below /root/catkin_ws/src/learning_communication

    经过痛苦查找,发现我的功能包名字叫: learning_comnunication
    上述的rosrun learning_communication talker 会查找根目录下那个相关文件夹;所以控制台报错
    说在XXXXX路径下找不到可执行文件 talker

    【将错就错】
    rosrun learning_comnunication talker
    rosrun learning_comnunication listener

    我们在三个终端中分别执行以下三条指令

    roscore 
    rosrun learning_communication talker
    rosrun learning_communication  listener

    消息定义如下:

    ##########3话题消息定义#############
    在 /home/catkin_ws/src/learning_communication
    mkdir msg
    ##创建消息文件Person.msg

    文件中添加以下内容:

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

    #在 /home/catkin_ws/src/learning_communication/package.xml添加依赖【注意添加位置,否则无效】
    <build_depend>message_generation</build_depend>
    <exec_depend>message_runtime</exec_depend>

    #在 /home/catkin_ws/src/learning_communication/CMakeLists.txt 中添加编译选项
    find_package( …… message_generation)

    catkin_package(CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime)

    add_message_files(FILES Person.msg)
    generate_messages(DEPENDENCIES std_msgs)


    ## 查看消息是否定义成功
    rosmsg show Person

    类似创建msg文件,

    mkdir srv
    gedit AddTwoInts.srv 文件中内容

    1 ## 请求数据 ,发送给服务端
    2 int64 a
    3 int64 b
    4 ---
    5 ## 应答数据,发送求和结果给客户端
    6 int64 sum

    #在 /home/catkin_ws/src/learning_communication/CMakeLists.txt 中添加编译选项
    find_package( …… message_generation)

    catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs message_runtime)

    ## 请你务必实现阅读package.xml文件的架构

    add_service_files(FILES AddTwoInts.srv)
    generate_messages(DEPENDENCIES std_msgs)

    然后编写client文件和service文件,修改CMakeList.txt

    add_executable(server src/server.cpp)
    target_link_libraries(server ${catkin_LIBRARIES})
    add_dependencies(server ${PROJECT_NAME}_gencpp)

    add_executable(client src/client.cpp)
    target_link_libraries(client ${catkin_LIBRARIES})
    add_dependencies(client ${PROJECT_NAME}_gencpp)

     package.xml修改后文件如下:

     1 <?xml version="1.0"?>
     2 <package format="2">
     3   <name>learning_communication</name>
     4   <version>0.0.0</version>
     5   <description>The learning_communication package</description>
     6 
     7   <!-- One maintainer tag required, multiple allowed, one person per tag -->
     8   <!-- Example:  -->
     9   <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
    10   <maintainer email="root@todo.todo">root</maintainer>
    11 
    12 
    13   <!-- One license tag required, multiple allowed, one license per tag -->
    14   <!-- Commonly used license strings: -->
    15   <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
    16   <license>TODO</license>
    17 
    18 
    19   <!-- Url tags are optional, but multiple are allowed, one per tag -->
    20   <!-- Optional attribute type can be: website, bugtracker, or repository -->
    21   <!-- Example: -->
    22   <!-- <url type="website">http://wiki.ros.org/learning_communication</url> -->
    23 
    24 
    25   <!-- Author tags are optional, multiple are allowed, one per tag -->
    26   <!-- Authors do not have to be maintainers, but could be -->
    27   <!-- Example: -->
    28   <!-- <author email="jane.doe@example.com">Jane Doe</author> -->
    29 
    30 
    31   <!-- The *depend tags are used to specify dependencies -->
    32   <!-- Dependencies can be catkin packages or system dependencies -->
    33   <!-- Examples: -->
    34   <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
    35   <!--   <depend>roscpp</depend> -->
    36   <!--   Note that this is equivalent to the following: -->
    37   <!--   <build_depend>roscpp</build_depend> -->
    38   <!--   <exec_depend>roscpp</exec_depend> -->
    39   <!-- Use build_depend for packages you need at compile time: -->
    40   <!--   <build_depend>message_generation</build_depend> -->
    41   <!-- Use build_export_depend for packages you need in order to build against this package: -->
    42   <!--   <build_export_depend>message_generation</build_export_depend> -->
    43   <!-- Use buildtool_depend for build tool packages: -->
    44   <!--   <buildtool_depend>catkin</buildtool_depend> -->
    45   <!-- Use exec_depend for packages you need at runtime: -->
    46   <!--   <exec_depend>message_runtime</exec_depend> -->
    47   <!-- Use test_depend for packages you need only for testing: -->
    48   <!--   <test_depend>gtest</test_depend> -->
    49   <!-- Use doc_depend for packages you need only for building documentation: -->
    50   <!--   <doc_depend>doxygen</doc_depend> -->
    51   <buildtool_depend>catkin</buildtool_depend>
    52   <build_depend>roscpp</build_depend>
    53   <build_depend>rospy</build_depend>
    54   <build_depend>std_msgs</build_depend>
    55   <build_export_depend>roscpp</build_export_depend>
    56   <build_export_depend>rospy</build_export_depend>
    57   <build_export_depend>std_msgs</build_export_depend>
    58   <exec_depend>roscpp</exec_depend>
    59   <exec_depend>rospy</exec_depend>
    60   <exec_depend>std_msgs</exec_depend>
    61 
    62   <build_depend>message_generation</build_depend>
    63   <exec_depend>message_runtime</exec_depend>
    64 
    65   <!-- The export tag contains other, unspecified, tags -->
    66   <export>
    67     <!-- Other tools can request additional information be placed here -->
    68 
    69 
    70   </export>
    71 </package>

    CMakeList.txt

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

    其中service的源代码如下:

     1 /**
     2  * AddTwoInts Server
     3  */
     4  
     5 #include "ros/ros.h"
     6 #include "learning_communication/AddTwoInts.h"
     7 
     8 // service回调函数,输入参数req,输出参数res
     9 bool add(learning_communication::AddTwoInts::Request  &req,
    10          learning_communication::AddTwoInts::Response &res)
    11 {
    12   // 将输入参数中的请求数据相加,结果放到应答变量中
    13   res.sum = req.a + req.b;
    14   ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
    15   ROS_INFO("sending back response: [%ld]", (long int)res.sum);
    16   
    17   return true;
    18 }
    19 
    20 int main(int argc, char **argv)
    21 {
    22   // ROS节点初始化
    23   ros::init(argc, argv, "add_two_ints_server");
    24   
    25   // 创建节点句柄
    26   ros::NodeHandle n;
    27 
    28   // 创建一个名为add_two_ints的server,注册回调函数add()
    29   ros::ServiceServer service = n.advertiseService("add_two_ints", add);
    30   
    31   // 循环等待回调函数
    32   ROS_INFO("Ready to add two ints.");
    33   ros::spin();
    34 
    35   return 0;
    36 }

    client代码:

     1 /**
     2  * AddTwoInts Client
     3  */
     4  
     5 #include <cstdlib>
     6 #include "ros/ros.h"
     7 #include "learning_communication/AddTwoInts.h"
     8 
     9 int main(int argc, char **argv)
    10 {
    11   // ROS节点初始化
    12   ros::init(argc, argv, "add_two_ints_client");
    13   
    14   // 从终端命令行获取两个加数
    15   if (argc != 3)
    16   {
    17     ROS_INFO("usage: add_two_ints_client X Y");
    18     return 1;
    19   }
    20 
    21   // 创建节点句柄
    22   ros::NodeHandle n;
    23   
    24   // 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoInts
    25   ros::ServiceClient client = n.serviceClient<learning_communication::AddTwoInts>("add_two_ints");
    26   
    27   // 创建learning_communication::AddTwoInts类型的service消息
    28   learning_communication::AddTwoInts srv;
    29   srv.request.a = atoll(argv[1]);
    30   srv.request.b = atoll(argv[2]);
    31   
    32   // 发布service请求,等待加法运算的应答结果
    33   if (client.call(srv))
    34   {
    35     ROS_INFO("Sum: %ld", (long int)srv.response.sum);
    36   }
    37   else
    38   {
    39     ROS_ERROR("Failed to call service add_two_ints");
    40     return 1;
    41   }
    42 
    43   return 0;
    44 }

    功能简述:客户端向服务器发送请求,服务器完成请求并响应反馈给客户端。

    在三个终端分别执行以下命令:

    roscore
    rosrun learning_communication  client 3 4
    rosrun learning_communication  server
    

     

  • 相关阅读:
    Thinkphp中如何书写按照指定字段同步更新的ORM
    一道money计算题引发的思考
    娱乐一下:汤姆君的大转盘算法(搞笑版)
    php导出数组到csv格式demo
    通过xshell/securecrt连接linux上传/下载文件
    windows设置代理.bat 脚本
    【面试题】输入并保存文件,完成后退出显示文件内容
    【设计模式学习笔记】 之 状态模式
    【学习笔记】FreeMarker 之于Servlet与Stuts2的应用
    【学习笔记】初识FreeMarker简单使用
  • 原文地址:https://www.cnblogs.com/winslam/p/10118472.html
Copyright © 2020-2023  润新知