Apollo部署与简易架构梳理

文章目录

    • apollo 安装
    • apollo的基本架构
    • 组件机制
      • component
        • 编译与加载
    • 节点通讯
      • 数据的传输
      • 消息读写的实现
        • 消息的写端
        • 消息读端
    • 常用术语
        • Component
        • Channel
        • Task
        • Node
        • Reader/Writer
        • Service/Client
        • Parameter
        • 服务发现
        • CRoutine
        • Scheduler
        • Message
        • Dag文件
        • Launch文件
        • Record文件
        • Mainboard
    • Monitor工具使用

原文

apollo 安装

sudo apt-get update
sudo apt-add-repository multiverse
sudo apt-get update
# sudo apt-get install nividia-driver-455 # 看版本

启用cuda


distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get -y update
sudo apt-get install -y nvidia-docker2

clone源代码

# 使用 SSH 的方式  
git clone git@github.com:ApolloAuto/apollo.git

启动容器

./docker/scripts/dev_start.sh

进入容器

./docker/scripts/dev_into.sh

构建

./apollo.sh build

启动

./scripts/bootstrap.sh start

http://localhost:8888 可以显示DreamView界面

回放demo
在docs/02_Quick Start/demo_guide

python3 record_helper.py demo_3.5.record
cyber_recorder play -f demo_3.5.record -l

cyber_recorder在apollo/中

apollo的基本架构

apollo开发文档

请添加图片描述

请添加图片描述

常用数据见本篇末尾

组件机制

Cyber RT 组件机制
Cyber RT采用了基于Component模块和有向无环图(DAG)的动态加载配置的工程框架。即将相关算法模块通过Component创建,并通过DAG拓扑定义对各Component依赖关系进行动态加载和配置,从而实现对算法进行统一调度,对资源进行统一分配。

component

Component构成去中心化的网络,系统由多个component组成,构成一张计算图,如

请添加图片描述

component分为两类:
apollo::cyber::Component最多可以支持4路消息融合。多个channel读取数据时,第一个channel为主channel。当主 Channel 有消息到达,Cyber RT会调用 Component 的 apollo::cyber::Component::Proc 进行一次数据处理。
也就是说,每次有主消息到达,其就会执行一次Proc。

apollo::cyber::TimerComponent不会被消息出发,而是由系统定时调用。

创建一个Component的方式如下:

//1、包含头文件
#include "cyber/component/component.h"
#include "test/proto/examples.pb.h"// 2、定义一个类,继承以Driver和Chatter为参数的Component模版类
class ComponentSample : public Component<Driver, Chatter> {
public://3、重写Init() 函数和Proc() 函数bool Init() override;bool Proc(const std::shared_ptr<Driver>& msg0,const std::shared_ptr<Chatter>& msg1) override;
};
//4、 在cyber中注册ComopnentSample
CYBER_REGISTER_COMPONENT(ComponentSample)

也就是说我们需要继承一个模版类,并在cyber RT中注册这个类。

编译与加载

在Cyber RT中,Component会变编译为独立的.so文件。Cyber RT可以使用cyber_launch工具启动componenet对应的launch文件(可以是二进制文件或dag)或使用mainboard启动component对应的dag文件。
![[Apollo部署与简易架构梳理/Pasted image 20240723163142.png]]

节点通讯

参考资料
Publish-Subscribe模式
Reader和Writer

![[apollo/Apollo部署与简易架构梳理/Pasted image 20240715111104.png]]
RTPS(Real-Time Publish-Subscribe) 是一种用于实时分布式系统的通信协议,主要用于实现设备间的实时数据交换。

Fast RTPS是DDS标准的一个非常流行的开源实现。

DDS(Data Distribution Service)标准提供了一个平台无关的数据模型,主要用于实时分布式系统。不同的实现可以相互通信。

  1. 数据中心化:DDS采用数据为中心的架构,数据被看作是核心,而不是进程之间的直接通信。
  2. 发布/订阅模型:DDS使用发布/订阅(Pub/Sub)模式,允许数据生产者(发布者)和数据消费者(订阅者)之间进行解耦,从而提高系统的灵活性和可扩展性。

