Cyber-话题通信

 

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


    流程
        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"
    ]
)

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

 

 

话题通信编译通过的源码

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[]) {

    apollo::cyber::Init(argv[0]);
    AINFO << "init...";
    auto talker_node = apollo::cyber::CreateNode("talker_node");
    auto talker = talker_node->CreateWriter<Student>("chatter");

    apollo::cyber::Rate rate(0.5);

    int seq = 0;
    while(apollo::cyber::OK())
    {
        ++seq;
        auto msg = std::make_shared<Student>();
        msg->set_name("lisi");
        msg->set_age(seq);
        msg->set_height(1.75);
        msg->add_books("yingyu");
        msg->add_books("shuxue");


        AINFO << "send message: " << "name " << msg->name() << ", age " << msg->age() << ", height " << msg->height();
        
        talker->Write(msg);
        rate.Sleep();
    }

    apollo::cyber::WaitForShutdown();


    return 0;
}

 

listener.cc

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

void callback(const std::shared_ptr<Student>& stu){

    std::string name = stu->name();
    std::uint64_t age = stu->age();
    double height = stu->height();

    AINFO << "recv message: " << "name " << name << ", age " << age << ", height " << height;
    for(int i = 0; i < stu->books_size(); i++){
        AINFO << stu->books(i);
    }
    AINFO << "-------------------------------------";


}



int main(int argc,  char* argv[]) {

    apollo::cyber::Init(argv[0]);
    AINFO << "init...";

    auto listener_node = apollo::cyber::CreateNode("listener_node");
    auto listener = listener_node->CreateReader<Student>("chatter", callback);


    apollo::cyber::WaitForShutdown();

    return 0;

}

 

BUILD

cc_binary(

    name = "talker_cc_bin",
    srcs = ["talker.cc"],
    deps = ["//cyber",
            "//cyber/demo_base_proto:student_proto_cc_lib"],

)

cc_binary(
    name = "listener_cc_bin",
    srcs = ["listener.cc"],
    deps = ["//cyber",
            "//cyber/demo_base_proto:student_proto_cc_lib"],


)

 

posted @ 2023-07-09 22:05  WTSRUVF  阅读(25)  评论(0)    收藏  举报