目录
1. proto文件
2. .lua配置文件
3. 代码
1)读取lua文件
2)赋值给proto options
获取proto参数值有两种方式:1)lua文件 2)通过service,例如如下代码中 InitialTrajectoryPose 的赋值
3) 如何使用 proto options
纯定位模式入口
我们需要掌握的是什么?要知道在哪里改变参数,从而更深入的理解算法。
TODO:
1. sensor topic 在哪里设置?
2. 自定义的一堆service 如何使用,效果如何?
系统的配置文件框架主要有三部分构成:
1. proto文件
- 根据自己的需要,自定义proto文件。比如:我们希望 参数 A 通过配置文件来设定具体数值,则 参数A 在proto文件中被定义。
- 一系列的proto文件 位于 cartographer/mapping/proto
- 如何自定义proto文件呢?例如:
//如下代码取自 cartographer/mapping/proto/trajectory_builder_options.proto
import "cartographer/mapping/proto/2d/local_trajectory_builder_options_2d.proto";
import "cartographer/mapping/proto/3d/local_trajectory_builder_options_3d.proto";
// 一组参数的集合称为options,用 message name{} 的形式定义
// options内部可以包含对个其他的options,必须import其所在的proto 如上面两行
// 也可以在内部定义新的 options 如 PureLocalizationTrimmerOptions
message TrajectoryBuilderOptions {
LocalTrajectoryBuilderOptions2D trajectory_builder_2d_options = 1;
LocalTrajectoryBuilderOptions3D trajectory_builder_3d_options = 2;
InitialTrajectoryPose initial_trajectory_pose = 4;
reserved 5;
bool pure_localization = 3 [deprecated = true];
message PureLocalizationTrimmerOptions {
int32 max_submaps_to_keep = 1;
}
PureLocalizationTrimmerOptions pure_localization_trimmer = 6;
bool collate_fixed_frame = 7;
bool collate_landmarks = 8;
}
2. .lua配置文件
对应的lua配置文件:
// 代码取自 cartographer2019-05-25/configuration_files/trajectory_builder.lua
// 对应的,也要 include options 相应的lua文件
include "trajectory_builder_2d.lua"
include "trajectory_builder_3d.lua"
// 这些options的名字必须是大写,但是不必和proto中保持一致
// 但是成员变量的名字必须和proto中保持一致
TRAJECTORY_BUILDER = {
trajectory_builder_2d = TRAJECTORY_BUILDER_2D,
trajectory_builder_3d = TRAJECTORY_BUILDER_3D,
-- pure_localization_trimmer = { -- 这个是定位模式
-- max_submaps_to_keep = 3,
-- },
collate_fixed_frame = true,
collate_landmarks = false,
}
3. 代码
主要分为如下三个步骤:
1)读取lua文件
- 这部分不细看了
2)赋值给proto options
其赋值主要有两种方式:
- 1. options.set_变量名(参数值)
- 2. options.mutable_变量名 = 参数值
获取proto参数值有两种方式:1)lua文件 2)通过service,例如如下代码中 InitialTrajectoryPose 的赋值
// 如下代码位于: cartographer_ros/node.cc
// cartographer_ros_msgs::StartTrajectory 是自定义的service,位于cartographer_ros_msgs/srv/StartTrajectory.srv
bool Node::HandleStartTrajectory(
::cartographer_ros_msgs::StartTrajectory::Request& request,
::cartographer_ros_msgs::StartTrajectory::Response& response) {
// 这个是在cartographer_ros/trajectory_options.h 中 自定义的类,与proto中的不同。
// 该类型包含了
// cartographer::mapping::proto::TrajectoryBuilderOptions 变量
// 和 一些其他的topic,频率等变量(这些变量会根据数据集的不同可能会变化,因此在最外层)。
// 对应 cartographer_ros/configuration_files/backpack_2d.lua 等文件
// 这些lua文件全部 include "map_builder.lua"
// include "trajectory_builder.lua"
// 所以,核心的lua还是 map_builder.lua; trajectory_builder.lua
// 而 map_builder.lua; trajectory_builder.lua 又分别包含其他的很多lua 就这样一层一层的。
TrajectoryOptions trajectory_options;
// 将lua转换为 proto options
// tie 可以将tuple解包,赋值给相应的参数。std::ignore 表示忽略第一个参数
std::tie(std::ignore, trajectory_options) = LoadOptions(
request.configuration_directory, request.configuration_basename);
// 省略中间部分
// 可以注意到:cartographer/configuration_files/trajectory_builder.lua中,
// 并没有给InitialTrajectoryPose 这个变量赋值,虽然 proto中包含这个变量
// 而是留到service中进行赋值
if (request.use_initial_pose) {
// InitialTrajectoryPose 是在 cartographer/mapping/proto/trajectory_builder_options.proto
// 中定义的一个 options , 其赋值主要有两种方式:
// 1. options.set_变量名(参数值)
// 2. options.mutable_变量名 = 参数值
// 注意:options 也是一个成员变量,其赋值也是使用上述两种方式之一
::cartographer::mapping::proto::InitialTrajectoryPose
initial_trajectory_pose;
initial_trajectory_pose.set_to_trajectory_id(
request.relative_to_trajectory_id);
*initial_trajectory_pose.mutable_relative_pose() =
cartographer::transform::ToProto(pose);
initial_trajectory_pose.set_timestamp(cartographer::common::ToUniversal(
::cartographer_ros::FromRos(ros::Time(0))));
*trajectory_options.trajectory_builder_options
.mutable_initial_trajectory_pose() = initial_trajectory_pose;
}
}
3) 如何使用 proto options
- 1. 如果想使用 options 成员变量,则先通过 has_name()来判断lua中是否给这个变量赋值了
- 2. 直接 name()即可获得该变量的值
// 位于 map_builder.cc
int MapBuilder::AddTrajectoryBuilder(
const std::set<SensorId>& expected_sensor_ids,
const proto::TrajectoryBuilderOptions& trajectory_options,
LocalSlamResultCallback local_slam_result_callback)
{
std::unique_ptr<LocalTrajectoryBuilder2D> local_trajectory_builder;
// 1. 如果想使用 options 成员变量,则先通过 has_name()来判断lua中是否给这个变量赋值了
if (trajectory_options.has_trajectory_builder_2d_options()) {
local_trajectory_builder = absl::make_unique<LocalTrajectoryBuilder2D>(
2. 直接 name()即可获得该变量的值
trajectory_options.trajectory_builder_2d_options(),
SelectRangeSensorIds(expected_sensor_ids));
}
// 下面这部分同理
if (trajectory_options.has_initial_trajectory_pose()) {
const auto& initial_trajectory_pose =
trajectory_options.initial_trajectory_pose();
pose_graph_->SetInitialTrajectoryPose(
trajectory_id, initial_trajectory_pose.to_trajectory_id(),
transform::ToRigid3(initial_trajectory_pose.relative_pose()),
common::FromUniversal(initial_trajectory_pose.timestamp()));
}
}
纯定位模式入口
// 位于文件 map_builder.cc
void MaybeAddPureLocalizationTrimmer(
const int trajectory_id,
const proto::TrajectoryBuilderOptions& trajectory_options,
PoseGraph* pose_graph) {
if (trajectory_options.pure_localization()) {
// 已经被弃用了,现在是改为使用pure_localization_trimmer
LOG(WARNING)
<< "'TrajectoryBuilderOptions::pure_localization' field is deprecated. "
"Use 'TrajectoryBuilderOptions::pure_localization_trimmer' instead.";
pose_graph->AddTrimmer(absl::make_unique<PureLocalizationTrimmer>(
trajectory_id, 3 /* max_submaps_to_keep */));
return;
}
if (trajectory_options.has_pure_localization_trimmer()) {
pose_graph->AddTrimmer(absl::make_unique<PureLocalizationTrimmer>(
trajectory_id,
trajectory_options.pure_localization_trimmer().max_submaps_to_keep()));
}
}
// 对应的 proto : cartographer/mapping/proto/trajectory_builder_options.proto
message TrajectoryBuilderOptions {
LocalTrajectoryBuilderOptions2D trajectory_builder_2d_options = 1;
LocalTrajectoryBuilderOptions3D trajectory_builder_3d_options = 2;
InitialTrajectoryPose initial_trajectory_pose = 4;
reserved 5;
bool pure_localization = 3 [deprecated = true];// deprecated 被弃用
message PureLocalizationTrimmerOptions {
int32 max_submaps_to_keep = 1;
}
PureLocalizationTrimmerOptions pure_localization_trimmer = 6;
bool collate_fixed_frame = 7;
bool collate_landmarks = 8;
}
我们需要掌握的是什么?要知道在哪里改变参数,从而更深入的理解算法。
1. proto文件全部位于:cartographer/mapping/proto
2. lua文件:
1)外层文件全部位于:cartographer_ros/configuration_files。 例如 backpack_2d.lua。
2)算法相关的文件全部位于:cartographer/configuration_files