diff --git a/cartographer/io/internal/pbstream_migrate.cc b/cartographer/io/internal/pbstream_migrate.cc index c21aa5f..59f1743 100644 --- a/cartographer/io/internal/pbstream_migrate.cc +++ b/cartographer/io/internal/pbstream_migrate.cc @@ -21,6 +21,10 @@ #include "gflags/gflags.h" #include "glog/logging.h" +DEFINE_bool(migrate_grid_format, false, + "Set if the submap data of the input pbstream uses the old " + "probability grid format."); + namespace cartographer { namespace io { @@ -28,9 +32,10 @@ int pbstream_migrate(int argc, char** argv) { std::stringstream ss; ss << "\n\nTool for migrating files that use the serialization output of " "Cartographer 0.3, to the new serialization format, which includes a " - "header (Version 1)." + "header (Version 1). You may need to specify the '--migrate_grid_format" + " flag if the input file contains submaps with the legacy grid format." << "\nUsage: " << argv[0] << " " << argv[1] - << " "; + << " [flags]"; google::SetUsageMessage(ss.str()); if (argc < 4) { @@ -41,7 +46,8 @@ int pbstream_migrate(int argc, char** argv) { cartographer::io::ProtoStreamWriter output(argv[3]); LOG(INFO) << "Migrating old serialization format in \"" << argv[2] << "\" to new serialization format in \"" << argv[3] << "\""; - cartographer::io::MigrateStreamFormatToVersion1(&input, &output); + cartographer::io::MigrateStreamFormatToVersion1(&input, &output, + FLAGS_migrate_grid_format); return EXIT_SUCCESS; } diff --git a/cartographer/io/pbstream_main.cc b/cartographer/io/pbstream_main.cc index e111082..6055b77 100644 --- a/cartographer/io/pbstream_main.cc +++ b/cartographer/io/pbstream_main.cc @@ -26,14 +26,15 @@ int main(int argc, char** argv) { google::InitGoogleLogging(argv[0]); FLAGS_logtostderr = true; - google::SetUsageMessage( + const std::string usage_message = "Swiss Army knife for pbstreams.\n\n" "Currently supported subcommands are:\n" "\tinfo - Prints summary of pbstream.\n" - "\tmigrate - Migrates old pbstream (w/o header) to new pbstream format."); + "\tmigrate - Migrates old pbstream (w/o header) to new pbstream format."; google::ParseCommandLineFlags(&argc, &argv, true); if (argc < 2) { + google::SetUsageMessage(usage_message); google::ShowUsageWithFlagsRestrict(argv[0], "pbstream_info_main"); return EXIT_FAILURE; } else if (std::string(argv[1]) == "info") { @@ -42,6 +43,7 @@ int main(int argc, char** argv) { return ::cartographer::io::pbstream_migrate(argc, argv); } else { LOG(INFO) << "Unknown subtool: \"" << argv[1]; + google::SetUsageMessage(usage_message); google::ShowUsageWithFlagsRestrict(argv[0], "pbstream_info_main"); return EXIT_FAILURE; } diff --git a/cartographer/io/serialization_format_migration.cc b/cartographer/io/serialization_format_migration.cc index 7bb015c..5f26710 100644 --- a/cartographer/io/serialization_format_migration.cc +++ b/cartographer/io/serialization_format_migration.cc @@ -19,7 +19,9 @@ #include #include +#include "cartographer/mapping/probability_values.h" #include "cartographer/mapping/proto/internal/legacy_serialized_data.pb.h" +#include "cartographer/mapping/proto/internal/legacy_submap.pb.h" #include "cartographer/mapping/proto/trajectory_builder_options.pb.h" #include "glog/logging.h" @@ -47,22 +49,89 @@ bool ReadBuilderOptions( options_vec.back().mutable_all_trajectory_builder_options()); } +mapping::proto::Submap MigrateLegacySubmap2d( + const mapping::proto::LegacySubmap& submap_in) { + mapping::proto::Submap2D submap_2d; + + // Convert probability grid to generalized grid. + *submap_2d.mutable_grid()->mutable_limits() = + submap_in.submap_2d().probability_grid().limits(); + *submap_2d.mutable_grid()->mutable_cells() = + submap_in.submap_2d().probability_grid().cells(); + for (auto& cell : *submap_2d.mutable_grid()->mutable_cells()) { + cell = -1 * cell; + } + // CellBox can't be trivially copied because the protobuf + // serialization field number doesn't match. + submap_2d.mutable_grid()->mutable_known_cells_box()->set_max_x( + submap_in.submap_2d().probability_grid().known_cells_box().max_x()); + submap_2d.mutable_grid()->mutable_known_cells_box()->set_max_y( + submap_in.submap_2d().probability_grid().known_cells_box().max_y()); + submap_2d.mutable_grid()->mutable_known_cells_box()->set_min_x( + submap_in.submap_2d().probability_grid().known_cells_box().min_x()); + submap_2d.mutable_grid()->mutable_known_cells_box()->set_min_y( + submap_in.submap_2d().probability_grid().known_cells_box().min_y()); + + // Correspondence costs can be safely set to standard values. + // Otherwise, this would be done during the next deserialization, but with a + // warning, which we can avoid by setting it already here. + submap_2d.mutable_grid()->set_max_correspondence_cost( + mapping::kMaxCorrespondenceCost); + submap_2d.mutable_grid()->set_min_correspondence_cost( + mapping::kMinCorrespondenceCost); + submap_2d.mutable_grid()->mutable_probability_grid_2d(); + *submap_2d.mutable_local_pose() = submap_in.submap_2d().local_pose(); + submap_2d.set_num_range_data(submap_in.submap_2d().num_range_data()); + submap_2d.set_finished(submap_in.submap_2d().finished()); + + mapping::proto::Submap submap_out; + *submap_out.mutable_submap_2d() = submap_2d; + *submap_out.mutable_submap_id() = submap_in.submap_id(); + return submap_out; +} + +mapping::proto::Submap MigrateLegacySubmap3d( + const mapping::proto::LegacySubmap& submap_in) { + mapping::proto::Submap3D submap_3d; + *submap_3d.mutable_local_pose() = submap_in.submap_3d().local_pose(); + submap_3d.set_num_range_data(submap_in.submap_3d().num_range_data()); + submap_3d.set_finished(submap_in.submap_3d().finished()); + *submap_3d.mutable_high_resolution_hybrid_grid() = + submap_in.submap_3d().high_resolution_hybrid_grid(); + *submap_3d.mutable_low_resolution_hybrid_grid() = + submap_in.submap_3d().low_resolution_hybrid_grid(); + + mapping::proto::Submap submap_out; + *submap_out.mutable_submap_3d() = submap_3d; + *submap_out.mutable_submap_id() = submap_in.submap_id(); + return submap_out; +} + bool DeserializeNext(cartographer::io::ProtoStreamReaderInterface* const input, ProtoMap* proto_map) { mapping::proto::LegacySerializedData legacy_data; if (!input->ReadProto(&legacy_data)) return false; if (legacy_data.has_submap()) { + LOG_FIRST_N(INFO, 1) << "Migrating submap data."; + if (legacy_data.submap().has_submap_2d()) { + CHECK(legacy_data.submap().submap_2d().grid().has_probability_grid_2d() || + legacy_data.submap().submap_2d().grid().has_tsdf_2d()) + << "\nThe legacy data contains a 2D submap, but it's not using the " + "expected grid format. Try to migrate the grid format instead."; + } auto& output_vector = (*proto_map)[SerializedData::kSubmapFieldNumber]; output_vector.emplace_back(); *output_vector.back().mutable_submap() = legacy_data.submap(); } if (legacy_data.has_node()) { + LOG_FIRST_N(INFO, 1) << "Migrating node data."; auto& output_vector = (*proto_map)[SerializedData::kNodeFieldNumber]; output_vector.emplace_back(); *output_vector.back().mutable_node() = legacy_data.node(); } if (legacy_data.has_trajectory_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating trajectory data."; auto& output_vector = (*proto_map)[SerializedData::kTrajectoryDataFieldNumber]; output_vector.emplace_back(); @@ -70,16 +139,19 @@ bool DeserializeNext(cartographer::io::ProtoStreamReaderInterface* const input, legacy_data.trajectory_data(); } if (legacy_data.has_imu_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating IMU data."; auto& output_vector = (*proto_map)[SerializedData::kImuDataFieldNumber]; output_vector.emplace_back(); *output_vector.back().mutable_imu_data() = legacy_data.imu_data(); } if (legacy_data.has_odometry_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating odometry data."; auto& output_vector = (*proto_map)[SerializedData::kOdometryData]; output_vector.emplace_back(); *output_vector.back().mutable_odometry_data() = legacy_data.odometry_data(); } if (legacy_data.has_fixed_frame_pose_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating fixed frame pose data."; auto& output_vector = (*proto_map)[SerializedData::kFixedFramePoseDataFieldNumber]; output_vector.emplace_back(); @@ -87,6 +159,72 @@ bool DeserializeNext(cartographer::io::ProtoStreamReaderInterface* const input, legacy_data.fixed_frame_pose_data(); } if (legacy_data.has_landmark_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating landmark data."; + auto& output_vector = + (*proto_map)[SerializedData::kLandmarkDataFieldNumber]; + output_vector.emplace_back(); + *output_vector.back().mutable_landmark_data() = legacy_data.landmark_data(); + } + return true; +} + +bool DeserializeNextAndMigrateGridFormat( + cartographer::io::ProtoStreamReaderInterface* const input, + ProtoMap* proto_map) { + mapping::proto::LegacySerializedDataLegacySubmap legacy_data; + if (!input->ReadProto(&legacy_data)) return false; + + if (legacy_data.has_submap()) { + LOG_FIRST_N(INFO, 1) << "Migrating submap data."; + auto& output_vector = (*proto_map)[SerializedData::kSubmapFieldNumber]; + output_vector.emplace_back(); + if (legacy_data.submap().has_submap_2d()) { + CHECK(legacy_data.submap().submap_2d().has_probability_grid()) + << "\nThe legacy data contains a 2D submap, but it has no legacy " + "probability grid that can be migrated to the new grid format."; + *output_vector.back().mutable_submap() = + MigrateLegacySubmap2d(legacy_data.submap()); + } else { + *output_vector.back().mutable_submap() = + MigrateLegacySubmap3d(legacy_data.submap()); + } + } + if (legacy_data.has_node()) { + LOG_FIRST_N(INFO, 1) << "Migrating node data."; + auto& output_vector = (*proto_map)[SerializedData::kNodeFieldNumber]; + output_vector.emplace_back(); + *output_vector.back().mutable_node() = legacy_data.node(); + } + if (legacy_data.has_trajectory_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating trajectory data."; + auto& output_vector = + (*proto_map)[SerializedData::kTrajectoryDataFieldNumber]; + output_vector.emplace_back(); + *output_vector.back().mutable_trajectory_data() = + legacy_data.trajectory_data(); + } + if (legacy_data.has_imu_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating IMU data."; + auto& output_vector = (*proto_map)[SerializedData::kImuDataFieldNumber]; + output_vector.emplace_back(); + *output_vector.back().mutable_imu_data() = legacy_data.imu_data(); + } + if (legacy_data.has_odometry_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating odometry data."; + auto& output_vector = (*proto_map)[SerializedData::kOdometryData]; + output_vector.emplace_back(); + *output_vector.back().mutable_odometry_data() = legacy_data.odometry_data(); + } + if (legacy_data.has_fixed_frame_pose_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating fixed frame pose data."; + auto& output_vector = + (*proto_map)[SerializedData::kFixedFramePoseDataFieldNumber]; + output_vector.emplace_back(); + *output_vector.back().mutable_fixed_frame_pose_data() = + legacy_data.fixed_frame_pose_data(); + } + if (legacy_data.has_landmark_data()) { + LOG_FIRST_N(INFO, 1) << "Migrating landmark data."; auto& output_vector = (*proto_map)[SerializedData::kLandmarkDataFieldNumber]; output_vector.emplace_back(); @@ -96,7 +234,8 @@ bool DeserializeNext(cartographer::io::ProtoStreamReaderInterface* const input, } ProtoMap ParseLegacyData( - cartographer::io::ProtoStreamReaderInterface* const input) { + cartographer::io::ProtoStreamReaderInterface* const input, + bool migrate_grid_format) { ProtoMap proto_map; CHECK(ReadPoseGraph(input, &proto_map)) << "Input stream seems to differ from original stream format. Could " @@ -106,8 +245,13 @@ ProtoMap ParseLegacyData( << "Input stream seems to differ from original stream format. Could " "not " "read AllTrajectoryBuilderOptions as second message."; - do { - } while (DeserializeNext(input, &proto_map)); + if (migrate_grid_format) { + do { + } while (DeserializeNextAndMigrateGridFormat(input, &proto_map)); + } else { + do { + } while (DeserializeNext(input, &proto_map)); + } return proto_map; } @@ -145,8 +289,10 @@ void SerializeToVersion1Format( void MigrateStreamFormatToVersion1( cartographer::io::ProtoStreamReaderInterface* const input, - cartographer::io::ProtoStreamWriterInterface* const output) { - SerializeToVersion1Format(ParseLegacyData(input), output); + cartographer::io::ProtoStreamWriterInterface* const output, + bool migrate_grid_format) { + SerializeToVersion1Format(ParseLegacyData(input, migrate_grid_format), + output); } } // namespace io diff --git a/cartographer/io/serialization_format_migration.h b/cartographer/io/serialization_format_migration.h index c6f4982..20c6017 100644 --- a/cartographer/io/serialization_format_migration.h +++ b/cartographer/io/serialization_format_migration.h @@ -28,7 +28,8 @@ namespace io { // SerializedData*). void MigrateStreamFormatToVersion1( cartographer::io::ProtoStreamReaderInterface* const input, - cartographer::io::ProtoStreamWriterInterface* const output); + cartographer::io::ProtoStreamWriterInterface* const output, + bool migrate_grid_format); } // namespace io } // namespace cartographer diff --git a/cartographer/io/serialization_format_migration_test.cc b/cartographer/io/serialization_format_migration_test.cc index 0d8bec3..11bee22 100644 --- a/cartographer/io/serialization_format_migration_test.cc +++ b/cartographer/io/serialization_format_migration_test.cc @@ -37,8 +37,43 @@ using ::testing::Eq; using ::testing::SizeIs; class MigrationTest : public ::testing::Test { + private: + template + void AddLegacyDataToReader(InMemoryProtoStreamReader& reader) { + mapping::proto::PoseGraph pose_graph; + mapping::proto::AllTrajectoryBuilderOptions all_options; + LegacySerializedDataType submap; + submap.mutable_submap(); + LegacySerializedDataType node; + node.mutable_node(); + LegacySerializedDataType imu_data; + imu_data.mutable_imu_data(); + LegacySerializedDataType odometry_data; + odometry_data.mutable_odometry_data(); + LegacySerializedDataType fixed_frame_pose; + fixed_frame_pose.mutable_fixed_frame_pose_data(); + LegacySerializedDataType trajectory_data; + trajectory_data.mutable_trajectory_data(); + LegacySerializedDataType landmark_data; + landmark_data.mutable_landmark_data(); + + reader.AddProto(pose_graph); + reader.AddProto(all_options); + reader.AddProto(submap); + reader.AddProto(node); + reader.AddProto(imu_data); + reader.AddProto(odometry_data); + reader.AddProto(fixed_frame_pose); + reader.AddProto(trajectory_data); + reader.AddProto(landmark_data); + } + protected: void SetUp() { + AddLegacyDataToReader(reader_); + AddLegacyDataToReader( + reader_for_migrating_grid_); + writer_.reset(new ForwardingProtoStreamWriter( [this](const google::protobuf::Message* proto) -> bool { std::string msg_string; @@ -46,44 +81,28 @@ class MigrationTest : public ::testing::Test { this->output_messages_.push_back(msg_string); return true; })); - - mapping::proto::PoseGraph pose_graph; - mapping::proto::AllTrajectoryBuilderOptions all_options; - mapping::proto::LegacySerializedData submap; - submap.mutable_submap(); - mapping::proto::LegacySerializedData node; - node.mutable_node(); - mapping::proto::LegacySerializedData imu_data; - imu_data.mutable_imu_data(); - mapping::proto::LegacySerializedData odometry_data; - odometry_data.mutable_odometry_data(); - mapping::proto::LegacySerializedData fixed_frame_pose; - fixed_frame_pose.mutable_fixed_frame_pose_data(); - mapping::proto::LegacySerializedData trajectory_data; - trajectory_data.mutable_trajectory_data(); - mapping::proto::LegacySerializedData landmark_data; - landmark_data.mutable_landmark_data(); - - reader_.AddProto(pose_graph); - reader_.AddProto(all_options); - reader_.AddProto(submap); - reader_.AddProto(node); - reader_.AddProto(imu_data); - reader_.AddProto(odometry_data); - reader_.AddProto(fixed_frame_pose); - reader_.AddProto(trajectory_data); - reader_.AddProto(landmark_data); + writer_for_migrating_grid_.reset(new ForwardingProtoStreamWriter( + [this](const google::protobuf::Message* proto) -> bool { + std::string msg_string; + TextFormat::PrintToString(*proto, &msg_string); + this->output_messages_after_migrating_grid_.push_back(msg_string); + return true; + })); } InMemoryProtoStreamReader reader_; + InMemoryProtoStreamReader reader_for_migrating_grid_; std::unique_ptr writer_; + std::unique_ptr writer_for_migrating_grid_; std::vector output_messages_; + std::vector output_messages_after_migrating_grid_; static constexpr int kNumOriginalMessages = 9; }; TEST_F(MigrationTest, MigrationAddsHeaderAsFirstMessage) { - MigrateStreamFormatToVersion1(&reader_, writer_.get()); + MigrateStreamFormatToVersion1(&reader_, writer_.get(), + false /* migrate_grid_format */); // We expect one message more than the original number of messages, because of // the added header. EXPECT_THAT(output_messages_, SizeIs(kNumOriginalMessages + 1)); @@ -93,8 +112,24 @@ TEST_F(MigrationTest, MigrationAddsHeaderAsFirstMessage) { EXPECT_THAT(header.format_version(), Eq(1)); } +TEST_F(MigrationTest, MigrationWithGridMigrationAddsHeaderAsFirstMessage) { + MigrateStreamFormatToVersion1(&reader_for_migrating_grid_, + writer_for_migrating_grid_.get(), + true /* migrate_grid_format */); + // We expect one message more than the original number of messages, because of + // the added header. + EXPECT_THAT(output_messages_after_migrating_grid_, + SizeIs(kNumOriginalMessages + 1)); + + mapping::proto::SerializationHeader header; + EXPECT_TRUE(TextFormat::ParseFromString( + output_messages_after_migrating_grid_[0], &header)); + EXPECT_THAT(header.format_version(), Eq(1)); +} + TEST_F(MigrationTest, SerializedDataOrderIsCorrect) { - MigrateStreamFormatToVersion1(&reader_, writer_.get()); + MigrateStreamFormatToVersion1(&reader_, writer_.get(), + false /* migrate_grid_format */); EXPECT_THAT(output_messages_, SizeIs(kNumOriginalMessages + 1)); std::vector serialized( @@ -115,6 +150,31 @@ TEST_F(MigrationTest, SerializedDataOrderIsCorrect) { EXPECT_TRUE(serialized[8].has_landmark_data()); } +TEST_F(MigrationTest, SerializedDataOrderAfterGridMigrationIsCorrect) { + MigrateStreamFormatToVersion1(&reader_for_migrating_grid_, + writer_for_migrating_grid_.get(), + true /* migrate_grid_format */); + EXPECT_THAT(output_messages_after_migrating_grid_, + SizeIs(kNumOriginalMessages + 1)); + + std::vector serialized( + output_messages_after_migrating_grid_.size() - 1); + for (size_t i = 1; i < output_messages_after_migrating_grid_.size(); ++i) { + EXPECT_TRUE(TextFormat::ParseFromString( + output_messages_after_migrating_grid_[i], &serialized[i - 1])); + } + + EXPECT_TRUE(serialized[0].has_pose_graph()); + EXPECT_TRUE(serialized[1].has_all_trajectory_builder_options()); + EXPECT_TRUE(serialized[2].has_submap()); + EXPECT_TRUE(serialized[3].has_node()); + EXPECT_TRUE(serialized[4].has_trajectory_data()); + EXPECT_TRUE(serialized[5].has_imu_data()); + EXPECT_TRUE(serialized[6].has_odometry_data()); + EXPECT_TRUE(serialized[7].has_fixed_frame_pose_data()); + EXPECT_TRUE(serialized[8].has_landmark_data()); +} + } // namespace } // namespace io } // namespace cartographer diff --git a/cartographer/mapping/2d/grid_2d.cc b/cartographer/mapping/2d/grid_2d.cc index 5eb5af5..d64d897 100644 --- a/cartographer/mapping/2d/grid_2d.cc +++ b/cartographer/mapping/2d/grid_2d.cc @@ -24,10 +24,9 @@ namespace { float MinCorrespondenceCostFromProto(const proto::Grid2D& proto) { if (proto.min_correspondence_cost() == 0.f && proto.max_correspondence_cost() == 0.f) { - LOG(WARNING) - << "proto::Grid2D: max_correspondence_cost and min_correspondence_cost " - "are initialized with 0 indicating an older version of the " - "protobuf format. Loading default values."; + LOG(WARNING) << "proto::Grid2D: min_correspondence_cost " + "is initialized with 0 indicating an older version of the " + "protobuf format. Loading default values."; return kMinCorrespondenceCost; } else { return proto.min_correspondence_cost(); @@ -37,10 +36,9 @@ float MinCorrespondenceCostFromProto(const proto::Grid2D& proto) { float MaxCorrespondenceCostFromProto(const proto::Grid2D& proto) { if (proto.min_correspondence_cost() == 0.f && proto.max_correspondence_cost() == 0.f) { - LOG(WARNING) - << "proto::Grid2D: max_correspondence_cost and min_correspondence_cost " - "are initialized with 0 indicating an older version of the " - "protobuf format. Loading default values."; + LOG(WARNING) << "proto::Grid2D: max_correspondence_cost " + "is initialized with 0 indicating an older version of the " + "protobuf format. Loading default values."; return kMaxCorrespondenceCost; } else { return proto.max_correspondence_cost(); diff --git a/cartographer/mapping/proto/internal/legacy_probability_grid.proto b/cartographer/mapping/proto/internal/legacy_probability_grid.proto new file mode 100644 index 0000000..58d9d68 --- /dev/null +++ b/cartographer/mapping/proto/internal/legacy_probability_grid.proto @@ -0,0 +1,37 @@ +// 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. + +syntax = "proto3"; + +package cartographer.mapping.proto; + +import "cartographer/mapping/proto/2d/map_limits.proto"; + +// The legacy probability grid that was used before the generalized +// grid structure was introduced. + +message LegacyProbabilityGrid { + message CellBox { + int32 max_x = 1; + int32 max_y = 2; + int32 min_x = 3; + int32 min_y = 4; + } + + MapLimits limits = 1; + // These values are actually int16s, but protos don't have a native int16 + // type. + repeated int32 cells = 2; + CellBox known_cells_box = 8; +} diff --git a/cartographer/mapping/proto/internal/legacy_serialized_data.proto b/cartographer/mapping/proto/internal/legacy_serialized_data.proto index 02189c3..56f9c6a 100644 --- a/cartographer/mapping/proto/internal/legacy_serialized_data.proto +++ b/cartographer/mapping/proto/internal/legacy_serialized_data.proto @@ -17,6 +17,7 @@ syntax = "proto3"; package cartographer.mapping.proto; import "cartographer/mapping/proto/serialization.proto"; +import "cartographer/mapping/proto/internal/legacy_submap.proto"; message LegacySerializedData { Submap submap = 1; @@ -27,3 +28,15 @@ message LegacySerializedData { TrajectoryData trajectory_data = 6; LandmarkData landmark_data = 7; } + +// For backwards compatibility with serialized data containing the legacy +// submap format that did not yet use the generalized 2D grid format. +message LegacySerializedDataLegacySubmap { + LegacySubmap submap = 1; + Node node = 2; + ImuData imu_data = 3; + OdometryData odometry_data = 4; + FixedFramePoseData fixed_frame_pose_data = 5; + TrajectoryData trajectory_data = 6; + LandmarkData landmark_data = 7; +} diff --git a/cartographer/mapping/proto/internal/legacy_submap.proto b/cartographer/mapping/proto/internal/legacy_submap.proto new file mode 100644 index 0000000..31ed41f --- /dev/null +++ b/cartographer/mapping/proto/internal/legacy_submap.proto @@ -0,0 +1,46 @@ +// 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. + +syntax = "proto3"; + +package cartographer.mapping.proto; + +import "cartographer/mapping/proto/pose_graph.proto"; +import "cartographer/mapping/proto/internal/legacy_probability_grid.proto"; +import "cartographer/mapping/proto/3d/hybrid_grid.proto"; +import "cartographer/transform/proto/transform.proto"; + +// Serialized state of a Submap2D. +// Uses the legacy, non-generalized probability grid format. +message LegacySubmap2D { + transform.proto.Rigid3d local_pose = 1; + int32 num_range_data = 2; + bool finished = 3; + LegacyProbabilityGrid probability_grid = 4; +} + +// Serialized state of a Submap3D. +message LegacySubmap3D { + transform.proto.Rigid3d local_pose = 1; + int32 num_range_data = 2; + bool finished = 3; + HybridGrid high_resolution_hybrid_grid = 4; + HybridGrid low_resolution_hybrid_grid = 5; +} + +message LegacySubmap { + SubmapId submap_id = 1; + LegacySubmap2D submap_2d = 2; + LegacySubmap3D submap_3d = 3; +}