Repository: slam-code/cartographer
Branch: master
Commit: 4332493a434d
Files: 273
Total size: 954.9 KB
Directory structure:
gitextract_6vczu7ti/
├── .gitignore
├── README.md
├── common/
│ ├── blocking_queue.h
│ ├── blocking_queue_test.cc
│ ├── ceres_solver_options.cc
│ ├── ceres_solver_options.h
│ ├── config.h
│ ├── config.h.cmake
│ ├── configuration_file_resolver.cc
│ ├── configuration_file_resolver.h
│ ├── fixed_ratio_sampler.cc
│ ├── fixed_ratio_sampler.h
│ ├── fixed_ratio_sampler_test.cc
│ ├── histogram.cc
│ ├── histogram.h
│ ├── lua.h
│ ├── lua_parameter_dictionary.cc
│ ├── lua_parameter_dictionary.h
│ ├── lua_parameter_dictionary_test.cc
│ ├── lua_parameter_dictionary_test_helpers.h
│ ├── make_unique.h
│ ├── make_unique_test.cc
│ ├── math.h
│ ├── math_test.cc
│ ├── mutex.h
│ ├── port.h
│ ├── port_le_test.cpp
│ ├── proto/
│ │ └── ceres_solver_options.proto
│ ├── rate_timer.h
│ ├── rate_timer_test.cc
│ ├── thread_pool.cc
│ ├── thread_pool.h
│ ├── time.cc
│ └── time.h
├── ground_truth/
│ └── compute_relations_metrics_main.cc
├── io/
│ ├── cairo_types.h
│ ├── coloring_points_processor.cc
│ ├── coloring_points_processor.h
│ ├── counting_points_processor.cc
│ ├── counting_points_processor.h
│ ├── file_writer.cc
│ ├── file_writer.h
│ ├── fixed_ratio_sampling_points_processor.cc
│ ├── fixed_ratio_sampling_points_processor.h
│ ├── intensity_to_color_points_processor.cc
│ ├── intensity_to_color_points_processor.h
│ ├── min_max_range_filtering_points_processor.cc
│ ├── min_max_range_filtering_points_processor.h
│ ├── null_points_processor.h
│ ├── outlier_removing_points_processor.cc
│ ├── outlier_removing_points_processor.h
│ ├── pcd_writing_points_processor.cc
│ ├── pcd_writing_points_processor.h
│ ├── ply_writing_points_processor.cc
│ ├── ply_writing_points_processor.h
│ ├── points_batch.cc
│ ├── points_batch.h
│ ├── points_processor.h
│ ├── points_processor_pipeline_builder.cc
│ ├── points_processor_pipeline_builder.h
│ ├── proto_stream.cc
│ ├── proto_stream.h
│ ├── proto_stream_test.cc
│ ├── xray_points_processor.cc
│ ├── xray_points_processor.h
│ ├── xyz_writing_points_processor.cc
│ └── xyz_writing_points_processor.h
├── kalman_filter/
│ ├── gaussian_distribution.h
│ ├── gaussian_distribution_test.cc
│ ├── pose_tracker.cc
│ ├── pose_tracker.h
│ ├── pose_tracker_test.cc
│ ├── proto/
│ │ └── pose_tracker_options.proto
│ ├── unscented_kalman_filter.h
│ └── unscented_kalman_filter_test.cc
├── mapping/
│ ├── collated_trajectory_builder.cc
│ ├── collated_trajectory_builder.h
│ ├── detect_floors.cc
│ ├── detect_floors.h
│ ├── global_trajectory_builder_interface.h
│ ├── id.h
│ ├── imu_tracker.cc
│ ├── imu_tracker.h
│ ├── map_builder.cc
│ ├── map_builder.h
│ ├── odometry_state_tracker.cc
│ ├── odometry_state_tracker.h
│ ├── probability_values.cc
│ ├── probability_values.h
│ ├── probability_values_test.cc
│ ├── proto/
│ │ ├── map_builder_options.proto
│ │ ├── sparse_pose_graph.proto
│ │ ├── sparse_pose_graph_options.proto
│ │ ├── submap_visualization.proto
│ │ ├── trajectory.proto
│ │ ├── trajectory_builder_options.proto
│ │ └── trajectory_connectivity.proto
│ ├── sparse_pose_graph/
│ │ ├── constraint_builder.cc
│ │ ├── constraint_builder.h
│ │ ├── optimization_problem_options.cc
│ │ ├── optimization_problem_options.h
│ │ └── proto/
│ │ ├── constraint_builder_options.proto
│ │ └── optimization_problem_options.proto
│ ├── sparse_pose_graph.cc
│ ├── sparse_pose_graph.h
│ ├── submaps.cc
│ ├── submaps.h
│ ├── submaps_test.cc
│ ├── trajectory_builder.cc
│ ├── trajectory_builder.h
│ ├── trajectory_connectivity.cc
│ ├── trajectory_connectivity.h
│ ├── trajectory_connectivity_test.cc
│ └── trajectory_node.h
├── mapping_2d/
│ ├── global_trajectory_builder.cc
│ ├── global_trajectory_builder.h
│ ├── local_trajectory_builder.cc
│ ├── local_trajectory_builder.h
│ ├── local_trajectory_builder_options.cc
│ ├── local_trajectory_builder_options.h
│ ├── map_limits.h
│ ├── map_limits_test.cc
│ ├── probability_grid.h
│ ├── probability_grid_test.cc
│ ├── proto/
│ │ ├── cell_limits.proto
│ │ ├── local_trajectory_builder_options.proto
│ │ ├── map_limits.proto
│ │ ├── probability_grid.proto
│ │ ├── range_data_inserter_options.proto
│ │ └── submaps_options.proto
│ ├── range_data_inserter.cc
│ ├── range_data_inserter.h
│ ├── range_data_inserter_test.cc
│ ├── ray_casting.cc
│ ├── ray_casting.h
│ ├── scan_matching/
│ │ ├── ceres_scan_matcher.cc
│ │ ├── ceres_scan_matcher.h
│ │ ├── ceres_scan_matcher_test.cc
│ │ ├── correlative_scan_matcher.cc
│ │ ├── correlative_scan_matcher.h
│ │ ├── correlative_scan_matcher_test.cc
│ │ ├── fast_correlative_scan_matcher.cc
│ │ ├── fast_correlative_scan_matcher.h
│ │ ├── fast_correlative_scan_matcher_test.cc
│ │ ├── fast_global_localizer.cc
│ │ ├── fast_global_localizer.h
│ │ ├── occupied_space_cost_functor.h
│ │ ├── proto/
│ │ │ ├── ceres_scan_matcher_options.proto
│ │ │ ├── fast_correlative_scan_matcher_options.proto
│ │ │ └── real_time_correlative_scan_matcher_options.proto
│ │ ├── real_time_correlative_scan_matcher.cc
│ │ ├── real_time_correlative_scan_matcher.h
│ │ ├── real_time_correlative_scan_matcher_test.cc
│ │ ├── rotation_delta_cost_functor.h
│ │ └── translation_delta_cost_functor.h
│ ├── sparse_pose_graph/
│ │ ├── constraint_builder.cc
│ │ ├── constraint_builder.h
│ │ ├── optimization_problem.cc
│ │ ├── optimization_problem.h
│ │ └── spa_cost_function.h
│ ├── sparse_pose_graph.cc
│ ├── sparse_pose_graph.h
│ ├── sparse_pose_graph_test.cc
│ ├── submaps.cc
│ ├── submaps.h
│ ├── submaps_test.cc
│ ├── xy_index.h
│ └── xy_index_test.cc
├── mapping_3d/
│ ├── acceleration_cost_function.h
│ ├── ceres_pose.cc
│ ├── ceres_pose.h
│ ├── global_trajectory_builder.cc
│ ├── global_trajectory_builder.h
│ ├── hybrid_grid.h
│ ├── hybrid_grid_test.cc
│ ├── imu_integration.cc
│ ├── imu_integration.h
│ ├── kalman_local_trajectory_builder.cc
│ ├── kalman_local_trajectory_builder.h
│ ├── kalman_local_trajectory_builder_options.cc
│ ├── kalman_local_trajectory_builder_options.h
│ ├── kalman_local_trajectory_builder_test.cc
│ ├── local_trajectory_builder.cc
│ ├── local_trajectory_builder.h
│ ├── local_trajectory_builder_interface.h
│ ├── local_trajectory_builder_options.cc
│ ├── local_trajectory_builder_options.h
│ ├── motion_filter.cc
│ ├── motion_filter.h
│ ├── motion_filter_test.cc
│ ├── optimizing_local_trajectory_builder.cc
│ ├── optimizing_local_trajectory_builder.h
│ ├── optimizing_local_trajectory_builder_options.cc
│ ├── optimizing_local_trajectory_builder_options.h
│ ├── proto/
│ │ ├── hybrid_grid.proto
│ │ ├── kalman_local_trajectory_builder_options.proto
│ │ ├── local_trajectory_builder_options.proto
│ │ ├── motion_filter_options.proto
│ │ ├── optimizing_local_trajectory_builder_options.proto
│ │ ├── range_data_inserter_options.proto
│ │ └── submaps_options.proto
│ ├── range_data_inserter.cc
│ ├── range_data_inserter.h
│ ├── range_data_inserter_test.cc
│ ├── rotation_cost_function.h
│ ├── scan_matching/
│ │ ├── ceres_scan_matcher.cc
│ │ ├── ceres_scan_matcher.h
│ │ ├── ceres_scan_matcher_test.cc
│ │ ├── fast_correlative_scan_matcher.cc
│ │ ├── fast_correlative_scan_matcher.h
│ │ ├── fast_correlative_scan_matcher_test.cc
│ │ ├── interpolated_grid.h
│ │ ├── interpolated_grid_test.cc
│ │ ├── occupied_space_cost_functor.h
│ │ ├── precomputation_grid.cc
│ │ ├── precomputation_grid.h
│ │ ├── precomputation_grid_test.cc
│ │ ├── proto/
│ │ │ ├── ceres_scan_matcher_options.proto
│ │ │ └── fast_correlative_scan_matcher_options.proto
│ │ ├── real_time_correlative_scan_matcher.cc
│ │ ├── real_time_correlative_scan_matcher.h
│ │ ├── real_time_correlative_scan_matcher_test.cc
│ │ ├── rotation_delta_cost_functor.h
│ │ ├── rotational_scan_matcher.cc
│ │ ├── rotational_scan_matcher.h
│ │ └── translation_delta_cost_functor.h
│ ├── sparse_pose_graph/
│ │ ├── constraint_builder.cc
│ │ ├── constraint_builder.h
│ │ ├── optimization_problem.cc
│ │ ├── optimization_problem.h
│ │ ├── optimization_problem_test.cc
│ │ └── spa_cost_function.h
│ ├── sparse_pose_graph.cc
│ ├── sparse_pose_graph.h
│ ├── submaps.cc
│ ├── submaps.h
│ └── translation_cost_function.h
├── sensor/
│ ├── collator.cc
│ ├── collator.h
│ ├── collator_test.cc
│ ├── compressed_point_cloud.cc
│ ├── compressed_point_cloud.h
│ ├── compressed_point_cloud_test.cc
│ ├── configuration.cc
│ ├── configuration.h
│ ├── data.h
│ ├── ordered_multi_queue.cc
│ ├── ordered_multi_queue.h
│ ├── ordered_multi_queue_le_test.cc
│ ├── ordered_multi_queue_test.cc
│ ├── point_cloud.cc
│ ├── point_cloud.h
│ ├── point_cloud_test.cc
│ ├── proto/
│ │ ├── adaptive_voxel_filter_options.proto
│ │ ├── configuration.proto
│ │ └── sensor.proto
│ ├── range_data.cc
│ ├── range_data.h
│ ├── range_data_test.cc
│ ├── voxel_filter.cc
│ ├── voxel_filter.h
│ └── voxel_filter_test.cc
└── transform/
├── proto/
│ └── transform.proto
├── rigid_transform.cc
├── rigid_transform.h
├── rigid_transform_le2_grid2_test.cc
├── rigid_transform_test_helpers.h
├── transform.cc
├── transform.h
├── transform_interpolation_buffer.cc
├── transform_interpolation_buffer.h
├── transform_interpolation_buffer_test.cc
└── transform_test.cc
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# 忽略*.o和*.a文件
*.[oa]
*.[out]
*build
build #过滤整个build文件夹
devel
*.class #过滤所有.class文件
.idea
cartographer
cartographer_ros
ceres-solver
Eigen
src
.zip
orig
backup
pictures
html
note
================================================
FILE: README.md
================================================
# cartographer
关于谷歌slam地图库 [cartographer](https://github.com/googlecartographer/cartographer)的源码注释。(只含源码)
博客文章:
* [知乎](https://zhuanlan.zhihu.com/learnmoreonce) (简略)
* [CSDN](http://blog.csdn.net/learnmoreonce) (详细)
源码分析的markdown文件可在 [这里]( https://github.com/slam4code/SLAM/tree/master/cartographer-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90 )
查找。
我的微信公众号:slamcode
================================================
FILE: common/blocking_queue.h
================================================
#ifndef CARTOGRAPHER_COMMON_BLOCKING_QUEUE_H_
#define CARTOGRAPHER_COMMON_BLOCKING_QUEUE_H_
#include
#include
#include
#include "cartographer/common/mutex.h"
#include "cartographer/common/port.h"
#include "cartographer/common/time.h"
#include "glog/logging.h"
/*
* BlockingQueue是线程安全的阻塞队列,(生产者消费者模式)
* 不可拷贝不可赋值
* 构造函数初始化队列大小,kInfiniteQueueSize=0默认不限制容量。queue_size限制容量:通过条件变量做到.
* Push()添加元素,容量不够时,阻塞等待
* Pop()删除元素,没有元素时,阻塞等待
* Peek()返回下一个应该弹出的元素
* PushWithTimeout(),添加元素,若超时则返回false
* PopWithTimeout(),删除元素,若超时则返回false
*
* */
namespace cartographer {
namespace common {
// A thread-safe blocking queue that is useful for producer/consumer patterns.
// 'T' must be movable.
template
class BlockingQueue {
public:
static constexpr size_t kInfiniteQueueSize = 0;
// Constructs a blocking queue with infinite queue size.
BlockingQueue() : BlockingQueue(kInfiniteQueueSize) {} //默认不限制容量
BlockingQueue(const BlockingQueue&) = delete;
BlockingQueue& operator=(const BlockingQueue&) = delete;
// Constructs a blocking queue with a size of 'queue_size'.限制容量
explicit BlockingQueue(const size_t queue_size) : queue_size_(queue_size) {}
// Pushes a value onto the queue. Blocks if the queue is full.
void Push(T t) {
MutexLocker lock(&mutex_);//加锁
lock.Await([this]() REQUIRES(mutex_) { return QueueNotFullCondition(); });//队列未满才能push
deque_.push_back(std::move(t)); //移动而非拷贝
}
// Like push, but returns false if 'timeout' is reached.
bool PushWithTimeout(T t, const common::Duration timeout) { //最多等待timeout时间
MutexLocker lock(&mutex_);
if (!lock.AwaitWithTimeout(
[this]() REQUIRES(mutex_) { return QueueNotFullCondition(); },
timeout)) {
return false;
}
deque_.push_back(std::move(t));
return true;
}
// Pops the next value from the queue. Blocks until a value is available.
T Pop() {
MutexLocker lock(&mutex_); //加锁
lock.Await([this]() REQUIRES(mutex_) { return QueueNotEmptyCondition(); });//队列不为空才能pop()
T t = std::move(deque_.front());
deque_.pop_front();
return t;
}
// Like Pop, but can timeout. Returns nullptr in this case.
T PopWithTimeout(const common::Duration timeout) {
MutexLocker lock(&mutex_);
if (!lock.AwaitWithTimeout(
[this]() REQUIRES(mutex_) { return QueueNotEmptyCondition(); },
timeout)) {
return nullptr;
}
T t = std::move(deque_.front());
deque_.pop_front();
return t;
}
// Returns the next value in the queue or nullptr if the queue is empty.
// Maintains ownership. This assumes a member function get() that returns
// a pointer to the given type R.
template
const R* Peek() {
MutexLocker lock(&mutex_);
if (deque_.empty()) {
return nullptr;
}
return deque_.front().get();
}
// Returns the number of items currently in the queue.
size_t Size() {
MutexLocker lock(&mutex_);
return deque_.size();
}
private:
// Returns true iff the queue is not empty.
bool QueueNotEmptyCondition() REQUIRES(mutex_) { return !deque_.empty(); }
// Returns true iff the queue is not full.
bool QueueNotFullCondition() REQUIRES(mutex_) {
return queue_size_ == kInfiniteQueueSize || deque_.size() < queue_size_;
}
Mutex mutex_;
const size_t queue_size_ GUARDED_BY(mutex_);
std::deque deque_ GUARDED_BY(mutex_);
};
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_BLOCKING_QUEUE_H_
================================================
FILE: common/blocking_queue_test.cc
================================================
#include "cartographer/common/blocking_queue.h"
#include
#include
#include "cartographer/common/make_unique.h"
#include "cartographer/common/time.h"
#include "gtest/gtest.h"
namespace cartographer {
namespace common {
namespace {
TEST(BlockingQueueTest, testPushPeekPop) {
BlockingQueue> blocking_queue;//元素是智能指针,不限容
blocking_queue.Push(common::make_unique(42)); //添加
ASSERT_EQ(1, blocking_queue.Size()); //size==1
blocking_queue.Push(common::make_unique(24)); //添加
ASSERT_EQ(2, blocking_queue.Size()); //size==2
EXPECT_EQ(42, *blocking_queue.Peek()); //顶元素==42
ASSERT_EQ(2, blocking_queue.Size()); //队列大小是2
EXPECT_EQ(42, *blocking_queue.Pop());
ASSERT_EQ(1, blocking_queue.Size());
EXPECT_EQ(24, *blocking_queue.Pop());
ASSERT_EQ(0, blocking_queue.Size());
EXPECT_EQ(nullptr, blocking_queue.Peek());
ASSERT_EQ(0, blocking_queue.Size());
}
TEST(BlockingQueueTest, testPushPopSharedPtr) {
BlockingQueue> blocking_queue; //不限容
blocking_queue.Push(std::make_shared(42));
blocking_queue.Push(std::make_shared(24));
EXPECT_EQ(42, *blocking_queue.Pop());
EXPECT_EQ(24, *blocking_queue.Pop());
}
TEST(BlockingQueueTest, testPopWithTimeout) {
BlockingQueue> blocking_queue;
EXPECT_EQ(nullptr, //没有插入,所以是nullptr
blocking_queue.PopWithTimeout(common::FromMilliseconds(150)));
}
TEST(BlockingQueueTest, testPushWithTimeout) {
BlockingQueue> blocking_queue(1);//限容
EXPECT_EQ(true, //插入成功
blocking_queue.PushWithTimeout(common::make_unique(42),
common::FromMilliseconds(150)));
EXPECT_EQ(false, //失败,因为队列大小是1
blocking_queue.PushWithTimeout(common::make_unique(15),
common::FromMilliseconds(150)));
EXPECT_EQ(42, *blocking_queue.Pop());
EXPECT_EQ(0, blocking_queue.Size());
}
TEST(BlockingQueueTest, testPushWithTimeoutInfinteQueue) {
BlockingQueue> blocking_queue; //不限容量
EXPECT_EQ(true,
blocking_queue.PushWithTimeout(common::make_unique(42),
common::FromMilliseconds(150)));
EXPECT_EQ(true,
blocking_queue.PushWithTimeout(common::make_unique(45),
common::FromMilliseconds(150)));
EXPECT_EQ(42, *blocking_queue.Pop());
EXPECT_EQ(45, *blocking_queue.Pop());
EXPECT_EQ(0, blocking_queue.Size());
}
TEST(BlockingQueueTest, testBlockingPop) {
BlockingQueue> blocking_queue;
ASSERT_EQ(0, blocking_queue.Size());
int pop = 0;
//多线程测试
std::thread thread([&blocking_queue, &pop] { pop = *blocking_queue.Pop(); });
std::this_thread::sleep_for(common::FromMilliseconds(100));
blocking_queue.Push(common::make_unique(42));
thread.join();
ASSERT_EQ(0, blocking_queue.Size());
EXPECT_EQ(42, pop);
}
TEST(BlockingQueueTest, testBlockingPopWithTimeout) {
BlockingQueue> blocking_queue;
ASSERT_EQ(0, blocking_queue.Size());
int pop = 0;
//多线程测试
std::thread thread([&blocking_queue, &pop] {
pop = *blocking_queue.PopWithTimeout(common::FromMilliseconds(2500));
});
std::this_thread::sleep_for(common::FromMilliseconds(100));
blocking_queue.Push(common::make_unique(42));
thread.join();
ASSERT_EQ(0, blocking_queue.Size());
EXPECT_EQ(42, pop);
}
} // namespace
} // namespace common
} // namespace cartographer
================================================
FILE: common/ceres_solver_options.cc
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cartographer/common/ceres_solver_options.h"
namespace cartographer {
namespace common {
/*
根据lua文件设置
*/
proto::CeresSolverOptions CreateCeresSolverOptionsProto(
common::LuaParameterDictionary* parameter_dictionary)
{
proto::CeresSolverOptions proto;
proto.set_use_nonmonotonic_steps(
parameter_dictionary->GetBool("use_nonmonotonic_steps"));//是否设置使用nonmonotonic
proto.set_max_num_iterations(
parameter_dictionary->GetNonNegativeInt("max_num_iterations"));//迭代次数
proto.set_num_threads(parameter_dictionary->GetNonNegativeInt("num_threads"));//线程数
CHECK_GT(proto.max_num_iterations(), 0);
CHECK_GT(proto.num_threads(), 0);
return proto;
}
/*
根据proto文件设置
*/
ceres::Solver::Options CreateCeresSolverOptions(
const proto::CeresSolverOptions& proto)
{
ceres::Solver::Options options;//建立临时对象
options.use_nonmonotonic_steps = proto.use_nonmonotonic_steps();//为临时对象赋值
options.max_num_iterations = proto.max_num_iterations(); //赋值
options.num_threads = proto.num_threads(); //赋值
return options;
}
} // namespace common
} // namespace cartographer
================================================
FILE: common/ceres_solver_options.h
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARTOGRAPHER_COMMON_CERES_SOLVER_OPTIONS_H_
#define CARTOGRAPHER_COMMON_CERES_SOLVER_OPTIONS_H_
#include "cartographer/common/lua_parameter_dictionary.h"
#include "cartographer/common/proto/ceres_solver_options.pb.h"
#include "ceres/ceres.h"
namespace cartographer {
namespace common {
/*
配置加载类, 根据lua设置 CeresSolver的选项
*/
proto::CeresSolverOptions CreateCeresSolverOptionsProto(
common::LuaParameterDictionary* parameter_dictionary);
//根据proto设置 CeresSolver的选项
ceres::Solver::Options CreateCeresSolverOptions(
const proto::CeresSolverOptions& proto);
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_CERES_SOLVER_OPTIONS_H_
================================================
FILE: common/config.h
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARTOGRAPHER_COMMON_CONFIG_H_
#define CARTOGRAPHER_COMMON_CONFIG_H_
namespace cartographer {
namespace common {
constexpr char kConfigurationFilesDirectory[] = //设置配置文件的路径
"";
constexpr char kSourceDirectory[] = "./";
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_CONFIG_H_
================================================
FILE: common/config.h.cmake
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARTOGRAPHER_COMMON_CONFIG_H_
#define CARTOGRAPHER_COMMON_CONFIG_H_
namespace cartographer {
namespace common {
constexpr char kConfigurationFilesDirectory[] = //设置配置文件的路径
"@CARTOGRAPHER_CONFIGURATION_FILES_DIRECTORY@";
constexpr char kSourceDirectory[] = "@PROJECT_SOURCE_DIR@";
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_CONFIG_H_
================================================
FILE: common/configuration_file_resolver.cc
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cartographer/common/configuration_file_resolver.h"
#include
#include
#include
#include "cartographer/common/config.h"//根据config.h.cmake生成
#include "glog/logging.h"
namespace cartographer {
namespace common {
ConfigurationFileResolver::ConfigurationFileResolver(
const std::vector& configuration_files_directories)
: configuration_files_directories_(configuration_files_directories) {
configuration_files_directories_.push_back(kConfigurationFilesDirectory);//配置文件夹路径
}
string ConfigurationFileResolver::GetFullPathOrDie(const string& basename) { //根据文件 夹和basename生成文件名
for (const auto& path : configuration_files_directories_) {
const string filename = path + "/" + basename;
std::ifstream stream(filename.c_str());
if (stream.good()) {
LOG(INFO) << "Found '" << filename << "' for '" << basename << "'.";
return filename;
}
}
LOG(FATAL) << "File '" << basename << "' was not found.";
}
string ConfigurationFileResolver::GetFileContentOrDie(const string& basename) {//根据文件名读取file内容
const string filename = GetFullPathOrDie(basename);
std::ifstream stream(filename.c_str()); //文件输入流
return string((std::istreambuf_iterator(stream)),//使用迭代器初始化string对象
std::istreambuf_iterator());
}
} // namespace common
} // namespace cartographer
================================================
FILE: common/configuration_file_resolver.h
================================================
/*
* Copyright 2016 The Cartographer Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARTOGRAPHER_COMMON_CONFIGURATION_FILE_RESOLVER_H_
#define CARTOGRAPHER_COMMON_CONFIGURATION_FILE_RESOLVER_H_
#include
#include "cartographer/common/lua_parameter_dictionary.h"
#include "cartographer/common/port.h"
namespace cartographer {
namespace common {
/*
ConfigurationFileResolver是配置文件解析类,继承自FileResolver类
在给定的目录下搜索配置文件,
*/
// A 'FileResolver' for the 'LuaParameterDictionary' that reads files from disk.
// It searches the 'configuration_files_directories' in order to find the
// requested filename. The last place searched is always the
// 'configuration_files/' directory installed with Cartographer. It contains
// reasonable configuration for the various Cartographer components which
// provide a good starting ground for new platforms.
class ConfigurationFileResolver : public FileResolver {
public:
explicit ConfigurationFileResolver(
const std::vector& configuration_files_directories);
string GetFullPathOrDie(const string& basename) override;//获取文件的全部路径
string GetFileContentOrDie(const string& basename) override; //获取文件内容
private:
std::vector configuration_files_directories_;
};
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_CONFIGURATION_FILE_RESOLVER_H_
================================================
FILE: common/fixed_ratio_sampler.cc
================================================
#include "cartographer/common/fixed_ratio_sampler.h"
namespace cartographer {
namespace common {
FixedRatioSampler::FixedRatioSampler(const double ratio) : ratio_(ratio) {}
FixedRatioSampler::~FixedRatioSampler() {}
bool FixedRatioSampler::Pulse() {
//如果当前采样率 samples/ pulses低于固定采样率,此次事件计入采样.
++num_pulses_;
if (static_cast(num_samples_) / num_pulses_ < ratio_) {
++num_samples_;
return true;
}
return false;
}
string FixedRatioSampler::DebugString() {
return std::to_string(num_samples_) + " (" +
std::to_string(100. * num_samples_ / num_pulses_) + "%)";
}
} // namespace common
} // namespace cartographer
================================================
FILE: common/fixed_ratio_sampler.h
================================================
#ifndef CARTOGRAPHER_COMMON_FIXED_RATIO_SAMPLER_H_
#define CARTOGRAPHER_COMMON_FIXED_RATIO_SAMPLER_H_
#include
#include "cartographer/common/port.h"
namespace cartographer {
namespace common {
/*
FixedRatioSampler是频率固定的采样器类,目的是从数据流中均匀的按照固定频率采样数据
FixedRatioSampler不可拷贝,不可赋值.
成员函数提供2种操作:
Pulse()产生一个事件pulses,并且:如果计入采样samples,返回true
DebugString():以string形式输出采样率
*/
// Signals when a sample should be taken from a stream of data to select a
// uniformly distributed fraction of the data.
class FixedRatioSampler {
public:
explicit FixedRatioSampler(double ratio);
~FixedRatioSampler();
FixedRatioSampler(const FixedRatioSampler&) = delete;
FixedRatioSampler& operator=(const FixedRatioSampler&) = delete;
// Returns true if this pulse should result in an sample.
bool Pulse();
// Returns a debug string describing the current ratio of samples to pulses.
string DebugString();
private:
// Sampling occurs if the proportion of samples to pulses drops below this
// number.
const double ratio_;
int64 num_pulses_ = 0; //产生的脉冲次数
int64 num_samples_ = 0;//记录的采样次数
};
} // namespace common
} // namespace cartographer
#endif // CARTOGRAPHER_COMMON_FIXED_RATIO_SAMPLER_H_
================================================
FILE: common/fixed_ratio_sampler_test.cc
================================================
#include "cartographer/common/fixed_ratio_sampler.h"
#include "gtest/gtest.h"
namespace cartographer {
namespace common {
namespace {
TEST(FixedRatioSamplerTest, AlwaysTrue) {
FixedRatioSampler fixed_ratio_sampler(1.);//固定采样率是1hz,每次Pulse都采集samples
for (int i = 0; i < 100; ++i) {
EXPECT_TRUE(fixed_ratio_sampler.Pulse());
}
}
TEST(FixedRatioSamplerTest, AlwaysFalse) {
FixedRatioSampler fixed_ratio_sampler(0.);//0 hz,不采集samples
for (int i = 0; i < 100; ++i) {
EXPECT_FALSE(fixed_ratio_sampler.Pulse());
}
}
TEST(FixedRatioSamplerTest, SometimesTrue) {
FixedRatioSampler fixed_ratio_sampler(0.5); //0.5hz
for (int i = 0; i < 100; ++i) {
EXPECT_EQ(i % 2 == 0, fixed_ratio_sampler.Pulse());//每2次Pulse采集一次samples
}
}
TEST(FixedRatioSamplerTest, FirstPulseIsTrue) {
// Choose a very very small positive number for the ratio.
FixedRatioSampler fixed_ratio_sampler(1e-20); //0.000000...001hz
EXPECT_TRUE(fixed_ratio_sampler.Pulse());
for (int i = 0; i < 100; ++i) {
EXPECT_FALSE(fixed_ratio_sampler.Pulse()); //每100000000次Pulse采集一次samples
}
}
} // namespace
} // namespace common
} // namespace cartographer
================================================
FILE: common/histogram.cc
================================================
#include "cartographer/common/histogram.h"
#include
#include
#include
#include "cartographer/common/port.h"
#include "glog/logging.h"
namespace cartographer {
namespace common {
//添加元素
void Histogram::Add(const float value) { values_.push_back(value); }
//以bin大小是buckets转成 string,输出 直方图信息.
string Histogram::ToString(const int buckets) const {
CHECK_GE(buckets, 1); //篮子个数必须>=1
if (values_.empty()) {
return "Count: 0";
}
const float min = *std::min_element(values_.begin(), values_.end());
const float max = *std::max_element(values_.begin(), values_.end());
const float mean =
std::accumulate(values_.begin(), values_.end(), 0.f) / values_.size();
string result = "Count: " + std::to_string(values_.size()) +
" Min: " + std::to_string(min) +
" Max: " + std::to_string(max) +
" Mean: " + std::to_string(mean);
if (min == max) { //最大等于最小直接返回.
return result;
}
CHECK_LT(min, max);
float lower_bound = min; //bin区间下界
int total_count = 0;
for (int i = 0; i != buckets; ++i) { //根据bin个数
const float upper_bound = //bin区间上界
(i + 1 == buckets)
? max
: (max * (i + 1) / buckets + min * (buckets - i - 1) / buckets);
int count = 0;
for (const float value : values_) { //对每一个vector的值
if (lower_bound <= value &&
(i + 1 == buckets ? value <= upper_bound : value < upper_bound)) {
++count;
}
}
total_count += count;
result += "\n[" + std::to_string(lower_bound) + ", " +
std::to_string(upper_bound) + ((i + 1 == buckets) ? "]" : ")");
constexpr int kMaxBarChars = 20;
const int bar =
(count * kMaxBarChars + values_.size() / 2) / values_.size();
result += "\t";
for (int i = 0; i != kMaxBarChars; ++i) {
result += (i < (kMaxBarChars - bar)) ? " " : "#";
}
result += "\tCount: " + std::to_string(count) + " (" +
std::to_string(count * 1e2f / values_.size()) + "%)";
result += "\tTotal: " + std::to_string(total_count) + " (" +
std::to_string(total_count * 1e2f / values_.size()) + "%)";
lower_bound = upper_bound;
}
return result;
}
} // namespace common
} // namespace cartographer
================================================
FILE: common/histogram.h
================================================
#ifndef CARTOGRAPHER_COMMON_HISTOGRAM_H_
#define CARTOGRAPHER_COMMON_HISTOGRAM_H_
#include