01_apollo_cyber子模块整体软件架构深入分析文档

0 阅读7分钟

1. 概述

  Apollo Cyber RT是专为自动驾驶场景设计的高性能开源运行时框架。该框架基于集中式计算模型,针对自动驾驶领域的高并发、低延迟和高吞吐量需求进行了深度优化。Cyber RT提供了高效的模块间通信机制、灵活的任务调度系统以及便捷的开发工具集,支持实时数据处理和任务调度,为自动驾驶系统提供了稳定可靠的技术基础。

2. 软件架构图

graph TB
    subgraph "应用层"
        A1[感知组件]
        A2[预测组件]
        A3[规划组件]
        A4[控制组件]
        A5[定位组件]
        A6[地图组件]
        A7[诊断组件]
        A8[监控组件]
    end

    subgraph "Cyber RT中间件"
        subgraph "通信框架"
            C1[发布订阅机制]
            C2[服务调用机制]
            C3[参数服务]
            C4[记录回放]
        end
        
        subgraph "任务调度"
            C5[Choreography调度器]
            C6[Fair调度器]
            C7[Classic调度器]
            C8[任务管理]
        end
        
        subgraph "数据管理"
            C9[共享内存管理]
            C10[数据缓存]
            C11[QoS控制]
            C12[消息序列化]
        end
        
        subgraph "服务发现"
            C13[节点管理]
            C14[通道管理]
            C15[服务管理]
            C16[拓扑管理]
        end
        
        subgraph "基础工具"
            C17[日志系统]
            C18[时间管理]
            C19[定时器]
            C20[协程]
        end
    end

    subgraph "基础设施层"
        I1[基础工具库]
        I2[内存管理]
        I3[错误处理]
        I4[原子操作]
        I5[类型转换]
        I6[字符串处理]
    end

    subgraph "传输层"
        T1[进程内传输]
        T2[共享内存传输]
        T3[RTPS网络传输]
        T4[消息序列化]
        T5[QoS策略]
        T6[传输控制]
    end

    subgraph "服务发现层"
        S1[节点注册]
        S2[通道注册]
        S3[服务注册]
        S4[拓扑变化通知]
        S5[节点生命周期管理]
        S6[服务生命周期管理]
    end

    subgraph "运行时环境"
        R1[主控板]
        R2[组件框架]
        R3[服务框架]
        R4[参数服务器]
        R5[记录器]
        R6[播放器]
    end

    A1 --> C1
    A2 --> C1
    A3 --> C1
    A4 --> C1
    A5 --> C1
    A6 --> C1
    A7 --> C1
    A8 --> C1
    
    C1 --> T1
    C1 --> T2
    C1 --> T3
    C1 --> T4
    C1 --> T5
    C1 --> T6
    
    C2 --> S1
    C2 --> S2
    C2 --> S3
    C2 --> S4
    C2 --> S5
    C2 --> S6
    
    C5 --> R1
    C6 --> R2
    C7 --> R3
    C8 --> R4
    C8 --> R5
    C8 --> R6
    
    I1 --> C1
    I2 --> C1
    I3 --> C1
    I4 --> C1
    I5 --> C1
    I6 --> C1
    
    R1 --> I1
    R2 --> I1
    R3 --> I1
    R4 --> I1
    R5 --> I1
    R6 --> I1
    
    S1 --> I1
    S2 --> I1
    S3 --> I1
    S4 --> I1
    S5 --> I1
    S6 --> I1

    style C1 fill:#e1f5fe
    style A1 fill:#f3e5f5
    style T1 fill:#fff3e0
    style I1 fill:#e8f5e8
    style C5 fill:#ffebee
    style C13 fill:#e8f5e8

3. 调用流程图

sequenceDiagram
    participant App as 应用程序
    participant Mainboard as 主控板
    participant Component as 组件
    participant Node as 节点
    participant Writer as 消息写入器
    participant Reader as 消息读取器
    participant Trans as 传输层
    participant SD as 服务发现
    participant Scheduler as 调度器
    participant Executor as 执行器
    participant CRoutine as 协程

    Note over App, CRoutine: 初始化阶段
    App->>Mainboard: 加载组件配置
    Mainboard->>Component: 创建组件实例
    Component->>Node: 初始化节点
    Node->>SD: 注册节点信息
    SD-->>Node: 返回注册结果
    
    Component->>Node: 创建写入器
    Node->>Writer: 创建Writer实例
    Writer->>Trans: 注册传输通道
    Trans->>SD: 更新拓扑信息
    
    Component->>Node: 创建读取器
    Node->>Reader: 创建Reader实例
    Reader->>SD: 订阅话题
    SD->>Reader: 匹配生产者
    
    Component->>Scheduler: 注册任务
    Scheduler->>Executor: 分配执行器
    Executor->>CRoutine: 创建协程
    
    Note over App, CRoutine: 运行阶段
    loop 消息处理循环
        App->>Writer: 发布消息
        Writer->>Trans: 传输消息
        Trans->>Reader: 投递消息
        Reader->>Component: 调用处理函数
        Component->>App: 处理结果
    end
    
    loop 服务调用
        App->>Node: 创建服务客户端
        Node->>SD: 查找服务
        SD->>Node: 返回服务地址
        Node->>App: 创建客户端
        App->>Node: 发送服务请求
        Node->>SD: 路由请求
        SD->>服务节点: 转发请求
        服务节点->>App: 返回响应
    end
    
    Note over App, CRoutine: 关闭阶段
    App->>Scheduler: 注销任务
    Scheduler->>CRoutine: 停止协程
    CRoutine->>Component: 关闭组件
    Component->>Node: 清理节点资源
    Node->>SD: 注销节点

