Learning the core technology of robot SLAM navigation (2) ROS

Chapter 1: Essential knowledge for getting started with ROS

The full name of ROS is Robot Operating System, which is an open source framework for robot application development. ROS provides a series of tools and libraries to make it easier for robot developers to write software to realize robot perception, control, positioning, navigation and other functions. ROS uses the publisher-subscriber model to implement message passing and supports multiple programming languages. Because it has a convenient modular design, it allows developers to debug and modify programs more conveniently, greatly reducing the development time of robot applications. ROS has been widely used in the field of robotics and has become one of the standard tools in academia and industry.

Overview of ROS

  • ROS is an open-source meta-operating system for robots
  • ROS integrates a large number of tools, libraries, protocols, provides functions similar to those provided by OS, and simplifies the control of robots
  • Providing tools and libraries for getting, building, writing and running code on multiple computers, ROS is in some ways similar to "Robot Framework"
  • ROS designers describe ROS as "ROS = Plumbing + Tools + Capabilities +
  • Ecosystem", that is, ROS is a collection of communication mechanisms, tool software packages, high-level skills of robots, and robot ecosystems.

The idea of ​​division of labor in robot development realizes the sharing and collaboration among different R&D teams and improves the efficiency of robot R&D. In order to serve the "division of labor", ROS mainly designs the following goals:

  • Code reuse: The goal of ROS is not to be the most versatile framework, the main goal of ROS is to support code reuse in robotics research and development.

  • Distributed: ROS is a distributed framework for processes (also known as Nodes). Processes in ROS can be distributed on different hosts, and different hosts work together to disperse computing pressure.

  • Loose coupling: Functional modules in ROS are packaged in independent functional packages or meta-functional packages for easy sharing. The modules in the functional package operate in units of nodes, and use ROS standard IO as the interface. Developers do not need to pay attention to the internal implementation of the module, as long as Reuse can be realized by understanding the interface rules, and the point-to-point loosely coupled connection between modules is realized

  • Lean: ROS is designed to be as lean as possible so that code written for ROS can be used with other robotics software frameworks. ROS is easy to integrate with other robot software frameworks: ROS has been integrated with OpenRAVE, Orocos and Player.

  • Language independence: including Java, C++, Python, etc. In order to support more application development and transplantation, ROS is designed as a weakly language-related framework structure, using a concise and neutral definition language to describe the message interface between modules, and regenerating the target file of the language used during compilation, for message interaction Provides support while allowing nested usage of message interfaces

  • Ease of testing: ROS has a built-in unit/integration testing framework called rostest that makes it easy to install and tear down testing tools.

  • Large applications: ROS is suitable for large runtime systems and large development pipelines.

  • Rich componentized toolkit: ROS can integrate some tools and software into the system in a componentized way and use them directly as a component, such as RVIZ (3D visualization tool), where developers can display robot models according to the interface defined by ROS, etc. Components also include simulation environment and message viewing tools, etc.
    Free and open source: there are many developers and many function packages

ROS development history

ROS is a large software project with a long history and many contributors. Before the birth of ROS, many scholars believed that robot research needed an open collaborative framework, and there were already many similar projects dedicated to realizing such a framework. In these works, Stanford University launched a series of related research projects in the middle of 2000, such as the Stanford AI Robot (STAIR) project and the Personal Robots (PR) project. Among the above projects, In the course of researching representative, integrated artificial intelligence systems, highly flexible, dynamic software systems for indoor scenarios were created, which can be used in robotics research.

  • 2007: ROS's predecessor, the "Switchyard" project, begins development by Morgan Quigley, Brian Gerkey, and William D. Smart at Stanford University's Artificial Intelligence Laboratory.
  • 2009: ROS was officially released and presented at the it-robots Exhibition. The first stable version of ROS, ROS 1.0, was also released in the same year.
  • 2010: In the DARPA Virtual Robotics Challenge sponsored by Google, many players used ROS as their robot control platform.
  • 2012: One of the most important updates to ROS, the Groovy Galapagos release, is released.
  • 2013: The rapid development of ROS, the number of users and the number of software packages have increased significantly.
  • 2014: Indigo Igloo, a new version of ROS, was released. This version improved the core tools of ROS and added industry-oriented functions. ROS entered the industry and has been used in many projects.
  • 2016: Kinetic, a new version of ROS, was released. This version supports the Ubuntu Xenial 16.04 LTS operating system, raising the stability and reliability of the ROS system to a new level.
  • 2020: The stable version of ROS2, Dashing Diademata, is released. Compared with ROS1, ROS2 supports more platforms and operating systems, and has better real-time and security.

