00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "cartographer/mapping/id.h"
00018
00019 #include <algorithm>
00020 #include <deque>
00021 #include <iterator>
00022 #include <random>
00023 #include <utility>
00024
00025 #include "cartographer/common/time.h"
00026 #include "gtest/gtest.h"
00027
00028 namespace cartographer {
00029 namespace mapping {
00030 namespace {
00031
00032 common::Time CreateTime(const int milliseconds) {
00033 return common::Time(common::FromMilliseconds(milliseconds));
00034 }
00035
00036 class Data {
00037 public:
00038 explicit Data(int milliseconds) : time_(CreateTime(milliseconds)) {}
00039
00040 const common::Time& time() const { return time_; }
00041
00042 private:
00043 const common::Time time_;
00044 };
00045
00046 template <typename IdType>
00047 static MapById<IdType, int> CreateTestMapById() {
00048 MapById<IdType, int> map_by_id;
00049 map_by_id.Append(7, 2);
00050 map_by_id.Append(42, 3);
00051 map_by_id.Append(0, 0);
00052 map_by_id.Append(0, 1);
00053 return map_by_id;
00054 }
00055
00056 TEST(IdTest, EmptyMapById) {
00057 MapById<NodeId, int> map_by_id;
00058 EXPECT_TRUE(map_by_id.empty());
00059 EXPECT_EQ(map_by_id.trajectory_ids().begin(),
00060 map_by_id.trajectory_ids().end());
00061 int unknown_trajectory_id = 3;
00062 EXPECT_EQ(map_by_id.trajectory(unknown_trajectory_id).begin(),
00063 map_by_id.trajectory(unknown_trajectory_id).end());
00064 const NodeId id = map_by_id.Append(42, 42);
00065 EXPECT_FALSE(map_by_id.empty());
00066 map_by_id.Trim(id);
00067 EXPECT_TRUE(map_by_id.empty());
00068 EXPECT_EQ(0, map_by_id.size());
00069 }
00070
00071 TEST(IdTest, DeleteTrajectory) {
00072 MapById<NodeId, int> map_by_id;
00073 int trajectory_id = 3;
00074 int other_trajectory_id = 5;
00075 map_by_id.Insert(NodeId{trajectory_id, 4}, 5);
00076 map_by_id.Insert(NodeId{trajectory_id, 5}, 7);
00077 map_by_id.Insert(NodeId{other_trajectory_id, 1}, 3);
00078 EXPECT_EQ(map_by_id.size(), 3);
00079 EXPECT_EQ(2, std::distance(map_by_id.trajectory_ids().begin(),
00080 map_by_id.trajectory_ids().end()));
00081 map_by_id.Trim(NodeId{trajectory_id, 4});
00082 map_by_id.Trim(NodeId{trajectory_id, 5});
00083 EXPECT_EQ(0, std::distance(map_by_id.trajectory(trajectory_id).begin(),
00084 map_by_id.trajectory(trajectory_id).end()));
00085 int invalid_trajectory_id = 2;
00086 EXPECT_EQ(map_by_id.trajectory(invalid_trajectory_id).begin(),
00087 map_by_id.trajectory(invalid_trajectory_id).end());
00088 EXPECT_EQ(map_by_id.size(), 1);
00089 EXPECT_EQ(1, std::distance(map_by_id.trajectory(other_trajectory_id).begin(),
00090 map_by_id.trajectory(other_trajectory_id).end()));
00091 EXPECT_EQ(1, std::distance(map_by_id.trajectory_ids().begin(),
00092 map_by_id.trajectory_ids().end()));
00093 EXPECT_FALSE(map_by_id.empty());
00094 }
00095
00096 TEST(IdTest, MapByIdIterator) {
00097 MapById<NodeId, int> map_by_id = CreateTestMapById<NodeId>();
00098 EXPECT_EQ(4, map_by_id.size());
00099 EXPECT_EQ(2, map_by_id.BeginOfTrajectory(7)->data);
00100 EXPECT_TRUE(std::next(map_by_id.BeginOfTrajectory(7)) ==
00101 map_by_id.EndOfTrajectory(7));
00102 std::deque<std::pair<NodeId, int>> expected_id_data = {
00103 {NodeId{0, 0}, 0},
00104 {NodeId{0, 1}, 1},
00105 {NodeId{7, 0}, 2},
00106 {NodeId{42, 0}, 3},
00107 };
00108 for (const auto& id_data : map_by_id) {
00109 ASSERT_FALSE(expected_id_data.empty());
00110 EXPECT_EQ(expected_id_data.front().first, id_data.id);
00111 EXPECT_EQ(expected_id_data.front().second, id_data.data);
00112 expected_id_data.pop_front();
00113 }
00114 EXPECT_TRUE(expected_id_data.empty());
00115 }
00116
00117 TEST(IdTest, MapByIdTrajectoryRange) {
00118 MapById<NodeId, int> map_by_id = CreateTestMapById<NodeId>();
00119 std::deque<std::pair<NodeId, int>> expected_data = {
00120 {NodeId{0, 0}, 0},
00121 {NodeId{0, 1}, 1},
00122 };
00123 for (const auto& entry : map_by_id.trajectory(0)) {
00124 ASSERT_FALSE(expected_data.empty());
00125 EXPECT_EQ(expected_data.front().first, entry.id);
00126 EXPECT_EQ(expected_data.front().second, entry.data);
00127 expected_data.pop_front();
00128 }
00129 EXPECT_TRUE(expected_data.empty());
00130 }
00131
00132 TEST(IdTest, MapByIdTrajectoryIdRange) {
00133 MapById<NodeId, int> map_by_id = CreateTestMapById<NodeId>();
00134 std::deque<int> expected_data = {0, 7, 42};
00135 for (const int trajectory_id : map_by_id.trajectory_ids()) {
00136 ASSERT_FALSE(expected_data.empty());
00137 EXPECT_EQ(expected_data.front(), trajectory_id);
00138 expected_data.pop_front();
00139 }
00140 EXPECT_TRUE(expected_data.empty());
00141 }
00142
00143 TEST(IdTest, MapByIdIterateByTrajectories) {
00144 MapById<NodeId, int> map_by_id = CreateTestMapById<NodeId>();
00145 std::deque<std::pair<NodeId, int>> expected_id_data = {
00146 {NodeId{0, 0}, 0},
00147 {NodeId{0, 1}, 1},
00148 {NodeId{7, 0}, 2},
00149 {NodeId{42, 0}, 3},
00150 };
00151 for (int trajectory_id : map_by_id.trajectory_ids()) {
00152 for (const auto& entry : map_by_id.trajectory(trajectory_id)) {
00153 ASSERT_FALSE(expected_id_data.empty());
00154 EXPECT_EQ(expected_id_data.front().first, entry.id);
00155 EXPECT_EQ(expected_id_data.front().second, entry.data);
00156 expected_id_data.pop_front();
00157 }
00158 }
00159 EXPECT_TRUE(expected_id_data.empty());
00160 }
00161
00162 TEST(IdTest, MapByIdPrevIterator) {
00163 MapById<NodeId, int> map_by_id;
00164 map_by_id.Append(42, 42);
00165 auto it = map_by_id.end();
00166 ASSERT_TRUE(it != map_by_id.begin());
00167 std::advance(it, -1);
00168 EXPECT_TRUE(it == map_by_id.begin());
00169 }
00170
00171 TEST(IdTest, InsertIntoMapById) {
00172 MapById<NodeId, int> map_by_id;
00173 EXPECT_EQ(0, map_by_id.SizeOfTrajectoryOrZero(42));
00174 map_by_id.Append(42, 42);
00175 map_by_id.Insert(NodeId{42, 5}, 42);
00176 EXPECT_EQ(2, map_by_id.SizeOfTrajectoryOrZero(42));
00177 }
00178
00179 TEST(IdTest, FindNodeId) {
00180 MapById<NodeId, int> map_by_id;
00181 map_by_id.Append(42, 42);
00182 map_by_id.Append(42, 43);
00183 map_by_id.Append(42, 44);
00184 CHECK_EQ(map_by_id.find(NodeId{42, 1})->data, 43);
00185 EXPECT_TRUE(map_by_id.find(NodeId{41, 0}) == map_by_id.end());
00186 EXPECT_TRUE(map_by_id.find(NodeId{42, 3}) == map_by_id.end());
00187 }
00188
00189 TEST(IdTest, FindSubmapId) {
00190 MapById<SubmapId, int> map_by_id;
00191 map_by_id.Append(42, 42);
00192 map_by_id.Append(42, 43);
00193 map_by_id.Append(42, 44);
00194 CHECK_EQ(map_by_id.find(SubmapId{42, 1})->data, 43);
00195 EXPECT_TRUE(map_by_id.find(SubmapId{42, 3}) == map_by_id.end());
00196 }
00197
00198 TEST(IdTest, LowerBoundEdgeCases) {
00199 MapById<SubmapId, Data> map_by_id;
00200 map_by_id.Append(0, Data(1));
00201 map_by_id.Append(2, Data(2));
00202 CHECK(map_by_id.lower_bound(1, CreateTime(10)) ==
00203 map_by_id.EndOfTrajectory(1));
00204 CHECK(map_by_id.lower_bound(2, CreateTime(3)) ==
00205 map_by_id.EndOfTrajectory(2));
00206 CHECK(map_by_id.lower_bound(2, CreateTime(1)) ==
00207 map_by_id.BeginOfTrajectory(2));
00208 }
00209
00210 TEST(IdTest, LowerBound) {
00211 MapById<SubmapId, Data> map_by_id;
00212 map_by_id.Append(0, Data(1));
00213 map_by_id.Append(0, Data(2));
00214 map_by_id.Append(0, Data(4));
00215 map_by_id.Append(0, Data(5));
00216 CHECK(map_by_id.lower_bound(0, CreateTime(3)) ==
00217 (MapById<SubmapId, Data>::ConstIterator(map_by_id, SubmapId{0, 2})));
00218 CHECK(map_by_id.lower_bound(0, CreateTime(2)) ==
00219 (MapById<SubmapId, Data>::ConstIterator(map_by_id, SubmapId{0, 1})));
00220 CHECK(map_by_id.lower_bound(0, CreateTime(4)) ==
00221 (MapById<SubmapId, Data>::ConstIterator(map_by_id, SubmapId{0, 2})));
00222 }
00223
00224 TEST(IdTest, LowerBoundFuzz) {
00225 constexpr int kMaxTimeIncrement = 20;
00226 constexpr int kMaxNumNodes = 20;
00227 constexpr int kNumTests = 100;
00228 constexpr int kTrajectoryId = 1;
00229
00230 std::mt19937 rng;
00231 std::uniform_int_distribution<int> dt_dist(1, kMaxTimeIncrement);
00232 std::uniform_int_distribution<int> N_dist(1, kMaxNumNodes);
00233
00234 for (int i = 0; i < kNumTests; ++i) {
00235 const int N = N_dist(rng);
00236 int t = 0;
00237 MapById<SubmapId, Data> map_by_id;
00238 for (int j = 0; j < N; ++j) {
00239 t = t + dt_dist(rng);
00240 map_by_id.Append(kTrajectoryId, Data(t));
00241 }
00242 std::uniform_int_distribution<int> t0_dist(1, N * kMaxTimeIncrement + 1);
00243 int t0 = t0_dist(rng);
00244 auto it = map_by_id.lower_bound(kTrajectoryId, CreateTime(t0));
00245
00246 auto ground_truth = std::lower_bound(
00247 map_by_id.BeginOfTrajectory(kTrajectoryId),
00248 map_by_id.EndOfTrajectory(kTrajectoryId), CreateTime(t0),
00249 [](MapById<SubmapId, Data>::IdDataReference a, const common::Time& t) {
00250 return a.data.time() < t;
00251 });
00252
00253 CHECK(ground_truth == it);
00254 }
00255 }
00256
00257 struct DataStruct {
00258 const common::Time time;
00259 };
00260
00261 TEST(IdTest, LowerBoundFuzzWithStruct) {
00262 constexpr int kMaxTimeIncrement = 20;
00263 constexpr int kMaxNumNodes = 20;
00264 constexpr int kNumTests = 100;
00265 constexpr int kTrajectoryId = 1;
00266
00267 std::mt19937 rng;
00268 std::uniform_int_distribution<int> dt_dist(1, kMaxTimeIncrement);
00269 std::uniform_int_distribution<int> N_dist(1, kMaxNumNodes);
00270
00271 for (int i = 0; i < kNumTests; ++i) {
00272 const int N = N_dist(rng);
00273 int t = 0;
00274 MapById<SubmapId, DataStruct> map_by_id;
00275 for (int j = 0; j < N; ++j) {
00276 t = t + dt_dist(rng);
00277 map_by_id.Append(kTrajectoryId, DataStruct{CreateTime(t)});
00278 }
00279 std::uniform_int_distribution<int> t0_dist(1, N * kMaxTimeIncrement + 1);
00280 int t0 = t0_dist(rng);
00281 auto it = map_by_id.lower_bound(kTrajectoryId, CreateTime(t0));
00282
00283 auto ground_truth = std::lower_bound(
00284 map_by_id.BeginOfTrajectory(kTrajectoryId),
00285 map_by_id.EndOfTrajectory(kTrajectoryId), CreateTime(t0),
00286 [](MapById<SubmapId, DataStruct>::IdDataReference a,
00287 const common::Time& t) { return a.data.time < t; });
00288
00289 CHECK(ground_truth == it);
00290 }
00291 }
00292 }
00293 }
00294 }