节点间通过channel进行读写形成数据通路,这些数据通路形成一个动态的数据流图。

cyber/service_discovery/TopologyManager对网络拓扑进行监控管理。只需要一个管理因此单例即可

- NodeManager用于管理网络拓扑中的节点。
  - ChannelManager用于管理channel,即网络拓扑中的边。
  - ServiceManager用于管理ServiceClient

TopologyManager::TopologyManager(): init_(false),node_manager_(nullptr),channel_manager_(nullptr),service_manager_(nullptr),participant_(nullptr),participant_listener_(nullptr) {Init();}

TopologyManager::CreateParticipant()函数可以创建网络拓扑的参与者——transport::Participant对象,其包含host name与process id的名称。
ParticipantListener用于监听网络的变化。网络拓扑发生变化时,Fast RTPS传上来ParticipantDiscoveryInfo,在TopologyManager::Convert()函数中对该信息转换成Cyber RT中的数据结构ChangeMsg。然后调用回调函数TopologyManager::OnParticipantChange(),它会调用其它几个子管理器的OnTopoModuleLeave()函数。然后子管理器中便可以将相应维护的信息进行更新(如NodeManager中将相应的节点删除)。

初始化的时候会创建实例

数据的传输

- INTRA:如果是同进程的,因为在同一地址空间,直接传指针就完了。
  - SHM(Shared memory):如果是同一机器上,但跨进程的,为了高效可以使用共享内存。
  - RTPS:如果是跨设备的,那就老老实实通过网络传吧。
  (目前我们的车机应该不太设计跨设备咯?)
![[apollo/Apollo部署与简易架构梳理/Pasted image 20240715120551.png]]
每个Writer有Transmitter,每个Reader有Receiver。它们是负责消息发送与收取的类。Transmitter与Receiver的基类为Endpoint,代表一个通信的端点,它主要的信息是身份标识与属性。其类型为RoleAttributes(定义在role_attributes.proto)的成员attr_包含了host name,process id和一个根据uuid产生的hash值作为id。通过它们就可以判断节点之间的相对位置关系了。

Reader和Writer会调用Transport的方法CreateTransmitter()和CreateReceiver()用于创建发送端的transmitter和接收端的receiver。创建时有四种模式可选,分别是INTRA,SHM和RTPS,和HYBRID。最后一种是前三种的混合模式,也是默认的模式。

消息读写的实现

消息的写端

在Component组件中通过CreaterWriter()函数创建Writer对象,然后向指定的channel发送消息。

writer_ = node_->CreateWriter<Image>(camera_config_->channel_name());// 创建writer对象// 在创建该对象时,会在Init()初始化中通过CreateTransmitter()创建Transmitter对象,并调用JointTheTopology()将其加入到ChannelManager维护的拓扑信息中。
//
//此外,还会对该channel的读者相应的调用Enable函数和Disable函数。
//
...
auto pb_image = std::make_shared<Image>();                                 
pb_image->mutable_header()->set_frame_id(camera_config_->frame_id());      
pb_image->set_width(raw_image_->width);                                    
pb_image->set_height(raw_image_->height);                                  
pb_image->mutable_data()->reserve(raw_image_->image_size);  
// 以上完成发送数据的准备
// 这些消息如pb_image是定义好的protobuf类消息。
...
writer_->Write(pb_image);
// 其会调用Transmitter::Transmit()将message发出
消息读端

对于一个component而言,其可以从多个channel收取消息。
上层模块要取用这些消息,主要两种方式:一种是通过ComponentProc()接口,它被调用时参数就是最新的消息。另一种是通过ReaderObserve()函数直接拿
例:

