Optionally read /tf from bag in place of a URDF. (#213)
parent
c3a319cabf
commit
cff972ddf2
|
@ -10,6 +10,15 @@ google_library(assets_writer
|
||||||
occupancy_grid
|
occupancy_grid
|
||||||
)
|
)
|
||||||
|
|
||||||
|
google_library(bag_reader
|
||||||
|
USES_CARTOGRAPHER
|
||||||
|
USES_GLOG
|
||||||
|
SRCS
|
||||||
|
bag_reader.cc
|
||||||
|
HDRS
|
||||||
|
bag_reader.h
|
||||||
|
)
|
||||||
|
|
||||||
google_library(map_builder_bridge
|
google_library(map_builder_bridge
|
||||||
USES_CARTOGRAPHER
|
USES_CARTOGRAPHER
|
||||||
SRCS
|
SRCS
|
||||||
|
@ -158,6 +167,7 @@ google_binary(cartographer_assets_writer
|
||||||
SRCS
|
SRCS
|
||||||
assets_writer_main.cc
|
assets_writer_main.cc
|
||||||
DEPENDS
|
DEPENDS
|
||||||
|
bag_reader
|
||||||
msg_conversion
|
msg_conversion
|
||||||
time_conversion
|
time_conversion
|
||||||
urdf_reader
|
urdf_reader
|
||||||
|
@ -188,6 +198,7 @@ google_binary(cartographer_offline_node
|
||||||
SRCS
|
SRCS
|
||||||
offline_node_main.cc
|
offline_node_main.cc
|
||||||
DEPENDS
|
DEPENDS
|
||||||
|
bag_reader
|
||||||
node
|
node
|
||||||
ros_log_sink
|
ros_log_sink
|
||||||
urdf_reader
|
urdf_reader
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "cartographer/io/points_processor.h"
|
#include "cartographer/io/points_processor.h"
|
||||||
#include "cartographer/io/points_processor_pipeline_builder.h"
|
#include "cartographer/io/points_processor_pipeline_builder.h"
|
||||||
#include "cartographer/transform/transform_interpolation_buffer.h"
|
#include "cartographer/transform/transform_interpolation_buffer.h"
|
||||||
|
#include "cartographer_ros/bag_reader.h"
|
||||||
#include "cartographer_ros/msg_conversion.h"
|
#include "cartographer_ros/msg_conversion.h"
|
||||||
#include "cartographer_ros/time_conversion.h"
|
#include "cartographer_ros/time_conversion.h"
|
||||||
#include "cartographer_ros/urdf_reader.h"
|
#include "cartographer_ros/urdf_reader.h"
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include "rosbag/bag.h"
|
#include "rosbag/bag.h"
|
||||||
#include "rosbag/view.h"
|
#include "rosbag/view.h"
|
||||||
#include "tf2_eigen/tf2_eigen.h"
|
#include "tf2_eigen/tf2_eigen.h"
|
||||||
|
#include "tf2_msgs/TFMessage.h"
|
||||||
#include "tf2_ros/buffer.h"
|
#include "tf2_ros/buffer.h"
|
||||||
#include "urdf/model.h"
|
#include "urdf/model.h"
|
||||||
|
|
||||||
|
@ -57,56 +59,23 @@ namespace {
|
||||||
|
|
||||||
namespace carto = ::cartographer;
|
namespace carto = ::cartographer;
|
||||||
|
|
||||||
void Run(const string& trajectory_filename, const string& bag_filename,
|
void HandlePointCloud2Message(
|
||||||
const string& configuration_directory,
|
const sensor_msgs::PointCloud2::ConstPtr& msg,
|
||||||
const string& configuration_basename, const string& urdf_filename) {
|
const string& tracking_frame,
|
||||||
std::ifstream stream(trajectory_filename.c_str());
|
const tf2_ros::Buffer& tf_buffer,
|
||||||
carto::mapping::proto::Trajectory trajectory_proto;
|
const carto::transform::TransformInterpolationBuffer&
|
||||||
CHECK(trajectory_proto.ParseFromIstream(&stream));
|
transform_interpolation_buffer,
|
||||||
|
const std::vector<std::unique_ptr<carto::io::PointsProcessor>>& pipeline) {
|
||||||
auto transform_interpolation_buffer =
|
|
||||||
carto::transform::TransformInterpolationBuffer::FromTrajectory(
|
|
||||||
trajectory_proto);
|
|
||||||
|
|
||||||
carto::io::PointsProcessorPipelineBuilder builder;
|
|
||||||
carto::io::RegisterBuiltInPointsProcessors(trajectory_proto, &builder);
|
|
||||||
|
|
||||||
auto file_resolver =
|
|
||||||
carto::common::make_unique<carto::common::ConfigurationFileResolver>(
|
|
||||||
std::vector<string>{configuration_directory});
|
|
||||||
const string code =
|
|
||||||
file_resolver->GetFileContentOrDie(configuration_basename);
|
|
||||||
carto::common::LuaParameterDictionary lua_parameter_dictionary(
|
|
||||||
code, std::move(file_resolver));
|
|
||||||
const string tracking_frame =
|
|
||||||
lua_parameter_dictionary.GetString("tracking_frame");
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<carto::io::PointsProcessor>> pipeline =
|
|
||||||
builder.CreatePipeline(
|
|
||||||
lua_parameter_dictionary.GetDictionary("pipeline").get());
|
|
||||||
|
|
||||||
tf2_ros::Buffer buffer;
|
|
||||||
// TODO(hrapp): Also parse tf messages and keep the 'buffer' updated as to
|
|
||||||
// support non-rigid sensor configurations.
|
|
||||||
if (!urdf_filename.empty()) {
|
|
||||||
ReadStaticTransformsFromUrdf(urdf_filename, &buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto handle_point_cloud_2_message = [&](
|
|
||||||
const sensor_msgs::PointCloud2::ConstPtr& msg) {
|
|
||||||
const carto::common::Time time = FromRos(msg->header.stamp);
|
const carto::common::Time time = FromRos(msg->header.stamp);
|
||||||
if (!transform_interpolation_buffer->Has(time)) {
|
if (!transform_interpolation_buffer.Has(time)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
carto::transform::Rigid3d tracking_to_map =
|
|
||||||
transform_interpolation_buffer->Lookup(time);
|
|
||||||
pcl::PointCloud<pcl::PointXYZ> pcl_point_cloud;
|
|
||||||
pcl::fromROSMsg(*msg, pcl_point_cloud);
|
|
||||||
|
|
||||||
const carto::transform::Rigid3d sensor_to_tracking = ToRigid3d(
|
const carto::transform::Rigid3d tracking_to_map =
|
||||||
buffer.lookupTransform(tracking_frame, msg->header.frame_id,
|
transform_interpolation_buffer.Lookup(time);
|
||||||
|
const carto::transform::Rigid3d sensor_to_tracking =
|
||||||
|
ToRigid3d(tf_buffer.lookupTransform(tracking_frame, msg->header.frame_id,
|
||||||
msg->header.stamp));
|
msg->header.stamp));
|
||||||
|
|
||||||
const carto::transform::Rigid3f sensor_to_map =
|
const carto::transform::Rigid3f sensor_to_map =
|
||||||
(tracking_to_map * sensor_to_tracking).cast<float>();
|
(tracking_to_map * sensor_to_tracking).cast<float>();
|
||||||
|
|
||||||
|
@ -115,13 +84,50 @@ void Run(const string& trajectory_filename, const string& bag_filename,
|
||||||
batch->origin = sensor_to_map * Eigen::Vector3f::Zero();
|
batch->origin = sensor_to_map * Eigen::Vector3f::Zero();
|
||||||
batch->frame_id = msg->header.frame_id;
|
batch->frame_id = msg->header.frame_id;
|
||||||
|
|
||||||
|
pcl::PointCloud<pcl::PointXYZ> pcl_point_cloud;
|
||||||
|
pcl::fromROSMsg(*msg, pcl_point_cloud);
|
||||||
for (const auto& point : pcl_point_cloud) {
|
for (const auto& point : pcl_point_cloud) {
|
||||||
batch->points.push_back(sensor_to_map *
|
batch->points.push_back(sensor_to_map *
|
||||||
Eigen::Vector3f(point.x, point.y, point.z));
|
Eigen::Vector3f(point.x, point.y, point.z));
|
||||||
}
|
}
|
||||||
pipeline.back()->Process(std::move(batch));
|
pipeline.back()->Process(std::move(batch));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
void Run(const string& trajectory_filename, const string& bag_filename,
|
||||||
|
const string& configuration_directory,
|
||||||
|
const string& configuration_basename, const string& urdf_filename) {
|
||||||
|
auto file_resolver =
|
||||||
|
carto::common::make_unique<carto::common::ConfigurationFileResolver>(
|
||||||
|
std::vector<string>{configuration_directory});
|
||||||
|
const string code =
|
||||||
|
file_resolver->GetFileContentOrDie(configuration_basename);
|
||||||
|
carto::common::LuaParameterDictionary lua_parameter_dictionary(
|
||||||
|
code, std::move(file_resolver));
|
||||||
|
|
||||||
|
std::ifstream stream(trajectory_filename.c_str());
|
||||||
|
carto::mapping::proto::Trajectory trajectory_proto;
|
||||||
|
CHECK(trajectory_proto.ParseFromIstream(&stream));
|
||||||
|
|
||||||
|
carto::io::PointsProcessorPipelineBuilder builder;
|
||||||
|
carto::io::RegisterBuiltInPointsProcessors(trajectory_proto, &builder);
|
||||||
|
std::vector<std::unique_ptr<carto::io::PointsProcessor>> pipeline =
|
||||||
|
builder.CreatePipeline(
|
||||||
|
lua_parameter_dictionary.GetDictionary("pipeline").get());
|
||||||
|
|
||||||
|
auto tf_buffer = ::cartographer::common::make_unique<tf2_ros::Buffer>();
|
||||||
|
if (!urdf_filename.empty()) {
|
||||||
|
ReadStaticTransformsFromUrdf(urdf_filename, tf_buffer.get());
|
||||||
|
} else {
|
||||||
|
LOG(INFO) << "Pre-loading transforms from bag...";
|
||||||
|
tf_buffer = ReadTransformsFromBag(bag_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
const string tracking_frame =
|
||||||
|
lua_parameter_dictionary.GetString("tracking_frame");
|
||||||
|
const auto transform_interpolation_buffer =
|
||||||
|
carto::transform::TransformInterpolationBuffer::FromTrajectory(
|
||||||
|
trajectory_proto);
|
||||||
|
LOG(INFO) << "Processing pipeline...";
|
||||||
do {
|
do {
|
||||||
rosbag::Bag bag;
|
rosbag::Bag bag;
|
||||||
bag.open(bag_filename, rosbag::bagmode::Read);
|
bag.open(bag_filename, rosbag::bagmode::Read);
|
||||||
|
@ -131,7 +137,9 @@ void Run(const string& trajectory_filename, const string& bag_filename,
|
||||||
|
|
||||||
for (const rosbag::MessageInstance& msg : view) {
|
for (const rosbag::MessageInstance& msg : view) {
|
||||||
if (msg.isType<sensor_msgs::PointCloud2>()) {
|
if (msg.isType<sensor_msgs::PointCloud2>()) {
|
||||||
handle_point_cloud_2_message(msg.instantiate<sensor_msgs::PointCloud2>());
|
HandlePointCloud2Message(msg.instantiate<sensor_msgs::PointCloud2>(),
|
||||||
|
tracking_frame, *tf_buffer,
|
||||||
|
*transform_interpolation_buffer, pipeline);
|
||||||
}
|
}
|
||||||
LOG_EVERY_N(INFO, 100000)
|
LOG_EVERY_N(INFO, 100000)
|
||||||
<< "Processed " << (msg.getTime() - begin_time).toSec() << " of "
|
<< "Processed " << (msg.getTime() - begin_time).toSec() << " of "
|
||||||
|
@ -146,6 +154,7 @@ void Run(const string& trajectory_filename, const string& bag_filename,
|
||||||
} // namespace cartographer_ros
|
} // namespace cartographer_ros
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
FLAGS_alsologtostderr = true;
|
||||||
google::InitGoogleLogging(argv[0]);
|
google::InitGoogleLogging(argv[0]);
|
||||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
@ -156,7 +165,6 @@ int main(int argc, char** argv) {
|
||||||
CHECK(!FLAGS_bag_filename.empty()) << "-bag_filename is missing.";
|
CHECK(!FLAGS_bag_filename.empty()) << "-bag_filename is missing.";
|
||||||
CHECK(!FLAGS_trajectory_filename.empty())
|
CHECK(!FLAGS_trajectory_filename.empty())
|
||||||
<< "-trajectory_filename is missing.";
|
<< "-trajectory_filename is missing.";
|
||||||
CHECK(!FLAGS_urdf_filename.empty()) << "-urdf_filename is missing.";
|
|
||||||
|
|
||||||
::cartographer_ros::Run(FLAGS_trajectory_filename, FLAGS_bag_filename,
|
::cartographer_ros::Run(FLAGS_trajectory_filename, FLAGS_bag_filename,
|
||||||
FLAGS_configuration_directory,
|
FLAGS_configuration_directory,
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 The Cartographer Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cartographer_ros/bag_reader.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cartographer/common/make_unique.h"
|
||||||
|
#include "glog/logging.h"
|
||||||
|
#include "rosbag/bag.h"
|
||||||
|
#include "rosbag/view.h"
|
||||||
|
#include "tf2_msgs/TFMessage.h"
|
||||||
|
|
||||||
|
namespace cartographer_ros {
|
||||||
|
|
||||||
|
constexpr char kTfStaticTopic[] = "/tf_static";
|
||||||
|
|
||||||
|
std::unique_ptr<tf2_ros::Buffer> ReadTransformsFromBag(
|
||||||
|
const string& bag_filename) {
|
||||||
|
rosbag::Bag bag;
|
||||||
|
bag.open(bag_filename, rosbag::bagmode::Read);
|
||||||
|
rosbag::View view(bag);
|
||||||
|
|
||||||
|
auto tf_buffer =
|
||||||
|
::cartographer::common::make_unique<tf2_ros::Buffer>(::ros::DURATION_MAX);
|
||||||
|
const ::ros::Time begin_time = view.getBeginTime();
|
||||||
|
const double duration_in_seconds = (view.getEndTime() - begin_time).toSec();
|
||||||
|
for (const rosbag::MessageInstance& msg : view) {
|
||||||
|
if (msg.isType<tf2_msgs::TFMessage>()) {
|
||||||
|
const auto tf_msg = msg.instantiate<tf2_msgs::TFMessage>();
|
||||||
|
for (const auto& transform : tf_msg->transforms) {
|
||||||
|
try {
|
||||||
|
// TODO(damonkohler): Handle topic remapping.
|
||||||
|
tf_buffer->setTransform(transform, "unused_authority",
|
||||||
|
msg.getTopic() == kTfStaticTopic);
|
||||||
|
} catch (const tf2::TransformException& ex) {
|
||||||
|
LOG(WARNING) << ex.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_EVERY_N(INFO, 100000) << "Processed "
|
||||||
|
<< (msg.getTime() - begin_time).toSec() << " of "
|
||||||
|
<< duration_in_seconds << " bag time seconds...";
|
||||||
|
}
|
||||||
|
|
||||||
|
bag.close();
|
||||||
|
return tf_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cartographer_ros
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 The Cartographer Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CARTOGRAPHER_ROS_BAG_READER_H_
|
||||||
|
#define CARTOGRAPHER_ROS_BAG_READER_H_
|
||||||
|
|
||||||
|
#include "cartographer/common/port.h"
|
||||||
|
#include "tf2_ros/buffer.h"
|
||||||
|
|
||||||
|
namespace cartographer_ros {
|
||||||
|
|
||||||
|
std::unique_ptr<tf2_ros::Buffer> ReadTransformsFromBag(
|
||||||
|
const string& bag_filename);
|
||||||
|
|
||||||
|
} // namespace cartographer_ros
|
||||||
|
|
||||||
|
#endif // CARTOGRAPHER_ROS_BAG_READER_H_
|
|
@ -22,6 +22,7 @@
|
||||||
#include "cartographer/common/lua_parameter_dictionary.h"
|
#include "cartographer/common/lua_parameter_dictionary.h"
|
||||||
#include "cartographer/common/make_unique.h"
|
#include "cartographer/common/make_unique.h"
|
||||||
#include "cartographer/common/port.h"
|
#include "cartographer/common/port.h"
|
||||||
|
#include "cartographer_ros/bag_reader.h"
|
||||||
#include "cartographer_ros/node.h"
|
#include "cartographer_ros/node.h"
|
||||||
#include "cartographer_ros/ros_log_sink.h"
|
#include "cartographer_ros/ros_log_sink.h"
|
||||||
#include "cartographer_ros/urdf_reader.h"
|
#include "cartographer_ros/urdf_reader.h"
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
#include "rosbag/bag.h"
|
#include "rosbag/bag.h"
|
||||||
#include "rosbag/view.h"
|
#include "rosbag/view.h"
|
||||||
#include "rosgraph_msgs/Clock.h"
|
#include "rosgraph_msgs/Clock.h"
|
||||||
|
#include "tf2_msgs/TFMessage.h"
|
||||||
#include "urdf/model.h"
|
#include "urdf/model.h"
|
||||||
|
|
||||||
DEFINE_string(configuration_directory, "",
|
DEFINE_string(configuration_directory, "",
|
||||||
|
@ -48,6 +50,7 @@ namespace {
|
||||||
|
|
||||||
constexpr int kLatestOnlyPublisherQueueSize = 1;
|
constexpr int kLatestOnlyPublisherQueueSize = 1;
|
||||||
constexpr char kClockTopic[] = "clock";
|
constexpr char kClockTopic[] = "clock";
|
||||||
|
constexpr char kTfStaticTopic[] = "/tf_static";
|
||||||
|
|
||||||
std::vector<string> SplitString(const string& input, const char delimiter) {
|
std::vector<string> SplitString(const string& input, const char delimiter) {
|
||||||
std::stringstream stream(input);
|
std::stringstream stream(input);
|
||||||
|
@ -68,11 +71,23 @@ void Run(std::vector<string> bag_filenames) {
|
||||||
cartographer::common::LuaParameterDictionary lua_parameter_dictionary(
|
cartographer::common::LuaParameterDictionary lua_parameter_dictionary(
|
||||||
code, std::move(file_resolver));
|
code, std::move(file_resolver));
|
||||||
|
|
||||||
tf2_ros::Buffer tf_buffer;
|
auto tf_buffer = ::cartographer::common::make_unique<tf2_ros::Buffer>();
|
||||||
tf_buffer.setUsingDedicatedThread(true);
|
if (!FLAGS_urdf_filename.empty()) {
|
||||||
ReadStaticTransformsFromUrdf(FLAGS_urdf_filename, &tf_buffer);
|
ReadStaticTransformsFromUrdf(FLAGS_urdf_filename, tf_buffer.get());
|
||||||
const auto options = CreateNodeOptions(&lua_parameter_dictionary);
|
} else {
|
||||||
Node node(options, &tf_buffer);
|
LOG(INFO) << "Pre-loading transforms from bag...";
|
||||||
|
// TODO(damonkohler): Support multi-trajectory.
|
||||||
|
CHECK_EQ(bag_filenames.size(), 1);
|
||||||
|
tf_buffer = ReadTransformsFromBag(bag_filenames.back());
|
||||||
|
}
|
||||||
|
tf_buffer->setUsingDedicatedThread(true);
|
||||||
|
|
||||||
|
auto options = CreateNodeOptions(&lua_parameter_dictionary);
|
||||||
|
// Since we preload the transform buffer, we should never have to wait for a
|
||||||
|
// transform. When we finish processing the bag, we will simply drop any
|
||||||
|
// remaining sensor data that cannot be transformed due to missing transforms.
|
||||||
|
options.lookup_transform_timeout_sec = 0.;
|
||||||
|
Node node(options, tf_buffer.get());
|
||||||
node.Initialize();
|
node.Initialize();
|
||||||
|
|
||||||
std::unordered_set<string> expected_sensor_ids;
|
std::unordered_set<string> expected_sensor_ids;
|
||||||
|
@ -138,6 +153,7 @@ void Run(std::vector<string> bag_filenames) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(damonkohler): Republish non-conflicting tf messages.
|
||||||
const string topic = node.node_handle()->resolveName(msg.getTopic());
|
const string topic = node.node_handle()->resolveName(msg.getTopic());
|
||||||
if (expected_sensor_ids.count(topic) == 0) {
|
if (expected_sensor_ids.count(topic) == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -147,21 +163,25 @@ void Run(std::vector<string> bag_filenames) {
|
||||||
->sensor_bridge(trajectory_id)
|
->sensor_bridge(trajectory_id)
|
||||||
->HandleLaserScanMessage(topic,
|
->HandleLaserScanMessage(topic,
|
||||||
msg.instantiate<sensor_msgs::LaserScan>());
|
msg.instantiate<sensor_msgs::LaserScan>());
|
||||||
} else if (msg.isType<sensor_msgs::MultiEchoLaserScan>()) {
|
}
|
||||||
|
if (msg.isType<sensor_msgs::MultiEchoLaserScan>()) {
|
||||||
node.map_builder_bridge()
|
node.map_builder_bridge()
|
||||||
->sensor_bridge(trajectory_id)
|
->sensor_bridge(trajectory_id)
|
||||||
->HandleMultiEchoLaserScanMessage(
|
->HandleMultiEchoLaserScanMessage(
|
||||||
topic, msg.instantiate<sensor_msgs::MultiEchoLaserScan>());
|
topic, msg.instantiate<sensor_msgs::MultiEchoLaserScan>());
|
||||||
} else if (msg.isType<sensor_msgs::PointCloud2>()) {
|
}
|
||||||
|
if (msg.isType<sensor_msgs::PointCloud2>()) {
|
||||||
node.map_builder_bridge()
|
node.map_builder_bridge()
|
||||||
->sensor_bridge(trajectory_id)
|
->sensor_bridge(trajectory_id)
|
||||||
->HandlePointCloud2Message(
|
->HandlePointCloud2Message(
|
||||||
topic, msg.instantiate<sensor_msgs::PointCloud2>());
|
topic, msg.instantiate<sensor_msgs::PointCloud2>());
|
||||||
} else if (msg.isType<sensor_msgs::Imu>()) {
|
}
|
||||||
|
if (msg.isType<sensor_msgs::Imu>()) {
|
||||||
node.map_builder_bridge()
|
node.map_builder_bridge()
|
||||||
->sensor_bridge(trajectory_id)
|
->sensor_bridge(trajectory_id)
|
||||||
->HandleImuMessage(topic, msg.instantiate<sensor_msgs::Imu>());
|
->HandleImuMessage(topic, msg.instantiate<sensor_msgs::Imu>());
|
||||||
} else if (msg.isType<nav_msgs::Odometry>()) {
|
}
|
||||||
|
if (msg.isType<nav_msgs::Odometry>()) {
|
||||||
node.map_builder_bridge()
|
node.map_builder_bridge()
|
||||||
->sensor_bridge(trajectory_id)
|
->sensor_bridge(trajectory_id)
|
||||||
->HandleOdometryMessage(topic,
|
->HandleOdometryMessage(topic,
|
||||||
|
@ -190,6 +210,7 @@ void Run(std::vector<string> bag_filenames) {
|
||||||
} // namespace cartographer_ros
|
} // namespace cartographer_ros
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
FLAGS_alsologtostderr = true;
|
||||||
google::InitGoogleLogging(argv[0]);
|
google::InitGoogleLogging(argv[0]);
|
||||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
@ -198,7 +219,6 @@ int main(int argc, char** argv) {
|
||||||
CHECK(!FLAGS_configuration_basename.empty())
|
CHECK(!FLAGS_configuration_basename.empty())
|
||||||
<< "-configuration_basename is missing.";
|
<< "-configuration_basename is missing.";
|
||||||
CHECK(!FLAGS_bag_filenames.empty()) << "-bag_filenames is missing.";
|
CHECK(!FLAGS_bag_filenames.empty()) << "-bag_filenames is missing.";
|
||||||
CHECK(!FLAGS_urdf_filename.empty()) << "-urdf_filename is missing.";
|
|
||||||
|
|
||||||
::ros::init(argc, argv, "cartographer_offline_node");
|
::ros::init(argc, argv, "cartographer_offline_node");
|
||||||
::ros::start();
|
::ros::start();
|
||||||
|
|
Loading…
Reference in New Issue