4. 详细UML类图

4.1. 核心框架类图

classDiagram
    class CyberRT {
        +Initialize(): bool
        +Shutdown(): void
        +CreateNode(name): shared_ptr~Node~
        +CreateComponent(config): shared_ptr~ComponentBase~
        +CreateService(name): shared_ptr~ServiceBase~
        +CreateClient(name): shared_ptr~ClientBase~
        -initialized: bool
        -scheduler: unique_ptr~Scheduler~
        -transport: unique_ptr~transport::Transport~
        -service_discovery: unique_ptr~service_discovery::TopologyManager~
        -parameter: unique_ptr~Parameter~
        -timer_scheduler: unique_ptr~TimerScheduler~
        -black_board: unique_ptr~BlackBoard~
    }

    class Node {
        <<abstract>>
        +Node(name)
        +CreateWriter~T~(const RoleAttributes&): shared_ptr~Writer~T~~
        +CreateReader~T~(const RoleAttributes&, Callback): shared_ptr~Reader~T~~
        +CreateService~Req, Res~(const string&, ServiceCallback): shared_ptr~Service~Req,Res~~
        +CreateClient~Req, Res~(const string&): shared_ptr~Client~Req,Res~~
        +GetName(): const string&
        +GetServiceAttr(const string&, ServiceAttribute*): bool
        +ListServices(vector~ServiceAttribute~*): bool
        -ReadParameter(const string&, string*): bool
        -WriteParameter(const string&, const string&): void
        -node_name_: string
        -name_space_: string
        -writers_: vector~WriterBase*~
        -readers_: vector~ReaderBase*~
        -servers_: vector~ServiceBase*~
        -clients_: vector~ClientBase*~
        -rw_mutex_: mutex
        -role_attr_: proto::RoleAttributes
    }

    class ComponentBase {
        <<abstract>>
        +Initialize(): bool
        +Process(const std::shared_ptr~Message~&): bool
        +Shutdown(): void
        +FillInChannelNames(const MultiSubOpt~M0,M1,M2~&): void
        #node_: std::shared_ptr~Node~
        #readers_: vector~ReaderBase*~
        #attrs_: vector~RoleAttributes~
    }

    class Component~M0, M1, M2~ {
        +Component()
        +Init(const MultiSubOpt~M0, M1, M2~&, std::shared_ptr~Node~): bool
        +Shutdown(): void
        -ProcByCaller(uint64_t, const std::shared_ptr~Data~&): bool
        -RegisterReaders(std::shared_ptr~Node~): bool
        -Proc(const std::shared_ptr~M0~&, const std::shared_ptr~M1~&, const std::shared_ptr~M2~&): bool
        #callers_: vector~CallbackCaller~M0,M1,M2~*~
    }

    class WriterBase {
        <<abstract>>
        +WriterBase()
        +Shutdown(): void
        +HasReader(): bool
        +GetReaderCount(): size_t
        +GetChannelName(): string
        -init_: bool
        -attr_: proto::RoleAttributes
    }

    class Writer~T~ {
        +Writer(const proto::RoleAttributes&, const proto::QosProfile&)
        +Write(const std::shared_ptr~T~&): bool
        +TryWrite(const std::shared_ptr~T~&): bool
        +Enable(): bool
        -message_writer_: transport::MessageWriter~T~
    }

    class ReaderBase {
        <<abstract>>
        +ReaderBase()
        +Shutdown(): void
        +GetCachedMessageSize(): uint64_t
        +GetChannelConnSize(): uint64_t
        -init_: bool
        -attr_: proto::RoleAttributes
    }

    class Reader~T~ {
        +Reader(const proto::RoleAttributes&, const Callback&): void
        +Observe(): void
        +GetLatestObserved(): shared_ptr~T~
        +GetOldestObserved(): shared_ptr~T~
        -message_listener_: shared_ptr~transport::MessageListener~T~~
        -cache_size_: uint64_t
    }

    class ServiceBase {
        <<abstract>>
        +ServiceBase()
        +ServiceType(): string
        +GetServiceName(): const string&
        -service_name_: string
    }

    class Service~Req, Res~ {
        +Service(const string&, const ServiceCall&): void
        +RegisterService(const ServiceCall&): void
        +HandleRequest(const std::shared_ptr~Req~&, std::shared_ptr~Res~&): void
        -service_call_: ServiceCall
    }

    class ClientBase {
        <<abstract>>
        +ClientBase()
        +ServiceType(): string
        +GetServiceName(): const string&
        -service_name_: string
    }

    class Client~Req, Res~ {
        +Client(const string&): void
        +SendRequest(std::shared_ptr~Req~&, std::shared_ptr~Res~&, double): bool
        -requester_: shared_ptr~transport::Requester~Req, Res~~
    }

    class Scheduler {
        +CreateTask(const std::function~void()~&, const std::string&): bool
        +CreateTask(std::shared_ptr~Node~, const std::string&): bool
        +RemoveTask(const std::string&): bool
        +NotifyStart(): bool
        +NotifyStop(): bool
        +DispatchTask(Task*): bool
        +SetSchedPolicy(const string&): bool
        +Shutdown(): void
        -policy_: unique_ptr~Policy~
        -tasks_: base::AtomicHashMap~TaskID, TaskExe~
        -task_pool_: base::CCObjectPool~Task~
        -cr_pool_: base::CCObjectPool~CRoutine~
    }

    class Transport {
        +transport::Transport()
        +Join(const RoleAttributes&): void
        +Leave(const RoleAttributes&): void
        +EnableTransport(const Identity&, const OptionalMode&): void
        +DisableTransport(const Identity&, const OptionalMode&): void
        -transport_mutex_: mutex
        -participant_: shared_ptr~rtps::Participant~
        
        -- Intra --
        -intra_transmitter_factory_: unique_ptr~IntraTransmitterFactory~
        -intra_receiver_factory_: unique_ptr~IntraReceiverFactory~
        
        -- SHM --
        -shm_transmitter_factory_: unique_ptr~ShmTransmitterFactory~
        -shm_receiver_factory_: unique_ptr~ShmReceiverFactory~
        
        -- RTPS --
        -rtps_transmitter_factory_: unique_ptr~RtpsTransmitterFactory~
        -rtps_receiver_factory_: unique_ptr~RtpsReceiverFactory~
    }

    class TopologyManager {
        +TopologyManager()
        +Init(): bool
        +Shutdown(): bool
        +Join(const RoleAttributes&): bool
        +Leave(const RoleAttributes&): bool
        +AddNode(const RoleAttributes&): bool
        +RemoveNode(const RoleAttributes&): bool
        +AddChannel(const RoleAttributes&): bool
        +RemoveChannel(const RoleAttributes&): bool
        +GetNodes(vector~RoleAttributes~*): bool
        +GetChannels(vector~RoleAttributes~*): bool
        -node_manager_: shared_ptr~NodeManager~
        -channel_manager_: shared_ptr~ChannelManager~
        -service_manager_: shared_ptr~ServiceProviderManager~
        -change_listener_: shared_ptr~ChangeListener~
        -participation_: shared_ptr~rtps::Participation~
    }

    class Parameter {
        +Parameter(std::shared_ptr~Node~)
        +Set(const std::string&, const Parameter&)
        +Get(const std::string&, Parameter*)
        +List(std::vector~ParameterPair~*)
        -node_: std::weak_ptr~Node~
        -param_client_: std::shared_ptr~ParameterClient~
        -param_server_: std::shared_ptr~ParameterServer~
        -param_map_: std::unordered_map~std::string, Parameter~
        -param_mutex_: std::mutex
    }

    CyberRT ..> Node
    CyberRT ..> ComponentBase
    CyberRT ..> ServiceBase
    CyberRT ..> ClientBase
    CyberRT ..> Scheduler
    CyberRT ..> Transport
    CyberRT ..> TopologyManager
    CyberRT ..> Parameter

    Node <|-- ComponentBase
    ComponentBase <|-- Component
    WriterBase <|-- Writer
    ReaderBase <|-- Reader
    ServiceBase <|-- Service
    ClientBase <|-- Client

    Scheduler ..> Transport
    Transport ..> TopologyManager
    Node ..> Parameter