template <typename M0, typename M1>  // 声明一个模板类Component,其中M0和M1是数据类型参数
bool Component<M0, M1, NullType, NullType>::Initialize(  // 初始化函数的定义...ReaderConfig reader_cfg;  // 创建一个ReaderConfig对象用于配置读者reader_cfg.channel_name = config.readers(1).channel();  // 设置通道名称为配置中的第二个读者通道reader_cfg.qos_profile.CopyFrom(config.readers(1).qos_profile());  // 从配置中复制第二个读者的QoS配置reader_cfg.pending_queue_size = config.readers(1).pending_queue_size();  // 设置待处理队列大小为配置中的第二个读者大小auto reader1 = node_->template CreateReader<M1>(reader_cfg);  // 使用配置创建一个类型为M1的读者,并命名为reader1reader_cfg.channel_name = config.readers(0).channel();  // 更新通道名称为配置中的第一个读者通道reader_cfg.qos_profile.CopyFrom(config.readers(0).qos_profile());  // 从配置中复制第一个读者的QoS配置reader_cfg.pending_queue_size = config.readers(0).pending_queue_size();  // 设置待处理队列大小为配置中的第一个读者大小auto reader0 = node_->template CreateReader<M0>(reader_cfg);  // 使用配置创建一个类型为M0的读者,并命名为reader0...readers_.push_back(std::move(reader0));  // 将reader0移动到readers_向量中readers_.push_back(std::move(reader1));  // 将reader1移动到readers_向量中...  std::vector<data::VisitorConfig> config_list;  // 创建一个data::VisitorConfig类型的向量用于存储访问者配置for (auto& reader : readers_) {  // 遍历所有读者config_list.emplace_back(reader->ChannelId(), reader->PendingQueueSize());  // 将每个读者的配置添加到配置列表中}  auto dv = std::make_shared<data::DataVisitor<M0, M1>>(config_list);  // 使用配置列表创建一个DataVisitor智能指针,并特化为M0和M1类型croutine::RoutineFactory factory =  // 创建一个RoutineFactory对象croutine::CreateRoutineFactory<M0, M1>(func, dv);  // 使用工厂函数创建RoutineFactory,并传入func函数和数据访问者return sched->CreateTask(factory, node_->Name());  // 创建一个任务并返回创建结果,任务使用RoutineFactory和节点名称
}

这个案例中有两个channel并分别创建了reader对象。
每个channel都有对应的协程进行数据处理,还有一个协程实现消息的组合,所以有n个channel的component至少会有n+1个协程

常用术语

Component

在自动驾驶系统中,模块(如感知、定位、控制系统…)在 Cyber RT 下以 Component 的形式存在。不同 Component 之间通过 Channel 进行通信。Component 概念不仅解耦了模块,还为将模块拆分为多个子模块提供了灵活性。

Channel

Channel 用于管理 Cyber RT 中的数据通信。用户可以发布/订阅同一个 Channel,实现 p2p 通信。

Task

Task 是 Cyber RT 中异步计算任务的抽象描述。

Node

Node 是 Cyber RT 的基本组成部分;每个模块都包含一个 Node 并通过 Node 进行通信。通过在节点中定义 Reader/Writer 或 Service/Client,模块可以具有不同类型的通信形式。

Reader/Writer

Reader/Writer 通常在 Node 内创建,作为 Cyber RT 中的主要消息传输接口。

Service/Client

除了 Reader/Writer 之外,Cyber RT 还提供了用于模块通信的 Service/Client 模式。它支持节点之间的双向通信。当对服务发出请求时,客户端节点将收到响应。

Parameter

参数服务在 Cyber RT 中提供了全局参数访问接口。它是基于 Service/Client 模式构建的。

服务发现

作为一个去中心化的框架,Cyber RT 没有用于服务注册的主/中心节点。所有节点都被平等对待,可以通过“服务发现”找到其他服务节点。使用UDP用来服务发现。

CRoutine

参考协程(Coroutine)的概念,Cyber RT 实现了 Coroutine 来优化线程使用和系统资源分配。

Scheduler

为了更好地支持自动驾驶场景,Cyber RT 提供了多种资源调度算法供开发者选择。

Message

Message 是 Cyber RT 中用于模块之间数据传输的数据单元。

Dag文件

Dag 文件是模块拓扑关系的配置文件。您可以在 dag 文件中定义使用的 Component 和上游/下游通道。

Launch文件

Launch 文件提供了一种启动模块的简单方法。通过在launch文件中定义一个或多个 dag 文件,可以同时启动多个模块。

