Cyber RT 话题通信

发布时间:2024年01月22日

Cyber RT中最为核心实现:通信机制。
所谓通信机制就是如何在不同的单元或模块之间传输数据,比如:雷达、摄像头、GPs(、地图、车辆控制、车辆参数、车辆目的地…这些消息是以何种方式在不同模块之间传输的,不同传输方式又有怎样的应用场景等等。

话题通信

场景: 无人车上整合了诸多传感器,比如:雷达,雷达驱动被启动后,就会不间断的感知环境并实时产生相关数据,产生的数据需要被接收然后继续处理转换成业务所需的障碍物信息。
在这一过程中,传感器的数据发布;用于实现二次处理的程序接收数据;同理,像摄像头、GPS、imu、车辆控制…相关的消息的发布和接收…
上述场景下便可以使用话题通信实现数据传输。

概念: 以发布订阅的方式实现不同节点之间数据交互的通信模式。

作用: 用于不断更新的,少逻辑处理的数据传输场景。

需求: 实现发布订阅模型,要求发布方可以循环发送消息,订阅方可以订阅到发布方的消息,并解析将结果在终端输出。

流程:
大致基本步骤:
1.编写消息载体(protobuf文件)并配置;
2.编写发布方并配置;
3.编写订阅方并配置;
4.编译执行。

C++ 实现

1.发布方实现
1.demo_cc 目录下新建C++文件 demo01_talker.cc,输入如下内容:

/*
    1.包含头文件
    2.初始化 cyber 框架
    3.创建节点
    4.创建发布者
    5.组织数据并发布
    6.等待关闭
*/
#include "cyber/cyber.h"
#include "cyber/demo_base_proto/student.pb.h"

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

int main(int argc, char const *argv[])
{
    apollo::cyber::Init(argv[0]);
    
    //创建节点
    auto talker_node = apollo::cyber::CreateNode("ergou");
    //创建发布者
    auto talker = talker_node->CreateWriter<Student>("chatter");
    //组织相关数据并发布
    uint64_t seq = 0;//计时器
    apollo::cyber::Rate rate(0.5);
    while (apollo::cyber::OK){  //判断节点是否正在运行
        seq++;
        AINFO <<"发布第"<<seq<<"条数据!"<<std::endl;

        //组织数据
        auto msg=std::make_shared<Student>();
        msg->set_name("feng");
        msg->set_age(seq);
        msg->set_height(120.0);
        msg->add_books("chinese");
        msg->add_books("math");
        msg->add_books("english");

        //发布
        talker->Write(msg);
        rate.Sleep();
    }
    //等待关闭
    apollo::cyber::WaitForShutdown();

    return 0;
}

2.编写 BUILD 文件

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

3.编译与执行

在这里插入图片描述

使用工具进行监听:

cyber_channel echo chatter

在这里插入图片描述

2.订阅方实现
1.demo_cc目录下新建 demo02_listener.cc,输入如下内容:

/*
    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 const *argv[])
{
    //初始化
    apollo::cyber::Init(argv[0]);
    AINFO <<"订阅方创建......";
    //创建节点
    auto listener_node = apollo::cyber::CreateNode("fei");
    //订阅方
    auto listener = listener_node->CreateReader<Student>("chatter",cb);
    //回调函数处理数据
    //等待关闭
    apollo::cyber::WaitForShutdown();


    return 0;
}

2.BUILD 文件

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

3.编译与执行
在这里插入图片描述

python 实现

1.发布方实现
1.demo_py 目录下创建 python 文件 demo01_talker_py.py,输入以下内容:

#!/usr/bin/env python3

"""
1.导包
2.初始化
3.创建节点
4.创建发布方
5.组织并发送数据
6.等待关闭
"""

from cyber.python.cyber_py3 import cyber
from cyber.demo_base_proto.student_pb2 import Student
import time

def talk():
    # 创建节点
    talker_node = cyber.Node("ergou_py")
    # 创建发布方
    talker  = talker_node.create_writer("chatter",Student)
    # 组织并发送数据
    seq = 0
    while not cyber.is_shutdown():
        seq += 1
        print("send message %d" % seq)
        stu = Student()
        stu.name = "Feng"
        stu.age = seq
        stu.height = 120.0
        stu.books.append("Chinese")
        stu.books.append("Math")
        stu.books.append("English")
        
        talker.write(stu)
        time.sleep(1.0)

if __name__ == "__main__":
    cyber.init()
    talk()
    cyber.shutdown()

2.BUILD 文件

py_binary(
    name = "demo01_talker_py",
    srcs = ["demo01_talker_py.py"],
    deps = [
        "//cyber/python/cyber_py3:cyber",
        "//cyber/demo_base_proto:student_py"
    ],
)

3.编译并执行
在这里插入图片描述
2.订阅方实现
1.demo_py 目录下创建 python 文件 demo02_listener_py.py,输入以下内容:

#!/usr/bin/env python3

"""
1.导包
2.初始化
3.创建节点
4.创建订阅方
5.处理数据
6.等待关闭
"""

from cyber.python.cyber_py3 import cyber
from cyber.demo_base_proto.student_pb2 import Student

def cb(stu):
    print("name = %s age = %d height = %.2f" % (stu.name,stu.age,stu.height))
    for book in stu.books:
        print("books: %s" %book)
    print("-"*30)

def listen():
    listener_node = cyber.Node("Feng_py")
    listener = listener_node.create_reader("chatter",Student,cb)
    listener_node.spin()

if __name__ == "__main__":
    cyber.init()
    listen()
    cyber.shutdown()

2.BUILD

py_binary(
    name = "demo02_listener_py",
    srcs = ["demo02_listener_py.py"],
    deps = [
        "//cyber/python/cyber_py3:cyber",
        "//cyber/demo_base_proto:student_py"
    ],
)

3.编译与执行
在这里插入图片描述

解耦合:可以使用C++的listener 和 python 的 talker,反之亦可

文章来源:https://blog.csdn.net/FDS99999/article/details/135681967
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。