The release version of ROS (ROS distribution) refers to the version of the ROS software package, which is similar to the concept of the distribution version of Linux (such as Ubuntu). The purpose of a ROS release is to allow developers to work with a relatively stable code base until it is ready to version everything. Therefore, after each release, ROS developers usually only fix bugs in this version, while providing a small number of improvements to the core package.
The version features are named in alphabetical order. ROS has released the ultimate version of ROS1: noetic, and it is recommended to transition to the ROS2 version later. Before the noetic version, Python2 was used by default, and noetic supports Python3. Suggested versions: noetic or melodic or kinetic

Overall, since 2007, ROS has grown rapidly in the field of robotics and has become one of the most popular robotic operating systems, widely used in both academia and industry.

ROS is easy to use

The programming languages ​​involved in ROS are mainly C++ and Python, and most programs in ROS can be implemented in both. The current code statistics of ROS, the total number of lines exceeds 14 million, and the number of authors exceeds 2477. The code language is mainly C++, 63.98% of the code is written in C++, and the second is python, accounting for 13.57%. It can be said that ROS basically uses these two languages ​​to realize most of the functions.

In this series of tutorials, each case will be demonstrated using two schemes, C++ and Python, and you can choose the appropriate implementation scheme according to your own situation. Even if programs in ROS use different programming languages, the implementation process is roughly similar. Taking the current HelloWorld program as an example, the implementation process is roughly as follows:

To implement the HelloWorld program in ROS, the following general process can be taken:

  • Create a ROS workspace (ROS workspace): First, you need to create a ROS workspace to host this project.

  • Create a ROS package (ROS package): Create a new ROS package in the workspace, this package will contain our code and dependencies.

  • Write a ROS node: Create a ROS node in the ROS package, this node will send the Hello World message.

  • Compile and build (build) ROS packages: Package ROS nodes into an executable binary file.

  • Run the ROS node: Run the ROS node in the terminal, and the ROS node will send the Hello World message.

For the detailed implementation process, please refer to official documents or tutorials. Here is just a rough overview of the process. Although C++ and Python can be interchanged to achieve the same function, which language to choose depends on the needs, because in comparison between the two languages: C++ has high operating efficiency but low coding efficiency, while Python is the opposite, based on The two complement each other. ROS designers have designed roscpp and rospy libraries respectively. The former aims to be a high-performance library for ROS, while the latter is generally used in scenarios that do not require performance, aiming to improve development efficiency.

Create workspace and initialize

Create a workspace and a src subdirectory, and then enter the workspace and call the catkin_make command to compile.

mkdir -p 自定义空间名称/src
cd 自定义空间名称
catkin_make

Enter src to create ros package and add dependencies

Generate a function package under the workspace, which depends on roscpp, rospy and std_msgs, where roscpp is a library implemented in C++, rospy is a library implemented in python, and std_msgs is a standard message library. When creating a ROS function package , generally rely on these three libraries to implement

cd src
catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs

HelloWorld(C++ version)

Assuming that you have created a ROS workspace and created a ROS function package, then you can enter the core steps and use C++ to write a program to achieve:

After entering the src directory of the ros package and editing the source file, the C++ source code implementation (file name customization)

// 导入ROS的头文件
#include "ros/ros.h"

int main(int argc, char *argv[])
{
    
    
    // 初始化ROS节点
    ros::init(argc, argv, "hello_world");

    // 创建句柄
    ros::NodeHandle nh;

    // 输出Hello World!
    ROS_INFO("Hello World!");

    return 0;
}

