Autoware.Auto
point_cloud_mapper.hpp
Go to the documentation of this file.
1 // Copyright 2020 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
16 
17 #ifndef POINT_CLOUD_MAPPING__POINT_CLOUD_MAPPER_HPP_
18 #define POINT_CLOUD_MAPPING__POINT_CLOUD_MAPPER_HPP_
19 
22 #include <sensor_msgs/msg/point_cloud2.hpp>
24 #include <tf2_sensor_msgs/tf2_sensor_msgs.h>
29 #include <experimental/optional>
30 #include <memory>
31 #include <string>
32 #include <utility>
33 #include <type_traits>
34 
35 namespace autoware
36 {
37 namespace mapping
38 {
39 namespace point_cloud_mapping
40 {
41 template<typename MapIncrementT>
42 using RegistrationResult = std::pair<std::reference_wrapper<const MapIncrementT>,
43  geometry_msgs::msg::PoseWithCovarianceStamped>;
44 
48 template<typename LocalizerSummaryT, typename MapIncrementT>
49 struct POINT_CLOUD_MAPPING_PUBLIC MapperRegistrationSummaryBase
50 {
51 public:
52  using MaybeLocalizerSummary = std::experimental::optional<LocalizerSummaryT>;
53 // /// Constructor
54 // /// \param increment const ref. to the Increment from the latest registration.
55 // /// \param update_summary Map update summary from the latest map insertion.
56 // /// \param localization_summary Localizer registration summary.
57 // MapperRegistrationSummaryBase(
58 // MapIncrementT increment,
59 // MapUpdateSummary update_summary, MaybeLocalizerSummary localization_summary)
60 // : map_increment{increment}, map_update_summary{update_summary},
61 // localizer_summary{localization_summary} {}
62 
63  MapIncrementT map_increment;
66 };
67 
70 
84 template<typename LocalizerT, typename MapRepresentationT,
85  typename ObservationMsgT, typename MapIncrementT, typename RegistrationSummaryT,
86  class WriteTriggerPolicyT, class PrefixGeneratorT>
87 class POINT_CLOUD_MAPPING_PUBLIC MapperBase
89  ObservationMsgT, MapIncrementT, RegistrationSummaryT>
90 {
91 public:
92  static_assert(
93  std::is_same<MapIncrementT, typename LocalizerT::MapMsg>::value,
94  "MapperBase and the utilized Relative Localizer must use the same map increment type");
95  static_assert(
96  std::is_same<ObservationMsgT, typename LocalizerT::InputMsg>::value,
97  "MapperBase and the utilized Relative Localizer must use the same observation type");
98 
99  using PoseWithCovarianceStamped = geometry_msgs::msg::PoseWithCovarianceStamped;
101  using MaybeLocalizerSummary =
102  std::experimental::optional<typename LocalizerT::RegistrationSummary>;
103  using MapIncrementPtrT = std::shared_ptr<MapIncrementT>;
104  using ConstMapIncrementPtrT = std::shared_ptr<const MapIncrementT>;
105  using RegistrationSummary = RegistrationSummaryT;
106  using LocalizerBase = localization::localization_common::
107  RelativeLocalizerBase<ObservationMsgT, MapIncrementT, typename LocalizerT::RegistrationSummary>;
108  using LocalizerBasePtr = std::unique_ptr<LocalizerBase>;
109 
117  const std::string & map_filename_prefix,
118  MapRepresentationT && map,
119  LocalizerBasePtr && localizer_ptr,
120  const std::string map_frame_id)
121  : m_base_fn_prefix{map_filename_prefix},
122  m_map{std::forward<MapRepresentationT>(map)},
123  m_localizer_ptr{std::forward<LocalizerBasePtr>(localizer_ptr)},
124  m_frame_id{map_frame_id}
125  {
126  this->set_map_valid();
127  }
128 
132  RegistrationSummaryT register_measurement_impl(
133  const ObservationMsgT & msg, const TransformStamped & transform_initial,
134  PoseWithCovarianceStamped & pose_out) override
135  {
136  PoseWithCovarianceStamped registered_pose;
137 
138  MaybeLocalizerSummary localization_summary{std::experimental::nullopt};
139 
140  if (m_map.size() > 0U) {
141  if (!m_localizer_ptr->map_valid()) {
142  throw std::runtime_error(
143  "MapperBase: Map representation has data but "
144  "the localizer's map is at an invalid state.");
145  }
146  localization_summary =
147  m_localizer_ptr->register_measurement(msg, transform_initial, pose_out);
148  } else {
149  // If the map is empty, there's nothing to register to. We can place the cloud at the
150  // center of the map.
151  pose_out = get_identity(get_stamp(msg), m_frame_id);
152  }
153 
154  const auto & increment_ptr = get_map_increment(msg, pose_out);
155 
156  const auto & update_summary = update_map(*increment_ptr, registered_pose);
157 
158  if (m_trigger_policy.ready(m_map)) {
159  write_to_file();
160  }
161 
162  return make_summary(increment_ptr, update_summary, localization_summary);
163  }
164 
165  const std::string & map_frame_id() const noexcept override
166  {
167  return m_frame_id;
168  }
169 
170  void set_map_impl(const MapIncrementT & msg) override
171  {
172  m_map.clear();
173  insert_to_map_impl(msg);
174  }
175 
176  std::chrono::system_clock::time_point map_stamp() const noexcept override
177  {
178  return m_current_stamp;
179  }
180 
181  void insert_to_map_impl(const MapIncrementT & msg) override
182  {
183  const auto & msg_frame = get_frame_id(msg);
184  if (msg_frame != m_frame_id) {
185  throw std::runtime_error("MapperBase: Can't insert a map that is in a different frame.");
186  }
187  update_map(msg, get_identity(get_stamp(msg), m_frame_id));
188  }
189 
191  virtual ~MapperBase()
192  {
193  write_to_file();
194  }
195 
196 protected:
197  void write_to_file() const
198  {
199  if (m_map.size() > 0U) {
200  m_map.write(m_fn_prefix_generator.get(m_base_fn_prefix));
201  }
202  }
203 
204  void set_write_trigger(WriteTriggerPolicyT && write_trigger)
205  {
206  m_trigger_policy = std::move(write_trigger);
207  }
208 
209  void set_prefix_generator(PrefixGeneratorT && prefix_generator)
210  {
211  m_fn_prefix_generator = std::move(prefix_generator);
212  }
213 
215  builtin_interfaces::msg::Time stamp,
216  const std::string frame_id) const noexcept
217  {
219  out.header.stamp = stamp;
220  out.header.frame_id = frame_id;
221  out.pose.pose.orientation.w = 1.0;
222  return out;
223  }
224 
225 private:
226  virtual RegistrationSummaryT make_summary(
227  const ConstMapIncrementPtrT & increment,
228  const MapUpdateSummary & map_update_summary,
229  const MaybeLocalizerSummary & localization_summary) const noexcept = 0;
230 
236  auto update_map(
237  const MapIncrementT & increment,
238  PoseWithCovarianceStamped pose)
239  {
240  const auto insert_summary = m_map.try_add_observation(increment, pose);
241 
242  // Let's update the stamp at the start of each map in case someone needs it.
243  if (insert_summary.update_type == MapUpdateType::NEW) {
244  m_current_stamp = time_utils::from_message(pose.header.stamp);
245  }
246  // Only also insert to the localizer's map if the maps are not shared.
247  // TODO(yunus.caliskan): switch to `if constexpr` when c++17 is available.
248  if (m_map.storage_mode() == MapStorageMode::Independent) {
249  switch (insert_summary.update_type) {
250  case MapUpdateType::NEW:
251  m_localizer_ptr->set_map(increment);
252  break;
254  m_localizer_ptr->insert_to_map(increment);
255  break;
257  default:
258  break;
259  }
260  }
261  return insert_summary;
262  }
263 
268  virtual ConstMapIncrementPtrT get_map_increment(
269  const ObservationMsgT & observation,
270  const PoseWithCovarianceStamped & registered_pose) = 0;
271 
272  std::string m_base_fn_prefix;
273  MapRepresentationT m_map;
274  LocalizerBasePtr m_localizer_ptr;
275  WriteTriggerPolicyT m_trigger_policy;
276  PrefixGeneratorT m_fn_prefix_generator;
277  std::string m_frame_id;
278  std::chrono::system_clock::time_point m_current_stamp{
279  std::chrono::system_clock::time_point::min()};
280 };
281 
282 using Cloud = sensor_msgs::msg::PointCloud2;
283 using CloudPtr = std::shared_ptr<Cloud>;
284 using ConstCloudPtr = std::shared_ptr<const Cloud>;
285 
290 template<typename LocalizerT, typename MapRepresentationT,
291  class WriteTriggerPolicyT, class FileNamePrefixGeneratorT>
292 class PointCloudMapper : public MapperBase<LocalizerT, MapRepresentationT,
293  sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2,
294  MapperRegistrationSummaryBase<typename LocalizerT::RegistrationSummary,
295  ConstCloudPtr>,
296  WriteTriggerPolicyT, FileNamePrefixGeneratorT>
297 {
298 public:
299  using RegistrationSummary =
300  MapperRegistrationSummaryBase<typename LocalizerT::RegistrationSummary,
302  using Base = MapperBase<LocalizerT, MapRepresentationT,
303  sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2,
304  RegistrationSummary, WriteTriggerPolicyT, FileNamePrefixGeneratorT>;
305  using PoseWithCovarianceStamped = geometry_msgs::msg::PoseWithCovarianceStamped;
307 
315  const std::string & map_filename_prefix,
316  MapRepresentationT && map, LocalizerBasePtr && localizer_ptr,
317  const std::string & map_frame)
318  : Base(map_filename_prefix, std::forward<MapRepresentationT>(map),
319  std::forward<LocalizerBasePtr>(localizer_ptr), map_frame),
320  m_cached_increment_ptr{std::make_shared<Cloud>()}
321  {
322  common::lidar_utils::init_pcl_msg(*m_cached_increment_ptr, map_frame);
323  }
324 
325 private:
331  ConstCloudPtr get_map_increment(
332  const Cloud & observation,
333  const PoseWithCovarianceStamped & registered_pose) override
334  {
335  reset_cached_msg(get_msg_size(observation));
336  // Convert pose to transform for `doTransform()`
338  tf.header.stamp = registered_pose.header.stamp;
339  tf.header.frame_id = registered_pose.header.frame_id;
340  tf.child_frame_id = observation.header.frame_id;
341  const auto & trans = registered_pose.pose.pose.position;
342  const auto & rot = registered_pose.pose.pose.orientation;
343  tf.transform.translation.set__x(trans.x).set__y(trans.y).set__z(trans.z);
344  tf.transform.rotation.set__x(rot.x).set__y(rot.y).set__z(rot.z).set__w(rot.w);
345 
346  tf2::doTransform(observation, *m_cached_increment_ptr, tf);
347  return m_cached_increment_ptr;
348  }
349 
350 private:
351  void reset_cached_msg(std::size_t size)
352  {
353  sensor_msgs::PointCloud2Modifier inc_modifier{*m_cached_increment_ptr};
354  inc_modifier.clear();
355  inc_modifier.resize(size);
356  }
357  std::size_t get_msg_size(const Cloud & msg) const
358  {
359  const auto safe_indices = common::lidar_utils::sanitize_point_cloud(msg);
360  // Only do the division when necessary.
361  return (safe_indices.data_length == msg.data.size()) ?
362  msg.width : (safe_indices.data_length / safe_indices.point_step);
363  }
364 
365  RegistrationSummary make_summary(
366  const ConstCloudPtr & increment,
367  const MapUpdateSummary & map_update_summary,
368  const typename Base::MaybeLocalizerSummary & localization_summary) const noexcept override
369  {
370  return RegistrationSummary{increment, map_update_summary, localization_summary};
371  }
372 
373  CloudPtr m_cached_increment_ptr;
374 };
375 
376 } // namespace point_cloud_mapping
377 } // namespace mapping
378 } // namespace autoware
379 
380 #endif // POINT_CLOUD_MAPPING__POINT_CLOUD_MAPPER_HPP_
autoware::mapping::point_cloud_mapping::MapperBase::register_measurement_impl
RegistrationSummaryT register_measurement_impl(const ObservationMsgT &msg, const TransformStamped &transform_initial, PoseWithCovarianceStamped &pose_out) override
Definition: point_cloud_mapper.hpp:132
autoware::mapping::point_cloud_mapping::MapUpdateType::UPDATE
@ UPDATE
autoware::common::helper_functions::message_field_adapters::get_stamp
const TimeStamp & get_stamp(const T &msg) noexcept
Definition: message_adapters.hpp:101
autoware::mapping::point_cloud_mapping::MapperRegistrationSummaryBase
Definition: point_cloud_mapper.hpp:49
localizer_base.hpp
autoware::mapping::point_cloud_mapping::MapperBase::insert_to_map_impl
void insert_to_map_impl(const MapIncrementT &msg) override
insert_to_map implementation.
Definition: point_cloud_mapper.hpp:181
autoware::mapping::point_cloud_mapping::MapperBase::~MapperBase
virtual ~MapperBase()
Virtual base destructor. Triggers map writing in case there is unwritten data in the map.
Definition: point_cloud_mapper.hpp:191
autoware::mapping::point_cloud_mapping::PointCloudMapper::PoseWithCovarianceStamped
geometry_msgs::msg::PoseWithCovarianceStamped PoseWithCovarianceStamped
Definition: point_cloud_mapper.hpp:305
autoware::mapping::point_cloud_mapping::CloudPtr
std::shared_ptr< Cloud > CloudPtr
Definition: point_cloud_mapper.hpp:283
autoware::mapping::point_cloud_mapping::PointCloudMapper
Definition: point_cloud_mapper.hpp:292
map.hpp
autoware::mapping::point_cloud_mapping::MapperRegistrationSummaryBase::map_increment
MapIncrementT map_increment
Definition: point_cloud_mapper.hpp:63
autoware::localization::localization_common::RelativeLocalizerBase< sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr > >::RegistrationSummary
MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr > RegistrationSummary
Definition: localizer_base.hpp:63
point_cloud_utils.hpp
This class defines common functions and classes to work with pointclouds.
autoware::mapping::point_cloud_mapping::MapperRegistrationSummaryBase::localizer_summary
MaybeLocalizerSummary localizer_summary
Definition: point_cloud_mapper.hpp:65
autoware::localization::localization_common::RelativeLocalizerBase< sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr > >::PoseWithCovarianceStamped
geometry_msgs::msg::PoseWithCovarianceStamped PoseWithCovarianceStamped
Definition: localizer_base.hpp:61
visibility_control.hpp
message_adapters.hpp
This file includes common helper functions.
autoware::mapping::point_cloud_mapping::PointCloudMapper::LocalizerBasePtr
typename Base::LocalizerBasePtr LocalizerBasePtr
Definition: point_cloud_mapper.hpp:306
autoware::mapping::point_cloud_mapping::MapperBase< LocalizerT, MapRepresentationT, sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr >, WriteTriggerPolicyT, FileNamePrefixGeneratorT >::MapIncrementPtrT
std::shared_ptr< sensor_msgs::msg::PointCloud2 > MapIncrementPtrT
Definition: point_cloud_mapper.hpp:103
autoware::common::helper_functions::message_field_adapters::get_frame_id
const std::string & get_frame_id(const T &msg) noexcept
Definition: message_adapters.hpp:83
autoware::mapping::point_cloud_mapping::MapStorageMode::Independent
@ Independent
autoware
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24
autoware::common::lidar_utils::init_pcl_msg
LIDAR_UTILS_PUBLIC void init_pcl_msg(sensor_msgs::msg::PointCloud2 &msg, const std::string &frame_id, const std::size_t size=static_cast< std::size_t >(MAX_SCAN_POINTS))
initializes header information for point cloud for x, y, z and intensity
Definition: point_cloud_utils.cpp:141
autoware::mapping::point_cloud_mapping::MapperBase::set_map_impl
void set_map_impl(const MapIncrementT &msg) override
set_map implementation.
Definition: point_cloud_mapper.hpp:170
autoware::mapping::point_cloud_mapping::Cloud
sensor_msgs::msg::PointCloud2 Cloud
Definition: point_cloud_mapper.hpp:282
autoware::mapping::point_cloud_mapping::MapperRegistrationSummaryBase::map_update_summary
MapUpdateSummary map_update_summary
Definition: point_cloud_mapper.hpp:64
autoware::mapping::point_cloud_mapping::MapperBase::get_identity
PoseWithCovarianceStamped get_identity(builtin_interfaces::msg::Time stamp, const std::string frame_id) const noexcept
Definition: point_cloud_mapper.hpp:214
autoware::mapping::point_cloud_mapping::MapUpdateSummary
Struct containing information on the attempt to push a new observation to a map.
Definition: map.hpp:56
autoware::mapping::point_cloud_mapping::MapperBase::map_stamp
std::chrono::system_clock::time_point map_stamp() const noexcept override
Definition: point_cloud_mapper.hpp:176
motion::motion_testing_nodes::TransformStamped
geometry_msgs::msg::TransformStamped TransformStamped
Definition: motion_testing_publisher.hpp:37
time_utils::from_message
TIME_UTILS_PUBLIC std::chrono::system_clock::time_point from_message(builtin_interfaces::msg::Time t) noexcept
Convert from std::chrono::time_point from time message.
Definition: time_utils.cpp:84
autoware::mapping::point_cloud_mapping::MapUpdateType::NO_CHANGE
@ NO_CHANGE
autoware::mapping::point_cloud_mapping::MapperBase< LocalizerT, MapRepresentationT, sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr >, WriteTriggerPolicyT, FileNamePrefixGeneratorT >::TransformStamped
geometry_msgs::msg::TransformStamped TransformStamped
Definition: point_cloud_mapper.hpp:100
autoware::mapping::point_cloud_mapping::MapperRegistrationSummaryBase::MaybeLocalizerSummary
std::experimental::optional< LocalizerSummaryT > MaybeLocalizerSummary
Definition: point_cloud_mapper.hpp:52
autoware::mapping::point_cloud_mapping::MapperBase< LocalizerT, MapRepresentationT, sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr >, WriteTriggerPolicyT, FileNamePrefixGeneratorT >::MaybeLocalizerSummary
std::experimental::optional< typename LocalizerT::RegistrationSummary > MaybeLocalizerSummary
Definition: point_cloud_mapper.hpp:102
autoware::mapping::point_cloud_mapping::ConstCloudPtr
std::shared_ptr< const Cloud > ConstCloudPtr
Definition: point_cloud_mapper.hpp:284
autoware::mapping::point_cloud_mapping::PointCloudMapper::RegistrationSummary
MapperRegistrationSummaryBase< typename LocalizerT::RegistrationSummary, ConstCloudPtr > RegistrationSummary
Definition: point_cloud_mapper.hpp:301
autoware::mapping::point_cloud_mapping::PointCloudMapper::PointCloudMapper
PointCloudMapper(const std::string &map_filename_prefix, MapRepresentationT &&map, LocalizerBasePtr &&localizer_ptr, const std::string &map_frame)
Definition: point_cloud_mapper.hpp:314
autoware::common::lidar_utils::sanitize_point_cloud
LIDAR_UTILS_PUBLIC SafeCloudIndices sanitize_point_cloud(const sensor_msgs::msg::PointCloud2 &msg)
Definition: point_cloud_utils.cpp:131
policies.hpp
time_utils.hpp
autoware::mapping::point_cloud_mapping::MapperBase::set_write_trigger
void set_write_trigger(WriteTriggerPolicyT &&write_trigger)
Definition: point_cloud_mapper.hpp:204
autoware::mapping::point_cloud_mapping::MapperBase
Definition: point_cloud_mapper.hpp:87
autoware::mapping::point_cloud_mapping::MapUpdateType::NEW
@ NEW
autoware::localization::localization_common::RelativeLocalizerBase
Definition: localizer_base.hpp:58
autoware::mapping::point_cloud_mapping::MapperBase< LocalizerT, MapRepresentationT, sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr >, WriteTriggerPolicyT, FileNamePrefixGeneratorT >::LocalizerBasePtr
std::unique_ptr< LocalizerBase > LocalizerBasePtr
Definition: point_cloud_mapper.hpp:108
autoware::mapping::point_cloud_mapping::RegistrationResult
std::pair< std::reference_wrapper< const MapIncrementT >, geometry_msgs::msg::PoseWithCovarianceStamped > RegistrationResult
Definition: point_cloud_mapper.hpp:43
autoware::mapping::point_cloud_mapping::MapperBase< LocalizerT, MapRepresentationT, sensor_msgs::msg::PointCloud2, sensor_msgs::msg::PointCloud2, MapperRegistrationSummaryBase< LocalizerT::RegistrationSummary, ConstCloudPtr >, WriteTriggerPolicyT, FileNamePrefixGeneratorT >::ConstMapIncrementPtrT
std::shared_ptr< const sensor_msgs::msg::PointCloud2 > ConstMapIncrementPtrT
Definition: point_cloud_mapper.hpp:104
autoware::mapping::point_cloud_mapping::MapperBase::write_to_file
void write_to_file() const
Definition: point_cloud_mapper.hpp:197
autoware::mapping::point_cloud_mapping::MapperBase::map_frame_id
const std::string & map_frame_id() const noexcept override
Definition: point_cloud_mapper.hpp:165
tf2::doTransform
void doTransform(const geometry_msgs::msg::Point32 &t_in, geometry_msgs::msg::Point32 &t_out, const geometry_msgs::msg::TransformStamped &transform)
Apply a geometry_msgs TransformStamped to an geometry_msgs Point32 type. This function is a specializ...
Definition: tf2_autoware_auto_msgs.hpp:54
autoware::mapping::point_cloud_mapping::MapperBase::MapperBase
MapperBase(const std::string &map_filename_prefix, MapRepresentationT &&map, LocalizerBasePtr &&localizer_ptr, const std::string map_frame_id)
Definition: point_cloud_mapper.hpp:116
autoware::mapping::point_cloud_mapping::MapperBase::set_prefix_generator
void set_prefix_generator(PrefixGeneratorT &&prefix_generator)
Definition: point_cloud_mapper.hpp:209