4.2. 传输层类图

classDiagram
    class TransmitterBase {
        <<abstract>>
        +TransmitterBase(const RoleAttributes&): void
        +TransmitterBase(const RoleAttributes&, const proto::QosProfile&): void
        +virtual ~TransmitterBase()
        +Transmit(const std::shared_ptr~DataT~&, const MessageInfo&): bool
        +GetMsgType(): const string&
        +GetProtoDesc(): const string&
        +GetSerializedType(): const string&
        +HasReader(): bool
        +GetReaderCount(): size_t
        +AddReader(const RoleAttributes&): void
        +RemoveReader(const RoleAttributes&): void
        +GetReaderSize(): size_t
        -role_attr_: RoleAttributes
        -msg_type_: string
        -proto_desc_: string
        -readers_: Container~RoleAttributes~
    }

    class ReceiverBase {
        <<abstract>>
        +ReceiverBase(const RoleAttributes&, const typename Transmitter~T~::MessageListener&): void
        +virtual ~ReceiverBase()
        +Shutdown(): void
        +HasNewMessage(): bool
        -role_attr_: RoleAttributes
        -msg_listener_: typename Transmitter~T~::MessageListener
        -enabled_: bool
    }

    class IntraTransmitter~T~ {
        +IntraTransmitter(const RoleAttributes&, const proto::QosProfile&): void
        +Transmit(const std::shared_ptr~T~&, const MessageInfo&): bool
        +AddListener(const typename Transmitter~T~::MessageListener&): void
        -readers_: Connection~T~
        -receiver_container_: Container~IntraReceiver~T~~*
    }

    class ShmTransmitter~T~ {
        +ShmTransmitter(const RoleAttributes&, const proto::QosProfile&): void
        +Transmit(const std::shared_ptr~T~&, const MessageInfo&): bool
        +AddListener(const typename Transmitter~T~::MessageListener&): void
        -shm_id_: uint64_t
        -shm_manager_: shared_ptr~transport::shmem::SegmentManager~
        -shm_notifier_: shared_ptr~transport::ConditionNotifier~
        -buf_idx_: uint32_t
        -shm_addr_: char*
        -msg_buffer_: string
    }

    class RtpsTransmitter~T~ {
        +RtpsTransmitter(const RoleAttributes&, const proto::QosProfile&): void
        +Transmit(const std::shared_ptr~T~&, const MessageInfo&): bool
        +AddListener(const typename Transmitter~T~::MessageListener&): void
        -pub_ : shared_ptr~rtps::Publisher~
        -msg_raw_ : transport::MessageInfo
        -msg_ : std::unique_ptr~T~
    }

    class IntraReceiver~T~ {
        +IntraReceiver(const RoleAttributes&, const typename Transmitter~T~::MessageListener&, const proto::QosProfile&): void
        +OnData(std::shared_ptr~T~&&): void
        -container_: shared_ptr~Container~T~~
    }

    class ShmReceiver~T~ {
        +ShmReceiver(const RoleAttributes&, const typename Transmitter~T~::MessageListener&, const proto::QosProfile&): void
        +OnData(uint64_t, uint32_t): void
        -shm_id_: uint64_t
        -shm_manager_: shared_ptr~transport::shmem::SegmentManager~
        -shm_notifier_: shared_ptr~transport::ConditionNotifier~
        -msg_buffer_: string
    }

    class RtpsReceiver~T~ {
        +RtpsReceiver(const RoleAttributes&, const typename Transmitter~T~::MessageListener&, const proto::QosProfile&): void
        +OnData(std::shared_ptr~T~&&): void
        -sub_ : shared_ptr~rtps::Subscriber~
    }

    class MessageInfo {
        +MessageInfo(): void
        +MessageInfo(const Identity&, uint64_t, uint64_t): void
        +operator==(const MessageInfo&): bool
        +operator<(const MessageInfo&): bool
        +SerializeTo(std::string*): bool
        +DeserializeFrom(const std::string&): bool
        -sender_id_: Identity
        -seq_: uint64_t
        -timestamp_: uint64_t
        -status_: MessageStatus
    }

    class QosProfile {
        +QosProfile(): void
        +static getDefaultQos(): QosProfile
        +getHistory(): HistoryPolicy
        +getReliability(): ReliabilityPolicy
        -history: HistoryPolicy
        -depth: uint32
        -reliability: ReliabilityPolicy
        -durability: DurabilityPolicy
        -deadline: Duration
        -lifespan: Duration
    }

    TransmitterBase <|-- IntraTransmitter
    TransmitterBase <|-- ShmTransmitter
    TransmitterBase <|-- RtpsTransmitter
    ReceiverBase <|-- IntraReceiver
    ReceiverBase <|-- ShmReceiver
    ReceiverBase <|-- RtpsReceiver
    IntraTransmitter ..> MessageInfo
    ShmTransmitter ..> MessageInfo
    RtpsTransmitter ..> MessageInfo
    IntraTransmitter ..> IntraReceiver
    ShmTransmitter ..> ShmReceiver
    RtpsTransmitter ..> RtpsReceiver
    IntraTransmitter ..> QosProfile
    ShmTransmitter ..> QosProfile
    RtpsTransmitter ..> QosProfile