Edit the Cmakelist.txt file under the ros package

add_executable(步骤3的源文件名
  src/步骤3的源文件名.cpp
)
target_link_libraries(步骤3的源文件名
  ${
    
    catkin_LIBRARIES}
)

Enter the workspace directory and compile

cd 自定义空间名称
catkin_make

生成 build devel ....

Execution
Start command line 1 first:

roscore

Start command line 2 again:

cd 工作空间
source ./devel/setup.bash
rosrun 包名 C++节点

HelloWorld(Python version)

Assuming that you have created a ROS workspace and created a ROS function package, then you can enter the core steps and use Python to write a program to achieve:

Enter the ros package to add the scripts directory and edit the python file

cd ros包
mkdir scripts

Create a new python file: (customized file name)

#! /usr/bin/env python

"""
    Python 版 HelloWorld

"""
import rospy

if __name__ == "__main__":
    rospy.init_node("Hello")
    rospy.loginfo("Hello World!!!!")

Add executable permissions to python files

chmod +x 自定义文件名.py

Edit the CamkeList.txt file under the ros package

catkin_install_python(PROGRAMS scripts/自定义文件名.py
  DESTINATION ${
    
    CATKIN_PACKAGE_BIN_DESTINATION}
)

Enter the workspace directory and compile

cd 自定义空间名称
catkin_make

Enter the workspace directory and execute
the first start command line 1:

roscore

Start command line 2 again:

cd 工作空间
source ./devel/setup.bash

rosrun 包名 自定义文件名.py

Output result: Hello World!!!

ROS Architecture

ROS adopts a distributed system structure, which consists of multiple processes (nodes), and each node interacts through the ROS communication mechanism (topic, Service). These nodes can be deployed on the same machine, or on different machines, or on the Internet. The following are the main components involved in the ROS architecture:

  • Node (Node): It is a basic component in the ROS architecture, usually referring to a running process, responsible for completing specific tasks. Each node can have multiple ROS milestones. ROS provides tools for processing nodes for query operations on node information, status, availability, etc. For example, the following commands can be used to operate on running nodes.

    • rosnode info <node_name>: used to output current node information.
    • rosnode kill <node_name>: used to kill the running node process to end the running of the node. rosnode list: used to list the currently active nodes.
    • rosnode machine : Used to list the nodes running on the specified machine. rosnode ping <node_name>: Used to test the network connectivity between nodes.
    • rosnode cleanup: used to clear the registration information of inaccessible nodes.
  • Master node (Master): It is an important component of the ROS system, responsible for maintaining the registration of running nodes, managing communication connections and service requests, etc., and also providing some monitoring and debugging functions.

  • Parameter Server (Parameter Server): It is a global parameter management component in ROS, which can share parameter data between different nodes, improving the reusability and scalability of the program. Parameter servers enable data to be stored at the core of a system by key. By using parameters, it is possible to dynamically configure the node or change the task of the node while the node is running. A parameter server is a shared, network-accessible multivariate dictionary that nodes use to store and retrieve parameters at runtime. For the command line tools of the parameter server in ROS, please see the following common commands.

    • rosparam list: Used to list all parameters in the parameter server.
    • rosparam get <parameter_name>: used to get the parameter value in the parameter server.
    • rosparam set <parameter_name> * : used to set the value of the parameter in the parameter server.
    • rosparam delete <parameter_name>: used to delete the parameter from the parameter server.
    • rosparam dump : used to save the parameters of the parameter server to a file.
    • rosparam load : Used to load parameters from a file to the parameter server.
  • Topic: It is a publish/subscribe mode communication mechanism in ROS, which is used to realize data interaction and data transmission between nodes. ROS provides command tools for operating themes, and some commonly used commands are listed here.

    • rostopic bw </topic_name>: Used to display the bandwidth used by the topic.
    • rostopic echo </topic_name>: used to output the message data in the topic to the screen. rostopic find <message_type>: Used to find topics by message type.
    • rostopic hz </topic_name>: Used to display the publishing frequency of the topic.
    • rostopic info </topic_name>: Used to output information about active topics, published topics, topic subscribers, and services. rostopic list: A list of currently active topics.
    • rostopic pub </topic_name> <message_type> : Used to publish data to a topic via the command line. rostopic type </topic_name>: used to output the message type published in the topic.
  • Service (Service): It is a request/response mode communication mechanism in ROS, which is used to implement function calls and parameter transfers between nodes.
    ROS provides command tools for operating services, and some commonly used commands are listed here.

    • rosservice call </service_name> : used to call the service via command line parameters.
    • rosservice find <service_type>: Used to query services by service type.
    • rosservice info </service_name>: used to output service information.
    • rosservice list: Used to list active services.
    • rosservice type </service_name>: used to output the service type.
    • rosservice uri </service_name>: ROSRPC URI for the output service.
  • Action: It is an advanced communication mechanism in ROS, which is used to realize complex interactive behaviors between nodes, such as controlling a robot to complete a series of actions.

  • Message (Message): It is a data structure format in ROS, which is used to transmit data in communication mechanisms such as topics, services, and behaviors. ROS provides command tools for obtaining message-related information. Here are some commonly used commands. Let’s take a look at them in detail.

    • rosmsg show <message_type>: The field used to display a message.
    • rosmsg list: used to list all messages.
    • rosmsg package : used to list all messages of the function package.
    • rosmsg packages: Used to list all function packages with this message.
    • rosmsg users <message_type>: Used to search for code files using this message type. rosmsg md5 <message_type>: used to display the MD5 summation result of a message.
  • ROS Tools (ROS Tools): ROS provides a series of tools for easy development, debugging and management, such as rqt, rqt_plot, rqt_graph, rviz, etc.

