ROS (Topic Communication) Publish-Subscribe-Kommunikationsmechanismus

1. Veröffentlichung und Abonnement von ROS-Basisdatentypen

std_msgs in ROS enthält viele grundlegende Datentypen. Die Veröffentlichung und das Abonnement grundlegender Datentypen werden über die Datentypen in std_msgs implementiert (benutzerdefinierte Datentypen folgen).

Die in std_msgs enthaltenen Datentypen können durch Eingabe von „rosmsg list“ im Terminal angezeigt werden. Hier sind einige grundlegende Datentypen, die in std_msgs enthalten sind:

std_msgs/Bool
std_msgs/Byte
std_msgs/ByteMultiArray
std_msgs/Char
std_msgs/ColorRGBA
std_msgs/Dauer std_msgs /
Leer
std_msgs/Float32
std_msgs/Float32MultiArray
std_msgs/Float64
std_msgs/ Float64MultiArray
std_msgs/Header
std_msgs/Int16
std_msgs/Int16MultiArray
std_msgs/Int32
std_msgs/Int32MultiArray
std_msgs/ Int64
std_msgs/Int64MultiArray
std_msgs/Int8
std_msgs/Int8MultiArray
std_msgs/MultiArrayDimension
std_msgs/MultiArrayLayout
std_msgs/String
std_msgs/Time
std_msgs/UInt16
std_msgs/UInt16MultiArray
std_msg s/UInt32 std_msgs/
UInt32MultiArray
std_msgs/UInt64
std_msgs/UInt64MultiArray
std_msgs/UInt8
std_msgs/UInt8MultiArray

1. Veröffentlichen und Abonnieren des ROS-String-Datentyps

1.1 Publisher-Implementierung

#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char *argv[])
{
    //乱码问题的解决
    setlocale(LC_ALL,"");
    //初始化ROS节点
    ros::init(argc,argv,"pubNode");
    //句柄
    ros::NodeHandle nh;
    //发布对象的创建
    ros::Publisher pub;
    pub = nh.advertise<std_msgs::String>("string",100);
    //发布频率的设置
    ros::Rate rate(1); //一秒一次

    //创建待发布消息对象
    std_msgs::String pubString;
    std::string str1 = "第";
    std::string str2 = "次发送!";

    int8_t number = 1;

    while(ros::ok())
    {
        //组织消息
        std::stringstream ss;
        ss<< str1 << std::to_string(number) <<str2;
        pubString.data = ss.str();
        //发布
        pub.publish(pubString);
        rate.sleep();
        number++;
    }
    return 0;
}

1.2 Abonnentenimplementierung

#include "ros/ros.h"
#include "std_msgs/String.h"

void doMsg(const std_msgs::String::ConstPtr& msg)
{
    ROS_INFO("订阅到的消息为:%s",msg->data.c_str());
}

int main(int argc, char *argv[])
{
    //乱码问题的解决
    setlocale(LC_ALL,"");
    //初始化ROS节点
    ros::init(argc,argv,"subNode");
    //句柄
    ros::NodeHandle nh;
    //发布对象的创建
    ros::Subscriber sub;
    sub = nh.subscribe<std_msgs::String>("string",100,doMsg);
    //回旋函数
    ros::spin();
    return 0;
}

1.3 Startdatei

<launch>
    <node pkg="string_pub_sub" type="demo_pub" name="pub" output="screen"/>
    <node pkg="string_pub_sub" type="demo_sub" name="sub" output="screen"/>
</launch>

2. Veröffentlichung und Abonnement von ROS-Kunststoffdatentypen

Ganzzahlige Daten werden in int8, uint8, int16, uint16 usw. unterteilt. Unterschiedliche Längen verwenden bei der Implementierung von Publish und Subscribe nur unterschiedliche Datentypen in std_msgs. Hier wird int8 als Beispiel verwendet.

2.1 Publisher-Implementierung

#include "ros/ros.h"
#include "std_msgs/Int8.h"

int main(int argc, char  *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc, argv, "pub");
    //句柄
    ros::NodeHandle nh;
    //初始化发布者对象
    ros::Publisher pub;
    pub = nh.advertise<std_msgs::Int8>("intPub",100);
    //组织数据
    int8_t number = 1;
    //设置发布频率
    ros::Rate rate(1); //一秒一次

    while(ros::ok())
    {
        //组织发布数据
        std_msgs::Int8 dataPub;
        dataPub.data = number;
        //发布
        pub.publish(dataPub);
        //休眠
        rate.sleep();  
        //自增
        number++;     
    }


    return 0;
}

