1. 概述
Apollo Cyber RT是专为自动驾驶场景设计的高性能开源运行时框架。该框架基于集中式计算模型,针对自动驾驶领域的高并发、低延迟和高吞吐量需求进行了深度优化。Cyber RT提供了高效的模块间通信机制、灵活的任务调度系统以及便捷的开发工具集,支持实时数据处理和任务调度,为自动驾驶系统提供了稳定可靠的技术基础。
2. 软件架构图
3. 调用流程图
4. 详细UML类图
4.1. 核心框架类图
4.2. 传输层类图
5. 状态机
5.1. Cyber RT 系统状态机
5.2. 节点生命周期状态机
5.3. 消息传输状态机
5.4. 协程状态机
6. 源码分析
6.1. Cyber RT 初始化与启动
6.1.1. 初始化流程
Cyber RT的初始化是整个框架运行的前提,它负责初始化各个子系统并建立协调机制。
cpp
// 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;
}
初始化过程主要包括:
- 设置信号处理器,阻止SIGPIPE信号的默认行为
- 初始化全局数据管理器
- 初始化日志系统
- 初始化调度器
- 初始化拓扑管理器(服务发现)
- 初始化传输层
6.1.2. 关闭流程
cpp
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中最基本的概念之一,它封装了消息收发和服务调用的基本功能。
cpp
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提供了创建消息读写器的模板方法,这是实现发布订阅模式的关键。
cpp
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网络传输。
cpp
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的重要手段:
cpp
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的调度器采用策略模式,支持多种调度算法。
cpp
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引入了协程机制,提高了并发处理效率:
cpp
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中实现模块自动发现和连接的重要机制:
cpp
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提供了组件框架,简化了模块开发:
cpp
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的多个核心组件使用了单例模式,确保系统中只有一个实例:
cpp
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. 策略模式
调度器使用了策略模式,支持不同的调度算法:
cpp
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. 观察者模式
服务发现机制使用观察者模式实现拓扑变化通知:
cpp
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. 工厂模式
传输层使用工厂模式创建不同类型的传输器:
cpp
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为自动驾驶系统提供了强大而稳定的运行环境。其采用的设计模式使系统具有良好的可扩展性和可维护性,为自动驾驶技术的发展提供了坚实基础.