Cyber RT 组件

news2024/10/6 20:32:49

场景

无人车上的传感器数据可能需要被融合,比如在车辆上安装了多颗雷达,不同雷达由于安装位置与自身参数差异,可探测的角度、范围、距离等都是不尽相同的,现在需要将不同雷达感知到的数据融合在一起以建立车辆所处的完整环境,可以使用组件实现数据融合。

概念

组件是 Cyber RT 提供的用于构建应用程序模块的基类,

作用

可用于实现数据过滤、融合。

实例1

需求:启动之前的消息发布节点,对订阅到的数据进行过滤,只获取其中的姓名和年龄信息并输出到终端

准备:保证之前话题通信中的发布方可以正常运行;在 demo_cc 目录下新建文件夹:component_common01,并在 component_common01 下新建BUILD文件。

实现流程
上述需求可以通过组件实现只要包括如下步骤:
1.自定义类继承 Component类,并重写其 Init()与 Proc() 函数;
2.编写 dag 文件声 launch 文件;
3.编辑BUILD文件;
4.编译执行。

1.继承并重写 Component 类

component_common01 目录下新建 C++ 文件 common_cpt.h,输入如下内容:

/*
    编写一个Student学生信息过滤组件
    实现:
    1 包含被依赖的其他头文件
    2 自定义继承 compoenent
    3 在 cyberRT 中 注册组建
*/
//1 包含被依赖的其他头文件
#include "cyber/component/component.h"
#include "cyber/demo_base_proto/student.pb.h"

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

//2 自定义继承 compoenent

/*
    1. Component 模板需要与处理的消息类型一致;
    2.最多支持四种通道数据
*/

class CommonCpt : public  Component<Student> {
    public:
        bool Init() override;
        bool Proc(const std::shared_ptr<Student> & stu) override;
};
    //3 在 cyberRT 中 注册组建

CYBER_REGISTER_COMPONENT(CommonCpt)

component_common01 目录下新建 C++ 文件 common_cpt.cc,输入如下内容:

#include "cyber/demo_cc/component_common01/common_cpt.h"

//初始化函数
bool CommonCpt::Init(){
    AINFO<<"-----------Init-------------";
    return true;
}

//消息处理,订阅到 Student 消息时,会调用该函数
bool CommonCpt::Proc(const std::shared_ptr<Student> & stu){
    //处理逻辑
    AINFO<<"name = "<<stu->name()<<"; age = "<<stu->age();
    return true;
}

BUILD 文件

cc_library(
    name="common_cpt_lib",
    srcs=["common_cpt.cc"],
    hdrs=["common_cpt.h"],
    deps=[
        "//cyber",
        "//cyber/demo_base_proto:student_cc"
        ]
)

cc_binary(
    name = "lib_common_cpt.so",
    deps = [":common_cpt_lib"],
    linkshared = True,
    linkstatic = False,

)

使用的模板与订阅的消息类型一致,
Init()函数是用于初始化的,只会执行一次。
proc()函数在订阅到消息时就会被回调执行。

2.编写 dag 文件与 launch 文件
在 component_common01 目录下创建 cpt.dag 文件,内容如下:

module_config{
    module library: "/apollo/bazel-bin/cyber/demo_cc/component_common01/lib_common_cpt.so"
    components {
        class_name:"CommonCpt"
        config{
            name : "my_common"
            readers{
                channel: "chatter"
            }
        }
    }
}

在 component_common01 目录下创建 cpt.launch 文件,内容如下:

<cyber>
    <module>
        <name>my_module</name>
        <dag_config>/apollo/cyber/demo_cc/component_common01/cpt.dag</dag_config>
        <process_name>my_cpt</process_name>
    </module>

</cyber>

实例2

需求:现无人车前后各安装了一颗雷达,雷达可以发布障碍物消息,开要将两颗雷达发送的消息进行融合

准备:编写两个节点,分别横拟前后雷达发送障碍物消息:在 demo_cc 目录下新建文件夹:component_common02,并在 component_common02 下新里BUILD文件。

模拟雷达消息发布实现如下:
1.定义雷达消息
demo_base_proto 目录下新建 laser.proto,输入如下内容:

// 1 声明版本
syntax = "proto2";
// 2 声明包
package apollo.cyber.demo_base_proto;

// 3 创建消息
message Laser {
    //雷达消息编号
    optional int64 seq = 1;
    //障碍物个数
    optional int64 count = 2;

}

配置文件添加如下内容:

#############组件
proto_library(
    name="laser_proto",
    srcs=["laser.proto"]
)

cc_proto_library(
    name = "laser_cc",
    deps = [":laser_proto"],
)

