美文网首页
Apollo cyber 源码解析—— launch 详解

Apollo cyber 源码解析—— launch 详解

作者: 飞天小小猫 | 来源:发表于2020-09-16 17:39 被阅读0次

    以scripts/camera.sh脚本为例,若要启用camera,只需要执行该脚本即可
    查看内容,在start()中调用了cyber_launch start /apollo/modules/drivers/camera/launch/camera.launch
    cyber_launch就是cyber\tools\cyber_launch\cyber_launch py脚本文件,它是何时加载的呢?

    在camera.sh Line24, source "${DIR}/apollo_base.sh"
    配置了基本的环境,而且执行了source /apollo/cyber/setup.bash,其中就把cyber_launch加入了PATH中,这样就可找到了

    先看camera.launch文件里的内容有哪些:

    <cyber>
        <module>
            <name>camera</name>
            <dag_conf>/apollo/modules/drivers/camera/dag/camera.dag</dag_conf>
            <process_name>usb_cam</process_name>
        </module>
    </cyber>
    

    沿用了ros1的xml格式,自定义了模块名,以及配置文件dag_conf
    cyber\tools\cyber_launch\cyber_launch中的start方法中,关键代码:

    if process_name not in process_list:
        if process_type == 'binary':
            pw = ProcessWrapper(
                process_name.split()[0], 0, [
                    ""], process_name, process_type,
                exception_handler)
        # Default is library
        else:
            pw = ProcessWrapper(
                g_binary_name, 0, dag_dict[
                    str(process_name)], process_name,
                process_type, sched_name, exception_handler)
        result = pw.start()
        pmon.register(pw)
        process_list.append(process_name)
    

    如果时可执行文件,就用py的多进程直接调起来,如果是lib文件,要通过g_binary_name="mainboard"这个程序来动态加载lib库文件
    也就是说,mainboard可执行文件是通用的程序,按照制定的标准api来加载运行lib

    源码位置: cyber\mainboard\mainboard.cc
    逻辑比较简单,主要是解析参数,然后将参数传入ModuleController的对象,在ModuleController::Init()中会调用ModuleController::LoadAll() -> ModuleController::LoadModule
    看下关键代码:

    bool ModuleController::LoadModule(const DagConfig& dag_config) {
        class_loader_manager_.LoadLibrary(load_path);
        for (auto& component : module_config.components()) {
          const std::string& class_name = component.class_name();
          std::shared_ptr<ComponentBase> base =
              class_loader_manager_.CreateClassObj<ComponentBase>(class_name);
          if (base == nullptr || !base->Initialize(component.config())) {
            return false;
          }
          component_list_.emplace_back(std::move(base));
        }
    
        for (auto& component : module_config.timer_components()) {
          const std::string& class_name = component.class_name();
          std::shared_ptr<ComponentBase> base =
              class_loader_manager_.CreateClassObj<ComponentBase>(class_name);
          if (base == nullptr || !base->Initialize(component.config())) {
            return false;
          }
          component_list_.emplace_back(std::move(base));
        }
      }
      return true;
    }
    

    首先会解析出lib的路径,然后通过class_loader_manager_加载动态库,拿到基类指针,并调用基类方法base->Initialize(component.config()),在基类方法中,调用虚函数Init()和Pross(),利用继承的特性调用到实际加载的lib子类中的初始化方法和处理方法。

    相关文章

      网友评论

          本文标题:Apollo cyber 源码解析—— launch 详解

          本文链接:https://www.haomeiwen.com/subject/xmjhyktx.html