Cyber RT 组件

场景

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

概念

组件是 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 自定义继承 compoenent3 在 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_->CreateWriterwriter = 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.rhkb.cn/news/269164.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习-面经(part5、KNN和SVM)

8. KNN 8.1 简述一下KNN算法的原理? 一句话概括:KNN的原理就是当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别 工作原理:存在一个样本数据集合,也称作为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数…

TypeError: the JSON object must be str, bytes or bytearray, not dict

参考文章&#xff1a;https://blog.csdn.net/yuan2019035055/article/details/124934362 Python基础系列&#xff08;一&#xff09;搞懂json数据解析与字典之间的关系 代码&#xff1a; 报错信息: TypeError: the JSON object must be str, bytes or bytearray, not dict …

局域网如何远程?

局域网远程一直是许多用户在处理远程连接需求时面临的一个难题。随着技术的不断进步&#xff0c;一种名为“天联”的组网解决方案应运而生。天联组网具有操作简单、跨平台应用、无网络要求以及独创的安全加速方案等独特优势&#xff0c;在解决各行业客户的远程连接需求方面发挥…

解决ipconfig不能使用的问题

问题所示&#xff1a;ipconfig不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 解决办法如下: 1.右击此电脑&#xff0c;点击属性设置&#xff1a; 2.点击高级系统设置 3.点击进入环境变量 4.在系统变量中进行设置&#xff0c;双击PATH进行配置 5.点击新建&am…

【如何在Docker中,修改已经挂载的卷(Volume)】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 提示&#xff1a;添加投票&#xff01;&#xff01;&#xff01; 目录 简述概要知识图谱 简述概要 如何在Docker中&#xff0c;修改已经挂载的卷&#xff08;Volume&#xff09; 知识图谱 在Docker中&#xff0c;修改已经挂载…

matlab 提取分割位于多边形区域边缘内部或边缘上的点

[in,on] = inpolygon(xq,yq,xv,yv) xv 和 yv 为定义的多边形区域的,如xv = [1 4 4 1 1 ];yv = [1 1 4 4 1 ];注意最后一个数字与第一个重复,保证多边形闭合; xq 和 yq 为待查询的点in:在多边形内部和边缘的点序号on:仅在多边形边缘的点序号 提取分割方法: matrix=[xq yq…

智能汽车加速车规级存储应用DS2431P+TR 汽车级EEPROM 存储器IC

DS2431PT&R是一款1024位1-Wire EEPROM芯片&#xff0c;由四页存储区组成&#xff0c;每页256位。数据先被写入一个8字节暂存器中&#xff0c;经校验后复制到EEPROM存储器。该器件的特点是&#xff0c;四页存储区相互独立&#xff0c;可以单独进行写保护或进入EPROM仿真模式…

折线图实现柱状阴影背景的demo

这个是一个由官网的基础折线图实现的流程&#xff0c;将涉及到的知识点附上个人浅薄的见解&#xff0c;源码在最后&#xff0c;需要的可自取。 折线图 成果展示代码注解参数backgroundColordataZoomlegendtitlexAxisyAxisgridseries 源码 成果展示 官网的基础折线图&#xff…

【Python】OpenCV-使用ResNet50进行图像分类

使用ResNet50进行图像分类 如何使用ResNet50模型对图像进行分类。 import os import cv2 import numpy as np from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions from tensorflow.keras.preprocessing import image# 设置…

计算机网络物理层知识点总结

本篇博客是基于谢希仁编写的《计算机网络》和王道考研视频总结出来的知识点&#xff0c;本篇总结的主要知识点是第二章的物理层。上一章的传送门&#xff1a;计算机网络体系结构-CSDN博客 通信基础 物理层概念 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流&am…

leetcode刷题日记-K个一组翻转(链表)

题目描述 解题思路 第一种解法&#xff0c;也是我们常用的一种解题方法&#xff0c;首先遍历一遍列表&#xff0c;将列表中的val的值存放到数组中&#xff0c;然后按照要求对数组进行排序&#xff0c;排序之后&#xff0c;我们重新定义节点&#xff0c;将节点按照排完序的结果…

如何远程连接MySQL数据库?

在现代互联网时代&#xff0c;远程连接MySQL数据库成为了许多开发者和管理员必备的技能。这不仅方便了数据的共享和管理&#xff0c;还可以使多个团队在全球范围内协同工作。本文将介绍如何通过天联组网实现远程连接MySQL数据库&#xff0c;并实现高效的信息远程通信。 天联组网…

力扣hot100:1.两数之和

输入中可能存在重复值 。 分析&#xff1a; 本题需要返回的是数组下标&#xff0c;因此如果需要使用排序然后双指针的话&#xff0c;需要用到哈希表&#xff0c;但是由于输入中可能存在重复值&#xff0c;因此哈希表的value值必须是vector<int>。 使用双指针求目标值targ…

OpenDDS 跨主机通信配置与实现(C++和Java)

目录 1、编写一个示例1.1、IDL接口定义1.2、MPC文件介绍1.3、生成解决方案 2、通讯测试2.1、使用repo server 通讯2.2、使用repo ipport方式2.3、对等发现face 1、编写一个示例 1.1、IDL接口定义 假设我们现在有以下结构&#xff1a; struct MessagerOne { int subject_id; …

CMU 10-414/714: Deep Learning Systems --hw0

hw0 宏观上的步骤: softmax loss: 实现softmax loss代码 概念 softmax就是将结果映射到0~1之间,且所有结果相加为1(概率形式)cross-entropy loss就是计算 p ( x ) log ⁡ q ( x ) p(x)\log {q(x)} p(x)logq(x),此值可用于衡量实际输出与期望输出的距离,进而衡量预测模…

各种排序算法

文章目录 1. 基于比较排序算法总结2. 非比较排序算法 1. 基于比较排序算法总结 2. 非比较排序算法

路由器端口映射如何配置?

在网络通信中&#xff0c;路由器是一个重要的设备&#xff0c;它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置&#xff0c;可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…

LabVIEW石油钻机提升系统数字孪生技术

LabVIEW石油钻机提升系统数字孪生技术 随着数字化、信息化、智能化的发展&#xff0c;石油钻采过程中的石油钻机数字化技术提升成为了提高钻井效率、降低生产成本的重要途径。基于中石油云平台提供的数据&#xff0c;采用数字孪生技术&#xff0c;对石油钻机提升系统进行数字化…

electron+vue3全家桶+vite项目搭建【29】封装窗口工具类【3】控制窗口定向移动

文章目录 引入实现效果思路声明通用的定位对象主进程模块渲染进程测试效果 引入 demo项目地址 窗口工具类系列文章&#xff1a; 封装窗口工具类【1】雏形 封装窗口工具类【2】窗口组&#xff0c;维护窗口关系 封装窗口工具类【3】控制窗口定向移动 很多时候&#xff0c;我们想…

C语言--- qsort函数

目录 一.qsort函数 1.qsort函数的功能 2.四个参数讲解 (1)base (2)num (3)size (4)compare 3.使用qsort函数对一个整形数组进行排序 4.qsort函数排序结构体数据 第一种&#xff1a;按照年龄进行比较 第二种&#xff1a;按照名字进行排序 二.利用冒泡排序模仿qsort函…