在node_main.cc中,当::ros::spin()结束了之后(在运行node的时候,按下Ctrl+C即结束spin开始运行spin之后的语句),开始结束所有处于活动状态的轨迹,
1 2 3 4 5 6 7 8 void  Run ()   {  ...   ::ros::spin ();      node.FinishAllTrajectories ();   ... }   
 
下面是FinishAllTrajectories的详细代码。
1 2 3 4 5 6 7 8 9 10 11 void  Node::FinishAllTrajectories ()   {  absl::MutexLock lock (&mutex_)  ;   for  (const  auto & entry : map_builder_bridge_.GetTrajectoryStates ()) {     if  (entry.second == TrajectoryState::ACTIVE) {       const  int  trajectory_id = entry.first;       CHECK_EQ (FinishTrajectoryUnderLock (trajectory_id).code,                cartographer_ros_msgs::StatusCode::OK);     }   } } 
 
此函数,调用map_builder_bridge来获取轨迹的状态,key为轨迹ID,value为轨迹状态,轨迹状态一共有四种
1 enum  class  TrajectoryState  {  ACTIVE, FINISHED, FROZEN, DELETED };
 
如果有轨迹的状态为ACTIVE,那么我们就通过FinishTrajectoryUnderLock, 将其进行结束操作
FinishTrajectoryUnderLock 此函数用于结束一条指定id的轨迹,返回一个状态,用于判定是否结束成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 cartographer_ros_msgs::StatusResponse Node::FinishTrajectoryUnderLock (      const  int  trajectory_id)   {  cartographer_ros_msgs::StatusResponse status_response;      if  (trajectories_scheduled_for_finish_.count (trajectory_id)) {     status_response.message = absl::StrCat ("Trajectory " , trajectory_id,                                            " already pending to finish." );     status_response.code = cartographer_ros_msgs::StatusCode::OK;     LOG (INFO) << status_response.message;     return  status_response;   }         status_response = TrajectoryStateToStatus (       trajectory_id, {TrajectoryState::ACTIVE} );      if  (status_response.code != cartographer_ros_msgs::StatusCode::OK) {     LOG (ERROR) << "Can't finish trajectory: "  << status_response.message;     return  status_response;   }            if  (subscribers_.count (trajectory_id)) {     for  (auto & entry : subscribers_[trajectory_id]) {       entry.subscriber.shutdown ();       subscribed_topics_.erase (entry.topic);       LOG (INFO) << "Shutdown the subscriber of ["  << entry.topic << "]" ;     }          CHECK_EQ (subscribers_.erase (trajectory_id), 1 );   }      map_builder_bridge_.FinishTrajectory (trajectory_id);      trajectories_scheduled_for_finish_.emplace (trajectory_id);   status_response.message =       absl::StrCat ("Finished trajectory " , trajectory_id, "." );   status_response.code = cartographer_ros_msgs::StatusCode::OK;   return  status_response; } 
 
检查一:是否在trajectoriesscheduled_for_finish 里面 如果判定轨迹已经在将要结束的轨迹中,trajectoriesscheduled_for_finish ,则直接给status_response一个OK状态
1 2 3 4 5 6 7 8 if  (trajectories_scheduled_for_finish_.count (trajectory_id)) {  status_response.message = absl::StrCat ("Trajectory " , trajectory_id,                                          " already pending to finish." );   status_response.code = cartographer_ros_msgs::StatusCode::OK;   LOG (INFO) << status_response.message;   return  status_response; } 
 
检查二:检查轨迹是否存在和状态 检查这个轨迹是否存在, 如果存在则检查这个轨迹是否是ACTIVE状态
1 2 3 4 5 6 7 8 9 status_response = TrajectoryStateToStatus (     trajectory_id, {TrajectoryState::ACTIVE} ); if  (status_response.code != cartographer_ros_msgs::StatusCode::OK) {  LOG (ERROR) << "Can't finish trajectory: "  << status_response.message;   return  status_response; } 
 
检查三:若存在,检查subscriber是否关闭 如果通过了步骤二,说明轨迹存在并且状态是ACTIVE。那么开始检查对应的轨迹ID是否有订阅者,使用count可以查看map里面的对应key的value个数,使用shutdown来关闭对应的订阅者。并且移除记录subscribedtopics  里面记录的已经有的topic名字。最后把subscribers_ 里面的轨迹ID给清除掉
1 2 3 4 5 6 7 8 9 10 if  (subscribers_.count (trajectory_id)) {  for  (auto & entry : subscribers_[trajectory_id]) {     entry.subscriber.shutdown ();     subscribed_topics_.erase (entry.topic);     LOG (INFO) << "Shutdown the subscriber of ["  << entry.topic << "]" ;   }      CHECK_EQ (subscribers_.erase (trajectory_id), 1 ); } 
 
结束轨迹 调用cartographer中的mapbuilder的FinishTrajectory()进行轨迹的结束,然后放入trajectories_scheduled_for_finish ,设置status_response的message和code即可
1 2 3 4 5 6 map_builder_bridge_.FinishTrajectory (trajectory_id); trajectories_scheduled_for_finish_.emplace (trajectory_id); status_response.message = absl::StrCat ("Finished trajectory " , trajectory_id, "." ); status_response.code = cartographer_ros_msgs::StatusCode::OK;