5. 状态机

5.1. Cyber RT 系统状态机

stateDiagram-v2
    [*] --> UNINITIALIZED: 系统启动
    UNINITIALIZED --> INITIALIZING: 初始化请求
    INITIALIZING --> INITIALIZED: 初始化成功
    INITIALIZING --> FAILED: 初始化失败
    INITIALIZED --> STARTING: 启动请求
    STARTING --> RUNNING: 所有模块启动
    RUNNING --> PAUSED: 暂停请求
    PAUSED --> RUNNING: 恢复请求
    RUNNING --> EMERGENCY_STOP: 紧急停止
    EMERGENCY_STOP --> RUNNING: 恢复运行
    RUNNING --> STOPPING: 正常停止
    STOPPING --> STOPPED: 停止完成
    STOPPED --> [*]: 系统关闭
    FAILED --> [*]: 系统退出

    state INITIALIZING {
        [*] --> LOADING_CONFIG: 加载配置
        LOADING_CONFIG --> INITIALIZING_SCHEDULER: 初始化调度器
        INITIALIZING_SCHEDULER --> INITIALIZING_TRANSPORT: 初始化传输层
        INITIALIZING_TRANSPORT --> INITIALIZING_TOPOLOGY: 初始化拓扑管理
        INITIALIZING_TOPOLOGY --> INITIALIZED: 初始化完成
    }

    state STARTING {
        [*] --> STARTING_NODES: 启动节点
        STARTING_NODES --> STARTING_COMPONENTS: 启动组件
        STARTING_COMPONENTS --> STARTING_SERVICES: 启动服务
        STARTING_SERVICES --> STARTING_TRANSMITTERS: 启动传输器
        STARTING_TRANSMITTERS --> RUNNING: 运行中
    }

    state STOPPING {
        [*] --> STOPPING_TRANSMITTERS: 停止传输器
        STOPPING_TRANSMITTERS --> STOPPING_SERVICES: 停止服务
        STOPPING_SERVICES --> STOPPING_COMPONENTS: 停止组件
        STOPPING_COMPONENTS --> STOPPING_NODES: 停止节点
        STOPPING_NODES --> STOPPED: 停止完成
    }

