msg_conversion_test.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2016 The Cartographer Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cmath>
18 #include <random>
19 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "sensor_msgs/LaserScan.h"
26 
27 namespace cartographer_ros {
28 namespace {
29 
30 using ::cartographer::sensor::LandmarkData;
31 using ::cartographer::sensor::LandmarkObservation;
32 using ::testing::AllOf;
33 using ::testing::DoubleNear;
34 using ::testing::ElementsAre;
35 using ::testing::Field;
36 
37 constexpr double kEps = 1e-6;
38 
39 TEST(MsgConversion, LaserScanToPointCloud) {
40  sensor_msgs::LaserScan laser_scan;
41  for (int i = 0; i < 8; ++i) {
42  laser_scan.ranges.push_back(1.f);
43  }
44  laser_scan.angle_min = 0.f;
45  laser_scan.angle_max = 8.f * static_cast<float>(M_PI_4);
46  laser_scan.angle_increment = static_cast<float>(M_PI_4);
47  laser_scan.range_min = 0.f;
48  laser_scan.range_max = 10.f;
49 
50  const auto point_cloud =
51  std::get<0>(ToPointCloudWithIntensities(laser_scan)).points;
52  EXPECT_TRUE(
53  point_cloud[0].isApprox(Eigen::Vector4f(1.f, 0.f, 0.f, 0.f), kEps));
54  EXPECT_TRUE(point_cloud[1].isApprox(
55  Eigen::Vector4f(1.f / std::sqrt(2.f), 1.f / std::sqrt(2.f), 0.f, 0.f),
56  kEps));
57  EXPECT_TRUE(
58  point_cloud[2].isApprox(Eigen::Vector4f(0.f, 1.f, 0.f, 0.f), kEps));
59  EXPECT_TRUE(point_cloud[3].isApprox(
60  Eigen::Vector4f(-1.f / std::sqrt(2.f), 1.f / std::sqrt(2.f), 0.f, 0.f),
61  kEps));
62  EXPECT_TRUE(
63  point_cloud[4].isApprox(Eigen::Vector4f(-1.f, 0.f, 0.f, 0.f), kEps));
64  EXPECT_TRUE(point_cloud[5].isApprox(
65  Eigen::Vector4f(-1.f / std::sqrt(2.f), -1.f / std::sqrt(2.f), 0.f, 0.f),
66  kEps));
67  EXPECT_TRUE(
68  point_cloud[6].isApprox(Eigen::Vector4f(0.f, -1.f, 0.f, 0.f), kEps));
69  EXPECT_TRUE(point_cloud[7].isApprox(
70  Eigen::Vector4f(1.f / std::sqrt(2.f), -1.f / std::sqrt(2.f), 0.f, 0.f),
71  kEps));
72 }
73 
74 TEST(MsgConversion, LaserScanToPointCloudWithInfinityAndNaN) {
75  sensor_msgs::LaserScan laser_scan;
76  laser_scan.ranges.push_back(1.f);
77  laser_scan.ranges.push_back(std::numeric_limits<float>::infinity());
78  laser_scan.ranges.push_back(2.f);
79  laser_scan.ranges.push_back(std::numeric_limits<float>::quiet_NaN());
80  laser_scan.ranges.push_back(3.f);
81  laser_scan.angle_min = 0.f;
82  laser_scan.angle_max = 3.f * static_cast<float>(M_PI_4);
83  laser_scan.angle_increment = static_cast<float>(M_PI_4);
84  laser_scan.range_min = 2.f;
85  laser_scan.range_max = 10.f;
86 
87  const auto point_cloud =
88  std::get<0>(ToPointCloudWithIntensities(laser_scan)).points;
89  ASSERT_EQ(2, point_cloud.size());
90  EXPECT_TRUE(
91  point_cloud[0].isApprox(Eigen::Vector4f(0.f, 2.f, 0.f, 0.f), kEps));
92  EXPECT_TRUE(
93  point_cloud[1].isApprox(Eigen::Vector4f(-3.f, 0.f, 0.f, 0.f), kEps));
94 }
95 
96 ::testing::Matcher<const LandmarkObservation&> EqualsLandmark(
97  const LandmarkObservation& expected) {
98  return ::testing::AllOf(
99  Field(&LandmarkObservation::id, expected.id),
100  Field(&LandmarkObservation::landmark_to_tracking_transform,
101  ::cartographer::transform::IsNearly(
102  expected.landmark_to_tracking_transform, kEps)),
103  Field(&LandmarkObservation::translation_weight,
104  DoubleNear(expected.translation_weight, kEps)),
105  Field(&LandmarkObservation::rotation_weight,
106  DoubleNear(expected.rotation_weight, kEps)));
107 }
108 
109 TEST(MsgConversion, LandmarkListToLandmarkData) {
110  cartographer_ros_msgs::LandmarkList message;
111  message.header.stamp.fromSec(10);
112 
113  cartographer_ros_msgs::LandmarkEntry landmark_0;
114  landmark_0.id = "landmark_0";
115  landmark_0.tracking_from_landmark_transform.position.x = 1.0;
116  landmark_0.tracking_from_landmark_transform.position.y = 2.0;
117  landmark_0.tracking_from_landmark_transform.position.z = 3.0;
118  landmark_0.tracking_from_landmark_transform.orientation.w = 1.0;
119  landmark_0.tracking_from_landmark_transform.orientation.x = 0.0;
120  landmark_0.tracking_from_landmark_transform.orientation.y = 0.0;
121  landmark_0.tracking_from_landmark_transform.orientation.z = 0.0;
122  landmark_0.translation_weight = 1.0;
123  landmark_0.rotation_weight = 2.0;
124  message.landmark.push_back(landmark_0);
125 
126  LandmarkData actual_landmark_data = ToLandmarkData(message);
127  EXPECT_THAT(actual_landmark_data,
128  AllOf(Field(&LandmarkData::time, FromRos(message.header.stamp)),
129  Field(&LandmarkData::landmark_observations,
130  ElementsAre(EqualsLandmark(LandmarkObservation{
131  "landmark_0",
133  Eigen::Vector3d(1., 2., 3.),
134  Eigen::Quaterniond(1., 0., 0., 0.)),
135  1.f,
136  2.f,
137  })))));
138 }
139 
140 TEST(MsgConversion, LatLongAltToEcef) {
141  Eigen::Vector3d equator_prime_meridian = LatLongAltToEcef(0, 0, 0);
142  EXPECT_TRUE(equator_prime_meridian.isApprox(Eigen::Vector3d(6378137, 0, 0)))
143  << equator_prime_meridian;
144  Eigen::Vector3d plus_ten_meters = LatLongAltToEcef(0, 0, 10);
145  EXPECT_TRUE(plus_ten_meters.isApprox(Eigen::Vector3d(6378147, 0, 0)))
146  << plus_ten_meters;
147  Eigen::Vector3d north_pole = LatLongAltToEcef(90, 0, 0);
148  EXPECT_TRUE(north_pole.isApprox(Eigen::Vector3d(0, 0, 6356752.3142), kEps))
149  << north_pole;
150  Eigen::Vector3d also_north_pole = LatLongAltToEcef(90, 90, 0);
151  EXPECT_TRUE(
152  also_north_pole.isApprox(Eigen::Vector3d(0, 0, 6356752.3142), kEps))
153  << also_north_pole;
154  Eigen::Vector3d south_pole = LatLongAltToEcef(-90, 0, 0);
155  EXPECT_TRUE(south_pole.isApprox(Eigen::Vector3d(0, 0, -6356752.3142), kEps))
156  << south_pole;
157  Eigen::Vector3d above_south_pole = LatLongAltToEcef(-90, 60, 20);
158  EXPECT_TRUE(
159  above_south_pole.isApprox(Eigen::Vector3d(0, 0, -6356772.3142), kEps))
160  << above_south_pole;
161  Eigen::Vector3d somewhere_on_earth =
162  LatLongAltToEcef(48.1372149, 11.5748024, 517.1);
163  EXPECT_TRUE(somewhere_on_earth.isApprox(
164  Eigen::Vector3d(4177983, 855702, 4727457), kEps))
165  << somewhere_on_earth;
166 }
167 
168 TEST(MsgConversion, ComputeLocalFrameFromLatLong) {
171  EXPECT_TRUE((north_pole * LatLongAltToEcef(90., 0., 1.))
172  .isApprox(Eigen::Vector3d::UnitZ()));
175  EXPECT_TRUE((south_pole * LatLongAltToEcef(-90., 0., 1.))
176  .isApprox(Eigen::Vector3d::UnitZ()));
177  cartographer::transform::Rigid3d prime_meridian_equator =
179  EXPECT_TRUE((prime_meridian_equator * LatLongAltToEcef(0., 0., 1.))
180  .isApprox(Eigen::Vector3d::UnitZ()))
181  << prime_meridian_equator * LatLongAltToEcef(0., 0., 1.);
182  cartographer::transform::Rigid3d meridian_90_equator =
184  EXPECT_TRUE((meridian_90_equator * LatLongAltToEcef(0., 90., 1.))
185  .isApprox(Eigen::Vector3d::UnitZ()))
186  << meridian_90_equator * LatLongAltToEcef(0., 90., 1.);
187 
188  std::mt19937 rng(42);
189  std::uniform_real_distribution<double> lat_distribution(-90., 90.);
190  std::uniform_real_distribution<double> long_distribution(-180., 180.);
191  std::uniform_real_distribution<double> alt_distribution(-519., 519.);
192 
193  for (int i = 0; i < 1000; ++i) {
194  const double latitude = lat_distribution(rng);
195  const double longitude = long_distribution(rng);
196  const double altitude = alt_distribution(rng);
197  cartographer::transform::Rigid3d transform_to_local_frame =
198  ComputeLocalFrameFromLatLong(latitude, longitude);
199  EXPECT_TRUE((transform_to_local_frame *
200  LatLongAltToEcef(latitude, longitude, altitude))
201  .isApprox(altitude * Eigen::Vector3d::UnitZ(), kEps))
202  << transform_to_local_frame *
203  LatLongAltToEcef(latitude, longitude, altitude)
204  << "\n"
205  << altitude;
206  }
207 }
208 
209 } // namespace
210 } // namespace cartographer_ros
LandmarkData ToLandmarkData(const LandmarkList &landmark_list)
cartographer::transform::Rigid3d ComputeLocalFrameFromLatLong(const double latitude, const double longitude)
Eigen::Vector3d LatLongAltToEcef(const double latitude, const double longitude, const double altitude)
TEST(ActionClientDestruction, persistent_goal_handles_1)
::cartographer::common::Time FromRos(const ::ros::Time &time)
std::tuple<::cartographer::sensor::PointCloudWithIntensities, ::cartographer::common::Time > ToPointCloudWithIntensities(const sensor_msgs::LaserScan &msg)


cartographer_ros
Author(s): The Cartographer Authors
autogenerated on Mon Feb 28 2022 22:06:05