In addition, ROS also has a rich core module. Its core modules include: communication structure foundation, robot characteristic function, tool set. The basis of the communication structure is mainly message passing, recording and playback messages, remote procedure calls, and distributed parameter systems; the robot feature functions are mainly standard robot messages, robot geometry libraries, robot description languages, preemptive remote procedure calls, diagnosis, position estimation, and positioning Navigation; the tool set mainly includes imperative tools, visualization tools, and graphical interfaces.
ROS core tools are very rich, ROS common command tools are rostopic, rosservice, rosnode, rosparam, rosmsg, rossrv, roswtf; ROS common visualization tools are rqt, rviz; ROS tool for storing and playback data rosbag; ROS log system records Information about software operation; ROS also has powerful third-party tool support: 3D simulation environment Gazebo, computer vision library OpenCV, point cloud library PCL, robotic arm control library MoveIt, industrial application library Industrial, robot programming toolbox MRPT, real-time control Library Orocos.
The above are the main components in the ROS architecture. The core concept of ROS is mainly nodes and topics and services for inter-node communication. Working together, they form a powerful and flexible ROS system that can support a wide variety of robots and application domains. Some common ROS application areas include robot control, autonomous driving, smart home, healthcare, etc.

Understanding ROS architecture from the file system level

Understanding the ROS architecture at the file system level

The ROS file system is one of the key parts of the ROS architecture and is called a package. The package folder contains ROS nodes, themes, services, parameters and other robot related files. Each package can have subdirectories to organize its components. ROS nodes can communicate across packets.

The basic structure of the ROS file system is as follows:

  • /opt/ros//: ROS installation folder, which is the ROS version number.
  • ~/catkin_ws/: ROS workspace, usually located under the user's home folder. These include the src folder, build folder, and devel folder.
  • ~/catkin_ws/src/: The source code folder under the ROS workspace. Every ROS package must be placed in this directory.
  • ~/catkin_ws/build/: the compilation folder. This directory contains all intermediate files and build output generated when building and compiling ROS packages.
  • ~/catkin_ws/devel/: the concept of developers. This directory contains folders compiled from source files. Typically used for developing software for robots etc.

(1) Workspace