然后编译,生成 laser.pb.cc 等文件。

2.分别编写前后雷达消息发送节点
component_common2 目录下新建C++文件 front_laser.cc,输入如下内容:

/*
    需求:模拟雷达发布节点,发布laser 消息
    实现:
                1 包含头文件;
                2 初始化 cyber 框架;
                3 创建节点
                4 创建发布方
                5 组织并发布数据
                6 等待关闭,释放资源
*/
#include "cyber/cyber.h"
#include "cyber/demo_base_proto/laser.pb.h"

using apollo::cyber::demo_base_proto::Laser;

int main(int argc, char const *argv[])
{
    /* code */
    apollo::cyber::Init(argv[0]);
    AINFO<<"前雷达节点———";
    auto front_laser_node = apollo::cyber::CreateNode("front_bode");

    auto front_laser = front_laser_node->CreateWriter<Laser>("/front/laser");
    apollo::cyber::Rate rate(0.5);
    uint64_t seq=0;
    while(apollo::cyber::OK()){
        seq++;
        auto laser_ptr=std::make_shared<Laser>();
        laser_ptr->set_seq(seq);
        laser_ptr->set_count(2);
        front_laser->Write(laser_ptr);
        rate.Sleep();
    }

    apollo::cyber::WaitForShutdown();

    return 0;
}

BUILD 文件:

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

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

back_laser.cc 内容与 front_laser.cc 类似。

3.重写组件
laser_cpt.h:

/*
    组件相关的头文件
    1 包含其他相关头文件
    2 自定义继承组件,重写 Init() 和 Proc() 函数
    3 在 cyber 中注册组件
*/

#include "cyber/component/component.h"
#include "cyber/demo_base_proto/laser.pb.h"

using apollo::cyber::Component;
using apollo::cyber::demo_base_proto::Laser;

class LaserCpt: public Component<Laser,Laser>{
    public:
        bool Init() override;
        bool Proc(const std::shared_ptr<Laser>& front, const std::shared_ptr<Laser>& back) override;
    private:
        std::shared_ptr<apollo::cyber::Writer<Laser>> writer = nullptr;
        uint64_t seq;
};

CYBER_REGISTER_COMPONENT(LaserCpt)

laser_cpt.cc:

#include "cyber/demo_cc/component_common02/laser_cpt.h"

bool LaserCpt::Init(){
    AINFO<<"-----------------初始化发布方-----------------";
    //初始化一个发布者
    //this->node_->CreateWriter
    writer = this->node_->CreateWriter<Laser>("laser");
    seq=0;
    return true;
}

bool LaserCpt::Proc(const std::shared_ptr<Laser>& front, const std::shared_ptr<Laser>& back){
    seq++;
    //数据融合

    //解析被融合数据
    uint64_t front_seq = front->seq();
    uint64_t front_count= front->count();
    uint64_t back_seq = back->seq();
    uint64_t back_count = back->count();

    uint64_t sum = front_count + back_count;

    AINFO << "front_seq="<<front_seq <<"   ----   back_seq="<<back_seq;
    AINFO<<"sum = "<<sum;
    //数据写出

    auto laser_ptr = std::make_shared<Laser>();
    laser_ptr->set_count(sum);
    laser_ptr->set_seq(seq);

    writer->Write(laser_ptr);


    return true;
}

4.dag 文件与launch 文件
dag:

module_config{
    module library: "/apollo/bazel-bin/cyber/demo_cc/component_common02/liblaser_cpt.so"
    components {
        class_name:"LaserCpt"
        config{
            name : "my_laser"
            readers{
                channel: "/front/laser"
            }
            readers{
                channel: "/back/laser"
            }
        }
    }
}

launch:

<cyber>
    <module>
        <name>my_laser</name>
        <dag_config>/apollo/cyber/demo_cc/component_common02/cpt2.dag</dag_config>
        <process_name>my_laser</process_name>
    </module>

</cyber>

5.编译运行
在这里插入图片描述

实例3

需求:周期性的执行某种操作
准备:在demo_cc 目录下新建文件夹:component_timer下新建BUILD文件

实现流程:
上述需求可以通过定时器组件实现,只需包括以下步骤:
1.自定义类继承 TimerComponent 类,并重写其 Init() 与 Proc() 函数;
2.编写 dag 文件与 launch文件;
3.编辑 BUILD 文件;
4.编译执行。

1.继承并重写 TimerComponent 类
component_timer 目录下新建 C++ 文件 timer_cpt.h,输入如下内容:

/*
    需求:实现定时器,循环控制台打印出语句
    实现:
        1 包含头文件
        2 自定义继承 TimerComponent 重写 Init() 与 Proc()
        3 在 Cyber 中注册组件
*/

