R
O
S
1
{\rm ROS1}
ROS1的基础及应用,基于古月的课,各位可以去看,基于
h
a
w
k
b
o
t
{\rm hawkbot}
hawkbot机器人进行实际操作。
R
O
S
{\rm ROS}
ROS版本:
R
O
S
1
{\rm ROS1}
ROS1的
M
e
l
o
d
i
c
{\rm Melodic}
Melodic;实际机器人:
H
a
w
k
b
o
t
{\rm Hawkbot}
Hawkbot;
1.创建工作空间
-
工作空间
工作空间 ( w o r k s p a c e ) ({\rm workspace}) (workspace)是一个存放工程开发相关文件的文件夹。
- s r c {\rm src} src:代码空间 ( S o u r c e S p a c e ) ({\rm Source\ Space}) (Source Space);
- b u i l d {\rm build} build:编译空间 ( B u i l d S p a c e ) ({\rm Build\ Space}) (Build Space);
- d e v e l {\rm devel} devel:开发空间 ( D e v e l o p m e n t S p a c e ) ({\rm Development\ Space}) (Development Space);
- i n s t a l l {\rm install} install:安装空间 ( I n s t a l l S p a c e ) ({\rm Install\ Space}) (Install Space);
工作空间目录树结构示例:
tree -L 2 catkin_ws/ =============================================================================== catkin_ws/ ├── build │ ├── atomic_configure │ ├── catkin │ ├── catkin_generated │ ├── CATKIN_IGNORE │ ├── catkin_make.cache │ ├── CMakeCache.txt │ ├── CMakeFiles │ ├── cmake_install.cmake │ ├── CTestConfiguration.ini │ ├── CTestCustom.cmake │ ├── CTestTestfile.cmake │ ├── gtest │ ├── hawkbot │ ├── hawkbot_applications │ ├── line_follower_turtlebot │ ├── Makefile │ ├── orb_slam_2_ros │ └── test_results ├── devel │ ├── cmake.lock │ ├── env.sh │ ├── include │ ├── lib │ ├── local_setup.bash │ ├── local_setup.sh │ ├── local_setup.zsh │ ├── setup.bash │ ├── setup.sh │ ├── _setup_util.py │ ├── setup.zsh │ └── share └── src ├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake ├── hawkbot ├── hawkbot_applications └── orb_slam_2_ros ===============================================================================
-
创建工作空间
# 1.创建工作空间 mkdir -p ~/willard_ws/src cd ~/willard_ws/src catkin_init_workspace # 2.编译工作空间 cd ~/willard_ws/ catkin_make # 3.设置环境变量 source devel/setup.sh vim ~/.bashrc source ~/.bashrc # 4.检查环境变量 echo $ROS_PACKAGE_PATH # 由于原来存在一个工作空间,因此使用echo命令输出如下: # /home/hawkbot/willard_ws/src:/home/hawkbot/catkin_ws/src:/opt/ros/melodic/share
-
创建功能包
# 语法:catkin_create_pkg <pkg_name> [depend1] [depend2].. # 1.创建功能包 cd ~/willard_ws/src catkin_create_pkg learning_communication std_msgs rospy roscpp # 2.编译功能包 cd ~/willard_ws catkin_make source ~/willard_ws/devel/setup.bash # 注意:同一个工作空间下,不允许存在同名功能包,不同工作空间下,允许存在同名功能包;
-
工作空间覆盖机制
- 工作空间的路径依次在 R O S _ P A C K A G E _ P A T H {\rm ROS\_PACKAGE\_PATH} ROS_PACKAGE_PATH环境变量中记录;
- 新设置的路径在 R O S _ P A C K A G E _ P A T H {\rm ROS\_PACKAGE\_PATH} ROS_PACKAGE_PATH中自动放在最前端;
- 运行时, R O S {\rm ROS} ROS优先查找最前端的工作空间中是否存在指定的功能包;
- 如果不存在,就顺序向后查找其他工作空间;
# 查看关于ros的所有环境变量 env | grep ros # 实践中的结果 ROS_PACKAGE_PATH=/home/hawkbot/willard_ws/src:/home/hawkbot/catkin_ws/src:/opt/ros/melodic/share # 可见ROS_PACKAGE_PATH存在三个工作空间的环境变量 # 执行顺序依次为:willard_ws、catkin_ws
2.ROS通信编程
2.1 话题通信编程
- 创建发布者;
- 创建订阅者;
- 添加编译选项;
- 运行可执行程序;
2.1.1 发布者编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
向 R O S M a s t e r {\rm ROS\ Master} ROS Master注册节点信息,包括:发布的话题名和话题中的消息类型;
-
按照一定频率循环发布消息;
-
编程实现:
// talker.cpp文件 /** * 该例程将发布chatter话题,消息类型为String */ #include <sstream> #include "ros/ros.h" #include "std_msgs/String.h" int main(int argc, char **argv) { // ROS节点初始化 ros::init(argc, argv, "talker"); // 创建节点句柄 ros::NodeHandle n; // 创建一个Publisher, 发布名为chatter的topic, 消息类型为std_msgs::String ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); // 设置循环的频率 ros::Rate loop_rate(10); int count = 0; while (ros::ok()) { // 初始化std_msgs::String类型的消息 std_msgs::String msg; std::stringstream ss; ss << "Hello.Welcome to FUXI.Technology." << count; msg.data = ss.str(); // 发布消息 ROS_INFO("%s", msg.data.c_str()); chatter_pub.publish(msg); // 循环等待回调函数 ros::spinOnce(); // 按照循环频率延时 loop_rate.sleep(); ++count; } return 0; }
2.1.2 订阅者编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
订阅需要的话题;
-
循环等待话题消息,接收到消息后进入回调函数;
-
在回调函数中完成消息处理;
-
编程实现:
// listener.cpp文件 /** * 该例程将订阅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; }
2.1.3 编译代码
-
设置需要编译的代码和生成的可执行文件;
-
设置链接库;
-
设置依赖;
-
具体实现在 l e a r n i n g c o m m u n i c a t i o n / C M a k e L i s t s . t x t {\rm learning_communication/CMakeLists.txt} learningcommunication/CMakeLists.txt文件:
cmake_minimum_required(VERSION 2.8.3) project(learning_communication) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) ## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs ) ## System dependencies are found with CMake's conventions # find_package(Boost REQUIRED COMPONENTS system) ## Uncomment this if the package has a setup.py. This macro ensures ## modules and global scripts declared therein get installed ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html # catkin_python_setup() ################################################ ## Declare ROS messages, services and actions ## ################################################ ## To declare and build messages, services or actions from within this ## package, follow these steps: ## * Let MSG_DEP_SET be the set of packages whose message types you use in ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). ## * In the file package.xml: ## * add a build_depend tag for "message_generation" ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in ## but can be declared for certainty nonetheless: ## * add a exec_depend tag for "message_runtime" ## * In this file (CMakeLists.txt): ## * add "message_generation" and every package in MSG_DEP_SET to ## find_package(catkin REQUIRED COMPONENTS ...) ## * add "message_runtime" and every package in MSG_DEP_SET to ## catkin_package(CATKIN_DEPENDS ...) ## * uncomment the add_*_files sections below as needed ## and list every .msg/.srv/.action file to be processed ## * uncomment the generate_messages entry below ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) ## Generate messages in the 'msg' folder # add_message_files( # FILES # Message1.msg # Message2.msg # ) ## Generate services in the 'srv' folder # add_service_files( # FILES # Service1.srv # Service2.srv # ) ## Generate actions in the 'action' folder # add_action_files( # FILES # Action1.action # Action2.action # ) ## Generate added messages and services with any dependencies listed here # generate_messages( # DEPENDENCIES # std_msgs # ) ################################################ ## Declare ROS dynamic reconfigure parameters ## ################################################ ## To declare and build dynamic reconfigure parameters within this ## package, follow these steps: ## * In the file package.xml: ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" ## * In this file (CMakeLists.txt): ## * add "dynamic_reconfigure" to ## find_package(catkin REQUIRED COMPONENTS ...) ## * uncomment the "generate_dynamic_reconfigure_options" section below ## and list every .cfg file to be processed ## Generate dynamic reconfigure parameters in the 'cfg' folder # generate_dynamic_reconfigure_options( # cfg/DynReconf1.cfg # cfg/DynReconf2.cfg # ) ################################### ## catkin specific configuration ## ################################### ## The catkin_package macro generates cmake config files for your package ## Declare things to be passed to dependent projects ## INCLUDE_DIRS: uncomment this if your package contains header files ## LIBRARIES: libraries you create in this project that dependent projects also need ## CATKIN_DEPENDS: catkin_packages dependent projects also need ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( # INCLUDE_DIRS include # LIBRARIES learning_communication # CATKIN_DEPENDS roscpp rospy std_msgs # DEPENDS system_lib ) ########### ## Build ## ########### ## Specify additional locations of header files ## Your package locations should be listed before other locations include_directories( # include ${catkin_INCLUDE_DIRS} ) ## Declare a C++ library # add_library(${PROJECT_NAME} # src/${PROJECT_NAME}/learning_communication.cpp # ) ## Add cmake target dependencies of the library ## as an example, code may need to be generated before libraries ## either from message generation or dynamic reconfigure # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Declare a C++ executable ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide # add_executable(${PROJECT_NAME}_node src/learning_communication_node.cpp) # 新增加的链接库和依赖 # --------------------------------------------------- add_executable(talker src/talker.cpp) target_link_libraries(talker ${catkin_LIBRARIES}) # add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp) add_executable(listener src/listener.cpp) target_link_libraries(listener ${catkin_LIBRARIES}) # add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp) # --------------------------------------------------- ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the ## target back to the shorter version for ease of user use ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") ## Add cmake target dependencies of the executable ## same as for the library above # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify libraries to link a library or executable target against # target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # ) ############# ## Install ## ############# # all install targets should use catkin DESTINATION variables # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination # install(PROGRAMS # scripts/my_python_script # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark executables for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html # install(TARGETS ${PROJECT_NAME}_node # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark libraries for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html # install(TARGETS ${PROJECT_NAME} # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} # ) ## Mark cpp header files for installation # install(DIRECTORY include/${PROJECT_NAME}/ # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} # FILES_MATCHING PATTERN "*.h" # PATTERN ".svn" EXCLUDE # ) ## Mark other files for installation (e.g. launch and bag files, etc.) # install(FILES # # myfile1 # # myfile2 # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} # ) ############# ## Testing ## ############# ## Add gtest based cpp test target and link libraries # catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() ## Add folders to be run by python nosetests # catkin_add_nosetests(test)
# 1.编写发布者talker.cpp # 2.编写订阅者listener.cpp # 3.在CMakeLists.txt文件中设置链接库和依赖; # 4.切换到工作空间进行编译; cd ~/Willard_ws/ catkin_make # 5.运行可执行文件,注:没有.cpp后缀; roscore rosrun learning_communication talker rosrun learning_communication listener # 注意:代码文件放在功能包learning_communication/src下; # 设置链接库和依赖是在learning_communication/CMakeLists.txt;
-
实现效果如下:
2.1.4 自定义话题消息
# 1.在learning_communication目录下新建msg目录
mkdir msg
# 2.定义msg文件;
# Person.msg
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
# 3.在package.xml中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
# 4.在CMakeLists.txt添加编译选项
find_package(... message_generation)
catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs message_runtime)
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
# 5.编译
cd ~/willard_ws/
catkin_make
# 6.编译成功后,查看Person.msg信息
rosmsg show Person
# Person.msg
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
<!-- packages.xml -->
<?xml version="1.0"?>
<package format="2">
<name>learning_communication</name>
<version>0.0.0</version>
<description>The learning_communication package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="hawkbot@todo.todo">hawkbot</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/learning_communication</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- 新增的依赖 -->
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
# CMakeLists.txt文件
cmake_minimum_required(VERSION 2.8.3)
project(learning_communication)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
# =============================================
# 新增message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# =============================================
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# =============================================
# 新增内容的位置
add_message_files(
FILES
Person.msg
# Message1.msg
# Message2.msg
)
# =============================================
## Generate services in the 'srv' folder
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed here
# =============================================
# 新增内容的位置
generate_messages(
DEPENDENCIES
std_msgs
)
# =============================================
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
# =============================================
# 需要新增内容的位置
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_communication
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
# =============================================
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/learning_communication.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/learning_communication_node.cpp)
# 新增加的链接库和依赖
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
2.2 服务通信编程
- 创建服务器;
- 创建客户端;
- 添加编译选项;
- 运行可执行文件;
2.2.1 自定义服务请求与应答
# 1.定义srv文件,放置在learning_communication/srv目录下
roscd learning_communication/
mkdir srv
cd srv
# 2.定义Add.srv文件
gedit Add.srv
# 3.在package.xml中添加功能包依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
# 4.在CMakeLists.txt添加编译选项
find_package(... message_generation)
catkin_package(CATKIN_DEPENDS roscpp rospy std_msgs message_runtime)
add_service_files(FILES Add.srv)
# 5.编译
cd ~/willard_ws/
catkin_make
# 注:自定义服务过程和自定义消息过程类似;
# Add.srv文件
int64 a
int64 b
int64 c
---
int64 sum
<!-- packages.xml文件 -->
<?xml version="1.0"?>
<package format="2">
<name>learning_communication</name>
<version>0.0.0</version>
<description>The learning_communication package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="hawkbot@todo.todo">hawkbot</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/learning_communication</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- 新增的依赖 -->
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
# CMakeLists.txt文件
cmake_minimum_required(VERSION 2.8.3)
project(learning_communication)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
# =============================================
# 新增message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# =============================================
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# =============================================
# 新增内容的位置
add_message_files(
FILES
Person.msg
# Message1.msg
# Message2.msg
)
# =============================================
## Generate services in the 'srv' folder
# =============================================
# 新增内容的位置
add_service_files(
FILES
Add.srv
# Service1.srv
# Service2.srv
)
# =============================================
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed here
# =============================================
# 新增内容的位置
generate_messages(
DEPENDENCIES
std_msgs
)
# =============================================
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
# =============================================
# 需要新增内容的位置
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_communication
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
# =============================================
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/learning_communication.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/learning_communication_node.cpp)
# 新增加的链接库和依赖
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
2.2.2 服务器编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
创建 S e r v e r {\rm Server} Server实例;
-
循环等待服务请求,进入回调函数;
-
在回调函数中完成服务功能的处理,并反馈应答数据;
-
服务器编程实现:
/** * Add Server */ #include "ros/ros.h" #include "learning_communication/Add.h" // service回调函数,输入参数req,输出参数res bool add(learning_communication::Add::Request &req, learning_communication::Add::Response &res) { // 将输入参数中的请求数据相加,结果放到应答变量中 res.sum = req.a + req.b + req.c; ROS_INFO("request: x=%ld, y=%ld,z=%ld", (long int)req.a, (long int)req.b, (long int)req.c); ROS_INFO("sending back response: [%ld]", (long int)res.sum); return true; } int main(int argc, char **argv) { // ROS节点初始化 ros::init(argc, argv, "add_server"); // 创建节点句柄 ros::NodeHandle n; // 创建一个名为add_three_ints的server,注册回调函数add() ros::ServiceServer service = n.advertiseService("add_three_ints", add); // 循环等待回调函数 ROS_INFO("Ready to add three ints."); ros::spin(); return 0; }
2.2.3 客户端编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
创建一个 C l i e n t {\rm Client} Client实例;
-
发布服务请求数据;
-
等待 S e r v e r {\rm Server} Server处理后的应答结果;
-
客户端编程实现:
/** * Add client */ #include <cstdlib> #include "ros/ros.h" #include "learning_communication/Add.h" int main(int argc, char **argv) { // ROS节点初始化 ros::init(argc, argv, "add_client"); // 从终端命令行获取三个加数 if (argc != 4) { ROS_INFO("usage: add_client X Y Z"); return 1; } // 创建节点句柄 ros::NodeHandle n; // 创建一个client,请求add service,service消息类型是learning_communication::Add; ros::ServiceClient client = n.serviceClient<learning_communication::Add>("add_three_ints"); // 注意和server注册的服务名一致 // 创建learning_communication::Add类型的service消息 learning_communication::Add srv; srv.request.a = atoll(argv[1]); srv.request.b = atoll(argv[2]); srv.request.c = atoll(argv[3]); // 发布service请求,等待加法运算的应答结果 if (client.call(srv)) { ROS_INFO("Sum: %ld", (long int)srv.response.sum); } else { ROS_ERROR("Failed to call service add_three_ints"); return 1; } return 0; }
2.2.4 编译代码
-
设置需要编译的代码和生成的可执行文件;
-
设置链接库;
-
设置依赖;
-
具体实现:
# CMakeLists.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)
-
服务建立过程:
# 1.定义服务的请求与应答文件; # 2.编写服务器端代码; # 3.编写客户端代码; # 4.设置需要编译的代码和生成的可执行文件,设置链接库,设置依赖; # 5.工作空间下编译; cd ~/willard_ws/ catkin_make # 6.运行可执行文件 roscore # 启动master rosrun learning_communication server rosrun learning_commnuication client 1 2 3
-
实现效果图:
2.3 动作通信编程
2.3.1 动作通信机制基础
-
动作 ( a c t i o n ) ({\rm action}) (action)的定义
-
一种问答通信机制;
-
带有连续反馈;
-
可以在任务过程中止运行;
-
基于 R O S {\rm ROS} ROS的消息机制实现;
-
动作 ( a c t i o n ) ({\rm action}) (action)通信机制:
-
-
A c t i o n {\rm Action} Action接口定义
-
g o a l {\rm goal} goal:发布任务目标;
-
c a n c e l {\rm cancel} cancel:请求取消任务;
-
s t a t u s {\rm status} status:通知客户端当前的状态;
-
f e e d b a c k {\rm feedback} feedback:周期反馈任务运行的监控数据;
-
r e s u l t {\rm result} result:向客户端发送任务的执行结果,只发布一次;
-
示意图如下:
-
2.3.2 自定义动作消息
# 1.定义action文件;
# DoDishes.action
------------------------------
# 定义目标信息
uint32 dishwasher_id
---
# 定义结果信息
uint32 total_dishes_cleaned
---
# 定义周期反馈的消息
float32 percent_complete
------------------------------
# 2.在package.xml中添加功能包依赖;
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
# 3.在CMakeLists.txt添加编译选项
# 注意:在原来的文件中加入一些依赖即可,不用另起一行重新加入这些信息;
# 直接找到find_package(...actionlib_msgs actionlib)
find_package(catkin REQUIRED actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action)
generate_messages(DEPENDENCIES actionlib_msgs)
# 1.创建action目录
roscd learning_communication/
mkdir action
# 2.定义.action文件
cd action
touch DoDishes.action
gedit DoDishes.action
# 3.在package.xml中添加功能包依赖
gedit package.xml
# 4.在CMakeLists.txt文件添加编译选项
gedit CMakeLists.txt
# 5.编译
cd ~/willard_ws/
catkin_make
# DoDishes.action文件
# 注意.action文件的定义格式
# 定义目标信息
uint32 dishwasher_id
---
# 定义结果信息
uint32 total_dishes_cleaned
---
# 定义周期反馈消息
float32 percent_complete
<!-- package.xml文件 -->
<?xml version="1.0"?>
<package format="2">
<name>learning_communication</name>
<version>0.0.0</version>
<description>The learning_communication package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="hawkbot@todo.todo">hawkbot</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/learning_communication</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- 新增的依赖 -->
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!-- action新增的依赖 -->
<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<exec_depend>actionlib</exec_depend>
<exec_depend>actionlib_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
# CMakeLists.txt文件
cmake_minimum_required(VERSION 2.8.3)
project(learning_communication)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
# =============================================
# 新增message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
# ==action新增依赖==
actionlib_msgs
actionlib
# ==================
)
# =============================================
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# =============================================
# 新增内容的位置
add_message_files(
FILES
Person.msg
# Message1.msg
# Message2.msg
)
# =============================================
## Generate services in the 'srv' folder
# =============================================
# 新增内容的位置
add_service_files(
FILES
Add.srv
# Service1.srv
# Service2.srv
)
# =============================================
## Generate actions in the 'action' folder
# =======================================================
# action新增内容的位置
add_action_files(
FILES
DoDishes.action
# Action1.action
# Action2.action
)
# =======================================================
## Generate added messages and services with any dependencies listed here
# =============================================
# 新增内容的位置
generate_messages(
DEPENDENCIES
std_msgs
actionlib_msgs
)
# =============================================
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
# =============================================
# 需要新增内容的位置
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_communication
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
# =============================================
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/learning_communication.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/learning_communication_node.cpp)
# 新增加的链接库和依赖
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
# ==================================================
# 服务新增加的依赖
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)
# ==================================================
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
2.3.3 动作服务器编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
创建动作服务器实例;
-
启动服务器,等待动作请求;
-
在回调函数中完成动作功能的处理,并反馈进度信息;
-
动作完成,发送结束信息;
-
动作服务器编程实现:
#include <ros/ros.h> #include <actionlib/server/simple_action_server.h> #include "learning_communication/DoDishesAction.h" typedef actionlib::SimpleActionServer<learning_communication::DoDishesAction> Server; // 收到action的goal后调用该回调函数 void execute(const learning_communication::DoDishesGoalConstPtr& goal, Server* as) { ros::Rate r(1); learning_communication::DoDishesFeedback feedback; ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id); // 假设洗盘子的进度,并且按照1hz的频率发布进度feedback for(int i=1; i<=10; i++) { feedback.percent_complete = i * 10; as->publishFeedback(feedback); r.sleep(); } // 当action完成后,向客户端返回结果 ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id); as->setSucceeded(); } int main(int argc, char** argv) { ros::init(argc, argv, "do_dishes_server"); ros::NodeHandle n; // 定义一个服务器 Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false); // 服务器开始运行 server.start(); ros::spin(); return 0; }
2.3.4 动作客户端编程实现
-
初始化 R O S {\rm ROS} ROS节点;
-
创建动作客户端实例;
-
连接动作服务端;
-
发动动作目标;
-
根据不同类型的服务端反馈处理回调函数;
-
动作客户端编程实现:
#include <actionlib/client/simple_action_client.h> #include "learning_communication/DoDishesAction.h" typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client; // 当action完成后会调用该回调函数一次 void doneCb(const actionlib::SimpleClientGoalState& state, const learning_communication::DoDishesResultConstPtr& result) { ROS_INFO("Yay! The dishes are now clean"); ros::shutdown(); } // 当action激活后会调用该回调函数一次 void activeCb() { ROS_INFO("Goal just went active"); } // 收到feedback后调用该回调函数 void feedbackCb(const learning_communication::DoDishesFeedbackConstPtr& feedback) { ROS_INFO(" percent_complete : %f ", feedback->percent_complete); } int main(int argc, char** argv) { ros::init(argc, argv, "do_dishes_client"); // 定义一个客户端 Client client("do_dishes", true); // 等待服务器端 ROS_INFO("Waiting for action server to start."); client.waitForServer(); ROS_INFO("Action server started, sending goal."); // 创建一个action的goal learning_communication::DoDishesGoal goal; goal.dishwasher_id = 1; // 发送action的goal给服务器端,并且设置回调函数 client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); ros::spin(); return 0; }
2.3.5 编译代码
# CMakeLists.txt文件
# 1.设置需要编译的代码和生成的可执行文件
# 2.设置链接库;
# 3.设置依赖;
add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries(DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries(DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})
# 4.编译工作空间;
cd ~/willard_ws/
catkin_make
# 5.运行
roscore
rosrun learning_communication DoDishes_client
rosrun learning_communication DoDishes_server
# CMakeLists.txt文件内容
cmake_minimum_required(VERSION 2.8.3)
project(learning_communication)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
# =============================================
# 新增message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
# ==action新增依赖==
actionlib_msgs
actionlib
# ==================
)
# =============================================
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# =============================================
# 新增内容的位置
add_message_files(
FILES
Person.msg
# Message1.msg
# Message2.msg
)
# =============================================
## Generate services in the 'srv' folder
# =============================================
# 新增内容的位置
add_service_files(
FILES
Add.srv
# Service1.srv
# Service2.srv
)
# =============================================
## Generate actions in the 'action' folder
# =======================================================
# action新增内容的位置
add_action_files(
FILES
DoDishes.action
# Action1.action
# Action2.action
)
# =======================================================
## Generate added messages and services with any dependencies listed here
# =============================================
# 新增内容的位置
generate_messages(
DEPENDENCIES
std_msgs
actionlib_msgs
)
# =============================================
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
# =============================================
# 需要新增内容的位置
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_communication
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
# =============================================
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/learning_communication.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/learning_communication_node.cpp)
# 新增加的链接库和依赖
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
# add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)
# ==================================================
# 服务新增加的依赖
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)
# ==================================================
# ======================================================================
# action新增加的依赖
add_executable(DoDishes_client src/DoDishes_client.cpp)
target_link_libraries(DoDishes_client ${catkin_LIBRARIES})
add_dependencies(DoDishes_client ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_executable(DoDishes_server src/DoDishes_server.cpp)
target_link_libraries(DoDishes_server ${catkin_LIBRARIES})
add_dependencies(DoDishes_server ${${PROJECT_NAME}_EXPORTED_TARGETS})
# ======================================================================
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
3.分布式通信
# 实现分布式多机通信
# 1.远程登录设置
sudo apt-get install openssh-server # 安装ssh服务
systemctl start ssh # 开启ssh服务
sudo ps -e | grep ssh # 查看ssh是否开启
ping IP地址 # 测试网络连通性
sudo ssh 用户名@IP地址 # 远程登录
ifconfig # 查看ip地址
# 2.设置IP地址
# 在本地端和远程端分别设置对方的IP地址
# 本地端
sudo vim /etc/hosts
===========================================================
127.0.0.1 localhost
127.0.1.1 ros
# 增加对方的IP地址和名字
192.168.66.103 ubuntu
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
===========================================================
# 远程端
===========================================================
127.0.0.1 localhost
127.0.1.1 ubuntu
# 增加对方的IP地址和名字
192.168.66.102 ros
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
===========================================================
# 测试网络连通性
# 本地端
ping ubuntu
# 远程端
ping ros
# 3.从机端设置ROS_MASTER_URI
# 此处从机为hawkbot端的PC
sudo vim ~/.bashrc
==============================================
# 在~/.bashrc文件中添加内容
export ROBOT_IP=192.168.66.102 # 主机IP
export ROS_MASTER_URI=http://$ROBOT_IP:11311
==============================================
# 4.测试实例
# 4.1 启动master(主机:ros)
roscore
# 4.2 启动海龟(主机:ros)
rosrun turtlesim turtlesim_node
# 4.3 发布控制命令(从机:hawkbot)
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "linear:
x:2.0
y:0.0
z:0.0
angular:
x:0.0
y:0.0
z:2.0
"
4.ROS的常用组件
4.1 Launch文件
L a u n c h {\rm Launch} Launch文件:通过 X M L {\rm XML} XML文件实现多节点的配置和启动( L a u n c h {\rm Launch} Launch可自动启动 R O S M a s t e r {\rm ROS\ Master} ROS Master);
# 1.<launch>标签
<launch>:launch文件的根元素采用<launch>标签定义;
# 2.<node>标签
<node>:启动节点
<node pkg="package-name" type="executable-name" name="node-name"/>
参数说明:
pkg:节点所在功能包名称;
type:节点可执行文件名称;
name:节点运行时的名称;
其他参数:output、respawn、required、ns、args;
# 3.<param>标签
<param>:设置ROS系统运行中的参数,存储在参数服务器中;
<param name="output_frame" value="odom"/>
参数说明:
name:参数名;
value:参数值;
# 4.<rosparam>标签
<rosparam>:加载参数文件中的多个参数;
<rosparam file="params.yaml" command="load" ns="params"/>
# 5.<arg>标签
<arg>:launch文件内部的局部变量,仅限于launch文件使用;
<arg name="arg-name" default="arg-value"/>
参数说明:
name:参数名;
value:参数值;
调用:
<param name="foo" value="$(arg arg-name)"/>
<node name="node" pkg="package" type="type" args="$(arg arg-name)"/>
# 6.<remap>标签
<remap>:重映射ROS计算图资源的命名;
<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>
参数说明:
from:原来的名字;
to:映射后的名字;
# 7.<include>标签
<include>:包含其他launch文件;
<include file="$(dirname)/other.launch"/>
参数说明:
file:包含的其他launch文件路径;
<!-- launch文件实例,gmapping_slam.launch实例 -->
<launch>
<node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen">
<param name="transform_publish_period" value="0.1"/>
<param name="base_frame" value="/base_footprint"/>
<param name="odom_frame" value="/odom"/>
<param name="map_frame" value="/map"/>
<param name="map_update_interval" value="2.0"/>
<param name="maxUrange" value="8"/>
<param name="sigma" value="0.05"/>
<param name="kernelSize" value="1"/>
<param name="lstep" value="0.05"/>
<param name="astep" value="0.05"/>
<param name="iterations" value="5"/>
<param name="lsigma" value="0.075"/>
<param name="ogain" value="3.0"/>
<param name="lskip" value="0"/>
<param name="minimumScore" value="50"/>
<param name="srr" value="0.1"/>
<param name="srt" value="0.2"/>
<param name="str" value="0.1"/>
<param name="stt" value="0.2"/>
<param name="linearUpdate" value="1.0"/>
<param name="angularUpdate" value="0.2"/>
<param name="temporalUpdate" value="0.5"/>
<param name="resampleThreshold" value="0.5"/>
<param name="particles" value="100"/>
<param name="xmin" value="-10.0"/>
<param name="ymin" value="-10.0"/>
<param name="xmax" value="10.0"/>
<param name="ymax" value="10.0"/>
<param name="delta" value="0.03"/>
<param name="llsamplerange" value="0.01"/>
<param name="llsamplestep" value="0.01"/>
<param name="lasamplerange" value="0.005"/>
<param name="lasamplestep" value="0.005"/>
</node>
<node pkg="rviz" type="rviz" name="rviz1" required="true" args="-d $(find hawkbot)/rviz/slam.rviz"/>
</launch>
4.2 TF坐标变换
4.2.1 TF坐标变换例程
sudo apt-get install ros-melodic-turtle-tf # 注意ros版本
roslaunch turtle_tf turtle_tf_demo.launch
rosrun turtlesim turtle_teleop_key
rosrun tf view_frames # 生成tf关系图
rosrun tf tf_echo turtle1 turtle2 # 查看具体tf关系
海龟例程坐标变换公式:
T
t
u
r
t
l
e
1
_
t
u
r
t
l
e
2
=
T
t
u
r
t
l
e
1
_
w
o
r
l
d
∗
T
w
o
r
l
d
_
t
u
r
t
l
e
2
{\rm T}_{turtle1\_turtle2}={\rm T}_{turtle1\_world}*{\rm T}_{world\_turtle2}
Tturtle1_turtle2=Tturtle1_world∗Tworld_turtle2
4.2.2 TF广播器和TF监听器编程实现
-
T F {\rm TF} TF坐标变换实现步骤
# 1.建立learning_tf功能包 cd ~/willard_ws/src/ catkin_create_pkg learning_tf std_msgs rospy roscpp # 2.编译功能包 cd ~/willard_ws catkin_make source ~/willard_ws/devel/setup.bash # 3.创建tf广播器.cpp touch turtle_tf_broadcaster.cpp # 4.创建tf监听器.cpp touch turtle_tf_listener.cpp # 5.编译代码(CMakeLists.txt) # 设置需要编译的代码和生成的可执行文件; # 设置链接库; # ================================================================== add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp) target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES}) add_executable(turtle_tf_listener src/turtle_tf_listener.cpp) target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES}) # ================================================================== # ====================================== # 其他需要修改 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation tf ) # ====================================== # 编译代码 cd ~/willard_ws/ catkin_make soure devel/setup.bash # 6.建立.launch文件,放置learning_tf/launch/下 # 启动.launch文件 roslaunch learning_tf start_demo_with_listener.launch
-
T F {\rm TF} TF广播器编程实现
-
定义 T F {\rm TF} TF广播器 ( T r a n s f o r m B r o a d c a s t e r ) ({\rm TransformBroadcaster}) (TransformBroadcaster);
-
创建坐标变换值;
-
发布坐标变换 ( s e n d T r a n s f o r m ) ({\rm sendTransform}) (sendTransform);
-
编程实现:
// turtle_tf_broadcaster.cpp文件 #include <ros/ros.h> #include <tf/transform_broadcaster.h> #include <turtlesim/Pose.h> std::string turtle_name; void poseCallback(const turtlesim::PoseConstPtr& msg) { // tf广播器 static tf::TransformBroadcaster br; // 根据乌龟当前的位姿,设置相对于世界坐标系的坐标变换 tf::Transform transform; transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) ); tf::Quaternion q; q.setRPY(0, 0, msg->theta); transform.setRotation(q); // 发布坐标变换 br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name)); } int main(int argc, char** argv) { // 初始化节点 ros::init(argc, argv, "my_tf_broadcaster"); if (argc != 2) { ROS_ERROR("need turtle name as argument"); return -1; }; turtle_name = argv[1]; // 订阅乌龟的pose信息 ros::NodeHandle node; ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback); ros::spin(); return 0; };
-
-
T F {\rm TF} TF监听器编程实现
-
定义 T F {\rm TF} TF监听器 ( T r a n s f o r m L i s t e n e r ) ({\rm TransformListener}) (TransformListener);
-
查找坐标变换 ( w a i t F o r T r a n s f o r m 、 l o o k u p T r a n s f o r m ) ({\rm waitForTransform、lookupTransform}) (waitForTransform、lookupTransform);
-
编程实现:
// turtle_tf_listener.cpp文件 #include <ros/ros.h> #include <tf/transform_listener.h> #include <geometry_msgs/Twist.h> #include <turtlesim/Spawn.h> int main(int argc, char** argv) { // 初始化节点 ros::init(argc, argv, "my_tf_listener"); ros::NodeHandle node; // 通过服务调用,产生第二只乌龟turtle2 ros::service::waitForService("spawn"); ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("spawn"); turtlesim::Spawn srv; add_turtle.call(srv); // 定义turtle2的速度控制发布器 ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 10); // tf监听器 tf::TransformListener listener; ros::Rate rate(10.0); while (node.ok()) { tf::StampedTransform transform; try { // 查找turtle2与turtle1的坐标变换 listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0)); listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform); } catch (tf::TransformException &ex) { ROS_ERROR("%s",ex.what()); ros::Duration(1.0).sleep(); continue; } // 根据turtle1和turtle2之间的坐标变换,计算turtle2需要运动的线速度和角速度 // 并发布速度控制指令,使turtle2向turtle1移动 geometry_msgs::Twist vel_msg; vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x()); vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2)); turtle_vel.publish(vel_msg); rate.sleep(); } return 0; };
-
-
编译文件 ( C M a k e L i s t s . t x t ) ({\rm CMakeLists.txt}) (CMakeLists.txt);
cmake_minimum_required(VERSION 2.8.3) project(learning_tf) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) ## is used, also find other catkin packages # =============================================== # tf修改部分 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation tf ) # =============================================== ## System dependencies are found with CMake's conventions # find_package(Boost REQUIRED COMPONENTS system) ## Uncomment this if the package has a setup.py. This macro ensures ## modules and global scripts declared therein get installed ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html # catkin_python_setup() ################################################ ## Declare ROS messages, services and actions ## ################################################ ## To declare and build messages, services or actions from within this ## package, follow these steps: ## * Let MSG_DEP_SET be the set of packages whose message types you use in ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). ## * In the file package.xml: ## * add a build_depend tag for "message_generation" ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in ## but can be declared for certainty nonetheless: ## * add a exec_depend tag for "message_runtime" ## * In this file (CMakeLists.txt): ## * add "message_generation" and every package in MSG_DEP_SET to ## find_package(catkin REQUIRED COMPONENTS ...) ## * add "message_runtime" and every package in MSG_DEP_SET to ## catkin_package(CATKIN_DEPENDS ...) ## * uncomment the add_*_files sections below as needed ## and list every .msg/.srv/.action file to be processed ## * uncomment the generate_messages entry below ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) ## Generate messages in the 'msg' folder # add_message_files( # FILES # Message1.msg # Message2.msg # ) ## Generate services in the 'srv' folder # add_service_files( # FILES # Service1.srv # Service2.srv # ) ## Generate actions in the 'action' folder # add_action_files( # FILES # Action1.action # Action2.action # ) ## Generate added messages and services with any dependencies listed here # generate_messages( # DEPENDENCIES # std_msgs # ) ################################################ ## Declare ROS dynamic reconfigure parameters ## ################################################ ## To declare and build dynamic reconfigure parameters within this ## package, follow these steps: ## * In the file package.xml: ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" ## * In this file (CMakeLists.txt): ## * add "dynamic_reconfigure" to ## find_package(catkin REQUIRED COMPONENTS ...) ## * uncomment the "generate_dynamic_reconfigure_options" section below ## and list every .cfg file to be processed ## Generate dynamic reconfigure parameters in the 'cfg' folder # generate_dynamic_reconfigure_options( # cfg/DynReconf1.cfg # cfg/DynReconf2.cfg # ) ################################### ## catkin specific configuration ## ################################### ## The catkin_package macro generates cmake config files for your package ## Declare things to be passed to dependent projects ## INCLUDE_DIRS: uncomment this if your package contains header files ## LIBRARIES: libraries you create in this project that dependent projects also need ## CATKIN_DEPENDS: catkin_packages dependent projects also need ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( # INCLUDE_DIRS include # LIBRARIES learning_tf # CATKIN_DEPENDS roscpp rospy std_msgs # DEPENDS system_lib ) ########### ## Build ## ########### ## Specify additional locations of header files ## Your package locations should be listed before other locations include_directories( # include ${catkin_INCLUDE_DIRS} ) ## Declare a C++ library # add_library(${PROJECT_NAME} # src/${PROJECT_NAME}/learning_tf.cpp # ) ## Add cmake target dependencies of the library ## as an example, code may need to be generated before libraries ## either from message generation or dynamic reconfigure # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Declare a C++ executable ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide # add_executable(${PROJECT_NAME}_node src/learning_tf_node.cpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the ## target back to the shorter version for ease of user use ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") ## Add cmake target dependencies of the executable ## same as for the library above # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify libraries to link a library or executable target against # target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # ) # ====================================================================== # tf新增内容 add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp) target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES}) add_executable(turtle_tf_listener src/turtle_tf_listener.cpp) target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES}) # ====================================================================== ############# ## Install ## ############# # all install targets should use catkin DESTINATION variables # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination # install(PROGRAMS # scripts/my_python_script # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark executables for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html # install(TARGETS ${PROJECT_NAME}_node # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark libraries for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html # install(TARGETS ${PROJECT_NAME} # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} # ) ## Mark cpp header files for installation # install(DIRECTORY include/${PROJECT_NAME}/ # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} # FILES_MATCHING PATTERN "*.h" # PATTERN ".svn" EXCLUDE # ) ## Mark other files for installation (e.g. launch and bag files, etc.) # install(FILES # # myfile1 # # myfile2 # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} # ) ############# ## Testing ## ############# ## Add gtest based cpp test target and link libraries # catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_tf.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() ## Add folders to be run by python nosetests # catkin_add_nosetests(test)
-
L a u n c h {\rm Launch} Launch文件启动
<!-- start_demo_with_listener.launch文件 --> <launch> <!-- 海龟仿真器 --> <node pkg="turtlesim" type="turtlesim_node" name="sim"/> <!-- 键盘控制 --> <node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/> <!-- 两只海龟的tf广播 --> <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" /> <node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf_broadcaster" /> <!-- 监听tf广播,并且控制turtle2移动 --> <node pkg="learning_tf" type="turtle_tf_listener" name="listener" /> </launch>
4.3 Rviz可视化平台简介
-
r v i z {\rm rviz} rviz中,可以使用可扩展标记语言 X M L {\rm XML} XML对机器人、周围物体等任何实物进行尺寸、质量、位置、材质、关节等属性的描述,且在界面中呈现出来;
-
r v i z {\rm rviz} rviz可以通过图形化的方式,实时显示机器人传感器的信息、机器人的运动状态、周围环境的变化等信息;
-
r v i z {\rm rviz} rviz可通过机器人模型参数、机器人发布的传感信息等数据,为用户进行所有可监测信息的图形化显示;用户和开发者可以在 r v i z {\rm rviz} rviz控制界面下,通过按钮、滑动条、数值等方式,控制机器人的行为;
-
r v i z {\rm rviz} rviz界面介绍:
4.4 Gazebo物理仿真环境简介
-
G
a
z
e
b
o
{\rm Gazebo}
Gazebo简介
- G a z e b o {\rm Gazebo} Gazebo是一款功能强大的三维物理仿真平台;
- 具备强大的物理引擎;
- 高质量的图形渲染;
- 方便的编程与图形接口;
- 开源免费;
-
G
a
z
e
b
o
{\rm Gazebo}
Gazebo典型应用场景
- 测试机器人算法;
- 机器人的设计;
- 现实情境下的回溯测试;
-
G
a
z
e
b
o
{\rm Gazebo}
Gazebo主要插件
- g a z e b o _ r o s {\rm gazebo\_ros} gazebo_ros:主要用于 g a z e b o {\rm gazebo} gazebo接口和封装、 g a z e b o {\rm gazebo} gazebo服务端和客户端的启动、 U R D F {\rm URDF} URDF模型生成等;
- g a z e b o _ m s g s {\rm gazebo\_msgs} gazebo_msgs: g a z e b o {\rm gazebo} gazebo的 M s g {\rm Msg} Msg和 S r v {\rm Srv} Srv数据结构;
- g a z e b o _ p l u g i n s {\rm gazebo\_plugins} gazebo_plugins:用于 g a z e b o {\rm gazebo} gazebo的通用传感器插件;
- g a z e b o _ r o s _ a p i _ p l u g i n 、 g a z e b o _ r o s _ p a t h _ p l u g i n {\rm gazebo\_ros\_api\_plugin}、{\rm gazebo\_ros\_path\_plugin} gazebo_ros_api_plugin、gazebo_ros_path_plugin:实现接口封装;
- 使用
G
a
z
e
b
o
{\rm Gazebo}
Gazebo仿真步骤
- 创建仿真环境;
- 配置机器人模型;
- 开始仿真;