map_builder_bridge.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright 2016 The Cartographer Authors
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "cartographer_ros/map_builder_bridge.h"
00018 
00019 #include "absl/memory/memory.h"
00020 #include "absl/strings/str_cat.h"
00021 #include "cartographer/io/color.h"
00022 #include "cartographer/io/proto_stream.h"
00023 #include "cartographer/mapping/pose_graph.h"
00024 #include "cartographer_ros/msg_conversion.h"
00025 #include "cartographer_ros/time_conversion.h"
00026 #include "cartographer_ros_msgs/StatusCode.h"
00027 #include "cartographer_ros_msgs/StatusResponse.h"
00028 
00029 namespace cartographer_ros {
00030 namespace {
00031 
00032 using ::cartographer::transform::Rigid3d;
00033 
00034 constexpr double kTrajectoryLineStripMarkerScale = 0.07;
00035 constexpr double kLandmarkMarkerScale = 0.2;
00036 constexpr double kConstraintMarkerScale = 0.025;
00037 
00038 ::std_msgs::ColorRGBA ToMessage(const cartographer::io::FloatColor& color) {
00039   ::std_msgs::ColorRGBA result;
00040   result.r = color[0];
00041   result.g = color[1];
00042   result.b = color[2];
00043   result.a = 1.f;
00044   return result;
00045 }
00046 
00047 visualization_msgs::Marker CreateTrajectoryMarker(const int trajectory_id,
00048                                                   const std::string& frame_id) {
00049   visualization_msgs::Marker marker;
00050   marker.ns = absl::StrCat("Trajectory ", trajectory_id);
00051   marker.id = 0;
00052   marker.type = visualization_msgs::Marker::LINE_STRIP;
00053   marker.header.stamp = ::ros::Time::now();
00054   marker.header.frame_id = frame_id;
00055   marker.color = ToMessage(cartographer::io::GetColor(trajectory_id));
00056   marker.scale.x = kTrajectoryLineStripMarkerScale;
00057   marker.pose.orientation.w = 1.;
00058   marker.pose.position.z = 0.05;
00059   return marker;
00060 }
00061 
00062 int GetLandmarkIndex(
00063     const std::string& landmark_id,
00064     std::unordered_map<std::string, int>* landmark_id_to_index) {
00065   auto it = landmark_id_to_index->find(landmark_id);
00066   if (it == landmark_id_to_index->end()) {
00067     const int new_index = landmark_id_to_index->size();
00068     landmark_id_to_index->emplace(landmark_id, new_index);
00069     return new_index;
00070   }
00071   return it->second;
00072 }
00073 
00074 visualization_msgs::Marker CreateLandmarkMarker(int landmark_index,
00075                                                 const Rigid3d& landmark_pose,
00076                                                 const std::string& frame_id) {
00077   visualization_msgs::Marker marker;
00078   marker.ns = "Landmarks";
00079   marker.id = landmark_index;
00080   marker.type = visualization_msgs::Marker::SPHERE;
00081   marker.header.stamp = ::ros::Time::now();
00082   marker.header.frame_id = frame_id;
00083   marker.scale.x = kLandmarkMarkerScale;
00084   marker.scale.y = kLandmarkMarkerScale;
00085   marker.scale.z = kLandmarkMarkerScale;
00086   marker.color = ToMessage(cartographer::io::GetColor(landmark_index));
00087   marker.pose = ToGeometryMsgPose(landmark_pose);
00088   return marker;
00089 }
00090 
00091 void PushAndResetLineMarker(visualization_msgs::Marker* marker,
00092                             std::vector<visualization_msgs::Marker>* markers) {
00093   markers->push_back(*marker);
00094   ++marker->id;
00095   marker->points.clear();
00096 }
00097 
00098 }  // namespace
00099 
00100 MapBuilderBridge::MapBuilderBridge(
00101     const NodeOptions& node_options,
00102     std::unique_ptr<cartographer::mapping::MapBuilderInterface> map_builder,
00103     tf2_ros::Buffer* const tf_buffer)
00104     : node_options_(node_options),
00105       map_builder_(std::move(map_builder)),
00106       tf_buffer_(tf_buffer) {}
00107 
00108 void MapBuilderBridge::LoadState(const std::string& state_filename,
00109                                  bool load_frozen_state) {
00110   // Check if suffix of the state file is ".pbstream".
00111   const std::string suffix = ".pbstream";
00112   CHECK_EQ(state_filename.substr(
00113                std::max<int>(state_filename.size() - suffix.size(), 0)),
00114            suffix)
00115       << "The file containing the state to be loaded must be a "
00116          ".pbstream file.";
00117   LOG(INFO) << "Loading saved state '" << state_filename << "'...";
00118   cartographer::io::ProtoStreamReader stream(state_filename);
00119   map_builder_->LoadState(&stream, load_frozen_state);
00120 }
00121 
00122 int MapBuilderBridge::AddTrajectory(
00123     const std::set<cartographer::mapping::TrajectoryBuilderInterface::SensorId>&
00124         expected_sensor_ids,
00125     const TrajectoryOptions& trajectory_options) {
00126   const int trajectory_id = map_builder_->AddTrajectoryBuilder(
00127       expected_sensor_ids, trajectory_options.trajectory_builder_options,
00128       [this](const int trajectory_id, const ::cartographer::common::Time time,
00129              const Rigid3d local_pose,
00130              ::cartographer::sensor::RangeData range_data_in_local,
00131              const std::unique_ptr<
00132                  const ::cartographer::mapping::TrajectoryBuilderInterface::
00133                      InsertionResult>) {
00134         OnLocalSlamResult(trajectory_id, time, local_pose, range_data_in_local);
00135       });
00136   LOG(INFO) << "Added trajectory with ID '" << trajectory_id << "'.";
00137 
00138   // Make sure there is no trajectory with 'trajectory_id' yet.
00139   CHECK_EQ(sensor_bridges_.count(trajectory_id), 0);
00140   sensor_bridges_[trajectory_id] = absl::make_unique<SensorBridge>(
00141       trajectory_options.num_subdivisions_per_laser_scan,
00142       trajectory_options.tracking_frame,
00143       node_options_.lookup_transform_timeout_sec, tf_buffer_,
00144       map_builder_->GetTrajectoryBuilder(trajectory_id));
00145   auto emplace_result =
00146       trajectory_options_.emplace(trajectory_id, trajectory_options);
00147   CHECK(emplace_result.second == true);
00148   return trajectory_id;
00149 }
00150 
00151 void MapBuilderBridge::FinishTrajectory(const int trajectory_id) {
00152   LOG(INFO) << "Finishing trajectory with ID '" << trajectory_id << "'...";
00153 
00154   // Make sure there is a trajectory with 'trajectory_id'.
00155   CHECK(GetTrajectoryStates().count(trajectory_id));
00156   map_builder_->FinishTrajectory(trajectory_id);
00157   sensor_bridges_.erase(trajectory_id);
00158 }
00159 
00160 void MapBuilderBridge::RunFinalOptimization() {
00161   LOG(INFO) << "Running final trajectory optimization...";
00162   map_builder_->pose_graph()->RunFinalOptimization();
00163 }
00164 
00165 bool MapBuilderBridge::SerializeState(const std::string& filename,
00166                                       const bool include_unfinished_submaps) {
00167   return map_builder_->SerializeStateToFile(include_unfinished_submaps,
00168                                             filename);
00169 }
00170 
00171 void MapBuilderBridge::HandleSubmapQuery(
00172     cartographer_ros_msgs::SubmapQuery::Request& request,
00173     cartographer_ros_msgs::SubmapQuery::Response& response) {
00174   cartographer::mapping::proto::SubmapQuery::Response response_proto;
00175   cartographer::mapping::SubmapId submap_id{request.trajectory_id,
00176                                             request.submap_index};
00177   const std::string error =
00178       map_builder_->SubmapToProto(submap_id, &response_proto);
00179   if (!error.empty()) {
00180     LOG(ERROR) << error;
00181     response.status.code = cartographer_ros_msgs::StatusCode::NOT_FOUND;
00182     response.status.message = error;
00183     return;
00184   }
00185 
00186   response.submap_version = response_proto.submap_version();
00187   for (const auto& texture_proto : response_proto.textures()) {
00188     response.textures.emplace_back();
00189     auto& texture = response.textures.back();
00190     texture.cells.insert(texture.cells.begin(), texture_proto.cells().begin(),
00191                          texture_proto.cells().end());
00192     texture.width = texture_proto.width();
00193     texture.height = texture_proto.height();
00194     texture.resolution = texture_proto.resolution();
00195     texture.slice_pose = ToGeometryMsgPose(
00196         cartographer::transform::ToRigid3(texture_proto.slice_pose()));
00197   }
00198   response.status.message = "Success.";
00199   response.status.code = cartographer_ros_msgs::StatusCode::OK;
00200 }
00201 
00202 std::map<int, ::cartographer::mapping::PoseGraphInterface::TrajectoryState>
00203 MapBuilderBridge::GetTrajectoryStates() {
00204   auto trajectory_states = map_builder_->pose_graph()->GetTrajectoryStates();
00205   // Add active trajectories that are not yet in the pose graph, but are e.g.
00206   // waiting for input sensor data and thus already have a sensor bridge.
00207   for (const auto& sensor_bridge : sensor_bridges_) {
00208     trajectory_states.insert(std::make_pair(
00209         sensor_bridge.first,
00210         ::cartographer::mapping::PoseGraph::TrajectoryState::ACTIVE));
00211   }
00212   return trajectory_states;
00213 }
00214 
00215 cartographer_ros_msgs::SubmapList MapBuilderBridge::GetSubmapList() {
00216   cartographer_ros_msgs::SubmapList submap_list;
00217   submap_list.header.stamp = ::ros::Time::now();
00218   submap_list.header.frame_id = node_options_.map_frame;
00219   for (const auto& submap_id_pose :
00220        map_builder_->pose_graph()->GetAllSubmapPoses()) {
00221     cartographer_ros_msgs::SubmapEntry submap_entry;
00222     submap_entry.is_frozen = map_builder_->pose_graph()->IsTrajectoryFrozen(
00223         submap_id_pose.id.trajectory_id);
00224     submap_entry.trajectory_id = submap_id_pose.id.trajectory_id;
00225     submap_entry.submap_index = submap_id_pose.id.submap_index;
00226     submap_entry.submap_version = submap_id_pose.data.version;
00227     submap_entry.pose = ToGeometryMsgPose(submap_id_pose.data.pose);
00228     submap_list.submap.push_back(submap_entry);
00229   }
00230   return submap_list;
00231 }
00232 
00233 std::unordered_map<int, MapBuilderBridge::LocalTrajectoryData>
00234 MapBuilderBridge::GetLocalTrajectoryData() {
00235   std::unordered_map<int, LocalTrajectoryData> local_trajectory_data;
00236   for (const auto& entry : sensor_bridges_) {
00237     const int trajectory_id = entry.first;
00238     const SensorBridge& sensor_bridge = *entry.second;
00239 
00240     std::shared_ptr<const LocalTrajectoryData::LocalSlamData> local_slam_data;
00241     {
00242       absl::MutexLock lock(&mutex_);
00243       if (local_slam_data_.count(trajectory_id) == 0) {
00244         continue;
00245       }
00246       local_slam_data = local_slam_data_.at(trajectory_id);
00247     }
00248 
00249     // Make sure there is a trajectory with 'trajectory_id'.
00250     CHECK_EQ(trajectory_options_.count(trajectory_id), 1);
00251     local_trajectory_data[trajectory_id] = {
00252         local_slam_data,
00253         map_builder_->pose_graph()->GetLocalToGlobalTransform(trajectory_id),
00254         sensor_bridge.tf_bridge().LookupToTracking(
00255             local_slam_data->time,
00256             trajectory_options_[trajectory_id].published_frame),
00257         trajectory_options_[trajectory_id]};
00258   }
00259   return local_trajectory_data;
00260 }
00261 
00262 void MapBuilderBridge::HandleTrajectoryQuery(
00263     cartographer_ros_msgs::TrajectoryQuery::Request& request,
00264     cartographer_ros_msgs::TrajectoryQuery::Response& response) {
00265   // This query is safe if the trajectory doesn't exist (returns 0 poses).
00266   // However, we can filter unwanted states at the higher level in the node.
00267   const auto node_poses = map_builder_->pose_graph()->GetTrajectoryNodePoses();
00268   for (const auto& node_id_data :
00269        node_poses.trajectory(request.trajectory_id)) {
00270     if (!node_id_data.data.constant_pose_data.has_value()) {
00271       continue;
00272     }
00273     geometry_msgs::PoseStamped pose_stamped;
00274     pose_stamped.header.frame_id = node_options_.map_frame;
00275     pose_stamped.header.stamp =
00276         ToRos(node_id_data.data.constant_pose_data.value().time);
00277     pose_stamped.pose = ToGeometryMsgPose(node_id_data.data.global_pose);
00278     response.trajectory.push_back(pose_stamped);
00279   }
00280   response.status.code = cartographer_ros_msgs::StatusCode::OK;
00281   response.status.message = absl::StrCat(
00282       "Retrieved ", response.trajectory.size(),
00283       " trajectory nodes from trajectory ", request.trajectory_id, ".");
00284 }
00285 
00286 visualization_msgs::MarkerArray MapBuilderBridge::GetTrajectoryNodeList() {
00287   visualization_msgs::MarkerArray trajectory_node_list;
00288   const auto node_poses = map_builder_->pose_graph()->GetTrajectoryNodePoses();
00289   // Find the last node indices for each trajectory that have either
00290   // inter-submap or inter-trajectory constraints.
00291   std::map<int, int /* node_index */>
00292       trajectory_to_last_inter_submap_constrained_node;
00293   std::map<int, int /* node_index */>
00294       trajectory_to_last_inter_trajectory_constrained_node;
00295   for (const int trajectory_id : node_poses.trajectory_ids()) {
00296     trajectory_to_last_inter_submap_constrained_node[trajectory_id] = 0;
00297     trajectory_to_last_inter_trajectory_constrained_node[trajectory_id] = 0;
00298   }
00299   const auto constraints = map_builder_->pose_graph()->constraints();
00300   for (const auto& constraint : constraints) {
00301     if (constraint.tag ==
00302         cartographer::mapping::PoseGraph::Constraint::INTER_SUBMAP) {
00303       if (constraint.node_id.trajectory_id ==
00304           constraint.submap_id.trajectory_id) {
00305         trajectory_to_last_inter_submap_constrained_node[constraint.node_id
00306                                                              .trajectory_id] =
00307             std::max(trajectory_to_last_inter_submap_constrained_node.at(
00308                          constraint.node_id.trajectory_id),
00309                      constraint.node_id.node_index);
00310       } else {
00311         trajectory_to_last_inter_trajectory_constrained_node
00312             [constraint.node_id.trajectory_id] =
00313                 std::max(trajectory_to_last_inter_submap_constrained_node.at(
00314                              constraint.node_id.trajectory_id),
00315                          constraint.node_id.node_index);
00316       }
00317     }
00318   }
00319 
00320   for (const int trajectory_id : node_poses.trajectory_ids()) {
00321     visualization_msgs::Marker marker =
00322         CreateTrajectoryMarker(trajectory_id, node_options_.map_frame);
00323     int last_inter_submap_constrained_node = std::max(
00324         node_poses.trajectory(trajectory_id).begin()->id.node_index,
00325         trajectory_to_last_inter_submap_constrained_node.at(trajectory_id));
00326     int last_inter_trajectory_constrained_node = std::max(
00327         node_poses.trajectory(trajectory_id).begin()->id.node_index,
00328         trajectory_to_last_inter_trajectory_constrained_node.at(trajectory_id));
00329     last_inter_submap_constrained_node =
00330         std::max(last_inter_submap_constrained_node,
00331                  last_inter_trajectory_constrained_node);
00332 
00333     if (map_builder_->pose_graph()->IsTrajectoryFrozen(trajectory_id)) {
00334       last_inter_submap_constrained_node =
00335           (--node_poses.trajectory(trajectory_id).end())->id.node_index;
00336       last_inter_trajectory_constrained_node =
00337           last_inter_submap_constrained_node;
00338     }
00339 
00340     marker.color.a = 1.0;
00341     for (const auto& node_id_data : node_poses.trajectory(trajectory_id)) {
00342       if (!node_id_data.data.constant_pose_data.has_value()) {
00343         PushAndResetLineMarker(&marker, &trajectory_node_list.markers);
00344         continue;
00345       }
00346       const ::geometry_msgs::Point node_point =
00347           ToGeometryMsgPoint(node_id_data.data.global_pose.translation());
00348       marker.points.push_back(node_point);
00349 
00350       if (node_id_data.id.node_index ==
00351           last_inter_trajectory_constrained_node) {
00352         PushAndResetLineMarker(&marker, &trajectory_node_list.markers);
00353         marker.points.push_back(node_point);
00354         marker.color.a = 0.5;
00355       }
00356       if (node_id_data.id.node_index == last_inter_submap_constrained_node) {
00357         PushAndResetLineMarker(&marker, &trajectory_node_list.markers);
00358         marker.points.push_back(node_point);
00359         marker.color.a = 0.25;
00360       }
00361       // Work around the 16384 point limit in RViz by splitting the
00362       // trajectory into multiple markers.
00363       if (marker.points.size() == 16384) {
00364         PushAndResetLineMarker(&marker, &trajectory_node_list.markers);
00365         // Push back the last point, so the two markers appear connected.
00366         marker.points.push_back(node_point);
00367       }
00368     }
00369     PushAndResetLineMarker(&marker, &trajectory_node_list.markers);
00370     size_t current_last_marker_id = static_cast<size_t>(marker.id - 1);
00371     if (trajectory_to_highest_marker_id_.count(trajectory_id) == 0) {
00372       trajectory_to_highest_marker_id_[trajectory_id] = current_last_marker_id;
00373     } else {
00374       marker.action = visualization_msgs::Marker::DELETE;
00375       while (static_cast<size_t>(marker.id) <=
00376              trajectory_to_highest_marker_id_[trajectory_id]) {
00377         trajectory_node_list.markers.push_back(marker);
00378         ++marker.id;
00379       }
00380       trajectory_to_highest_marker_id_[trajectory_id] = current_last_marker_id;
00381     }
00382   }
00383   return trajectory_node_list;
00384 }
00385 
00386 visualization_msgs::MarkerArray MapBuilderBridge::GetLandmarkPosesList() {
00387   visualization_msgs::MarkerArray landmark_poses_list;
00388   const std::map<std::string, Rigid3d> landmark_poses =
00389       map_builder_->pose_graph()->GetLandmarkPoses();
00390   for (const auto& id_to_pose : landmark_poses) {
00391     landmark_poses_list.markers.push_back(CreateLandmarkMarker(
00392         GetLandmarkIndex(id_to_pose.first, &landmark_to_index_),
00393         id_to_pose.second, node_options_.map_frame));
00394   }
00395   return landmark_poses_list;
00396 }
00397 
00398 visualization_msgs::MarkerArray MapBuilderBridge::GetConstraintList() {
00399   visualization_msgs::MarkerArray constraint_list;
00400   int marker_id = 0;
00401   visualization_msgs::Marker constraint_intra_marker;
00402   constraint_intra_marker.id = marker_id++;
00403   constraint_intra_marker.ns = "Intra constraints";
00404   constraint_intra_marker.type = visualization_msgs::Marker::LINE_LIST;
00405   constraint_intra_marker.header.stamp = ros::Time::now();
00406   constraint_intra_marker.header.frame_id = node_options_.map_frame;
00407   constraint_intra_marker.scale.x = kConstraintMarkerScale;
00408   constraint_intra_marker.pose.orientation.w = 1.0;
00409 
00410   visualization_msgs::Marker residual_intra_marker = constraint_intra_marker;
00411   residual_intra_marker.id = marker_id++;
00412   residual_intra_marker.ns = "Intra residuals";
00413   // This and other markers which are less numerous are set to be slightly
00414   // above the intra constraints marker in order to ensure that they are
00415   // visible.
00416   residual_intra_marker.pose.position.z = 0.1;
00417 
00418   visualization_msgs::Marker constraint_inter_same_trajectory_marker =
00419       constraint_intra_marker;
00420   constraint_inter_same_trajectory_marker.id = marker_id++;
00421   constraint_inter_same_trajectory_marker.ns =
00422       "Inter constraints, same trajectory";
00423   constraint_inter_same_trajectory_marker.pose.position.z = 0.1;
00424 
00425   visualization_msgs::Marker residual_inter_same_trajectory_marker =
00426       constraint_intra_marker;
00427   residual_inter_same_trajectory_marker.id = marker_id++;
00428   residual_inter_same_trajectory_marker.ns = "Inter residuals, same trajectory";
00429   residual_inter_same_trajectory_marker.pose.position.z = 0.1;
00430 
00431   visualization_msgs::Marker constraint_inter_diff_trajectory_marker =
00432       constraint_intra_marker;
00433   constraint_inter_diff_trajectory_marker.id = marker_id++;
00434   constraint_inter_diff_trajectory_marker.ns =
00435       "Inter constraints, different trajectories";
00436   constraint_inter_diff_trajectory_marker.pose.position.z = 0.1;
00437 
00438   visualization_msgs::Marker residual_inter_diff_trajectory_marker =
00439       constraint_intra_marker;
00440   residual_inter_diff_trajectory_marker.id = marker_id++;
00441   residual_inter_diff_trajectory_marker.ns =
00442       "Inter residuals, different trajectories";
00443   residual_inter_diff_trajectory_marker.pose.position.z = 0.1;
00444 
00445   const auto trajectory_node_poses =
00446       map_builder_->pose_graph()->GetTrajectoryNodePoses();
00447   const auto submap_poses = map_builder_->pose_graph()->GetAllSubmapPoses();
00448   const auto constraints = map_builder_->pose_graph()->constraints();
00449 
00450   for (const auto& constraint : constraints) {
00451     visualization_msgs::Marker *constraint_marker, *residual_marker;
00452     std_msgs::ColorRGBA color_constraint, color_residual;
00453     if (constraint.tag ==
00454         cartographer::mapping::PoseGraph::Constraint::INTRA_SUBMAP) {
00455       constraint_marker = &constraint_intra_marker;
00456       residual_marker = &residual_intra_marker;
00457       // Color mapping for submaps of various trajectories - add trajectory id
00458       // to ensure different starting colors. Also add a fixed offset of 25
00459       // to avoid having identical colors as trajectories.
00460       color_constraint = ToMessage(
00461           cartographer::io::GetColor(constraint.submap_id.submap_index +
00462                                      constraint.submap_id.trajectory_id + 25));
00463       color_residual.a = 1.0;
00464       color_residual.r = 1.0;
00465     } else {
00466       if (constraint.node_id.trajectory_id ==
00467           constraint.submap_id.trajectory_id) {
00468         constraint_marker = &constraint_inter_same_trajectory_marker;
00469         residual_marker = &residual_inter_same_trajectory_marker;
00470         // Bright yellow
00471         color_constraint.a = 1.0;
00472         color_constraint.r = color_constraint.g = 1.0;
00473       } else {
00474         constraint_marker = &constraint_inter_diff_trajectory_marker;
00475         residual_marker = &residual_inter_diff_trajectory_marker;
00476         // Bright orange
00477         color_constraint.a = 1.0;
00478         color_constraint.r = 1.0;
00479         color_constraint.g = 165. / 255.;
00480       }
00481       // Bright cyan
00482       color_residual.a = 1.0;
00483       color_residual.b = color_residual.g = 1.0;
00484     }
00485 
00486     for (int i = 0; i < 2; ++i) {
00487       constraint_marker->colors.push_back(color_constraint);
00488       residual_marker->colors.push_back(color_residual);
00489     }
00490 
00491     const auto submap_it = submap_poses.find(constraint.submap_id);
00492     if (submap_it == submap_poses.end()) {
00493       continue;
00494     }
00495     const auto& submap_pose = submap_it->data.pose;
00496     const auto node_it = trajectory_node_poses.find(constraint.node_id);
00497     if (node_it == trajectory_node_poses.end()) {
00498       continue;
00499     }
00500     const auto& trajectory_node_pose = node_it->data.global_pose;
00501     const Rigid3d constraint_pose = submap_pose * constraint.pose.zbar_ij;
00502 
00503     constraint_marker->points.push_back(
00504         ToGeometryMsgPoint(submap_pose.translation()));
00505     constraint_marker->points.push_back(
00506         ToGeometryMsgPoint(constraint_pose.translation()));
00507 
00508     residual_marker->points.push_back(
00509         ToGeometryMsgPoint(constraint_pose.translation()));
00510     residual_marker->points.push_back(
00511         ToGeometryMsgPoint(trajectory_node_pose.translation()));
00512   }
00513 
00514   constraint_list.markers.push_back(constraint_intra_marker);
00515   constraint_list.markers.push_back(residual_intra_marker);
00516   constraint_list.markers.push_back(constraint_inter_same_trajectory_marker);
00517   constraint_list.markers.push_back(residual_inter_same_trajectory_marker);
00518   constraint_list.markers.push_back(constraint_inter_diff_trajectory_marker);
00519   constraint_list.markers.push_back(residual_inter_diff_trajectory_marker);
00520   return constraint_list;
00521 }
00522 
00523 SensorBridge* MapBuilderBridge::sensor_bridge(const int trajectory_id) {
00524   return sensor_bridges_.at(trajectory_id).get();
00525 }
00526 
00527 void MapBuilderBridge::OnLocalSlamResult(
00528     const int trajectory_id, const ::cartographer::common::Time time,
00529     const Rigid3d local_pose,
00530     ::cartographer::sensor::RangeData range_data_in_local) {
00531   std::shared_ptr<const LocalTrajectoryData::LocalSlamData> local_slam_data =
00532       std::make_shared<LocalTrajectoryData::LocalSlamData>(
00533           LocalTrajectoryData::LocalSlamData{time, local_pose,
00534                                              std::move(range_data_in_local)});
00535   absl::MutexLock lock(&mutex_);
00536   local_slam_data_[trajectory_id] = std::move(local_slam_data);
00537 }
00538 
00539 }  // namespace cartographer_ros


cartographer_ros
Author(s): The Cartographer Authors
autogenerated on Wed Jul 10 2019 04:10:28