forked from autowarefoundation/autoware_universe
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpointcloud_densification.cpp
116 lines (93 loc) · 3.39 KB
/
pointcloud_densification.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2024 TIER IV, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "lidar_transfusion/preprocess/pointcloud_densification.hpp"
#include <pcl_ros/transforms.hpp>
#include <pcl_conversions/pcl_conversions.h>
#ifdef ROS_DISTRO_GALACTIC
#include <tf2_eigen/tf2_eigen.h>
#else
#include <tf2_eigen/tf2_eigen.hpp>
#endif
#include <boost/optional.hpp>
#include <string>
#include <utility>
namespace
{
boost::optional<geometry_msgs::msg::Transform> getTransform(
const tf2_ros::Buffer & tf_buffer, const std::string & target_frame_id,
const std::string & source_frame_id, const rclcpp::Time & time)
{
try {
geometry_msgs::msg::TransformStamped transform_stamped;
transform_stamped = tf_buffer.lookupTransform(
target_frame_id, source_frame_id, time, rclcpp::Duration::from_seconds(0.5));
return transform_stamped.transform;
} catch (tf2::TransformException & ex) {
RCLCPP_WARN_STREAM(rclcpp::get_logger("lidar_transfusion"), ex.what());
return boost::none;
}
}
Eigen::Affine3f transformToEigen(const geometry_msgs::msg::Transform & t)
{
Eigen::Affine3f a;
a.matrix() = tf2::transformToEigen(t).matrix().cast<float>();
return a;
}
} // namespace
namespace lidar_transfusion
{
PointCloudDensification::PointCloudDensification(
const DensificationParam & param, cudaStream_t & stream)
: param_(param), stream_(stream)
{
}
bool PointCloudDensification::enqueuePointCloud(
const sensor_msgs::msg::PointCloud2 & pointcloud_msg, const tf2_ros::Buffer & tf_buffer)
{
const auto header = pointcloud_msg.header;
if (param_.pointcloud_cache_size() > 1) {
auto transform_world2current =
getTransform(tf_buffer, header.frame_id, param_.world_frame_id(), header.stamp);
if (!transform_world2current) {
return false;
}
auto affine_world2current = transformToEigen(transform_world2current.get());
enqueue(pointcloud_msg, affine_world2current);
} else {
enqueue(pointcloud_msg, Eigen::Affine3f::Identity());
}
dequeue();
return true;
}
void PointCloudDensification::enqueue(
const sensor_msgs::msg::PointCloud2 & msg, const Eigen::Affine3f & affine_world2current)
{
affine_world2current_ = affine_world2current;
current_timestamp_ = rclcpp::Time(msg.header.stamp).seconds();
auto data_d = cuda::make_unique<uint8_t[]>(
sizeof(uint8_t) * msg.width * msg.height * msg.point_step / sizeof(uint8_t));
CHECK_CUDA_ERROR(cudaMemcpyAsync(
data_d.get(), msg.data.data(), sizeof(uint8_t) * msg.width * msg.height * msg.point_step,
cudaMemcpyHostToDevice, stream_));
PointCloudWithTransform pointcloud = {
std::move(data_d), msg.header, msg.width * msg.height, affine_world2current.inverse()};
pointcloud_cache_.push_front(std::move(pointcloud));
}
void PointCloudDensification::dequeue()
{
if (pointcloud_cache_.size() > param_.pointcloud_cache_size()) {
pointcloud_cache_.pop_back();
}
}
} // namespace lidar_transfusion