Chapter2:ROS基础

news2024/11/18 21:45:31

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.创建工作空间

  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
    ===============================================================================
    
  2. 创建工作空间

    # 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
    
  3. 创建功能包

    # 语法: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
    
    # 注意:同一个工作空间下,不允许存在同名功能包,不同工作空间下,允许存在同名功能包;
    
  4. 工作空间覆盖机制

    • 工作空间的路径依次在 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 话题通信编程

1

  1. 创建发布者;
  2. 创建订阅者;
  3. 添加编译选项;
  4. 运行可执行程序;
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

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 服务通信编程

3

  1. 创建服务器;
  2. 创建客户端;
  3. 添加编译选项;
  4. 运行可执行文件;
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
    
  • 实现效果图:

    4

2.3 动作通信编程
2.3.1 动作通信机制基础
  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)通信机制:

      5

  2. 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:向客户端发送任务的执行结果,只发布一次;

    • 示意图如下:

      6

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
"

8

9

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_worldTworld_turtle2
9

4.2.2 TF广播器和TF监听器编程实现
  1. 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
    
  2. 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;
      };
      
  3. 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}) (waitForTransformlookupTransform)

    • 编程实现:

      // 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;
      };
      
  4. 编译文件 ( 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)
    
  5. 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界面介绍:

    20

4.4 Gazebo物理仿真环境简介
  1. G a z e b o {\rm Gazebo} Gazebo简介
    • G a z e b o {\rm Gazebo} Gazebo是一款功能强大的三维物理仿真平台;
    • 具备强大的物理引擎;
    • 高质量的图形渲染;
    • 方便的编程与图形接口;
    • 开源免费;
  2. G a z e b o {\rm Gazebo} Gazebo典型应用场景
    • 测试机器人算法;
    • 机器人的设计;
    • 现实情境下的回溯测试;
  3. 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_plugingazebo_ros_path_plugin:实现接口封装;
  4. 使用 G a z e b o {\rm Gazebo} Gazebo仿真步骤
    1. 创建仿真环境;
    2. 配置机器人模型;
    3. 开始仿真;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/185688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Magisk内部实现原理

Android10以后&#xff0c;Android系统限制了System分区的修改&#xff0c;结果就是&#xff0c;即使你i是自己编译的Android系统&#xff0c;即使是有做高的root权限&#xff0c;你依然无法挂载System分区并对其内容进行修改,尽管网上有各种帖子说可以使用mount -o rw,remount…

SpringBoot+Vue项目企业客户管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…

Linux(centos7)基本操作---文件管理和用户管理

文件管理 文件的目录结构 文件的目录结构从根&#xff08;/&#xff09;目录开始&#xff0c;主要由一下几个目录组成&#xff0c;之间的作用也是不同的&#xff0c;具体作用如下&#xff1a; bin目录&#xff1a;主要存放系统中的一些基本的有执行权限&#xff08;x&#…

动态AOP 自动以标签 源码解析

Spring AOP 是一个简化版的AOP 实现&#xff0c;并没有提供完整的AOP功能&#xff0c;通常情况下&#xff0c;Spring AOP 是能够满足我们日常开发过程中的大多数场景的&#xff0c;但在某些情况下&#xff0c; 我们可能需要使用Spring AOP 范围外的某些AOP 功能。 AspectJ是一…

【JAVA程序设计】(C00101)基于Servlet的在线鞋店销售管理系统

基于Servlet的在线鞋店销售管理系统项目简介项目获取开发环境项目技术运行截图项目简介 本项目是基于J2EE的servlet的在线鞋店销售管理系统&#xff0c;网上鞋店&#xff0c;球鞋&#xff0c;篮球鞋&#xff0c;跑步鞋&#xff0c;本项目有三种权限&#xff1a;游客、用户、管…

LeetCode 1480. 一维数组的动态和

有人相爱 有人深夜看海 有人LeetCode第一题都做不出来 小趴菜就是我 女神镇楼压压惊 文章目录LeetCode 1480. 一维数组的动态和题目描述&#xff1a;示例1&#xff1a;示例2&#xff1a;示例3&#xff1a;提示&#xff1a;解题思路题解结果展示大神题解执行消耗内存为 0 kb&am…

轻量级 K8S 环境、本地 K8S 环境Minikube,一键使用 (史上最全)

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…

基于android的教育机构家校通系统app

需求信息&#xff1a; 客户端老师 1&#xff1a;用户注册与登录 2&#xff1a;添加作业信息&#xff1b;作业包含选择、填空以及简单题 3&#xff1a;查看自己添加的试题信息&#xff1b; 4&#xff1a;对学生提交的作业信息进行查看和批改&#xff1b; 5&#xff1a;和学生进行…

