百度 Apollo Cyber RT简介、基本概念以及与 ROS 对照

一,背景

ROS 应用于自动驾驶领域的不足:

  • 调度的不确定性:各节点以独立进程运行,节点运行顺序无法确定,因而业务逻辑的调度顺序无法保证;
  • 运行效率:ROS 为分布式系统,存在通信开销

二,Cyber RT 框架

Cyber RT 框架
从下到上依次为:

  • 基础库:高性能,无锁队列;
  • 通信层:Publish/Subscribe机制,Service/Client机制,服务自发现,自适应的通信机制(共享内存、Socket、进程内);
  • 数据层:数据缓存与融合。多路传感器之间数据需要融合,而且算法可能需要缓存一定的数据。比如典型的仿真应用,不同算法模块之间需要有一个数据桥梁,数据层起到了这个模块间通信的桥梁的作用;
  • 计算层:计算模型,任务以及任务调度;

三,运行流程

Cyber RT 运行流程

  • 算法模块通过有向无环图(DAG),配置任务间的逻辑关系。对于每个算法可以进行优先级、运行时间、使用资源等方面的配置。
  • 系统启动时,结合DAG、调度配置等,创建相应的任务,从框架内部来讲,就是协程(coroutine)
  • 调度器把任务放到各个 Processor 的队列中。
  • 然后,由 Sensor 输入的数据,驱动整个系统运转。

四,基本概念以及与 ROS 对照

CyberROS注释
Component组件之间通过 Cyber channel 通信。
ChannelTopicchannel 用于管理数据通信,用户可以通过 publish/subscribe 相同的 channel 来通信。
NodeNode每一个模块包含 Node 并通过 Node 来通信。一个模块通过定义 read/write 和/或 service/client 使用不同的通信模式。
Reader/WriterPublish/Subscribe订阅者模式。往 channel 读写消息的类。 通常作为 Node 主要的消息传输接口。
Service/ClientService/Client请求/响应模式,支持节点间双向通信。
MessageMessageCyber RT 中用于模块间通信的数据单元。其实现基于 protobuf
ParameterParameterParameter 服务提供全局参数访问接口。该服务基于 service/client 模式。
Record fileBag file用于记录从 channel 发送或接收的消息。 回放 record file 可以重现之前的操作行为。
Launch fileLaunch file提供一种启动模块的便利途径。通过在 launch file 中定义一个或多个 dag 文件,可以同时启动多个 modules。
Task异步计算任务
CRoutine协程,优化线程使用与系统资源分配
Scheduler任务调度器,用户空间。
Dag file定义模块拓扑结构的配置文件。

五,特色

  • 高性能:无锁对象,协程(coroutine),自适应通信机制;
  • 确定性:可配置的任务以及任务调度,通过协程将调度从内核空间转移到用户空间;
  • 模块化:在框架内实现组件以及节点,即可完成系统任务;
  • 便利性:创建和使用任务

六,示例

Writer/Reader

Message:
syntax = "proto2";
package apollo.cyber.examples.proto;
message Chatter {
    optional uint64 timestamp = 1;
    optional uint64 lidar_timestamp = 2;
    optional uint64 seq = 3;
    optional bytes content = 4;
};
Writer:
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"
#include "cyber/time/rate.h"
#include "cyber/time/time.h"

using apollo::cyber::Rate;
using apollo::cyber::Time;
using apollo::cyber::examples::proto::Chatter;

int main(int argc, char *argv[]) {
  // init cyber framework
  apollo::cyber::Init(argv[0]);
  // create talker node
  auto talker_node = apollo::cyber::CreateNode("talker");
  // create talker
  auto talker = talker_node->CreateWriter<Chatter>("channel/chatter");
  Rate rate(1.0);
  while (apollo::cyber::OK()) {
    static uint64_t seq = 0;
    auto msg = std::make_shared<Chatter>();
    msg->set_timestamp(Time::Now().ToNanosecond());
    msg->set_lidar_timestamp(Time::Now().ToNanosecond());
    msg->set_seq(seq++);
    msg->set_content("Hello, apollo!");
    talker->Write(msg);
    AINFO << "talker sent a message!";
    rate.Sleep();
  }
  return 0;
}
Reader:
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"

void MessageCallback(
    const std::shared_ptr<apollo::cyber::examples::proto::Chatter>& msg) {
  AINFO << "Received message seq-> " << msg->seq();
  AINFO << "msgcontent->" << msg->content();
}

int main(int argc, char* argv[]) {
  // init cyber framework
  apollo::cyber::Init(argv[0]);
  // create listener node
  auto listener_node = apollo::cyber::CreateNode("listener");
  // create listener
  auto listener =
      listener_node->CreateReader<apollo::cyber::examples::proto::Chatter>(
          "channel/chatter", MessageCallback);
  apollo::cyber::WaitForShutdown();
  return 0;
}

Service/Client

Message:
syntax = "proto2";

package apollo.cyber.examples.proto;

message Driver {
    optional string content = 1;
    optional uint64 msg_id = 2;
    optional uint64 timestamp = 3;
};
Service/client:
#include "cyber/cyber.h"
#include "cyber/examples/proto/examples.pb.h"

using apollo::cyber::examples::proto::Driver;

int main(int argc, char* argv[]) {
  apollo::cyber::Init(argv[0]);
  std::shared_ptr<apollo::cyber::Node> node(
      apollo::cyber::CreateNode("start_node"));
  auto server = node->CreateService<Driver, Driver>(
      "test_server", [](const std::shared_ptr<Driver>& request,
                        std::shared_ptr<Driver>& response) {
        AINFO << "server: i am driver server";
        static uint64_t id = 0;
        ++id;
        response->set_msg_id(id);
        response->set_timestamp(0);
      });
  auto client = node->CreateClient<Driver, Driver>("test_server");
  auto driver_msg = std::make_shared<Driver>();
  driver_msg->set_msg_id(0);
  driver_msg->set_timestamp(0);
  while (apollo::cyber::OK()) {
    auto res = client->SendRequest(driver_msg);
    if (res != nullptr) {
      AINFO << "client: responese: " << res->ShortDebugString();
    } else {
      AINFO << "client: service may not ready.";
    }
    sleep(1);
  }

  apollo::cyber::WaitForShutdown();
  return 0;
}

七,Apollo 整体框架
Apollo 整体框架

Apollo Cyber RTApollo自动驾驶系统中的一个关键组件。它是在Apollo v3.0之后引入的,用于替代之前版本中使用的ROS框架。\[3\]Apollo Cyber RT提供了一套开发工具,包括rosbag_to_record工具,支持多个channel,如/perception/obstacles、/planning、/prediction等等。\[1\]通过使用Apollo Cyber RT,开发人员可以更好地满足商业化自动驾驶解决方案对稳健性和性能的需求。\[3\]如果你想了解更多关于Apollo Cyber RT的信息,可以参考Apollo Cyber RT Developer Tools、CyberRT介绍、百度Apollo Cyber RT简介基本概念以及与ROS对照Cyber RT Documents documentation和Apollo6.0学习002:Cyber RT框架等文档。\[2\] #### 引用[.reference_title] - *1* *2* [【Apollo 6.0学习笔记】Apollo Cyber RT介绍](https://blog.csdn.net/Travis_X/article/details/120965138)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [自动驾驶Apollo源码分析系统,CyberRT篇(一):简述CyberRT框架基础概念](https://blog.csdn.net/briblue/article/details/123432580)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值