From fbb283552536791289aae9ca9b1bdb0f7c391a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Sch=C3=BCtte?= Date: Tue, 29 May 2018 19:26:33 +0200 Subject: [PATCH] Implement receive_global_slam_optimizations_handler (#1169) --- .../cloud/internal/client_server_test.cc | 11 +++ ...ceive_global_slam_optimizations_handler.cc | 81 +++++++++++++++++++ ...eceive_global_slam_optimizations_handler.h | 49 +++++++++++ .../receive_local_slam_results_handler.cc | 12 ++- .../receive_local_slam_results_handler.h | 3 +- .../cloud/internal/map_builder_context_impl.h | 16 +++- .../internal/map_builder_context_interface.h | 27 +++++-- .../cloud/internal/map_builder_server.cc | 58 ++++++++++--- .../cloud/internal/map_builder_server.h | 25 ++++-- .../testing/mock_map_builder_context.h | 10 ++- .../cloud/proto/map_builder_service.proto | 11 +++ 11 files changed, 272 insertions(+), 31 deletions(-) create mode 100644 cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.cc create mode 100644 cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.h diff --git a/cartographer/cloud/internal/client_server_test.cc b/cartographer/cloud/internal/client_server_test.cc index 0cb0093..073edb4 100644 --- a/cartographer/cloud/internal/client_server_test.cc +++ b/cartographer/cloud/internal/client_server_test.cc @@ -21,6 +21,7 @@ #include "cartographer/cloud/internal/map_builder_server.h" #include "cartographer/cloud/map_builder_server_options.h" #include "cartographer/mapping/internal/testing/mock_map_builder.h" +#include "cartographer/mapping/internal/testing/mock_pose_graph.h" #include "cartographer/mapping/internal/testing/mock_trajectory_builder.h" #include "cartographer/mapping/internal/testing/test_helpers.h" #include "cartographer/mapping/local_slam_result_data.h" @@ -33,6 +34,7 @@ using ::cartographer::mapping::MapBuilderInterface; using ::cartographer::mapping::PoseGraphInterface; using ::cartographer::mapping::TrajectoryBuilderInterface; using ::cartographer::mapping::testing::MockMapBuilder; +using ::cartographer::mapping::testing::MockPoseGraph; using ::cartographer::mapping::testing::MockTrajectoryBuilder; using ::testing::_; using SensorId = ::cartographer::mapping::TrajectoryBuilderInterface::SensorId; @@ -126,6 +128,14 @@ class ClientServerTest : public ::testing::Test { void InitializeServerWithMockMapBuilder() { auto mock_map_builder = common::make_unique(); mock_map_builder_ = mock_map_builder.get(); + mock_pose_graph_ = common::make_unique(); + EXPECT_CALL( + *mock_map_builder_, + pose_graph()) + .WillOnce(::testing::Return(mock_pose_graph_.get())); + EXPECT_CALL( + *mock_pose_graph_, + SetGlobalSlamOptimizationCallback(_)); server_ = common::make_unique( map_builder_server_options_, std::move(mock_map_builder)); EXPECT_TRUE(server_ != nullptr); @@ -160,6 +170,7 @@ class ClientServerTest : public ::testing::Test { proto::MapBuilderServerOptions map_builder_server_options_; proto::MapBuilderServerOptions uploading_map_builder_server_options_; MockMapBuilder* mock_map_builder_; + std::unique_ptr mock_pose_graph_; std::unique_ptr mock_trajectory_builder_; ::cartographer::mapping::proto::TrajectoryBuilderOptions trajectory_builder_options_; diff --git a/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.cc b/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.cc new file mode 100644 index 0000000..5c902b7 --- /dev/null +++ b/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.cc @@ -0,0 +1,81 @@ +/* + * Copyright 2018 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/cloud/internal/handlers/receive_global_slam_optimizations_handler.h" + +#include "async_grpc/rpc_handler.h" +#include "cartographer/cloud/internal/map_builder_context_interface.h" +#include "cartographer/cloud/proto/map_builder_service.pb.h" +#include "cartographer/common/make_unique.h" +#include "cartographer/transform/transform.h" + +namespace cartographer { +namespace cloud { +namespace handlers { +namespace { + +std::unique_ptr GenerateResponse( + const std::map &last_optimized_submap_ids, + const std::map &last_optimized_node_ids) { + auto response = + common::make_unique(); + for (const auto &entry : last_optimized_submap_ids) { + entry.second.ToProto( + &(*response->mutable_last_optimized_submap_ids())[entry.first]); + } + for (const auto &entry : last_optimized_node_ids) { + entry.second.ToProto( + &(*response->mutable_last_optimized_node_ids())[entry.first]); + } + return response; +} + +} // namespace + +void ReceiveGlobalSlamOptimizationsHandler::OnRequest( + const google::protobuf::Empty &request) { + auto writer = GetWriter(); + const int subscription_index = + GetUnsynchronizedContext() + ->SubscribeGlobalSlamOptimizations( + [writer](const std::map + &last_optimized_submap_ids, + const std::map + &last_optimized_node_ids) { + if (!writer.Write(GenerateResponse(last_optimized_submap_ids, + last_optimized_node_ids))) { + // Client closed connection. + LOG(INFO) << "Client closed connection."; + return false; + } + return true; + }); + + LOG(INFO) << "Added subscription: " << subscription_index; + subscription_index_ = subscription_index; +} + +void ReceiveGlobalSlamOptimizationsHandler::OnFinish() { + if (subscription_index_.has_value()) { + LOG(INFO) << "Removing subscription " << subscription_index_.value(); + GetUnsynchronizedContext() + ->UnsubscribeGlobalSlamOptimizations(subscription_index_.value()); + } +} + +} // namespace handlers +} // namespace cloud +} // namespace cartographer diff --git a/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.h b/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.h new file mode 100644 index 0000000..8a177b6 --- /dev/null +++ b/cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018 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_CLOUD_INTERNAL_HANDLERS_RECEIVE_GLOBAL_SLAM_OPTIMIZATIONS_HANDLER_H +#define CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_RECEIVE_GLOBAL_SLAM_OPTIMIZATIONS_HANDLER_H + +#include + +#include "async_grpc/rpc_handler.h" +#include "cartographer/cloud/internal/map_builder_context_interface.h" +#include "cartographer/cloud/proto/map_builder_service.pb.h" + +namespace cartographer { +namespace cloud { +namespace handlers { + +DEFINE_HANDLER_SIGNATURE( + ReceiveGlobalSlamOptimizationsSignature, google::protobuf::Empty, + async_grpc::Stream, + "/cartographer.cloud.proto.MapBuilderService/" + "ReceiveGlobalSlamOptimizations") + +class ReceiveGlobalSlamOptimizationsHandler + : public async_grpc::RpcHandler { + public: + void OnRequest(const google::protobuf::Empty &request) override; + void OnFinish() override; + + private: + common::optional subscription_index_; +}; + +} // namespace handlers +} // namespace cloud +} // namespace cartographer + +#endif // CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_RECEIVE_GLOBAL_SLAM_OPTIMIZATIONS_HANDLER_H diff --git a/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.cc b/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.cc index e4239c4..94956f7 100644 --- a/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.cc +++ b/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.cc @@ -51,7 +51,7 @@ std::unique_ptr GenerateResponse( void ReceiveLocalSlamResultsHandler::OnRequest( const proto::ReceiveLocalSlamResultsRequest& request) { auto writer = GetWriter(); - MapBuilderContextInterface::SubscriptionId subscription_id = + MapBuilderContextInterface::LocalSlamSubscriptionId subscription_id = GetUnsynchronizedContext() ->SubscribeLocalSlamResults( request.trajectory_id(), @@ -59,16 +59,22 @@ void ReceiveLocalSlamResultsHandler::OnRequest( std::unique_ptr local_slam_result) { if (local_slam_result) { - writer.Write(GenerateResponse(std::move(local_slam_result))); + if (!writer.Write( + GenerateResponse(std::move(local_slam_result)))) { + // Client closed connection. + LOG(INFO) << "Client closed connection."; + return false; + } } else { // Callback with 'nullptr' signals that the trajectory // finished. writer.WritesDone(); } + return true; }); subscription_id_ = - common::make_unique( + common::make_unique( subscription_id); } diff --git a/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.h b/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.h index 4b7b704..41fb0b6 100644 --- a/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.h +++ b/cartographer/cloud/internal/handlers/receive_local_slam_results_handler.h @@ -39,7 +39,8 @@ class ReceiveLocalSlamResultsHandler void OnFinish() override; private: - std::unique_ptr subscription_id_; + std::unique_ptr + subscription_id_; }; } // namespace handlers diff --git a/cartographer/cloud/internal/map_builder_context_impl.h b/cartographer/cloud/internal/map_builder_context_impl.h index 7c77a52..18883a5 100644 --- a/cartographer/cloud/internal/map_builder_context_impl.h +++ b/cartographer/cloud/internal/map_builder_context_impl.h @@ -61,7 +61,7 @@ void MapBuilderContext::AddSensorDataToTrajectory( } template -MapBuilderContextInterface::SubscriptionId +MapBuilderContextInterface::LocalSlamSubscriptionId MapBuilderContext::SubscribeLocalSlamResults( int trajectory_id, LocalSlamSubscriptionCallback callback) { return map_builder_server_->SubscribeLocalSlamResults(trajectory_id, @@ -70,10 +70,22 @@ MapBuilderContext::SubscribeLocalSlamResults( template void MapBuilderContext::UnsubscribeLocalSlamResults( - const SubscriptionId& subscription_id) { + const LocalSlamSubscriptionId& subscription_id) { map_builder_server_->UnsubscribeLocalSlamResults(subscription_id); } +template +int MapBuilderContext::SubscribeGlobalSlamOptimizations( + GlobalSlamOptimizationCallback callback) { + return map_builder_server_->SubscribeGlobalSlamOptimizations(callback); +} + +template +void MapBuilderContext::UnsubscribeGlobalSlamOptimizations( + int subscription_index) { + map_builder_server_->UnsubscribeGlobalSlamOptimizations(subscription_index); +} + template void MapBuilderContext::NotifyFinishTrajectory(int trajectory_id) { map_builder_server_->NotifyFinishTrajectory(trajectory_id); diff --git a/cartographer/cloud/internal/map_builder_context_interface.h b/cartographer/cloud/internal/map_builder_context_interface.h index 388ec74..6a87a14 100644 --- a/cartographer/cloud/internal/map_builder_context_interface.h +++ b/cartographer/cloud/internal/map_builder_context_interface.h @@ -21,6 +21,7 @@ #include "cartographer/cloud/internal/local_trajectory_uploader.h" #include "cartographer/common/blocking_queue.h" #include "cartographer/mapping/map_builder_interface.h" +#include "cartographer/mapping/pose_graph_interface.h" #include "cartographer/mapping/proto/serialization.pb.h" #include "cartographer/sensor/data.h" #include "cartographer/sensor/range_data.h" @@ -40,14 +41,27 @@ class MapBuilderContextInterface : public async_grpc::ExecutionContext { std::unique_ptr insertion_result; }; - // Calling with 'nullptr' signals subscribers that the subscription has ended. + // Calling with 'nullptr' signals subscribers that the subscription has ended, + // e.g. this happens when the corresponding trajectory was finished and hence + // no more local SLAM updates will occur. + // The callback can return 'false' to indicate that the client is not + // interested in more local SLAM updates and 'MapBuilderServer' will end the + // subscription. using LocalSlamSubscriptionCallback = - std::function)>; + std::function)>; + + // The callback can return 'false' to indicate that the client is not + // interested in more global SLAM runs and 'MapBuilderServer' will end the + // subscription. + using GlobalSlamOptimizationCallback = std::function&, + const std::map&)>; + struct Data { int trajectory_id; std::unique_ptr data; }; - struct SubscriptionId { + struct LocalSlamSubscriptionId { const int trajectory_id; const int subscription_index; }; @@ -64,10 +78,13 @@ class MapBuilderContextInterface : public async_grpc::ExecutionContext { virtual mapping::TrajectoryBuilderInterface::LocalSlamResultCallback GetLocalSlamResultCallbackForSubscriptions() = 0; virtual void AddSensorDataToTrajectory(const Data& sensor_data) = 0; - virtual SubscriptionId SubscribeLocalSlamResults( + virtual LocalSlamSubscriptionId SubscribeLocalSlamResults( int trajectory_id, LocalSlamSubscriptionCallback callback) = 0; virtual void UnsubscribeLocalSlamResults( - const SubscriptionId& subscription_id) = 0; + const LocalSlamSubscriptionId& subscription_id) = 0; + virtual int SubscribeGlobalSlamOptimizations( + GlobalSlamOptimizationCallback callback) = 0; + virtual void UnsubscribeGlobalSlamOptimizations(int subscription_index) = 0; virtual void NotifyFinishTrajectory(int trajectory_id) = 0; virtual LocalTrajectoryUploaderInterface* local_trajectory_uploader() = 0; virtual void EnqueueSensorData(int trajectory_id, diff --git a/cartographer/cloud/internal/map_builder_server.cc b/cartographer/cloud/internal/map_builder_server.cc index 4eeec76..d135982 100644 --- a/cartographer/cloud/internal/map_builder_server.cc +++ b/cartographer/cloud/internal/map_builder_server.cc @@ -33,6 +33,7 @@ #include "cartographer/cloud/internal/handlers/is_trajectory_finished_handler.h" #include "cartographer/cloud/internal/handlers/is_trajectory_frozen_handler.h" #include "cartographer/cloud/internal/handlers/load_state_handler.h" +#include "cartographer/cloud/internal/handlers/receive_global_slam_optimizations_handler.h" #include "cartographer/cloud/internal/handlers/receive_local_slam_results_handler.h" #include "cartographer/cloud/internal/handlers/run_final_optimization_handler.h" #include "cartographer/cloud/internal/handlers/set_landmark_pose_handler.h" @@ -73,6 +74,8 @@ MapBuilderServer::MapBuilderServer( server_builder.RegisterHandler(); server_builder.RegisterHandler(); server_builder.RegisterHandler(); + server_builder + .RegisterHandler(); server_builder.RegisterHandler(); server_builder.RegisterHandler(); server_builder.RegisterHandler(); @@ -99,6 +102,9 @@ MapBuilderServer::MapBuilderServer( LOG(FATAL) << "Set either use_trajectory_builder_2d or use_trajectory_builder_3d"; } + map_builder_->pose_graph()->SetGlobalSlamOptimizationCallback( + std::bind(&MapBuilderServer::OnGlobalSlamOptimizations, this, + std::placeholders::_1, std::placeholders::_2)); } void MapBuilderServer::Start() { @@ -184,7 +190,7 @@ void MapBuilderServer::OnLocalSlamResult( ->EnqueueSensorData(std::move(sensor_data)); } - common::MutexLocker locker(&local_slam_subscriptions_lock_); + common::MutexLocker locker(&subscriptions_lock_); for (auto& entry : local_slam_subscriptions_[trajectory_id]) { auto copy_of_insertion_result = insertion_result @@ -194,34 +200,64 @@ void MapBuilderServer::OnLocalSlamResult( : nullptr; MapBuilderContextInterface::LocalSlamSubscriptionCallback callback = entry.second; - callback(common::make_unique( - MapBuilderContextInterface::LocalSlamResult{ - trajectory_id, time, local_pose, shared_range_data, - std::move(copy_of_insertion_result)})); + if (!callback( + common::make_unique( + MapBuilderContextInterface::LocalSlamResult{ + trajectory_id, time, local_pose, shared_range_data, + std::move(copy_of_insertion_result)}))) { + LOG(INFO) << "Removing subscription with index: " << entry.first; + CHECK_EQ(local_slam_subscriptions_[trajectory_id].erase(entry.first), 1u); + } } } -MapBuilderContextInterface::SubscriptionId +void MapBuilderServer::OnGlobalSlamOptimizations( + const std::map& last_optimized_submap_ids, + const std::map& last_optimized_node_ids) { + common::MutexLocker locker(&subscriptions_lock_); + for (auto& entry : global_slam_subscriptions_) { + if (!entry.second(last_optimized_submap_ids, last_optimized_node_ids)) { + LOG(INFO) << "Removing subscription with index: " << entry.first; + CHECK_EQ(global_slam_subscriptions_.erase(entry.first), 1u); + } + } +} + +MapBuilderContextInterface::LocalSlamSubscriptionId MapBuilderServer::SubscribeLocalSlamResults( int trajectory_id, MapBuilderContextInterface::LocalSlamSubscriptionCallback callback) { - common::MutexLocker locker(&local_slam_subscriptions_lock_); + common::MutexLocker locker(&subscriptions_lock_); local_slam_subscriptions_[trajectory_id].emplace(current_subscription_index_, callback); - return MapBuilderContextInterface::SubscriptionId{ + return MapBuilderContextInterface::LocalSlamSubscriptionId{ trajectory_id, current_subscription_index_++}; } void MapBuilderServer::UnsubscribeLocalSlamResults( - const MapBuilderContextInterface::SubscriptionId& subscription_id) { - common::MutexLocker locker(&local_slam_subscriptions_lock_); + const MapBuilderContextInterface::LocalSlamSubscriptionId& + subscription_id) { + common::MutexLocker locker(&subscriptions_lock_); CHECK_EQ(local_slam_subscriptions_[subscription_id.trajectory_id].erase( subscription_id.subscription_index), 1u); } +int MapBuilderServer::SubscribeGlobalSlamOptimizations( + MapBuilderContextInterface::GlobalSlamOptimizationCallback callback) { + common::MutexLocker locker(&subscriptions_lock_); + global_slam_subscriptions_.emplace(current_subscription_index_, callback); + return current_subscription_index_++; +} + +void MapBuilderServer::UnsubscribeGlobalSlamOptimizations( + int subscription_index) { + common::MutexLocker locker(&subscriptions_lock_); + CHECK_EQ(global_slam_subscriptions_.erase(subscription_index), 1u); +} + void MapBuilderServer::NotifyFinishTrajectory(int trajectory_id) { - common::MutexLocker locker(&local_slam_subscriptions_lock_); + common::MutexLocker locker(&subscriptions_lock_); for (auto& entry : local_slam_subscriptions_[trajectory_id]) { MapBuilderContextInterface::LocalSlamSubscriptionCallback callback = entry.second; diff --git a/cartographer/cloud/internal/map_builder_server.h b/cartographer/cloud/internal/map_builder_server.h index 2c403d3..761d9c5 100644 --- a/cartographer/cloud/internal/map_builder_server.h +++ b/cartographer/cloud/internal/map_builder_server.h @@ -49,10 +49,13 @@ class MapBuilderContext : public MapBuilderContextInterface { mapping::TrajectoryBuilderInterface::LocalSlamResultCallback GetLocalSlamResultCallbackForSubscriptions() override; void AddSensorDataToTrajectory(const Data& sensor_data) override; - MapBuilderContextInterface::SubscriptionId SubscribeLocalSlamResults( + MapBuilderContextInterface::LocalSlamSubscriptionId SubscribeLocalSlamResults( int trajectory_id, LocalSlamSubscriptionCallback callback) override; void UnsubscribeLocalSlamResults( - const SubscriptionId& subscription_id) override; + const LocalSlamSubscriptionId& subscription_id) override; + int SubscribeGlobalSlamOptimizations( + GlobalSlamOptimizationCallback callback) override; + void UnsubscribeGlobalSlamOptimizations(int subscription_index) override; void NotifyFinishTrajectory(int trajectory_id) override; LocalTrajectoryUploaderInterface* local_trajectory_uploader() override; void EnqueueSensorData(int trajectory_id, @@ -107,11 +110,18 @@ class MapBuilderServer : public MapBuilderServerInterface { std::unique_ptr< const mapping::TrajectoryBuilderInterface::InsertionResult> insertion_result); - MapBuilderContextInterface::SubscriptionId SubscribeLocalSlamResults( + void OnGlobalSlamOptimizations( + const std::map& last_optimized_submap_ids, + const std::map& last_optimized_node_ids); + MapBuilderContextInterface::LocalSlamSubscriptionId SubscribeLocalSlamResults( int trajectory_id, MapBuilderContextInterface::LocalSlamSubscriptionCallback callback); void UnsubscribeLocalSlamResults( - const MapBuilderContextInterface::SubscriptionId& subscription_id); + const MapBuilderContextInterface::LocalSlamSubscriptionId& + subscription_id); + int SubscribeGlobalSlamOptimizations( + MapBuilderContextInterface::GlobalSlamOptimizationCallback callback); + void UnsubscribeGlobalSlamOptimizations(int subscription_index); void NotifyFinishTrajectory(int trajectory_id); bool shutting_down_ = false; @@ -120,10 +130,13 @@ class MapBuilderServer : public MapBuilderServerInterface { std::unique_ptr map_builder_; common::BlockingQueue> incoming_data_queue_; - common::Mutex local_slam_subscriptions_lock_; + common::Mutex subscriptions_lock_; int current_subscription_index_ = 0; std::map - local_slam_subscriptions_ GUARDED_BY(local_slam_subscriptions_lock_); + local_slam_subscriptions_ GUARDED_BY(subscriptions_lock_); + std::map + global_slam_subscriptions_ GUARDED_BY(subscriptions_lock_); std::unique_ptr local_trajectory_uploader_; int starting_submap_index_ = 0; }; diff --git a/cartographer/cloud/internal/testing/mock_map_builder_context.h b/cartographer/cloud/internal/testing/mock_map_builder_context.h index ff8b0f3..f9ba0e8 100644 --- a/cartographer/cloud/internal/testing/mock_map_builder_context.h +++ b/cartographer/cloud/internal/testing/mock_map_builder_context.h @@ -39,11 +39,15 @@ class MockMapBuilderContext : public MapBuilderContextInterface { MOCK_METHOD1(AddSensorDataToTrajectory, void(const MapBuilderContextInterface::Data &)); MOCK_METHOD2(SubscribeLocalSlamResults, - MapBuilderContextInterface::SubscriptionId( + MapBuilderContextInterface::LocalSlamSubscriptionId( int, MapBuilderContextInterface::LocalSlamSubscriptionCallback)); - MOCK_METHOD1(UnsubscribeLocalSlamResults, - void(const MapBuilderContextInterface::SubscriptionId &)); + MOCK_METHOD1( + UnsubscribeLocalSlamResults, + void(const MapBuilderContextInterface::LocalSlamSubscriptionId &)); + MOCK_METHOD1(SubscribeGlobalSlamOptimizations, + int(GlobalSlamOptimizationCallback)); + MOCK_METHOD1(UnsubscribeGlobalSlamOptimizations, void(int)); MOCK_METHOD1(NotifyFinishTrajectory, void(int)); MOCK_METHOD0(local_trajectory_uploader, LocalTrajectoryUploaderInterface *()); diff --git a/cartographer/cloud/proto/map_builder_service.proto b/cartographer/cloud/proto/map_builder_service.proto index e5a2d17..b3e88d7 100644 --- a/cartographer/cloud/proto/map_builder_service.proto +++ b/cartographer/cloud/proto/map_builder_service.proto @@ -114,6 +114,13 @@ message ReceiveLocalSlamResultsResponse { LocalSlamInsertionResult insertion_result = 5; } +message ReceiveGlobalSlamOptimizationsResponse { + map + last_optimized_node_ids = 1; + map + last_optimized_submap_ids = 2; +} + message GetSubmapRequest { cartographer.mapping.proto.SubmapId submap_id = 1; } @@ -230,6 +237,10 @@ service MapBuilderService { rpc ReceiveLocalSlamResults(ReceiveLocalSlamResultsRequest) returns (stream ReceiveLocalSlamResultsResponse); + // Requests the server to send a stream of global SLAM notifications. + rpc ReceiveGlobalSlamOptimizations(google.protobuf.Empty) + returns (stream ReceiveGlobalSlamOptimizationsResponse); + // Marks a trajectory corresponding to 'trajectory_id' as finished, // i.e. no further sensor data is expected. rpc FinishTrajectory(FinishTrajectoryRequest) returns (google.protobuf.Empty);