5.2. 节点生命周期状态机

stateDiagram-v2
    [*] --> CREATED: 节点创建
    CREATED --> INITIALIZING: 初始化请求
    INITIALIZING --> INITIALIZED: 初始化成功
    INITIALIZING --> ERROR: 初始化失败
    INITIALIZED --> STARTING: 启动请求
    STARTING --> RUNNING: 启动成功
    STARTING --> ERROR: 启动失败
    RUNNING --> PAUSED: 暂停请求
    PAUSED --> RUNNING: 恢复请求
    RUNNING --> STOPPING: 停止请求
    STOPPING --> STOPPED: 停止完成
    STOPPED --> SHUTDOWN: 关闭请求
    SHUTDOWN --> TERMINATED: 关闭完成
    ERROR --> SHUTDOWN: 关闭请求
    TERMINATED --> [*]: 节点销毁
    
    note right of INITIALIZED
        节点已初始化
        可创建读写器
        可注册服务
    end note
    
    note right of RUNNING
        节点正在运行
        可收发消息
        服务可用
    end note
    
    note right of STOPPED
        节点停止
        暂停消息处理
        服务不可用
    end note

5.3. 消息传输状态机

stateDiagram-v2
    [*] --> IDLE: 初始状态
    IDLE --> PREPARING : 准备发送
    PREPARING --> SERIALIZING : 序列化消息
    SERIALIZING --> READY : 序列化完成
    READY --> TRANSMITTING : 开始传输
    TRANSMITTING --> SUCCESS : 传输成功
    TRANSMITTING --> FAILED : 传输失败
    TRANSMITTING --> QUEUED : 队列满,等待
    SUCCESS --> IDLE : 传输完成
    FAILED --> IDLE : 传输失败
    QUEUED --> TRANSMITTING : 缓冲区可用
    QUEUED --> FAILED : 超时失败
    FAILED --> RETRY : 重试传输
    RETRY --> TRANSMITTING : 重新开始传输
    
    state PREPARING {
        [*] --> VALIDATING_MSG
        VALIDATING_MSG --> ALLOCATING_BUFFER
        ALLOCATING_BUFFER --> COPYING_DATA
        COPYING_DATA --> READY
    }
    
    state TRANSMITTING {
        [*] --> CHECK_QOS
        CHECK_QOS --> ENFORCE_QOS_POLICY
        ENFORCE_QOS_POLICY --> SEND_OVER_CHANNEL
        SEND_OVER_CHANNEL --> SUCCESS
    }
    
    FAILED --> [*]
    SUCCESS --> [*]

5.4. 协程状态机

stateDiagram-v2
    [*] --> READY: 协程创建
    READY --> RUNNING: 调度执行
    RUNNING --> SUSPEND: 主动让出
    RUNNING --> BLOCKED: 等待资源
    SUSPEND --> READY: 被唤醒
    BLOCKED --> READY: 资源可用
    RUNNING --> FINISHED: 执行完成
    READY --> YIELD: 被抢占
    YIELD --> READY: 重新就绪
    FINISHED --> TERMINATED: 协程结束
    TERMINATED --> [*]: 内存回收
    
    state RUNNING {
        [*] --> PROCESSING
        PROCESSING --> WAITING_MUTEX
        PROCESSING --> WAITING_CONDITION
        PROCESSING --> WAITING_IO
        WAITING_MUTEX --> PROCESSING
        WAITING_CONDITION --> PROCESSING
        WAITING_IO --> PROCESSING
    }
    
    state FINISHED {
        [*] --> CLEANUP_RESOURCES
        CLEANUP_RESOURCES --> TERMINATED
    }

6. 源码分析

6.1. Cyber RT 初始化与启动

6.1.1. 初始化流程

  Cyber RT的初始化是整个框架运行的前提,它负责初始化各个子系统并建立协调机制。

// cyber/init.h
bool Init(const std::string& binary_name);

// cyber/init.cc
bool Init(const std::string& binary_name) {
  if (IsInit()) {
    return true;
  }

  SignalHandle::PreventDefault(SIGPIPE);

  if (!::apollo::cyber::common::GlobalData::Instance()->Init()) {
    AERROR << "global data init failed.";
    return false;
  }

  GlobalData::Instance()->SetProcessGroupName(binary_name);

  if (!LogWrapper::Instance()->Init()) {
    AERROR << "log wrapper init failed.";
    return false;
  }

  if (!::apollo::cyber::scheduler::Scheduler::Instance()->Init()) {
    AERROR << "scheduler init failed.";
    return false;
  }

  if (!::apollo::cyber::service_discovery::TopologyManager::Instance()->Init()) {
    AERROR << "topology manager init failed.";
    return false;
  }

  if (!::apollo::cyber::transport::Transport::Instance()->Init()) {
    AERROR << "transport init failed.";
    return false;
  }

  {
    std::lock_guard<std::mutex> lock(global_init_mutex_);
    global_init_.store(true);
  }
  AWARN << "cyber has been initialized successfully.";
  return true;
}

  初始化过程主要包括:

  1. 设置信号处理器,阻止SIGPIPE信号的默认行为
  2. 初始化全局数据管理器
  3. 初始化日志系统
  4. 初始化调度器
  5. 初始化拓扑管理器(服务发现)
  6. 初始化传输层

