/home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/point_cloud.hpp Source File

/home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/point_cloud.hpp Source File#

Beluga ROS: /home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/point_cloud.hpp Source File
Beluga ROS
point_cloud.hpp
Go to the documentation of this file.
1 // Copyright 2024 Ekumen, Inc.
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 #ifndef BELUGA_ROS_POINT_CLOUD_HPP
16 #define BELUGA_ROS_POINT_CLOUD_HPP
17 
18 #include <range/v3/view/iota.hpp>
19 
22 #include <beluga_ros/messages.hpp>
23 
24 #include <sophus/se3.hpp>
25 
26 #include <Eigen/Dense>
27 
28 #include "beluga/eigen_compatibility.hpp"
29 
44 namespace beluga_ros {
45 
47 template <typename T>
48 class PointCloud3 : public beluga::BasePointCloud<PointCloud3<T>> {
49  public:
51  using Scalar = T;
52 
54  static_assert(
55  std::is_same_v<Scalar, float> || std::is_same_v<Scalar, double>,
56  "Pointcloud3 only supports float or double datatype");
57 
62  explicit PointCloud3(beluga_ros::msg::PointCloud2ConstSharedPtr cloud, Sophus::SE3d origin = Sophus::SE3d())
63  : cloud_(std::move(cloud)), origin_(std::move(origin)) {
64  assert(cloud_ != nullptr);
65  constexpr uint8_t fieldType = sensor_msgs::typeAsPointFieldType<T>::value;
66  // Check if point cloud is 3D
67  if (cloud_->fields.size() < 3) {
68  throw std::invalid_argument("PointCloud is not 3D");
69  }
70  // Check point cloud is XYZ... type
71  if (cloud_->fields.at(0).name != "x" || cloud_->fields.at(1).name != "y" || cloud_->fields.at(2).name != "z") {
72  throw std::invalid_argument("PointCloud not XYZ...");
73  }
74  // Check XYZ datatype is the same
75  if (cloud_->fields.at(0).datatype != fieldType || cloud_->fields.at(1).datatype != fieldType ||
76  cloud_->fields.at(2).datatype != fieldType) {
77  throw std::invalid_argument("XYZ datatype are not same");
78  }
79  // Check stride is divisible
80  if (cloud_->point_step % sizeof(Scalar) != 0) {
81  throw std::invalid_argument("Data is not memory-aligned");
82  }
83  stride_ = static_cast<int>(cloud_->point_step / sizeof(Scalar));
84  }
85 
87  [[nodiscard]] const auto& origin() const { return origin_; }
88 
90  [[nodiscard]] auto points() const {
91  const beluga_ros::msg::PointCloud2ConstIterator<Scalar> iter_points(*cloud_, "x");
92  return Eigen::Map<const Eigen::Matrix3X<Scalar>, 0, Eigen::OuterStride<>>(
93  &iter_points[0], 3, cloud_->width * cloud_->height, stride_);
94  }
95 
96  private:
97  beluga_ros::msg::PointCloud2ConstSharedPtr cloud_;
98  int stride_;
99  Sophus::SE3d origin_;
100 };
101 
102 } // namespace beluga_ros
103 
104 #endif // BELUGA_ROS_POINT_CLOUD_HPP
Thin wrapper type for 3D sensor_msgs/PointCloud2 messages.
Definition: point_cloud.hpp:48
const auto & origin() const
Get the point cloud frame origin in the filter frame.
Definition: point_cloud.hpp:87
auto points() const
Get the unorganized 3D point collection as an Eigen Map<Eigen::Matrix3X>.
Definition: point_cloud.hpp:90
PointCloud3(beluga_ros::msg::PointCloud2ConstSharedPtr cloud, Sophus::SE3d origin=Sophus::SE3d())
Check type is float or double.
Definition: point_cloud.hpp:62
T Scalar
PointCloud type.
Definition: point_cloud.hpp:51
The main Beluga ROS namespace.
Definition: amcl.hpp:44