#include "cyber/component/timer_component.h"
#include "cyber/component/component.h"

using apollo::cyber::TimerComponent;

class MyTimer: public TimerComponent{
    public:
        bool Init() override;
        bool Proc() override;
    private:
        uint64_t seq;
};

CYBER_REGISTER_COMPONENT(MyTimer)


component_timer 目录下新建 C++ 文件 timer_cpt.cc,输入如下内容:

#include "cyber/demo_cc/component_timer/timer_cpt.h"

bool MyTimer::Init(){
    AINFO <<"-----------------------timer Component Init";
    seq=0;
    return true;
}

bool MyTimer::Proc(){
    seq++;
    AINFO<<"-------------------"<<seq;
    return true;
}

新建 BUILD 文件,输入如下内容:

# load("//tools/install:install.bzl","install")

# 配合组件
cc_library(
    name = "timer_cpt_lib",
    deps = [
        "//cyber",
    ],
    srcs = ["timer_cpt.cc"],
    hdrs = ["timer_cpt.h"],
)

cc_binary(
    name = "libtimer_cpt.so",
    linkshared =  True,
    linkstatic = False,
    deps = [":libtimer_cpt"],
)

# 将 dag 与 launch 划分在 同一文件组
filegroup(
    name="conf",
    srcs=[
        ":timer.dag",
        ":timer.launch",
    ],
)
# 安装函数安装
install(
    name="install",
    data=[
        ":conf",
    ],
    runtime_dest="cyber/demo_cc/component_timer",
    targets=[
        ":libtimer_cpt.so",
    ],
)

2.dag 文件 与 launch 文件:
dag:

module_config{
    module library: "/apollo/bazel-bin/cyber/demo_cc/component_timer/libtimer_cpt.so"
    components {
        class_name:"MyTimer"
        config{
            name : "timer"
            interval: 10
        }
    }
}

launch:

<cyber>
    <module>
        <name>MyTimer</name>
        <dag_config>/apollo/cyber/demo_cc/component_timer/timer.dag</dag_config>
        <process_name>MyTimer</process_name>
    </module>

</cyber>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1489134.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP 设置后台JOB批量扩充MRP区域

SAP 升级了HANA以后,不良品仓位的控制都是由MRP区域来控制了,当我们创建物料的时候,希望系统能自动扩充物料到NMRP的区域。我们可以通过创建后台JOB,定时的让程序跑后台JOB的方式来扩充物料的MRP区域 1、执行程序—SE38—RMMDDIBE 2、Tcode:MMD1创建MRP参数文件 点击选…

搜索算法(DFS和BFS 蓝桥杯 C++)

目录 题目一&#xff08;N皇后问题&#xff09;&#xff1a; 代码&#xff1a; 题目二&#xff08;路径之谜&#xff09;&#xff1a; 代码&#xff1a; 题目三&#xff08;最大数字&#xff09;&#xff1a; 代码&#xff1a; 题目四&#xff08;长草&#xff09;&#…

极简技术 | 能够很方便地解决教学中的实际问题

如今&#xff0c;极简教育技术开始兴盛&#xff0c;作为一种能够很方便地解决教学中的实际问题技术体系&#xff0c;“极简主义”与“教育技术”又能碰撞出什么样的火花呢&#xff1f; 一、教育要“技术化”&#xff0c;也可以“极简化” “极简主义”是一种生活理念或哲学&a…

深入理解Docker

文章目录 1 Docker理论1.1 背景知识1.2 是什么1.3 Docker基本三要素1.4 镜像原理1.5 安装教程 2 Docker常用命令2.0 防火墙相关命令2.1 镜像命令2.2 容器命令2.3 进阶命令 3. 实战之Docker部署springboot项目步骤一&#xff1a;Springboot项目配置1.1 添加docker的maven依赖1.2…

spring boot概述

SpringBoot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。 通过这种方式&#xff0c;SpringBoot致力于在蓬勃发展的快速应用开发…

“祖传代码“的是是非非

程序员眼中的“祖传代码”&#xff0c;就像一本古老而神秘的魔法书&#xff0c;藏着无穷的智慧和技巧&#xff0c;有些代码像家传宝贝&#xff0c;有些像祖传秘方。快来分享一下你遇到的“祖传代码”吧~ 祖传代码的历史与文化价值 祖传代码通常指的是经过长时间使用和传承的代…

Linux操作系统——进程信号