A workspace is a folder containing function packages, editable source files, and compilation packages . It is very useful when you want to compile different function packages at the same time, and you can save local development packages. Of course, users can create multiple workspaces according to their needs, and develop function packages for different purposes in each workspace. But as a study, let's take a workspace as an example. As shown above, a workspace named catkin_ws has been created, and there will be 3 folders under this workspace: src, build, and devel.

  • src source file space : This folder places each function package and a CMake configuration file CMakeLists.txt for these function packages. Let me explain here. Since the source code in ROS is compiled using the catkin tool, and the catkin tool is based on the cmake technology, we will see a file CMakeLists.txt in the src source file space and each function package. This file It is to play the role of compiling configuration.
  • build compilation space : This folder places the cache, configuration, intermediate files, etc. generated when CMake and catkin compile function packages.
  • devel development space : This folder contains compiled executable programs, which can be run directly without installation. Once the function package source code is compiled and tested, these compiled executable files can be directly exported to share with other developers.

(2) Feature Pack

In ROS, function packages are a standardized mechanism for organizing, managing, and sharing ROS programs and related resources. A ROS function package can contain the smallest unit of work of a ROS program, usually including ROS processes (nodes), published and subscribed messages, service definitions, parameter files, and other necessary files and resources. Packages are one of the fundamental building blocks of ROS's powerful and flexible architecture. As shown above, a function package mainly includes these files:

  • CMakeLists.txt function package configuration file: the configuration file used for this function package cmake compilation.
  • package.xml function package list file: use xml tag format to mark various related information of this function package, such as package name, dependency relationship, etc. The main role is to make it easier to install and distribute feature packages.
  • include/<package_name> function package header file directory : You can put the *.h header files included in your function package program here. The reason why you need to add a level path <package_name> under include is to better distinguish your own definitions Header files and system standard header files, <package_name> is replaced by the name of the actual function package.
  • msg Non-standard message definition directory : message is the information sent from one process (node) to other processes (nodes) in ROS. The message type is the data structure of the message. The ROS system provides many standard types of messages that can be used directly. If you want To use some non-standard types of messages, you need to define the type of messages yourself, and put the defined files here. However, this folder is not necessary, such as the case where only standard types of messages are used in the program.
  • srv service type definition directory : service is the request/response communication process between processes (nodes) in ROS, service type is the data structure of service request/response, and the definition of service type is placed here. If you want to call this service, you need to use the package name and service name. However, this folder is not necessary, such as the case where the service is not used in the program.
  • scripts Executable script file storage directory : This is used to store executable files of bash, python or other scripts. However, this folder is not necessary, such as the case where executable scripts are not used in the program.
  • Launch file directory : This is used to store *.launch files. *.launch files are used to start one or more nodes in the ROS function package, which is useful in large-scale projects with multiple node startups. However, this folder is not necessary, and the node can also be started without the launch file.
  • The node source file storage directory in the src function package : there can be multiple process (node) programs in a function package to complete different functions, each process (node) program can be run independently, here is used to store these processes ( Node) program source files, where you can create folders and files to organize source files according to your needs, source files can be written in c++, python, etc.
    In order to create, modify, and use function packages, ROS provides us with some practical tools, and the following tools are commonly used.
  • rospack : Used to get information or find workspaces in the system.
  • catkin_create_pkg : used to create a new function package under the src source space of the workspace. catkin_make: used to compile the function package in the workspace.
  • rosdep : System dependencies for installing feature packages.
  • rqt_dep : Used to view the dependency graph of a feature package.

(3) message

A sample message definition file
A message is the information sent by a process (node) to other processes (nodes) in ROS. The message type is the data structure of the message. The ROS system provides many standard types of messages that can be used directly. If you want to use some non-standard types of messages , you need to define this type of message yourself.
ROS uses a compact message type description language to describe data values ​​published by ROS processes (nodes). Through the definition of message types in this description language, ROS can use this message in programs written in different programming languages ​​(such as c++, python, etc.). Whether it is a standard type message provided by the ROS system or a user-defined non-standard type message, the definition file has an extension of *.msg. The definition of the message type is divided into two main parts: the data type of the field and the name of the field. Simply put, it is the variable type and variable name in the structure. For example, the content of the following example message definition file example.msg, as shown in the figure above, int32, float32, and string are the data types of the fields, and id, vel, and name are the names of the fields.