2.2 Abonnentenimplementierung

#include "ros/ros.h"
#include "std_msgs/Int8.h"

void doMsg(const std_msgs::Int8::ConstPtr& msg)
{
    ROS_INFO("接受到的消息为:%d",msg->data);
}

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"sub");
    //句柄
    ros::NodeHandle nh;
    //订阅方对象
    ros::Subscriber sub;
    sub = nh.subscribe<std_msgs::Int8>("intPub",100,doMsg);
    //回旋
    ros::spin();
    return 0;
}

Startdatei

<launch>
    <node pkg="int_pub_sub" type="demo_pub_int" name="pub" output="screen"/>
    <node pkg="int_pub_sub" type="demo_sub_int" name="sub" output="screen"/>
</launch>

3. Veröffentlichen und Abonnieren von ROS-Gleitkomma-Datentypen

3.1 Publisher-Implementierung

#include "ros/ros.h"
#include "std_msgs/Float32.h"

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"pub");
    //句柄
    ros::NodeHandle nh;
    //创建发布者对象
    ros::Publisher pub;
    pub = nh.advertise<std_msgs::Float32>("floatPub",100);
    //发布频率设置
    ros::Rate rate(1);
    
    double number = 1.0;

    while(ros::ok())
    {
        //组织发布消息
        std_msgs::Float32 pubData;
        pubData.data = number;
        //发布
        pub.publish(pubData);
        //自增
        number = number +0.1;
        rate.sleep();
    }

    return 0;
}


3.2 Abonnentenimplementierung

#include "ros/ros.h"
#include "std_msgs/Float32.h"

void domsg(const std_msgs::Float32::ConstPtr& msg)
{
    ROS_INFO("接收到的消息为%.2f",msg->data);
}

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"pub");
    //句柄
    ros::NodeHandle nh;
    //创建订阅者对象
    ros::Subscriber sub;
    sub = nh.subscribe<std_msgs::Float32>("floatPub",100,domsg);
    ros::spin();
    return 0;
}

Startdatei

<launch>
    <node pkg="flaoat_pub_sub" type="demo_pub_float" name="pub" output="screen"/>
    <node pkg="flaoat_pub_sub" type="demo_sub_float" name="sub" output="screen"/>
</launch>

4. Veröffentlichen und Abonnieren von booleschen ROS-Datentypen

4.1 Publisher-Implementierung

#include "ros/ros.h"
#include "std_msgs/Bool.h"

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码问题
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"pub");
    //句柄
    ros::NodeHandle nh;
    //发布者对象
    ros::Publisher pub;
    pub = nh.advertise<std_msgs::Bool>("boolPub",100);
    //发布频率
    ros::Rate rate(1);
    //组织数据
    bool boolData =0;

    while(ros::ok())
    {
        //组织被发布数据
        std_msgs::Bool boolPub;
        boolPub.data = boolData;
        //发布数据
        pub.publish(boolPub);
        //反转
        if (boolData==1)
        {
            boolData = 0;
        }
        else
        {
            boolData = 1;
        }
        //休眠
        rate.sleep();
    }



    return 0;
}

4.2 Abonnentenimplementierung

#include "ros/ros.h"
#include "std_msgs/Bool.h"

void doMsg(const std_msgs::Bool::ConstPtr& msg)
{
    if(msg->data == 1)
    {
        ROS_INFO("接收到的消息为真");
    }
    else
    {
        ROS_INFO("接收到的消息为假");
    }
}

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码问题
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"pub");
    //句柄
    ros::NodeHandle nh;
    //订阅者对象
    ros::Subscriber sub;
    sub = nh.subscribe<std_msgs::Bool>("boolPub",100,doMsg);
    ros::spin();

    return 0;
}

Startdatei

<launch>
    <node pkg="bool_pub_sub" type="demo_pub_bool" name="pub" output="screen"/>
    <node pkg="bool_pub_sub" type="demo_sub_bool" name="sub" output="screen"/>
</launch>

2. Veröffentlichen und Abonnieren von benutzerdefinierten ROS-Datentypen

std_msgs kapselt einige häufig verwendete Datentypen. In tatsächlichen Anwendungen können jedoch einige Nachrichtentypen entsprechend den Anforderungen des Projekts angepasst werden. Daher ist es erforderlich, benutzerdefinierte Nachrichten erstellen zu können.

1. Verwandte Konfigurationen

1.1 Msg-Datei definieren

