@@ -63,14 +63,12 @@ void OccupancyGridMapProjectiveBlindSpot::updateWithPointCloud(
63
63
64
64
// Transform from base_link to map frame
65
65
PointCloud2 map_raw_pointcloud, map_obstacle_pointcloud; // point cloud in map frame
66
- utils::transformPointcloud (raw_pointcloud, robot_pose, map_raw_pointcloud);
67
- utils::transformPointcloud (obstacle_pointcloud, robot_pose, map_obstacle_pointcloud);
66
+ Eigen::Matrix4f matmap = utils::getTransformMatrix (robot_pose);
68
67
69
68
// Transform from map frame to scan frame
70
69
PointCloud2 scan_raw_pointcloud, scan_obstacle_pointcloud; // point cloud in scan frame
71
70
const auto scan2map_pose = utils::getInversePose (scan_origin); // scan -> map transform pose
72
- utils::transformPointcloud (map_raw_pointcloud, scan2map_pose, scan_raw_pointcloud);
73
- utils::transformPointcloud (map_obstacle_pointcloud, scan2map_pose, scan_obstacle_pointcloud);
71
+ Eigen::Matrix4f matscan = utils::getTransformMatrix (scan2map_pose);
74
72
75
73
// Create angle bins and sort points by range
76
74
struct BinInfo3D
@@ -97,36 +95,92 @@ void OccupancyGridMapProjectiveBlindSpot::updateWithPointCloud(
97
95
double projected_wy;
98
96
};
99
97
100
- std::vector</* angle bin*/ std::vector<BinInfo3D>> obstacle_pointcloud_angle_bins;
101
- std::vector</* angle bin*/ std::vector<BinInfo3D>> raw_pointcloud_angle_bins;
102
- obstacle_pointcloud_angle_bins.resize(angle_bin_size);
103
- raw_pointcloud_angle_bins.resize(angle_bin_size);
104
- for (PointCloud2ConstIterator<float > iter_x (scan_raw_pointcloud, " x" ),
105
- iter_y(scan_raw_pointcloud, " y" ), iter_wx(map_raw_pointcloud, " x" ),
106
- iter_wy(map_raw_pointcloud, " y" ), iter_wz(map_raw_pointcloud, " z" );
107
- iter_x != iter_x.end(); ++iter_x, ++iter_y, ++iter_wx, ++iter_wy, ++iter_wz) {
108
- const double angle = atan2 (*iter_y, *iter_x);
109
- const int angle_bin_index = (angle - min_angle) / angle_increment;
98
+ std::vector</* angle bin*/ std::vector<BinInfo3D>> obstacle_pointcloud_angle_bins (angle_bin_size);
99
+ std::vector</* angle bin*/ std::vector<BinInfo3D>> raw_pointcloud_angle_bins (angle_bin_size);
100
+ const int x_offset_raw = raw_pointcloud.fields[pcl::getFieldIndex(raw_pointcloud, " x" )].offset;
101
+ const int y_offset_raw = raw_pointcloud.fields[pcl::getFieldIndex(raw_pointcloud, " y" )].offset;
102
+ const int z_offset_raw = raw_pointcloud.fields[pcl::getFieldIndex(raw_pointcloud, " z" )].offset;
103
+ const int x_offset_obstacle =
104
+ obstacle_pointcloud.fields[pcl::getFieldIndex(obstacle_pointcloud, " x" )].offset;
105
+ const int y_offset_obstacle =
106
+ obstacle_pointcloud.fields[pcl::getFieldIndex(obstacle_pointcloud, " y" )].offset;
107
+ const int z_offset_obstacle =
108
+ obstacle_pointcloud.fields[pcl::getFieldIndex(obstacle_pointcloud, " z" )].offset;
109
+ const size_t raw_pointcloud_size = raw_pointcloud.width * raw_pointcloud.height;
110
+ const size_t obstacle_pointcloud_size = obstacle_pointcloud.width * obstacle_pointcloud.height;
111
+
112
+ const size_t raw_reserve_size = raw_pointcloud_size / angle_bin_size;
113
+ const size_t obstacle_reserve_size = obstacle_pointcloud_size / angle_bin_size;
114
+ for (auto & raw_pointcloud_angle_bin : raw_pointcloud_angle_bins) {
115
+ raw_pointcloud_angle_bin.reserve (raw_reserve_size);
116
+ }
117
+ for (auto & obstacle_pointcloud_angle_bin : obstacle_pointcloud_angle_bins) {
118
+ obstacle_pointcloud_angle_bin.reserve (obstacle_reserve_size);
119
+ }
120
+ size_t global_offset = 0 ;
121
+ const auto angle_increment_inv = 1.0 / angle_increment;
122
+
123
+ for (size_t i = 0 ; i < raw_pointcloud_size; i++) {
124
+ Eigen::Vector4f pt (
125
+ *reinterpret_cast <const float *>(&raw_pointcloud.data [global_offset + x_offset_raw]),
126
+ *reinterpret_cast <const float *>(&raw_pointcloud.data [global_offset + y_offset_raw]),
127
+ *reinterpret_cast <const float *>(&raw_pointcloud.data [global_offset + z_offset_raw]), 1 );
128
+ // Exclude invalid points
129
+ if (!std::isfinite (pt[0 ]) || !std::isfinite (pt[1 ]) || !std::isfinite (pt[2 ])) {
130
+ global_offset += raw_pointcloud.point_step ;
131
+ continue ;
132
+ }
133
+ // Apply height filter
134
+ if (pt[2 ] < min_height_ || max_height_ < pt[2 ]) {
135
+ global_offset += raw_pointcloud.point_step ;
136
+ continue ;
137
+ }
138
+ // Calculate transformed points
139
+ Eigen::Vector4f pt_map (matmap * pt);
140
+ Eigen::Vector4f pt_scan (matscan * pt_map);
141
+ const double angle = atan2 (pt_scan[1 ], pt_scan[0 ]);
142
+ const int angle_bin_index = (angle - min_angle) * angle_increment_inv;
110
143
raw_pointcloud_angle_bins.at (angle_bin_index)
111
- .emplace_back (std::hypot (*iter_y, *iter_x), *iter_wx, *iter_wy, *iter_wz);
144
+ .emplace_back (
145
+ std::sqrt (pt_scan[1 ] * pt_scan[1 ] + pt_scan[0 ] * pt_scan[0 ]), pt_map[0 ], pt_map[1 ],
146
+ pt_map[2 ]);
147
+ global_offset += raw_pointcloud.point_step ;
112
148
}
113
149
for (auto & raw_pointcloud_angle_bin : raw_pointcloud_angle_bins) {
114
150
std::sort (raw_pointcloud_angle_bin.begin (), raw_pointcloud_angle_bin.end (), [](auto a, auto b) {
115
151
return a.range < b.range ;
116
152
});
117
153
}
118
- // Create obstacle angle bins and sort points by range
119
- for (PointCloud2ConstIterator<float > iter_x (scan_obstacle_pointcloud, " x" ),
120
- iter_y(scan_obstacle_pointcloud, " y" ), iter_z(scan_obstacle_pointcloud, " z" ),
121
- iter_wx(map_obstacle_pointcloud, " x" ), iter_wy(map_obstacle_pointcloud, " y" ),
122
- iter_wz(map_obstacle_pointcloud, " z" );
123
- iter_x != iter_x.end(); ++iter_x, ++iter_y, ++iter_z, ++iter_wx, ++iter_wy, ++iter_wz) {
154
+
155
+ global_offset = 0 ;
156
+ for (size_t i = 0 ; i < obstacle_pointcloud_size; i++) {
157
+ Eigen::Vector4f pt (
158
+ *reinterpret_cast <const float *>(
159
+ &obstacle_pointcloud.data [global_offset + x_offset_obstacle]),
160
+ *reinterpret_cast <const float *>(
161
+ &obstacle_pointcloud.data [global_offset + y_offset_obstacle]),
162
+ *reinterpret_cast <const float *>(
163
+ &obstacle_pointcloud.data [global_offset + z_offset_obstacle]),
164
+ 1 );
165
+ // Exclude invalid points
166
+ if (!std::isfinite (pt[0 ]) || !std::isfinite (pt[1 ]) || !std::isfinite (pt[2 ])) {
167
+ global_offset += obstacle_pointcloud.point_step ;
168
+ continue ;
169
+ }
170
+ // Apply height filter
171
+ if (pt[2 ] < min_height_ || max_height_ < pt[2 ]) {
172
+ global_offset += obstacle_pointcloud.point_step ;
173
+ continue ;
174
+ }
175
+ // Calculate transformed points
176
+ Eigen::Vector4f pt_map (matmap * pt);
177
+ Eigen::Vector4f pt_scan (matscan * pt_map);
124
178
const double scan_z = scan_origin.position .z - robot_pose.position .z ;
125
- const double obstacle_z = (*iter_wz ) - robot_pose.position .z ;
179
+ const double obstacle_z = (pt_map[ 2 ] ) - robot_pose.position .z ;
126
180
const double dz = scan_z - obstacle_z;
127
- const double angle = atan2 (*iter_y, *iter_x );
128
- const int angle_bin_index = (angle - min_angle) / angle_increment ;
129
- const double range = std::hypot (*iter_x, *iter_y );
181
+ const double angle = atan2 (pt_scan[ 1 ], pt_scan[ 0 ] );
182
+ const int angle_bin_index = (angle - min_angle) * angle_increment_inv ;
183
+ const double range = std::sqrt (pt_scan[ 1 ] * pt_scan[ 1 ] + pt_scan[ 0 ] * pt_scan[ 0 ] );
130
184
// Ignore obstacle points exceed the range of the raw points
131
185
if (raw_pointcloud_angle_bins.at (angle_bin_index).empty ()) {
132
186
continue ; // No raw point in this angle bin
@@ -136,17 +190,18 @@ void OccupancyGridMapProjectiveBlindSpot::updateWithPointCloud(
136
190
if (dz > projection_dz_threshold_) {
137
191
const double ratio = obstacle_z / dz;
138
192
const double projection_length = range * ratio;
139
- const double projected_wx = (*iter_wx ) + ((*iter_wx ) - scan_origin.position .x ) * ratio;
140
- const double projected_wy = (*iter_wy ) + ((*iter_wy ) - scan_origin.position .y ) * ratio;
193
+ const double projected_wx = (pt_map[ 0 ] ) + ((pt_map[ 0 ] ) - scan_origin.position .x ) * ratio;
194
+ const double projected_wy = (pt_map[ 1 ] ) + ((pt_map[ 1 ] ) - scan_origin.position .y ) * ratio;
141
195
obstacle_pointcloud_angle_bins.at (angle_bin_index)
142
196
.emplace_back (
143
- range, *iter_wx, *iter_wy, *iter_wz , projection_length, projected_wx, projected_wy);
197
+ range, pt_map[ 0 ], pt_map[ 1 ], pt_map[ 2 ] , projection_length, projected_wx, projected_wy);
144
198
} else {
145
199
obstacle_pointcloud_angle_bins.at (angle_bin_index)
146
200
.emplace_back (
147
- range, *iter_wx, *iter_wy, *iter_wz , std::numeric_limits<double >::infinity (),
201
+ range, pt_map[ 0 ], pt_map[ 1 ], pt_map[ 2 ] , std::numeric_limits<double >::infinity (),
148
202
std::numeric_limits<double >::infinity (), std::numeric_limits<double >::infinity ());
149
203
}
204
+ global_offset += obstacle_pointcloud.point_step ;
150
205
}
151
206
for (auto & obstacle_pointcloud_angle_bin : obstacle_pointcloud_angle_bins) {
152
207
std::sort (
0 commit comments