Record文件

Record 文件用于记录从 Cyber RT 中的 Channel 发送/接收的消息。回放 Record 文件可以帮助重现Cyber RT之前操作的行为。

Mainboard

Cyber RT 的主入口,可以通过mainboard -d xxx.dag来启动一个模块进程。

Monitor工具使用

ESC | q key ---- 退出
Backspace ---- 后退
h | H ---- 显示帮助页
PageDown | Ctrl+d ---- 上一页
PageUp | Ctrl+u ---- 下一页
Up, down or w, s keys ---- 上下移动当前的高亮行
Right arrow or d key ---- 进入高亮行, 显示高亮行数据的详细信息
Left arrow or a key ---- 从当前界面返回上一层界面
Enter key ---- 与d键相同
f | F ---- 显示数据帧频率
t | T ---- 显示channel消息类型
Space ---- 关闭|开启 channel (仅在channel有数据到达时有效; channel关闭后会变成黄色)
i | I ---- 显示channel的Reader和Writer信息
b | B ---- 显示channel消息内容
n | N ---- 显示消息中RepeatedField的下一条数据
m | M ---- 显示消息中RepeatedField的上一条数据

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

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

相关文章

在图神经网络(GNN)上进行关系推理的新架构

开发能够学习推理的模型是一个众所周知的具有挑战性的问题&#xff0c;在这个领域中&#xff0c;使用图神经网络&#xff08;GNNs&#xff09;似乎是一个自然的选择。然而&#xff0c;以往关于使用GNNs进行推理的工作表明&#xff0c;当这些模型面对需要比训练时更长推理链的测…

(leetcode学习)236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十一章 添加设备树节点

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

linux禁用root

linux禁用root 1. 禁止普通用户切换到root1.1 sudo -i和sudo -s的区别1.2 sudo -i和直接登录root账号的区别1.3 禁止sudo -i切换root1.4 禁止su - root切换root 2. 禁止root远程登录2.1 ssh禁止root登录2.2 禁止远程桌面登录 本文主要介绍&#xff1a; 如何禁止普通用户切换到r…

Java---后端事务管理

代码世界聚眸光&#xff0c;昼夜敲盘思绪长。 算法心间精构建&#xff0c;编程路上细思量。 屏前架构乾坤定&#xff0c;键上飞驰智慧扬。 默默耕耘成果现&#xff0c;创新科技铸辉煌。 目录 一&#xff0c;概念 二&#xff0c;Spring事务管理 三&#xff0c;rollbackFor事务回…

运维锅总浅析Kubernetes之Ceph

Ceph 的核心组件有哪些&#xff1f;Ceph读写数据流程及故障自愈是怎样的&#xff1f;如何对Ceph部署架构进行调优&#xff1f;如何用Ceph集成到kubernetes&#xff1f;希望本文能帮您解答这些疑惑&#xff01; 一、Ceph简介 Ceph 是一个开源的分布式存储系统&#xff0c;旨在…

PySide(PyQt)使用QPropertyAnimation制作动态界面

主脚本&#xff1a; # encoding: utf-8 import os import sysfrom PySide6.QtCore import QPropertyAnimation, QEasingCurvefrom UIS import *# 主画面类 class MainWindow(QMainWindow, animationButton_ui.Ui_MainWindow):def __init__(self):super().__init__()self.setup…

韩顺平0基础学Java——第37天

p736-758 MySQL三层结构 1.所谓安装Mysql数据库&#xff0c;就是在主机安装一个数据库管理系统(DBMS)&#xff0c;这个管理程序可以管理多个数据库。DBMS(database manage system) 2.一个数据库中可以创建多个表,以保存数据(信息)。 3.数据库管理系统(DBMS)、数据库和表的关系…

Android 性能之刷新率设置和管理

目录 1. 刷新率和帧率 2. 多种刷新率 3. 基本原理 3.1 屏幕 & 显示控制器 3.2 Composer Service 4. Framework 策略 4.1基本架构 4.2 刷新率设置项的定义 4.2.1 最低刷新率 4.2.2 默认刷新率 & 默认的用户设置刷新率 4.2.2.1 设置入口 4.2.2.2 设置场景 4…