Topic

Topic communication is the most frequently used distributed communication mode in ROS, which is used to transmit real-time messages. A topic is a data stream object with a subscribe-publish model that allows nodes to communicate through asynchronous message transmission between them. That is: one node publishes a message, and another node subscribes to the message.
The collection of sensor data such as radar, camera, GPS, etc. also uses topic communication. In other words, topic communication is suitable for application scenarios related to continuously updated data transmission.

theoretical model

Is a named data channel through which messages are passed in communication. Topic name is the most important part in topic communication, it is used as a criterion for identification and linking. The model is shown in the figure below, and there are three roles involved in the model:

  • ROS Master (manager)
  • A Talker (publisher) is a ROS node that sends messages to one or more topics. Publishers use the ROS client library to publish messages to the ROS master and ask it to distribute the messages to the appropriate topics.
  • Listener (subscriber) In the subscriber node, the user can register a callback function to listen to the specified topic. Once a new message arrives at the topic, the callback function will be activated to receive and process the message.

ROS Master is responsible for keeping the registered information of Talker and Listener, matching Talker and Listener with the same topic, and helping Talker and Listener establish a connection. After the connection is established, Talker can publish messages, and the published messages will be subscribed by Listener.
topic communication model
Talker registration
After the Talker is started, it will register its own information in the ROS Master through RPC, which includes the topic name of the published message. ROS Master will add the registration information of the node to the registry.
Listener registration
After the Listener is started, it will also register its own information in the ROS Master through RPC, including the topic name that needs to subscribe to the message. ROS Master will add the registration information of the node to the registry.
ROS Master implements information matching
ROS Master will match Talker and Listener according to the information in the registry, and send Talker's RPC address information to Listener through RPC.
Listener sends a request to Talker
According to the received RPC address, Listener sends a connection request to Talker through RPC, and transmits the subscribed topic name, message type and communication protocol (TCP/UDP).
Talker confirms the request
After receiving the Listener's request, the Talker also confirms the connection information to the Listener through RPC, and sends its own TCP address information.
The Listener connects with the Talker in the software.
The Listener uses TCP to establish a network connection with the Talker according to the message returned in step 4.
Talker sends message to Listener
After the connection is established, the Talker starts publishing messages to the Listener.

Topic Communication Basic Operation A (C++)

To write a publish-subscribe implementation, the publisher is required to publish a text message at a frequency of 10HZ (10 times per second), and the subscriber subscribes to the message and prints out the message content.
process:

  • Write the publisher implementation;
  • Write a subscriber implementation;
  • Edit the configuration file;
  • Compile and execute.

It should be noted that this is a simple publisher program example, which is written based on the ROS C++ client library. The classes and library functions involved need to be correctly initialized, configured, constructed, and called, and it is necessary to ensure that the correct release process and related operations are implemented in the ROS system.
Message publishing and subscription ROS communication network structure diagramThe above figure is a message publishing and subscribing ROS communication network structure diagram

Publisher

/*
    需求: 实现基本的话题通信,一方发布数据,一方接收数据,
         实现的关键点:
         1.发送方
         2.接收方
         3.数据(此处为普通文本)

         PS: 二者需要设置相同的话题


    消息发布方:
        循环发布信息:HelloWorld 后缀数字编号

    实现流程:
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 发布者 对象
        5.组织被发布的数据,并编写逻辑发布数据

*/
// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>

