1、工程实现之参数读取类

有时候在做工程时不希望把参数写死在程序里面希望可以通过参数文件去动态调整,而不是改一个参数再把程序重新编译一次,所以这里实现一个参数读取类:
我们直接把类定义在头文件中:
目录结构

|
|--bin
|   |——testPd
|--config
    |——default.txt
|--paramReader.h
|--testPd.cpp
|--build
|--CMakeLists.txt 
/// paramReader.h
// 不要重复包含
#pragma once
// filestream 读取或者输出文件
#include "fstream"
// 标准io,cout,cin,cerr,clog等
#include "iostream"
// 映射(数据结构)
#include "map"
// 类的实现
class ParameterReader
{
public:
    // 构造函数,默认的路径是../config/default.txt 
    ParameterReader(std::string filename="../config/default.txt")
    {
        // 初始化一个input filestream 打开路径下文件
        std::ifstream fin(filename.c_str());
        if(!fin)
        {
            // 没找到就报个错
            std::cerr<<"parameter file does not exist!"<<std::endl;
            return;
        }
        // 当没有到文件末尾end of file时
        while(!fin.eof())
        {
            std::string str;
            // 读一行拷贝给str
            std::getline(fin,str);
            if(str[0] == '#')
            {
            // 开头是#说明是注释,就跳过
                continue;
            }
            // 找到中间等于号位置
            int pos =str.find("=");
            if(pos==-1)
            {
            // 没找到就说明不符合格式,跳过
                continue;
            }
            // 把等于号前面的记作key
            std::string key =str.substr(0,pos);
            // 等于号后面的记作value
            std::string value = str.substr(pos+1,str.length());
            // 存在映射表里面
            data[key] = value;
            // 情况不妙,撤退
            if(!fin.good())
            break;
        }
    }
    std::string getData(std::string key)
    {
        // 用迭代器去找
        std::map<std::string,std::string>::iterator iter = data.find(key);
        if(iter == data.end())
        {
            // 找不到我就报错
            std::cerr<<"Parameter name:"<<key<<"not found"<<std::endl;
            return std::string ("NOT FOUND");
        }
        // 找到了我就返回value
        return iter->second;
    }
public:
    // 这就是类里面的映射表,一般设置为私有,但是自己用就随便一点吧
    std::map<std::string,std::string> data;
};

写个测试函数测试一下并且表明用法:

/// testPd.cpp
// 包含一下写的类
#include "paramReader.h"
// 标准io流
#include "iostream"
// 设置io流输出的一些函数
#include "iomanip"
// 主函数入口
int main()
{
  // 生成一个对象
  ParameterReader pd;
  // 相机x方向焦距是float类型,用atof转成float,c_str转成字符数组
  float fx = atof(pd.getData("camera.fx").c_str());
  std::cout<<"camera.fx ="<<std::setw(4)<<fx<<std::endl;
  // rgb图像的路径,就是字符流就不用转了
  std::string rgb_dir = pd.getData("rgb_dir").c_str();
  std::cout<<"The filepath for rgb images is:"<<std::setw(4)<<rgb_dir<<std::endl;
  return 0}

参数文件这么写:

# this is a parameter file to store params
# use it to change the parameters without compiling the source code again
# define params as " key = value" like camera.fx = 325.5



# for camera intrin
camera.cx=325.5
camera.cy=253.5
camera.fx=518.0
camera.fy=519.0
camera.scale=1000.0

# for index 
start_index=1
end_index=780
# for data
rgb_dir=/opt/data/private/Code/RGBDSLAM/Lecture2/image/data/rgb_png/
rgb_extension=.png
depth_dir=/opt/data/private/Code/RGBDSLAM/Lecture2/image/data/depth_png/
depth_extension=.png

# for point cloud
voxel_grid=0.01

# enable real-time visualization
visualize_pointcloud=yes

# minimum matches
min_good_match=10

# min_inliers
min_inliers=10

#maximum motion error
max_norm=2.0

# part 7
keyframe_threshold=0.15
max_norm_lp=2.0

# loop closure
check_loop_closure=yes
nearby_loops=5
random_loops=5

CMakeLists.txt

# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(test)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
include_directories(
    ${PROJECT_SOURCE_DIR}
)
add_executable(testPd testPd.cpp)

随后拿终端编译运行一下,测试应该没有错误

cd build && cmake .. && make && ../bin/testPd
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页