https://wiki.ros.org/cn/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
bash展开代码root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws# roscd beginner_tutorials
roscd: No such package/stack 'beginner_tutorials'
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws# . devel/setup.bash
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws# roscd beginner_tutorials
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials#
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials/src# wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp
这个程序的主要功能是:
bash展开代码wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/listener/listener.cpp
这个程序的主要功能是:
chatterCallback
函数处理与之前的"talker"程序配合使用时:
这种发布-订阅模式是ROS中最基本也是最重要的通信机制之一,广泛应用于机器人系统中不同模块间的数据交换。在实际应用中,消息类型通常会替换为更复杂的自定义消息类型,以传输各种传感器数据、控制指令等。
这句话是 C++ 的“类实例化”语法,也叫“构造对象”语法。 等价于: ros::Rate loop_rate = ros::Rate(10);
这句话的作用是让 ROS 节点订阅名为 "chatter" 的话题,并在收到消息时调用 chatterCallback 回调函数。详细解释如下:
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
这句代码的意思是:“订阅 chatter 话题,每当有新消息到来时,就调用 chatterCallback 处理消息,并且最多缓存 1000 条未处理的消息。”
这几句加进去:
bash展开代码add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)
这几行代码是 ROS/Catkin 项目中的 CMake 构建指令,用于编译和链接 ROS 节点(可执行文件)。以下是逐行解析其核心功能:
add_executable(talker src/talker.cpp)
src/talker.cpp
编译成一个名为 talker
的可执行文件(ROS 节点)。talker.cpp
代码。talker
二进制文件(通常在 devel/lib/<package_name>/
目录下)。target_link_libraries(talker ${catkin_LIBRARIES})
talker
可执行文件链接到 ROS 的核心库(catkin_LIBRARIES
)。talker
能调用 ROS 的 API(如 ros::init()
, ros::Publisher
等)。${catkin_LIBRARIES}
是 Catkin 工具链提供的预定义变量,包含所有必要的 ROS 依赖库(如 roscpp
、std_msgs
等)。add_dependencies(talker beginner_tutorials_generate_messages_cpp)
talker
依赖于 beginner_tutorials_generate_messages_cpp
。talker
之前,先编译生成该包(beginner_tutorials
)的自定义消息(如果有)。.msg
文件),ROS 需要先将其转换为 C++ 代码(通过 message_generation
),然后才能被 talker
使用。add_executable(listener src/listener.cpp)
src/listener.cpp
编译成名为 listener
的可执行文件(ROS 节点)。listener.cpp
代码。listener
二进制文件。target_link_libraries(listener ${catkin_LIBRARIES})
listener
链接到 ROS 核心库(catkin_LIBRARIES
)。listener
能使用 ROS 的订阅功能(如 ros::Subscriber
、回调函数等)。add_dependencies(listener beginner_tutorials_generate_messages_cpp)
listener
依赖于 beginner_tutorials_generate_messages_cpp
。talker
类似,确保自定义消息(如果有)先被生成,再编译 listener
。指令 | 功能 |
---|---|
add_executable | 将源代码编译为可执行文件(ROS 节点) |
target_link_libraries | 链接 ROS 核心库,使节点能调用 ROS API |
add_dependencies | 确保自定义消息先于节点编译,避免未定义符号错误 |
catkin_LIBRARIES
:
roscpp
、std_msgs
等基础库。MyMessage.msg
),必须通过 add_dependencies
确保消息生成先完成,否则编译会失败。add_executable
≈ 告诉编译器:“把这份代码变成可执行程序”。target_link_libraries
≈ 告诉链接器:“这个程序需要 ROS 的库才能运行”。add_dependencies
≈ 告诉构建系统:“先搞定消息生成,再编译这个程序”。cmake错误,CMakeLists.txt改为这样:
bash展开代码cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
add_message_files(
FILES
Num.msg
)
add_service_files(
FILES
AddTwoInts.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime roscpp rospy std_msgs
)
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
CMakeLists.txt 里的 ROS 相关指令:
作用:查找并加载 catkin 以及你需要用到的 ROS 包(如 roscpp、rospy、std_msgs、message_generation 等),让后续的 CMake 指令能用到这些包的功能和头文件。
示例:
cmake展开代码find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation )
通俗理解:告诉 CMake,“我要用到这些包,请帮我找好它们。”
作用:声明本包要用到的自定义消息(.msg 文件),让 catkin 知道需要为这些消息生成代码。
示例:
cmake展开代码add_message_files( FILES Num.msg )
通俗理解:告诉 CMake,“我要用这些自定义消息,请帮我生成相关代码。”
作用:声明本包要用到的自定义服务(.srv 文件),让 catkin 知道需要为这些服务生成代码。
示例:
cmake展开代码add_service_files( FILES AddTwoInts.srv )
通俗理解:告诉 CMake,“我要用这些自定义服务,请帮我生成相关代码。”
作用:根据上面声明的消息和服务,自动生成 C++/Python 等语言的消息/服务代码。
DEPENDENCIES 里写上你消息/服务里用到的其他消息包(比如 std_msgs)。
示例:
cmake展开代码generate_messages( DEPENDENCIES std_msgs )
通俗理解:告诉 CMake,“现在请为我声明的消息和服务生成代码。”
作用:声明本包对外提供哪些功能、依赖哪些包。这样其他包在依赖你时能自动找到你的头文件、库、消息等。
示例:
cmake展开代码catkin_package( CATKIN_DEPENDS message_runtime roscpp rospy std_msgs )
通俗理解:告诉 CMake,“我的包对外提供哪些功能,依赖哪些包。”
作用:指定头文件搜索路径。一般要包含本包的 include 目录和 catkin 自动生成的头文件路径。
示例:
cmake展开代码include_directories( include ${catkin_INCLUDE_DIRS} )
通俗理解:告诉 CMake,“编译时请到这些目录找头文件。”
作用:
示例:
cmake展开代码add_executable(talker src/talker.cpp) target_link_libraries(talker ${catkin_LIBRARIES}) add_dependencies(talker ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
通俗理解:
在ws目录执行catkin_make
bash展开代码Scanning dependencies of target beginner_tutorials_generate_messages Scanning dependencies of target talker Scanning dependencies of target listener [ 76%] Built target beginner_tutorials_generate_messages [ 82%] Building CXX object beginner_tutorials/CMakeFiles/listener.dir/src/listener.cpp.o [ 88%] Building CXX object beginner_tutorials/CMakeFiles/talker.dir/src/talker.cpp.o [ 94%] Linking CXX executable /root/xiedong/learning-ros/catkin_ws/devel/lib/beginner_tutorials/talker [ 94%] Built target talker [100%] Linking CXX executable /root/xiedong/learning-ros/catkin_ws/devel/lib/beginner_tutorials/listener [100%] Built target listener
可见有可执行文件:
catkin_make 后,所有 add_executable 生成的目标(如 talker、listener)都在 devel/lib/包名/ 目录下。 你可以用 rosrun 包名 可执行文件名 或直接用绝对路径运行。
bash展开代码rosrun beginner_tutorials talker rosrun beginner_tutorials listener
~/xiedong/learning-ros/catkin_ws/devel/lib/beginner_tutorials/talker
,但 rosrun 会自动帮你查找路径和设置环境变量。~/xiedong/learning-ros/catkin_ws/devel/lib/beginner_tutorials/listener
。下面就可以执行节点了:
bash展开代码. devel/setup.bash
nohup roscore &
rosrun beginner_tutorials talker
rosrun beginner_tutorials listener
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!