话题通信

发布时间 2023-07-09 22:13:50作者: WTSRUVF

 

/*
    话题通信:传感器与处理程序之间的通信
        以发布订阅的方式实现不同节点之间数据交互的通信方式
        用于不断更新的、少逻辑处理的数据传输场景
*/
/*
    需求
        实现发布订阅模型,要求发布方可以周期性的循环发送学生信息,订阅方可以订阅到学生信息,
        并解析将结果在终端输出


    流程
        1.编写消息载体(protobuf)并配置
        2.编写发布方并配置
        3.编写订阅方并配置
        4.编译并执行
*/


////////////////////student.proto//////////////////////////

syntax = "proto2";

package apollo.cyber.demo_base_proto;

message Student{

    required string name = 1;
    optional uint64 age = 2;
    optional uint64 height = 3;
    repeated string books = 4;

}
//////////////////////////////////////////////////////////

/////////////////////student.proto  BUILD文件/////////////

proto_library(
    name = "student_proto",
    srcs = ["student.proto"]
)

cc_library(
    name = "student_cc",
    deps = ["student_proto"]
)

//////////////////////////////////////////////////////////


////////////////////发布方cpp/////////////////////////////

// 在demo_cc目录下新建c++文件demo01_talker.cc

#include "cyber/cyber.h"
#include "cyber/demo_base_proto/student.pb.h"

using apollo::cyber::demo_base_proto::Student;

int main(int argc, char* argv[])
{
    // 创建节点
    auto talker_node = apollo::cyber::CreateNode("ergou");

    // 创建发布者
    auto talker = talker_node->CreateWriter<Student>("chatter"); // chatter是话题名称,通过话题名称可以将发布者和订阅者关联到一起

    // 计数器
    uint64_t seq = 0;

    // 组织数据并发布

    apollo::cyber::Rate rate(0.5); // 发布频率,0.5表示2s一次
    while(apollo::cyber::OK())
    {
        ++seq;
        AINFO << "发布第 " << seq << " 条数据!"; // 有日志的话,别忘了刷新环境变量,不然不会在终端输出

        auto msg = std::make_shared<Student>();

        msg->set_name("zhangsan");
        msg->set_age(seq);
        msg->set_height(1.76);
        msg->add_books("chinese");
        msg->add_books("math");
        msg->add_books("english");


        // 发布
        talker->Write(msg);
        rate.Sleep(); // 发布频率生效

    }

    // 等待关闭,并释放资源
    apollo::cyber::WaitForShutdown();



    return 0;
}

////////////////////////////////////////////////////////


/////////////////////发布方demo01_talker.cc的BUILD//////

cc_binary(
    name = "demo01_talker_cc",
    src = ["demo01_talker.cc"],
    deps = [
    "//cyber",
    "//cyber/demo_base_proto:student_cc"]  //  //表示根目录下的文件
)

///////////////////////////////////////////////////////

///////////////////////////订阅方cpp///////////////////

/*
    1.包含头文件
    2.初始化
    3.创建节点
    4.创建订阅方
    5.回调函数处理数据
    6.等待关闭

*/



#include "cyber/cyber.h"
#include "cyber/demo_base_proto/student.pb.h"
using apollo::cyber::demo_base_proto::Student;

// 回调函数
void cb(const std::shared_ptr<Student>& stu)
{
    AINFO << "name: " << stu->name();
    AINFO << "age: " << stu->age();
    AINFO << "height: " << stu->height();

    for(int i = 0; i < stu->books_size(); i++)
    {

        AINFO << "books: " << stu->books(i);

    }

    AINFO << "-------------------------------";

}


int main(int argc, char* argv[])
{
    // 创建节点
    auto listener_node = apollo::cyber::CreateNode("smallming");
    auto listener = listener_node->CreateReader<Student>("chatter", cb); // 创建订阅方,参数为话题、回调函数

    // 回调函数处理数据

    // 等待关闭
    apollo::cyber::WaitForShutdown();


    return 0;
}
/////////////////////////发布方BUILD////////////////////////////////////


cc_binary(
    name = "demo02_listener",
    srcs = ["demo02_listener.cc"]
    deps = [
    "//cyber",
    "//cyber//demo_base_proto:student_cc"
    ]
)

///////////////////////////////////////////////////////////////////////