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()); } }