2D SLAM_Cartographer(2)_业务逻辑

cartographer通过main()函数调用void Run()来启动程序,Run()也承接了cartographer的业务逻辑。

void Run() 
{
  constexpr double kTfBufferCacheTimeInSeconds = 10.;
  //tf2_ros::Buffer是tf2 library的主要工具。Its main public API is defined by tf2_ros::BufferInterface. 
  tf2_ros::Buffer tf_buffer
  {
    ::ros::Duration(kTfBufferCacheTimeInSeconds)
  };
  tf2_ros::TransformListener tf(tf_buffer);//定义监听器
  
  NodeOptions node_options;
  TrajectoryOptions trajectory_options;
  std::tie(node_options, trajectory_options) =LoadOptions(FLAGS_configuration_directory, FLAGS_configuration_basename);
  
  auto map_builder = absl::make_unique<cartographer::mapping::MapBuilder>(node_options.map_builder_options);
  Node node(node_options, std::move(map_builder), &tf_buffer,FLAGS_collect_metrics);
  
  if (!FLAGS_load_state_filename.empty()) 
  {
    node.LoadState(FLAGS_load_state_filename, FLAGS_load_frozen_state);//加载数据包数据
  }
  if (FLAGS_start_trajectory_with_default_topics) {
    node.StartTrajectoryWithDefaultTopics(trajectory_options);
  }
  
  ::ros::spin();//将会进入循环, 一直调用回调函数chatterCallback(),
  node.FinishAllTrajectories();
  node.RunFinalOptimization();

  if (!FLAGS_save_state_filename.empty()) 
  {//如果保存的状态文件不为空
    node.SerializeState(FLAGS_save_state_filename, true /* include_unfinished_submaps */);
  }
}

解析:

  constexpr double kTfBufferCacheTimeInSeconds = 10.;
  tf2_ros::Buffer tf_buffer
  {
    ::ros::Duration(kTfBufferCacheTimeInSeconds)
  };
  tf2_ros::TransformListener tf(tf_buffer);//定义监听器

//这里定义了一个10s的tf缓存器。然后定义了监听器tf,用于监听cartographer系统发布的所有的坐标系变换的关系,并将缓存到tf_buffer中,而kTfBufferCacheTimeInSeconds表示缓存10s

  NodeOptions node_options;
  TrajectoryOptions trajectory_options;
  std::tie(node_options, trajectory_options) =LoadOptions(FLAGS_configuration_directory, FLAGS_configuration_basename);

NodeOptions在/cartographer_ros/cartographer_ros/cartographer/node_options.h中定义;用于加载配置文件。
该struct中包含了对一些基本参数的设置,比如接收tf的timeout时间设置、子图发布周期设置等
tie将LoadOptions获取到的参数值分别赋给node_options和trajectory_options. LoadOptions函数在node_options.h中定义。

  if (!FLAGS_load_state_filename.empty()) 
  {
    node.LoadState(FLAGS_load_state_filename, FLAGS_load_frozen_state);//加载数据包数据
  }
  if (FLAGS_start_trajectory_with_default_topics) {
    node.StartTrajectoryWithDefaultTopics(trajectory_options);
  }

LoadState(),大概意思就是说通过命令参数的形式,加载已有的系统状态文件,那么系统可以接着这个状态接着运行。
StartTrajectoryWithDefaultTopics(),根据默认的topic,开始启动新的轨迹,接着进入node.cc调用
AddTrajectory(options, DefaultSensorTopics());函数,开始接收各个topic数据,启动cartographer底层算法。

 ::ros::spin();//将会进入循环, 一直调用回调函数chatterCallback(),

完成系列初始化和必要的变量定义之后,就可以开启逻辑循环了,node对象将通过消息回调多线程等机制完成整个定位建图过程。

  node.FinishAllTrajectories();
  node.RunFinalOptimization();

如果在ROS的逻辑循环过程中,触发退出机制,Run函数就会执行以上语句,完成最终的轨迹和地图的优化。

  if (!FLAGS_save_state_filename.empty()) 
  {
    node.SerializeState(FLAGS_save_state_filename, true /* include_unfinished_submaps */);
  }

最后如果运行参数保存的系统状态文件不为空,则将当前的系统状态存到参数save_state_filename所指定的文件中。

你可能感兴趣的:(2D,SLAM)