Erstellen Sie den msg-Ordner unter dem Funktionspaket und fügen Sie die .msg-Datei im Ordner hinzu

Beispiel:

Veröffentlichen Sie die Nachricht eines Kontakts, die Name, Geschlecht, Telefonnummer, Adresse (die ersten vier sind String-Typen), Alter (Int-Typ) und Größe (Float-Typ) enthält.

string name
string gender
string phoneNumber
string addres
int8 age
float32 height

1.2 Konfigurationsdatei bearbeiten

Fügen Sie Kompilierungsabhängigkeiten und Ausführungsabhängigkeiten in der Datei package.xml hinzu

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

1.3 CMakeList.txt Nachrichtenbezogene Konfiguration bearbeiten

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必须有 std_msgs

## 配置 msg 源文件
add_message_files(
  FILES
  Person.msg #自定义的文件名称
)

# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)

#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime # 新加message_runtime
#  DEPENDS system_lib
)

1.4 Zusammenstellung

Kompilierte Zwischendateien anzeigen

Fügen Sie hier eine Bildbeschreibung ein

1.5 vscode-Konfiguration

Um Code-Eingabeaufforderungen zu erleichtern und falsche Ausnahmen zu vermeiden, müssen Sie zuerst vscode konfigurieren. Um Code-Eingabeaufforderungen zu erleichtern und falsche Ausnahmen zu vermeiden, müssen Sie zuerst vscode konfigurieren und den zuvor generierten Head-Dateipfad im Includepath-Attribut von c_cpp_properties konfigurieren .json:

Hinweis: Um den Pfad anzuzeigen, können Sie mit der rechten Maustaste auf den Include-Ordner der generierten Zwischendatei klicken, „In integriertem Terminal öffnen“ auswählen, dann den Befehl „pwd“ in das Terminal eingeben und dann den Pfad kopieren. Achten Sie darauf „/**“ nach include. Verstanden

Fügen Sie hier eine Bildbeschreibung ein

{
    
    
    "configurations": [
        {
    
    
            "browse": {
    
    
                "databaseFilename": "",
                "limitSymbolsToIncludedHeaders": true
            },
            "includePath": [
                "/opt/ros/noetic/include/**",
                "/usr/include/**",
                "/xxx/yyy工作空间/devel/include/**", //配置 head 文件的路径 
                "/home/wang/demo03_ws/devel/include/**",//例子
            ],
            "name": "ROS",
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

2. Publisher-Implementierung

#include "ros/ros.h"
#include "msg_pub_sub/Person.h"

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"pub");
    //句柄
    ros::NodeHandle nh;
    //创建发布者对象
    ros::Publisher pub;
    pub = nh.advertise<msg_pub_sub::Person>("msgPub",100);
    //组织发布消息
    msg_pub_sub::Person person;
    person.age = 18;
    person.addres = "ubuntu路ros小区msg号";
    person.gender = "男";
    person.height = 1.88;
    person.name = "msgPubSub";
    person.phoneNumber = "12345678910";

    //发布频率
    ros::Rate rate(1);

    while(ros::ok())
    {
        pub.publish(person);
        rate.sleep();
    }



    return 0;
}

3. Abonnentenimplementierung

#include "ros/ros.h"
#include "msg_pub_sub/Person.h"


void doMsg(const msg_pub_sub::Person::ConstPtr& msg)
{
    ROS_INFO("联系人的姓名:%s",msg->name.c_str());
    ROS_INFO("联系人的地址:%s",msg->addres.c_str());
    ROS_INFO("联系人的性别:%s",msg->gender.c_str());
    ROS_INFO("联系人的电话:%s",msg->phoneNumber.c_str());
    ROS_INFO("联系人的年龄:%d",msg->age);
    ROS_INFO("联系人的身高:%.2f",msg->height);
    
}

int main(int argc, char *argv[])
{
    /* code */
    //解决乱码
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"sub");
    //句柄
    ros::NodeHandle nh;
    //创建发布者对象
    ros::Subscriber sub;
    sub = nh.subscribe<msg_pub_sub::Person>("msgPub",100,doMsg);
    ros::spin();
}


4. Datei starten

<launch>
    <node pkg="msg_pub_sub" type="demo_pub_msg" name="pub" output="screen"/>
    <node pkg="msg_pub_sub" type="demo_sub_msg" name="sub" output="screen"/>
</launch>

Supongo que te gusta

Origin blog.csdn.net/weixin_49216787/article/details/132655918
Recomendado
Clasificación