6.1.2. 关闭流程

void Clear() {
  if (!IsInit()) {
    return;
  }

  ::apollo::cyber::service_discovery::TopologyManager::Instance()->Shutdown();
  ::apollo::cyber::scheduler::Scheduler::Instance()->Shutdown();
  ::apollo::cyber::transport::Transport::Instance()->Shutdown();
  LogWrapper::Instance()->Shutdown();

  std::lock_guard<std::mutex> lock(global_init_mutex_);
  global_init_.store(false);
}

6.2. 节点管理机制

6.2.1. 节点基类设计

  Node是Cyber RT中最基本的概念之一,它封装了消息收发和服务调用的基本功能。

class Node {
 public:
  explicit Node(const std::string& node_name,
                const std::string& name_space = "");

  virtual ~Node();

  template <typename M0, typename C0>
  auto CreateWriter(const std::string& channel_name)
      -> std::shared_ptr<transport::Writer<M0>>;

  template <typename M0, typename C0>
  auto CreateReader(const std::string& channel_name, const C0& callback)
      -> std::shared_ptr<transport::Reader<M0>>;

  template <typename S0, typename S1>
  auto CreateService(const std::string& service_name,
                     const std::function<void(const S0&, S1*)>& service_call)
      -> std::shared_ptr<Service<S0, S1>>;

  template <typename S0, typename S1>
  auto CreateClient(const std::string& service_name)
      -> std::shared_ptr<Client<S0, S1>>;

  const std::string& Name() const;

  bool GetServiceAttr(const std::string& service_name,
                      proto::ServiceAttribute* service_attr);

  bool ListServices(std::vector<proto::ServiceAttribute>* services);

 private:
  void Init();
  std::string node_name_;
  std::string name_space_;
  std::vector<transport::WriterBasePtr> writers_;
  std::vector<transport::ReaderBasePtr> readers_;
  std::vector<ServiceBasePtr> servers_;
  std::vector<ClientBasePtr> clients_;
  std::mutex rw_mutex_;
  apollo::cyber::proto::RoleAttributes role_attr_;
};

6.2.2. 消息读写器创建

  Node提供了创建消息读写器的模板方法,这是实现发布订阅模式的关键。

template <typename M0, typename C0>
auto Node::CreateWriter(const std::string& channel_name)
    -> std::shared_ptr<transport::Writer<M0>> {
  proto::RoleAttributes role_attr;
  role_attr.set_node_name(node_name_);
  role_attr.set_channel_name(channel_name);
  role_attr.set_channel_type(transport::ParseMessageTypeName<M0>());
  
  auto writer = std::make_shared<transport::Writer<M0>>(role_attr);
  {
    std::lock_guard<std::mutex> lock(rw_mutex_);
    writers_.emplace_back(writer);
  }
  return writer;
}

template <typename M0, typename C0>
auto Node::CreateReader(const std::string& channel_name, const C0& callback)
    -> std::shared_ptr<transport::Reader<M0>> {
  proto::RoleAttributes role_attr;
  role_attr.set_node_name(node_name_);
  role_attr.set_channel_name(channel_name);
  role_attr.mutable_qos_profile()->CopyFrom(
      QosProfileConf::QOS_PROFILE_DEFAULT);

  auto reader = std::make_shared<transport::Reader<M0>>(role_attr, callback);
  {
    std::lock_guard<std::mutex> lock(rw_mutex_);
    readers_.emplace_back(reader);
  }
  return reader;
}

6.3. 传输层实现

6.3.1. 传输层架构

  Cyber RT的传输层支持多种传输方式,包括进程内传输、共享内存传输和RTPS网络传输。

namespace transport {

class Transport {
 public:
  virtual ~Transport();

  static Transport* Instance();

  void Join(const RoleAttributes& attr);
  void Leave(const RoleAttributes& attr);

  template <typename T>
  auto CreateTransmitter(const proto::RoleAttributes& role_attr,
                         const proto::QosProfile& qos_prof)
      -> std::shared_ptr<Transmitter<T>>;

  template <typename T>
  auto CreateReceiver(const proto::RoleAttributes& role_attr,
                      const typename Transmitter<T>::MessageListener& msg_listener,
                      const proto::QosProfile& qos_prof)
      -> std::shared_ptr<Receiver<T>>;

 private:
  Transport();

  void InitInternalParams();
  void EnableTransport(const Identity& host_id, 
                       const proto::OptionalMode& mode);
  void DisableTransport(const Identity& host_id, 
                        const proto::OptionalMode& mode);

  std::mutex transport_mutex_;
  std::shared_ptr<rtps::Participant> participant_;

  std::unique_ptr<IntraTransmitterFactory> intra_transmitter_factory_;
  std::unique_ptr<IntraReceiverFactory> intra_receiver_factory_;

  std::unique_ptr<ShmTransmitterFactory> shm_transmitter_factory_;
  std::unique_ptr<ShmReceiverFactory> shm_receiver_factory_;

  std::unique_ptr<RtpsTransmitterFactory> rtps_transmitter_factory_;
  std::unique_ptr<RtpsReceiverFactory> rtps_receiver_factory_;
};

}  // namespace transport

