您好,登錄后才能下訂單哦!
這篇文章主要介紹了C++ Cartographer怎么加載配置文件的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇C++ Cartographer怎么加載配置文件文章都會(huì)有所收獲,下面我們一起來看看吧。
在node_main.cc文件中,有如下代碼
std::tie(node_options, trajectory_options) = LoadOptions(FLAGS_configuration_directory, FLAGS_configuration_basename);
std::tie作用是同時(shí)對(duì)多個(gè)變量賦值,但是只能個(gè)從元組tuple賦值,在node_options.cc中有如下定義:
std::tuple<NodeOptions, TrajectoryOptions> LoadOptions( const std::string& configuration_directory, const std::string& configuration_basename) { // 獲取配置文件所在的目錄 auto file_resolver = absl::make_unique<cartographer::common::ConfigurationFileResolver>(std::vector<std::string>{configuration_directory}); // 讀取配置文件內(nèi)容到code中 const std::string code = file_resolver->GetFileContentOrDie(configuration_basename); // 根據(jù)給定的字符串, 生成一個(gè)lua字典 cartographer::common::LuaParameterDictionary lua_parameter_dictionary( code, std::move(file_resolver)); // 創(chuàng)建元組tuple,元組定義了一個(gè)有固定數(shù)目元素的容器, 其中的每個(gè)元素類型都可以不相同 // 將配置文件的內(nèi)容填充進(jìn)NodeOptions與TrajectoryOptions, 并返回 return std::make_tuple(CreateNodeOptions(&lua_parameter_dictionary), CreateTrajectoryOptions(&lua_parameter_dictionary)); }
這返回值為元組tuple.
ps:vector初始化:
要注意“()”和“{}”這樣的初始化情況,比如:
std::vector<int> nVec(10,1); // 包含10個(gè)元素,且值為1
std::vector<int> nVec{10,1}; // 包含2個(gè)元素,值分別為10,1
CreateNodeOptions,是定義在node_options.h文件里的一個(gè)結(jié)構(gòu)體,同理CreateTrajectoryOptions,里面的參數(shù)是由lua文件傳入的.
trajectoryoptions只在開始軌跡的時(shí)候用了,見node_main.cc
在trajectory_options.cc中有如下定義
void CheckTrajectoryOptions(const TrajectoryOptions& options) { CHECK_GE(options.num_subdivisions_per_laser_scan, 1); CHECK_GE(options.num_laser_scans + options.num_multi_echo_laser_scans + options.num_point_clouds, 1) << "Configuration error: 'num_laser_scans', " "'num_multi_echo_laser_scans' and 'num_point_clouds' are " "all zero, but at least one is required."; }
這個(gè)說明是要至少一個(gè)激光,或者激光+超聲雷達(dá)+點(diǎn)云的個(gè)數(shù)要>1才能運(yùn)行程序
NodeOptions CreateNodeOptions( ::cartographer::common::LuaParameterDictionary* const lua_parameter_dictionary) { NodeOptions options; options.map_builder_options = ::cartographer::mapping::CreateMapBuilderOptions( lua_parameter_dictionary->GetDictionary("map_builder").get()); options.map_frame = lua_parameter_dictionary->GetString("map_frame"); options.lookup_transform_timeout_sec = lua_parameter_dictionary->GetDouble("lookup_transform_timeout_sec"); options.submap_publish_period_sec = lua_parameter_dictionary->GetDouble("submap_publish_period_sec"); options.pose_publish_period_sec = lua_parameter_dictionary->GetDouble("pose_publish_period_sec"); options.trajectory_publish_period_sec = lua_parameter_dictionary->GetDouble("trajectory_publish_period_sec"); if (lua_parameter_dictionary->HasKey("publish_to_tf")) { options.publish_to_tf = lua_parameter_dictionary->GetBool("publish_to_tf"); } if (lua_parameter_dictionary->HasKey("publish_tracked_pose")) { options.publish_tracked_pose = lua_parameter_dictionary->GetBool("publish_tracked_pose"); } if (lua_parameter_dictionary->HasKey("use_pose_extrapolator")) { options.use_pose_extrapolator = lua_parameter_dictionary->GetBool("use_pose_extrapolator"); } return options; }
上面的程序是根據(jù)lua字典中的參數(shù), 生成protobuf的序列化數(shù)據(jù)結(jié)構(gòu), 結(jié)構(gòu)體NodeOptions定義在頭文件中,其中有個(gè)元素為::cartographer::mapping::proto::MapBuilderOptions map_builder_options;是proto類型,在上述程序中的第一個(gè)參數(shù)被賦值
在node_options.cc有個(gè)類ConfigurationFileResolver,定義在configuration_file_resolver.h中,公有繼承來自FileResolver
class ConfigurationFileResolver : public FileResolver{ public: // c++11: explicit關(guān)鍵字 的作用就是防止類構(gòu)造函數(shù)的隱式自動(dòng)轉(zhuǎn)換 explicit ConfigurationFileResolver( const std::vector<std::string>& configuration_files_directories); std::string GetFullPathOrDie(const std::string& basename) override; std::string GetFileContentOrDie(const std::string& basename) override; private: std::vector<std::string> configuration_files_directories_; };
FileResolver定義在lua_parameter_dictionary.h中:
class FileResolver { public: virtual ~FileResolver() {} virtual std::string GetFullPathOrDie(const std::string& basename) = 0; virtual std::string GetFileContentOrDie(const std::string& basename) = 0; };
這個(gè)都是虛函數(shù),只是個(gè)接口
cartographer經(jīng)常有對(duì)接口類的繼承
ConfigurationFileResolver的構(gòu)造函數(shù)在configuration_file_resolver.cc里面
ConfigurationFileResolver::ConfigurationFileResolver( const std::vector<std::string>& configuration_files_directories) : configuration_files_directories_(configuration_files_directories) { configuration_files_directories_.push_back(kConfigurationFilesDirectory); }
這個(gè)函數(shù)有個(gè)初始化列表,可以看到最終傳入的參數(shù)是kConfigurationFilesDirectory,這個(gè)參數(shù)定義在config.h.這個(gè)文件里,這個(gè)文件是config.h.cmake編譯生成的,如下內(nèi)容
namespace cartographer { namespace common { constexpr char kConfigurationFilesDirectory[] = "@CARTOGRAPHER_CONFIGURATION_FILES_DIRECTORY@"; constexpr char kSourceDirectory[] = "@PROJECT_SOURCE_DIR@"; } // namespace common } // namespace cartographer
一個(gè)是定義工程配置文件的文件夾,一個(gè)是工程地址的目錄,在config.h中會(huì)生成匹配自己電腦的字符串地址.那么上面的ConfigurationFileResolver的構(gòu)造函數(shù)就是為了傳入自己電腦的某些目錄地址..
GetFullPathOrDie:遍歷整個(gè)文件夾文件名看看能不能找到相應(yīng)文件,如不能就報(bào)錯(cuò)
GetFileContentOrDie的作用是看傳入的地址變量是不是空的,然后通過GetFullPathOrDie暴力查找是否在當(dāng)前目錄中存在,然后讀取配置文件轉(zhuǎn)為string格式然后返回.
再回到node_options.cc中
接下來是讀取配置文件到code中,然后從code和之前讀取的file_resolver生成一個(gè)lua字典
lua是個(gè)類似cpp的程序語言,定義在lua_parameter_dictionary.cc中,不細(xì)說了
如果想自己通過lua文件寫入一些配置和參數(shù),步驟如下
在自己寫的lua配置文件中寫入自己的參數(shù),如th=1.1,
在想一下這個(gè)th是屬于node_options還是trajectory_options,如在node_options中,則在node_options.h中定義好自己的數(shù)據(jù)類型和初始值,如double th = 1.1;
然后在node_options.cc中寫入
if (lua_parameter_dictionary->HasKey("th")) { options.th = lua_parameter_dictionary->GetDouble("th"); }
關(guān)于“C++ Cartographer怎么加載配置文件”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“C++ Cartographer怎么加載配置文件”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。