从零开始:在linux系统安装MongoDB数据完整指南 新手常用命令

1 前言 MongoDB 是为快速开发互联网应用而设计的数据库系统。MongoDB 的设计目标是极简、灵活、作为 Web 应用栈的一部分。MongoDB 的数据模型是面向文档的&#xff0c;所谓文档是一种类似于json的结构。 官网教程&#xff1a;https://www.mongodb.com/docs/manual/ 2 安装部…

【接口自动化_11课_框架实战:基于封装的框架进行实战演练-下】

目标&#xff1a; 在原有基础上进行框架优化&#xff0c;本内容不做强制要求&#xff0c;了解即可。 1. Faker&#xff08;伪造器&#xff09;模块生成数据 2. 实战&#xff1a;结合框架动态生成请求数据 3. 实战&#xff1a;响应进行动态断言处理 一、 Faker&#xff…

LoFTR关键点特征匹配算法环境构建与图像匹配测试Demo

0&#xff0c;LoFTR CVPR 2021论文《LoFTR: Detector-Free Local Feature Matching with Transformers》开源代码 1&#xff0c;项目主页 LoFTR: Detector-Free Local Feature Matching with Transformers 2&#xff0c;GItHub主页 GitHub - zju3dv/LoFTR: Code for "…

微软蓝屏事件对企业数字化转型有什么影响?

引言&#xff1a;从北京时间2024年7月19日&#xff08;周五&#xff09;下午2点多开始&#xff0c;全球大量Windows用户出现电脑崩溃、蓝屏死机、无法重启等情况。事发后&#xff0c;网络安全公司CrowdStrike称&#xff0c;收到大量关于Windows电脑出现蓝屏报告&#xff0c;公司…

畅游时空|虚拟世界初体验,元宇宙游戏如何开发?

在元宇宙中&#xff0c;用户可以通过虚拟身份进行互动、社交、工作和娱乐&#xff0c;体验与现实世界平行的生活和活动。元宇宙不仅仅是一个虚拟空间&#xff0c;更是一个融合了虚拟和现实的生态系统&#xff0c;具有巨大的发展潜力和应用前景。 在不断发展的数字环境中&#x…

简单几步,教你使用scikit-learn做分类和回归预测

前言 scikit-learn是基于Python的一个机器学习库&#xff0c;你可以在scikit-learn库中选择合适的模型&#xff0c;使用它训练数据集并对新数据集作出预测。 对于初学者来说&#xff0c;有一个共同的困惑&#xff1a; 怎么使用scikit-learn库中的模型做预测&#xff1f; 本文…

IOS微软语音转文本,lame压缩音频

在IOS开发中&#xff0c;用微软进行语音转文本操作&#xff0c;并将录音文件压缩后返回 项目中遇到了利用微软SDK进行实时录音转文本操作&#xff0c;如果操作失败&#xff0c;那么就利用原始音频文件通过网络请求操作&#xff0c;最终这份文件上传到阿里云保存&#xff0c;考…

MongoDB教程(十五):MongoDB原子操作

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…

11 深度推荐模型演化中的“范式替换“灵活组合

上一课时&#xff0c;我们介绍了 DIEN 模型添加了 RNN中 的 GRU&#xff0c;使模型获得了对序列数据的建模能力&#xff1b;而 DSIN 模型不仅使用了 RNN 中的 bi-LSTM&#xff0c;还使用了 Transformer 组件。 由此可见&#xff0c;在新的演化模型中&#xff0c;根据场景和数据…

Lua脚本简单理解

目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令&#xff1a; yum -y update yum i…

本地部署VMware ESXi服务实现无公网IP远程访问管理服务器

文章目录 前言1. 下载安装ESXi2. 安装Cpolar工具3. 配置ESXi公网地址4. 远程访问ESXi5. 固定ESXi公网地址 前言 在虚拟化技术日益成熟的今天&#xff0c;VMware ESXi以其卓越的性能和稳定性&#xff0c;成为了众多企业构建虚拟化环境的首选。然而&#xff0c;随着远程办公和跨…