1.信号的概念 生活当中哪些场景算信号呢&#xff1f;比如说你晚上调了个闹钟&#xff0c;然后第二天早上你听到了闹钟响了你就知道该起床了&#xff0c;这种机制就叫做信号机制。在生活中我们的信号是非常非常多的&#xff0c;比如说有&#xff1a;红绿灯&#xff0c;下课铃声…

网络编程作业day3

项目作业1&#xff1a;TCP机械臂测试 客户端操作代码&#xff1a; /*机械臂客户端控制代码*/ #include <myhead.h>#define SER_IP "192.168.125.176" //机械臂服务器IP地址 #define SER_PORT 8888 //机械臂服务器端口号 #define CLI_IP "…

代码随想录算法训练营第35天 | 435. 无重叠区间 ,763.划分字母区间 , 56. 合并区间

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 435. 无重叠区间 题目链接&#xff1a;https://leetcode.cn/problems/non-overlapping-intervals/ 思路&#xff1a; 相信…

理疗美容按摩小程序有哪些功能

医疗、美容和按摩等行业是一个快速发展的领域&#xff0c;很多美容院和理疗中心都希望通过小程序来提升服务质量和用户体验。下面我们来看看一个理疗美容小程序可以具备哪些功能&#xff0c;并介绍如何使用这些功能。 1. **在线预约服务**&#xff1a;用户可以通过小程序预约理…

第8章:Nginx与Web应用《Nginx实战:从入门到精通》

Nginx不仅仅是一个高效的静态内容服务器和反向代理服务器&#xff0c;它还能与各种流行的Web应用框架和语言环境无缝集成&#xff0c;从而提供强大的动态内容处理能力。在本章中&#xff0c;我们将深入探讨Nginx如何与PHP、Python、Ruby和Node.js等常见的Web应用和语言环境协同…

爬虫入门到精通_实战篇10(使用Redis+Flask维护动态代理池)

1 目标 为什么要用代理池 许多网站有专门的反爬虫措施&#xff0c;可能遇到封IP等问题。互联网上公开了大量免费代理&#xff0c;利用好资源。通过定时的检测维护同样可以得到多个可用代理。 代理池的要求 多站抓取&#xff0c;异步检测定时筛选&#xff0c;持续更新提供接…

【大厂AI课学习笔记NO.56】(9)模型评测

作者简介&#xff1a;giszz&#xff0c;腾讯云人工智能从业者TCA认证&#xff0c;信息系统项目管理师。 博客地址&#xff1a;https://giszz.blog.csdn.net 声明&#xff1a;本学习笔记来自腾讯云人工智能课程&#xff0c;叠加作者查阅的背景资料、延伸阅读信息&#xff0c;及学…

数字化转型导师坚鹏:BLM金融机构数字化转型战略工作坊

BLM金融机构数字化转型战略工作坊 ——以BLM模型为核心&#xff0c;实现知行果合一 课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不知道如何系统地制定金融机构数字化转型战略&#xff1f; 不清楚其它金融机构数字化转型战略是如何制定的&#xff1f; …

动态IP代理技术在网络爬虫中的实际使用

目录 前言 一、什么是动态IP代理技术&#xff1f; 二、动态IP代理技术的实际使用 1. 获取代理IP地址 2. 在网络爬虫中设置代理 3. 周期性更换代理 结论 前言 网络爬虫是一种通过自动化程序从互联网上获取数据的技术。然而&#xff0c;由于某些网站对爬虫进行限制&#…

No matching version found for @babel/traverse@^7.24.0.

问题&#xff1a; npm安装 依赖失败&#xff0c;找不到所需依赖。 原因&#xff1a; npm镜像源中没有该依赖。&#xff08;大概率是因为依赖最近刚更新&#xff0c;当前镜像源没有同步&#xff09; 解决&#xff1a; 查看自己的npm镜像&#xff1a;npm config get registry…

史上最细,企业性能测试步骤详细,测试老鸟带你一篇打通!

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试流程 …

nodejs,JSDOM 补 window环境

window[atob] 是一个在浏览器中使用的 JavaScript 函数&#xff0c;用于将 base64 编码的字符串解码为原始数据。具体来说&#xff0c;atob 函数会将 base64 字符串解码为一个 DOMString&#xff0c;其中包含解码后的二进制数据。这在处理从服务器获取的 base64 编码的数据或在…

[Vulnhub]靶场 Red

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 …

带你从Spark官网啃透Spark Structured Streaming

By 远方时光原创&#xff0c;可转载&#xff0c;open 合作微信公众号&#xff1a;大数据左右手 本文是基于spark官网结构化流解读 Structured Streaming Programming Guide - Spark 3.5.1 Documentation (apache.org) spark官网对结构化流解释 我浓缩了一些关键信息&#xff…