软件结构图
cyber入口
cyber的入口在"cyber/mainboard"目录中:
├── mainboard.cc // 主函数
├── module_argument.cc // 模块输入参数
├── module_argument.h
├── module_controller.cc // 模块加载,卸载
└── module_controller.h
mainboard中的文件比较少,也很好理解,我们先从"mainboard.cc"中开始分析:
int main(int argc, char** argv) {
// 解析参数
ModuleArgument module_args;
module_args.ParseArgument(argc, argv);
// 初始化cyber
apollo::cyber::Init(argv[0]);
// 加载模块
ModuleController controller(module_args);
if (!controller.Init()) {
controller.Clear();
AERROR << "module start error.";
return -1;
}
// 等待cyber关闭
apollo::cyber::WaitForShutdown();
// 卸载模块
controller.Clear();
AINFO << "exit mainboard.";
return 0;
}
mainboard 是 cyberRT 的入口,init 方法都在这里触发。Module 也在这里启动。
解析参数ModuleArgument
解析参数是在"ModuleArgument"类中实现的,主要是解析加载DAG文件时候带的参数
void ModuleArgument::ParseArgument(const int argc, char* const argv[]) {
// 二进制模块名称
binary_name_ = std::string(basename(argv[0]));
// 解析参数
GetOptions(argc, argv);
// 如果没有process_group_和sched_name_,则赋值为默认值
if (process_group_.empty()) {
process_group_ = DEFAULT_process_group_;
}
if (sched_name_.empty()) {
sched_name_ = DEFAULT_sched_name_;
}
// 如果有,则设置对应的参数
GlobalData::Instance()->SetProcessGroup(process_group_);
GlobalData::Instance()->SetSchedName(sched_name_);
// 打印dag_conf配置
AINFO << "binary_name_ is " << binary_name_ << ", process_group_ is "
<< process_group_ << ", has " << dag_conf_list_.size() << " dag conf";
for (std::string& dag : dag_conf_list_) {
AINFO << "dag_conf: " << dag;
}
}
模块加载ModuleController
在"ModuleController"实现cyber模块的加载,在"ModuleController::Init()"中调用"LoadAll()"来加载所有模块