node_main.cc
node_main.cc—>node.cc—>map_builder_bridge.cc—>map_builder.cc
node_main.cc:cartographer_ros/cartographer_ros/cartographer_ros/node_main.cc
// MapBuilder类是完整的SLAM算法类,包含前端(TransformingTrajectoryBuilder,scan to submap)、后端(用于查找回环的PoseGraph)、优化器等模块。
auto map_builder =
cartographer::mapping::CreateMapBuilder(node_options.map_builder_options);
// 输入:
// node_options:节点选项
// map_builder:地图构建器
// tf_buffer:tf缓存
// collect_metrics:是否收集运行时指标
// 输出:
// node:Cartographer节点
// 这里使用了std::move()函数,将map_builder转移到Node对象中,避免map_builder被销毁。
// std::move()函数将左值(左值引用)转移到右值(右值引用)并返回右值。
Node node(node_options, std::move(map_builder), &tf_buffer,
FLAGS_collect_metrics); //node.cc
Node类的构造函数:cartographer_ros/cartographer_ros/cartographer_ros/node.cc
// 该构造函数主要是初始化Node对象,包括初始化ROS节点句柄、地图构建器桥接、TF缓冲区、度量注册表、发布者、服务服务器、定时器等。
// 其中,初始化ROS节点句柄、地图构建器桥接、TF缓冲区、发布者、服务服务器、定时器等的过程,均是通过调用相应的初始化函数完成。
// 其中,初始化地图构建器桥接的过程,主要是创建地图构建器接口对象,并将其传递给地图构建器桥接对象。
// 作用:创建Node对象,并初始化Node对象。
Node::Node(
const NodeOptions& node_options, // 节点选项
std::unique_ptr<cartographer::mapping::MapBuilderInterface> map_builder, // 地图构建器接口
tf2_ros::Buffer* const tf_buffer, // TF缓冲区
const bool collect_metrics) // 是否收集度量
//
: node_options_(node_options), // 初始化节点选项只是赋值给成员变量
map_builder_bridge_(node_options_, std::move(map_builder), tf_buffer) // map_builder_bridge.cc
MapBuilderBridge类的构造函数:cartographer_ros/cartographer_ros/cartographer_ros/map_builder_bridge.cc
// MapBuilderBridge类的构造函数,用于初始化MapBuilderBridge对象。
// 参数:
// node_options: NodeOptions对象,包含节点配置选项。
// map_builder: 指向cartographer::mapping::MapBuilderInterface对象的智能指针,用于地图构建。
// tf_buffer: 指向tf2_ros::Buffer对象的指针,用于处理TF变换。
MapBuilderBridge::MapBuilderBridge(
const NodeOptions& node_options,
std::unique_ptr<cartographer::mapping::MapBuilderInterface> map_builder,
tf2_ros::Buffer* const tf_buffer)
: node_options_(node_options),
map_builder_(std::move(map_builder)),// map_builder.cc
tf_buffer_(tf_buffer) {}
MapBuilder类的构造函数:cartographer/cartographer/mapping/map_builder.cc
MapBuilder::MapBuilder(const proto::MapBuilderOptions& options)
: options_(options), thread_pool_(options.num_background_threads())
ThreadPool类的构造函数:cartographer/cartographer/common/thread_pool.cc
// 线程池类构造函数,接受一个整数参数num_threads,表示线程池中的线程数量。
// 该构造函数会检查传入的线程数量是否大于0,如果不大于0则输出错误信息。
// 然后,它会创建指定数量的线程,并将它们添加到线程池中。每个线程都会执行ThreadPool::DoWork方法。
ThreadPool::ThreadPool(int num_threads) {
CHECK_GT(num_threads, 0) << "ThreadPool requires a positive num_threads!";
absl::MutexLock locker(&mutex_);
for (int i = 0; i != num_threads; ++i) {
pool_.emplace_back([this]() { ThreadPool::DoWork(); });
}
}
ThreadPool::DoWork函数:
// 线程池的工作线程执行函数。该函数负责从任务队列中取出任务并执行。
void ThreadPool::DoWork() {
#ifdef __linux__
// 在Linux系统上,调整当前线程的优先级,以确保后台任务不会占用前台线程的CPU资源。
CHECK_NE(nice(10), -1);
#endif
const auto predicate = [this]() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {
return !task_queue_.empty() || !running_;
};
// 死循环,不断从任务队列中取出任务并执行。
for (;;) {
std::shared_ptr<Task> task;
{
absl::MutexLock locker(&mutex_);
mutex_.Await(absl::Condition(&predicate));
if (!task_queue_.empty()) {
task = std::move(task_queue_.front());
task_queue_.pop_front();
} else if (!running_) {
// 线程池停止运行,退出循环。
return;
}
}
CHECK(task);
CHECK_EQ(task->GetState(), common::Task::DEPENDENCIES_COMPLETED);
Execute(task.get());
}
}
© 版权声明
特别提醒: 内容为用户自行发布,如有侵权,请联系我们管理员删除,邮箱:mail@xieniao.com ,在收到您的邮件后我们会在3个工作日内处理。
相关文章
暂无评论...