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

 

转载于:https://www.cnblogs.com/winslam/p/10118472.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值