int main(int argc, char  *argv[])
{
    
       
    //设置编码
    setlocale(LC_ALL,"");

    //2.初始化 ROS 节点:命名(唯一)
    // 参数1和参数2 后期为节点传值会使用
    // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
    ros::init(argc,argv,"talker");
    //3.实例化 ROS 句柄
    ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能

    //4.实例化 发布者 对象
    //泛型: 发布的消息类型
    //参数1: 要发布到的话题
    //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);

    //5.组织被发布的数据,并编写逻辑发布数据
    //数据(动态组织)
    std_msgs::String msg;
    // msg.data = "你好啊!!!";
    std::string msg_front = "Hello 你好!"; //消息前缀
    int count = 0; //消息计数器

    //逻辑(一秒10次)
    ros::Rate r(1);

    //节点不死
    while (ros::ok())
    {
    
    
        //使用 stringstream 拼接字符串与编号
        std::stringstream ss;
        ss << msg_front << count;
        msg.data = ss.str();
        //发布消息
        pub.publish(msg);
        //加入调试,打印发送的消息
        ROS_INFO("发送的消息:%s",msg.data.c_str());

        //根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;
        r.sleep();
        count++;//循环结束前,让 count 自增
        //暂无应用
        ros::spinOnce();
    }


    return 0;
}

Subscriber

// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h"

void doMsg(const std_msgs::String::ConstPtr& msg_p){
    
    
    ROS_INFO("我听见:%s",msg_p->data.c_str());
    // ROS_INFO("我听见:%s",(*msg_p).data.c_str());
}
int main(int argc, char  *argv[])
{
    
    
    setlocale(LC_ALL,"");
    //2.初始化 ROS 节点:命名(唯一)
    ros::init(argc,argv,"listener");
    //3.实例化 ROS 句柄
    ros::NodeHandle nh;

    //4.实例化 订阅者 对象
    ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
    //5.处理订阅的消息(回调函数)

    //     6.设置循环调用回调函数
    ros::spin();//循环读取接收的数据,并调用回调函数处理

    return 0;
}

Configure CMakeLists.txt
First, add_executable is used to create executables. In this example, it creates two executables Hello_pub and Hello_sub respectively. src/Hello_pub.cpp and src/Hello_sub.cpp are the source codes of the two executable files respectively.

Then, target_link_libraries is used to link the required libraries. ${catkin_LIBRARIES} is a variable that refers to all libraries that need to be linked in ROS.

What this code does is create two executables in the ROS workspace and link ${catkin_LIBRARIES} as a link library. These executables may be ROS nodes or other forms of programs.

//发布者的可执行文件的源代码
add_executable(Hello_pub
  src/Hello_pub.cpp
)
//订阅者的可执行文件的源代码
add_executable(Hello_sub
  src/Hello_sub.cpp
)

//发布者所需的链接库
target_link_libraries(Hello_pub
  ${
    
    catkin_LIBRARIES}
)
//订阅者所需的链接库
target_link_libraries(Hello_sub
  ${
    
    catkin_LIBRARIES}
)

#! /usr/bin/env python
"""
    需求: 实现基本的话题通信,一方发布数据,一方接收数据,
         实现的关键点:
         1.发送方
         2.接收方
         3.数据(此处为普通文本)

         PS: 二者需要设置相同的话题


    消息发布方:
        循环发布信息:HelloWorld 后缀数字编号

    实现流程:
        1.导包 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 发布者 对象
        4.组织被发布的数据,并编写逻辑发布数据


"""
#1.导包 
import rospy
from std_msgs.msg import String

if __name__ == "__main__":
    #2.初始化 ROS 节点:命名(唯一)
    rospy.init_node("talker_p")
    #3.实例化 发布者 对象
    pub = rospy.Publisher("chatter",String,queue_size=10)
    #4.组织被发布的数据,并编写逻辑发布数据
    msg = String()  #创建 msg 对象
    msg_front = "hello 你好"
    count = 0  #计数器 
    # 设置循环频率
    rate = rospy.Rate(1)
    while not rospy.is_shutdown():

        #拼接字符串
        msg.data = msg_front + str(count)

        pub.publish(msg)
        rate.sleep()
        rospy.loginfo("写出的数据:%s",msg.data)
        count += 1

#! /usr/bin/env python
"""
    需求: 实现基本的话题通信,一方发布数据,一方接收数据,
         实现的关键点:
         1.发送方
         2.接收方
         3.数据(此处为普通文本)


    消息订阅方:
        订阅话题并打印接收到的消息

    实现流程:
        1.导包 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 订阅者 对象
        4.处理订阅的消息(回调函数)
        5.设置循环调用回调函数



"""
#1.导包 
import rospy
from std_msgs.msg import String

