在构造Node类的时候,cartographer也声明了一些服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| service_servers_.push_back(node_handle_.advertiseService( kSubmapQueryServiceName, &Node::HandleSubmapQuery, this)); service_servers_.push_back(node_handle_.advertiseService( kTrajectoryQueryServiceName, &Node::HandleTrajectoryQuery, this)); service_servers_.push_back(node_handle_.advertiseService( kStartTrajectoryServiceName, &Node::HandleStartTrajectory, this)); service_servers_.push_back(node_handle_.advertiseService( kFinishTrajectoryServiceName, &Node::HandleFinishTrajectory, this)); service_servers_.push_back(node_handle_.advertiseService( kWriteStateServiceName, &Node::HandleWriteState, this)); service_servers_.push_back(node_handle_.advertiseService( kGetTrajectoryStatesServiceName, &Node::HandleGetTrajectoryStates, this)); service_servers_.push_back(node_handle_.advertiseService( kReadMetricsServiceName, &Node::HandleReadMetrics, this));
|
获取submap
服务内容包括,处理获取对应id轨迹的 索引为submap_index 的submap
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
bool Node::HandleSubmapQuery( ::cartographer_ros_msgs::SubmapQuery::Request& request, ::cartographer_ros_msgs::SubmapQuery::Response& response) { absl::MutexLock lock(&mutex_); map_builder_bridge_.HandleSubmapQuery(request, response); return true; }
|
消息的数据结构SubmapQuery,可以从cartographer_ros/srv里面查看
1 2 3 4 5 6
| int32 trajectory_id int32 submap_index --- cartographer_ros_msgs/StatusResponse status int32 submap_version cartographer_ros_msgs/SubmapTexture[] textures
|
获取对应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
|
bool Node::HandleTrajectoryQuery( ::cartographer_ros_msgs::TrajectoryQuery::Request& request, ::cartographer_ros_msgs::TrajectoryQuery::Response& response) { absl::MutexLock lock(&mutex_);
response.status = TrajectoryStateToStatus( request.trajectory_id, {TrajectoryState::ACTIVE, TrajectoryState::FINISHED, TrajectoryState::FROZEN} ); if (response.status.code != cartographer_ros_msgs::StatusCode::OK) { LOG(ERROR) << "Can't query trajectory from pose graph: " << response.status.message; return true; } map_builder_bridge_.HandleTrajectoryQuery(request, response); return true; }
|
开启一条新的轨迹
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
bool Node::HandleStartTrajectory( ::cartographer_ros_msgs::StartTrajectory::Request& request, ::cartographer_ros_msgs::StartTrajectory::Response& response) { TrajectoryOptions trajectory_options; std::tie(std::ignore, trajectory_options) = LoadOptions( request.configuration_directory, request.configuration_basename);
if (request.use_initial_pose) { const auto pose = ToRigid3d(request.initial_pose); if (!pose.IsValid()) { response.status.message = "Invalid pose argument. Orientation quaternion must be normalized."; LOG(ERROR) << response.status.message; response.status.code = cartographer_ros_msgs::StatusCode::INVALID_ARGUMENT; return true; }
response.status = TrajectoryStateToStatus( request.relative_to_trajectory_id, {TrajectoryState::ACTIVE, TrajectoryState::FROZEN, TrajectoryState::FINISHED} ); if (response.status.code != cartographer_ros_msgs::StatusCode::OK) { LOG(ERROR) << "Can't start a trajectory with initial pose: " << response.status.message; return true; }
::cartographer::mapping::proto::InitialTrajectoryPose initial_trajectory_pose; initial_trajectory_pose.set_to_trajectory_id( request.relative_to_trajectory_id); *initial_trajectory_pose.mutable_relative_pose() = cartographer::transform::ToProto(pose); initial_trajectory_pose.set_timestamp(cartographer::common::ToUniversal( ::cartographer_ros::FromRos(ros::Time(0))));
*trajectory_options.trajectory_builder_options .mutable_initial_trajectory_pose() = initial_trajectory_pose; }
if (!ValidateTrajectoryOptions(trajectory_options)) { response.status.message = "Invalid trajectory options."; LOG(ERROR) << response.status.message; response.status.code = cartographer_ros_msgs::StatusCode::INVALID_ARGUMENT; } else if (!ValidateTopicNames(trajectory_options)) { response.status.message = "Topics are already used by another trajectory."; LOG(ERROR) << response.status.message; response.status.code = cartographer_ros_msgs::StatusCode::INVALID_ARGUMENT; } else { response.status.message = "Success."; response.trajectory_id = AddTrajectory(trajectory_options); response.status.code = cartographer_ros_msgs::StatusCode::OK; } return true; }
void Node::StartTrajectoryWithDefaultTopics(const TrajectoryOptions& options) { absl::MutexLock lock(&mutex_); CHECK(ValidateTrajectoryOptions(options)); AddTrajectory(options); }
|
结束一条轨迹
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
bool Node::HandleFinishTrajectory( ::cartographer_ros_msgs::FinishTrajectory::Request& request, ::cartographer_ros_msgs::FinishTrajectory::Response& response) { absl::MutexLock lock(&mutex_); response.status = FinishTrajectoryUnderLock(request.trajectory_id); return true; }
|
获得所有轨迹的状态
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
|
bool Node::HandleGetTrajectoryStates( ::cartographer_ros_msgs::GetTrajectoryStates::Request& request, ::cartographer_ros_msgs::GetTrajectoryStates::Response& response) { using TrajectoryState = ::cartographer::mapping::PoseGraphInterface::TrajectoryState;
absl::MutexLock lock(&mutex_); response.status.code = ::cartographer_ros_msgs::StatusCode::OK; response.trajectory_states.header.stamp = ros::Time::now(); for (const auto& entry : map_builder_bridge_.GetTrajectoryStates()) { response.trajectory_states.trajectory_id.push_back(entry.first); switch (entry.second) { case TrajectoryState::ACTIVE: response.trajectory_states.trajectory_state.push_back( ::cartographer_ros_msgs::TrajectoryStates::ACTIVE); break; case TrajectoryState::FINISHED: response.trajectory_states.trajectory_state.push_back( ::cartographer_ros_msgs::TrajectoryStates::FINISHED); break; case TrajectoryState::FROZEN: response.trajectory_states.trajectory_state.push_back( ::cartographer_ros_msgs::TrajectoryStates::FROZEN); break; case TrajectoryState::DELETED: response.trajectory_states.trajectory_state.push_back( ::cartographer_ros_msgs::TrajectoryStates::DELETED); break; } } return true; }
|