6.3.2. 共享内存传输实现

  共享内存传输是Cyber RT实现高性能IPC的重要手段:

template <typename T>
bool ShmTransmitter<T>::Transmit(const std::shared_ptr<T>& msg,
                                 const MessageInfo& msg_info) {
  RETURN_VAL_IF_NULL(msg, false);
  if (!shm_manager_->AcquireBuffer(&buf_idx_, &shm_addr_)) {
    AERROR << "acquire buffer failed.";
    return false;
  }

  uint32_t msg_size = 0;
  if (MessageType::SerializeToString(msg.get(), &msg_buffer_)) {
    msg_size = msg_buffer_.size();
  } else {
    AERROR << "serialize message failed.";
    shm_manager_->ReleaseBuffer(buf_idx_);
    return false;
  }

  auto hdr = reinterpret_cast<Header*>(shm_addr_);
  hdr->seq = msg_info.seq_num();
  hdr->hash = msg_info.sender_id().HashValue();
  hdr->size = msg_size;
  hdr->timestamp = msg_info.timestamp();

  memcpy(shm_addr_ + sizeof(Header), msg_buffer_.data(), msg_size);

  if (!shm_notifier_->Notify(shm_id_, buf_idx_)) {
    AERROR << "notify failed.";
    shm_manager_->ReleaseBuffer(buf_idx_);
    return false;
  }

  return true;
}

6.4. 调度系统

6.4.1. 调度器设计

  Cyber RT的调度器采用策略模式,支持多种调度算法。

class Scheduler {
 public:
  virtual ~Scheduler() = default;

  static Scheduler* Instance();

  virtual bool CreateTask(const std::function<void()>& func,
                          const std::string& name) = 0;
  virtual bool CreateTask(std::shared_ptr<Node> node,
                          const std::string& name) = 0;
  virtual bool RemoveTask(const std::string& name) = 0;
  virtual bool NotifyStart() = 0;
  virtual bool NotifyStop() = 0;

  virtual bool DispatchTask(Task* task) = 0;

 protected:
  Scheduler() = default;
};

// 具体调度策略实现
class ClassicalScheduler : public Scheduler {
 public:
  bool CreateTask(const std::function<void()>& func,
                  const std::string& name) override;
  bool CreateTask(std::shared_ptr<Node> node,
                  const std::string& name) override;
  bool RemoveTask(const std::string& name) override;
  bool NotifyStart() override;
  bool NotifyStop() override;
  bool DispatchTask(Task* task) override;

 private:
  bool CreateTaskInternal(const std::shared_ptr<Task>& task,
                          const std::string& name);
  bool CreateThreadForChoreography(std::shared_ptr<CRoutine> cr);
  bool CreateClassicThread(std::shared_ptr<CRoutine> cr);

  std::unordered_map<std::string, std::shared_ptr<Task>> tasks_;
  std::unordered_map<uint64_t, std::thread> threads_;
  std::unordered_map<std::string, std::vector<std::string>> node_proc_map_;
  std::unordered_set<std::string> raw_tasks_;
  std::mutex task_mutex_;

  apollo::cyber::base::AtomicHashMap<std::string, std::string> cr_concerned_map_;
};

6.4.2. 协程调度机制

  Cyber RT引入了协程机制,提高了并发处理效率:

class CRoutine {
 public:
  explicit CRoutine(const std::function<void()>& func);
  explicit CRoutine(std::shared_ptr<Runnable> runnable);
  virtual ~CRoutine();

  void Resume();
  void Yield();
  void Release();

  // 状态管理
  State GetState() const { return state_; }
  void SetState(State state) { state_ = state; }

  // 获取/设置ID
  uint64_t Id() const { return id_; }

  // 获取/设置优先级
  uint32_t Priority() const { return priority_; }
  void SetPriority(uint32_t priority) { priority_ = priority; }

  // 获取/设置所属处理器
  int64_t ProcessorId() const { return processor_id_; }
  void SetProcessorId(int64_t proc_id) { processor_id_ = proc_id; }

  std::string Name() const { return name_; }
  void SetName(std::string name) { name_ = name; }

 private:
  State state_;
  uint64_t id_;
  uint32_t priority_;
  int64_t processor_id_;
  std::string name_;
  std::shared_ptr<Runnable> runnable_;
};

6.5. 服务发现机制

6.5.1. 拓扑管理

  服务发现是Cyber RT中实现模块自动发现和连接的重要机制:

class TopologyManager {
 public:
  TopologyManager();
  virtual ~TopologyManager();

  bool Init();
  bool Shutdown();

  bool Join(const RoleAttributes& self_attr);
  bool Leave(const RoleAttributes& self_attr);

  bool AddNode(const RoleAttributes& self_attr);
  bool RemoveNode(const RoleAttributes& self_attr);

  bool AddChannel(const RoleAttributes& self_attr);
  bool RemoveChannel(const RoleAttributes& self_attr);

  bool GetNodes(std::vector<RoleAttributes>* nodes);
  bool GetChannels(std::vector<RoleAttributes>* channels);

  template <typename M0, typename C0>
  bool Subscribe(const std::string& channel_name, const C0& callback) {
    return change_listener_->Subscribe<M0, C0>(channel_name, callback);
  }

