17 #include <condition_variable> 28 #include "glog/logging.h" 29 #include "gmock/gmock.h" 30 #include "gtest/gtest.h" 32 using ::cartographer::mapping::MapBuilder;
33 using ::cartographer::mapping::MapBuilderInterface;
34 using ::cartographer::mapping::PoseGraphInterface;
35 using ::cartographer::mapping::TrajectoryBuilderInterface;
36 using ::cartographer::mapping::testing::MockMapBuilder;
37 using ::cartographer::mapping::testing::MockPoseGraph;
38 using ::cartographer::mapping::testing::MockTrajectoryBuilder;
48 constexpr
double kDuration = 4.;
49 constexpr
double kTimeStep = 0.1;
50 constexpr
double kTravelDistance = 1.2;
52 class ClientServerTest :
public ::testing::Test {
54 void SetUp()
override {
57 const std::string kMapBuilderServerLua = R
"text( 58 include "map_builder_server.lua" 59 MAP_BUILDER.use_trajectory_builder_2d = true 60 MAP_BUILDER.pose_graph.optimize_every_n_nodes = 0 61 MAP_BUILDER_SERVER.num_event_threads = 1 62 MAP_BUILDER_SERVER.num_grpc_threads = 1 63 MAP_BUILDER_SERVER.uplink_server_address = "" 64 MAP_BUILDER_SERVER.server_address = "0.0.0.0:50051" 65 return MAP_BUILDER_SERVER)text"; 66 auto map_builder_server_parameters =
71 const std::string kUploadingMapBuilderServerLua = R
"text( 72 include "map_builder_server.lua" 73 MAP_BUILDER.use_trajectory_builder_2d = true 74 MAP_BUILDER.pose_graph.optimize_every_n_nodes = 0 75 MAP_BUILDER_SERVER.num_event_threads = 1 76 MAP_BUILDER_SERVER.num_grpc_threads = 1 77 MAP_BUILDER_SERVER.uplink_server_address = "localhost:50051" 78 MAP_BUILDER_SERVER.server_address = "0.0.0.0:50052" 79 MAP_BUILDER_SERVER.upload_batch_size = 1 80 return MAP_BUILDER_SERVER)text"; 81 auto uploading_map_builder_server_parameters =
84 uploading_map_builder_server_parameters.get());
86 const std::string kTrajectoryBuilderLua = R
"text( 87 include "trajectory_builder.lua" 88 TRAJECTORY_BUILDER.trajectory_builder_2d.use_imu_data = false 89 TRAJECTORY_BUILDER.trajectory_builder_2d.submaps.num_range_data = 4 90 return TRAJECTORY_BUILDER)text"; 91 auto trajectory_builder_parameters =
94 trajectory_builder_parameters.get());
100 const mapping::TrajectoryBuilderInterface::InsertionResult>
103 if (insertion_result) {
112 void InitializeRealServer() {
113 auto map_builder = common::make_unique<MapBuilder>(
116 std::move(map_builder));
117 EXPECT_TRUE(server_ !=
nullptr);
120 void InitializeRealUploadingServer() {
121 auto map_builder = common::make_unique<MapBuilder>(
125 EXPECT_TRUE(uploading_server_ !=
nullptr);
128 void InitializeServerWithMockMapBuilder() {
129 auto mock_map_builder = common::make_unique<MockMapBuilder>();
132 EXPECT_CALL(*mock_map_builder_, pose_graph())
135 server_ = common::make_unique<MapBuilderServer>(
137 EXPECT_TRUE(
server_ !=
nullptr);
141 void InitializeStub() {
142 stub_ = common::make_unique<MapBuilderStub>(
144 EXPECT_TRUE(
stub_ !=
nullptr);
147 void InitializeStubForUploadingServer() {
153 void WaitForLocalSlamResults(
size_t size) {
159 void WaitForLocalSlamResultUploads(
size_t size) {
162 return stub_->pose_graph()->GetTrajectoryNodePoses().size() >= size;
171 ::cartographer::mapping::proto::TrajectoryBuilderOptions
175 std::unique_ptr<MapBuilderStub>
stub_;
177 TrajectoryBuilderInterface::LocalSlamResultCallback
187 TEST_F(ClientServerTest, StartAndStopServer) {
188 InitializeRealServer();
193 TEST_F(ClientServerTest, AddTrajectoryBuilder) {
194 InitializeRealServer();
197 int trajectory_id =
stub_->AddTrajectoryBuilder(
199 EXPECT_FALSE(
stub_->pose_graph()->IsTrajectoryFinished(trajectory_id));
200 stub_->FinishTrajectory(trajectory_id);
201 EXPECT_TRUE(
stub_->pose_graph()->IsTrajectoryFinished(trajectory_id));
202 EXPECT_FALSE(
stub_->pose_graph()->IsTrajectoryFrozen(trajectory_id));
206 TEST_F(ClientServerTest, AddTrajectoryBuilderWithMock) {
207 InitializeServerWithMockMapBuilder();
210 std::set<SensorId> expected_sensor_ids = {kImuSensorId};
213 AddTrajectoryBuilder(::testing::ContainerEq(expected_sensor_ids), _, _))
214 .WillOnce(::testing::Return(3));
216 .WillRepeatedly(::testing::Return(
nullptr));
217 int trajectory_id =
stub_->AddTrajectoryBuilder(
219 EXPECT_EQ(trajectory_id, 3);
221 stub_->FinishTrajectory(trajectory_id);
225 TEST_F(ClientServerTest, AddSensorData) {
227 ->set_use_imu_data(
true);
228 InitializeRealServer();
231 int trajectory_id =
stub_->AddTrajectoryBuilder(
233 TrajectoryBuilderInterface* trajectory_stub =
234 stub_->GetTrajectoryBuilder(trajectory_id);
236 Eigen::Vector3d(0., 0., 9.8),
237 Eigen::Vector3d::Zero()};
238 trajectory_stub->AddSensorData(kImuSensorId.id, imu_data);
239 stub_->FinishTrajectory(trajectory_id);
243 TEST_F(ClientServerTest, AddSensorDataWithMock) {
244 InitializeServerWithMockMapBuilder();
247 std::set<SensorId> expected_sensor_ids = {kImuSensorId};
250 AddTrajectoryBuilder(::testing::ContainerEq(expected_sensor_ids), _, _))
251 .WillOnce(::testing::Return(3));
252 int trajectory_id =
stub_->AddTrajectoryBuilder(
254 EXPECT_EQ(trajectory_id, 3);
257 mapping::TrajectoryBuilderInterface* trajectory_stub =
258 stub_->GetTrajectoryBuilder(trajectory_id);
260 Eigen::Vector3d(0., 0., 9.8),
261 Eigen::Vector3d::Zero()};
263 AddSensorData(::testing::StrEq(kImuSensorId.id),
264 ::testing::Matcher<const sensor::ImuData&>(_)))
265 .WillOnce(::testing::Return());
266 trajectory_stub->AddSensorData(kImuSensorId.id, imu_data);
268 stub_->FinishTrajectory(trajectory_id);
272 TEST_F(ClientServerTest, LocalSlam2D) {
273 InitializeRealServer();
279 TrajectoryBuilderInterface* trajectory_stub =
280 stub_->GetTrajectoryBuilder(trajectory_id);
282 kTravelDistance, kDuration, kTimeStep);
283 for (
const auto& measurement : measurements) {
284 trajectory_stub->AddSensorData(kRangeSensorId.id, measurement);
286 WaitForLocalSlamResults(measurements.size());
287 stub_->FinishTrajectory(trajectory_id);
289 EXPECT_NEAR(kTravelDistance,
293 0.1 * kTravelDistance);
297 TEST_F(ClientServerTest, GlobalSlam3D) {
299 ->set_use_trajectory_builder_2d(
false);
301 ->set_use_trajectory_builder_3d(
true);
303 ->mutable_pose_graph_options()
304 ->set_optimize_every_n_nodes(3);
306 ->mutable_motion_filter_options()
307 ->set_max_distance_meters(0);
309 ->mutable_motion_filter_options()
310 ->set_max_angle_radians(0);
311 InitializeRealServer();
314 int trajectory_id =
stub_->AddTrajectoryBuilder(
317 TrajectoryBuilderInterface* trajectory_stub =
318 stub_->GetTrajectoryBuilder(trajectory_id);
320 kTravelDistance, kDuration, kTimeStep);
321 for (
const auto& measurement : measurements) {
322 sensor::ImuData imu_data{
324 Eigen::Vector3d(0., 0., 9.8), Eigen::Vector3d::Zero()};
325 trajectory_stub->AddSensorData(kImuSensorId.id, imu_data);
326 trajectory_stub->AddSensorData(kRangeSensorId.id, measurement);
330 WaitForLocalSlamResults(measurements.size() - 1);
331 stub_->FinishTrajectory(trajectory_id);
332 EXPECT_NEAR(kTravelDistance,
336 0.1 * kTravelDistance);
340 TEST_F(ClientServerTest, StartAndStopUploadingServerAndServer) {
341 InitializeRealServer();
343 InitializeRealUploadingServer();
349 TEST_F(ClientServerTest, AddTrajectoryBuilderWithUploadingServer) {
350 InitializeRealServer();
352 InitializeRealUploadingServer();
355 InitializeStubForUploadingServer();
360 EXPECT_FALSE(
stub_->pose_graph()->IsTrajectoryFinished(trajectory_id));
364 EXPECT_TRUE(
stub_->pose_graph()->IsTrajectoryFinished(trajectory_id));
367 EXPECT_FALSE(
stub_->pose_graph()->IsTrajectoryFrozen(trajectory_id));
372 TEST_F(ClientServerTest, LocalSlam2DWithUploadingServer) {
373 InitializeRealServer();
376 InitializeRealUploadingServer();
378 InitializeStubForUploadingServer();
382 TrajectoryBuilderInterface* trajectory_stub =
385 kTravelDistance, kDuration, kTimeStep);
386 for (
const auto& measurement : measurements) {
387 trajectory_stub->AddSensorData(kRangeSensorId.id, measurement);
389 WaitForLocalSlamResults(measurements.size());
393 EXPECT_NEAR(kTravelDistance,
397 0.1 * kTravelDistance);
std::condition_variable local_slam_result_upload_condition_
std::vector< cartographer::sensor::TimedPointCloudData > GenerateFakeRangeMeasurements(double travel_distance, double duration, double time_step)
int number_of_insertion_results_
std::vector< transform::Rigid3d > local_slam_result_poses_
std::mutex local_slam_result_upload_mutex_
::cartographer::mapping::proto::TrajectoryBuilderOptions trajectory_builder_options_
UniversalTimeScaleClock::time_point Time
std::mutex local_slam_result_mutex_
Time FromUniversal(const int64 ticks)
std::unique_ptr< MockPoseGraph > mock_pose_graph_
Duration FromSeconds(const double seconds)
proto::MapBuilderServerOptions uploading_map_builder_server_options_
std::unique_ptr< MockTrajectoryBuilder > mock_trajectory_builder_
TrajectoryBuilderInterface::LocalSlamResultCallback local_slam_result_callback_
proto::TrajectoryBuilderOptions CreateTrajectoryBuilderOptions(common::LuaParameterDictionary *const parameter_dictionary)
std::unique_ptr< MapBuilderServer > server_
std::unique_ptr< MapBuilderServer > uploading_server_
std::condition_variable local_slam_result_condition_
proto::MapBuilderServerOptions CreateMapBuilderServerOptions(common::LuaParameterDictionary *lua_parameter_dictionary)
MockMapBuilder * mock_map_builder_
std::unique_ptr<::cartographer::common::LuaParameterDictionary > ResolveLuaParameters(const std::string &lua_code)
::cartographer::mapping::TrajectoryBuilderInterface::SensorId SensorId
std::unique_ptr< MapBuilderStub > stub_for_uploading_server_
proto::MapBuilderServerOptions map_builder_server_options_
std::unique_ptr< MapBuilderStub > stub_