无人驾驶笔记系列(五):gflags的使用和设置

一、Gflags简介

Gflags是一种命令行解析工具,主要用于解析用命令行执行可执行文件时传入的参数。就是这个功能。

二、安装

候补

三、先贴个例子

#include 
#include 

DEFINE_bool(isvip, false, "If Is VIP");
DEFINE_string(ip, "127.0.0.1", "connect ip");
DECLARE_int32(port);
DEFINE_int32(port, 80, "listen port");

int main(int argc, char** argv)
{
  google::ParseCommandLineFlags(&argc, &argv, true);
  std::cout<<"ip:"<<FLAGS_ip<<std::endl;
  std::cout<<"port:"<<FLAGS_port<<std::endl;
  if (FLAGS_isvip)
  {
      std::cout<<"isvip:"<<FLAGS_isvip<<std::endl;
  }
  google::ShutDownCommandLineFlags();
  return 0;
}

链接时使用 -gflags ,运行使用./gflags -ip="211.152.52.106" -port=8080 -isvip=true

输出结果如下:

ip:211.152.52.106
port:8080
isvip:1

四、flag变量的使用

用DEFINE宏定义的flag都可以像普通的变量一样进行调用,定义的变量是以FLAGS_为前缀,如上述例子中定义了两个变量FLAGS_ipFLAGS_port,可以像普通的变量一样对其进行读写。

DEFINE_string(ip, "127.0.0.1", "connect ip");
DEFINE_int32(port, 80, "listen port");

std::cout<<"ip:"<<FLAGS_ip<<std::endl;
std::cout<<"port:"<<FLAGS_port<<std::endl;

五、apollo 框架如何调用flag变量

在另外一个文件中如果想要使用上述定义的FLAGS_port,只需要在该文件的头部进行如下声明

DECLARE_int32(port);

上述声明从功能上等价于

extern FLAGS_port; 

如果其他文件需要使用定义好的flag,就在.h头文件中进行DECLARE声明,然后只需要#include该头文件即可,这样是一种显示的依赖关系,并且该flag成为一个全局变量。

我们以apollomsf_localization模块配置参数加载过程说明:

申明

// modules/localization/common/localization_gflags.h
#pragma once

#include "gflags/gflags.h"

DECLARE_string(localization_module_name);

DECLARE_double(localization_publish_freq);

DECLARE_string(localization_config_file);
DECLARE_string(rtk_adapter_config_file);
DECLARE_string(msf_adapter_config_file);
DECLARE_string(msf_visual_adapter_config_file);

定义

// modules/localization/common/localization_gflags.cc
#include "modules/localization/common/localization_gflags.h"

DEFINE_string(localization_module_name, "localization",
              "localization module name");

DEFINE_double(localization_publish_freq, 100,
              "localization publishing frequency.");

DEFINE_string(rtk_adapter_config_file,
              "/apollo/modules/localization/conf/rtk_adapter.conf",
              "rtk adapter configuration");

DEFINE_string(localization_config_file,
              "/apollo/modules/localization/conf/localization_config.pb.txt",
              "localization config file");

DEFINE_string(msf_adapter_config_file,
              "/apollo/modules/localization/conf/msf_adapter.conf",
              "msf adapter configuration");

DEFINE_string(msf_visual_adapter_config_file,
              "/apollo/modules/localization/conf/msf_visual_adapter.conf",
              "msf visualization adapter configuration");

引用

这样我们就可以直接使用这个参数了。

// modules/localization/msf/msf_localization_component.cc

#include "modules/localization/msf/msf_localization_component.h"

#include "modules/common/math/quaternion.h"
#include "modules/common/time/time.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/localization/common/localization_gflags.h"

bool MSFLocalizationComponent::InitConfig() {
  lidar_topic_ = FLAGS_lidar_topic;
  bestgnsspos_topic_ = FLAGS_gnss_best_pose_topic;
  gnss_heading_topic_ = FLAGS_heading_topic;

  if (publisher_->InitConfig() != true) {
    AERROR << "Init publisher config failed.";
    return false;
  }

  if (localization_.Init().ok() != true) {
    AERROR << "Init class MSFLocalization failed.";
    return false;
  }

  return true;
}

六、参数是怎么来的?

你是不是有好多问号了?虽然用起来了,但是它怎么来的了?

一切都得从这句指令开始

启动指令

cyber_launch modules/localization/launch/msf_localization.launch

launch文件

// modules/localization/launch/msf_localization.launch

<cyber>
    <module>
        <name>localization</name>
        <dag_conf>/apollo/modules/localization/dag/dag_streaming_msf_localization.dag</dag_conf>
        <process_name>localization</process_name>
    </module>
</cyber>

dag文件

//modules/localization/dag/dag_streaming_msf_localization.dag

# Define all coms in DAG streaming.
module_config {
    module_library : "/apollo/bazel-bin/modules/localization/msf/libmsf_localization_component.so"

    components {
      class_name : "MSFLocalizationComponent"
      config {
        name : "msf_localization"
        //请注意这条配置
        flag_file_path : "/apollo/modules/localization/conf/localization.conf"
        readers: [
          {
            channel: "/apollo/sensor/gnss/imu"
            qos_profile: {
              depth : 10
            }
            pending_queue_size: 50
          }
        ]
      }
    }
}

conf文件

// modules/localization/conf/localization.conf

# The pointcloud topic name.
# type: string
# default: /apollo/sensor/velodyne64/compensator/PointCloud2
--lidar_topic=/apollo/sensor/pandar64/compensator/PointCloud2

# The lidar extrinsics file
# type: string
# default: /apollo/modules/localization/msf/params/velodyne_params/velodyne128_novatel_extrinsics.yaml
--lidar_extrinsics_file=/apollo/modules/drivers/pandar/params/v4/pandar64_novatel_extrinsics.yaml

# The lidar height file
# type: string
# default: /apollo/modules/localization/msf/params/velodyne_params/velodyne64_height.yaml
--lidar_height_file=/apollo/modules/localization/msf/params/velodyne_params/pandar64_height.yaml

好了,到现在一起一目了然了。

你可能感兴趣的:(无人驾驶,apollo)