34 AINFO <<
"PointWise unet Configs: " << model_param_.DebugString();
36 use_gpu_ = model_param_.
use_gpu();
40 resolution_ = unet_params.resolution();
41 unet_width_ = unet_params.unet_width();
42 unet_length_ = unet_params.unet_length();
43 min_height_ = unet_params.min_height();
44 max_height_ = unet_params.max_height();
45 min_x_ = unet_params.min_x();
46 max_x_ = unet_params.max_x();
47 min_y_ = unet_params.min_y();
48 max_y_ = unet_params.max_y();
50 max_point_number_ = unet_params.max_point_number();
54 unet_nodes_.resize(unet_width_ * unet_length_);
58 AERROR <<
"Init model error.";
62 cudaStreamCreate(&stream_);
69 CHECK_EQ(motion_class_mapping_.size(), 4) <<
"class num and motion map size not match";
76 if (frame ==
nullptr) {
77 AERROR <<
"Input null frame ptr.";
81 AERROR <<
"Input null frame cloud.";
85 AERROR <<
"Input none points.";
90 original_cloud_ = frame->
cloud;
94 while (!prev_world_clouds_.empty()
96 prev_world_clouds_.pop_front();
100 if (prev_world_clouds_.size() == 0) {
101 AINFO <<
"No cached point cloud available, skip.";
102 prev_world_clouds_.push_back(std::make_pair(timestamp, frame->
world_cloud));
111 lidar_frame_ref_ = frame;
113 TransformCloud(prev_cloud, prev_world_clouds_.front().second);
117 GeneratePfnFeature(prev_cloud);
118 pfn_inference_->Infer();
119 GenerateBackboneFeature(prev_bev_feature_);
120 double prev_pfn_feature_time = timer.
toc(
true);
122 GeneratePfnFeature(original_cloud_);
123 pfn_inference_->Infer();
124 GenerateBackboneFeature(bev_feature_);
125 double cur_pfn_feature_time = timer.
toc(
true);
127 seg_pred_blob_->Reshape({max_point_number_, 4});
129 double backbone_infer_time = timer.
toc(
true);
131 LabelToPointCloud(frame);
132 double label_pointcloud_time = timer.
toc(
true);
134 AINFO <<
"MotionNet time: "
135 <<
"previous pfn feature time: " << prev_pfn_feature_time <<
"ms, "
136 <<
"current pfn feature time: " << cur_pfn_feature_time <<
"ms, "
137 <<
"backbone infer time: " << backbone_infer_time <<
"ms, "
138 <<
"pointcloud label time: " << label_pointcloud_time <<
"ms.";
140 prev_world_clouds_.push_back(std::make_pair(timestamp, frame->
world_cloud));
145bool MotionUnet::InitModel() {
147 std::map<std::string, std::vector<int>> pfn_blob_maps;
149 auto pfn_info = model_param_.
pfn_info();
154 std::string pfn_proto_file =
GetModelFile(model_path, pfn_info.proto_file().file());
158 "apollo::perception::inference::" + pfn_info.infer_plugin());
159 pfn_inference_->set_model_info(pfn_proto_file, pfn_input_names, pfn_output_names);
160 pfn_inference_->set_gpu_id(preprocess.gpu_id());
161 pfn_inference_->set_max_batch_size(max_point_number_ * 2);
166 pfn_inference_->Init(pfn_blob_maps);
168 if (pfn_input_names.size() == 1) {
169 voxels_ = pfn_inference_->get_blob(pfn_input_names.at(0));
170 CHECK_NOTNULL(voxels_.get());
172 AERROR <<
"Init pfn_inferece input blob error.";
176 if (pfn_output_names.size() == 1) {
177 pfn_point_feats_ = pfn_inference_->get_blob(pfn_output_names.at(0));
178 CHECK_NOTNULL(pfn_point_feats_.get());
180 AERROR <<
"Init pfn_inferece output blob error.";
183 AINFO <<
"Init pointwise unet pfn model success.";
186 std::map<std::string, std::vector<int>> blob_maps;
188 auto info = model_param_.
info();
190 std::string proto_file =
GetModelFile(model_path, info.proto_file().file());
194 "apollo::perception::inference::" + info.infer_plugin());
195 inference_->set_model_info(proto_file, input_names, output_names);
196 inference_->set_gpu_id(preprocess.gpu_id());
197 inference_->set_max_batch_size(max_point_number_ * 2);
202 inference_->Init(blob_maps);
206 if (input_names.size() == 4) {
207 coors_ = inference_->get_blob(input_names.at(0));
208 point_feats_ = inference_->get_blob(input_names.at(1));
209 bev_feature_ = inference_->get_blob(input_names.at(2));
210 prev_bev_feature_ = inference_->get_blob(input_names.at(3));
212 CHECK_NOTNULL(coors_.get());
213 CHECK_NOTNULL(point_feats_.get());
214 CHECK_NOTNULL(bev_feature_.get());
215 CHECK_NOTNULL(prev_bev_feature_.get());
217 AERROR <<
"Init inferece input blobs error.";
221 if (output_names.size() == 1) {
222 seg_pred_blob_ = inference_->get_blob(output_names.at(0));
223 CHECK_NOTNULL(seg_pred_blob_.get());
225 AERROR <<
"Init inferece output blobs error.";
228 AINFO <<
"Init pointwise unet backbone model success.";
237 std::vector<Unode>().swap(unet_nodes_);
238 unet_nodes_.resize(unet_width_ * unet_length_);
241 valid_point_index_.clear();
242 valid_point_index_.reserve(cloud->size());
245 valid_node_index_.clear();
246 valid_node_index_.reserve(unet_width_ * unet_length_);
249 for (
size_t i = 0; i < cloud->size(); i++) {
250 auto pt = cloud->at(i);
252 if (pt.x < min_x_ || pt.x > max_x_ || pt.y < min_y_ || pt.y > max_y_ || pt.z + z_offset_ < min_height_
253 || pt.z + z_offset_ > max_height_) {
257 int grid_x = (pt.x - min_x_) / resolution_;
258 int grid_y = (pt.y - min_y_) / resolution_;
259 if (grid_x >= 0 && grid_x < unet_width_ && grid_y >= 0 && grid_y < unet_length_) {
261 int pillar_idx = grid_y * unet_length_ + grid_x;
263 valid_point_index_.push_back(i);
265 valid_node_index_.push_back(pillar_idx);
269 unet_nodes_.at(pillar_idx).sum_x += pt.x;
270 unet_nodes_.at(pillar_idx).sum_y += pt.y;
271 unet_nodes_.at(pillar_idx).sum_z += pt.z;
272 if (unet_nodes_.at(pillar_idx).point_size == 0) {
274 unet_nodes_.at(pillar_idx).geometric_x
275 =
static_cast<float>(grid_x) * resolution_ + 0.5 * resolution_ + min_x_;
276 unet_nodes_.at(pillar_idx).geometric_y
277 =
static_cast<float>(grid_y) * resolution_ + 0.5 * resolution_ + min_y_;
278 unet_nodes_.at(pillar_idx).geometric_z = 0;
280 unet_nodes_.at(pillar_idx).grid_x = grid_x;
281 unet_nodes_.at(pillar_idx).grid_y = grid_y;
283 unet_nodes_.at(pillar_idx).point_size += 1;
286 if (
static_cast<int>(valid_point_index_.size()) >= max_point_number_) {
293 voxels_->Reshape({valid_point_index_.size(), 10});
294 auto voxel_cpu_data = voxels_->mutable_cpu_data();
296 pfn_point_feats_->Reshape({valid_point_index_.size(), 64});
298 coors_->Reshape({valid_point_index_.size(), 4});
299 auto coors_cpu_data = coors_->mutable_cpu_data();
300 for (
size_t i = 0; i < valid_point_index_.size(); i++) {
301 auto pt = cloud->at(valid_point_index_.at(i));
302 Unode node = unet_nodes_.at(valid_node_index_.at(i));
304 voxel_cpu_data[i * 10 + 0] = pt.x;
305 voxel_cpu_data[i * 10 + 1] = pt.y;
306 voxel_cpu_data[i * 10 + 2] = pt.z + z_offset_;
307 voxel_cpu_data[i * 10 + 3] = pt.intensity / 255.;
308 voxel_cpu_data[i * 10 + 4] = pt.x - node.sum_x / (node.point_size + 1e-6);
309 voxel_cpu_data[i * 10 + 5] = pt.y - node.sum_y / (node.point_size + 1e-6);
310 voxel_cpu_data[i * 10 + 6] = pt.z - node.sum_z / (node.point_size + 1e-6);
311 voxel_cpu_data[i * 10 + 7] = pt.x - node.geometric_x;
312 voxel_cpu_data[i * 10 + 8] = pt.y - node.geometric_y;
313 voxel_cpu_data[i * 10 + 9] = pt.z + z_offset_ - node.geometric_z;
316 coors_cpu_data[i * 4 + 0] = 0;
317 coors_cpu_data[i * 4 + 1] = 0;
318 coors_cpu_data[i * 4 + 2] = node.grid_y;
319 coors_cpu_data[i * 4 + 3] = node.grid_x;
323void MotionUnet::GenerateBackboneFeatureCPU(std::shared_ptr<base::Blob<float>> feature) {
325 point_feats_->Reshape(pfn_point_feats_->shape());
326 point_feats_->set_gpu_data(pfn_point_feats_->mutable_gpu_data());
329 auto point_feats_cpu = pfn_point_feats_->mutable_cpu_data();
332 feature->Reshape({1, 64, unet_length_, unet_width_});
333 auto feature_data = feature->mutable_cpu_data();
334 memset(feature_data, 0,
sizeof(
float) * 64 * unet_length_ * unet_width_);
336 for (
size_t i = 0; i < valid_node_index_.size(); i++) {
337 int pillar_idx = valid_node_index_.at(i);
338 Unode node = unet_nodes_.at(pillar_idx);
340 for (
int j = 0; j < 64; j++) {
341 int index = j * unet_length_ * unet_width_ + node.grid_y * unet_length_ + node.grid_x;
342 float value = feature_data[index];
343 float max_val = point_feats_cpu[i * 64 + j];
344 max_val = std::max(max_val, value);
345 feature_data[index] = max_val;
350void MotionUnet::LabelToPointCloud(LidarFrame* frame) {
352 if (!original_cloud_ || !original_world_cloud_) {
353 AERROR <<
"Fail to labeling, original_cloud_ or original_world_cloud_ is empty !";
357 auto sematic_result = seg_pred_blob_->mutable_cpu_data();
358 for (
size_t i = 0; i < valid_point_index_.size(); i++) {
360 float max_prob = std::numeric_limits<float>::min();
361 for (
int n = 0; n < 4; n++) {
362 float prob = sematic_result[i * 4 + n];
363 if (max_prob < prob) {
368 int point_index = valid_point_index_.at(i);
371 &original_cloud_->points_semantic_label(point_index));
374 &original_world_cloud_->points_semantic_label(point_index));
378void MotionUnet::TransformCloud(
382 cloud_ptr->reserve(world_cloud_ptr->size());
383 for (
size_t i = 0; i < world_cloud_ptr->size(); ++i) {
384 auto &point = world_cloud_ptr->at(i);
385 Eigen::Vector3d trans_point(point.x, point.y, point.z);
388 pt.
x =
static_cast<float>(trans_point(0));
389 pt.y =
static_cast<float>(trans_point(1));
390 pt.z =
static_cast<float>(trans_point(2));
391 pt.intensity =
static_cast<float>(point.intensity);
392 cloud_ptr->push_back(pt);
#define PERCEPTION_REGISTER_POINTCLOUDPARSER(name)
static PluginManager * Instance()
get singleton instance of PluginManager
std::shared_ptr< Base > CreateInstance(const std::string &derived_class)
create plugin instance of derived class based on Base
bool Parse(const PointCloudParserOptions &options, LidarFrame *frame)
Detect foreground objects
bool Init(const PointCloudParserInitOptions &options=PointCloudParserInitOptions())
Init the Base PointCloud Parser object
double toc(bool reset=false)
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
std::shared_ptr< PointDCloud > PointDCloudPtr
std::shared_ptr< PointFCloud > PointFCloudPtr
std::vector< std::string > GetBlobNames(const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
void AddShape(std::map< std::string, std::vector< int > > *shape_map, const google::protobuf::RepeatedPtrField< common::ModelBlob > &model_blobs)
void SetMotionLabel(PointMotionLabel label, uint8_t *value)
std::string GetModelFile(const std::string &model_name, const std::string &file_name)
Get the model file path by model path and file name
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
std::string GetModelPath(const std::string &model_name)
Get the model path by model name, search from APOLLO_MODEL_PATH
Eigen::Affine3d lidar2world_pose
std::shared_ptr< base::AttributePointCloud< base::PointD > > world_cloud
std::shared_ptr< base::AttributePointCloud< base::PointF > > cloud
optional common::ModelInfo pfn_info
optional UnetParam unet_params
optional float fuse_time_interval
optional common::ModelInfo info
optional common::PointCloudPreProcess preprocess