def doMsg(msg):
    rospy.loginfo("I heard:%s",msg.data)

if __name__ == "__main__":
    #2.初始化 ROS 节点:命名(唯一)
    rospy.init_node("listener_p")
    #3.实例化 订阅者 对象
    sub = rospy.Subscriber("chatter",String,doMsg,queue_size=10)
    #4.处理订阅的消息(回调函数)
    #5.设置循环调用回调函数
    rospy.spin()

catkin_install_python(PROGRAMS
  scripts/talker_p.py
  scripts/listener_p.py
  DESTINATION ${
    
    CATKIN_PACKAGE_BIN_DESTINATION}
)

Topic communication custom msg
In the ROS communication protocol, the data carrier is an important part. ROS encapsulates some native data types through std_msgs, such as: String, Int32, Int64, Char, Bool, Empty... However, these data Generally, it contains only one data field. The single structure means functional limitations. When transmitting some complex data, such as: lidar information... std_msgs is not enough due to its poor descriptiveness. In this scenario, you can use custom message type.

In ROS, custom message types are defined in .msg files. The file contains the type and name of one or more fields, and a message name. After saving the message definition into the msg file, you need to add the necessary information in your CMakeLists.txt file and package.xml for the message to take effect.
In ROS, custom messages are usually composed of different primitive types. The following are the basic types supported by custom messages in ROS:

Integers : Integer types, including byte, char, int8, int16, int32 and int64.

Floating point numbers : Floating point numbers, including float32 and float64.

Boolean values ​​: Boolean type, only two values: True or False.

Strings : string type, including string.

Time and duration : Time and time interval types in ROS, including time and duration.

Arrays : Array type, also known as sequence, including types enclosed in angle brackets <> (for example: int16[]).

Fixed-length arrays : Fixed-length array types, also known as arrays, are enclosed in curly braces {}, followed by them, where n is the length of the array (for example: int16{4}).

Header : The message header in ROS, including std_msgs/Header. Contains timestamp and coordinate frame information commonly used in ROS. It is common to see that the first line of a msg file has a Header header.

First, create an empty package to store the msg type separately (of course, you can also customize the msg type in any package). Here, for the convenience of explanation, create a package named test_msgs for examples of the usage of the custom msg type.

Process:
Create a new msg file
and then create a msg folder in test_msgs, and create a new message type file named Test.msg in the msg folder

$ cd catkin_ws/src
$ catkin_create_pkg test_msgs

$ cd test_msgs
$ mkdir msg

Contents of Test.msg

float32[] data
float32 vel
geometry_msgs/Pose pose
string name

After modifying package.xml,
message_generation is required to generate code that can be used by C++ or Python, and message_runtime is required to provide runtime support, so add the following two sentences to package.xml

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

Modify CMakeLists.txt
Modify CMakeLists.txt
CMakeLists.txt should pay attention to four places

(1) First call find_package to find dependent packages, roscpp rospy message_generation is necessary, and others are added according to specific types. For example, geometry_msgs/Pose pose type is used in the above msg file, then geometry_msgs must be searched

find_package(catkin REQUIRED COMPONENTS roscpp rospy message_generation std_msgs geometry_msgs)

(2) Then add_message_files, specify the msg file

add_message_files(
  FILES
  Test.msg
  # Message2.msg
)

(3) Then generate_messages specifies the dependencies when generating message files. For example, if other message types geometry_msgs are nested above, then it must be specified

#generate_messages必须在catkin_package前面
generate_messages(
 DEPENDENCIES
 geometry_msgs
)

(4) Then catkin_package sets the running dependencies

catkin_package(

CATKIN_DEPENDS message_runtime

)

compile

slightly

Note : To use a custom message type, you must source the workspace where the custom message is located. Otherwise, rosmsg show test_msgs/Test and rostopic echo /test_msg (/test_msg is a topic that uses the custom message type test_msgs/Test in the node) will report an error. Since custom message types are invisible without source, they are considered undefined types

To be continued!

Guess you like

Origin blog.csdn.net/qq_38915354/article/details/130175254