自学Vue开发Dapp去中心化钱包(三)

前言本篇主要记录学习Vue并实际参与完结web3门户项目的经验和走过的弯路。拖了这么久才来还债&#xff0c;说项目忙那是借口&#xff0c;还是因为个人懒&#xff01;从自学到实战Vue实际中间就1周的学习熟悉时间&#xff0c;学习不够深就会造成基础不稳&#xff0c;多次推翻重来…

新的一年里技术管理者(工作者)们如何做好技术规划?

技术管理者的主要工作 技术管理者的主要工作是带人、做事、看方向: 带人是指团队人员能力的培养、团队梯队的建设等等;做事是指完成各项业务需求;看方向是指明确团队未来的发展方向和目标。我们经常会辩论“做管理了还要不要写代码”这个话题,而“写代码”只是“做事”里面…

Java——Maven项目管理

目录Maven1&#xff0c;Maven1.1 Maven简介1.1.1 Maven模型1.1.2 仓库1.3 Maven基本使用1.3.1 Maven 常用命令1.3.2 Maven 生命周期1.4.2 Maven 坐标详解1.4.3 IDEA 创建 Maven项目1.4.4 IDEA 导入 Maven项目1.5 依赖管理1.5.1 使用坐标引入jar包1.5.2 依赖范围Maven 目标 能够…

服务器与客户端的一般套路

WinSocket 套接字 ————服务器与客户端的一般套路 一、开发环境 IDE: Red Panda Dev-C 6.5编程语言&#xff1a;C语言库&#xff1a;winsock2.h 二、套接字工作流程图 注意&#xff1a;这个工作流程图非常重要&#xff0c;后面的代码编写基本就是这个逻辑 三、服务器各…

前端基于DOM或者Canvas实现页面水印

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff1a;vue3从入门…

AtCoder Beginner Contest 287(A~E)

比赛名称&#xff1a;UNIQUE VISION Programming Contest 2023 New Year (AtCoder Beginner Contest 287) 比赛链接&#xff1a;AtCoder Beginner Contest 287 目录 A - Majority B - Postal Card C - Path Graph? D - Match or Not E - Karuta A - Majority 问字…

工作和学习中都能用到的5款实用软件

如今&#xff0c;工作和学习都离不开电脑&#xff0c;所以电脑里的软件自然也是必不可少的&#xff0c;但是电脑软件那么多&#xff0c;不可能每个都装上吧&#xff0c;所以我们要装好用的、实用的&#xff0c;下面给大家分享5款好用到爆的软件&#xff0c;很多懂电脑的人都在用…

【算法】雪花算法

一.特点 1.全局唯一性&#xff1a;对于大数据量的分库分表场景&#xff0c;例如水平分表需要保证主键id的全局唯一性。 2.趋势递增&#xff1a;整体的id趋势是递增的&#xff0c;不是单调递增。 3.不规则性&#xff1a;id不连续&#xff0c;无规则&#xff0c;不规则。 4.包含…

乾元通多卡聚合通信设备保障生态环境监测网络

针对目前城市大气环境监测网格化建设&#xff0c;推出的新一代城市网格化大气环境监测系统&#xff0c;可以实现城市区域环境多维一体化监测管理&#xff0c;该设备主要用于监测大气环境中的PM10、TSP、PM2.5等颗粒物浓度&#xff0c;还可以实现环境监控&#xff0c;测噪音、大…

Node.JS 安装配置 | 安装排错解析

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Node.js下载 Node.js官方下载地址 官方下载如果慢&#xff0c;请用如下地址下载&#xff1a; Node.js 中文网 根据自己计算机配置下载 Next Next 安装地址可更换 Next…

年后找工作必看的自动化测试面试宝典,一般人我不告诉他

目录 前言 1.1 什么是 API&#xff1f; 1.2 什么是 API 测试&#xff1f; 1.3 常见的 API 测试类型有哪些&#xff1f; 1.4 列举 API 测试中使用的一些常用协议&#xff1f; 1.9API 常见测试有哪些&#xff1f; 1.10API 测试有哪些优势&#xff1f; 1.11API 测试中究竟…

【PHP 随记】—— Composer 安装项目以及项目的扩展

&#x1f449;总目录&#x1f448;\large\colorbox{skyblue}{&#x1f449;总目录&#x1f448;}&#x1f449;总目录&#x1f448;​ 文章目录1、Composer 安装项目① 项目安装示例② 相关问题解决③ 框架搜索指南2、Composer 安装项目的扩展使用 Composer 更轻松方便地安装 P…