  template <typename M0>
  bool Unsubscribe(const std::string& channel_name) {
    return change_listener_->Unsubscribe<M0>(channel_name);
  }

  template <typename S0, typename S1>
  bool AddService(const std::string& service_name,
                  const std::function<void(const S0&, S1*)>& service_call) {
    return change_listener_->AddService<S0, S1>(service_name, service_call);
  }

  template <typename S0>
  bool RemoveService(const std::string& service_name) {
    return change_listener_->RemoveService<S0>(service_name);
  }

  template <typename S0, typename S1>
  auto GetServiceProxy(const std::string& service_name)
      -> std::shared_ptr<Service<S0, S1>> {
    return change_listener_->GetServiceProxy<S0, S1>(service_name);
  }

 private:
  void OnTopoChange(const TopologyChange& change);

  std::mutex manager_mutex_;
  std::shared_ptr<NodeManager> node_manager_;
  std::shared_ptr<ChannelManager> channel_manager_;
  std::shared_ptr<ServiceProviderManager> service_manager_;
  std::shared_ptr<ChangeListener> change_listener_;
  std::shared_ptr<rtps::Participation> participation_;
};

6.6. 组件框架

6.6.1. 组件基类

  Cyber RT提供了组件框架,简化了模块开发:

template <typename M0, typename M1 = NullType, typename M2 = NullType>
class Component : public ComponentBase {
 public:
  Component();
  virtual ~Component() = default;

  bool Init(const MultiSubOpt&M0, M1, M2>& multi_sub_opt,
            std::shared_ptr<Node> node) override;

 protected:
  virtual bool Proc(const std::shared_ptr<M0>& msg0,
                    const std::shared_ptr<M1>& msg1,
                    const std::shared_ptr<M2>& msg2) = 0;

 private:
  bool ProcByCaller(
      uint64_t caller_id, 
      const std::shared_ptr<apollo::cyber::Data>& data) override;

  std::vector<CallbackCaller<M0, M1, M2>*> callers_;
};

template <typename M0, typename M1, typename M2>
bool Component<M0, M1, M2>::Init(
    const MultiSubOpt<M0, M1, M2>& multi_sub_opt,
    std::shared_ptr<Node> node) {
  node_ = node;
  auto channel_ptrs = multi_sub_opt.GetChannelVec();
  for (uint32_t i = 0; i < channel_ptrs.size(); ++i) {
    if (std::get<0>(channel_ptrs[i]) == nullptr) {
      continue;
    }
    auto caller = new CallbackCaller<M0, M1, M2>();
    auto callback = RegisterBindingCallback(
        &CallbackCaller<M0, M1, M2>::TemplateCallback, caller);
    std::string channel = *(std::get<0>(channel_ptrs[i]));
    auto reader = node_->template CreateReader<M0, M1, M2>(
        channel, callback, *(std::get<1>(channel_ptrs[i])));
    callers_.emplace_back(caller);
  }
  return true;
}

7. 设计模式

7.1. 单例模式

  Cyber RT的多个核心组件使用了单例模式,确保系统中只有一个实例:

template <typename T>
T* GetSingleton() {
  static T instance;
  return &instance;
}

#define SINGLETON(T)                                    \
 public:                                                \
  static T* Instance() {                                \
    return GetSingleton<T>();                           \
  }                                                     \
  void ConfigReinit() {                                 \
    delete GetSingleton<T>();                           \
    Instance();                                         \
  }                                                     \
 private:                                               \
  T();                                                  \
  ~T();                                                 \
  friend class GetSingleton<T>;

7.2. 策略模式

  调度器使用了策略模式,支持不同的调度算法:

class Scheduler {
 public:
  virtual bool CreateTask(const std::function<void()>& func,
                          const std::string& name) = 0;
  virtual bool NotifyStart() = 0;
  virtual bool NotifyStop() = 0;
  // ... 其他纯虚函数
};

class FairScheduler : public Scheduler {
  // 实现公平调度算法
};

class ClassicScheduler : public Scheduler {
  // 实现经典调度算法
};

7.3. 观察者模式

  服务发现机制使用观察者模式实现拓扑变化通知:

class TopologyObserver {
 public:
  virtual void OnJoin(const RoleAttributes& attr) = 0;
  virtual void OnLeave(const RoleAttributes& attr) = 0;
  virtual void OnUpdate(const RoleAttributes& attr) = 0;
};

class ChangeListener : public TopologyObserver {
  // 实现拓扑变化监听
};

7.4. 工厂模式

  传输层使用工厂模式创建不同类型的传输器:

template <typename M0>
class TransmitterFactory {
 public:
  static auto CreateTransmitter(const proto::RoleAttributes& role_attr,
                                const proto::QosProfile& qos_profile)
      -> std::shared_ptr<Transmitter<M0>> {
    // 根据qos_profile创建相应类型的传输器
  }
};

8. 总结

  Apollo Cyber RT是一个高度优化的实时运行时框架,其架构设计充分考虑了自动驾驶场景的特殊需求。通过模块化设计、高效的消息传递机制和灵活的调度策略,Cyber RT为自动驾驶系统提供了强大而稳定的运行环境。其采用的设计模式使系统具有良好的可扩展性和可维护性,为自动驾驶技术的发展提供了坚实基础.